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