svc: Relevant messages and structures definitions
[libsamsung-ipc.git] / samsung-ipc / ipc_util.c
1 /*
2  * This file is part of libsamsung-ipc.
3  *
4  * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
5  * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
6  *
7  * libsamsung-ipc is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * libsamsung-ipc is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with libsamsung-ipc.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdint.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <ctype.h>
28 #include <sys/ioctl.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <asm/types.h>
32
33 #include <samsung-ipc.h>
34 #include "ipc.h"
35
36 /* Log utils */
37 const char *ipc_response_type_to_str(int type)
38 {
39     switch (type) {
40         case IPC_TYPE_INDI:
41             return "INDI";
42         case IPC_TYPE_RESP:
43             return "RESP";
44         case IPC_TYPE_NOTI:
45             return "NOTI";
46         default:
47             return "UNKNOWN";
48     }
49 }
50
51 const char *ipc_request_type_to_str(int type)
52 {
53     switch (type) {
54         case IPC_TYPE_EXEC:
55             return "EXEC";
56         case IPC_TYPE_GET:
57             return "GET";
58         case IPC_TYPE_SET:
59             return "SET";
60         case IPC_TYPE_CFRM:
61             return "CFRM";
62         case IPC_TYPE_EVENT:
63             return "EVENT";
64         default:
65             return "UNKNOWN";
66     }
67 }
68
69 const char *ipc_command_to_str(int command)
70 {
71     switch (command) {
72         case IPC_CALL_OUTGOING:
73             return "IPC_CALL_OUTGOING";
74         case IPC_CALL_INCOMING:
75             return "IPC_CALL_INCOMING";
76         case IPC_CALL_RELEASE:
77             return "IPC_CALL_RELEASE";
78         case IPC_CALL_ANSWER:
79             return "IPC_CALL_ANSWER";
80         case IPC_CALL_STATUS:
81             return "IPC_CALL_STATUS";
82         case IPC_CALL_LIST:
83             return "IPC_CALL_LIST";
84         case IPC_CALL_BURST_DTMF:
85             return "IPC_CALL_BURST_DTMF";
86         case IPC_CALL_CONT_DTMF:
87             return "IPC_CALL_CONT_DTMF";
88         case IPC_CALL_WAITING:
89             return "IPC_CALL_WAITING";
90         case IPC_CALL_LINE_ID:
91             return "IPC_CALL_LINE_ID";
92         case IPC_DISP_ICON_INFO:
93             return "IPC_DISP_ICON_INFO";
94         case IPC_DISP_HOMEZONE_INFO:
95             return "IPC_DISP_HOMEZONE_INFO";
96         case IPC_DISP_RSSI_INFO:
97             return "IPC_DISP_RSSI_INFO";
98         case IPC_GEN_PHONE_RES:
99             return "IPC_GEN_PHONE_RES";
100         case IPC_GPRS_DEFINE_PDP_CONTEXT:
101             return "IPC_GPRS_DEFINE_PDP_CONTEXT";
102         case IPC_GPRS_QOS:
103             return "IPC_GPRS_QOS";
104         case IPC_GPRS_PS:
105             return "IPC_GPRS_PS";
106         case IPC_GPRS_PDP_CONTEXT:
107             return "IPC_GPRS_PDP_CONTEXT";
108         case IPC_GPRS_ENTER_DATA:
109             return "IPC_GPRS_ENTER_DATA";
110         case IPC_GPRS_SHOW_PDP_ADDR:
111             return "IPC_GPRS_SHOW_PDP_ADDR";
112         case IPC_GPRS_MS_CLASS:
113             return "IPC_GPRS_MS_CLASS";
114         case IPC_GPRS_3G_QUAL_SERVICE_PROFILE:
115             return "IPC_GPRS_3G_QUAL_SERVICE_PROFILE";
116         case IPC_GPRS_IP_CONFIGURATION:
117             return "IPC_GPRS_IP_CONFIGURATION";
118         case IPC_GPRS_DEFINE_SEC_PDP_CONTEXT:
119             return "IPC_GPRS_DEFINE_SEC_PDP_CONTEXT";
120         case IPC_GPRS_TFT:
121             return "IPC_GPRS_TFT";
122         case IPC_GPRS_HSDPA_STATUS:
123             return "IPC_GPRS_HSDPA_STATUS";
124         case IPC_GPRS_CURRENT_SESSION_DATA_COUNT:
125             return "IPC_GPRS_CURRENT_SESSION_DATA_COUNT";
126         case IPC_GPRS_DATA_DORMANT:
127             return "IPC_GPRS_DATA_DORMANT";
128         case IPC_GPRS_DUN_PIN_CTRL:
129             return "IPC_GPRS_DUN_PIN_CTRL";
130         case IPC_GPRS_CALL_STATUS:
131             return "IPC_GPRS_CALL_STATUS";
132         case IPC_GPRS_PORT_LIST:
133             return "IPC_GPRS_PORT_LIST";
134         case IPC_IMEI_START:
135             return "IPC_IMEI_START";
136         case IPC_IMEI_CHECK_DEVICE_INFO:
137             return "IPC_IMEI_CHECK_DEVICE_INFO";
138         case IPC_MISC_ME_VERSION:
139             return "IPC_MISC_ME_VERSION";
140         case IPC_MISC_ME_IMSI:
141             return "IPC_MISC_ME_IMSI";
142         case IPC_MISC_ME_SN:
143             return "IPC_MISC_ME_SN";
144         case IPC_MISC_TIME_INFO:
145             return "IPC_MISC_TIME_INFO";
146         case IPC_MISC_DEBUG_LEVEL:
147             return "IPC_MISC_DEBUG_LEVEL";
148         case IPC_NET_PREF_PLMN:
149             return "IPC_NET_PREF_PLMN";
150         case IPC_NET_PLMN_SEL:
151             return "IPC_NET_PLMN_SEL";
152         case IPC_NET_CURRENT_PLMN:
153             return "IPC_NET_CURRENT_PLMN";
154         case IPC_NET_PLMN_LIST:
155             return "IPC_NET_PLMN_LIST";
156         case IPC_NET_REGIST:
157             return "IPC_NET_REGIST";
158         case IPC_NET_SUBSCRIBER_NUM:
159             return "IPC_NET_SUBSCRIBER_NUM";
160         case IPC_NET_BAND_SEL:
161             return "IPC_NET_BAND_SEL";
162         case IPC_NET_SERVICE_DOMAIN_CONFIG:
163             return "IPC_NET_SERVICE_DOMAIN_CONFIG";
164         case IPC_NET_POWERON_ATTACH:
165             return "IPC_NET_POWERON_ATTACH";
166         case IPC_NET_MODE_SEL:
167             return "IPC_NET_MODE_SEL";
168         case IPC_NET_ACQ_ORDER:
169             return "IPC_NET_ACQ_ORDER";
170         case IPC_NET_IDENTITY:
171             return "IPC_NET_IDENTITY";
172         case IPC_NET_CURRENT_RRC_STATUS:
173             return "IPC_NET_CURRENT_RRC_STATUS";
174         case IPC_PB_ACCESS:
175             return "IPC_PB_ACCESS";
176         case IPC_PB_STORAGE:
177             return "IPC_PB_STORAGE";
178         case IPC_PB_STORAGE_LIST:
179             return "IPC_PB_STORAGE_LIST";
180         case IPC_PB_ENTRY_INFO:
181             return "IPC_PB_ENTRY_INFO";
182         case IPC_PB_CAPABILITY_INFO:
183             return "IPC_PB_CAPABILITY_INFO";
184         case IPC_PWR_PHONE_PWR_UP:
185             return "IPC_PWR_PHONE_PWR_UP";
186         case IPC_PWR_PHONE_PWR_OFF:
187             return "IPC_PWR_PHONE_PWR_OFF";
188         case IPC_PWR_PHONE_RESET:
189             return "IPC_PWR_PHONE_RESET";
190         case IPC_PWR_BATT_STATUS:
191             return "IPC_PWR_BATT_STATUS";
192         case IPC_PWR_BATT_TYPE:
193             return "IPC_PWR_BATT_TYPE";
194         case IPC_PWR_BATT_COMP:
195             return "IPC_PWR_BATT_COMP";
196         case IPC_PWR_PHONE_STATE:
197             return "IPC_PWR_PHONE_STATE";
198         case IPC_RFS_NV_READ_ITEM:
199             return "IPC_RFS_NV_READ_ITEM";
200         case IPC_RFS_NV_WRITE_ITEM:
201             return "IPC_RFS_NV_WRITE_ITEM";
202         case IPC_SAT_PROFILE_DOWNLOAD:
203             return "IPC_SAT_PROFILE_DOWNLOAD";
204         case IPC_SAT_ENVELOPE_CMD:
205             return "IPC_SAT_ENVELOPE_CMD";
206         case IPC_SAT_PROACTIVE_CMD:
207             return "IPC_SAT_PROACTIVE_CMD";
208         case IPC_SAT_TERMINATE_USAT_SESSION:
209             return "IPC_SAT_TERMINATE_USAT_SESSION";
210         case IPC_SAT_EVENT_DOWNLOAD:
211             return "IPC_SAT_EVENT_DOWNLOAD";
212         case IPC_SAT_PROVIDE_LOCAL_INFO:
213             return "IPC_SAT_PROVIDE_LOCAL_INFO";
214         case IPC_SAT_POLLING:
215             return "IPC_SAT_POLLING";
216         case IPC_SAT_REFRESH:
217             return "IPC_SAT_REFRESH";
218         case IPC_SAT_SETUP_EVENT_LIST:
219             return "IPC_SAT_SETUP_EVENT_LIST";
220         case IPC_SAT_CALL_CONTROL_RESULT:
221             return "IPC_SAT_CALL_CONTROL_RESULT";
222         case IPC_SAT_IMAGE_CLUT:
223             return "IPC_SAT_IMAGE_CLUT";
224         case IPC_SAT_CALL_PROCESSING:
225             return "IPC_SAT_CALL_PROCESSING";
226         case IPC_SEC_SIM_STATUS:
227             return "IPC_SEC_SIM_STATUS";
228         case IPC_SEC_PHONE_LOCK:
229             return "IPC_SEC_PHONE_LOCK";
230         case IPC_SEC_CHANGE_LOCKING_PW:
231             return "IPC_SEC_CHANGE_LOCKING_PW";
232         case IPC_SEC_SIM_LANG:
233             return "IPC_SEC_SIM_LANG";
234         case IPC_SEC_RSIM_ACCESS:
235             return "IPC_SEC_RSIM_ACCESS";
236         case IPC_SEC_GSIM_ACCESS:
237             return "IPC_SEC_GSIM_ACCESS";
238         case IPC_SEC_SIM_ICC_TYPE:
239             return "IPC_SEC_SIM_ICC_TYPE";
240         case IPC_SEC_LOCK_INFO:
241             return "IPC_SEC_LOCK_INFO";
242         case IPC_SEC_ISIM_AUTH:
243             return "IPC_SEC_ISIM_AUTH";
244         case IPC_SMS_SEND_MSG:
245             return "IPC_SMS_SEND_MSG";
246         case IPC_SMS_INCOMING_MSG:
247             return "IPC_SMS_INCOMING_MSG";
248         case IPC_SMS_READ_MSG:
249             return "IPC_SMS_READ_MSG";
250         case IPC_SMS_SAVE_MSG:
251             return "IPC_SMS_SAVE_MSG";
252         case IPC_SMS_DEL_MSG:
253             return "IPC_SMS_DEL_MSG";
254         case IPC_SMS_DELIVER_REPORT:
255             return "IPC_SMS_DELIVER_REPORT";
256         case IPC_SMS_DEVICE_READY:
257             return "IPC_SMS_DEVICE_READY";
258         case IPC_SMS_SEL_MEM:
259             return "IPC_SMS_SEL_MEM";
260         case IPC_SMS_STORED_MSG_COUNT:
261             return "IPC_SMS_STORED_MSG_COUNT";
262         case IPC_SMS_SVC_CENTER_ADDR:
263             return "IPC_SMS_SVC_CENTER_ADDR";
264         case IPC_SMS_SVC_OPTION:
265             return "IPC_SMS_SVC_OPTION";
266         case IPC_SMS_MEM_STATUS:
267             return "IPC_SMS_MEM_STATUS";
268         case IPC_SMS_CBS_MSG:
269             return "IPC_SMS_CBS_MSG";
270         case IPC_SMS_CBS_CONFIG:
271             return "IPC_SMS_CBS_CONFIG";
272         case IPC_SMS_STORED_MSG_STATUS:
273             return "IPC_SMS_STORED_MSG_STATUS";
274         case IPC_SMS_PARAM_COUNT:
275             return "IPC_SMS_PARAM_COUNT";
276         case IPC_SMS_PARAM:
277             return "IPC_SMS_PARAM";
278         case IPC_SND_SPKR_VOLUME_CTRL:
279             return "IPC_SND_SPKR_VOLUME_CTRL";
280         case IPC_SND_MIC_MUTE_CTRL:
281             return "IPC_SND_MIC_MUTE_CTRL";
282         case IPC_SND_AUDIO_PATH_CTRL:
283             return "IPC_SND_AUDIO_PATH_CTRL";
284         case IPC_SND_AUDIO_SOURCE_CTRL:
285             return "IPC_SND_AUDIO_SOURCE_CTRL";
286         case IPC_SND_LOOPBACK_CTRL:
287             return "IPC_SND_LOOPBACK_CTRL";
288         case IPC_SND_VOICE_RECORDING_CTRL:
289             return "IPC_SND_VOICE_RECORDING_CTRL";
290         case IPC_SND_VIDEO_CALL_CTRL:
291             return "IPC_SND_VIDEO_CALL_CTRL";
292         case IPC_SND_RINGBACK_TONE_CTRL:
293             return "IPC_SND_RINGBACK_TONE_CTRL";
294         case IPC_SND_CLOCK_CTRL:
295             return "IPC_SND_CLOCK_CTRL";
296         case IPC_SND_WB_AMR_STATUS:
297             return "IPC_SND_WB_AMR_STATUS";
298         case IPC_SS_WAITING:
299             return "IPC_SS_WAITING";
300         case IPC_SS_CLI:
301             return "IPC_SS_CLI";
302         case IPC_SS_BARRING:
303             return "IPC_SS_BARRING";
304         case IPC_SS_BARRING_PW:
305             return "IPC_SS_BARRING_PW";
306         case IPC_SS_FORWARDING:
307             return "IPC_SS_FORWARDING";
308         case IPC_SS_INFO:
309             return "IPC_SS_INFO";
310         case IPC_SS_MANAGE_CALL:
311             return "IPC_SS_MANAGE_CALL";
312         case IPC_SS_USSD:
313             return "IPC_SS_USSD";
314         case IPC_SS_AOC:
315             return "IPC_SS_AOC";
316         case IPC_SS_RELEASE_COMPLETE:
317             return "IPC_SS_RELEASE_COMPLETE";
318         case IPC_SVC_ENTER:
319             return "IPC_SVC_ENTER";
320         case IPC_SVC_END:
321             return "IPC_SVC_END";
322         case IPC_SVC_PRO_KEYCODE:
323             return "IPC_SVC_PRO_KEYCODE";
324         case IPC_SVC_SCREEN_CFG:
325             return "IPC_SVC_SCREEN_CFG";
326         case IPC_SVC_DISPLAY_SCREEN:
327             return "IPC_SVC_DISPLAY_SCREEN";
328         case IPC_SVC_CHANGE_SVC_MODE:
329             return "IPC_SVC_CHANGE_SVC_MODE";
330         case IPC_SVC_DEVICE_TEST:
331             return "IPC_SVC_DEVICE_TEST";
332         case IPC_SVC_DEBUG_DUMP_MESSAGE:
333             return "IPC_SVC_DEBUG_DUMP_MESSAGE";
334         case IPC_SVC_DEBUG_STRING_MESSAGE:
335             return "IPC_SVC_DEBUG_STRING_MESSAGE";
336         default:
337             return "UNKNOWN";
338     }
339 }
340
341 void ipc_client_hex_dump(struct ipc_client *client, void *data, int size)
342 {
343     /* dumps size bytes of *data to stdout. Looks like:
344      * [0000] 75 6E 6B 6E 6F 77 6E 20
345      *                  30 FF 00 00 00 00 39 00 unknown 0.....9.
346      * (in a single line of course)
347      */
348
349     unsigned char *p = data;
350     unsigned char c;
351     int n;
352     char bytestr[4] = {0};
353     char addrstr[10] = {0};
354     char hexstr[ 16*3 + 5] = {0};
355     char charstr[16*1 + 5] = {0};
356     for (n=1;n<=size;n++) {
357         if (n%16 == 1) {
358             /* store address for this line */
359             unsigned int end = 0, start = 0;
360             end = *((unsigned int*) p);
361             start = *((unsigned int*) data);
362             snprintf(addrstr, sizeof(addrstr), "%.4x", end - start);
363         }
364
365         c = *p;
366         if (isalnum(c) == 0) {
367             c = '.';
368         }
369
370         /* store hex str (for left side) */
371         snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
372         strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
373
374         /* store char str (for right side) */
375         snprintf(bytestr, sizeof(bytestr), "%c", c);
376         strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
377
378         if (n%16 == 0) {
379             /* line completed */
380             ipc_client_log(client, "[%4.4s]   %-50.50s  %s", addrstr, hexstr, charstr);
381             hexstr[0] = 0;
382             charstr[0] = 0;
383         } else if (n%8 == 0) {
384             /* half line: add whitespaces */
385             strncat(hexstr, "  ", sizeof(hexstr)-strlen(hexstr)-1);
386             strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
387         }
388         p++; /* next byte */
389     }
390
391     if (strlen(hexstr) > 0) {
392         /* print rest of buffer if not empty */
393         ipc_client_log(client, "[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
394     }
395 }
396
397 void ipc_client_log_recv(struct ipc_client *client,
398     struct ipc_message_info *response, const char *prefix)
399 {
400     switch (client->type) {
401         case IPC_CLIENT_TYPE_FMT:
402             ipc_client_log(client, "%s: RECV FMT!", prefix);
403             ipc_client_log(client, "%s: Response: aseq=0x%02x command=%s (0x%04x) type=%s",
404                 prefix, response->aseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response), ipc_response_type_to_str(response->type));
405 #ifdef DEBUG
406             if (response->length > 0) {
407                 ipc_client_log(client, "==== FMT DATA DUMP ====");
408                 ipc_client_hex_dump(client, (void *) response->data,
409                     response->length > 0x100 ? 0x100 : response->length);
410                 ipc_client_log(client, "=======================");
411             }
412 #endif
413             break;
414         case IPC_CLIENT_TYPE_RFS:
415             ipc_client_log(client, "%s: RECV RFS!", prefix);
416             ipc_client_log(client, "%s: Response: aseq=0x%02x command=%s (0x%04x)",
417                 prefix, response->aseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response));
418 #ifdef DEBUG
419             if (response->length > 0) {
420                 ipc_client_log(client, "==== RFS DATA DUMP ====");
421                 ipc_client_hex_dump(client, (void *) response->data,
422                     response->length > 0x100 ? 0x100 : response->length);
423                 ipc_client_log(client, "=======================");
424             }
425 #endif
426             break;
427     }
428 }
429
430 void ipc_client_log_send(struct ipc_client *client,
431     struct ipc_message_info *request, const char *prefix)
432 {
433     switch (client->type) {
434         case IPC_CLIENT_TYPE_FMT:
435             ipc_client_log(client, "%s: SEND FMT!", prefix);
436             ipc_client_log(client, "%s: Request: mseq=0x%02x command=%s (0x%04x) type=%s",
437                 prefix, request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request), ipc_request_type_to_str(request->type));
438 #ifdef DEBUG
439             if (request->length > 0) {
440                 ipc_client_log(client, "==== FMT DATA DUMP ====");
441                 ipc_client_hex_dump(client, (void *) request->data,
442                     request->length > 0x100 ? 0x100 : request->length);
443                 ipc_client_log(client, "=======================");
444             }
445 #endif
446             break;
447         case IPC_CLIENT_TYPE_RFS:
448             ipc_client_log(client, "%s: SEND RFS!", prefix);
449             ipc_client_log(client, "%s: Request: mseq=0x%02x command=%s (0x%04x)",
450                 prefix, request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request));
451 #ifdef DEBUG
452             if (request->length > 0) {
453                 ipc_client_log(client, "==== RFS DATA DUMP ====");
454                 ipc_client_hex_dump(client, (void *) request->data,
455                     request->length > 0x100 ? 0x100 : request->length);
456                 ipc_client_log(client, "=======================");
457             }
458 #endif
459             break;
460     }
461 }
462
463 void ipc_fmt_header_fill(struct ipc_fmt_header *header, struct ipc_message_info *message)
464 {
465     if (header == NULL || message == NULL)
466         return;
467
468     memset(header, 0, sizeof(struct ipc_fmt_header));
469     header->mseq = message->mseq;
470     header->aseq = message->aseq;
471     header->group = message->group;
472     header->index = message->index;
473     header->type = message->type;
474     header->length = message->length + sizeof(struct ipc_fmt_header);
475 }
476
477 void ipc_fmt_message_fill(struct ipc_fmt_header *header, struct ipc_message_info *message)
478 {
479     if (header == NULL || message == NULL)
480         return;
481
482     memset(message, 0, sizeof(struct ipc_message_info));
483     message->mseq = header->mseq;
484     message->aseq = header->aseq;
485     message->group = header->group;
486     message->index = header->index;
487     message->type = header->type;
488     message->cmd = IPC_COMMAND(message);
489     message->length = 0;
490     message->data = NULL;
491 }
492
493 void ipc_rfs_header_fill(struct ipc_rfs_header *header, struct ipc_message_info *message)
494 {
495     if (header == NULL || message == NULL)
496         return;
497
498     memset(header, 0, sizeof(struct ipc_rfs_header));
499     header->id = message->mseq;
500     header->index = message->index;
501     header->length = message->length + sizeof(struct ipc_rfs_header);
502 }
503
504 void ipc_rfs_message_fill(struct ipc_rfs_header *header, struct ipc_message_info *message)
505 {
506     if (header == NULL || message == NULL)
507         return;
508
509     memset(message, 0, sizeof(struct ipc_message_info));
510     message->aseq = header->id;
511     message->group = IPC_GROUP_RFS;
512     message->index = header->index;
513     message->length = 0;
514     message->data = NULL;
515 }
516
517 // vim:ts=4:sw=4:expandtab