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);
474 if(FALSE == tcore_hal_get_power_state(hal)){
475 dbg("cp not ready/n");
476 return TCORE_RETURN_ENOSYS;
479 (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_DEACTIVATE, cid);
480 dbg("At commands :- %s", cmd_str);
482 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
483 on_response_deactivate_ps_context, ps_context);
484 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
485 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
486 return TCORE_RETURN_SUCCESS;
488 _unable_to_get_pending(co_ps, ps_context);
489 return TCORE_RETURN_FAILURE;
492 static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
494 struct tnoti_ps_pdp_ipconfiguration noti = {0};
495 struct tnoti_ps_call_status data_status = {0};
496 char devname[10] = {0, };
497 char *dns_prim = NULL;
498 char *dns_sec = NULL;
499 char *pdp_address = NULL;
501 GSList *tokens = NULL;
503 const char *line = NULL;
504 char *token_dns = NULL;
505 char *token_add = NULL;
507 char *token_pdp_address = NULL;
508 int no_pdp_active = 0;
511 CoreObject *ps_context = user_data;
512 const TcoreATResponse *resp = data;
513 CoreObject *co_ps = tcore_pending_ref_core_object(p);
514 int cid = tcore_context_get_id(ps_context);
518 if (resp->final_response) {
521 dbg("DNS data present in the Response");
522 pRespData = (GSList *) resp->lines;
523 no_pdp_active = g_slist_length(pRespData);
524 dbg("Total Number of Active PS Context :- %d", no_pdp_active);
525 if (0 == no_pdp_active) {
529 dbg("traversing the DNS data for each active context");
530 line = (const char *) pRespData->data;
531 dbg("Response->lines->data :%s", line);
532 tokens = tcore_at_tok_new(line);
533 if (cid == atoi(g_slist_nth_data(tokens, 0))) {
534 dbg("Found the DNS details for the Current context");
535 dbg("Context Id of The Context : %d", atoi(g_slist_nth_data(tokens, 0)));
538 tcore_at_tok_free(tokens);
540 pRespData = pRespData->next;
542 { /* Read primary DNS */
543 token_dns = g_slist_nth_data(tokens, 1);
544 /* Strip off starting " and ending " from this token to read actual PDP address */
545 dns_prim = util_removeQuotes((void *) token_dns);
546 dbg("Token_dns :%s", token_dns);
547 dbg("Primary DNS :- %s", dns_prim);
549 token_add = strtok(dns_prim, ".");
550 while (token_add != NULL) {
551 noti.primary_dns[index++] = atoi(token_add);
552 token_add = strtok(NULL, ".");
556 { /* Read Secondary DNS */
558 token_dns = g_slist_nth_data(tokens, 2);
559 dns_sec = util_removeQuotes((void *) token_dns);
561 dbg("Token_dns :%s", token_dns);
562 dbg("Secondary DNS :- %s", dns_sec);
564 token_add = strtok(dns_sec, ".");
565 while (token_add != NULL) {
566 noti.secondary_dns[index++] = atoi(token_add);
567 token_add = strtok(NULL, ".");
571 tcore_at_tok_free(tokens);
575 dbg("No data present in the Response");
581 dbg("Adding default DNS");
582 dbg("Adding the Primary DNS");
583 noti.primary_dns[0] = 8;
584 noti.primary_dns[1] = 8;
585 noti.primary_dns[2] = 8;
586 noti.primary_dns[3] = 8;
587 dbg("Adding Secondary DNS");
588 noti.secondary_dns[0] = 8;
589 noti.secondary_dns[1] = 8;
590 noti.secondary_dns[2] = 4;
591 noti.secondary_dns[3] = 4;
595 dbg("Able to get the DNS from the DNS Query");
596 token_pdp_address = tcore_context_get_address(ps_context);
597 pdp_address = util_removeQuotes((void *) token_pdp_address);
599 dbg("PDP address :- %s", pdp_address);
600 /* Store IP address in char array, Telephony expected IP address in this format */
601 token_add = strtok(pdp_address, ".");
603 while ((token_add != NULL) && (index < 4)) { /* Currently only IPv4 is supported */
604 addr[index++] = atoi(token_add);
605 token_add = strtok(NULL, ".");
607 _ps_free(pdp_address);
608 _ps_free((void *) token_pdp_address);
609 noti.field_flag = (0x0001 & 0x0002 & 0x0004);
611 noti.context_id = cid;
612 memcpy(¬i.ip_address, &addr, 4);
613 if (_pdp_device_control(cid) != TCORE_RETURN_SUCCESS) {
614 dbg("_pdp_device_control() failed. errno=%d", errno);
616 snprintf(devname, 10, "pdp%d", cid - 1);
617 memcpy(noti.devname, devname, 10);
618 dbg("devname = [%s]", devname);
619 if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS) {
620 dbg("util_netif_up() failed. errno=%d", errno);
623 dbg("Send Notification upwards of IP address");
624 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps, TNOTI_PS_PDP_IPCONFIGURATION,
625 sizeof(struct tnoti_ps_pdp_ipconfiguration), ¬i);
627 data_status.context_id = cid;
628 data_status.state = 1;
629 data_status.result = 0;
631 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
632 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_status);
633 dbg("EXIT : Without error");
638 static TReturn send_get_dns_cmd(CoreObject *co_ps, CoreObject *ps_context)
640 TcoreHal *hal = NULL;
641 TcorePending *pending = NULL;
642 char cmd_str[MAX_AT_CMD_STR_LEN];
644 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
647 hal = tcore_object_get_hal(co_ps);
649 (void) sprintf(cmd_str, "AT+XDNS?");
650 pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
651 on_response_get_dns_cmnd, ps_context);
652 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
653 return TCORE_RETURN_SUCCESS;
655 _unable_to_get_pending(co_ps, ps_context);
656 return TCORE_RETURN_FAILURE;
659 static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
661 const TcoreATResponse *resp = data;
662 CoreObject *co_ps = tcore_pending_ref_core_object(p);
663 CoreObject *ps_context = user_data;
664 GSList *tokens = NULL;
666 char *token_pdp_address;
668 if (resp->final_response) {
670 if (resp->lines != NULL) {
671 dbg("resp->lines present ");
672 line = (const char *) resp->lines->data;
673 tokens = tcore_at_tok_new(line);
674 if (g_slist_length(tokens) < 2) {
675 msg("invalid message");
678 dbg("line:- %s", line);
679 /* CID is already stored in ps_context, skip over & read PDP address */
680 token_pdp_address = g_slist_nth_data(tokens, 1);
682 dbg("token_pdp_address :- %s", token_pdp_address);
683 /* Strip off starting " and ending " from this token to read actual PDP address */
684 (void) tcore_context_set_address(ps_context, (const char *) token_pdp_address);
687 (void) send_get_dns_cmd(co_ps, ps_context);
690 /*without PDP address we will not be able to start packet service*/
691 (void) deactivate_ps_context(co_ps, ps_context, NULL);
694 tcore_at_tok_free(tokens);
698 static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
700 TcoreHal *hal = NULL;
701 TcorePending *pending = NULL;
702 unsigned int cid = PS_INVALID_CID;
703 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
706 hal = tcore_object_get_hal(co_ps);
708 cid = tcore_context_get_id(ps_context);
709 (void) sprintf(cmd_str, "AT+CGPADDR=%d", cid);
710 pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
711 on_response_get_pdp_address, ps_context);
712 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
713 return TCORE_RETURN_SUCCESS;
715 _unable_to_get_pending(co_ps, ps_context);
716 return TCORE_RETURN_FAILURE;
719 static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
721 CoreObject *co_ps = NULL;
722 const TcoreATResponse *resp = data;
723 CoreObject *ps_context = user_data;
726 cid = tcore_context_get_id(ps_context);
733 co_ps = tcore_pending_ref_core_object(p);
737 /*getting the IP address and DNS from the modem*/
738 dbg("Getting the IP Address");
739 (void) send_get_pdp_address_cmd(co_ps, ps_context);
742 dbg("Unable to actiavte PDP context for CID: %d ", cid);
743 dbg("Undefineing the PDP context");
744 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
745 send_undefine_context_cmd(co_ps, ps_context);
750 _unable_to_get_pending(co_ps, ps_context);
755 static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
757 TcoreHal *hal = NULL;
758 TcorePending *pending = NULL;
759 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
762 /* FIXME: Before MUX setup, use PHY HAL directly. */
763 hal = tcore_object_get_hal(co_ps);
765 /*Getting Context ID from Core Object*/
766 cid = tcore_context_get_id(ps_context);
767 (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
768 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
769 on_response_send_pdp_activate_cmd, ps_context);
770 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
771 return TCORE_RETURN_SUCCESS;
773 _unable_to_get_pending(co_ps, ps_context);
774 return TCORE_RETURN_FAILURE;
777 static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
780 return send_pdp_activate_cmd(co_ps, ps_context);
783 static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
785 TcoreATResponse *resp = (TcoreATResponse *) data;
786 CoreObject *co_ps = tcore_pending_ref_core_object(p);
787 CoreObject *ps_context = user_data;
788 struct tnoti_ps_call_status noti = {0};
793 cid = tcore_context_get_id(ps_context);
797 dbg("DNS address getting is Enabled");
798 noti.context_id = cid;
803 noti.context_id = cid;
806 /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
809 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
810 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), ¬i);
814 static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
816 TcoreHal *hal = NULL;
817 TcorePending *pending = NULL;
819 char cmd_str[MAX_AT_CMD_STR_LEN];
822 memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
824 hal = tcore_object_get_hal(co_ps);
825 cid = tcore_context_get_id(ps_context);
827 (void) sprintf(cmd_str, "AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
828 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
829 on_response_xdns_enable_cmd, ps_context);
830 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
831 return TCORE_RETURN_SUCCESS;
833 _unable_to_get_pending(co_ps, ps_context);
834 return TCORE_RETURN_FAILURE;
837 static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
839 const TcoreATResponse *resp = data;
840 CoreObject *ps_context = (CoreObject *) user_data;
841 CoreObject *co_ps = tcore_pending_ref_core_object(p);
846 send_xdns_enable_cmd(co_ps, ps_context);
849 _unable_to_get_pending(co_ps, ps_context);
855 static TReturn send_define_pdp_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
857 TcoreHal *hal = NULL;
858 TcorePending *pending = NULL;
860 char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
861 char pdp_type_str[10] = {0};
862 unsigned int cid = PS_INVALID_CID;
863 enum co_context_type pdp_type;
864 enum co_context_d_comp d_comp;
865 enum co_context_h_comp h_comp;
869 cid = tcore_context_get_id(ps_context);
870 pdp_type = tcore_context_get_type(ps_context);
871 d_comp = tcore_context_get_data_compression(ps_context);
872 h_comp = tcore_context_get_header_compression(ps_context);
873 apn = tcore_context_get_apn(ps_context);
875 hal = tcore_object_get_hal(co_ps);
877 case CONTEXT_TYPE_X25:
879 dbg("CONTEXT_TYPE_X25");
880 strcpy(pdp_type_str, "X.25");
884 case CONTEXT_TYPE_IP:
886 dbg("CONTEXT_TYPE_IP");
887 strcpy(pdp_type_str, "IP");
891 case CONTEXT_TYPE_PPP:
893 dbg("CONTEXT_TYPE_PPP");
894 strcpy(pdp_type_str, "PPP");
898 case CONTEXT_TYPE_IPV6:
900 dbg("CONTEXT_TYPE_IPV6");
901 strcpy(pdp_type_str, "IPV6");
907 /*PDP Type not supported supported*/
908 dbg("Unsupported PDP type :- %d returning ", pdp_type);
909 return TCORE_RETURN_FAILURE;
912 dbg("Activating context for CID :- %d", cid);
913 (void) sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", cid, pdp_type_str, apn, d_comp, h_comp);
915 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
916 on_response_define_pdp_context, ps_context);
917 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
918 return TCORE_RETURN_SUCCESS;
920 _unable_to_get_pending(co_ps, ps_context);
921 return TCORE_RETURN_FAILURE;
924 static TReturn define_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
928 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(co_ps))){
929 dbg("cp not ready/n");
930 return TCORE_RETURN_ENOSYS;
932 return send_define_pdp_context_cmd(co_ps, ps_context);
936 static struct tcore_ps_operations ps_ops = {
937 .define_context = define_ps_context,
938 .activate_context = activate_ps_context,
939 .deactivate_context = deactivate_ps_context
942 gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal)
945 struct context *context_table = NULL;
948 o = tcore_ps_new(p, "umts_ps", &ps_ops, hal);
952 tcore_object_link_user_data(o, (void *) context_table);
954 tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle, p);
955 tcore_object_add_callback(o, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, p);
961 void s_ps_exit(TcorePlugin *p)
966 o = tcore_plugin_ref_core_object(p, "umts_ps");