4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
33 #include <tzplatform_config.h>
35 #include <co_network.h>
37 #include "imc_network.h"
38 #include "imc_common.h"
40 #define IMC_NETWORK_BASE_16 16
42 static TelNetworkAct __imc_network_map_act(guint act)
51 * 6 UTRAN w/HSDPA and HSUPA
55 return TEL_NETWORK_ACT_GSM;
57 return TEL_NETWORK_ACT_UMTS;
59 return TEL_NETWORK_ACT_EGPRS;
61 return TEL_NETWORK_ACT_HSDPA;
63 return TEL_NETWORK_ACT_HSUPA;
65 return TEL_NETWORK_ACT_HSPA;
67 return TEL_NETWORK_ACT_UNKNOWN;
71 static TelNetworkRegStatus __imc_network_map_stat(guint stat)
75 * 0 Not registered, ME is not currently searching a
76 * new operator to register to
77 * 1 Registered, home network
78 * 2 Not registered, but ME is currently searching a
79 * new operator to register
80 * 3 Registration denied
82 * 5 Registered, in roaming
86 return TEL_NETWORK_REG_STATUS_UNREGISTERED;
88 return TEL_NETWORK_REG_STATUS_REGISTERED;
90 return TEL_NETWORK_REG_STATUS_SEARCHING;
92 return TEL_NETWORK_REG_STATUS_DENIED;
94 return TEL_NETWORK_REG_STATUS_UNKNOWN;
96 return TEL_NETWORK_REG_STATUS_ROAMING;
98 return TEL_NETWORK_REG_STATUS_UNKNOWN;
102 static void __on_response_imc_network_registration(TcorePending *p,
103 guint data_len, const void *data, void *user_data)
105 const TcoreAtResponse *at_resp = data;
108 if (at_resp && at_resp->success) {
109 dbg("Network Registration - [OK]");
111 err("Network Registration - [NOK]");
115 static void __imc_network_register_to_network(CoreObject *co)
119 /* Send Request to modem */
120 ret = tcore_at_prepare_and_send_request(co,
122 TCORE_AT_COMMAND_TYPE_NO_RESULT,
123 TCORE_PENDING_PRIORITY_DEFAULT,
125 __on_response_imc_network_registration, NULL,
126 on_send_imc_request, NULL,
128 dbg("Sending Network Registration request: [%s]",
129 (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAIL"));
132 static void __on_response_imc_network_fetch_nw_name_internal(CoreObject *co,
133 gint result, const void *response, void *user_data)
135 TelNetworkIdentityInfo *identity = (TelNetworkIdentityInfo *)response;
137 /* Send notification if result is SUCCESS */
138 if (result == TEL_NETWORK_RESULT_SUCCESS)
139 tcore_object_send_notification(co,
140 TCORE_NOTIFICATION_NETWORK_IDENTITY,
141 sizeof(TelNetworkIdentityInfo), identity);
144 static TcoreHookReturn __on_response_imc_hook_set_flight_mode(CoreObject *co,
145 gint result, TcoreCommand command, const void *response, const void *user_data)
148 tcore_check_return_value(result == TEL_MODEM_RESULT_SUCCESS,
149 TCORE_HOOK_RETURN_CONTINUE);
151 dbg("Flight mode 'disabled', register to Network");
154 * TODO - Check for selection_mode
155 * Need to check if it is Manual or Automatic and based on
156 * that need to initiate Network Registratin accordingly.
158 __imc_network_register_to_network(co);
160 return TCORE_HOOK_RETURN_CONTINUE;
163 static void __on_response_imc_network_fetch_nw_name(TcorePending *p,
164 guint data_len, const void *data, void *user_data)
166 const TcoreAtResponse *at_resp = data;
167 CoreObject *co = tcore_pending_ref_core_object(p);
168 ImcRespCbData *resp_cb_data = user_data;
169 TelNetworkIdentityInfo identity = {0, };
171 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
175 tcore_check_return_assert(co != NULL);
176 tcore_check_return_assert(resp_cb_data != NULL);
178 if (at_resp && at_resp->success) {
179 if (at_resp->lines) {
181 GSList *tokens = NULL;
185 /* Validate that only 3 lines of response is received */
186 nol = g_slist_length(at_resp->lines);
188 err("Invalid response message");
192 /* Process the Multi-line response */
193 for (i = 0; i < nol; i++) {
194 line = g_slist_nth_data(at_resp->lines, i);
199 * +XCOPS: <type>[,<name>[,<display_condition>]]
201 dbg("<line> : [%s]", line);
202 tokens = tcore_at_tok_new(line);
204 if ((token_str = tcore_at_tok_nth(tokens, 0))) {
205 guint type = atoi(token_str);
206 dbg("<type> : [%d]", type);
209 case 0: /* PLMN (mcc, mnc) */
210 if ((token_str = tcore_at_tok_nth(tokens, 1))) {
211 if (strlen(token_str) > 0) {
212 identity.plmn = tcore_at_tok_extract((const char *)token_str);
215 tcore_network_set_plmn( co, identity.plmn);
220 case 1: /* Short Name in ROM (NV-RAM) */
221 case 3: /* Short Network Operator Name (CPHS) */
222 case 5: /* Short NITZ Name */
223 if ((token_str = tcore_at_tok_nth(tokens, 1))) {
224 if (strlen(token_str) > 0) {
225 identity.short_name = tcore_at_tok_extract((const char *)token_str);
228 /* Update Short name */
229 tcore_network_set_short_name(co, identity.short_name);
234 case 2: /* Long Name in ROM (NV-RAM) */
235 case 4: /* Long Network Operator Name (CPHS) */
236 case 6: /* Full NITZ Name */
237 if ((token_str = tcore_at_tok_nth(tokens, 1))) {
238 if (strlen(token_str) > 0) {
239 identity.long_name = tcore_at_tok_extract((const char *)token_str);
241 /* Update Long name */
242 tcore_network_set_long_name(co, identity.long_name);
253 tcore_at_tok_free(tokens);
256 /* Send Notification - Network identity */
257 dbg("Network name - Long name: [%s] Short name: [%s] "
258 "PLMN: [%s]", identity.long_name,
259 identity.short_name, identity.plmn);
261 result = TEL_NETWORK_RESULT_SUCCESS;
265 /* Invoke callback */
266 if (resp_cb_data->cb)
267 resp_cb_data->cb(co, (gint)result, &identity, resp_cb_data->cb_data);
270 tcore_free(identity.long_name);
271 tcore_free(identity.short_name);
272 tcore_free(identity.plmn);
274 /* Free callback data */
275 imc_destroy_resp_cb_data(resp_cb_data);
279 * Operation - fetch_nw_name
282 * AT-Command: AT+XCOPS=<Type>
285 * 0 numeric format of network MCC/MNC (three BCD
286 * digit country code and two/three BCD digit network code)
287 * 1 Short Name in ROM (NV-RAM)
288 * 2 Long Name in ROM (NV-RAM)
289 * 3 Short Network Operator Name (CPHS)
290 * 4 Long Network Operator Name (CPHS)
293 * 7 Service Provider Name
294 * 8 EONS short operator name from EF-PNN
295 * 9 EONS long operator name from EF-PNN
296 * 11 Short PLMN name (When PS or CS is registered)
297 * 12 Long PLMN name (When PS or CS is registered)
298 * 13 numeric format of network MCC/MNC even in limited service
300 * Response - Network name
301 * Success: (Multiple Single line)
302 * +XCOPS: <type>[,<name>[,<display_condition>]]
305 * +CME ERROR: <error>
307 static TelReturn __imc_network_fetch_nw_name(CoreObject *co,
308 TcoreObjectResponseCallback cb, void *cb_data)
310 ImcRespCbData *resp_cb_data = NULL;
313 /* Response callback data */
314 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
316 /* Send Request to modem */
317 ret = tcore_at_prepare_and_send_request(co,
318 "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS",
319 TCORE_AT_COMMAND_TYPE_MULTILINE,
320 TCORE_PENDING_PRIORITY_DEFAULT,
322 __on_response_imc_network_fetch_nw_name, resp_cb_data,
323 on_send_imc_request, NULL,
325 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Fetch Network name");
331 static TcoreHookReturn on_hook_imc_set_flight_mode(CoreObject *co,
332 TcoreCommand command, const void *request, const void *user_data,
333 TcoreObjectResponseCallback cb, const void *cb_data)
335 gboolean *flight_mode = (gboolean *)request;
338 * Hook Set Flight mode request.
340 * Disable Flight mode - Hook response (if success Register to Network)
341 * Enable Flight mode - return
343 if(*flight_mode != TRUE) {
344 /* Add response hook */
345 tcore_object_add_response_hook(co, command, request,
346 __on_response_imc_hook_set_flight_mode, NULL);
348 return TCORE_HOOK_RETURN_CONTINUE;
351 dbg("Flight mode - [Enabled]");
352 return TCORE_HOOK_RETURN_CONTINUE;
355 static TcoreHookReturn on_hook_imc_sim_status(TcorePlugin *plugin,
356 TcoreNotification command, guint data_len, void *data, void *user_data)
358 const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
360 tcore_check_return_value(sim_status != NULL,
361 TCORE_HOOK_RETURN_CONTINUE);
364 * Hook SIM initialization Notification
366 * SIM INIT complete - Attach to network (Register to network)
367 * SIM INIT not complete - return
369 if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
370 CoreObject *co = (CoreObject *)user_data;
371 dbg("SIM Initialized!!! Attach to Network");
373 tcore_check_return_value_assert(co != NULL,
374 TCORE_HOOK_RETURN_CONTINUE);
377 * TODO - Check for selection_mode
378 * Need to check if it is Manual or Automatic and based on
379 * that need to initiate Network Registratin accordingly.
381 __imc_network_register_to_network(co);
383 return TCORE_HOOK_RETURN_CONTINUE;
386 dbg("SIM not yet initialized - SIM Status: [%d]", *sim_status);
387 return TCORE_HOOK_RETURN_CONTINUE;
390 /* Notification callbacks */
392 * Notification: +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
394 * Possible values of <stat> can be
395 * 0 Not registered, ME is not currently searching
396 * a new operator to register to
397 * 1 Registered, home network
398 * 2 Not registered, but ME is currently searching
399 * a new operator to register
400 * 3 Registration denied
402 * 5 Registered, in roaming
405 * string type; two byte location area code in
406 * hexadecimal format (e.g. 00C3)
409 * string type; four byte cell ID in hexadecimal
410 * format (e.g. 0000A13F)
418 * 6 UTRAN w/HSDPA and HSUPA
420 static gboolean on_notification_imc_cs_network_info(CoreObject *co,
421 const void *event_info, void *user_data)
423 GSList *lines = NULL;
426 dbg("Network notification - CS network info: [+CREG]");
428 lines = (GSList *)event_info;
429 if (g_slist_length(lines) != 1) {
430 err("+CREG unsolicited message expected to be Single line "
431 "but received multiple lines");
435 line = (gchar *) (lines->data);
437 TelNetworkRegStatusInfo registration_status = {0, };
438 TelNetworkCellInfo cell_info = {0, };
439 GSList *tokens = NULL;
441 guint stat = 0, act = 0, lac = 0, ci = 0;
442 gboolean roam_state = FALSE;
447 * +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
449 tokens = tcore_at_tok_new(line);
450 if (g_slist_length(tokens) < 1) {
451 err("Invalid notification message");
456 if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
457 err("No <stat> in +CREG");
460 stat = __imc_network_map_stat(atoi(token_str));
461 (void)tcore_network_set_cs_reg_status(co, stat);
464 if ((token_str = g_slist_nth_data(tokens, 1))) {
465 token_str = tcore_at_tok_extract((const gchar *)token_str);
467 lac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
469 /* Update Location Area Code (lac) information */
470 (void)tcore_network_set_lac(co, lac);
472 tcore_free(token_str);
474 dbg("No <lac> in +CREG");
475 (void)tcore_network_get_lac(co, &lac);
479 if ((token_str = g_slist_nth_data(tokens, 2))) {
480 token_str = tcore_at_tok_extract((const gchar *)token_str);
482 ci = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
484 /* Update Cell ID (ci) information */
485 (void)tcore_network_set_cell_id(co, ci);
487 tcore_free(token_str);
489 dbg("No <ci> in +CREG");
490 (void)tcore_network_get_cell_id(co, &ci);
494 if ((token_str = g_slist_nth_data(tokens, 3))) {
495 act = __imc_network_map_act(atoi(token_str));
496 (void)tcore_network_set_access_technology(co, act);
498 dbg("No <AcT> in +CREG");
499 (void)tcore_network_get_access_technology(co, &act);
501 dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d", stat, lac, ci, act);
503 /* Send Notification - Network (CS) Registration status */
504 registration_status.cs_status = stat;
505 registration_status.act = act;
506 (void)tcore_network_get_ps_reg_status(co, ®istration_status.ps_status);
508 tcore_object_send_notification(co,
509 TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
510 sizeof(TelNetworkRegStatusInfo), ®istration_status);
513 case TEL_NETWORK_REG_STATUS_ROAMING:
514 roam_state = TRUE; // no break
515 case TEL_NETWORK_REG_STATUS_REGISTERED:
516 /* Fetch Network name - Internal request */
517 (void)__imc_network_fetch_nw_name(co,
518 __on_response_imc_network_fetch_nw_name_internal, NULL);
524 /* Set Roaming state */
525 tcore_network_set_roam_state(co, roam_state);
527 /* Send Notification - Cell info */
528 cell_info.lac = (gint)lac;
529 cell_info.cell_id = (gint)ci;
530 (void)tcore_network_get_rac(co, &cell_info.rac);
532 tcore_object_send_notification(co,
533 TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
534 sizeof(TelNetworkCellInfo), &cell_info);
538 tcore_at_tok_free(tokens);
545 * Notification: +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
547 * Possible values of <stat> can be
548 * 0 Not registered, ME is not currently searching a
549 * new operator to register to
550 * 1 Registered, home network
551 * 2 Not registered, but ME is currently searching a
552 * new operator to register
553 * 3 Registration denied
555 * 5 Registered, in roaming
558 * string type; two byte location area code in
559 * hexadecimal format (e.g. 00C3)
562 * string type; four byte cell ID in hexadecimal
563 * format (e.g. 0000A13F)
571 * 6 UTRAN w/HSDPA and HSUPA
574 * string type; one byte routing area code in hexadecimal format
576 static gboolean on_notification_imc_ps_network_info(CoreObject *co,
577 const void *event_info, void *user_data)
579 GSList *lines = NULL;
582 dbg("Network notification - PS network info: [+CGREG]");
584 lines = (GSList *)event_info;
585 if (g_slist_length(lines) != 1) {
586 err("+CGREG unsolicited message expected to be Single line "
587 "but received multiple lines");
591 line = (gchar *) (lines->data);
593 TelNetworkRegStatusInfo registration_status = {0, };
594 TelNetworkCellInfo cell_info = {0, };
595 GSList *tokens = NULL;
597 guint stat = 0, act = 0, lac = 0, ci = 0, rac = 0;
598 gboolean roam_state = FALSE;
603 * +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
605 tokens = tcore_at_tok_new(line);
606 if (g_slist_length(tokens) < 1) {
607 err("Invalid notification message");
612 if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
613 err("No <stat> in +CGREG");
616 stat = __imc_network_map_stat(atoi(token_str));
617 (void)tcore_network_set_ps_reg_status(co, stat);
620 if ((token_str = g_slist_nth_data(tokens, 1))) {
621 token_str = tcore_at_tok_extract((const gchar *)token_str);
623 lac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
625 /* Update Location Area Code (lac) information */
626 (void)tcore_network_set_lac(co, lac);
628 tcore_free(token_str);
630 dbg("No <lac> in +CGREG");
631 (void)tcore_network_get_lac(co, &lac);
635 if ((token_str = g_slist_nth_data(tokens, 2))) {
636 token_str = tcore_at_tok_extract((const gchar *)token_str);
638 ci = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
640 /* Update Cell ID (ci) information */
641 (void)tcore_network_set_cell_id(co, ci);
643 tcore_free(token_str);
645 dbg("No <ci> in +CGREG");
646 (void)tcore_network_get_cell_id(co, &ci);
650 if ((token_str = g_slist_nth_data(tokens, 3))) {
651 act = __imc_network_map_act(atoi(token_str));
652 (void)tcore_network_set_access_technology(co, act);
654 dbg("No <AcT> in +CGREG");
655 (void)tcore_network_get_access_technology(co, &act);
659 if ((token_str = g_slist_nth_data(tokens, 4))) {
660 token_str = tcore_at_tok_extract((const gchar *)token_str);
662 rac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
664 /* Update Routing Area Code (rac) information */
665 (void)tcore_network_set_rac(co, rac);
667 tcore_free(token_str);
669 err("No <ci> in +CGREG");
670 (void)tcore_network_get_rac(co, &rac);
672 dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d <rac>: 0x%x", stat, lac, ci, act, rac);
674 /* Send Notification - Network (PS) Registration status */
675 registration_status.ps_status = stat;
676 registration_status.act = act;
677 (void)tcore_network_get_cs_reg_status(co, ®istration_status.cs_status);
679 tcore_object_send_notification(co,
680 TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
681 sizeof(TelNetworkRegStatusInfo), ®istration_status);
683 /* Set Roaming state */
684 if (registration_status.ps_status == TEL_NETWORK_REG_STATUS_ROAMING)
687 tcore_network_set_roam_state(co, roam_state);
689 /* Send Notification - Cell info */
691 cell_info.cell_id = ci;
693 tcore_object_send_notification(co,
694 TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
695 sizeof(TelNetworkCellInfo), &cell_info);
699 tcore_at_tok_free(tokens);
706 * Notification: +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
709 * string type; Network name in long alphanumeric format.
712 * string type; Network name in short alphanumeric format.
715 * Local Time Zone; represented as 1 unit = 15 minutes.
718 * string type value; Universal Time
719 * format is "yy/MM/dd,hh:mm:ss",
720 * wherein characters indicates year, month, day, hour,
723 * Daylight Saving Time; represented in hours.
725 static gboolean on_notification_imc_network_time_info(CoreObject *co,
726 const void *event_info, void *user_data)
728 GSList *lines = NULL;
731 dbg("Network notification - Time info: [+XNITZINFO]");
733 lines = (GSList *)event_info;
734 if (g_slist_length(lines) != 1) {
735 err("+XNITZINFO unsolicited message expected to be Single line "
736 "but received multiple lines");
740 line = (gchar *)lines->data;
742 GSList *tokens = NULL;
743 TelNetworkNitzInfoNoti nitz_info = {0, };
744 gchar *fullname, *shortname;
746 gchar tmp_time[8] = {0};
752 * +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
754 tokens = tcore_at_tok_new(line);
757 if ((fullname = tcore_at_tok_nth(tokens, 1))) {
758 if (strlen(fullname) > 0) {
759 fullname = tcore_at_tok_extract((const char *)fullname);
761 /* Update Long name */
762 tcore_network_set_long_name(co, fullname);
764 tcore_free(fullname);
769 if ((shortname = tcore_at_tok_nth(tokens, 1))) {
770 if (strlen(shortname) > 0) {
771 shortname = tcore_at_tok_extract((const char *)shortname);
773 /* Update Short name */
774 tcore_network_set_short_name(co, shortname);
776 tcore_free(shortname);
781 if ((ltz = g_slist_nth_data(tokens, 2)))
782 nitz_info.gmtoff = atoi(ltz) * 15;/* gmtoff in minutes */
784 if ((time = g_slist_nth_data(tokens, 3))
785 && (strlen(time) > 18)) {
786 /* (time + 1) - Skip past initial quote (") */
787 g_strlcpy(tmp_time, time + 1, 2+1);
788 nitz_info.year = atoi(tmp_time);
790 /* skip slash (/) after year param */
791 g_strlcpy(tmp_time, time + 4, 2+1);
792 nitz_info.month = atoi(tmp_time);
794 /* skip past slash (/) after month param */
795 g_strlcpy(tmp_time, time + 7, 2+1);
796 nitz_info.day = atoi(tmp_time);
798 /* skip past comma (,) after day param */
799 g_strlcpy(tmp_time, time + 10, 2+1);
800 nitz_info.hour = atoi(tmp_time);
802 /* skip past colon (:) after hour param */
803 g_strlcpy(tmp_time, time + 13, 2+1);
804 nitz_info.minute = atoi(tmp_time);
806 /* skip past colon (:) after minute param */
807 g_strlcpy(tmp_time, time + 16, 2+1);
808 nitz_info.second = atoi(tmp_time);
812 if ((dstoff = g_slist_nth_data(tokens, 4))) {
813 nitz_info.dstoff = atoi(dstoff);
814 nitz_info.isdst = TRUE;
818 tcore_network_get_plmn(co, &nitz_info.plmn);
820 /* Send Notification - Network time info */
821 tcore_object_send_notification(co,
822 TCORE_NOTIFICATION_NETWORK_TIMEINFO,
823 sizeof(TelNetworkNitzInfoNoti), &nitz_info);
826 tcore_free(nitz_info.plmn);
827 tcore_at_tok_free(tokens);
837 * +XCIEV:,<battery_level>
839 * 'Radio Signal Strength' <rssi> can have the values
840 * 0 -107 dBm or less or unknown
849 * 'Battery Level' <battery_level> can have the values
850 * 0 0 % <= level < 5 %
851 * 1 5 % <= level < 15 %
852 * 2 15 % <= level < 25 %
853 * 3 25 % <= level < 40 %
854 * 4 40 % <= level < 55 %
855 * 5 55 % <= level < 70 %
856 * 6 70 % <= level < 85 %
857 * 7 85 % <= level <= 100 %
860 * <battery_level> is not consider for
861 * TCORE_NOTIFICATION_NETWORK_RSSI notification
863 static gboolean on_notification_imc_network_rssi(CoreObject *co,
864 const void *event_info, void *user_data)
866 GSList *lines = NULL;
869 dbg("Network notification - Icon (rssi) info: [+XCIEV]");
871 lines = (GSList *)event_info;
872 if (g_slist_length(lines) != 1) {
873 err("+XCIEV unsolicited message expected to be Single line "
874 "but received multiple lines");
878 line = (gchar *)lines->data;
880 GSList *tokens = NULL;
888 tokens = tcore_at_tok_new(line);
890 rssi_token = (gchar *)g_slist_nth_data(tokens, 0);
891 if (rssi_token && strlen(rssi_token)) {
892 guint rssi_bar = atoi(rssi_token);
893 dbg("RSSI Level: [%d]", rssi_bar);
895 /* Send Notification - Network Rssi */
896 tcore_object_send_notification(co,
897 TCORE_NOTIFICATION_NETWORK_RSSI,
898 sizeof(guint), &rssi_bar);
902 tcore_at_tok_free(tokens);
908 /* Network Responses */
910 static void on_response_imc_network_search(TcorePending *p,
911 guint data_len, const void *data, void *user_data)
913 const TcoreAtResponse *at_resp = data;
914 CoreObject *co = tcore_pending_ref_core_object(p);
915 ImcRespCbData *resp_cb_data = user_data;
916 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
917 TelNetworkPlmnList plmn_list = {0,};
918 guint num_network_avail;
920 GSList *tokens = NULL;
923 tcore_check_return_assert(co != NULL);
924 tcore_check_return_assert(resp_cb_data != NULL);
926 if (at_resp && at_resp->success) {
928 GSList *net_token = NULL;
932 if (!at_resp->lines) {
933 err("invalid response received");
937 line = (char *) at_resp->lines->data;
938 tokens = tcore_at_tok_new(line);
939 num_network_avail = g_slist_length(tokens);
940 if (num_network_avail < 1) {
941 err("invalid message");
945 plmn_list.network_list = tcore_malloc0(sizeof(TelNetworkInfo) * num_network_avail);
948 for (count = 0; count < num_network_avail; count++) {
950 net_token = tcore_at_tok_new(g_slist_nth_data(tokens, count));
951 if (NULL == net_token)
954 resp = tcore_at_tok_nth(net_token, 0);
956 plmn_list.network_list[count].plmn_status = atoi(resp);
957 dbg("status[%d]", plmn_list.network_list[count].plmn_status);
960 if ((resp = tcore_at_tok_nth(net_token, 1))) {
961 /* Long Alpha name */
962 dbg("long alpha name[%s]", resp);
963 plmn_list.network_list[count].network_identity.long_name =
964 tcore_at_tok_extract(resp);
967 if ((resp = tcore_at_tok_nth(net_token, 2))) {
968 /* Short Alpha name */
969 dbg("Short Alpha name[%s]", resp);
970 plmn_list.network_list[count].network_identity.short_name =
971 tcore_at_tok_extract(resp);
975 if ((resp = tcore_at_tok_nth(net_token, 3))) {
976 dbg("PLMN ID[%s]", resp);
977 plmn_list.network_list[count].network_identity.plmn =
978 tcore_at_tok_extract(resp);
981 /* Parse Access Technology */
982 if ((resp = tcore_at_tok_nth(tokens, 4))) {
985 plmn_list.network_list[count].act = TEL_NETWORK_ACT_GSM;
987 plmn_list.network_list[count].act = TEL_NETWORK_ACT_UMTS;
990 dbg("Operator [%d] :: status = %d, long_name = %s, short_name = %s plmn = %s, AcT=%d",
992 plmn_list.network_list[count].plmn_status,
993 plmn_list.network_list[count].network_identity.long_name,
994 plmn_list.network_list[count].network_identity.short_name,
995 plmn_list.network_list[count].network_identity.plmn,
996 plmn_list.network_list[count].act);
999 tcore_at_tok_free(net_token);
1001 result = TEL_NETWORK_RESULT_SUCCESS;
1003 err("RESPONSE NOK");
1005 err("CME Error[%s]",(char *)at_resp->lines->data);
1009 dbg("Network search : [%s]",
1010 (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1012 /* Invoke callback */
1013 if(resp_cb_data->cb)
1014 resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data);
1016 imc_destroy_resp_cb_data(resp_cb_data);
1018 for (count = 0; count < num_network_avail; count++) {
1019 g_free(plmn_list.network_list[count].network_identity.long_name);
1020 g_free(plmn_list.network_list[count].network_identity.short_name);
1021 g_free(plmn_list.network_list[count].network_identity.plmn);
1024 tcore_free(plmn_list.network_list);
1025 tcore_at_tok_free(tokens);
1028 static void on_response_imc_network_get_selection_mode(TcorePending *p,
1029 guint data_len, const void *data, void *user_data)
1031 const TcoreAtResponse *at_resp = data;
1032 CoreObject *co = tcore_pending_ref_core_object(p);
1033 ImcRespCbData *resp_cb_data = user_data;
1034 TelNetworkSelectionMode selection_mode = -1;
1035 GSList *tokens = NULL;
1037 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
1040 tcore_check_return_assert(co != NULL);
1041 tcore_check_return_assert(resp_cb_data != NULL);
1043 if (at_resp && at_resp->success) {
1047 if (!at_resp->lines) {
1048 err("invalid response received");
1052 line = (char *) at_resp->lines->data;
1053 tokens = tcore_at_tok_new(line);
1054 if (g_slist_length(tokens) < 1) {
1055 msg("invalid message");
1060 mode = atoi(tcore_at_tok_nth(tokens, 0));
1062 selection_mode = TEL_NETWORK_SELECTION_MODE_AUTOMATIC;
1064 selection_mode = TEL_NETWORK_SELECTION_MODE_MANUAL;
1066 result = TEL_NETWORK_RESULT_SUCCESS;
1067 dbg("selection mode[%d]", selection_mode);
1070 err("RESPONSE NOK");
1074 dbg("Get selection mode : [%s]",
1075 (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1076 /* Invoke callback */
1077 if (resp_cb_data->cb)
1078 resp_cb_data->cb(co, (gint)result, &selection_mode, resp_cb_data->cb_data);
1080 /* Free callback data */
1081 imc_destroy_resp_cb_data(resp_cb_data);
1083 tcore_at_tok_free(tokens);
1086 static void on_response_imc_network_default(TcorePending *p,
1087 guint data_len, const void *data, void *user_data)
1089 const TcoreAtResponse *at_resp = data;
1090 CoreObject *co = tcore_pending_ref_core_object(p);
1091 ImcRespCbData *resp_cb_data = user_data;
1092 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
1095 tcore_check_return_assert(co != NULL);
1096 tcore_check_return_assert(resp_cb_data != NULL);
1098 if (at_resp && at_resp->success) {
1100 result = TEL_NETWORK_RESULT_SUCCESS;
1102 err("RESPONSE NOK");
1104 err("CME Error[%s]",(char *)at_resp->lines->data);
1107 /* Invoke callback */
1108 if(resp_cb_data->cb)
1109 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
1111 imc_destroy_resp_cb_data(resp_cb_data);
1115 static void on_response_imc_network_get_mode(TcorePending *p,
1116 guint data_len, const void *data, void *user_data)
1118 const TcoreAtResponse *at_resp = data;
1119 CoreObject *co = tcore_pending_ref_core_object(p);
1120 ImcRespCbData *resp_cb_data = user_data;
1121 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
1122 TelNetworkMode mode = -1;
1123 GSList *tokens = NULL;
1126 tcore_check_return_assert(co != NULL);
1127 tcore_check_return_assert(resp_cb_data != NULL);
1129 if (at_resp && at_resp->success) {
1133 if (!at_resp->lines) {
1134 err("invalid response received");
1138 line = (char *) at_resp->lines->data;
1139 tokens = tcore_at_tok_new(line);
1140 if (g_slist_length(tokens) < 1) {
1141 err("invalid message");
1146 net_mode = atoi(tcore_at_tok_nth(tokens, 0));
1147 dbg("mode = %d", net_mode);
1151 mode = TEL_NETWORK_MODE_2G;
1154 mode = TEL_NETWORK_MODE_AUTO;
1157 mode = TEL_NETWORK_MODE_3G;
1160 err("Unsupported mode [%d]", net_mode);
1163 result = TEL_NETWORK_RESULT_SUCCESS;
1165 err("RESPONSE NOK");
1168 /* Invoke callback */
1169 if (resp_cb_data->cb)
1170 resp_cb_data->cb(co, (gint)result, &mode, resp_cb_data->cb_data);
1172 /* Free callback data */
1173 imc_destroy_resp_cb_data(resp_cb_data);
1175 tcore_at_tok_free(tokens);
1178 static void on_response_imc_network_get_preferred_plmn(TcorePending *p,
1179 guint data_len, const void *data, void *user_data)
1181 const TcoreAtResponse *at_resp = data;
1182 CoreObject *co = tcore_pending_ref_core_object(p);
1183 ImcRespCbData *resp_cb_data = user_data;
1184 TelNetworkPreferredPlmnList plmn_list = {0,};
1185 guint count = 0, total_lines = 0;
1186 TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
1189 tcore_check_return_assert(co != NULL);
1190 tcore_check_return_assert(resp_cb_data != NULL);
1192 if (at_resp && at_resp->success) {
1196 gboolean gsm_act2 = FALSE, gsm_compact_act2 = FALSE;
1197 gboolean utran_act2 = FALSE;
1199 if (!at_resp->lines) {
1200 err("invalid response received");
1204 total_lines = g_slist_length(at_resp->lines);
1205 if (total_lines < 1) {
1206 msg("invalid message");
1211 result = TEL_NETWORK_RESULT_SUCCESS;
1213 plmn_list.list = tcore_malloc0(sizeof(TelNetworkPreferredPlmnInfo) * total_lines);
1214 plmn_list.count = 0;
1216 for (count = 0; count < total_lines; count++) {
1217 /* Take each line response at a time & parse it */
1218 line = tcore_at_tok_nth(at_resp->lines, count);
1219 tokens = tcore_at_tok_new(line);
1222 if ((resp = tcore_at_tok_nth(tokens, 0))) {
1223 plmn_list.list[count].index = atoi(resp);
1227 if ((resp = tcore_at_tok_nth(tokens, 2))) {
1228 plmn_list.list[count].plmn = tcore_at_tok_extract(resp);
1232 if ((resp = tcore_at_tok_nth(tokens, 3))) {
1233 gsm_act2 = atoi(resp);
1236 /*GSM_Compact_AcT2 */
1237 if ((resp = tcore_at_tok_nth(tokens, 4))) {
1238 gsm_compact_act2 = atoi(resp);
1242 if ((resp = tcore_at_tok_nth(tokens, 5))) {
1243 utran_act2 = atoi(resp);
1247 plmn_list.list[count].act = TEL_NETWORK_ACT_UMTS;
1248 else if (utran_act2 || gsm_compact_act2)
1249 plmn_list.list[count].act = TEL_NETWORK_ACT_GSM;
1252 tcore_at_tok_free(tokens);
1254 dbg("index[%d], plmn[%s], act[%d]",
1255 plmn_list.list[count].index,
1256 plmn_list.list[count].plmn,
1257 plmn_list.list[count].act);
1260 plmn_list.count = count;
1262 err("RESPONSE NOK");
1264 err("CME Error[%s]",(char *)at_resp->lines->data);
1268 dbg("get preferred plmn : [%s]",
1269 (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
1271 /* Invoke callback */
1272 if (resp_cb_data->cb)
1273 resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data);
1275 /* Free callback data */
1276 imc_destroy_resp_cb_data(resp_cb_data);
1278 for(count = 0; count < total_lines; count++) {
1279 g_free(plmn_list.list[count].plmn);
1281 tcore_free(plmn_list.list);
1285 /* Network Operations */
1287 * Operation - set_power_status
1290 * AT-Command: AT+XCOPS=<Type>
1293 * 0 numeric format of network MCC/MNC (three BCD
1294 * digit country code and two/three BCD digit network code)
1295 * 1 Short Name in ROM (NV-RAM)
1296 * 2 Long Name in ROM (NV-RAM)
1297 * 3 Short Network Operator Name (CPHS)
1298 * 4 Long Network Operator Name (CPHS)
1301 * 7 Service Provider Name
1302 * 8 EONS short operator name from EF-PNN
1303 * 9 EONS long operator name from EF-PNN
1304 * 11 Short PLMN name (When PS or CS is registered)
1305 * 12 Long PLMN name (When PS or CS is registered)
1306 * 13 numeric format of network MCC/MNC even in limited service
1308 * Response - Network name
1309 * Success: (Multiple Single line)
1310 * +XCOPS: <type>[,<name>[,<display_condition>]]
1313 * +CME ERROR: <error>
1315 static TelReturn imc_network_get_identity_info(CoreObject *co,
1316 TcoreObjectResponseCallback cb, void *cb_data)
1318 return __imc_network_fetch_nw_name(co, cb, cb_data);
1322 * Operation - network search
1324 * AT-Command: AT+COPS=?
1327 * Success: (Single line)
1328 * +COPS: [list of supported (<stat>,long alphanumeric <oper>
1329 * ,short alphanumeric <oper>,numeric <oper>[,< AcT>]
1330 * [,,(list of supported <mode>s),(list of supported <format>s)]
1333 * describes the format in which operator name is to be displayed. Different values of <format> can be:
1334 * 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays
1335 * combination of Mcc and MNC in string format.
1336 * 1 <oper> format presentation is set to short alphanumeric.
1337 * 2 <oper> format presentations set to numeric.
1339 * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
1340 * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
1342 * describes the status of the network. It is one of the response parameter for test command.
1343 * 0 Unknown Networks
1344 * 1 Network Available
1346 * 3 Forbidden Network
1348 * indicates the radio access technology and values can be:
1353 * +CME ERROR: <error>
1356 static TelReturn imc_network_search(CoreObject *co,
1357 TcoreObjectResponseCallback cb, void *cb_data)
1359 ImcRespCbData *resp_cb_data;
1360 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1362 /* Response callback data */
1363 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1365 /* Send Request to modem */
1366 ret = tcore_at_prepare_and_send_request(co,
1367 "AT+COPS=?", "+COPS",
1368 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1369 TCORE_PENDING_PRIORITY_DEFAULT,
1371 on_response_imc_network_search, resp_cb_data,
1372 on_send_imc_request, NULL,
1375 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Network Search");
1379 static TelReturn imc_network_cancel_search(CoreObject *co,
1380 TcoreObjectResponseCallback cb, void *cb_data)
1382 ImcRespCbData *resp_cb_data;
1383 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1385 /* Response callback data */
1386 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1388 /* Send Request to modem */
1389 ret = tcore_at_prepare_and_send_request(co,
1391 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1392 TCORE_PENDING_PRIORITY_IMMEDIATELY,
1394 on_response_imc_network_default, resp_cb_data,
1395 on_send_imc_request, NULL,
1398 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Cancel network search");
1403 * Operation - automatic network selection
1405 * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
1408 * is used to select, whether the selection is done automatically by the ME or is forced by this command to
1409 * operator <oper> given in the format <format>.
1410 * The values of <mode> can be:
1411 * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
1412 * 1 Manual. Other parameters like format and operator need to be passed
1413 * 2 Deregister from network
1414 * 3 It sets <format> value. In this case <format> becomes a mandatory input
1415 * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
1418 * Success:(No result)
1422 static TelReturn imc_network_select_automatic(CoreObject *co,
1423 TcoreObjectResponseCallback cb, void *cb_data)
1425 ImcRespCbData *resp_cb_data;
1426 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1429 /* Response callback data */
1430 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1432 /* Send Request to modem */
1433 ret = tcore_at_prepare_and_send_request(co,
1435 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1436 TCORE_PENDING_PRIORITY_DEFAULT,
1438 on_response_imc_network_default, resp_cb_data,
1439 on_send_imc_request, NULL,
1442 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Automatic network selection");
1447 * Operation - manual network selection
1449 * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
1452 * is used to select, whether the selection is done automatically by the ME or is forced by this command to
1453 * operator <oper> given in the format <format>.
1454 * The values of <mode> can be:
1455 * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
1456 * 1 Manual. Other parameters like format and operator need to be passed
1457 * 2 Deregister from network
1458 * 3 It sets <format> value. In this case <format> becomes a mandatory input
1459 * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered.
1461 * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
1462 * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
1464 * indicates the radio access technology and values can be:
1469 * Success:(No result)
1473 static TelReturn imc_network_select_manual(CoreObject *co,
1474 const TelNetworkSelectManualInfo *sel_manual,
1475 TcoreObjectResponseCallback cb, void *cb_data)
1477 ImcRespCbData *resp_cb_data;
1478 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1483 switch(sel_manual->act) {
1484 case TEL_NETWORK_ACT_GSM:
1485 case TEL_NETWORK_ACT_GPRS:
1486 case TEL_NETWORK_ACT_EGPRS:
1489 case TEL_NETWORK_ACT_UMTS:
1490 case TEL_NETWORK_ACT_GSM_AND_UMTS:
1491 case TEL_NETWORK_ACT_HSDPA:
1492 case TEL_NETWORK_ACT_HSPA:
1496 err("unsupported AcT");
1501 at_cmd = g_strdup_printf("AT+COPS=1,2,\"%s\",%d", sel_manual->plmn, act);
1503 /* Response callback data */
1504 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1506 /* Send Request to modem */
1507 ret = tcore_at_prepare_and_send_request(co,
1509 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1510 TCORE_PENDING_PRIORITY_DEFAULT,
1512 on_response_imc_network_default, resp_cb_data,
1513 on_send_imc_request, NULL,
1516 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Manual network selection");
1523 * Operation - get network selection mode
1525 * AT-Command: AT+COPS?
1528 * Success: (Single line)
1529 * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
1531 * is used to select, whether the selection is done automatically by the ME or is forced by this command to
1532 * operator <oper> given in the format <format>.
1533 * The values of <mode> can be:
1534 * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
1535 * 1 Manual. Other parameters like format and operator need to be passed
1536 * 2 Deregister from network
1537 * 3 It sets <format> value. In this case <format> becomes a mandatory input
1538 * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
1541 * +CME ERROR: <error>
1543 static TelReturn imc_network_get_selection_mode(CoreObject *co,
1544 TcoreObjectResponseCallback cb, void *cb_data)
1546 ImcRespCbData *resp_cb_data;
1547 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1549 /* Response callback data */
1550 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1552 /* Send Request to modem */
1553 ret = tcore_at_prepare_and_send_request(co,
1554 "AT+COPS?", "+COPS",
1555 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1556 TCORE_PENDING_PRIORITY_DEFAULT,
1558 on_response_imc_network_get_selection_mode, resp_cb_data,
1559 on_send_imc_request, NULL,
1562 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get selection mode");
1567 * Operation - set preferred plmn
1569 * AT-Command: AT+CPOL=<index>][,<format>[,<oper>[,<GSM_AcT>,<GSM_Compact_AcT>,<UTRAN_AcT>]]]
1571 * <indexn> integer type; the order number of operator in the SIM/USIM preferred operator list
1573 * 0 long format alphanumeric <oper>
1574 * 1 short format alphanumeric <oper>
1576 * <opern> string type; <format> indicates if the format is alphanumeric or numeric (see +COPS)
1577 * <GSM_AcTn>: GSM access technology
1578 * 0 access technology not selected
1579 * 1 access technology selected
1580 * <GSM_Compact_AcTn>: GSM compact access technology
1581 * 0 access technology not selected
1582 * 1 access technology selected
1583 * <UTRA_AcTn>: UTRA access technology
1584 * 0 access technology not selected
1585 * 1 access technology selected
1588 * Success:(No Result)
1591 * +CME ERROR: <error>
1593 static TelReturn imc_network_set_preferred_plmn(CoreObject *co,
1594 const TelNetworkPreferredPlmnInfo *pref_plmn,
1595 TcoreObjectResponseCallback cb, void *cb_data)
1597 ImcRespCbData *resp_cb_data;
1599 gboolean gsm_act = FALSE;
1600 gboolean gsm_compact_act = FALSE;
1601 gboolean utran_act = FALSE;
1602 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1605 switch(pref_plmn->act) {
1606 case TEL_NETWORK_ACT_GSM:
1607 case TEL_NETWORK_ACT_GPRS:
1608 case TEL_NETWORK_ACT_EGPRS:
1611 case TEL_NETWORK_ACT_UMTS:
1612 case TEL_NETWORK_ACT_HSDPA:
1613 case TEL_NETWORK_ACT_HSPA:
1616 case TEL_NETWORK_ACT_GSM_AND_UMTS:
1617 gsm_act = utran_act = TRUE;
1620 warn("unsupported AcT");
1624 at_cmd = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d",
1625 pref_plmn->index, 2, pref_plmn->plmn, gsm_act, gsm_compact_act, utran_act);
1627 /* Response callback data */
1628 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1630 /* Send Request to modem */
1631 ret = tcore_at_prepare_and_send_request(co,
1633 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1634 TCORE_PENDING_PRIORITY_DEFAULT,
1636 on_response_imc_network_default, resp_cb_data,
1637 on_send_imc_request, NULL,
1640 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set preferred plmn");
1646 * Operation - get preferred plmn
1648 * AT-Command: AT+CPOL?
1650 * Success: (multiline)
1651 * +CPOL: <index1>,<format>,<oper1>
1652 * [,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>][<CR><LF>
1653 * +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>] [
\85]]
1658 static TelReturn imc_network_get_preferred_plmn(CoreObject *co,
1659 TcoreObjectResponseCallback cb, void *cb_data)
1661 ImcRespCbData *resp_cb_data;
1662 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1665 /* Response callback data */
1666 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1668 /* Send Request to modem */
1669 ret = tcore_at_prepare_and_send_request(co,
1670 "AT+CPOL=,2;+CPOL?", "+CPOL", //to make sure <oper> is numeric type in reponse.
1671 TCORE_AT_COMMAND_TYPE_MULTILINE,
1672 TCORE_PENDING_PRIORITY_DEFAULT,
1674 on_response_imc_network_get_preferred_plmn, resp_cb_data,
1675 on_send_imc_request, NULL,
1678 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get preferred plmn");
1683 * Operation - set network mode
1685 * AT-Command: AT+XRAT=<AcT> [, <PreferredAct>]
1687 * <AcT> indicates the radio access technology and may be
1689 * 1 GSM / UMTS Dual mode
1691 * 3-7 Reserved for future use.
1692 * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
1693 * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
1694 * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
1696 * This parameter is used for network registration in case of <AcT>=1.
1700 * Success: (No result)
1703 * +CME ERROR: <error>
1705 static TelReturn imc_network_set_mode(CoreObject *co, TelNetworkMode mode,
1706 TcoreObjectResponseCallback cb, void *cb_data)
1708 ImcRespCbData *resp_cb_data;
1709 TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
1714 case TEL_NETWORK_MODE_AUTO:
1717 case TEL_NETWORK_MODE_2G:
1720 case TEL_NETWORK_MODE_3G:
1723 case TEL_NETWORK_MODE_LTE:
1725 err("Unsupported mode");
1731 at_cmd = g_strdup_printf("AT+XRAT=%d,2", act); //PreferredAct is UMTS
1734 at_cmd = g_strdup_printf("AT+XRAT=%d", act);
1736 /* Response callback data */
1737 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1739 /* Send Request to modem */
1740 ret = tcore_at_prepare_and_send_request(co,
1742 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1743 TCORE_PENDING_PRIORITY_DEFAULT,
1745 on_response_imc_network_default, resp_cb_data,
1746 on_send_imc_request, NULL,
1748 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set network mode");
1754 * Operation - get network mode
1756 * AT-Command: AT+XRAT?
1759 * Success: (Single line)
1760 * +XRAT : <Act>,<PreferredAct>
1761 * <AcT> indicates the radio access technology and may be
1763 * 1 GSM / UMTS Dual mode
1765 * 3-7 Reserved for future use.
1766 * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
1767 * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
1768 * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
1770 * This parameter is used for network registration in case of <AcT>=1.
1775 * +CME ERROR: <error>
1778 static TelReturn imc_network_get_mode(CoreObject *co,
1779 TcoreObjectResponseCallback cb, void *cb_data)
1781 ImcRespCbData *resp_cb_data;
1785 /* Response callback data */
1786 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
1788 /* Send Request to modem */
1789 ret = tcore_at_prepare_and_send_request(co,
1790 "AT+XRAT?", "+XRAT",
1791 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1792 TCORE_PENDING_PRIORITY_DEFAULT,
1794 on_response_imc_network_get_mode, resp_cb_data,
1795 on_send_imc_request, NULL,
1798 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get network mode");
1802 static TelReturn imc_network_get_neighboring_cell_info(CoreObject *co,
1803 TcoreObjectResponseCallback cb, void *cb_data)
1807 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
1810 /* Network Operations */
1811 static TcoreNetworkOps imc_network_ops = {
1812 .get_identity_info = imc_network_get_identity_info,
1813 .search = imc_network_search,
1814 .cancel_search = imc_network_cancel_search,
1815 .select_automatic = imc_network_select_automatic,
1816 .select_manual = imc_network_select_manual,
1817 .get_selection_mode = imc_network_get_selection_mode,
1818 .set_preferred_plmn = imc_network_set_preferred_plmn,
1819 .get_preferred_plmn = imc_network_get_preferred_plmn,
1820 .set_mode = imc_network_set_mode,
1821 .get_mode = imc_network_get_mode,
1822 .get_neighboring_cell_info = imc_network_get_neighboring_cell_info
1825 gboolean imc_network_init(TcorePlugin *p, CoreObject *co)
1829 /* Set operations */
1830 tcore_network_set_ops(co, &imc_network_ops);
1833 tcore_object_add_callback(co, "+CREG", on_notification_imc_cs_network_info, NULL);
1834 tcore_object_add_callback(co, "+CGREG", on_notification_imc_ps_network_info, NULL);
1835 tcore_object_add_callback(co, "+XNITZINFO", on_notification_imc_network_time_info, NULL);
1836 tcore_object_add_callback(co, "+XCIEV", on_notification_imc_network_rssi, NULL);
1839 * Add Hooks - Request and Notification
1841 tcore_plugin_add_request_hook(p,
1842 TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
1843 on_hook_imc_set_flight_mode, NULL);
1844 tcore_plugin_add_notification_hook(p,
1845 TCORE_NOTIFICATION_SIM_STATUS,
1846 on_hook_imc_sim_status, co);
1848 //_insert_mcc_mnc_oper_list(cp, co_network);
1854 void imc_network_exit(TcorePlugin *p, CoreObject *co)