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