SISO code cleanup & bug fix
[profile/ivi/tel-plugin-imc.git] / src / s_ps.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: Arun Shukla <arun.shukla@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 <unistd.h>\r
25 \r
26 #include <glib.h>\r
27 #include <fcntl.h>\r
28 #include <sys/ioctl.h>\r
29 \r
30 #include <tcore.h>\r
31 #include <hal.h>\r
32 #include <core_object.h>\r
33 #include <plugin.h>\r
34 #include <queue.h>\r
35 #include <co_ps.h>\r
36 #include <co_context.h>\r
37 #include <storage.h>\r
38 #include <server.h>\r
39 #include <at.h>\r
40 #include <util.h>\r
41 #include <type/ps.h>\r
42 \r
43 #include "s_common.h"\r
44 #include "s_ps.h"\r
45 \r
46 \r
47 \r
48 #define VNET_CH_PATH_BOOT0      "/dev/umts_boot0"\r
49 #define IOCTL_CG_DATA_SEND  _IO('o', 0x37)\r
50 \r
51 /*Invalid Session ID*/\r
52 #define PS_INVALID_CID  999 /*Need to check */\r
53 \r
54 /*Maximum String length Of the Command*/\r
55 #define MAX_AT_CMD_STR_LEN      150\r
56 \r
57 /*Command for PDP activation and Deactivation*/\r
58 #define AT_PDP_ACTIVATE 1\r
59 #define AT_PDP_DEACTIVATE 0\r
60 \r
61 #define AT_XDNS_ENABLE 1\r
62 #define AT_XDNS_DISABLE 0\r
63 #define AT_SESSION_DOWN 0\r
64 static void _ps_free(void * ptr)\r
65 {\r
66         dbg("Entered");\r
67         if(ptr)\r
68         {\r
69                 (void)free(ptr);\r
70                 ptr = NULL;\r
71         }\r
72         dbg("Exit");\r
73         return;\r
74 }\r
75 static void _unable_to_get_pending(CoreObject *co_ps,CoreObject *ps_context)\r
76 {\r
77         struct tnoti_ps_call_status data_resp = {0};\r
78         dbg("Entered");\r
79         data_resp.context_id = tcore_context_get_id(ps_context);\r
80         data_resp.state = AT_SESSION_DOWN;/*check value of state*/\r
81         data_resp.result =0xFF;/*check error value*/\r
82         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
83                 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);\r
84         (void)tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);\r
85         dbg("Exit");\r
86 }\r
87 static TReturn _pdp_device_control(unsigned int cid)\r
88 {\r
89         int fd = -1;\r
90         int ret = -1;\r
91         fd = open ( VNET_CH_PATH_BOOT0, O_RDWR );\r
92         if(fd < 0)\r
93         {\r
94                 dbg("error : open [ %s ] [ %s ]", VNET_CH_PATH_BOOT0, strerror(errno));\r
95                 return -1;\r
96         }\r
97         /*To Do for different Cids*/\r
98         dbg("Send IOCTL: arg 0x05 (0101) HSIC1, cid=%d \n",cid);\r
99         if(cid == 1)\r
100         {\r
101                 ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0x05);\r
102         }\r
103         else if(cid == 2)\r
104         {\r
105                 ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0xA);\r
106         }\r
107         else\r
108         {\r
109                 dbg("More Than 2 context are not supported right Now");\r
110         }\r
111         close(fd);\r
112         if (ret < 0)\r
113         {\r
114                 dbg("[ error ] send IOCTL_CG_DATA_SEND (0x%x) fail!! \n",IOCTL_CG_DATA_SEND);\r
115                 return TCORE_RETURN_FAILURE;\r
116         }\r
117         else\r
118         {\r
119                 dbg("[ ok ] send IOCTL_CG_DATA_SEND (0x%x) success!! \n",IOCTL_CG_DATA_SEND);\r
120                 return TCORE_RETURN_SUCCESS;\r
121         }\r
122 }\r
123 \r
124 static gboolean on_event_cgev_handle(CoreObject *co_ps, const void *data, void *user_data)\r
125 {\r
126 \r
127         char *token = NULL;\r
128         GSList *tokens= NULL;\r
129     GSList *lines = NULL;\r
130         const char *line = NULL;\r
131         char *noti_data = NULL;\r
132         int i = 0;\r
133         int value = 20;\r
134         int state = -1;\r
135         struct tnoti_ps_call_status data_resp = {0};\r
136 \r
137         dbg("Entered");\r
138         lines = (GSList*)data;\r
139         line = (const char *)lines->data;\r
140         dbg("Lines->data :-%s",line);\r
141 \r
142         tokens = tcore_at_tok_new(line);\r
143         switch(g_slist_length(tokens))\r
144         {\r
145                 case 0:\r
146                         {\r
147                                 dbg("No token present: Ignore +CGEV Notifications ");\r
148                                 return TRUE;\r
149                         }\r
150                         case 1:\r
151                         {\r
152                                 dbg("one Token present");\r
153                                 noti_data = g_slist_nth_data(tokens, 0);\r
154                                 dbg("notification data :-%s",noti_data);\r
155                                 if(0 ==  strcmp(noti_data,"ME CLASS B"))\r
156                                 {\r
157                                         dbg("ME Class B notification received");\r
158                                         goto ignore;\r
159                                 }\r
160                                 if(0 ==  strcmp(noti_data,"NW CLASS A"))\r
161                                 {\r
162                                         dbg("NW Class A notification received");\r
163                                         goto ignore;\r
164                                 }\r
165                                 token = strtok(noti_data, " ");\r
166                                 while(token != NULL)\r
167                                 {\r
168                                         if((i == 0) && (0!=  strcmp(token,"ME")))\r
169                                         {\r
170                                                 break;\r
171                                         }\r
172                                         if((i == 1) && (0!=  strcmp(token,"PDN")))\r
173                                         {\r
174                                                 break;\r
175                                         }\r
176                                         if((i == 2) && (0 ==  strcmp(token,"ACT")))\r
177                                         {\r
178                                                 state = 1;\r
179                                         }\r
180                                         if((i == 2) && (0 ==  strcmp(token,"DEACT")))\r
181                                         {\r
182                                                 state = 0;\r
183                                         }\r
184                                         if(i == 3 )\r
185                                         {\r
186                                                 value = atoi(token);\r
187                                                 break;\r
188                                         }\r
189                                         i++;\r
190                                         token = strtok(NULL, " ");\r
191                                 }\r
192                                 dbg("value:%d ",value);\r
193                                 i = 0;\r
194                                 break;\r
195                         }\r
196                         case 3:\r
197                         {\r
198                                 i = 0;\r
199                                 state = 0;\r
200                                 value = 0;\r
201                                 dbg("Three Token present");\r
202                                 noti_data = g_slist_nth_data(tokens, 0);\r
203                                 dbg("notification data :-%s",noti_data);\r
204                                 token = strtok(noti_data, " ");\r
205                                 while(token != NULL)\r
206                                 {\r
207                                         if((i == 0) && (0 ==  strcmp(token,"ME")))\r
208                                         {\r
209                                                 state = 1;\r
210                                         }\r
211                                         if((i == 1) && (0!=  strcmp(token,"DEACT")))\r
212                                         {\r
213                                                 break;\r
214                                         }\r
215                                         if((i == 2) && (0 ==  strcmp(token,"\"IP\"")) && (0 == state))\r
216                                         {\r
217                                                 dbg("MObile Deactiavted the Context");\r
218                                                 value = 10;\r
219                                                 break;\r
220                                         }\r
221                                         if((i == 2) && (0 ==  strcmp(token,"\"IP\"")) && (1 == state))\r
222                                         {\r
223                                                 dbg("NW Deactiavted the Context");\r
224                                                 value = 10;\r
225                                                 break;\r
226                                         }\r
227                                         i++;\r
228                                         token = strtok(NULL, " ");\r
229                                 }\r
230                                 if(value == 10 && state == 0)\r
231                                 {\r
232                                         dbg("Recieved Notification for Context deactivations from network");\r
233                                         noti_data = g_slist_nth_data(tokens, 1);\r
234                                         dbg("PDP Address :- %s",noti_data);\r
235                                         noti_data = g_slist_nth_data(tokens, 2);\r
236                                         dbg("CID got deactivated :- %d",atoi(noti_data));\r
237                                 }\r
238                                 if(value == 10 && state == 1)\r
239                                 {\r
240                                         dbg("Recieved Notification for Context deactivations from Mobile");\r
241                                         noti_data = g_slist_nth_data(tokens, 1);\r
242                                         dbg("PDP Address :- %s",noti_data);\r
243                                         noti_data = g_slist_nth_data(tokens, 2);\r
244                                         dbg("CID got deactivated :- %d",atoi(noti_data));\r
245                                 }\r
246                                 data_resp.context_id = atoi(noti_data);\r
247                                 data_resp.state = 3;/*check value of state*/\r
248                                 dbg("State of the service :- %d",data_resp.state);\r
249                                 data_resp.result =0xFF;/*check error value*/\r
250                                 dbg("Sending the notification");\r
251
252                                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
253                                 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);\r
254
255                                 state = 100;\r
256                                 value  = 100;\r
257                                 
258                                 break;\r
259                 }\r
260                 default:\r
261                 {\r
262                         dbg("Ignore +CGEV Notifications ");\r
263                 }\r
264         }\r
265         if(state == 1)\r
266         {\r
267                 dbg("Notification recieved for Activation of CID:-%d",value);\r
268         }\r
269         else if(state == 0)\r
270         {\r
271                 dbg("Notification recieved for Deactivation of CID:-%d",value);\r
272         }\r
273         else\r
274         {\r
275                 dbg("ignore");\r
276         }\r
277 ignore:\r
278         tcore_at_tok_free(tokens);\r
279         return TRUE;\r
280 }\r
281 \r
282 static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)\r
283 {\r
284         GSList *tokens=NULL;\r
285         const char *line = NULL;\r
286         int value = 0;\r
287         GSList *lines = NULL;\r
288         dbg("Entered");\r
289 \r
290         lines = (GSList*)data;\r
291         if (1 != g_slist_length(lines))\r
292         {\r
293                 dbg("unsolicited msg but multiple line");\r
294                 goto OUT;\r
295         }\r
296         line = (char*)(lines->data);\r
297         tokens = tcore_at_tok_new(line);\r
298         value = atoi(g_slist_nth_data(tokens, 0));\r
299 \r
300         /*\r
301         <status> may be\r
302         0: DUN activation in progress\r
303         1: DUN deactivation in progress\r
304         2: DUN activated\r
305         3: DUN deactivated\r
306         */\r
307         switch(value)\r
308         {\r
309                 case 0:/*Fall Through*/\r
310                 case 1:\r
311                 {\r
312                         break;\r
313                 }\r
314                 case 2:\r
315                 {\r
316                         /*To Do:- Fill Data structure : data*/\r
317                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,\r
318                         TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);\r
319                 }\r
320                 case 3:\r
321                 {\r
322                         /*To Do:- Fill Data structure : data*/\r
323                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,\r
324                         TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);\r
325                 }\r
326                 break;\r
327                 default:\r
328                 goto OUT;\r
329         }\r
330         OUT:\r
331         if(NULL!=tokens)\r
332         {\r
333                 tcore_at_tok_free(tokens);\r
334         }\r
335         return TRUE;\r
336 }\r
337 static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)\r
338 {\r
339         CoreObject *co_ps = NULL;\r
340         const TcoreATResponse *resp = data;\r
341         CoreObject *ps_context = user_data;\r
342         dbg("Entered");\r
343         co_ps = tcore_pending_ref_core_object(p);\r
344         if(resp->success)\r
345         {\r
346                 dbg("Response Ok");\r
347                 return;
348         }\r
349         dbg("Response NOk");\r
350         _unable_to_get_pending(co_ps,ps_context);\r
351         return;\r
352 }\r
353 \r
354 static void send_undefine_context_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
355 {\r
356         TcoreHal *hal = NULL;\r
357         TcorePending *pending = NULL;\r
358         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
359         int cid = 0;\r
360 \r
361         dbg("Entered");\r
362         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
363 \r
364         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
365         hal = tcore_object_get_hal(co_ps);\r
366 \r
367         /*Getting Context ID from Core Object*/\r
368         cid = tcore_context_get_id(ps_context);\r
369 \r
370         (void)sprintf(cmd_str, "AT+CGDCONT=%d",cid);\r
371         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
372                                         on_response_undefine_context_cmd,ps_context );\r
373         if(NULL == pending)\r
374         {\r
375                 err("Unable to get the create a AT request ");\r
376                 goto error;\r
377         }\r
378         tcore_hal_send_request(hal, pending);\r
379         dbg("Exit: Successfully");\r
380         return ;\r
381 error:\r
382         {\r
383                 dbg("Exit: With error");\r
384                 _unable_to_get_pending(co_ps,ps_context);\r
385                 return;\r
386         }\r
387 }\r
388 static void on_response_data_counter_command(TcorePending *p, int data_len, const void *data, void *user_data)\r
389 {\r
390         CoreObject *ps_context = user_data;\r
391         const TcoreATResponse *resp = data;\r
392         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
393 \r
394         GSList *tokens=NULL;\r
395         GSList *pRespData;\r
396         const char *line = NULL;\r
397         int no_pdp_active =0;\r
398         unsigned long long Rx;\r
399         unsigned long long Tx;\r
400         int cid = tcore_context_get_id(ps_context);\r
401         dbg("Entered");\r
402 \r
403         if(resp->final_response)\r
404         {\r
405                 dbg("Response OK");\r
406                 dbg(" response lines : -%s",resp->lines);\r
407                 if(resp->lines)\r
408                 {\r
409                         pRespData =  (GSList*)resp->lines;\r
410                         no_pdp_active = g_slist_length(pRespData);\r
411                         dbg("Total Number of Active PS Context :- %d",no_pdp_active);\r
412 \r
413                         if(no_pdp_active == 0)\r
414                         {\r
415                                 return;\r
416                         }\r
417                         while(pRespData)\r
418                         {\r
419                                 dbg("Entered the Loop pRespData");\r
420 \r
421                                 line = (const char*)pRespData->data;\r
422                                 dbg("Response->lines->data :%s",line);\r
423                                 tokens = tcore_at_tok_new(line);\r
424                                 if(cid == atoi(g_slist_nth_data(tokens, 0)))\r
425                                 {\r
426                                         dbg("Found the data for our CID");\r
427                                         Tx = (unsigned long long)g_ascii_strtoull((g_slist_nth_data(tokens,1)), NULL, 10);\r
428                                         dbg("Tx: %d", Tx);\r
429 \r
430                                         Rx = (unsigned long long)g_ascii_strtoull((g_slist_nth_data(tokens, 2)), NULL, 10);\r
431                                         dbg("Rx: %d", Rx);\r
432 \r
433                                         tcore_at_tok_free(tokens);\r
434                                         tokens = NULL;\r
435                                         dbg("Exiting the Loop pRespData");\r
436                                         break;\r
437                                 }\r
438                                 tcore_at_tok_free(tokens);\r
439                                 tokens = NULL;\r
440                                 pRespData= pRespData->next;\r
441 \r
442                         }\r
443                         dbg("Sending Data counter notifications");\r
444 \r
445                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
446                                 TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, 0, NULL);\r
447                         return;\r
448                 }\r
449                 else\r
450                 {\r
451                 dbg("No Active PS Context");\r
452                 }\r
453         }\r
454         dbg("Response NOK");\r
455 }\r
456 \r
457 static TReturn send_data_counter_command(CoreObject *co_ps,CoreObject *ps_context)\r
458 {\r
459         TcoreHal *hal = NULL;\r
460         TcorePending *pending = NULL;\r
461         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
462 \r
463         dbg("Enetered");\r
464         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
465 \r
466         hal = tcore_object_get_hal(co_ps);\r
467 \r
468         (void)sprintf(cmd_str, "AT+XGCNTRD");\r
469         pending = tcore_at_pending_new(co_ps,cmd_str,"+XGCNTRD",TCORE_AT_MULTILINE,\r
470                                         on_response_data_counter_command,ps_context );\r
471         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
472         {\r
473                 return TCORE_RETURN_SUCCESS;\r
474         }\r
475         _unable_to_get_pending(co_ps,ps_context);\r
476         return TCORE_RETURN_FAILURE;\r
477 /*Add code if unable to get the data usage*/\r
478 }\r
479 static void on_response_deactivate_ps_context(TcorePending *p, int data_len, const void *data, void *user_data)\r
480 {\r
481         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
482         CoreObject *ps_context = user_data;\r
483         const TcoreATResponse *resp = data;\r
484         int cid ;\r
485 \r
486         cid = tcore_context_get_id(ps_context);\r
487         if(resp->success)\r
488         {\r
489                 dbg("Response OK");\r
490                 /*get the data usage and report it application*/\r
491                 (void)send_data_counter_command(co_ps,ps_context);\r
492                 /*get the HSDPA status and report it to server*/\r
493         }\r
494         else\r
495         {\r
496                 dbg("Response NOK");\r
497                 send_undefine_context_cmd(co_ps,ps_context);\r
498         }\r
499         return;\r
500 }\r
501 \r
502 static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)\r
503 {\r
504         TcoreHal *hal = NULL;\r
505         TcorePending *pending = NULL;\r
506         unsigned int cid = PS_INVALID_CID;\r
507         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
508 \r
509         dbg("Entered");\r
510         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
511 \r
512         /*Getting Context ID from Core Object*/\r
513         cid = tcore_context_get_id(ps_context);\r
514 \r
515         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
516         hal = tcore_object_get_hal(co_ps);\r
517 \r
518         (void)sprintf(cmd_str, "AT+CGACT=%d,%d",AT_PDP_DEACTIVATE,cid);\r
519         dbg("At commands :- %s",cmd_str);\r
520 \r
521         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
522                                         on_response_deactivate_ps_context,ps_context );\r
523         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
524         {\r
525                 (void)tcore_context_set_state(ps_context,CONTEXT_STATE_DEACTIVATING);\r
526                 return TCORE_RETURN_SUCCESS;\r
527         }\r
528         _unable_to_get_pending(co_ps,ps_context);\r
529         return TCORE_RETURN_FAILURE;\r
530 }\r
531 \r
532 static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)\r
533 {\r
534 \r
535         struct tnoti_ps_pdp_ipconfiguration noti = {0};\r
536         struct tnoti_ps_call_status data_status = {0};\r
537         char devname[10] = {0,};\r
538         char *dns_prim = NULL;
539         char *dns_sec = NULL;
540         char *pdp_address = NULL;
541         char addr[4]= {0};\r
542         GSList *tokens=NULL;\r
543         GSList *pRespData;\r
544         const char *line = NULL;\r
545         char *token_dns = NULL;\r
546         char *token_add = NULL;\r
547 \r
548         char *token_pdp_address = NULL;\r
549         int no_pdp_active =0;\r
550         int index = 0;\r
551 \r
552         CoreObject *ps_context = user_data;\r
553         const TcoreATResponse *resp = data;\r
554         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
555         int cid = tcore_context_get_id(ps_context);\r
556 \r
557         dbg("Entered");\r
558 \r
559         if(resp->final_response)\r
560         {\r
561                 dbg("Response OK");\r
562                 if(resp->lines)\r
563                 {\r
564                         dbg("DNS data present in the Response");\r
565                         pRespData =  (GSList*)resp->lines;\r
566                         no_pdp_active = g_slist_length(pRespData);\r
567                         dbg("Total Number of Active PS Context :- %d",no_pdp_active);\r
568                         if(0 == no_pdp_active)\r
569                         {\r
570                                 goto exit_fail;\r
571                         }\r
572                         while(pRespData)\r
573                         {\r
574                                 dbg("traversing the DNS data for each active context");\r
575                                 line = (const char*)pRespData->data;\r
576                                 dbg("Response->lines->data :%s",line);\r
577                                 tokens = tcore_at_tok_new(line);\r
578                                 if(cid == atoi(g_slist_nth_data(tokens, 0)))\r
579                                 {\r
580                                         dbg("Found the DNS details for the Current context");\r
581                                         dbg("Context Id of The Context : %d",atoi(g_slist_nth_data(tokens, 0)));\r
582                                         break;\r
583                                 }\r
584                                 tcore_at_tok_free(tokens);\r
585                                 tokens = NULL;\r
586                                 pRespData= pRespData->next;\r
587                         }\r
588                         { /* Read primary DNS */\r
589                                 token_dns = g_slist_nth_data(tokens,1);\r
590                                 /* Strip off starting " and ending " from this token to read actual PDP address */\r
591                                 dns_prim = util_removeQuotes((void *)token_dns);
592                                 dbg("Token_dns :%s",token_dns);\r
593                                 dbg("Primary DNS :- %s",dns_prim);
594                                 index = 0;\r
595                                 token_add = strtok(dns_prim, ".");
596                                 while(token_add != NULL)\r
597                                 {\r
598                                         noti.primary_dns[index++]= atoi(token_add);\r
599                                         token_add = strtok(NULL, ".");\r
600                                 }\r
601                                 _ps_free(dns_prim);
602                         }\r
603                         { /* Read Secondary DNS */\r
604                                 token_add = NULL;\r
605                                 token_dns = g_slist_nth_data(tokens,2);\r
606                                 dns_sec = util_removeQuotes((void *)token_dns);
607 \r
608                                 dbg("Token_dns :%s",token_dns);\r
609                                 dbg("Secondary DNS :- %s",dns_sec);
610                                 index = 0;\r
611                                 token_add = strtok(dns_sec, ".");
612                                 while(token_add != NULL)\r
613                                 {\r
614                                         noti.secondary_dns[index++]= atoi(token_add);\r
615                                         token_add = strtok(NULL, ".");\r
616                                 }\r
617                                 _ps_free(dns_sec);
618                         }\r
619                         tcore_at_tok_free(tokens);\r
620                         tokens = NULL;\r
621                         goto exit_success;\r
622                 }\r
623                 else\r
624                 {\r
625                         dbg("No data present in the Response");\r
626                 }\r
627 \r
628         }\r
629         dbg("Response NOK");\r
630         exit_fail:\r
631         {\r
632                 dbg("Adding default DNS");\r
633                 dbg("Adding the Primary DNS");\r
634                 noti.primary_dns[0] = 8;\r
635                 noti.primary_dns[1] = 8;\r
636                 noti.primary_dns[2] = 8;\r
637                 noti.primary_dns[3] = 8;\r
638                 dbg("Adding Secondary DNS");\r
639                 noti.secondary_dns[0] = 8;\r
640                 noti.secondary_dns[1] = 8;\r
641                 noti.secondary_dns[2] = 4;\r
642                 noti.secondary_dns[3] = 4;\r
643         }\r
644         exit_success:\r
645         {\r
646                 dbg("Able to get the DNS from the DNS Query");\r
647                 token_pdp_address = tcore_context_get_address(ps_context);\r
648                 pdp_address = util_removeQuotes((void *)token_pdp_address);
649
650                 dbg("PDP address :- %s",pdp_address);\r
651                 /* Store IP address in char array, Telephony expected IP address in this format */\r
652                 token_add = strtok(pdp_address, ".");\r
653                 index = 0;\r
654                 while((token_add != NULL) && (index<4)) /* Currently only IPv4 is supported */\r
655                 {\r
656                         addr[index++]= atoi(token_add);\r
657                         token_add = strtok(NULL, ".");\r
658                 }\r
659                 _ps_free(pdp_address);
660                 _ps_free((void *)token_pdp_address);
661                 noti.field_flag = (0x0001 & 0x0002 & 0x0004);\r
662                 noti.err = 0;\r
663                 noti.context_id = cid;\r
664                 memcpy(&noti.ip_address, &addr, 4);\r
665                 if (_pdp_device_control(cid) != TCORE_RETURN_SUCCESS)\r
666                 {\r
667                         dbg("_pdp_device_control() failed. errno=%d", errno);\r
668                 }\r
669                 snprintf(devname, 10, "pdp%d", cid - 1);\r
670                 memcpy(noti.devname, devname, 10);\r
671                 dbg("devname = [%s]", devname);\r
672                 if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS)\r
673                 {\r
674                         dbg("util_netif_up() failed. errno=%d", errno);\r
675                 }\r
676 \r
677                 dbg("Send Notification upwards of IP address");\r
678                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps, TNOTI_PS_PDP_IPCONFIGURATION,\r
679                 sizeof(struct tnoti_ps_pdp_ipconfiguration), &noti);\r
680 \r
681                 data_status.context_id = cid;\r
682                 data_status.state = 1;\r
683                 data_status.result = 0 ;\r
684 \r
685                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
686                 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_status);\r
687                 dbg("EXIT : Without error");\r
688                 return;\r
689         }\r
690 }\r
691 \r
692 static TReturn send_get_dns_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
693 {\r
694         TcoreHal *hal = NULL;\r
695         TcorePending *pending = NULL;\r
696         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
697         \r
698         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
699 \r
700         dbg("Entered");\r
701         hal = tcore_object_get_hal(co_ps);\r
702 \r
703         (void)sprintf(cmd_str, "AT+XDNS?");\r
704         pending = tcore_at_pending_new(co_ps,cmd_str,"+XDNS",TCORE_AT_MULTILINE,\r
705                                         on_response_get_dns_cmnd,ps_context );\r
706         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
707         {\r
708                 return TCORE_RETURN_SUCCESS;\r
709         }\r
710         _unable_to_get_pending(co_ps,ps_context);\r
711         return TCORE_RETURN_FAILURE;\r
712 }\r
713 \r
714 static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)\r
715 {\r
716         const TcoreATResponse *resp = data;\r
717         CoreObject *co_ps =  tcore_pending_ref_core_object(p);\r
718         CoreObject *ps_context = user_data;\r
719         GSList *tokens=NULL;\r
720         const char *line;\r
721         char *token_pdp_address;\r
722         dbg("Enetered");\r
723         if(resp->final_response)\r
724         {\r
725                 dbg("RESPONSE OK");\r
726                 if(resp->lines != NULL)\r
727                 {\r
728                         dbg("resp->lines present ");\r
729                         line = (const char*)resp->lines->data;\r
730                         tokens = tcore_at_tok_new(line);\r
731                         if (g_slist_length(tokens) < 2)\r
732                         {\r
733                                 msg("invalid message");\r
734                                 goto error;\r
735                         }\r
736                         dbg("line:- %s",line);\r
737                         /* CID is already stored in ps_context, skip over & read PDP address */\r
738                         token_pdp_address = g_slist_nth_data(tokens, 1);\r
739 \r
740                         dbg("token_pdp_address :- %s",token_pdp_address);\r
741                         /* Strip off starting " and ending " from this token to read actual PDP address */\r
742                         (void)tcore_context_set_address(ps_context,(const char *)token_pdp_address);\r
743                 }\r
744 \r
745                 (void)send_get_dns_cmd(co_ps,ps_context);\r
746         }\r
747         else\r
748         {\r
749                 dbg("Response NOK");\r
750                 /*without PDP address we will not be able to start packet service*/\r
751                 (void)deactivate_ps_context(co_ps,ps_context,NULL);\r
752         }\r
753         error:\r
754         tcore_at_tok_free(tokens);\r
755         return;\r
756 }\r
757 \r
758 static TReturn send_get_pdp_address_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
759 {\r
760         TcoreHal *hal = NULL;\r
761         TcorePending *pending = NULL;\r
762         unsigned int cid = PS_INVALID_CID;\r
763         char cmd_str[MAX_AT_CMD_STR_LEN] = {0};\r
764 \r
765         dbg("Entered");\r
766         hal = tcore_object_get_hal(co_ps);\r
767 \r
768         cid = tcore_context_get_id(ps_context);\r
769         (void)sprintf(cmd_str, "AT+CGPADDR=%d",cid);\r
770         pending = tcore_at_pending_new(co_ps,cmd_str,"+CGPADDR",TCORE_AT_SINGLELINE,\r
771         on_response_get_pdp_address,ps_context );\r
772         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
773         {\r
774                 return TCORE_RETURN_SUCCESS;\r
775         }\r
776         _unable_to_get_pending(co_ps,ps_context);\r
777         return TCORE_RETURN_FAILURE;\r
778 }\r
779 \r
780 static void on_response_send_pdp_activate_cmd (TcorePending *p, int data_len, const void *data, void *user_data)\r
781 {\r
782         CoreObject *co_ps = NULL;\r
783         const TcoreATResponse *resp = data;\r
784         CoreObject *ps_context = user_data;\r
785 \r
786         int cid;\r
787         cid = tcore_context_get_id(ps_context);\r
788 \r
789 \r
790         dbg("Entered");\r
791         if(!p)\r
792         {\r
793                 goto error;\r
794         }\r
795         co_ps = tcore_pending_ref_core_object(p);\r
796 \r
797         if(resp->success)\r
798         {\r
799                 dbg("Response Ok");\r
800                 /*getting the IP address and DNS from the modem*/\r
801                 dbg("Getting the IP Address");\r
802                 (void)send_get_pdp_address_cmd(co_ps,ps_context);\r
803                 return;\r
804         }\r
805         else\r
806         {\r
807 \r
808                 dbg("Unable to actiavte PDP context for CID: %d ",cid);\r
809                 dbg("Undefineing the PDP context");\r
810                 (void)tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);\r
811                 send_undefine_context_cmd(co_ps,ps_context);\r
812                 return;\r
813         }\r
814 error:\r
815         {\r
816                 _unable_to_get_pending(co_ps,ps_context);\r
817                 return;\r
818         }\r
819 }\r
820 \r
821 static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)\r
822 {\r
823         TcoreHal *hal = NULL;\r
824         TcorePending *pending = NULL;\r
825         char cmd_str[MAX_AT_CMD_STR_LEN] = {0};\r
826         int cid = 0;\r
827         dbg("Entered");\r
828         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
829         hal = tcore_object_get_hal(co_ps);\r
830 \r
831         /*Getting Context ID from Core Object*/\r
832         cid = tcore_context_get_id(ps_context);\r
833         (void)sprintf(cmd_str, "AT+CGACT=%d,%d",AT_PDP_ACTIVATE,cid);\r
834         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
835                                         on_response_send_pdp_activate_cmd,ps_context);\r
836         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
837         {\r
838                 return TCORE_RETURN_SUCCESS;\r
839         }\r
840         _unable_to_get_pending(co_ps,ps_context);\r
841         return TCORE_RETURN_FAILURE;\r
842 }\r
843 \r
844 static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)\r
845 {\r
846         TcoreATResponse *resp = (TcoreATResponse *)data;\r
847         CoreObject *co_ps =  tcore_pending_ref_core_object(p);\r
848         CoreObject *ps_context = user_data;\r
849         dbg("Entered");\r
850         if(resp->success)\r
851         {\r
852                 dbg("Response OK");\r
853                 dbg("DNS address getting is Enabled");\r
854         }\r
855         else\r
856         {\r
857                 dbg("Response NOK");\r
858                 /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/\r
859         }\r
860         (void)send_pdp_activate_cmd(co_ps,ps_context);\r
861         return;\r
862 }\r
863 \r
864 static TReturn send_xdns_enable_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
865 {\r
866         TcoreHal *hal = NULL;\r
867         TcorePending *pending = NULL;\r
868         int cid = -1 ;\r
869         char cmd_str[MAX_AT_CMD_STR_LEN];\r
870 \r
871         dbg("Entered");\r
872         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
873 \r
874         hal = tcore_object_get_hal(co_ps);\r
875         cid = tcore_context_get_id(ps_context);\r
876 \r
877         (void)sprintf(cmd_str, "AT+XDNS=%d,%d",cid,AT_XDNS_ENABLE);\r
878         pending = tcore_at_pending_new(co_ps,cmd_str, NULL, TCORE_AT_NO_RESULT,\r
879                                         on_response_xdns_enable_cmd, ps_context);\r
880         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
881         {\r
882                 return TCORE_RETURN_SUCCESS;\r
883         }\r
884         _unable_to_get_pending(co_ps,ps_context);\r
885         return TCORE_RETURN_FAILURE;\r
886 }\r
887 \r
888 static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)\r
889 {\r
890         const TcoreATResponse *resp = data;\r
891         CoreObject *ps_context = (CoreObject *)user_data;\r
892         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
893 \r
894         dbg("Entered");\r
895         if(resp->success)\r
896         {\r
897                 dbg("Response OK");\r
898                 send_xdns_enable_cmd(co_ps,ps_context);\r
899         }\r
900         else\r
901         {\r
902                 dbg("response NOK");\r
903                 _unable_to_get_pending(co_ps,ps_context);\r
904                 dbg("Exiting");\r
905         }\r
906         return;\r
907         \r
908 }\r
909 \r
910 static TReturn send_define_pdp_context_cmd(CoreObject *co_ps, CoreObject *ps_context)\r
911 {\r
912         TcoreHal *hal = NULL;\r
913         TcorePending *pending = NULL;\r
914         char *apn = NULL;\r
915         char cmd_str[MAX_AT_CMD_STR_LEN] ={0} ;\r
916         char pdp_type_str[10] = {0};\r
917         unsigned int cid = PS_INVALID_CID;\r
918         enum co_context_type pdp_type;\r
919         enum co_context_d_comp d_comp;\r
920         enum co_context_h_comp h_comp;\r
921 \r
922         dbg("Entered");\r
923 \r
924         cid = tcore_context_get_id(ps_context);\r
925         pdp_type = tcore_context_get_type(ps_context);\r
926         d_comp = tcore_context_get_data_compression(ps_context);\r
927         h_comp = tcore_context_get_header_compression(ps_context);\r
928         apn = tcore_context_get_apn(ps_context);\r
929 \r
930         hal = tcore_object_get_hal(co_ps);\r
931         switch(pdp_type)\r
932         {\r
933                 case CONTEXT_TYPE_X25:\r
934                 {\r
935                         dbg("CONTEXT_TYPE_X25");\r
936                         strcpy(pdp_type_str,"X.25");\r
937                         break;\r
938                 }\r
939                 case CONTEXT_TYPE_IP:\r
940                 {\r
941                         dbg("CONTEXT_TYPE_IP");\r
942                         strcpy(pdp_type_str,"IP");\r
943                 }\r
944                 break;\r
945                 case CONTEXT_TYPE_PPP:\r
946                 {\r
947                         dbg("CONTEXT_TYPE_PPP");\r
948                         strcpy(pdp_type_str,"PPP");\r
949                 }\r
950                 break;\r
951                 case CONTEXT_TYPE_IPV6:\r
952                 {\r
953                         dbg("CONTEXT_TYPE_IPV6");\r
954                         strcpy(pdp_type_str,"IPV6");\r
955                         break;\r
956                 }\r
957                 default :\r
958                 {\r
959                         /*PDP Type not supported supported*/\r
960                         dbg("Unsupported PDP type :- %d returning ",pdp_type);\r
961                         return TCORE_RETURN_FAILURE;\r
962                 }\r
963         }\r
964         dbg("Activating context for CID :- %d",cid);\r
965                 (void)sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d",cid,pdp_type_str,apn,d_comp,h_comp);\r
966         
967         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
968                                         on_response_define_pdp_context,ps_context );\r
969         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
970         {\r
971                 (void)tcore_context_set_state(ps_context,CONTEXT_STATE_ACTIVATING);\r
972                 return TCORE_RETURN_SUCCESS;\r
973         }\r
974         _unable_to_get_pending(co_ps,ps_context);\r
975         return TCORE_RETURN_FAILURE;\r
976 }\r
977 \r
978 static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)\r
979 {\r
980         dbg("Entered");\r
981         return send_define_pdp_context_cmd(co_ps,ps_context);\r
982 }\r
983 \r
984 \r
985 static struct tcore_ps_operations ps_ops =\r
986 {\r
987         .activate_context = activate_ps_context,\r
988         .deactivate_context = deactivate_ps_context\r
989 };\r
990 \r
991 gboolean s_ps_init(TcorePlugin *p,TcoreHal *hal)\r
992 {\r
993         CoreObject *o;\r
994         struct context *context_table = NULL;\r
995 \r
996         dbg("Entered");\r
997         o = tcore_ps_new(p,"umts_ps", &ps_ops, hal);\r
998 \r
999         if (!o)\r
1000                 return FALSE;\r
1001         tcore_object_link_user_data(o, (void *)context_table);\r
1002 \r
1003         tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle,p);\r
1004         tcore_object_add_callback(o, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, p);\r
1005 \r
1006         dbg("Exiting");\r
1007         return TRUE;\r
1008 }\r
1009 \r
1010 void s_ps_exit(TcorePlugin *p)\r
1011 {\r
1012         CoreObject *o;\r
1013 \r
1014         dbg("Entered");\r
1015         o = tcore_plugin_ref_core_object(p,"umts_ps");\r
1016         if (!o)\r
1017                 return;\r
1018 \r
1019         tcore_ps_free(o);\r
1020         dbg("Exiting");\r
1021 }\r
1022 \r
1023 \r