// SPDX-License-Identifier: BSD-3-Clause
/*
 * util.h
 * implements utility functions and definitions.
 *
 * Copyright (C) 2021-2024 IOPSYS Software Solutions AB. All rights reserved.
 * Copyright (C) 2025 Genexis AB.
 *
 * Author: anjan.chanda@iopsys.eu
 */

#ifndef UTIL_H
#define UTIL_H


#include <libubox/list.h>
#include <arpa/inet.h>
#include <sys/time.h>

extern int uuid_strtob(char *uuidstr, uint8_t *uuid);
extern int uuid_btostr(uint8_t *uuid, char *uuidstr);

struct i1905_useropts {
	const char *ubus_sockpath;
	const char *cmdpath;
	const char *pidfile;
	const char *objname;
	bool daemonize;
	const char *conffile;
	const char *confpath;
	uint32_t features;
	int loglevel;
	const char *logfile;
	bool logfile_isfifo;
	bool syslogging;
	const char *alid;
	bool lo;
	bool registrar;
};

/* default options */
#define IEEE1905_CONFFILE             "ieee1905"
#define IEEE1905_CONFFILE_PATH        "/etc/config"
#define IEEE1905_OBJECT               "ieee1905"
#define IEEE1905_OBJECT_EXT           IEEE1905_OBJECT".extension"
#define IEEE1905_PIDFILE              "/var/run/"IEEE1905_OBJECT".pid"
#define IEEE1905_CMDPATH              "/tmp/ieee1905"


void do_daemonize(const char *pidfile);

int getcurrtime(struct timeval *out);
int timeradd_msecs(struct timeval *a, unsigned long msecs, struct timeval *res);
int timersub_msecs(struct timeval *a, unsigned long msecs, struct timeval *res);
void get_random_bytes(int num, uint8_t *buf);
void bufprintf(uint8_t *buf, int len, const char *label);

typedef unsigned int ifstatus_t;
typedef unsigned char ifopstatus_t;

enum if_mediatype {
	IF_MEDIA_ETH,
	IF_MEDIA_WIFI,
	IF_MEDIA_PLD,
	IF_MEDIA_MOCA,
	IF_MEDIA_UNKNOWN,
};


int if_brportnum(const char *ifname);
int if_getcarrier(const char *ifname, int *carrier);

#if defined __has_include
#  if __has_include (<linux/ethtool_netlink.h>)
#    define HAVE_ETHTOOL_NETLINK 1
#  endif
#endif

int eth_get_linkspeed(const char *ifname, uint32_t *speed);

const char *regex_match(const char *str, const char *pattern);

#ifndef BIT
#define BIT(x)	(1 << (x))
#endif

#ifndef max
#define max(a,b)	(a) > (b) ? (a) : (b)
#endif

#define MACFMT		"%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC2STR(_m)	(_m)[0], (_m)[1], (_m)[2], (_m)[3], (_m)[4], (_m)[5]

#ifndef list_flush
#define list_flush(head, type, member)					\
do {									\
	type *__p = NULL, *__tmp;					\
									\
	if (!list_empty(head))						\
		list_for_each_entry_safe(__p, __tmp, head, member) {	\
			list_del(&__p->member);				\
			free(__p);					\
		}							\
} while (0)
#endif

#define foreach_token_r(t, tokens, saveptr, delim)	\
	for ((t = strtok_r(tokens, delim, &saveptr)); t; (t = strtok_r(NULL, delim, &saveptr)))

char *strstr_exact(char *haystack, const char *needle);

#define blobmsg_add_macaddr(b, f, v)	\
do {					\
	char _vstr[18] = {0};		\
	hwaddr_ntoa(v, _vstr);		\
	blobmsg_add_string(b, f, _vstr);\
} while (0)

#endif /* UTIL_H */
