Fix and place modem plugin in modems folder
[platform/core/telephony/tel-plugin-imc.git] / src / s_sat.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Chandan Swarup Patra <chandan.sp@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <tcore.h>
26 #include <hal.h>
27 #include <core_object.h>
28 #include <plugin.h>
29 #include <queue.h>
30 #include <server.h>
31 #include <co_sat.h>
32 #include <user_request.h>
33 #include <at.h>
34
35 #include "s_common.h"
36 #include "s_sat.h"
37 #define ENVELOPE_CMD_LEN        256
38
39 static TReturn s_terminal_response(CoreObject *o, UserRequest *ur);
40 static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data);      // from Kernel
41
42 static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data)
43 {
44         dbg("on_confirmation_modem_message_send - msg out from queue.\n");
45
46         if (result == FALSE) {
47                 /* Fail */
48                 dbg("SEND FAIL");
49         } else {
50                 dbg("SEND OK");
51         }
52 }
53
54 static gboolean on_response_terminal_response_confirm(CoreObject *o, const void *event_info, void *user_data)
55 {
56         dbg("Function Entry");
57         return TRUE;
58         dbg("Function Exit");
59 }
60
61 static gboolean on_event_sat_proactive_command(CoreObject *o, const void *event_info, void *user_data)
62 {
63         struct tcore_sat_proactive_command decoded_data;
64         struct tnoti_sat_proactive_ind proactive_noti;
65         int len_proactive_cmd = 0;
66         GSList *lines = NULL;
67         GSList *tokens = NULL;
68         char *line = NULL;
69         char *hexData = NULL;
70         char *tmp = NULL;
71         char *recordData = NULL;
72
73         dbg("Function Entry");
74
75         memset(&proactive_noti, 0x00, sizeof(struct tnoti_sat_proactive_ind));
76         memset(&decoded_data, 0x00, sizeof(struct tcore_sat_proactive_command));
77         lines = (GSList *) event_info;
78         line = (char *) lines->data;
79         tokens = tcore_at_tok_new(line);
80         if (g_slist_length(tokens) != 1) {
81                 dbg("invalid message");
82                 tcore_at_tok_free(tokens);
83                 return FALSE;
84         }
85         hexData = (char *) g_slist_nth_data(tokens, 0);
86
87         dbg("hexdata %s ", hexData);
88         dbg("hexdata length %d", strlen(hexData));
89
90         tmp = util_removeQuotes(hexData);
91         recordData = util_hexStringToBytes(tmp);
92         dbg("recordData: %x", recordData);
93         free(tmp);
94         util_hex_dump("    ", strlen(hexData) / 2, recordData);
95         len_proactive_cmd = strlen(recordData);
96         dbg("len_proactive_cmd = %d", len_proactive_cmd);
97         tcore_sat_decode_proactive_command((unsigned char *) recordData, (strlen(hexData) / 2) - 1, &decoded_data);
98         free(recordData);
99
100         proactive_noti.cmd_number = decoded_data.cmd_num;
101         proactive_noti.cmd_type = decoded_data.cmd_type;
102
103         switch (decoded_data.cmd_type) {
104         case SAT_PROATV_CMD_DISPLAY_TEXT:
105                 dbg("decoded command is display text!!");
106                 memcpy(&proactive_noti.proactive_ind_data.display_text, &decoded_data.data.display_text, sizeof(struct tel_sat_display_text_tlv));
107                 break;
108
109         case SAT_PROATV_CMD_GET_INKEY:
110                 dbg("decoded command is get inkey!!");
111                 memcpy(&proactive_noti.proactive_ind_data.get_inkey, &decoded_data.data.get_inkey, sizeof(struct tel_sat_get_inkey_tlv));
112                 break;
113
114         case SAT_PROATV_CMD_GET_INPUT:
115                 dbg("decoded command is get input!!");
116                 memcpy(&proactive_noti.proactive_ind_data.get_input, &decoded_data.data.get_input, sizeof(struct tel_sat_get_input_tlv));
117                 break;
118
119         case SAT_PROATV_CMD_MORE_TIME:
120                 dbg("decoded command is more time!!");
121                 memcpy(&proactive_noti.proactive_ind_data.more_time, &decoded_data.data.more_time, sizeof(struct tel_sat_more_time_tlv));
122                 break;
123
124         case SAT_PROATV_CMD_PLAY_TONE:
125                 dbg("decoded command is play tone!!");
126                 memcpy(&proactive_noti.proactive_ind_data.play_tone, &decoded_data.data.play_tone, sizeof(struct tel_sat_play_tone_tlv));
127                 break;
128
129         case SAT_PROATV_CMD_SETUP_MENU:
130                 dbg("decoded command is SETUP MENU!!");
131                 memcpy(&proactive_noti.proactive_ind_data.setup_menu, &decoded_data.data.setup_menu, sizeof(struct tel_sat_setup_menu_tlv));
132                 break;
133
134         case SAT_PROATV_CMD_SELECT_ITEM:
135                 dbg("decoded command is select item!!");
136                 memcpy(&proactive_noti.proactive_ind_data.select_item, &decoded_data.data.select_item, sizeof(struct tel_sat_select_item_tlv));
137                 break;
138
139         case SAT_PROATV_CMD_SEND_SMS:
140                 dbg("decoded command is send sms!!");
141                 memcpy(&proactive_noti.proactive_ind_data.send_sms, &decoded_data.data.send_sms, sizeof(struct tel_sat_send_sms_tlv));
142                 break;
143
144         case SAT_PROATV_CMD_SEND_SS:
145                 dbg("decoded command is send ss!!");
146                 memcpy(&proactive_noti.proactive_ind_data.send_ss, &decoded_data.data.send_ss, sizeof(struct tel_sat_send_ss_tlv));
147                 break;
148
149         case SAT_PROATV_CMD_SEND_USSD:
150                 dbg("decoded command is send ussd!!");
151                 memcpy(&proactive_noti.proactive_ind_data.send_ussd, &decoded_data.data.send_ussd, sizeof(struct tel_sat_send_ussd_tlv));
152                 break;
153
154         case SAT_PROATV_CMD_SETUP_CALL:
155                 dbg("decoded command is setup call!!");
156                 memcpy(&proactive_noti.proactive_ind_data.setup_call, &decoded_data.data.setup_call, sizeof(struct tel_sat_setup_call_tlv));
157                 break;
158
159         case SAT_PROATV_CMD_REFRESH:
160                 dbg("decoded command is refresh");
161                 memcpy(&proactive_noti.proactive_ind_data.refresh, &decoded_data.data.refresh, sizeof(struct tel_sat_refresh_tlv));
162                 break;
163
164         case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
165                 dbg("decoded command is provide local info");
166                 memcpy(&proactive_noti.proactive_ind_data.provide_local_info, &decoded_data.data.provide_local_info, sizeof(struct tel_sat_provide_local_info_tlv));
167                 break;
168
169         case SAT_PROATV_CMD_SETUP_EVENT_LIST:
170                 dbg("decoded command is setup event list!!");
171                 memcpy(&proactive_noti.proactive_ind_data.setup_event_list, &decoded_data.data.setup_event_list, sizeof(struct tel_sat_setup_event_list_tlv));
172                 // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
173                 break;
174
175         case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
176                 dbg("decoded command is setup idle mode text");
177                 memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text, &decoded_data.data.setup_idle_mode_text, sizeof(struct tel_sat_setup_idle_mode_text_tlv));
178                 break;
179
180         case SAT_PROATV_CMD_SEND_DTMF:
181                 dbg("decoded command is send dtmf");
182                 memcpy(&proactive_noti.proactive_ind_data.send_dtmf, &decoded_data.data.send_dtmf, sizeof(struct tel_sat_send_dtmf_tlv));
183                 break;
184
185         case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
186                 dbg("decoded command is language notification");
187                 memcpy(&proactive_noti.proactive_ind_data.language_notification, &decoded_data.data.language_notification, sizeof(struct tel_sat_language_notification_tlv));
188                 break;
189
190         case SAT_PROATV_CMD_LAUNCH_BROWSER:
191                 dbg("decoded command is launch browser");
192                 memcpy(&proactive_noti.proactive_ind_data.launch_browser, &decoded_data.data.launch_browser, sizeof(struct tel_sat_launch_browser_tlv));
193                 break;
194
195         case SAT_PROATV_CMD_OPEN_CHANNEL:
196                 dbg("decoded command is open channel!!");
197                 memcpy(&proactive_noti.proactive_ind_data.open_channel, &decoded_data.data.open_channel, sizeof(struct tel_sat_open_channel_tlv));
198                 break;
199
200         case SAT_PROATV_CMD_CLOSE_CHANNEL:
201                 dbg("decoded command is close channel!!");
202                 memcpy(&proactive_noti.proactive_ind_data.close_channel, &decoded_data.data.close_channel, sizeof(struct tel_sat_close_channel_tlv));
203                 break;
204
205         case SAT_PROATV_CMD_RECEIVE_DATA:
206                 dbg("decoded command is receive data!!");
207                 memcpy(&proactive_noti.proactive_ind_data.receive_data, &decoded_data.data.receive_data, sizeof(struct tel_sat_receive_channel_tlv));
208                 break;
209
210         case SAT_PROATV_CMD_SEND_DATA:
211                 dbg("decoded command is send data!!");
212                 memcpy(&proactive_noti.proactive_ind_data.send_data, &decoded_data.data.send_data, sizeof(struct tel_sat_send_channel_tlv));
213                 break;
214
215         case SAT_PROATV_CMD_GET_CHANNEL_STATUS:
216                 dbg("decoded command is get channel status!!");
217                 memcpy(&proactive_noti.proactive_ind_data.get_channel_status, &decoded_data.data.get_channel_status, sizeof(struct tel_sat_get_channel_status_tlv));
218                 break;
219
220         default:
221                 dbg("wrong input");
222                 break;
223         }
224         if ((decoded_data.cmd_type == SAT_PROATV_CMD_REFRESH) || (decoded_data.cmd_type == SAT_PROATV_CMD_SETUP_EVENT_LIST)) {
225                 /*Not supported*/
226                 dbg("Not suported Proactive command");
227                 return FALSE;
228         }
229         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_PROACTIVE_CMD,
230                                                                    sizeof(struct tnoti_sat_proactive_ind), &proactive_noti);
231         tcore_at_tok_free(tokens);
232         dbg("Function Exit");
233         return TRUE;
234 }
235
236 static void on_response_envelop_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
237 {
238         const TcoreATResponse *resp = data;
239         UserRequest *ur = NULL;
240         CoreObject *o = NULL;
241         const struct                treq_sat_envelop_cmd_data *req_data = NULL;
242         GSList *tokens = NULL;
243         struct                      tresp_sat_envelop_data res;
244         const char *line = NULL;
245         const char *env_res = NULL;
246         int sw2 = -1;
247
248         ur = tcore_pending_ref_user_request(p);
249         req_data = tcore_user_request_ref_data(ur, NULL);
250         o = tcore_pending_ref_core_object(p);
251
252         if (!req_data) {
253                 dbg("request data is NULL");
254                 return;
255         }
256         memset(&res, 0, sizeof(struct tresp_sat_envelop_data));
257
258         res.sub_cmd = req_data->sub_cmd;
259
260         if (resp->success > 0) {
261                 dbg("RESPONSE OK");
262                 if (resp->lines) {
263                         line = (const char *) resp->lines->data;
264                         tokens = tcore_at_tok_new(line);
265                         if (g_slist_length(tokens) < 1) {
266                                 msg("invalid message");
267                                 tcore_at_tok_free(tokens);
268                                 return;
269                         }
270                 }
271                 env_res = g_slist_nth_data(tokens, 0);
272                 res.result = 0x8000;
273                 res.envelop_resp = ENVELOPE_SUCCESS;
274                 dbg("RESPONSE OK 3");
275                 if (NULL != g_slist_nth_data(tokens, 1)) {
276                         sw2 = atoi(g_slist_nth_data(tokens, 1));
277                         dbg("RESPONSE OK 4");
278                         if (sw2 == 0) {
279                                 dbg("RESPONSE OK 5");
280                                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
281                         }
282                 }
283         } else {
284                 dbg("RESPONSE NOK");
285                 res.result = -1;
286                 res.envelop_resp = ENVELOPE_FAILED;
287         }
288
289         if (ur) {
290                 tcore_user_request_send_response(ur, TRESP_SAT_REQ_ENVELOPE, sizeof(struct tresp_sat_envelop_data), &res);
291         }
292         tcore_at_tok_free(tokens);
293         dbg(" Function exit");
294 }
295
296
297 static void on_response_terminal_response(TcorePending *p, int data_len, const void *data, void *user_data)
298 {
299         UserRequest *ur = NULL;
300         CoreObject *o = NULL;
301         const TcoreATResponse *resp = data;
302         gpointer tmp = NULL;
303
304         dbg("Function Entry");
305
306         if (resp->success > 0) {
307                 dbg("RESPONSE OK");
308                 dbg(" resp->success = %d", resp->success);
309                 ur = tcore_pending_ref_user_request(p);
310                 tmp = (gpointer) tcore_user_request_ref_communicator(ur);
311                 if (!ur || !tmp) {
312                         dbg("error - current ur is NULL");
313                         return;
314                 }
315
316                 o = tcore_pending_ref_core_object(p);
317                 if (!o)
318                         dbg("error - current sat core is NULL");
319                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
320         }
321         dbg("Function Exit");
322 }
323
324 static TReturn s_envelope(CoreObject *o, UserRequest *ur)
325 {
326         TcoreHal *hal;
327         TcoreATRequest *req = NULL;
328         TcorePending *pending = NULL;
329         char *cmd_str = NULL;
330         const struct            treq_sat_envelop_cmd_data *req_data = NULL;
331         int envelope_cmd_len = 0;
332         char envelope_cmd[ENVELOPE_CMD_LEN];
333         int count = 0;
334         char envelope_cmdhex[ENVELOPE_CMD_LEN * 2];
335         char *pbuffer = NULL;
336
337         dbg("Function Entry");
338         memset(&envelope_cmdhex, 0x00, sizeof(envelope_cmdhex));
339         pbuffer = envelope_cmdhex;
340
341         hal = tcore_object_get_hal(o);
342         if(FALSE == tcore_hal_get_power_state(hal)){
343                 dbg("cp not ready/n");
344                 return TCORE_RETURN_ENOSYS;
345         }
346
347         pending = tcore_pending_new(o, 0);
348         req_data = tcore_user_request_ref_data(ur, NULL);
349         dbg("new pending sub cmd(%d)", req_data->sub_cmd);
350
351         envelope_cmd_len = tcore_sat_encode_envelop_cmd(req_data, (char *) envelope_cmd);
352
353         dbg("envelope_cmd_len %d", envelope_cmd_len);
354         if (envelope_cmd_len == 0) {
355                 return TCORE_RETURN_EINVAL;
356         }
357         for (count = 0; count < envelope_cmd_len; count++) {
358                 dbg("envelope_cmd %02x", envelope_cmd[count]);
359                 sprintf(pbuffer, "%02x", envelope_cmd[count]);
360                 pbuffer += 2;
361         }
362         dbg("pbuffer %s", envelope_cmdhex);
363         cmd_str = g_strdup_printf("AT+SATE=\"%s\"", envelope_cmdhex);
364         req = tcore_at_request_new(cmd_str, "+SATE:", TCORE_AT_SINGLELINE);
365         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
366
367         tcore_pending_set_request_data(pending, 0, req);
368         tcore_pending_set_response_callback(pending, on_response_envelop_cmd, hal);
369         tcore_pending_link_user_request(pending, ur);
370         tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
371         tcore_hal_send_request(hal, pending);
372
373         g_free(cmd_str);
374         dbg("Function Exit");
375         return TCORE_RETURN_SUCCESS;
376 }
377
378 static TReturn s_terminal_response(CoreObject *o, UserRequest *ur)
379 {
380         TcoreHal *hal = NULL;
381         TcoreATRequest *req = NULL;
382         TcorePending *pending = NULL;
383         char *cmd_str = NULL;
384         const struct            treq_sat_terminal_rsp_data *req_data = NULL;
385         int proactive_resp_len = 0;
386         char proactive_resp[ENVELOPE_CMD_LEN];
387         char proactive_resphex[ENVELOPE_CMD_LEN * 2];
388         char *pbuffer = NULL;
389         int i = 0;
390         char *hexString = NULL;
391
392         dbg("Function Entry");
393         memset(&proactive_resphex, 0x00, sizeof(proactive_resphex));
394         pbuffer = proactive_resphex;
395         hal = tcore_object_get_hal(o);
396         if(FALSE == tcore_hal_get_power_state(hal)){
397                 dbg("cp not ready/n");
398                 return TCORE_RETURN_ENOSYS;
399         }
400
401         pending = tcore_pending_new(o, 0);
402         req_data = tcore_user_request_ref_data(ur, NULL);
403
404         proactive_resp_len = tcore_sat_encode_terminal_response(req_data, (char *) proactive_resp);
405         dbg("proactive_resp %s", proactive_resp);
406         dbg("proactive_resp length %d", strlen(proactive_resp));
407         if (proactive_resp_len == 0) {
408                 return TCORE_RETURN_EINVAL;
409         }
410         hexString = calloc((proactive_resp_len * 2) + 1, 1);
411
412         for (i = 0; i < proactive_resp_len * 2; i += 2) {
413                 char value = 0;
414                 value = (proactive_resp[i / 2] & 0xf0) >> 4;
415                 if (value < 0xA)
416                         hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + '0';
417                 else
418                         hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
419
420                 value = proactive_resp[i / 2] & 0x0f;
421                 if (value < 0xA)
422                         hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + '0';
423                 else
424                         hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + 'A' - 10;
425         }
426
427         dbg("hexString %s", hexString);
428         cmd_str = g_strdup_printf("AT+SATR=\"%s\"", hexString);
429
430         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
431         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
432
433         tcore_pending_set_request_data(pending, 0, req);
434         tcore_pending_set_response_callback(pending, on_response_terminal_response, hal);
435         tcore_pending_link_user_request(pending, ur);
436         tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
437         tcore_hal_send_request(hal, pending);
438
439         g_free(cmd_str);
440         dbg("Function Exit");
441         return TCORE_RETURN_SUCCESS;
442 }
443
444 static struct tcore_sat_operations sat_ops = {
445         .envelope = s_envelope,
446         .terminal_response = s_terminal_response,
447 };
448
449 gboolean s_sat_init(TcorePlugin *cp, CoreObject *co_sat)
450 {
451         dbg("Entry");
452
453         tcore_sat_override_ops(co_sat, &sat_ops);
454
455         tcore_object_override_callback(co_sat, "+SATI", on_event_sat_proactive_command, NULL);
456         tcore_object_override_callback(co_sat, "+SATN", on_event_sat_proactive_command, NULL);
457         tcore_object_override_callback(co_sat, "+SATF", on_response_terminal_response_confirm, NULL);
458
459         dbg("Exit");
460
461         return TRUE;
462 }
463
464 void s_sat_exit(TcorePlugin *cp, CoreObject *co_sat)
465 {
466         dbg("Exit");
467 }