c5e318e4f743b164d59ea71ac28f75c5c1eccce3
[platform/core/system/swap-probe.git] / include / binproto.h
1 /*
2  *  DA probe
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Nikita Kalyazin <n.kalyazin@samsung.com>
9  * Anastasia Lyupa <a.lyupa@samsung.com>
10  *
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU Lesser General Public License as published by the
13  * Free Software Foundation; either version 2.1 of the License, or (at your option)
14  * any later version.
15  *
16  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this library; if not, write to the Free Software Foundation, Inc., 51
23  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  * Contributors:
26  * - Samsung RnD Institute Russia
27  *
28  */
29
30 #ifndef __BIN_PROTO_H__
31 #define __BIN_PROTO_H__
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <stdarg.h>
38
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include <sys/types.h>
43 #include <sys/stat.h>
44
45 // getpid/gettid
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <sys/syscall.h>
49
50 #include <sys/time.h>
51
52 #include <sys/socket.h>
53 #include "dahelper.h"
54 #include "api_id_mapping.h"
55
56 #define MSG_PROBE_MEMORY 0x0101
57 #define MSG_PROBE_UICONTROL 0x0102
58 #define MSG_PROBE_UIEVENT 0x0103
59 #define MSG_PROBE_RESOURCE 0x0104
60 #define MSG_PROBE_LIFECYCLE 0x0105
61 #define MSG_PROBE_SCREENSHOT 0x0106
62 #define MSG_PROBE_SCENE 0x0107
63 #define MSG_PROBE_THREAD 0x0108
64 #define MSG_PROBE_CUSTOM 0x0109
65 #define MSG_PROBE_SYNC 0x0110
66 #define MSG_PROBE_NETWORK 0x0111
67 #define MSG_PROBE_GL 0x0112
68
69 // TODO: remove this copy-paste
70 #define CALLER_ADDRESS                                                  \
71         ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
72
73
74
75 // COMMON
76 static inline char *pack_int32(char *to, uint32_t val)
77 {
78         *(uint32_t *)to = val;
79         return to + sizeof(uint32_t);
80 }
81
82 static inline char *pack_int64(char *to, uint64_t val)
83 {
84         *(uint64_t *)to = val;
85         return to + sizeof(uint64_t);
86 }
87
88 static char __attribute__((used)) *pack_string(char *to, const char *str)
89 {
90         size_t len = strlen(str) + 1;
91         strncpy(to, str, len);
92         return to + len;
93 }
94
95 static char __attribute__((used)) *pack_bin(char *to, const char *from,
96                                             uint32_t len)
97 {
98         memcpy(to, from, len);
99         return to + len;
100 }
101
102 static inline char *pack_double(char *to, double val)
103 {
104         *(double *)to = val;
105         return to + sizeof(double);
106 }
107
108 static inline char *pack_timestamp(char *to)
109 {
110         struct timeval tv;
111
112         gettimeofday(&tv, NULL);
113         to = pack_int32(to, tv.tv_sec);
114         to = pack_int32(to, tv.tv_usec * 1000);
115
116         return to;
117 }
118
119 static char __attribute__((used)) *pack_args(char *to, const char *fmt, ...)
120 {
121         va_list args;
122         uint32_t num = strlen(fmt);
123         const char *t = fmt;
124
125         if(*t == '\0') {
126                 num = 0;
127         }
128
129         memcpy(to, &num, sizeof(num));
130         to += sizeof(num);
131
132         va_start(args, fmt);
133
134         uint8_t c;
135         uint32_t d;
136         uint64_t x;
137         uint64_t p;
138         float f;
139         double w;
140         char *s;
141         int n;
142
143         for (t = fmt; *t != '\0'; t++) {
144                 switch (*t) {
145                 case 'c':
146                         c = (uint8_t)va_arg(args, uint32_t);
147                         *to++ = *t;
148                         memcpy(to, &c, sizeof(c));
149                         to += sizeof(c);
150                         break;
151                 case 'd':
152                         d = va_arg(args, uint32_t);
153                         *to++ = *t;
154                         memcpy(to, &d, sizeof(d));
155                         to += sizeof(d);
156                         break;
157                 case 'x':
158                         x = 0; // real value may be less then uint64_t
159                         x = (unsigned long)(uint64_t)va_arg(args, uint64_t);
160                         *to++ = *t;
161                         memcpy(to, &x, sizeof(x));
162                         to += sizeof(x);
163                         break;
164                 case 'p':
165                         p = 0; // real value may be less then uint64_t
166                         p = (unsigned long)(uintptr_t)va_arg(args, uint64_t);
167                         *to++ = *t;
168                         memcpy(to, &p, sizeof(p));
169                         to += sizeof(p);
170                         break;
171                 case 'f':
172                         f = (float)va_arg(args, double);
173                         *to++ = *t;
174                         memcpy(to, &f, sizeof(f));
175                         to += sizeof(f);
176                         break;
177                 case 'w':
178                         w = va_arg(args, double);
179                         *to++ = *t;
180                         memcpy(to, &w, sizeof(w));
181                         to += sizeof(w);
182                         break;
183                 case 's':
184                         s = va_arg(args, char *);
185                         *to++ = *t;
186                         n = strlen(s) + 1;
187                         strncpy(to, s, n);
188                         to += n;
189                         break;
190                 default:
191                         break;
192                 }
193         }
194
195         va_end(args);
196
197         return to;
198 }
199
200 #define BUF_PTR p
201 #define RET_PTR ret_p
202 #define PACK_INT32(val)                         \
203         BUF_PTR = pack_int32(BUF_PTR, val);
204 #define PACK_INT64(val)                         \
205         BUF_PTR = pack_int64(BUF_PTR, val);
206 #define PACK_STRING(str)                        \
207         BUF_PTR = pack_string(BUF_PTR, str);
208
209 #define PACK_COMMON_BEGIN(msg_id, api_id, fmt, ...)             \
210         do {                                                    \
211                 BUF_PTR = pack_int32(BUF_PTR, msg_id);          \
212                 BUF_PTR = pack_int32(BUF_PTR, 0);               \
213                 BUF_PTR = pack_timestamp(BUF_PTR);              \
214                 BUF_PTR = pack_int32(BUF_PTR, 0);               \
215                 BUF_PTR = pack_int32(BUF_PTR, api_id);          \
216                 BUF_PTR = pack_int32(BUF_PTR, getpid());                \
217                 BUF_PTR = pack_int32(BUF_PTR, syscall(__NR_gettid));    \
218                 BUF_PTR = pack_args(BUF_PTR, fmt, __VA_ARGS__); \
219                 RET_PTR = BUF_PTR;              \
220         } while (0)
221
222 #define PACK_COMMON_END(ret, errn, intern_call)         \
223         do {                                                    \
224                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(ret));        \
225                 BUF_PTR = pack_int64(BUF_PTR, (uint64_t)errn);  \
226                 BUF_PTR = pack_int32(BUF_PTR, (uint32_t)intern_call);   \
227                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)CALLER_ADDRESS); \
228                 BUF_PTR = pack_int32(BUF_PTR, 0);               \
229                 BUF_PTR = pack_int32(BUF_PTR, 0);               \
230         } while (0)
231
232 #define PACK_RETURN_END(ret)                                                            \
233                 RET_PTR = pack_int64(RET_PTR, (uintptr_t)(ret));
234
235 #define PACK_MEMORY(size, memory_api_type, addr)                \
236         do {                                                    \
237                 BUF_PTR = pack_int64(BUF_PTR, size);                    \
238                 BUF_PTR = pack_int32(BUF_PTR, memory_api_type); \
239                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)addr); \
240         } while (0)
241
242 #define PACK_UICONTROL(control)                                         \
243         do {                                                            \
244                 if (unlikely(control == NULL)) {                        \
245                         BUF_PTR = pack_string(BUF_PTR, "");             \
246                         BUF_PTR = pack_string(BUF_PTR, "");             \
247                         BUF_PTR = pack_int64(BUF_PTR, 0);               \
248                 } else {                                                \
249                         char *type = NULL, *name = NULL;                \
250                         if (find_object_hash((void*)(control),          \
251                                              &type, &name) == 1) {      \
252                                 BUF_PTR = pack_string(BUF_PTR, type);   \
253                                 BUF_PTR = pack_string(BUF_PTR, name);   \
254                         } else {                                        \
255                                 BUF_PTR = pack_string(BUF_PTR, "");     \
256                                 BUF_PTR = pack_string(BUF_PTR, "");     \
257                         }                                               \
258                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(control)); \
259                 }                                                       \
260         } while(0)
261
262 #define PACK_UIEVENT(event_type, detail_type, x, y, info1, info2)       \
263         do {                                                            \
264                 BUF_PTR = pack_int32(BUF_PTR, event_type);              \
265                 BUF_PTR = pack_int32(BUF_PTR, detail_type);             \
266                 BUF_PTR = pack_int32(BUF_PTR, x);                       \
267                 BUF_PTR = pack_int32(BUF_PTR, y);                       \
268                 BUF_PTR = pack_string(BUF_PTR, info1);                  \
269                 BUF_PTR = pack_int32(BUF_PTR, info2);                   \
270         } while (0)
271
272 #define PACK_RESOURCE(size, fd_value, fd_api_type, file_size,   \
273                       file_path)                                        \
274         do {                                                            \
275                 BUF_PTR = pack_int64(BUF_PTR, size);                    \
276                 BUF_PTR = pack_int64(BUF_PTR, fd_value);                \
277                 BUF_PTR = pack_int32(BUF_PTR, fd_api_type);             \
278                 BUF_PTR = pack_int64(BUF_PTR, file_size);               \
279                 BUF_PTR = pack_string(BUF_PTR, file_path);              \
280         } while (0)
281
282 #define PACK_SCREENSHOT(image_file_path, orientation)                           \
283                 do {                                                            \
284                           BUF_PTR = pack_string(BUF_PTR, image_file_path);      \
285                           BUF_PTR = pack_int32(BUF_PTR, orientation);           \
286                 } while (0)
287
288 #define PACK_SCENE(scene_name, formid, pform, panelid, ppanel, transition, user)        \
289         do {                                                                            \
290                 BUF_PTR = pack_string(BUF_PTR,  scene_name);                            \
291                 if (unlikely(pform == NULL)) {                                          \
292                         BUF_PTR = pack_string(BUF_PTR, "");                             \
293                         BUF_PTR = pack_int64(BUF_PTR, 0);                               \
294                 } else {                                                                \
295                         char *type = NULL, *name = NULL;                                \
296                         if (find_object_hash((void*)(pform), &type, &name) == 1) {      \
297                                 BUF_PTR = pack_string(BUF_PTR, name);                   \
298                         } else {                                                        \
299                                 BUF_PTR = pack_string(BUF_PTR, "");                     \
300                         }                                                               \
301                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)pform);                \
302                 }                                                                       \
303                 if (unlikely(ppanel == NULL)) {                                         \
304                         BUF_PTR = pack_string(BUF_PTR, "");                             \
305                         BUF_PTR = pack_int64(BUF_PTR, 0);                               \
306                 } else {                                                                \
307                         char *type = NULL, *name = NULL;                                \
308                         if (find_object_hash((void*)(ppanel), &type, &name) == 1) {     \
309                                 BUF_PTR = pack_string(BUF_PTR, name);                   \
310                         } else {                                                        \
311                                 BUF_PTR = pack_string(BUF_PTR, "");                     \
312                         }                                                               \
313                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(ppanel));             \
314                 }                                                                       \
315                 BUF_PTR = pack_int64(BUF_PTR, transition);                              \
316                 BUF_PTR = pack_int64(BUF_PTR, user);                                    \
317         } while(0)
318
319  #define PACK_THREAD(thread_id, thread_type, api_type)                  \
320          do {                                                           \
321         if(thread_type == THREAD_PTHREAD) {                             \
322             BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
323             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
324         } else if(thread_type == THREAD_TIZENTHREAD_WORKER              \
325                     || thread_type == THREAD_TIZENTHREAD_EVENTDRIVEN) {   \
326             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
327             BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
328         } else {                                                        \
329             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
330             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
331         }                                                               \
332         BUF_PTR = pack_int32(BUF_PTR, thread_type);                     \
333         BUF_PTR = pack_int32(BUF_PTR, api_type);                        \
334         } while (0)
335
336 #define PACK_CUSTOM(handle, type, name, color, value)           \
337         do {                                                    \
338                 BUF_PTR = pack_int32(BUF_PTR, handle);          \
339                 BUF_PTR = pack_int32(BUF_PTR, type);            \
340                 BUF_PTR = pack_string(BUF_PTR, name);           \
341                 BUF_PTR = pack_int32(BUF_PTR, color);           \
342                 BUF_PTR = pack_double(BUF_PTR, value);          \
343         } while (0)
344
345 #define PACK_SYNC(sync_val, sync_type, api_type)                     \
346         do {                                                         \
347                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)sync_val);  \
348                 BUF_PTR = pack_int32(BUF_PTR, sync_type);            \
349                 BUF_PTR = pack_int32(BUF_PTR, api_type);             \
350         } while (0)
351
352 #define LOCAL_BUF_SIZE 1024
353
354 #define PREPARE_LOCAL_BUF()                     \
355                 char msg_buf[LOCAL_BUF_SIZE];\
356                 char *BUF_PTR = msg_buf;                        \
357                 char *RET_PTR = NULL
358
359 #define MSG_LEN_OFFSET 16
360 #define MSG_HDR_LEN 20
361 #define FLUSH_LOCAL_BUF()                                               \
362                 *(uint32_t *)(msg_buf + MSG_LEN_OFFSET) = (p - msg_buf) - MSG_HDR_LEN; \
363                 send(gTraceInfo.socket.daemonSock, msg_buf, (p - msg_buf), 0)
364
365 // =========================== post block macro ===========================
366
367 #define POST_PACK_PROBEBLOCK_BEGIN()                                    \
368         newerrno = errno;                                               \
369         if(postBlockBegin(blockresult)) {
370
371 #define POST_PACK_PROBEBLOCK_END()                                      \
372                 postBlockEnd();                                         \
373         }                                                               \
374         errno = (newerrno != 0) ? newerrno : olderrno
375
376 /* int main(int argc, char **argv) */
377 /* { */
378 /*      char buf[1024]; */
379 /*      char *p = buf; */
380
381 /*      p = PACK_COMMON_BEGIN(p, 42, "cdxpfws", 'a', 10, (uint64_t)80, */
382 /*                            (uint64_t)0, 0.19, 0.33, "hello!"); */
383 /*      p = PACK_COMMON_END(p, 0); */
384
385 /*      int fd = creat("out.bin", 0644); */
386 /*      if (fd == -1) { */
387 /*              printf("error\n"); */
388 /*              exit(1); */
389 /*      } */
390
391 /*      write(fd, buf, p - buf); */
392 /*      close(fd); */
393
394 /*      return 0; */
395 /* } */
396
397 #endif /* __BIN_PROTO_H__ */