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>
43 #include "imc_common.h"
46 /*Invalid Session ID*/
47 #define PS_INVALID_CID 999 /*Need to check */
49 /*Maximum String length Of the Command*/
50 #define MAX_AT_CMD_STR_LEN 150
52 /*Command for PDP activation and Deactivation*/
53 #define AT_PDP_ACTIVATE 1
54 #define AT_PDP_DEACTIVATE 0
56 #define AT_XDNS_ENABLE 1
57 #define AT_XDNS_DISABLE 0
58 #define AT_SESSION_DOWN 0
60 enum ps_data_call_status {
61 PS_DATA_CALL_CTX_DEFINED,
62 PS_DATA_CALL_CONNECTED,
63 PS_DATA_CALL_NOT_CONNECTED = 3,
67 CoreObject *ps_context;
68 struct tnoti_ps_pdp_ipconfiguration data_call_conf;
71 static void __convert_ipv4_atoi(unsigned char *ip4, const char *str)
79 token = strtok_r(temp, ".", &ptr);
80 while (token != NULL) {
81 ip4[local_index++] = atoi(token);
82 msg(" [%d]", ip4[local_index-1]);
83 token = strtok_r(NULL, ".", &ptr);
87 static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
89 struct tnoti_ps_call_status data_resp = {0};
92 data_resp.context_id = tcore_context_get_id(ps_context);
93 data_resp.state = PS_DATA_CALL_NOT_CONNECTED;
94 dbg("Sending Call Status Notification - Context ID: [%d] Context State: [NOT CONNECTED]",
95 data_resp.context_id);
97 /* Send CALL Status Notification */
98 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)),
99 co_ps, TNOTI_PS_CALL_STATUS, sizeof(data_resp), &data_resp);
101 /* Set PS State to Deactivated */
102 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
107 * Notification - GPRS event reporting
110 * +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
111 * The network has forced a context deactivation. The <cid> that was used to activate the context is provided if
114 static gboolean on_cgev_notification(CoreObject *co_ps,
115 const void *data, void *user_data)
117 GSList *tokens = NULL;
118 GSList *lines = (GSList *)data;
119 const gchar *line = lines->data;
123 struct tnoti_ps_call_status noti = {0};
129 err("Ignore, No data present in notification received for CGEV");
133 dbg("Lines->data :%s", line);
135 tokens = tcore_at_tok_new(line);
136 if (g_slist_length(tokens) != 3) {
137 err("Ignore, sufficient data not present for deactivation");
141 noti_data = g_slist_nth_data(tokens, 0);
143 /* Only care about NW context deactivation */
144 if (g_str_has_prefix(noti_data, "NW DEACT") == FALSE) {
145 err("Ignore, only care about nw deactivation");
149 noti_data = g_slist_nth_data(tokens, 1);
150 dbg("PDP Address: %s", noti_data);
152 noti_data = g_slist_nth_data(tokens, 2);
153 /*TODO: Need to handle context id with multiple PDP*/
154 if (noti_data != NULL)
155 context_id = (guint)atoi(noti_data);
157 err("No Context ID!");
161 dbg("Context %d deactivated", context_id);
163 /* Set State - CONNECTED */
164 noti.context_id = context_id;
165 noti.state = PS_DATA_CALL_NOT_CONNECTED;
166 dbg("Sending Call Status Notification - Context ID: [%d] Context State: [ NOT CONNECTED]", noti.context_id);
168 /* Send Notification */
169 server = tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps));
170 tcore_server_send_notification(server, co_ps,
171 TNOTI_PS_CALL_STATUS,
172 sizeof(struct tnoti_ps_call_status),
175 hal = tcore_object_get_hal(co_ps);
176 if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id,
177 FALSE) != TCORE_RETURN_SUCCESS)
178 err("Failed to disable network interface");
182 tcore_at_tok_free(tokens);
186 static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)
188 GSList *tokens = NULL;
189 const char *line = NULL;
191 GSList *lines = NULL;
194 lines = (GSList *) data;
195 if (g_slist_length(lines) != 1) {
196 dbg("Unsolicited message BUT multiple lines");
200 line = (char *) (lines->data);
201 tokens = tcore_at_tok_new(line);
202 value = atoi(g_slist_nth_data(tokens, 0));
206 * 0: DUN Activation in progress
207 * 1: DUN Deactivation in progress
212 case 0: /* FALL THROUGH */
220 /* TODO:- Fill Data structure: 'data' */
221 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
222 TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
228 /* TODO:- Fill Data structure: 'data' */
229 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
230 TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
240 tcore_at_tok_free(tokens);
244 static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
246 CoreObject *co_ps = NULL;
247 const TcoreATResponse *resp = data;
248 CoreObject *ps_context = user_data;
251 co_ps = tcore_pending_ref_core_object(p);
259 _unable_to_get_pending(co_ps, ps_context);
263 static void send_undefine_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
265 TcoreHal *hal = NULL;
266 TcorePending *pending = NULL;
267 char *cmd_str = NULL;
272 /* FIXME: Before MUX setup, use PHY HAL directly. */
273 hal = tcore_object_get_hal(co_ps);
275 /*Getting Context ID from Core Object*/
276 cid = tcore_context_get_id(ps_context);
278 cmd_str = g_strdup_printf("AT+CGDCONT=%d", cid);
280 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
282 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
283 on_response_undefine_context_cmd, ps_context);
284 if (NULL == pending) {
285 err("Unable to get the create a AT request ");
288 tcore_hal_send_request(hal, pending);
290 dbg("Exit: Successfully");
294 dbg("Exit: With error");
295 _unable_to_get_pending(co_ps, ps_context);
301 static void on_setup_pdp(CoreObject *co_ps, int result,
302 const char *netif_name, void *user_data)
304 struct ps_user_data *ps_data = user_data;
305 struct tnoti_ps_call_status data_status = {0};
311 err("PS_data unavailable. Exiting.");
316 /* Deactivate PDP context */
317 tcore_ps_deactivate_context(co_ps, ps_data->ps_context, NULL);
321 dbg("Device name: [%s]", netif_name);
322 if (tcore_util_netif_up(netif_name) != TCORE_RETURN_SUCCESS) {
323 err("util_netif_up() failed. errno=%d", errno);
324 /* Deactivate PDP context */
325 tcore_ps_deactivate_context(co_ps, ps_data->ps_context, NULL);
328 dbg("tcore_util_netif_up() PASS...");
331 /* Set Device name */
332 g_strlcpy(ps_data->data_call_conf.devname, netif_name, sizeof(ps_data->data_call_conf.devname));
334 ps_data->data_call_conf.context_id = (int)tcore_context_get_id(ps_data->ps_context);
336 dbg("Sending IP Configuration Notification - Context ID: [%d] Context State: [CONNECTED]", ps_data->data_call_conf.context_id);
337 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)),
339 TNOTI_PS_PDP_IPCONFIGURATION,
340 sizeof(struct tnoti_ps_pdp_ipconfiguration),
341 &ps_data->data_call_conf);
343 /* Set State - CONNECTED */
344 data_status.context_id = tcore_context_get_id(ps_data->ps_context);
345 data_status.state = PS_DATA_CALL_CONNECTED;
346 dbg("Sending Call Status Notification - Context ID: [%d] Context State: [CONNECTED]", data_status.context_id);
348 /* Send Notification */
349 server = tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps));
350 tcore_server_send_notification(server, co_ps,
351 TNOTI_PS_CALL_STATUS,
352 sizeof(struct tnoti_ps_call_status),
359 static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
361 GSList *tokens = NULL;
363 const char *line = NULL;
364 char *dns_prim = NULL;
365 char *dns_sec = NULL;
366 char *token_dns = NULL;
367 int no_pdp_active = 0;
368 struct ps_user_data *ps_data = user_data;
369 const TcoreATResponse *resp = data;
370 CoreObject *co_ps = tcore_pending_ref_core_object(p);
371 int cid = tcore_context_get_id(ps_data->ps_context);
372 TcoreHal *h = tcore_object_get_hal(co_ps);
376 if (resp->final_response) {
379 dbg("DNS data present in the Response");
380 pRespData = (GSList *) resp->lines;
381 no_pdp_active = g_slist_length(pRespData);
382 dbg("Total Number of Active PS Context: [%d]", no_pdp_active);
383 if (0 == no_pdp_active)
387 line = (const char *) pRespData->data;
388 dbg("Received Data: [%s]", line);
389 tokens = tcore_at_tok_new(line);
391 /* Check if Context ID is matching */
392 if (cid == atoi(g_slist_nth_data(tokens, 0))) {
393 dbg("Found the DNS details for the Current Context - Context ID: [%d]", cid);
398 tcore_at_tok_free(tokens);
401 /* Move to next line */
402 pRespData = pRespData->next;
405 /* Read primary DNS */
407 token_dns = g_slist_nth_data(tokens, 1);
409 /* Strip off starting " and ending " from this token to read actual PDP address */
410 dns_prim = tcore_at_tok_extract((void *)token_dns);
411 dbg("Primary DNS: [%s]", dns_prim);
414 /* Read Secondary DNS */
416 token_dns = g_slist_nth_data(tokens, 2);
418 /* Strip off starting " and ending " from this token to read actual PDP address */
419 dns_sec = tcore_at_tok_extract((void *)token_dns);
420 dbg("Secondary DNS: [%s]", dns_sec);
423 if ((g_strcmp0("0.0.0.0", dns_prim) == 0)
424 && (g_strcmp0("0.0.0.0", dns_sec) == 0)) {
430 tcore_at_tok_free(tokens);
436 __convert_ipv4_atoi(ps_data->data_call_conf.primary_dns, dns_prim);
437 __convert_ipv4_atoi(ps_data->data_call_conf.secondary_dns, dns_sec);
439 tcore_util_hex_dump(" ", 4, ps_data->data_call_conf.primary_dns);
440 tcore_util_hex_dump(" ", 4, ps_data->data_call_conf.secondary_dns);
442 /* Set DNS Address */
443 tcore_context_set_dns1(ps_data->ps_context, dns_prim);
444 tcore_context_set_dns2(ps_data->ps_context, dns_sec);
449 tcore_at_tok_free(tokens);
453 dbg("No data present in the Response");
459 dbg("Adding default DNS");
461 __convert_ipv4_atoi(ps_data->data_call_conf.primary_dns, "8.8.8.8");
462 __convert_ipv4_atoi(ps_data->data_call_conf.secondary_dns, "8.8.4.4");
464 tcore_context_set_dns1(ps_data->ps_context, (const char *)ps_data->data_call_conf.primary_dns);
465 tcore_context_set_dns2(ps_data->ps_context, (const char *)ps_data->data_call_conf.secondary_dns);
468 /* Mount network interface */
469 if (tcore_hal_setup_netif(h, co_ps, on_setup_pdp, (void *)ps_data, cid, TRUE)
470 != TCORE_RETURN_SUCCESS) {
471 err("Setup network interface failed");
475 dbg("EXIT : Without error");
478 static TReturn send_get_dns_cmd(CoreObject *co_ps, struct ps_user_data *ps_data)
480 TcoreHal *hal = NULL;
481 TcorePending *pending = NULL;
482 char *cmd_str = NULL;
485 hal = tcore_object_get_hal(co_ps);
487 cmd_str = g_strdup("AT+XDNS?");
488 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
490 pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
491 on_response_get_dns_cmnd, (void *)ps_data);
492 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
494 return TCORE_RETURN_SUCCESS;
496 _unable_to_get_pending(co_ps, ps_data->ps_context);
498 return TCORE_RETURN_FAILURE;
501 static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
503 const TcoreATResponse *resp = data;
504 CoreObject *co_ps = tcore_pending_ref_core_object(p);
505 GSList *tokens = NULL;
507 char *token_pdp_address = NULL;
508 char *token_address = NULL;
509 CoreObject *ps_context = user_data;
510 struct ps_user_data *ps_data = {0, };
514 if (resp->final_response) {
515 ps_data = g_try_malloc0(sizeof(struct ps_user_data));
516 if (ps_data == NULL) {
517 err("Memory allocation failed!!");
520 ps_data->ps_context = ps_context;
522 if (resp->lines != NULL) {
523 line = (const char *) resp->lines->data;
524 tokens = tcore_at_tok_new(line);
525 if (g_slist_length(tokens) < 2) {
526 msg("Invalid message");
529 dbg("Received Data: [%s]", line);
531 /* CID is already stored in ps_context, skip over & read PDP address */
532 token_address = g_slist_nth_data(tokens, 1);
533 token_pdp_address = tcore_at_tok_extract((void *)token_address);
534 dbg("IP Address: [%s]", token_pdp_address);
536 __convert_ipv4_atoi(ps_data->data_call_conf.ip_address, token_pdp_address);
538 tcore_util_hex_dump(" ", 4, ps_data->data_call_conf.ip_address);
540 /* Strip off starting " and ending " from this token to read actual PDP address */
542 (void)tcore_context_set_address(ps_context, (const char *)ps_data->data_call_conf.ip_address);
544 g_free(token_pdp_address);
547 /* Get DNS Address */
548 (void) send_get_dns_cmd(co_ps, ps_data);
552 /*without PDP address we will not be able to start packet service*/
553 tcore_ps_deactivate_context(co_ps, ps_context, NULL);
556 tcore_at_tok_free(tokens);
560 static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
562 TcoreHal *hal = NULL;
563 TcorePending *pending = NULL;
564 unsigned int cid = PS_INVALID_CID;
565 char *cmd_str = NULL;
568 hal = tcore_object_get_hal(co_ps);
570 cid = tcore_context_get_id(ps_context);
571 cmd_str = g_strdup_printf("AT+CGPADDR=%d", cid);
573 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
575 pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
576 on_response_get_pdp_address, ps_context);
577 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
579 return TCORE_RETURN_SUCCESS;
581 _unable_to_get_pending(co_ps, ps_context);
583 return TCORE_RETURN_FAILURE;
586 static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
588 CoreObject *co_ps = NULL;
589 const TcoreATResponse *resp = data;
590 CoreObject *ps_context = user_data;
593 cid = tcore_context_get_id(ps_context);
600 co_ps = tcore_pending_ref_core_object(p);
605 /* Getting the IP address and DNS from the modem */
606 dbg("Getting IP Address");
607 (void) send_get_pdp_address_cmd(co_ps, ps_context);
610 dbg("Unable to activate PDP context - Context ID: [%d]", cid);
611 dbg("Undefining PDP context");
612 (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
613 send_undefine_context_cmd(co_ps, ps_context);
618 _unable_to_get_pending(co_ps, ps_context);
623 static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
625 TcoreHal *hal = NULL;
626 TcorePending *pending = NULL;
627 char *cmd_str = NULL;
632 /* FIXME: Before MUX setup, use PHY HAL directly. */
633 hal = tcore_object_get_hal(co_ps);
635 /*Getting Context ID from Core Object*/
636 cid = tcore_context_get_id(ps_context);
637 cmd_str = g_strdup_printf("AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
639 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
641 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
642 on_response_send_pdp_activate_cmd, ps_context);
643 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
645 return TCORE_RETURN_SUCCESS;
647 _unable_to_get_pending(co_ps, ps_context);
649 return TCORE_RETURN_FAILURE;
652 static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
655 return send_pdp_activate_cmd(co_ps, ps_context);
658 static void on_response_send_pdp_deactivate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
660 CoreObject *co_ps = NULL;
661 const TcoreATResponse *resp = data;
662 CoreObject *ps_context = user_data;
663 TcoreHal *hal = NULL;
664 unsigned char context_id = 0;
670 err("Invalid pending data");
673 co_ps = tcore_pending_ref_core_object(p);
674 hal = tcore_object_get_hal(co_ps);
675 context_id = tcore_context_get_id(ps_context);
676 dbg("Context ID : %d", context_id);
679 /* Since PDP deactivation failed, no need to move to
680 * PS_DATA_CALL_NOT_CONNECTED state
686 _unable_to_get_pending(co_ps, ps_context);
688 if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id, FALSE) != TCORE_RETURN_SUCCESS)
689 err("Failed to disable network interface");
692 static TReturn send_pdp_deactivate_cmd(CoreObject *co_ps, CoreObject *ps_context)
694 TcoreHal *hal = NULL;
695 TcorePending *pending = NULL;
696 char *cmd_str = NULL;
701 hal = tcore_object_get_hal(co_ps);
703 /*Getting Context ID from Core Object*/
704 cid = tcore_context_get_id(ps_context);
705 cmd_str = g_strdup_printf("AT+CGACT=%d,%u", AT_PDP_DEACTIVATE, cid);
707 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
709 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
710 on_response_send_pdp_deactivate_cmd, ps_context);
711 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
713 return TCORE_RETURN_SUCCESS;
716 return TCORE_RETURN_FAILURE;
719 static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
722 return send_pdp_deactivate_cmd(co_ps, ps_context);
724 static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
726 TcoreATResponse *resp = (TcoreATResponse *) data;
727 CoreObject *co_ps = tcore_pending_ref_core_object(p);
728 CoreObject *ps_context = user_data;
729 struct tnoti_ps_call_status noti = {0};
734 cid = tcore_context_get_id(ps_context);
738 dbg("DNS address getting is Enabled");
739 noti.context_id = cid;
740 noti.state = PS_DATA_CALL_CTX_DEFINED;
743 noti.context_id = cid;
744 noti.state = PS_DATA_CALL_NOT_CONNECTED;
745 /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
748 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
749 TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), ¬i);
753 static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
755 TcoreHal *hal = NULL;
756 TcorePending *pending = NULL;
758 char *cmd_str = NULL;
762 hal = tcore_object_get_hal(co_ps);
763 cid = tcore_context_get_id(ps_context);
765 cmd_str = g_strdup_printf("AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
766 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
768 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
769 on_response_xdns_enable_cmd, ps_context);
770 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
772 return TCORE_RETURN_SUCCESS;
774 _unable_to_get_pending(co_ps, ps_context);
776 return TCORE_RETURN_FAILURE;
779 static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
781 const TcoreATResponse *resp = data;
782 CoreObject *ps_context = (CoreObject *) user_data;
783 CoreObject *co_ps = tcore_pending_ref_core_object(p);
788 send_xdns_enable_cmd(co_ps, ps_context);
791 _unable_to_get_pending(co_ps, ps_context);
797 static TReturn define_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
799 TcoreHal *hal = NULL;
800 TcorePending *pending = NULL;
802 char *cmd_str = NULL;
803 char *pdp_type_str = NULL;
804 unsigned int cid = PS_INVALID_CID;
805 enum co_context_type pdp_type;
806 enum co_context_d_comp d_comp;
807 enum co_context_h_comp h_comp;
811 cid = tcore_context_get_id(ps_context);
812 pdp_type = tcore_context_get_type(ps_context);
813 d_comp = tcore_context_get_data_compression(ps_context);
814 h_comp = tcore_context_get_header_compression(ps_context);
815 apn = tcore_context_get_apn(ps_context);
817 hal = tcore_object_get_hal(co_ps);
819 case CONTEXT_TYPE_X25:
821 dbg("CONTEXT_TYPE_X25");
822 pdp_type_str = g_strdup_printf("X.25");
826 case CONTEXT_TYPE_IPV4V6:
827 case CONTEXT_TYPE_IP:
829 dbg("CONTEXT_TYPE_IP");
830 pdp_type_str = g_strdup_printf("IP");
834 case CONTEXT_TYPE_PPP:
836 dbg("CONTEXT_TYPE_PPP");
837 pdp_type_str = g_strdup_printf("PPP");
841 case CONTEXT_TYPE_IPV6:
843 dbg("CONTEXT_TYPE_IPV6");
844 pdp_type_str = g_strdup_printf("IPV6");
850 /*PDP Type not supported supported*/
851 dbg("Unsupported PDP type: %d returning ", pdp_type);
853 return TCORE_RETURN_FAILURE;
856 dbg("Activating context for CID: %d", cid);
857 cmd_str = g_strdup_printf("AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d",
858 cid, pdp_type_str, apn, d_comp, h_comp);
860 dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
863 pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
864 on_response_define_pdp_context, ps_context);
865 if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
867 g_free(pdp_type_str);
868 return TCORE_RETURN_SUCCESS;
870 _unable_to_get_pending(co_ps, ps_context);
872 g_free(pdp_type_str);
873 return TCORE_RETURN_FAILURE;
876 static struct tcore_ps_operations ps_ops = {
877 .define_context = define_ps_context,
878 .activate_context = activate_ps_context,
879 /* Use AT_standard entry point */
880 .deactivate_context = deactivate_ps_context,
883 gboolean imc_ps_init(TcorePlugin *cp, CoreObject *co_ps)
885 TcorePlugin *plugin = tcore_object_ref_plugin(co_ps);
890 tcore_ps_set_ops(co_ps, &ps_ops, TCORE_OPS_TYPE_CP);
892 tcore_object_add_callback(co_ps, "+CGEV", on_cgev_notification, NULL);
893 tcore_object_add_callback(co_ps, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, plugin);
900 void imc_ps_exit(TcorePlugin *cp, CoreObject *co_ps)