2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5 * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr>
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.
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.
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/>.
27 #include <sys/ioctl.h>
29 #include <sys/types.h>
30 #include <asm/types.h>
32 #include <samsung-ipc.h>
35 int ipc_seq_valid(unsigned char seq)
37 if (seq == 0x00 || seq == 0xff)
43 const char *ipc_request_type_string(unsigned char type)
45 static char type_string[5] = { 0 };
49 return "IPC_TYPE_EXEC";
51 return "IPC_TYPE_GET";
53 return "IPC_TYPE_SET";
55 return "IPC_TYPE_CFRM";
57 return "IPC_TYPE_EVENT";
59 snprintf((char *) &type_string, sizeof(type_string), "0x%02x", type);
64 const char *ipc_response_type_string(unsigned char type)
66 static char type_string[5] = { 0 };
70 return "IPC_TYPE_INDI";
72 return "IPC_TYPE_RESP";
74 return "IPC_TYPE_NOTI";
76 snprintf((char *) &type_string, sizeof(type_string), "0x%02x", type);
81 const char *ipc_command_string(unsigned short command)
83 static char command_string[7] = { 0 };
86 case IPC_PWR_PHONE_PWR_UP:
87 return "IPC_PWR_PHONE_PWR_UP";
88 case IPC_PWR_PHONE_PWR_OFF:
89 return "IPC_PWR_PHONE_PWR_OFF";
90 case IPC_PWR_PHONE_RESET:
91 return "IPC_PWR_PHONE_RESET";
92 case IPC_PWR_BATT_STATUS:
93 return "IPC_PWR_BATT_STATUS";
94 case IPC_PWR_BATT_TYPE:
95 return "IPC_PWR_BATT_TYPE";
96 case IPC_PWR_BATT_COMP:
97 return "IPC_PWR_BATT_COMP";
98 case IPC_PWR_PHONE_STATE:
99 return "IPC_PWR_PHONE_STATE";
100 case IPC_CALL_OUTGOING:
101 return "IPC_CALL_OUTGOING";
102 case IPC_CALL_INCOMING:
103 return "IPC_CALL_INCOMING";
104 case IPC_CALL_RELEASE:
105 return "IPC_CALL_RELEASE";
106 case IPC_CALL_ANSWER:
107 return "IPC_CALL_ANSWER";
108 case IPC_CALL_STATUS:
109 return "IPC_CALL_STATUS";
111 return "IPC_CALL_LIST";
112 case IPC_CALL_BURST_DTMF:
113 return "IPC_CALL_BURST_DTMF";
114 case IPC_CALL_CONT_DTMF:
115 return "IPC_CALL_CONT_DTMF";
116 case IPC_CALL_WAITING:
117 return "IPC_CALL_WAITING";
118 case IPC_CALL_LINE_ID:
119 return "IPC_CALL_LINE_ID";
120 case IPC_SMS_SEND_MSG:
121 return "IPC_SMS_SEND_MSG";
122 case IPC_SMS_INCOMING_MSG:
123 return "IPC_SMS_INCOMING_MSG";
124 case IPC_SMS_READ_MSG:
125 return "IPC_SMS_READ_MSG";
126 case IPC_SMS_SAVE_MSG:
127 return "IPC_SMS_SAVE_MSG";
128 case IPC_SMS_DEL_MSG:
129 return "IPC_SMS_DEL_MSG";
130 case IPC_SMS_DELIVER_REPORT:
131 return "IPC_SMS_DELIVER_REPORT";
132 case IPC_SMS_DEVICE_READY:
133 return "IPC_SMS_DEVICE_READY";
134 case IPC_SMS_SEL_MEM:
135 return "IPC_SMS_SEL_MEM";
136 case IPC_SMS_STORED_MSG_COUNT:
137 return "IPC_SMS_STORED_MSG_COUNT";
138 case IPC_SMS_SVC_CENTER_ADDR:
139 return "IPC_SMS_SVC_CENTER_ADDR";
140 case IPC_SMS_SVC_OPTION:
141 return "IPC_SMS_SVC_OPTION";
142 case IPC_SMS_MEM_STATUS:
143 return "IPC_SMS_MEM_STATUS";
144 case IPC_SMS_CBS_MSG:
145 return "IPC_SMS_CBS_MSG";
146 case IPC_SMS_CBS_CFG:
147 return "IPC_SMS_CBS_CFG";
148 case IPC_SMS_STORED_MSG_STATUS:
149 return "IPC_SMS_STORED_MSG_STATUS";
150 case IPC_SMS_PARAM_COUNT:
151 return "IPC_SMS_PARAM_COUNT";
153 return "IPC_SMS_PARAM";
154 case IPC_SEC_PIN_STATUS:
155 return "IPC_SEC_PIN_STATUS";
156 case IPC_SEC_PHONE_LOCK:
157 return "IPC_SEC_PHONE_LOCK";
158 case IPC_SEC_CHANGE_LOCKING_PW:
159 return "IPC_SEC_CHANGE_LOCKING_PW";
160 case IPC_SEC_SIM_LANG:
161 return "IPC_SEC_SIM_LANG";
162 case IPC_SEC_RSIM_ACCESS:
163 return "IPC_SEC_RSIM_ACCESS";
164 case IPC_SEC_GSIM_ACCESS:
165 return "IPC_SEC_GSIM_ACCESS";
166 case IPC_SEC_SIM_ICC_TYPE:
167 return "IPC_SEC_SIM_ICC_TYPE";
168 case IPC_SEC_LOCK_INFOMATION:
169 return "IPC_SEC_LOCK_INFOMATION";
170 case IPC_SEC_IMS_AUTH:
171 return "IPC_SEC_IMS_AUTH";
173 return "IPC_PB_ACCESS";
175 return "IPC_PB_STORAGE";
176 case IPC_PB_STORAGE_LIST:
177 return "IPC_PB_STORAGE_LIST";
178 case IPC_PB_ENTRY_INFO:
179 return "IPC_PB_ENTRY_INFO";
180 case IPC_PB_3GPB_CAPA:
181 return "IPC_PB_3GPB_CAPA";
182 case IPC_DISP_ICON_INFO:
183 return "IPC_DISP_ICON_INFO";
184 case IPC_DISP_HOMEZONE_INFO:
185 return "IPC_DISP_HOMEZONE_INFO";
186 case IPC_DISP_RSSI_INFO:
187 return "IPC_DISP_RSSI_INFO";
188 case IPC_NET_PREF_PLMN:
189 return "IPC_NET_PREF_PLMN";
190 case IPC_NET_PLMN_SEL:
191 return "IPC_NET_PLMN_SEL";
192 case IPC_NET_SERVING_NETWORK:
193 return "IPC_NET_SERVING_NETWORK";
194 case IPC_NET_PLMN_LIST:
195 return "IPC_NET_PLMN_LIST";
197 return "IPC_NET_REGIST";
198 case IPC_NET_SUBSCRIBER_NUM:
199 return "IPC_NET_SUBSCRIBER_NUM";
200 case IPC_NET_BAND_SEL:
201 return "IPC_NET_BAND_SEL";
202 case IPC_NET_SERVICE_DOMAIN_CONFIG:
203 return "IPC_NET_SERVICE_DOMAIN_CONFIG";
204 case IPC_NET_POWERON_ATTACH:
205 return "IPC_NET_POWERON_ATTACH";
206 case IPC_NET_MODE_SEL:
207 return "IPC_NET_MODE_SEL";
208 case IPC_NET_ACQ_ORDER:
209 return "IPC_NET_ACQ_ORDER";
210 case IPC_NET_IDENTITY:
211 return "IPC_NET_IDENTITY";
212 case IPC_NET_PREFERRED_NETWORK_INFO:
213 return "IPC_NET_PREFERRED_NETWORK_INFO";
214 case IPC_SND_SPKR_VOLUME_CTRL:
215 return "IPC_SND_SPKR_VOLUME_CTRL";
216 case IPC_SND_MIC_MUTE_CTRL:
217 return "IPC_SND_MIC_MUTE_CTRL";
218 case IPC_SND_AUDIO_PATH_CTRL:
219 return "IPC_SND_AUDIO_PATH_CTRL";
220 case IPC_SND_AUDIO_SOURCE_CTRL:
221 return "IPC_SND_AUDIO_SOURCE_CTRL";
222 case IPC_SND_LOOPBACK_CTRL:
223 return "IPC_SND_LOOPBACK_CTRL";
224 case IPC_SND_VOICE_RECORDING_CTRL:
225 return "IPC_SND_VOICE_RECORDING_CTRL";
226 case IPC_SND_VIDEO_CALL_CTRL:
227 return "IPC_SND_VIDEO_CALL_CTRL";
228 case IPC_SND_RINGBACK_TONE_CTRL:
229 return "IPC_SND_RINGBACK_TONE_CTRL";
230 case IPC_SND_CLOCK_CTRL:
231 return "IPC_SND_CLOCK_CTRL";
232 case IPC_SND_WB_AMR_STATUS:
233 return "IPC_SND_WB_AMR_STATUS";
234 case IPC_MISC_ME_VERSION:
235 return "IPC_MISC_ME_VERSION";
236 case IPC_MISC_ME_IMSI:
237 return "IPC_MISC_ME_IMSI";
239 return "IPC_MISC_ME_SN";
240 case IPC_MISC_TIME_INFO:
241 return "IPC_MISC_TIME_INFO";
242 case IPC_MISC_DEBUG_LEVEL:
243 return "IPC_MISC_DEBUG_LEVEL";
245 return "IPC_SVC_ENTER";
247 return "IPC_SVC_END";
248 case IPC_SVC_PRO_KEYCODE:
249 return "IPC_SVC_PRO_KEYCODE";
250 case IPC_SVC_SCREEN_CFG:
251 return "IPC_SVC_SCREEN_CFG";
252 case IPC_SVC_DISPLAY_SCREEN:
253 return "IPC_SVC_DISPLAY_SCREEN";
254 case IPC_SVC_CHANGE_SVC_MODE:
255 return "IPC_SVC_CHANGE_SVC_MODE";
256 case IPC_SVC_DEVICE_TEST:
257 return "IPC_SVC_DEVICE_TEST";
258 case IPC_SVC_DEBUG_DUMP:
259 return "IPC_SVC_DEBUG_DUMP";
260 case IPC_SVC_DEBUG_STRING:
261 return "IPC_SVC_DEBUG_STRING";
263 return "IPC_SS_WAITING";
267 return "IPC_SS_BARRING";
268 case IPC_SS_BARRING_PW:
269 return "IPC_SS_BARRING_PW";
270 case IPC_SS_FORWARDING:
271 return "IPC_SS_FORWARDING";
273 return "IPC_SS_INFO";
274 case IPC_SS_MANAGE_CALL:
275 return "IPC_SS_MANAGE_CALL";
277 return "IPC_SS_USSD";
280 case IPC_SS_RELEASE_COMPLETE:
281 return "IPC_SS_RELEASE_COMPLETE";
282 case IPC_GPRS_DEFINE_PDP_CONTEXT:
283 return "IPC_GPRS_DEFINE_PDP_CONTEXT";
285 return "IPC_GPRS_QOS";
287 return "IPC_GPRS_PS";
288 case IPC_GPRS_PDP_CONTEXT:
289 return "IPC_GPRS_PDP_CONTEXT";
290 case IPC_GPRS_ENTER_DATA:
291 return "IPC_GPRS_ENTER_DATA";
292 case IPC_GPRS_SHOW_PDP_ADDR:
293 return "IPC_GPRS_SHOW_PDP_ADDR";
294 case IPC_GPRS_MS_CLASS:
295 return "IPC_GPRS_MS_CLASS";
296 case IPC_GPRS_3G_QUAL_SRVC_PROFILE:
297 return "IPC_GPRS_3G_QUAL_SRVC_PROFILE";
298 case IPC_GPRS_IP_CONFIGURATION:
299 return "IPC_GPRS_IP_CONFIGURATION";
300 case IPC_GPRS_DEFINE_SEC_PDP_CONTEXT:
301 return "IPC_GPRS_DEFINE_SEC_PDP_CONTEXT";
303 return "IPC_GPRS_TFT";
304 case IPC_GPRS_HSDPA_STATUS:
305 return "IPC_GPRS_HSDPA_STATUS";
306 case IPC_GPRS_CURRENT_SESSION_DATA_COUNTER:
307 return "IPC_GPRS_CURRENT_SESSION_DATA_COUNTER";
308 case IPC_GPRS_DATA_DORMANT:
309 return "IPC_GPRS_DATA_DORMANT";
310 case IPC_GPRS_PIN_CTRL:
311 return "IPC_GPRS_PIN_CTRL";
312 case IPC_GPRS_CALL_STATUS:
313 return "IPC_GPRS_CALL_STATUS";
314 case IPC_GPRS_PORT_LIST:
315 return "IPC_GPRS_PORT_LIST";
316 case IPC_SAT_PROFILE_DOWNLOAD:
317 return "IPC_SAT_PROFILE_DOWNLOAD";
318 case IPC_SAT_ENVELOPE_CMD:
319 return "IPC_SAT_ENVELOPE_CMD";
320 case IPC_SAT_PROACTIVE_CMD:
321 return "IPC_SAT_PROACTIVE_CMD";
322 case IPC_SAT_TERMINATE_USAT_SESSION:
323 return "IPC_SAT_TERMINATE_USAT_SESSION";
324 case IPC_SAT_EVENT_DOWNLOAD:
325 return "IPC_SAT_EVENT_DOWNLOAD";
326 case IPC_SAT_PROVIDE_LOCAL_INFO:
327 return "IPC_SAT_PROVIDE_LOCAL_INFO";
328 case IPC_SAT_POLLING:
329 return "IPC_SAT_POLLING";
330 case IPC_SAT_REFRESH:
331 return "IPC_SAT_REFRESH";
332 case IPC_SAT_SETUP_EVENT_LIST:
333 return "IPC_SAT_SETUP_EVENT_LIST";
334 case IPC_SAT_CALL_CONTROL_RESULT:
335 return "IPC_SAT_CALL_CONTROL_RESULT";
336 case IPC_SAT_IMAGE_CLUT:
337 return "IPC_SAT_IMAGE_CLUT";
338 case IPC_SAT_SETUP_CALL_PROCESSING:
339 return "IPC_SAT_SETUP_CALL_PROCESSING";
341 return "IPC_IMEI_START";
342 case IPC_IMEI_CHECK_DEVICE_INFO:
343 return "IPC_IMEI_CHECK_DEVICE_INFO";
344 case IPC_RFS_NV_READ_ITEM:
345 return "IPC_RFS_NV_READ_ITEM";
346 case IPC_RFS_NV_WRITE_ITEM:
347 return "IPC_RFS_NV_WRITE_ITEM";
348 case IPC_GEN_PHONE_RES:
349 return "IPC_GEN_PHONE_RES";
351 snprintf((char *) &command_string, sizeof(command_string), "0x%04x", command);
352 return command_string;
356 int ipc_data_dump(struct ipc_client *client, const void *data, size_t size)
358 unsigned int cols = 8;
359 unsigned int cols_count = 2;
366 unsigned int rollback;
367 unsigned int i, j, k;
370 if (data == NULL || size == 0)
373 // spacer = string length - offset print length - data print length - ascii print length
374 spacer = (sizeof(string) - 1) - 6 - (3 * cols * cols_count - 1 + (cols_count - 1)) - (cols * cols_count + cols_count - 1);
382 p = (unsigned char *) data;
385 while (offset < size) {
388 print = (char *) &string;
389 length = sizeof(string);
393 rc = snprintf(print, length, "[%04x]", offset);
399 for (i = 0; i < (unsigned int) spacer; i++) {
406 for (i = 0; i < cols_count; i++) {
407 for (j = 0; j < cols; j++) {
409 rc = snprintf(print, length, "%02X", *p);
417 for (k = 0; k < 2; k++) {
423 if (j != (cols - 1)) {
429 if (i != (cols_count - 1)) {
430 for (k = 0; k < 2; k++) {
439 for (i = 0; i < (unsigned int) spacer; i++) {
449 for (i = 0; i < cols_count; i++) {
450 for (j = 0; j < cols; j++) {
452 if (isascii(*p) && isprint(*p))
466 if (i != (cols_count - 1) && offset < size) {
474 ipc_client_log(client, string);
480 void ipc_client_log_send(struct ipc_client *client, struct ipc_message *message,
483 if (client == NULL || message == NULL || prefix == NULL)
486 switch (client->type) {
487 case IPC_CLIENT_TYPE_FMT:
488 ipc_client_log(client, "%s: Sent FMT message", prefix);
489 ipc_client_log(client, "%s: Message: mseq=0x%02x, command=%s, type=%s, size=%d", prefix, message->mseq, ipc_command_string(message->command), ipc_request_type_string(message->type), message->size);
491 if (message->size > 0) {
492 ipc_client_log(client, "================================= IPC FMT data =================================");
493 ipc_data_dump(client, (void *) message->data, message->size > 0x100 ? 0x100 : message->size);
494 ipc_client_log(client, "================================================================================");
498 case IPC_CLIENT_TYPE_RFS:
499 ipc_client_log(client, "%s: Sent RFS message", prefix);
500 ipc_client_log(client, "%s: Message: mseq=0x%02x, command=%s, size=%d", prefix, message->mseq, ipc_command_string(message->command), message->size);
502 if (message->size > 0) {
503 ipc_client_log(client, "================================= IPC RFS data =================================");
504 ipc_data_dump(client, (void *) message->data, message->size > 0x100 ? 0x100 : message->size);
505 ipc_client_log(client, "================================================================================");
512 void ipc_client_log_recv(struct ipc_client *client, struct ipc_message *message,
515 if (client == NULL || message == NULL || prefix == NULL)
518 switch (client->type) {
519 case IPC_CLIENT_TYPE_FMT:
520 ipc_client_log(client, "%s: Received FMT message", prefix);
521 ipc_client_log(client, "%s: Message: aseq=0x%02x, command=%s, type=%s, size=%d", prefix, message->aseq, ipc_command_string(message->command), ipc_response_type_string(message->type), message->size);
523 if (message->size > 0) {
524 ipc_client_log(client, "================================= IPC FMT data =================================");
525 ipc_data_dump(client, (void *) message->data, message->size > 0x100 ? 0x100 : message->size);
526 ipc_client_log(client, "================================================================================");
530 case IPC_CLIENT_TYPE_RFS:
531 ipc_client_log(client, "%s: Received RFS message", prefix);
532 ipc_client_log(client, "%s: Message: aseq=0x%02x, command=%s, size=%d", prefix, message->aseq, ipc_command_string(message->command), message->size);
534 if (message->size > 0) {
535 ipc_client_log(client, "================================= IPC RFS data =================================");
536 ipc_data_dump(client, (void *) message->data, message->size > 0x100 ? 0x100 : message->size);
537 ipc_client_log(client, "================================================================================");
544 int ipc_fmt_header_setup(struct ipc_fmt_header *header,
545 const struct ipc_message *message)
547 if (header == NULL || message == NULL)
550 memset(header, 0, sizeof(struct ipc_fmt_header));
551 header->length = message->size + sizeof(struct ipc_fmt_header);
552 header->mseq = message->mseq;
553 header->aseq = message->aseq;
554 header->group = IPC_GROUP(message->command);
555 header->index = IPC_INDEX(message->command);
556 header->type = message->type;
561 int ipc_fmt_message_setup(const struct ipc_fmt_header *header,
562 struct ipc_message *message)
564 if (header == NULL || message == NULL)
567 memset(message, 0, sizeof(struct ipc_message));
568 message->mseq = header->mseq;
569 message->aseq = header->aseq;
570 message->command = IPC_COMMAND(header->group, header->index);
571 message->type = header->type;
572 message->data = NULL;
578 int ipc_rfs_header_setup(struct ipc_rfs_header *header,
579 const struct ipc_message *message)
581 if (header == NULL || message == NULL)
584 memset(header, 0, sizeof(struct ipc_rfs_header));
585 header->length = message->size + sizeof(struct ipc_rfs_header);
586 header->id = message->mseq;
587 header->index = IPC_INDEX(message->command);
592 int ipc_rfs_message_setup(const struct ipc_rfs_header *header,
593 struct ipc_message *message)
595 if (header == NULL || message == NULL)
598 memset(message, 0, sizeof(struct ipc_message));
599 message->aseq = header->id;
600 message->command = IPC_COMMAND(IPC_GROUP_RFS, header->index);
601 message->data = NULL;
607 // vim:ts=4:sw=4:expandtab