4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Arun Shukla <arun.shukla@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
28 #include <sys/ioctl.h>
32 #include <core_object.h>
36 #include <co_context.h>
48 #define VNET_CH_PATH_BOOT0 "/dev/umts_boot0"
49 #define IOCTL_CG_DATA_SEND _IO('o', 0x37)
51 /*Invalid Session ID*/
52 #define PS_INVALID_CID 999 /*Need to check */
54 /*Maximum String length Of the Command*/
55 #define MAX_AT_CMD_STR_LEN 150
57 /*Command for PDP activation and Deactivation*/
58 #define AT_PDP_ACTIVATE 1
59 #define AT_PDP_DEACTIVATE 0
61 #define AT_XDNS_ENABLE 1
62 #define AT_XDNS_DISABLE 0
63 #define AT_SESSION_DOWN 0
64 static void _ps_free(void *ptr)
74 static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
76 struct tnoti_ps_call_status data_resp = {0};
78 data_resp.context_id = tcore_context_get_id(ps_context);
79 data_resp.state = AT_SESSION_DOWN; /*check value of state*/
80 data_resp.result = 0xFF; /*check error value*/
81 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
82 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);
83 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
86 static TReturn _pdp_device_control(unsigned int cid)
90 fd = open(VNET_CH_PATH_BOOT0, O_RDWR);
92 dbg("error : open [ %s ] [ %s ]", VNET_CH_PATH_BOOT0, strerror(errno));
95 /*To Do for different Cids*/
96 dbg("Send IOCTL: arg 0x05 (0101) HSIC1, cid=%d \n", cid);
98 ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0x05);
99 } else if (cid == 2) {
100 ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0xA);
102 dbg("More Than 2 context are not supported right Now");
106 dbg("[ error ] send IOCTL_CG_DATA_SEND (0x%x) fail!! \n", IOCTL_CG_DATA_SEND);
107 return TCORE_RETURN_FAILURE;
109 dbg("[ ok ] send IOCTL_CG_DATA_SEND (0x%x) success!! \n", IOCTL_CG_DATA_SEND);
110 return TCORE_RETURN_SUCCESS;
114 static gboolean on_event_cgev_handle(CoreObject *co_ps, const void *data, void *user_data)
117 GSList *tokens = NULL;
118 GSList *lines = NULL;
119 const char *line = NULL;
120 char *noti_data = NULL;
124 struct tnoti_ps_call_status data_resp = {0};
127 lines = (GSList *) data;
128 line = (const char *) lines->data;
129 dbg("Lines->data :-%s", line);
131 tokens = tcore_at_tok_new(line);
132 switch (g_slist_length(tokens)) {
135 dbg("No token present: Ignore +CGEV Notifications ");
141 dbg("one Token present");
142 noti_data = g_slist_nth_data(tokens, 0);
143 dbg("notification data :-%s", noti_data);
144 if (0 == strcmp(noti_data, "ME CLASS B")) {
145 dbg("ME Class B notification received");
148 if (0 == strcmp(noti_data, "NW CLASS A")) {
149 dbg("NW Class A notification received");
152 token = strtok(noti_data, " ");
153 while (token != NULL) {
154 if ((i == 0) && (0 != strcmp(token, "ME"))) {
157 if ((i == 1) && (0 != strcmp(token, "PDN"))) {
160 if ((i == 2) && (0 == strcmp(token, "ACT"))) {
163 if ((i == 2) && (0 == strcmp(token, "DEACT"))) {
171 token = strtok(NULL, " ");
173 dbg("value:%d ", value);
183 dbg("Three Token present");
184 noti_data = g_slist_nth_data(tokens, 0);
185 dbg("notification data :-%s", noti_data);
186 token = strtok(noti_data, " ");
187 while (token != NULL) {
188 if ((i == 0) && (0 == strcmp(token, "ME"))) {
191 if ((i == 1) && (0 != strcmp(token, "DEACT"))) {
194 if ((i == 2) && (0 == strcmp(token, "\"IP\"")) && (0 == state)) {
195 dbg("MObile Deactiavted the Context");
199 if ((i == 2) && (0 == strcmp(token, "\"IP\"")) && (1 == state)) {
200 dbg("NW Deactiavted the Context");
205 token = strtok(NULL, " ");
207 if (value == 10 && state == 0) {
208 dbg("Recieved Notification for Context deactivations from network");
209 noti_data = g_slist_nth_data(tokens, 1);
210 dbg("PDP Address :- %s", noti_data);
211 noti_data = g_slist_nth_data(tokens, 2);
212 dbg("CID got deactivated :- %d", atoi(noti_data));
214 if (value == 10 && state == 1) {
215 dbg("Recieved Notification for Context deactivations from Mobile");
216 noti_data = g_slist_nth_data(tokens, 1);
217 dbg("PDP Address :- %s", noti_data);
218 noti_data = g_slist_nth_data(tokens, 2);
219 dbg("CID got deactivated :- %d", atoi(noti_data));
221 data_resp.context_id = atoi(noti_data);
222 data_resp.state = 3; /*check value of state*/
223 dbg("State of the service :- %d", data_resp.state);
224 data_resp.result = 0xFF; /*check error value*/
225 dbg("Sending the notification");
227 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
228 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);
238 dbg("Ignore +CGEV Notifications ");
242 dbg("Notification recieved for Activation of CID:-%d", value);
243 } else if (state == 0) {
244 dbg("Notification recieved for Deactivation of CID:-%d", value);
249 tcore_at_tok_free(tokens);
253 static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)
255 GSList *tokens = NULL;
256 const char *line = NULL;
258 GSList *lines = NULL;
261 lines = (GSList *) data;
262 if (1 != g_slist_length(lines)) {
263 dbg("unsolicited msg but multiple line");
266 line = (char *) (lines->data);
267 tokens = tcore_at_tok_new(line);
268 value = atoi(g_slist_nth_data(tokens, 0));
272 0: DUN activation in progress
273 1: DUN deactivation in progress
278 case 0: /*Fall Through*/
286 /*To Do:- Fill Data structure : data*/
287 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
288 TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
293 /*To Do:- Fill Data structure : data*/
294 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
295 TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
303 if (NULL != tokens) {
304 tcore_at_tok_free(tokens);
308 static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
310 CoreObject *co_ps = NULL;
311 const TcoreATResponse *resp = data;
312 CoreObject *ps_context = user_data;
314 co_ps = tcore_pending_ref_core_object(p);
320 _unable_to_get_pending(co_ps, ps_context);
324 static void send_undefine_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
326 TcoreHal *hal = NULL;
327 TcorePending *pending = NULL;
328 char cmd_str[MAX_AT_CMD_STR_LEN];
332 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
334 /* FIXME: Before MUX setup, use PHY HAL directly. */
335 hal = tcore_object_get_hal(co_ps);
337 /*Getting Context ID from Core Object*/
338 cid = tcore_context_get_id(ps_context);
340 (void) sprintf(cmd_str, "AT+CGDCONT=%d", cid);
341 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
342 on_response_undefine_context_cmd, ps_context);
343 if (NULL == pending) {
344 err("Unable to get the create a AT request ");
347 tcore_hal_send_request(hal, pending);
348 dbg("Exit: Successfully");
352 dbg("Exit: With error");
353 _unable_to_get_pending(co_ps, ps_context);
357 static void on_response_data_counter_command(TcorePending *p, int data_len, const void *data, void *user_data)
359 CoreObject *ps_context = user_data;
360 const TcoreATResponse *resp = data;
361 CoreObject *co_ps = tcore_pending_ref_core_object(p);
363 GSList *tokens = NULL;
365 const char *line = NULL;
366 int no_pdp_active = 0;
367 unsigned long long Rx;
368 unsigned long long Tx;
369 int cid = tcore_context_get_id(ps_context);
372 if (resp->final_response) {
374 dbg(" response lines : -%s", resp->lines);
376 pRespData = (GSList *) resp->lines;
377 no_pdp_active = g_slist_length(pRespData);
378 dbg("Total Number of Active PS Context :- %d", no_pdp_active);
380 if (no_pdp_active == 0) {
384 dbg("Entered the Loop pRespData");
386 line = (const char *) pRespData->data;
387 dbg("Response->lines->data :%s", line);
388 tokens = tcore_at_tok_new(line);
389 if (cid == atoi(g_slist_nth_data(tokens, 0))) {
390 dbg("Found the data for our CID");
391 Tx = (unsigned long long) g_ascii_strtoull((g_slist_nth_data(tokens, 1)), NULL, 10);
394 Rx = (unsigned long long) g_ascii_strtoull((g_slist_nth_data(tokens, 2)), NULL, 10);
397 tcore_at_tok_free(tokens);
399 dbg("Exiting the Loop pRespData");
402 tcore_at_tok_free(tokens);
404 pRespData = pRespData->next;
406 dbg("Sending Data counter notifications");
408 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
409 TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, 0, NULL);
412 dbg("No Active PS Context");
418 static TReturn send_data_counter_command(CoreObject *co_ps, CoreObject *ps_context)
420 TcoreHal *hal = NULL;
421 TcorePending *pending = NULL;
422 char cmd_str[MAX_AT_CMD_STR_LEN];
425 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
427 hal = tcore_object_get_hal(co_ps);
429 (void) sprintf(cmd_str, "AT+XGCNTRD");
430 pending = tcore_at_pending_new(co_ps, cmd_str, "+XGCNTRD", TCORE_AT_MULTILINE,
431 on_response_data_counter_command, ps_context);
432 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
433 return TCORE_RETURN_SUCCESS;
435 _unable_to_get_pending(co_ps, ps_context);
436 return TCORE_RETURN_FAILURE;
437 /*Add code if unable to get the data usage*/
439 static void on_response_deactivate_ps_context(TcorePending *p, int data_len, const void *data, void *user_data)
441 CoreObject *co_ps = tcore_pending_ref_core_object(p);
442 CoreObject *ps_context = user_data;
443 const TcoreATResponse *resp = data;
446 cid = tcore_context_get_id(ps_context);
449 /*get the data usage and report it application*/
450 (void) send_data_counter_command(co_ps, ps_context);
451 /*get the HSDPA status and report it to server*/
454 send_undefine_context_cmd(co_ps, ps_context);
459 static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
461 TcoreHal *hal = NULL;
462 TcorePending *pending = NULL;
463 unsigned int cid = PS_INVALID_CID;
464 char cmd_str[MAX_AT_CMD_STR_LEN];
467 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
469 /*Getting Context ID from Core Object*/
470 cid = tcore_context_get_id(ps_context);
472 /* FIXME: Before MUX setup, use PHY HAL directly. */
473 hal = tcore_object_get_hal(co_ps);
475 (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_DEACTIVATE, cid);
476 dbg("At commands :- %s", cmd_str);
478 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
479 on_response_deactivate_ps_context, ps_context);
480 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
481 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
482 return TCORE_RETURN_SUCCESS;
484 _unable_to_get_pending(co_ps, ps_context);
485 return TCORE_RETURN_FAILURE;
488 static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
490 struct tnoti_ps_pdp_ipconfiguration noti = {0};
491 struct tnoti_ps_call_status data_status = {0};
492 char devname[10] = {0, };
493 char *dns_prim = NULL;
494 char *dns_sec = NULL;
495 char *pdp_address = NULL;
497 GSList *tokens = NULL;
499 const char *line = NULL;
500 char *token_dns = NULL;
501 char *token_add = NULL;
503 char *token_pdp_address = NULL;
504 int no_pdp_active = 0;
507 CoreObject *ps_context = user_data;
508 const TcoreATResponse *resp = data;
509 CoreObject *co_ps = tcore_pending_ref_core_object(p);
510 int cid = tcore_context_get_id(ps_context);
514 if (resp->final_response) {
517 dbg("DNS data present in the Response");
518 pRespData = (GSList *) resp->lines;
519 no_pdp_active = g_slist_length(pRespData);
520 dbg("Total Number of Active PS Context :- %d", no_pdp_active);
521 if (0 == no_pdp_active) {
525 dbg("traversing the DNS data for each active context");
526 line = (const char *) pRespData->data;
527 dbg("Response->lines->data :%s", line);
528 tokens = tcore_at_tok_new(line);
529 if (cid == atoi(g_slist_nth_data(tokens, 0))) {
530 dbg("Found the DNS details for the Current context");
531 dbg("Context Id of The Context : %d", atoi(g_slist_nth_data(tokens, 0)));
534 tcore_at_tok_free(tokens);
536 pRespData = pRespData->next;
538 { /* Read primary DNS */
539 token_dns = g_slist_nth_data(tokens, 1);
540 /* Strip off starting " and ending " from this token to read actual PDP address */
541 dns_prim = util_removeQuotes((void *) token_dns);
542 dbg("Token_dns :%s", token_dns);
543 dbg("Primary DNS :- %s", dns_prim);
545 token_add = strtok(dns_prim, ".");
546 while (token_add != NULL) {
547 noti.primary_dns[index++] = atoi(token_add);
548 token_add = strtok(NULL, ".");
552 { /* Read Secondary DNS */
554 token_dns = g_slist_nth_data(tokens, 2);
555 dns_sec = util_removeQuotes((void *) token_dns);
557 dbg("Token_dns :%s", token_dns);
558 dbg("Secondary DNS :- %s", dns_sec);
560 token_add = strtok(dns_sec, ".");
561 while (token_add != NULL) {
562 noti.secondary_dns[index++] = atoi(token_add);
563 token_add = strtok(NULL, ".");
567 tcore_at_tok_free(tokens);
571 dbg("No data present in the Response");
577 dbg("Adding default DNS");
578 dbg("Adding the Primary DNS");
579 noti.primary_dns[0] = 8;
580 noti.primary_dns[1] = 8;
581 noti.primary_dns[2] = 8;
582 noti.primary_dns[3] = 8;
583 dbg("Adding Secondary DNS");
584 noti.secondary_dns[0] = 8;
585 noti.secondary_dns[1] = 8;
586 noti.secondary_dns[2] = 4;
587 noti.secondary_dns[3] = 4;
591 dbg("Able to get the DNS from the DNS Query");
592 token_pdp_address = tcore_context_get_address(ps_context);
593 pdp_address = util_removeQuotes((void *) token_pdp_address);
595 dbg("PDP address :- %s", pdp_address);
596 /* Store IP address in char array, Telephony expected IP address in this format */
597 token_add = strtok(pdp_address, ".");
599 while ((token_add != NULL) && (index < 4)) { /* Currently only IPv4 is supported */
600 addr[index++] = atoi(token_add);
601 token_add = strtok(NULL, ".");
603 _ps_free(pdp_address);
604 _ps_free((void *) token_pdp_address);
605 noti.field_flag = (0x0001 & 0x0002 & 0x0004);
607 noti.context_id = cid;
608 memcpy(¬i.ip_address, &addr, 4);
609 if (_pdp_device_control(cid) != TCORE_RETURN_SUCCESS) {
610 dbg("_pdp_device_control() failed. errno=%d", errno);
612 snprintf(devname, 10, "pdp%d", cid - 1);
613 memcpy(noti.devname, devname, 10);
614 dbg("devname = [%s]", devname);
615 if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS) {
616 dbg("util_netif_up() failed. errno=%d", errno);
619 dbg("Send Notification upwards of IP address");
620 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps, TNOTI_PS_PDP_IPCONFIGURATION,
621 sizeof(struct tnoti_ps_pdp_ipconfiguration), ¬i);
623 data_status.context_id = cid;
624 data_status.state = 1;
625 data_status.result = 0;
627 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
628 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_status);
629 dbg("EXIT : Without error");
634 static TReturn send_get_dns_cmd(CoreObject *co_ps, CoreObject *ps_context)
636 TcoreHal *hal = NULL;
637 TcorePending *pending = NULL;
638 char cmd_str[MAX_AT_CMD_STR_LEN];
640 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
643 hal = tcore_object_get_hal(co_ps);
645 (void) sprintf(cmd_str, "AT+XDNS?");
646 pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
647 on_response_get_dns_cmnd, ps_context);
648 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
649 return TCORE_RETURN_SUCCESS;
651 _unable_to_get_pending(co_ps, ps_context);
652 return TCORE_RETURN_FAILURE;
655 static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
657 const TcoreATResponse *resp = data;
658 CoreObject *co_ps = tcore_pending_ref_core_object(p);
659 CoreObject *ps_context = user_data;
660 GSList *tokens = NULL;
662 char *token_pdp_address;
664 if (resp->final_response) {
666 if (resp->lines != NULL) {
667 dbg("resp->lines present ");
668 line = (const char *) resp->lines->data;
669 tokens = tcore_at_tok_new(line);
670 if (g_slist_length(tokens) < 2) {
671 msg("invalid message");
674 dbg("line:- %s", line);
675 /* CID is already stored in ps_context, skip over & read PDP address */
676 token_pdp_address = g_slist_nth_data(tokens, 1);
678 dbg("token_pdp_address :- %s", token_pdp_address);
679 /* Strip off starting " and ending " from this token to read actual PDP address */
680 (void) tcore_context_set_address(ps_context, (const char *) token_pdp_address);
683 (void) send_get_dns_cmd(co_ps, ps_context);
686 /*without PDP address we will not be able to start packet service*/
687 (void) deactivate_ps_context(co_ps, ps_context, NULL);
690 tcore_at_tok_free(tokens);
694 static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
696 TcoreHal *hal = NULL;
697 TcorePending *pending = NULL;
698 unsigned int cid = PS_INVALID_CID;
699 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
702 hal = tcore_object_get_hal(co_ps);
704 cid = tcore_context_get_id(ps_context);
705 (void) sprintf(cmd_str, "AT+CGPADDR=%d", cid);
706 pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
707 on_response_get_pdp_address, ps_context);
708 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
709 return TCORE_RETURN_SUCCESS;
711 _unable_to_get_pending(co_ps, ps_context);
712 return TCORE_RETURN_FAILURE;
715 static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
717 CoreObject *co_ps = NULL;
718 const TcoreATResponse *resp = data;
719 CoreObject *ps_context = user_data;
722 cid = tcore_context_get_id(ps_context);
729 co_ps = tcore_pending_ref_core_object(p);
733 /*getting the IP address and DNS from the modem*/
734 dbg("Getting the IP Address");
735 (void) send_get_pdp_address_cmd(co_ps, ps_context);
738 dbg("Unable to actiavte PDP context for CID: %d ", cid);
739 dbg("Undefineing the PDP context");
740 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
741 send_undefine_context_cmd(co_ps, ps_context);
746 _unable_to_get_pending(co_ps, ps_context);
751 static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
753 TcoreHal *hal = NULL;
754 TcorePending *pending = NULL;
755 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
758 /* FIXME: Before MUX setup, use PHY HAL directly. */
759 hal = tcore_object_get_hal(co_ps);
761 /*Getting Context ID from Core Object*/
762 cid = tcore_context_get_id(ps_context);
763 (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
764 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
765 on_response_send_pdp_activate_cmd, ps_context);
766 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
767 return TCORE_RETURN_SUCCESS;
769 _unable_to_get_pending(co_ps, ps_context);
770 return TCORE_RETURN_FAILURE;
773 static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
775 TcoreATResponse *resp = (TcoreATResponse *) data;
776 CoreObject *co_ps = tcore_pending_ref_core_object(p);
777 CoreObject *ps_context = user_data;
781 dbg("DNS address getting is Enabled");
784 /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
786 (void) send_pdp_activate_cmd(co_ps, ps_context);
790 static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
792 TcoreHal *hal = NULL;
793 TcorePending *pending = NULL;
795 char cmd_str[MAX_AT_CMD_STR_LEN];
798 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
800 hal = tcore_object_get_hal(co_ps);
801 cid = tcore_context_get_id(ps_context);
803 (void) sprintf(cmd_str, "AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
804 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
805 on_response_xdns_enable_cmd, ps_context);
806 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
807 return TCORE_RETURN_SUCCESS;
809 _unable_to_get_pending(co_ps, ps_context);
810 return TCORE_RETURN_FAILURE;
813 static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
815 const TcoreATResponse *resp = data;
816 CoreObject *ps_context = (CoreObject *) user_data;
817 CoreObject *co_ps = tcore_pending_ref_core_object(p);
822 send_xdns_enable_cmd(co_ps, ps_context);
825 _unable_to_get_pending(co_ps, ps_context);
831 static TReturn send_define_pdp_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
833 TcoreHal *hal = NULL;
834 TcorePending *pending = NULL;
836 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
837 char pdp_type_str[10] = {0};
838 unsigned int cid = PS_INVALID_CID;
839 enum co_context_type pdp_type;
840 enum co_context_d_comp d_comp;
841 enum co_context_h_comp h_comp;
845 cid = tcore_context_get_id(ps_context);
846 pdp_type = tcore_context_get_type(ps_context);
847 d_comp = tcore_context_get_data_compression(ps_context);
848 h_comp = tcore_context_get_header_compression(ps_context);
849 apn = tcore_context_get_apn(ps_context);
851 hal = tcore_object_get_hal(co_ps);
853 case CONTEXT_TYPE_X25:
855 dbg("CONTEXT_TYPE_X25");
856 strcpy(pdp_type_str, "X.25");
860 case CONTEXT_TYPE_IP:
862 dbg("CONTEXT_TYPE_IP");
863 strcpy(pdp_type_str, "IP");
867 case CONTEXT_TYPE_PPP:
869 dbg("CONTEXT_TYPE_PPP");
870 strcpy(pdp_type_str, "PPP");
874 case CONTEXT_TYPE_IPV6:
876 dbg("CONTEXT_TYPE_IPV6");
877 strcpy(pdp_type_str, "IPV6");
883 /*PDP Type not supported supported*/
884 dbg("Unsupported PDP type :- %d returning ", pdp_type);
885 return TCORE_RETURN_FAILURE;
888 dbg("Activating context for CID :- %d", cid);
889 (void) sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", cid, pdp_type_str, apn, d_comp, h_comp);
891 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
892 on_response_define_pdp_context, ps_context);
893 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
894 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
895 return TCORE_RETURN_SUCCESS;
897 _unable_to_get_pending(co_ps, ps_context);
898 return TCORE_RETURN_FAILURE;
901 static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
904 return send_define_pdp_context_cmd(co_ps, ps_context);
908 static struct tcore_ps_operations ps_ops = {
909 .activate_context = activate_ps_context,
910 .deactivate_context = deactivate_ps_context
913 gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal)
916 struct context *context_table = NULL;
919 o = tcore_ps_new(p, "umts_ps", &ps_ops, hal);
923 tcore_object_link_user_data(o, (void *) context_table);
925 tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle, p);
926 tcore_object_add_callback(o, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, p);
932 void s_ps_exit(TcorePlugin *p)
937 o = tcore_plugin_ref_core_object(p, "umts_ps");