1 #ifndef UTILS_H 2 #define UTILS_H 3 #define _GNU_SOURCE 4 #include <pthread.h> 5 6 #include <stdint.h> 7 #include <sys/types.h> 8 #include <sys/uio.h> 9 10 #define VAR_UINT8 1 11 #define VAR_INT8 2 12 #define VAR_UINT16 3 13 #define VAR_INT16 4 14 #define VAR_INT 5 15 #define VAR_INT64 6 16 #define VAR_STRING 7 17 #define VAR_PSTRING 8 18 #define VAR_FLOAT 9 19 #define VAR_HEX 10 20 #define VAR_ARRAY 16 21 #define VAR_ARRAY_UINT8 (VAR_ARRAY + VAR_UINT8) 22 #define VAR_ARRAY_INT8 (VAR_ARRAY + VAR_INT8) 23 #define VAR_ARRAY_UINT16 (VAR_ARRAY + VAR_UINT16) 24 #define VAR_ARRAY_INT16 (VAR_ARRAY + VAR_INT16) 25 #define VAR_ARRAY_INT (VAR_ARRAY + VAR_INT) 26 #define VAR_ARRAY_INT64 (VAR_ARRAY + VAR_INT64) 27 #define VAR_ARRAY_FLOAT (VAR_ARRAY + VAR_FLOAT) 28 #define VAR_ARRAY_HEX (VAR_ARRAY + VAR_HEX) 29 #define VAR_ARRAY_STRING (VAR_ARRAY + VAR_STRING) 30 #define VAR_ARRAY_PSTRING (VAR_ARRAY + VAR_PSTRING) 31 #define VAR_AARRAY 32 32 #define VAR_AARRAY_UINT8 (VAR_AARRAY + VAR_UINT8) 33 #define VAR_AARRAY_INT8 (VAR_AARRAY + VAR_INT8) 34 #define VAR_AARRAY_UINT16 (VAR_AARRAY + VAR_UINT16) 35 #define VAR_AARRAY_INT16 (VAR_AARRAY + VAR_INT16) 36 #define VAR_AARRAY_INT (VAR_AARRAY + VAR_INT) 37 #define VAR_AARRAY_INT64 (VAR_AARRAY + VAR_INT64) 38 #define VAR_AARRAY_FLOAT (VAR_AARRAY + VAR_FLOAT) 39 #define VAR_AARRAY_HEX (VAR_AARRAY + VAR_HEX) 40 #define VAR_AARRAY_STRING (VAR_AARRAY + VAR_STRING) 41 #define VAR_AARRAY_PSTRING (VAR_AARRAY + VAR_PSTRING) 42 #define VAR_FUNCTION 48 43 #define VAR_FUNCTION_INT (VAR_FUNCTION + VAR_INT) 44 #define VAR_FUNCTION_INT64 (VAR_FUNCTION + VAR_INT64) 45 #define VAR_FUNCTION_STRING (VAR_FUNCTION + VAR_STRING) 46 47 typedef int (*get_data_int)(int p); 48 typedef int64_t (*get_data_int64)(int p); 49 typedef char *(*get_data_string)(int p, char *dest, int max_len); 50 51 typedef struct struct_symbols { 52 const char *name; 53 int type; 54 void *addr; 55 float multiplier; // multiply the value of the variable 56 int len; 57 int skip; 58 } _symbols; 59 60 typedef struct struct_mutex { 61 int enabled; 62 pthread_mutex_t mtx; 63 int state; 64 int line; 65 pthread_t tid; 66 int64_t lock_time, create_time; 67 char *file; 68 } SMutex; 69 70 struct struct_http_client; 71 typedef int (*http_client_action)(void *s, int len, void *opaque, 72 struct struct_http_client *h); 73 74 typedef struct struct_http_client { 75 char enabled; 76 SMutex mutex; 77 int state; 78 http_client_action action; 79 void *opaque; 80 char host[200]; 81 char req[200]; 82 int port; 83 int id; 84 } Shttp_client; 85 86 typedef struct hash_item { 87 uint16_t len; 88 uint16_t max_size; 89 uint8_t is_alloc; 90 int64_t key; 91 void *data; 92 } SHashItem; 93 94 typedef struct hash_table { 95 char init, resize; 96 int len; 97 int size; 98 SHashItem *items; 99 int64_t conflicts; 100 SMutex mutex; 101 } SHashTable; 102 103 #define MAX_HTTPC 100 104 105 #define get_httpc(i) \ 106 ((i >= 0 && i < MAX_HTTPC && httpc[i] && httpc[i]->enabled) ? httpc[i] \ 107 : NULL) 108 109 extern Shttp_client *httpc[MAX_HTTPC]; 110 111 int http_client(char *url, char *request, void *callback, void *opaque); 112 113 // Hash Table implementation: 114 // it holds the key (int32) and the value (void *) of specified size 115 // The data is allocated inside of the hash_item and resized if needed 116 // put will actually copy the data from the argument to the hash_item.data 117 // the value 0 means unused (do not set a key with value 0) 118 #define HASH_ITEM_ENABLED(h) (h.len) 119 #define FOREACH_ITEM(h, a) \ 120 for (i = 0; i < (h)->size; i++) \ 121 if (HASH_ITEM_ENABLED((h)->items[i]) && (a = (h)->items[i].data)) 122 123 int create_hash_table(SHashTable *hash, int no); 124 void copy_hash_table(SHashTable *s, SHashTable *d); 125 void free_hash(SHashTable *hash); 126 void *getItem(SHashTable *hash, uint32_t key); 127 int getItemLen(SHashTable *hash, uint32_t key); 128 #define setItem(a, b, c, d) _setItem(a, b, c, d, 1) 129 int _setItem(SHashTable *hash, uint32_t key, void *data, int len, int copy); 130 int delItem(SHashTable *hash, uint32_t key); 131 int delItemP(SHashTable *hash, void *p); 132 int getItemSize(SHashTable *hash, uint32_t key); 133 int setItemLen(SHashTable *hash, uint32_t key, int len); 134 int split(char **rv, char *s, int lrv, char sep); 135 int map_int(char *s, char **v); 136 int map_intd(char *s, char **v, int dv); 137 int map_float(char *s, int mul); 138 int check_strs(char *s, char **v, int dv); 139 void *mymalloc(int a, char *f, int l); 140 void *myrealloc(void *p, int a, char *f, int l); 141 void myfree(void *x, char *f, int l); 142 char *header_parameter(char **arg, int i); 143 char *get_current_timestamp(); 144 char *get_current_timestamp_log(); 145 void _log(const char *file, int line, const char *fmt, ...); 146 char *strip(char *s); 147 int split(char **rv, char *s, int lrv, char sep); 148 void set_signal_handler(char *argv0); 149 int becomeDaemon(); 150 int end_of_header(char *buf); 151 char *readfile(char *fn, char *ctype, int *len); 152 int get_json_state(char *buf, int len); 153 int get_json_bandwidth(char *buf, int len); 154 void process_file(void *sock, char *s, int len, char *ctype); 155 int closefile(char *mem, int len); 156 157 int mutex_init(SMutex *mutex); 158 int mutex_lock1(char *FILE, int line, SMutex *mutex); 159 int mutex_unlock1(char *FILE, int line, SMutex *mutex); 160 int mutex_destroy(SMutex *mutex); 161 void clean_mutexes(); 162 pthread_t start_new_thread(char *name); 163 pthread_t get_tid(); 164 void set_thread_prio(pthread_t tid, int prio); 165 166 int add_new_lock(void **arr, int count, int size, SMutex *mutex); 167 int64_t getTick(); 168 int64_t getTickUs(); 169 void join_thread(); 170 void add_join_thread(pthread_t t); 171 int init_utils(char *arg0); 172 void _hexdump(char *desc, void *addr, int len); 173 uint32_t crc_32(const uint8_t *data, int datalen); 174 void _dump_packets(char *message, unsigned char *b, int len, int packet_offset); 175 int get_index_hash_search(int start_pos, void *p, int max, int struct_size, 176 uint32_t key, uint32_t value); 177 int buffer_to_ts(uint8_t *dest, int dstsize, uint8_t *src, int srclen, char *cc, 178 int pid); 179 void write_buf_to_file(char *file, uint8_t *buf, int len); 180 181 #define mutex_lock(m) mutex_lock1(__FILE__, __LINE__, m) 182 #define mutex_unlock(m) mutex_unlock1(__FILE__, __LINE__, m) 183 //#define proxy_log(level, fmt, ...) _proxy_log(level, fmt"\n", ##__VA_ARGS__) 184 185 //#define LOG(a,...) {opts.last_log=a;if(opts.log){int 186 // x=getTick();printf(CC([%d.%03d]: 187 //,a,\n),x/1000,x%1000,##__VA_ARGS__);fflush(stdout);};} #define LOG(a,...) 188 //{opts.last_log=a;if(opts.log){printf(CC([%s]:\x20,a,\n),get_current_timestamp_log(),##__VA_ARGS__);fflush(stdout);};} 189 #define LOGL(level, a, ...) \ 190 { \ 191 if ((level)&opts.log) \ 192 _log(__FILE__, __LINE__, a, ##__VA_ARGS__); \ 193 } 194 195 #define LOGM(a, ...) LOGL(DEFAULT_LOG, a, ##__VA_ARGS__) 196 197 #define LOG(a, ...) LOGL(1, a, ##__VA_ARGS__) 198 199 #define DEBUGL(level, a, ...) \ 200 { \ 201 if ((level)&opts.debug) \ 202 _log(__FILE__, __LINE__, a, ##__VA_ARGS__); \ 203 } 204 #define DEBUGM(a, ...) DEBUGL(DEFAULT_LOG, a, ##__VA_ARGS__) 205 206 #define dump_packets(message, b, len, packet_offset) \ 207 if (DEFAULT_LOG & opts.debug) \ 208 _dump_packets(message, b, len, packet_offset) 209 #define hexdump(message, b, len) \ 210 if (DEFAULT_LOG & opts.debug) \ 211 _hexdump(message, b, len) 212 213 #define LOG0(a, ...) \ 214 { _log(__FILE__, __LINE__, a, ##__VA_ARGS__); } 215 216 #define FAIL(a, ...) \ 217 { \ 218 if (opts.log) { \ 219 LOGL(0, a, ##__VA_ARGS__); \ 220 } else \ 221 LOG0(a, ##__VA_ARGS__); \ 222 unlink(pid_file); \ 223 exit(1); \ 224 } 225 #define LOG_AND_RETURN(rc, a, ...) \ 226 { \ 227 LOG(a, ##__VA_ARGS__); \ 228 return rc; \ 229 } 230 #define malloc1(a) mymalloc(a, __FILE__, __LINE__) 231 #define free1(a) myfree(a, __FILE__, __LINE__) 232 #define realloc1(a, b) myrealloc(a, b, __FILE__, __LINE__) 233 234 #define strlcatf(buf, size, ptr, fmt...) \ 235 do { \ 236 int __r = snprintf((buf) + ptr, (size)-ptr, fmt); \ 237 ptr = __r >= (size)-ptr ? (size)-1 : ptr + __r; \ 238 } while (0) 239 240 #define strcatf(buf, ptr, fmt, ...) \ 241 strlcatf(buf, sizeof(buf) - 1, ptr, fmt, ##__VA_ARGS__) 242 243 #define SAFE_STRCPY(a, b) \ 244 { \ 245 int x = sizeof(a); \ 246 if (x < 10) \ 247 LOG("sizeof %d is too small at %s:%d", x, __FILE__, __LINE__); \ 248 strncpy(a, b, x - 1); \ 249 a[x - 1] = 0; \ 250 } 251 252 #define TEST_FUNC(a, str, ...) \ 253 { \ 254 int _tmp_var; \ 255 if ((_tmp_var = (a))) { \ 256 LOG(#a " failed with message: " str, ##__VA_ARGS__); \ 257 return _tmp_var; \ 258 } else \ 259 LOG("%-40s OK", #a); \ 260 } 261 262 #define LOG_GENERAL 1 263 #define LOG_HTTP (1 << 1) 264 #define LOG_SOCKETWORKS (1 << 2) 265 #define LOG_STREAM (1 << 3) 266 #define LOG_ADAPTER (1 << 4) 267 #define LOG_SATIPC (1 << 5) 268 #define LOG_PMT (1 << 6) 269 #define LOG_TABLES (1 << 7) 270 #define LOG_DVBAPI (1 << 8) 271 #define LOG_LOCK (1 << 9) 272 #define LOG_NETCEIVER (1 << 10) 273 #define LOG_DVBCA (1 << 11) 274 #define LOG_AXE (1 << 12) 275 #define LOG_SOCKET (1 << 13) 276 #define LOG_UTILS (1 << 14) 277 #define LOG_DMX (1 << 15) 278 #define LOG_SSDP (1 << 16) 279 #define LOG_DVB (1 << 17) 280 281 typedef ssize_t (*mywritev)(int fd, const struct iovec *io, int len); 282 283 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 284 #define PID_FROM_TS(b) (((b)[1] & 0x1F) * 256 + (b)[2]) 285 286 #ifdef TESTING 287 288 #define ASSERT(cond, msg) \ 289 if (!(cond)) \ 290 LOG_AND_RETURN(1, "%s:%d %s: %s", __FILE__, __LINE__, __FUNCTION__, msg) 291 292 #define writev(a, b, c) _writev(a, b, c) 293 294 #endif 295 296 #ifdef UTILS_C 297 char *loglevels[] = {"general", "http", "socketworks", "stream", "adapter", 298 "satipc", "pmt", "tables", "dvbapi", "lock", 299 "netceiver", "ca", "axe", "socket", "utils", 300 "dmx", "ssdp", "dvb", NULL}; 301 mywritev _writev = writev; 302 #else 303 extern char *loglevels[]; 304 extern mywritev _writev; 305 #endif 306 307 #endif 308