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