Fix build error and do Boiler Plate.
[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                                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
252                                 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);\r
253                                 state = 100;\r
254                                 value  = 100;\r
255                                 break;\r
256                 }\r
257                 default:\r
258                 {\r
259                         dbg("Ignore +CGEV Notifications ");\r
260                 }\r
261         }\r
262         if(state == 1)\r
263         {\r
264                 dbg("Notification recieved for Activation of CID:-%d",value);\r
265         }\r
266         else if(state == 0)\r
267         {\r
268                 dbg("Notification recieved for Deactivation of CID:-%d",value);\r
269         }\r
270         else\r
271         {\r
272                 dbg("ignore");\r
273         }\r
274 ignore:\r
275         tcore_at_tok_free(tokens);\r
276         return TRUE;\r
277 }\r
278 \r
279 static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)\r
280 {\r
281         GSList *tokens=NULL;\r
282         const char *line = NULL;\r
283         int value = 0;\r
284         GSList *lines = NULL;\r
285         dbg("Entered");\r
286 \r
287         lines = (GSList*)data;\r
288         if (1 != g_slist_length(lines))\r
289         {\r
290                 dbg("unsolicited msg but multiple line");\r
291                 goto OUT;\r
292         }\r
293         line = (char*)(lines->data);\r
294         tokens = tcore_at_tok_new(line);\r
295         value = atoi(g_slist_nth_data(tokens, 0));\r
296 \r
297         /*\r
298         <status> may be\r
299         0: DUN activation in progress\r
300         1: DUN deactivation in progress\r
301         2: DUN activated\r
302         3: DUN deactivated\r
303         */\r
304         switch(value)\r
305         {\r
306                 case 0:/*Fall Through*/\r
307                 case 1:\r
308                 {\r
309                         break;\r
310                 }\r
311                 case 2:\r
312                 {\r
313                         /*To Do:- Fill Data structure : data*/\r
314                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,\r
315                         TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);\r
316                 }\r
317                 case 3:\r
318                 {\r
319                         /*To Do:- Fill Data structure : data*/\r
320                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,\r
321                         TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);\r
322                 }\r
323                 break;\r
324                 default:\r
325                 goto OUT;\r
326         }\r
327         OUT:\r
328         if(NULL!=tokens)\r
329         {\r
330                 tcore_at_tok_free(tokens);\r
331         }\r
332         return TRUE;\r
333 }\r
334 static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)\r
335 {\r
336         CoreObject *co_ps = NULL;\r
337         const TcoreATResponse *resp = data;\r
338         CoreObject *ps_context = user_data;\r
339         dbg("Entered");\r
340         co_ps = tcore_pending_ref_core_object(p);\r
341         if(resp->success)\r
342         {\r
343                 dbg("Response Ok");\r
344                 /*getting the IP address and DNS from the modem*/\r
345         }\r
346         dbg("Response NOk");\r
347         _unable_to_get_pending(co_ps,ps_context);\r
348         return;\r
349 }\r
350 \r
351 static void send_undefine_context_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
352 {\r
353         TcoreHal *hal = NULL;\r
354         TcorePending *pending = NULL;\r
355         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
356         int cid = 0;\r
357 \r
358         dbg("Entered");\r
359         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
360 \r
361         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
362         hal = tcore_object_get_hal(co_ps);\r
363 \r
364         /*Getting Context ID from Core Object*/\r
365         cid = tcore_context_get_id(ps_context);\r
366 \r
367         (void)sprintf(cmd_str, "AT+CGDCONT=%d",cid);\r
368         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
369                                         on_response_undefine_context_cmd,ps_context );\r
370         if(NULL == pending)\r
371         {\r
372                 err("Unable to get the create a AT request ");\r
373                 goto error;\r
374         }\r
375         tcore_hal_send_request(hal, pending);\r
376         dbg("Exit: Successfully");\r
377         return ;\r
378 error:\r
379         {\r
380                 dbg("Exit: With error");\r
381                 _unable_to_get_pending(co_ps,ps_context);\r
382                 return;\r
383         }\r
384 }\r
385 static void on_response_data_counter_command(TcorePending *p, int data_len, const void *data, void *user_data)\r
386 {\r
387         CoreObject *ps_context = user_data;\r
388         const TcoreATResponse *resp = data;\r
389         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
390 \r
391         GSList *tokens=NULL;\r
392         GSList *pRespData;\r
393         const char *line = NULL;\r
394         int no_pdp_active =0;\r
395         unsigned long long Rx;\r
396         unsigned long long Tx;\r
397         int cid = tcore_context_get_id(ps_context);\r
398         dbg("Entered");\r
399 \r
400         if(resp->final_response)\r
401         {\r
402                 dbg("Response OK");\r
403                 dbg(" response lines : -%s",resp->lines);\r
404                 if(resp->lines)\r
405                 {\r
406                         pRespData =  (GSList*)resp->lines;\r
407                         no_pdp_active = g_slist_length(pRespData);\r
408                         dbg("Total Number of Active PS Context :- %d",no_pdp_active);\r
409 \r
410                         if(no_pdp_active == 0)\r
411                         {\r
412                                 return;\r
413                         }\r
414                         while(pRespData)\r
415                         {\r
416                                 dbg("Entered the Loop pRespData");\r
417 \r
418                                 line = (const char*)pRespData->data;\r
419                                 dbg("Response->lines->data :%s",line);\r
420                                 tokens = tcore_at_tok_new(line);\r
421                                 if(cid == atoi(g_slist_nth_data(tokens, 0)))\r
422                                 {\r
423                                         dbg("Found the data for our CID");\r
424                                         Tx = (unsigned long long)g_ascii_strtoull((g_slist_nth_data(tokens,1)), NULL, 10);\r
425                                         dbg("Tx: %d", Tx);\r
426 \r
427                                         Rx = (unsigned long long)g_ascii_strtoull((g_slist_nth_data(tokens, 2)), NULL, 10);\r
428                                         dbg("Rx: %d", Rx);\r
429 \r
430                                         tcore_at_tok_free(tokens);\r
431                                         tokens = NULL;\r
432                                         dbg("Exiting the Loop pRespData");\r
433                                         break;\r
434                                 }\r
435                                 tcore_at_tok_free(tokens);\r
436                                 tokens = NULL;\r
437                                 pRespData= pRespData->next;\r
438 \r
439                         }\r
440                         dbg("Sending Data counter notifications");\r
441 \r
442                         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
443                                 TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, 0, NULL);\r
444                         return;\r
445                 }\r
446                 else\r
447                 {\r
448                 dbg("No Active PS Context");\r
449                 }\r
450         }\r
451         dbg("Response NOK");\r
452 }\r
453 \r
454 static TReturn send_data_counter_command(CoreObject *co_ps,CoreObject *ps_context)\r
455 {\r
456         TcoreHal *hal = NULL;\r
457         TcorePending *pending = NULL;\r
458         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
459 \r
460         dbg("Enetered");\r
461         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
462 \r
463         hal = tcore_object_get_hal(co_ps);\r
464 \r
465         (void)sprintf(cmd_str, "AT+XGCNTRD");\r
466         pending = tcore_at_pending_new(co_ps,cmd_str,"+XGCNTRD",TCORE_AT_MULTILINE,\r
467                                         on_response_data_counter_command,ps_context );\r
468         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
469         {\r
470                 return TCORE_RETURN_SUCCESS;\r
471         }\r
472         _unable_to_get_pending(co_ps,ps_context);\r
473         return TCORE_RETURN_FAILURE;\r
474 /*Add code if unable to get the data usage*/\r
475 }\r
476 static void on_response_deactivate_ps_context(TcorePending *p, int data_len, const void *data, void *user_data)\r
477 {\r
478         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
479         CoreObject *ps_context = user_data;\r
480         const TcoreATResponse *resp = data;\r
481         int cid ;\r
482 \r
483         cid = tcore_context_get_id(ps_context);\r
484         if(resp->success)\r
485         {\r
486                 dbg("Response OK");\r
487                 /*get the data usage and report it application*/\r
488                 (void)send_data_counter_command(co_ps,ps_context);\r
489                 /*get the HSDPA status and report it to server*/\r
490         }\r
491         else\r
492         {\r
493                 dbg("Response NOK");\r
494                 send_undefine_context_cmd(co_ps,ps_context);\r
495         }\r
496         return;\r
497 }\r
498 \r
499 static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)\r
500 {\r
501         TcoreHal *hal = NULL;\r
502         TcorePending *pending = NULL;\r
503         unsigned int cid = PS_INVALID_CID;\r
504         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
505 \r
506         dbg("Entered");\r
507         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
508 \r
509         /*Getting Context ID from Core Object*/\r
510         cid = tcore_context_get_id(ps_context);\r
511 \r
512         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
513         hal = tcore_object_get_hal(co_ps);\r
514 \r
515         (void)sprintf(cmd_str, "AT+CGACT=%d,%d",AT_PDP_DEACTIVATE,cid);\r
516         dbg("At commands :- %s",cmd_str);\r
517 \r
518         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
519                                         on_response_deactivate_ps_context,ps_context );\r
520         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
521         {\r
522                 (void)tcore_context_set_state(ps_context,CONTEXT_STATE_DEACTIVATING);\r
523                 return TCORE_RETURN_SUCCESS;\r
524         }\r
525         _unable_to_get_pending(co_ps,ps_context);\r
526         return TCORE_RETURN_FAILURE;\r
527 }\r
528 \r
529 static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)\r
530 {\r
531 \r
532         struct tnoti_ps_pdp_ipconfiguration noti = {0};\r
533         struct tnoti_ps_call_status data_status = {0};\r
534         char devname[10] = {0,};\r
535         char dns[50] = {0}; /* 3 characted for each IP address value: 12 for IPv4, 48 for IP6*/\r
536         char pdp_address[50]={0};\r
537         char addr[4]= {0};\r
538         GSList *tokens=NULL;\r
539         GSList *pRespData;\r
540         const char *line = NULL;\r
541         char *token_dns = NULL;\r
542         char *token_add = NULL;\r
543 \r
544         char *token_pdp_address = NULL;\r
545         int no_pdp_active =0;\r
546         int index = 0;\r
547 \r
548         CoreObject *ps_context = user_data;\r
549         const TcoreATResponse *resp = data;\r
550         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
551         int cid = tcore_context_get_id(ps_context);\r
552 \r
553         dbg("Entered");\r
554 \r
555         if(resp->final_response)\r
556         {\r
557                 dbg("Response OK");\r
558                 if(resp->lines)\r
559                 {\r
560                         dbg("DNS data present in the Response");\r
561                         pRespData =  (GSList*)resp->lines;\r
562                         no_pdp_active = g_slist_length(pRespData);\r
563                         dbg("Total Number of Active PS Context :- %d",no_pdp_active);\r
564                         if(0 == no_pdp_active)\r
565                         {\r
566                                 goto exit_fail;\r
567                         }\r
568                         while(pRespData)\r
569                         {\r
570                                 dbg("traversing the DNS data for each active context");\r
571                                 line = (const char*)pRespData->data;\r
572                                 dbg("Response->lines->data :%s",line);\r
573                                 tokens = tcore_at_tok_new(line);\r
574                                 if(cid == atoi(g_slist_nth_data(tokens, 0)))\r
575                                 {\r
576                                         dbg("Found the DNS details for the Current context");\r
577                                         dbg("Context Id of The Context : %d",atoi(g_slist_nth_data(tokens, 0)));\r
578                                         break;\r
579                                 }\r
580                                 tcore_at_tok_free(tokens);\r
581                                 tokens = NULL;\r
582                                 pRespData= pRespData->next;\r
583                         }\r
584                         { /* Read primary DNS */\r
585                                 token_dns = g_slist_nth_data(tokens,1);\r
586                                 /* Strip off starting " and ending " from this token to read actual PDP address */\r
587                                 strncpy(dns, token_dns+1, strlen(token_dns)-2);\r
588                                 dbg("Token_dns :%s",token_dns);\r
589                                 dbg("Primary DNS :- %s",dns);\r
590                                 index = 0;\r
591                                 token_add = strtok(dns, ".");\r
592                                 while(token_add != NULL)\r
593                                 {\r
594                                         noti.primary_dns[index++]= atoi(token_add);\r
595                                         token_add = strtok(NULL, ".");\r
596                                 }\r
597                         }\r
598                         { /* Read Secondary DNS */\r
599                                 memset(dns,0x0,50);\r
600                                 token_add = NULL;\r
601                                 token_dns = g_slist_nth_data(tokens,2);\r
602                                 /* Strip off starting " and ending " from this token to read actual PDP address */\r
603                                 strncpy(dns, token_dns+1, strlen(token_dns)-2);\r
604 \r
605                                 dbg("Token_dns :%s",token_dns);\r
606                                 dbg("Secondary DNS :- %s",dns);\r
607                                 index = 0;\r
608                                 token_add = strtok(dns, ".");\r
609                                 while(token_add != NULL)\r
610                                 {\r
611                                         noti.secondary_dns[index++]= atoi(token_add);\r
612                                         token_add = strtok(NULL, ".");\r
613                                 }\r
614                         }\r
615                         tcore_at_tok_free(tokens);\r
616                         tokens = NULL;\r
617                         goto exit_success;\r
618                 }\r
619                 else\r
620                 {\r
621                         dbg("No data present in the Response");\r
622                 }\r
623 \r
624         }\r
625         dbg("Response NOK");\r
626         exit_fail:\r
627         {\r
628                 dbg("Adding default DNS");\r
629                 dbg("Adding the Primary DNS");\r
630                 noti.primary_dns[0] = 8;\r
631                 noti.primary_dns[1] = 8;\r
632                 noti.primary_dns[2] = 8;\r
633                 noti.primary_dns[3] = 8;\r
634                 dbg("Adding Secondary DNS");\r
635                 noti.secondary_dns[0] = 8;\r
636                 noti.secondary_dns[1] = 8;\r
637                 noti.secondary_dns[2] = 4;\r
638                 noti.secondary_dns[3] = 4;\r
639         }\r
640         exit_success:\r
641         {\r
642                 dbg("Able to get the DNS from the DNS Query");\r
643                 token_pdp_address = tcore_context_get_address(ps_context);\r
644                 strncpy(pdp_address, token_pdp_address+1, strlen(token_pdp_address)-2);\r
645                 _ps_free((void *)token_pdp_address);\r
646                 dbg("PDP address :- %s",pdp_address);\r
647                 /* Store IP address in char array, Telephony expected IP address in this format */\r
648                 token_add = strtok(pdp_address, ".");\r
649                 index = 0;\r
650                 while((token_add != NULL) && (index<4)) /* Currently only IPv4 is supported */\r
651                 {\r
652                         addr[index++]= atoi(token_add);\r
653                         token_add = strtok(NULL, ".");\r
654                 }\r
655                 noti.field_flag = (0x0001 & 0x0002 & 0x0004);\r
656                 noti.err = 0;\r
657                 noti.context_id = cid;\r
658                 memcpy(&noti.ip_address, &addr, 4);\r
659                 if (_pdp_device_control(cid) != TCORE_RETURN_SUCCESS)\r
660                 {\r
661                         dbg("_pdp_device_control() failed. errno=%d", errno);\r
662                 }\r
663                 snprintf(devname, 10, "pdp%d", cid - 1);\r
664                 memcpy(noti.devname, devname, 10);\r
665                 dbg("devname = [%s]", devname);\r
666                 if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS)\r
667                 {\r
668                         dbg("util_netif_up() failed. errno=%d", errno);\r
669                 }\r
670 \r
671                 dbg("Send Notification upwards of IP address");\r
672                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps, TNOTI_PS_PDP_IPCONFIGURATION,\r
673                 sizeof(struct tnoti_ps_pdp_ipconfiguration), &noti);\r
674 \r
675                 data_status.context_id = cid;\r
676                 data_status.state = 1;\r
677                 data_status.result = 0 ;\r
678 \r
679                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,\r
680                 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_status);\r
681                 dbg("EXIT : Without error");\r
682                 return;\r
683         }\r
684 }\r
685 \r
686 static TReturn send_get_dns_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
687 {\r
688         TcoreHal *hal = NULL;\r
689         TcorePending *pending = NULL;\r
690         char cmd_str[MAX_AT_CMD_STR_LEN] ;\r
691         \r
692         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
693 \r
694         dbg("Entered");\r
695         hal = tcore_object_get_hal(co_ps);\r
696 \r
697         (void)sprintf(cmd_str, "AT+XDNS?");\r
698         pending = tcore_at_pending_new(co_ps,cmd_str,"+XDNS",TCORE_AT_MULTILINE,\r
699                                         on_response_get_dns_cmnd,ps_context );\r
700         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
701         {\r
702                 return TCORE_RETURN_SUCCESS;\r
703         }\r
704         _unable_to_get_pending(co_ps,ps_context);\r
705         return TCORE_RETURN_FAILURE;\r
706 }\r
707 \r
708 static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)\r
709 {\r
710         const TcoreATResponse *resp = data;\r
711         CoreObject *co_ps =  tcore_pending_ref_core_object(p);\r
712         CoreObject *ps_context = user_data;\r
713         GSList *tokens=NULL;\r
714         const char *line;\r
715         char *token_pdp_address;\r
716         dbg("Enetered");\r
717         if(resp->final_response)\r
718         {\r
719                 dbg("RESPONSE OK");\r
720                 if(resp->lines != NULL)\r
721                 {\r
722                         dbg("resp->lines present ");\r
723                         line = (const char*)resp->lines->data;\r
724                         tokens = tcore_at_tok_new(line);\r
725                         if (g_slist_length(tokens) < 2)\r
726                         {\r
727                                 msg("invalid message");\r
728                                 goto error;\r
729                         }\r
730                         dbg("line:- %s",line);\r
731                         /* CID is already stored in ps_context, skip over & read PDP address */\r
732                         token_pdp_address = g_slist_nth_data(tokens, 1);\r
733 \r
734                         dbg("token_pdp_address :- %s",token_pdp_address);\r
735                         /* Strip off starting " and ending " from this token to read actual PDP address */\r
736                         (void)tcore_context_set_address(ps_context,(const char *)token_pdp_address);\r
737                 }\r
738 \r
739                 (void)send_get_dns_cmd(co_ps,ps_context);\r
740         }\r
741         else\r
742         {\r
743                 dbg("Response NOK");\r
744                 /*without PDP address we will not be able to start packet service*/\r
745                 (void)deactivate_ps_context(co_ps,ps_context,NULL);\r
746         }\r
747         error:\r
748         tcore_at_tok_free(tokens);\r
749         return;\r
750 }\r
751 \r
752 static TReturn send_get_pdp_address_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
753 {\r
754         TcoreHal *hal = NULL;\r
755         TcorePending *pending = NULL;\r
756         unsigned int cid = PS_INVALID_CID;\r
757         char cmd_str[MAX_AT_CMD_STR_LEN] = {0};\r
758 \r
759         dbg("Entered");\r
760         hal = tcore_object_get_hal(co_ps);\r
761 \r
762         cid = tcore_context_get_id(ps_context);\r
763         (void)sprintf(cmd_str, "AT+CGPADDR=%d",cid);\r
764         pending = tcore_at_pending_new(co_ps,cmd_str,"+CGPADDR",TCORE_AT_SINGLELINE,\r
765         on_response_get_pdp_address,ps_context );\r
766         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
767         {\r
768                 return TCORE_RETURN_SUCCESS;\r
769         }\r
770         _unable_to_get_pending(co_ps,ps_context);\r
771         return TCORE_RETURN_FAILURE;\r
772 }\r
773 \r
774 static void on_response_send_pdp_activate_cmd (TcorePending *p, int data_len, const void *data, void *user_data)\r
775 {\r
776         CoreObject *co_ps = NULL;\r
777         const TcoreATResponse *resp = data;\r
778         CoreObject *ps_context = user_data;\r
779 \r
780         int cid;\r
781         cid = tcore_context_get_id(ps_context);\r
782 \r
783 \r
784         dbg("Entered");\r
785         if(!p)\r
786         {\r
787                 goto error;\r
788         }\r
789         co_ps = tcore_pending_ref_core_object(p);\r
790 \r
791         if(resp->success)\r
792         {\r
793                 dbg("Response Ok");\r
794                 /*getting the IP address and DNS from the modem*/\r
795                 dbg("Getting the IP Address");\r
796                 (void)send_get_pdp_address_cmd(co_ps,ps_context);\r
797                 return;\r
798         }\r
799         else\r
800         {\r
801 \r
802                 dbg("Unable to actiavte PDP context for CID: %d ",cid);\r
803                 dbg("Undefineing the PDP context");\r
804                 (void)tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);\r
805                 send_undefine_context_cmd(co_ps,ps_context);\r
806                 return;\r
807         }\r
808 error:\r
809         {\r
810                 _unable_to_get_pending(co_ps,ps_context);\r
811                 return;\r
812         }\r
813 }\r
814 \r
815 static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)\r
816 {\r
817         TcoreHal *hal = NULL;\r
818         TcorePending *pending = NULL;\r
819         char cmd_str[MAX_AT_CMD_STR_LEN] = {0};\r
820         int cid = 0;\r
821         dbg("Entered");\r
822         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
823         hal = tcore_object_get_hal(co_ps);\r
824 \r
825         /*Getting Context ID from Core Object*/\r
826         cid = tcore_context_get_id(ps_context);\r
827         (void)sprintf(cmd_str, "AT+CGACT=%d,%d",AT_PDP_ACTIVATE,cid);\r
828         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
829                                         on_response_send_pdp_activate_cmd,ps_context);\r
830         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
831         {\r
832                 return TCORE_RETURN_SUCCESS;\r
833         }\r
834         _unable_to_get_pending(co_ps,ps_context);\r
835         return TCORE_RETURN_FAILURE;\r
836 }\r
837 \r
838 static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)\r
839 {\r
840         TcoreATResponse *resp = (TcoreATResponse *)data;\r
841         CoreObject *co_ps =  tcore_pending_ref_core_object(p);\r
842         CoreObject *ps_context = user_data;\r
843         dbg("Entered");\r
844         if(resp->success)\r
845         {\r
846                 dbg("Response OK");\r
847                 dbg("DNS address getting is Enabled");\r
848         }\r
849         else\r
850         {\r
851                 dbg("Response NOK");\r
852                 /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/\r
853         }\r
854         (void)send_pdp_activate_cmd(co_ps,ps_context);\r
855         return;\r
856 }\r
857 \r
858 static TReturn send_xdns_enable_cmd(CoreObject *co_ps,CoreObject *ps_context)\r
859 {\r
860         TcoreHal *hal = NULL;\r
861         TcorePending *pending = NULL;\r
862         int cid = -1 ;\r
863         char cmd_str[MAX_AT_CMD_STR_LEN];\r
864 \r
865         dbg("Entered");\r
866         memset(cmd_str,0x0,MAX_AT_CMD_STR_LEN);\r
867 \r
868         hal = tcore_object_get_hal(co_ps);\r
869         cid = tcore_context_get_id(ps_context);\r
870 \r
871         (void)sprintf(cmd_str, "AT+XDNS=%d,%d",cid,AT_XDNS_ENABLE);\r
872         pending = tcore_at_pending_new(co_ps,cmd_str, NULL, TCORE_AT_NO_RESULT,\r
873                                         on_response_xdns_enable_cmd, ps_context);\r
874         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
875         {\r
876                 return TCORE_RETURN_SUCCESS;\r
877         }\r
878         _unable_to_get_pending(co_ps,ps_context);\r
879         return TCORE_RETURN_FAILURE;\r
880 }\r
881 \r
882 static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)\r
883 {\r
884         const TcoreATResponse *resp = data;\r
885         CoreObject *ps_context = (CoreObject *)user_data;\r
886         CoreObject *co_ps = tcore_pending_ref_core_object(p);\r
887 \r
888         dbg("Entered");\r
889         if(resp->success)\r
890         {\r
891                 dbg("Response OK");\r
892                 send_xdns_enable_cmd(co_ps,ps_context);\r
893         }\r
894         else\r
895         {\r
896                 dbg("response NOK");\r
897                 _unable_to_get_pending(co_ps,ps_context);\r
898                 dbg("Exiting");\r
899         }\r
900         return;\r
901         \r
902 }\r
903 \r
904 static TReturn send_define_pdp_context_cmd(CoreObject *co_ps, CoreObject *ps_context)\r
905 {\r
906 \r
907         TcoreHal *hal = NULL;\r
908         TcorePending *pending = NULL;\r
909         char *apn = NULL;\r
910         char *addr = NULL;\r
911         char cmd_str[MAX_AT_CMD_STR_LEN] ={0} ;\r
912         char pdp_type_str[10] = {0};\r
913         unsigned int cid = PS_INVALID_CID;\r
914         enum co_context_type pdp_type;\r
915         enum co_context_d_comp d_comp;\r
916         enum co_context_h_comp h_comp;\r
917 \r
918         dbg("Entered");\r
919 \r
920         cid = tcore_context_get_id(ps_context);\r
921 \r
922         pdp_type = tcore_context_get_type(ps_context);\r
923         d_comp = tcore_context_get_data_compression(ps_context);\r
924         h_comp = tcore_context_get_header_compression(ps_context);\r
925         apn = tcore_context_get_apn(ps_context);\r
926         addr = tcore_context_get_address(ps_context);\r
927 \r
928         /* FIXME: Before MUX setup, use PHY HAL directly. */\r
929         hal = tcore_object_get_hal(co_ps);\r
930         switch(pdp_type)\r
931         {\r
932                 case CONTEXT_TYPE_X25:\r
933                 {\r
934                         dbg("CONTEXT_TYPE_X25");\r
935                         strcpy(pdp_type_str,"X.25");\r
936                         break;\r
937                 }\r
938                 case CONTEXT_TYPE_IP:\r
939                 {\r
940                         dbg("CONTEXT_TYPE_IP");\r
941                         strcpy(pdp_type_str,"IP");\r
942                 }\r
943                 break;\r
944                 case CONTEXT_TYPE_PPP:\r
945                 {\r
946                         dbg("CONTEXT_TYPE_PPP");\r
947                         strcpy(pdp_type_str,"PPP");\r
948                 }\r
949                 break;\r
950                 case CONTEXT_TYPE_IPV6:\r
951                 {\r
952                         dbg("CONTEXT_TYPE_IPV6");\r
953                         strcpy(pdp_type_str,"IPV6");\r
954                         break;\r
955                 }\r
956                 default :\r
957                 {\r
958                         /*PDP Type not supported supported*/\r
959                         dbg("Unsupported PDP type :- %d returning ",pdp_type);\r
960                         return TCORE_RETURN_FAILURE;\r
961                 }\r
962         }\r
963         dbg("Activating context for CID :- %d",cid);\r
964         if(addr)\r
965                 (void)sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",%s,%d,%d",cid,pdp_type_str,apn,addr,d_comp,h_comp);\r
966         else\r
967                 (void)sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d",cid,pdp_type_str,apn,d_comp,h_comp);\r
968         pending = tcore_at_pending_new(co_ps,cmd_str,NULL,TCORE_AT_NO_RESULT,\r
969                                         on_response_define_pdp_context,ps_context );\r
970         if(TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal,pending))\r
971         {\r
972                 (void)tcore_context_set_state(ps_context,CONTEXT_STATE_ACTIVATING);\r
973                 return TCORE_RETURN_SUCCESS;\r
974         }\r
975         _unable_to_get_pending(co_ps,ps_context);\r
976         return TCORE_RETURN_FAILURE;\r
977 \r
978 }\r
979 \r
980 static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)\r
981 {\r
982         dbg("Entered");\r
983         return send_define_pdp_context_cmd(co_ps,ps_context);\r
984 }\r
985 \r
986 \r
987 static struct tcore_ps_operations ps_ops =\r
988 {\r
989         .activate_context = activate_ps_context,\r
990         .deactivate_context = deactivate_ps_context\r
991 };\r
992 \r
993 gboolean s_ps_init(TcorePlugin *p,TcoreHal *hal)\r
994 {\r
995         CoreObject *o;\r
996         struct context *context_table = NULL;\r
997 \r
998         dbg("Entered");\r
999         o = tcore_ps_new(p,"umts_ps", &ps_ops, hal);\r
1000 \r
1001         if (!o)\r
1002                 return FALSE;\r
1003         tcore_object_link_user_data(o, (void *)context_table);\r
1004 \r
1005         tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle,p);\r
1006         tcore_object_add_callback(o, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, p);\r
1007 \r
1008         dbg("Exiting");\r
1009         return TRUE;\r
1010 }\r
1011 \r
1012 void s_ps_exit(TcorePlugin *p)\r
1013 {\r
1014         CoreObject *o;\r
1015 \r
1016         dbg("Entered");\r
1017         o = tcore_plugin_ref_core_object(p,"umts_ps");\r
1018         if (!o)\r
1019                 return;\r
1020 \r
1021         tcore_ps_free(o);\r
1022         dbg("Exiting");\r
1023 }\r
1024 \r
1025 \r