4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Harish Bishnoi <hbishnoi@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.
29 #include <core_object.h>
31 #include <user_request.h>
33 #include <co_network.h>
39 #include <tzplatform_config.h>
42 #include "s_network.h"
44 #define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
45 #define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
46 #define AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
47 #define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
48 #define AT_CREG_STAT_UNKNOWN 4 /* unknown */
49 #define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
51 #define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
52 #define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
53 #define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
54 #define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
55 #define AT_COPS_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
57 #define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
58 #define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
59 #define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
61 #define AT_COPS_ACT_GSM 0 /* GSM */
62 #define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
63 #define AT_COPS_ACT_UTRAN 2 /* UTRAN */
64 #define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
65 #define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
66 #define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
67 #define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
68 #define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
70 #define AT_GSM_XBANDSEL_AUTOMATIC 0
71 #define AT_GSM_XBANDSEL_1800 1800
72 #define AT_GSM_XBANDSEL_1900 1900
73 #define AT_GSM_XBANDSEL_900 900
74 #define AT_GSM_XBANDSEL_850 850
75 #define AT_GSM_XBANDSEL_450 450
76 #define AT_GSM_XBANDSEL_480 480
77 #define AT_GSM_XBANDSEL_750 750
78 #define AT_GSM_XBANDSEL_380 380
79 #define AT_GSM_XBANDSEL_410 410
82 #define AT_XRAT_DUAL 1
83 #define AT_XRAT_UMTS 2
85 #define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
86 #define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
88 static unsigned int lookup_tbl_net_status[] = {
89 [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
90 [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
91 [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
92 [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
93 [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
94 [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
97 static unsigned int lookup_tbl_access_technology[] = {
98 [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
99 [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
100 [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
101 [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
102 [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
103 [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
104 [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
105 [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
108 static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
111 static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
113 dbg("on_confirmation_modem_message_send - msg out from queue.\n");
115 if (result == FALSE) {
123 static void nwk_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
125 TcoreATRequest *req = NULL;
127 TcorePending *pending = NULL;
130 hal = tcore_object_get_hal(co);
132 pending = tcore_pending_new(co, 0);
133 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
135 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
137 tcore_pending_set_request_data(pending, 0, req);
138 tcore_pending_set_response_callback(pending, callback, req->cmd);
139 tcore_pending_link_user_request(pending, ur);
140 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
142 ret = tcore_hal_send_request(hal, pending);
147 static void _insert_mcc_mnc_oper_list(TcorePlugin *p, CoreObject *o)
152 char query[255] = { 0, };
155 GHashTable *result = NULL, *row = NULL;
156 struct tcore_network_operator_info *noi = NULL;
157 const char *path = NULL;
160 s = tcore_plugin_ref_server(p);
161 strg = tcore_server_find_storage(s, "database");
163 path = tzplatform_mkpath(TZ_SYS_DB, ".mcc_mnc_oper_list.db");
165 handle = tcore_storage_create_handle(strg, path);
167 dbg("fail to create database handle");
171 snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
173 result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
174 (GDestroyNotify) g_hash_table_destroy);
176 tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
178 g_hash_table_iter_init(&iter, result);
179 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
182 noi = calloc(sizeof(struct tcore_network_operator_info), 1);
184 snprintf(noi->mcc, 4, "%s", (char *) g_hash_table_lookup(row, "1"));
185 snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
186 snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
187 snprintf(noi->country, 4, "%s", (char *) g_hash_table_lookup(row, "0"));
189 tcore_network_operator_info_add(o, noi);
194 dbg("count = %d", count);
196 g_hash_table_destroy(result);
198 tcore_storage_remove_handle(strg, handle);
201 static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
202 int domain, int act, int cs_status, int ps_status)
204 enum telephony_network_service_type ret;
209 case NETWORK_ACT_UNKNOWN:
210 ret = NETWORK_SERVICE_TYPE_UNKNOWN;
213 case NETWORK_ACT_GSM:
214 if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
215 ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
217 ret = NETWORK_SERVICE_TYPE_2G;
220 case NETWORK_ACT_EGPRS:
221 return NETWORK_SERVICE_TYPE_2_5G_EDGE;
224 case NETWORK_ACT_UMTS:
225 ret = NETWORK_SERVICE_TYPE_3G;
229 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
230 ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
231 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
232 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
235 ret = NETWORK_SERVICE_TYPE_SEARCH;
237 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
238 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
241 ret = NETWORK_SERVICE_TYPE_EMERGENCY;
248 static void _ps_set(TcorePlugin *p, int status)
252 co_ps = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PS);
254 err("No PS Core Object on plugin");
258 if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
259 tcore_ps_set_online(co_ps, TRUE);
261 tcore_ps_set_online(co_ps, FALSE);
264 static void on_timeout_search_network(TcorePending *p, void *user_data)
267 struct tresp_network_search resp;
269 dbg("TIMEOUT !!!!! pending=%p", p);
271 memset(&resp, 0, sizeof(struct tresp_network_search));
273 resp.result = TCORE_RETURN_FAILURE;
276 ur = tcore_pending_ref_user_request(p);
278 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
282 static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
285 const TcoreATResponse *atResp = data;
286 // GSList *tokens = NULL;
287 // char * line = NULL;
288 struct tresp_network_set_plmn_selection_mode resp = {0};
290 if (atResp->success > 0) {
292 resp.result = TCORE_RETURN_SUCCESS;
295 resp.result = TCORE_RETURN_FAILURE;
298 ur = tcore_pending_ref_user_request(p);
300 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
304 static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
307 struct tresp_network_get_plmn_selection_mode resp = {0};
308 const TcoreATResponse *atResp = data;
309 GSList *tokens = NULL;
313 resp.result = TCORE_RETURN_FAILURE;
315 if (atResp->success > 0) {
318 +COPS: <mode>[,<format>,<oper>[,< AcT>]]
322 line = (char *) atResp->lines->data;
323 tokens = tcore_at_tok_new(line);
324 if (g_slist_length(tokens) < 1) {
325 msg("invalid message");
328 mode = atoi(tcore_at_tok_nth(tokens, 0));
329 dbg("mode = %d", mode);
332 case AT_COPS_MODE_AUTOMATIC:
333 resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
336 case AT_COPS_MODE_MANUAL:
337 case AT_COPS_MODE_MANUAL_AUTOMATIC:
338 resp.mode = NETWORK_SELECT_MODE_MANUAL;
341 case AT_COPS_MODE_DEREGISTER:
342 case AT_COPS_MODE_SET_ONLY:
343 resp.result = TCORE_RETURN_FAILURE;
346 resp.result = TCORE_RETURN_SUCCESS;
350 resp.result = TCORE_RETURN_FAILURE;
354 ur = tcore_pending_ref_user_request(p);
356 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
360 tcore_at_tok_free(tokens);
365 static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
368 struct tresp_network_search resp;
371 const TcoreATResponse *atResp = data;
372 GSList *tokens = NULL;
373 GSList *network_token = NULL;
375 char *temp_plmn_info = NULL;
376 char *alpha_name = NULL;
378 int num_network_avail = 0;
380 memset(&resp, 0, sizeof(struct tresp_network_search));
381 resp.result = TCORE_RETURN_FAILURE;
384 if (atResp->success > 0) {
387 line = (char *) atResp->lines->data;
388 tokens = tcore_at_tok_new(line);
389 num_network_avail = g_slist_length(tokens);
390 dbg(" length of tokens is %d\n", num_network_avail);
391 if (num_network_avail < 1) {
392 msg("invalid message");
397 resp.result = TCORE_RETURN_SUCCESS;
399 * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
400 * [,,(list of supported <mode>s),(list of supported <format>s)]
403 for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
404 network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
406 pResp = (tcore_at_tok_nth(network_token, 0));
408 dbg("status : %s", pResp);
409 resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
412 if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Alpha name */
413 dbg("Long Alpha name : %s", pResp);
415 if (strlen(pResp) > 0)
416 /* Strip off starting quote & ending quote */
417 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
420 if ((pResp = tcore_at_tok_nth(network_token, 2))) {
421 dbg("Short Aplha name : %s", pResp);
422 /* Short Aplha name */
423 /* Strip off starting quote & ending quote */
424 if (strlen(pResp) > 0)
425 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
429 pResp = tcore_at_tok_nth(network_token, 3);
431 dbg("PLMN ID : %s", pResp);
432 temp_plmn_info = tcore_at_tok_extract((const char *)pResp);
433 strncpy(resp.list[i].plmn, temp_plmn_info, 6);
434 resp.list[i].plmn[6] = '\0';
437 /* Parse Access Technology */
438 if ((pResp = tcore_at_tok_nth(network_token, 4))) {
439 if (strlen(pResp) > 0) {
443 resp.list[i].act = NETWORK_ACT_GSM;
445 resp.list[i].act = NETWORK_ACT_UMTS;
449 dbg("Operator [%d] :: stat = %d, Name =%s, plmnId = %s, AcT=%d\n", resp.list_count, resp.list[i].status, resp.list[i].name, resp.list[i].plmn, resp.list[i].act);
452 tcore_at_tok_free(network_token);
454 g_free(temp_plmn_info);
458 resp.result = TCORE_RETURN_FAILURE;
462 ur = tcore_pending_ref_user_request(p);
464 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
468 tcore_at_tok_free(tokens);
471 static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
473 const TcoreATResponse *atResp = data;
475 dbg("On Response Set UMTS Band");
477 if (atResp->success > 0) {
483 dbg("Wait for response of XRAT before sending final band setting response to AP");
488 static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
490 const TcoreATResponse *atResp = data;
492 dbg("On Response Set GSM Band");
493 if (atResp->success > 0) {
499 dbg("Wait for response of XRAT before sending final band setting response to AP");
503 static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
505 const TcoreATResponse *atResp = data;
506 GSList *tokens = NULL;
507 const char *line = NULL;
508 int total_umts_bands = 0;
510 char *band_token = NULL;
511 char umts_band[20] = {0};
512 char umts_band_1 = 0;
513 char umts_band_2 = 0;
514 char umts_band_5 = 0;
515 UserRequest *ur = NULL;
516 struct tresp_network_get_band resp = {0};
518 dbg("Entry on_response_get_umts_band");
520 resp.mode = NETWORK_BAND_MODE_PREFERRED;
521 resp.result = TCORE_RETURN_SUCCESS;
523 if (atResp->success > 0) {
526 line = (char *) atResp->lines->data;
527 tokens = tcore_at_tok_new(line);
528 total_umts_bands = g_slist_length(tokens);
529 dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
530 if (total_umts_bands < 1) {
539 for (i = 0; i < total_umts_bands; i++) {
540 band_token = tcore_at_tok_nth(tokens, i);
542 if (band_token == NULL)
545 memset(umts_band, 0x00, sizeof(umts_band));
547 if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
548 umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
552 /* Strip off starting quotes & ending quotes */
553 strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
555 if (!strcmp(umts_band, "UMTS_BAND_I")) {
557 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
559 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
562 /* Telephony is not interest */
563 dbg("Telephony is not interested in %s band", umts_band);
568 if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
569 resp.band = NETWORK_BAND_TYPE_WCDMA;
570 } else if (umts_band_1) {
571 resp.band = NETWORK_BAND_TYPE_WCDMA2100;
572 } else if (umts_band_2) {
573 resp.band = NETWORK_BAND_TYPE_WCDMA1900;
574 } else if (umts_band_5) {
575 resp.band = NETWORK_BAND_TYPE_WCDMA850;
577 resp.result = TCORE_RETURN_FAILURE;
580 dbg("Final resp.band sent to TS = %d", resp.band);
582 ur = tcore_pending_ref_user_request(p);
584 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
588 tcore_at_tok_free(tokens);
590 dbg("Exit on_response_get_umts_band");
594 static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
596 struct tresp_network_get_band resp = {0};
597 const TcoreATResponse *atResp = data;
598 GSList *tokens = NULL;
599 int total_gsm_bands = 0;
600 const char *line = NULL;
602 char *band_token = NULL;
603 UserRequest *ur = NULL;
609 dbg("Entry on_response_get_gsm_band");
611 resp.mode = NETWORK_BAND_MODE_PREFERRED;
612 resp.result = TCORE_RETURN_SUCCESS;
614 if (atResp->success > 0) {
617 line = (char *) atResp->lines->data;
618 tokens = tcore_at_tok_new(line);
619 total_gsm_bands = g_slist_length(tokens);
620 dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
621 if (total_gsm_bands < 1)
626 for (i = 0; i < total_gsm_bands; i++) {
627 band_token = tcore_at_tok_nth(tokens, i);
629 if (band_token == NULL)
632 if (atoi(band_token) == 0) { /* 0 means GSM automatic */
633 gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
637 switch (atoi(band_token)) {
638 case AT_GSM_XBANDSEL_850:
642 case AT_GSM_XBANDSEL_900:
646 case AT_GSM_XBANDSEL_1800:
650 case AT_GSM_XBANDSEL_1900:
661 if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
662 resp.band = NETWORK_BAND_TYPE_GSM;
663 } else if (gsm_850 && gsm_1900) {
664 resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
665 } else if (gsm_900 && gsm_1800) {
666 resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
667 } else if (gsm_1900) {
668 resp.band = NETWORK_BAND_TYPE_GSM1900;
669 } else if (gsm_850) {
670 resp.band = NETWORK_BAND_TYPE_GSM850;
671 } else if (gsm_1800) {
672 resp.band = NETWORK_BAND_TYPE_GSM1800;
673 } else if (gsm_900) {
674 resp.band = NETWORK_BAND_TYPE_GSM900;
676 resp.result = TCORE_RETURN_FAILURE;
679 dbg("Final resp.band sent to TS = %d", resp.band);
681 ur = tcore_pending_ref_user_request(p);
683 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
687 tcore_at_tok_free(tokens);
689 dbg("Exit on_response_get_gsm_band");
694 static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
697 UserRequest *ur = NULL;
699 TcoreATRequest *atreq;
700 char *cmd_str = NULL;
701 UserRequest *dup_ur = NULL;
702 const TcoreATResponse *atResp = data;
703 const char *line = NULL;
705 GSList *tokens = NULL;
706 TcorePending *pending = NULL;
707 CoreObject *o = NULL;
709 struct tresp_network_get_band resp = {0};
711 dbg("Enter on_response_get_xrat !!");
713 resp.mode = NETWORK_BAND_MODE_PREFERRED;
715 ur = tcore_pending_ref_user_request(p);
716 h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
717 o = tcore_pending_ref_core_object(p);
719 if (atResp->success > 0) {
722 line = (char *) atResp->lines->data;
723 tokens = tcore_at_tok_new(line);
724 if (g_slist_length(tokens) < 1) {
725 msg("invalid message");
730 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
731 cp_xrat = atoi(pResp);
733 if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
734 resp.result = TCORE_RETURN_SUCCESS;
735 resp.band = NETWORK_BAND_TYPE_ANY;
737 ur = tcore_pending_ref_user_request(p);
739 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
742 } else if ((cp_xrat == AT_XRAT_UMTS)) {
743 /* Get UMTS Band Information */
744 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
745 cmd_str = g_strdup_printf("AT+XUBANDSEL?");
746 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
747 pending = tcore_pending_new(o, 0);
748 tcore_pending_set_request_data(pending, 0, atreq);
749 tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
750 tcore_pending_link_user_request(pending, ur);
751 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
752 tcore_hal_send_request(h, pending);
754 } else if ((cp_xrat == AT_XRAT_UMTS)) {
755 /* Get GSM Band Information */
756 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
757 cmd_str = g_strdup_printf("AT+XBANDSEL?");
758 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
759 pending = tcore_pending_new(o, 0);
760 tcore_pending_set_request_data(pending, 0, atreq);
761 tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
762 tcore_pending_link_user_request(pending, dup_ur);
763 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
764 tcore_hal_send_request(h, pending);
771 resp.result = TCORE_RETURN_FAILURE;
772 resp.band = NETWORK_BAND_TYPE_ANY;
774 ur = tcore_pending_ref_user_request(p);
776 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
782 tcore_at_tok_free(tokens);
784 dbg("Exit on_response_get_xrat !!");
790 static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
792 UserRequest *ur = NULL;
793 struct tresp_network_set_band resp = {0};
794 const TcoreATResponse *atResp = data;
796 dbg("On Response Set XRAT");
798 if (atResp->success > 0) {
800 resp.result = TCORE_RETURN_SUCCESS;
803 resp.result = TCORE_RETURN_FAILURE;
806 ur = tcore_pending_ref_user_request(p);
808 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
814 static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
816 UserRequest *ur = NULL;
817 struct tresp_network_set_preferred_plmn resp = {0};
818 const TcoreATResponse *atResp = data;
820 dbg("ENTER on_response_set_preferred_plmn");
822 if (atResp->success > 0) {
824 resp.result = TCORE_RETURN_SUCCESS;
827 resp.result = TCORE_RETURN_FAILURE;
830 ur = tcore_pending_ref_user_request(p);
832 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
835 dbg("Exit on_response_set_preferred_plmn");
839 static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
841 const TcoreATResponse *atResp = data;
842 GSList *tokens = NULL;
843 const char *line = NULL;
844 CoreObject *o = NULL;
845 struct tnoti_network_identity noti;
848 int net_name_type = 0;
850 char *net_name = NULL;
852 dbg("Entry on_response_get_nitz_name (+XCOPS)");
853 o = tcore_pending_ref_core_object(p);
854 if (atResp->success > 0) {
858 nol = g_slist_length(atResp->lines);
860 msg("invalid message");
864 memset(¬i, 0, sizeof(struct tnoti_network_identity));
866 for (count = 0; count < nol; count++) {
868 line = g_slist_nth_data(atResp->lines, count);
869 tokens = tcore_at_tok_new(line);
870 dbg("line %d start---------------", count);
872 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
873 net_name_type = atoi(pResp);
874 dbg("Net name type : %d", net_name_type);
876 switch (net_name_type) {
877 case 0: /* plmn_id (mcc, mnc) */
878 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
879 if (strlen(pResp) > 0) {
880 net_name = tcore_at_tok_extract((const char *)pResp);
881 strncpy(noti.plmn, net_name, 6);
887 case 5: /* Short NITZ name*/
888 case 3: /* Short Network Name (CPHS) */
889 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
890 if (strlen(pResp) > 0) {
891 net_name = tcore_at_tok_extract((const char *)pResp);
892 strncpy(noti.short_name, net_name, 16);
893 noti.short_name[16] = '\0';
898 case 6: /* Full NITZ name */
899 case 4: /* Long Network Name (CPHS) */
900 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
901 if (strlen(pResp) > 0) {
902 net_name = tcore_at_tok_extract((const char *)pResp);
903 strncpy(noti.full_name, net_name, 32);
904 noti.full_name[32] = '\0';
917 tcore_at_tok_free(tokens);
920 dbg("plmn <%s> short NITZ name<%s> full NITZ name<%s>",
921 noti.plmn, noti.short_name, noti.full_name);
922 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
923 sizeof(struct tnoti_network_identity), ¬i);
930 dbg("Exit on_response_get_nitz_name");
933 static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
938 const TcoreATResponse *atResp = data;
939 GSList *tokens = NULL;
943 struct tresp_network_get_preferred_plmn resp = {0};
945 int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
949 if (atResp->success > 0) {
952 total_lines = g_slist_length(atResp->lines);
953 dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
955 if (total_lines < 1) {
956 msg("invalid message");
960 if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
961 total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
964 +CPOL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
965 +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
967 resp.result = TCORE_RETURN_SUCCESS;
969 for (i = 0; i < total_lines; i++) {
970 /* Take each line response at a time & parse it */
971 line = tcore_at_tok_nth(atResp->lines, i);
972 tokens = tcore_at_tok_new(line);
974 /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
977 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
978 dbg("Index : %s", pResp);
979 resp.list[i].index = atoi(pResp);
982 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
983 dbg("format : %s", pResp);
984 plmn_format = atoi(pResp);
987 /* Operator PLMN ID */
988 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
989 dbg("plmn ID : %s", pResp);
991 if (strlen(pResp) > 0) {
994 oper = tcore_at_tok_extract((const char *)pResp);
995 dbg("operator <%s>", oper);
998 if (plmn_format == 2) {
999 strncpy(resp.list[i].plmn, oper, 6);
1000 resp.list[i].plmn[6] = '\0';
1007 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
1008 dbg("GSM_AcT2 : %s", pResp);
1009 GSM_AcT2 = atoi(pResp);
1012 if ((pResp = tcore_at_tok_nth(tokens, 4))) {
1013 dbg("GSM_Compact AcT2 : %s", pResp);
1014 GSM_Compact_AcT2 = atoi(pResp);
1017 if ((pResp = tcore_at_tok_nth(tokens, 5))) {
1018 dbg("UTRAN_AcT2 : %s", pResp);
1019 UTRAN_AcT2 = atoi(pResp);
1022 if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
1023 resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
1024 else if (UTRAN_AcT2)
1025 resp.list[i].act = NETWORK_ACT_UMTS;
1026 else if (GSM_AcT2 || GSM_Compact_AcT2)
1027 resp.list[i].act = NETWORK_ACT_GPRS;
1029 (resp.list_count)++;
1031 tcore_at_tok_free(tokens);
1035 dbg("RESPONSE NOT OK");
1036 // TODO: CMEE error mapping is required.
1037 resp.result = TCORE_RETURN_FAILURE;
1041 ur = tcore_pending_ref_user_request(p);
1043 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
1049 static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
1051 const TcoreATResponse *resp = data;
1053 struct tresp_network_get_serving_network Tresp = {0};
1054 char *long_plmn_name = NULL;
1055 char *short_plmn_name = NULL;
1056 char *plmn_id = NULL;
1058 GSList *tokens = NULL;
1060 int network_mode = -1;
1061 int plmn_format = -1;
1063 struct tnoti_network_identity noti;
1067 o = tcore_pending_ref_core_object(p);
1069 if (resp->success <= 0) {
1070 dbg("RESPONSE NOK");
1072 ur = tcore_pending_ref_user_request(p);
1074 Tresp.result = TCORE_RETURN_FAILURE;
1075 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1081 nol = g_slist_length(resp->lines);
1082 dbg("nol : %d", nol);
1084 for (count = 0; count < nol; count++) {
1086 line = g_slist_nth_data(resp->lines, count);
1087 tokens = tcore_at_tok_new(line);
1088 dbg("line %d start---------------", count);
1090 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
1091 dbg("mode : %s", pResp);
1092 network_mode = atoi(pResp);
1095 // format (optional)
1096 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
1097 dbg("format : %s", pResp);
1098 if (strlen(pResp) > 0)
1099 plmn_format = atoi(pResp);
1103 switch (plmn_format) {
1104 case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
1105 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1106 dbg("long PLMN : %s", pResp);
1107 if (strlen(pResp) > 0) {
1108 long_plmn_name = tcore_at_tok_extract((const char *)pResp);
1110 // set network name into po
1111 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
1116 case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
1117 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1118 dbg("short PLMN : %s", pResp);
1119 if (strlen(pResp) > 0) {
1120 short_plmn_name = tcore_at_tok_extract((const char *)pResp);
1122 // set network name into po
1123 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
1128 case AT_COPS_FORMAT_NUMERIC:
1129 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1130 dbg("numeric : %s", pResp);
1131 if (strlen(pResp) > 0) {
1132 plmn_id = tcore_at_tok_extract((const char *)pResp);
1134 // set plmn id into po
1135 tcore_network_set_plmn(o, plmn_id);
1145 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
1146 dbg("AcT : %s", pResp);
1147 if (strlen(pResp) > 0) {
1149 tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
1153 tcore_at_tok_free(tokens);
1157 memcpy(Tresp.plmn, plmn_id, strlen(plmn_id));
1158 tcore_network_get_access_technology(o, &(Tresp.act));
1159 tcore_network_get_lac(o, &(Tresp.gsm.lac));
1161 ur = tcore_pending_ref_user_request(p);
1163 Tresp.result = TCORE_RETURN_SUCCESS;
1164 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1166 /* Network change noti */
1167 struct tnoti_network_change network_change;
1169 memset(&network_change, 0, sizeof(struct tnoti_network_change));
1171 memcpy(network_change.plmn, plmn_id, strlen(plmn_id));
1172 tcore_network_get_access_technology(o, &(network_change.act));
1173 tcore_network_get_lac(o, &(network_change.gsm.lac));
1175 tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
1176 TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
1177 dbg("dbg.. network_change.plmn : %s", network_change.plmn);
1178 dbg("dbg.. network_change.act : %d", network_change.act);
1179 dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
1181 if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
1182 (AT_COPS_MODE_SET_ONLY != network_mode)) {
1183 /*Network identity noti*/
1184 memset(¬i, 0x0, sizeof(struct tnoti_network_identity));
1186 memcpy(noti.full_name, long_plmn_name, MIN(32, strlen(long_plmn_name)));
1187 if (short_plmn_name)
1188 memcpy(noti.short_name, short_plmn_name, MIN(16, strlen(short_plmn_name)));
1190 memcpy(noti.plmn, plmn_id, strlen(plmn_id)); // plmn_id length is necessarily <= 6
1192 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1193 o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
1194 dbg("dbg.. noti.short_name : %s", noti.short_name);
1195 dbg("dbg.. noti.full_name : %s", noti.full_name);
1196 dbg("dbg.. noti.plmn : %s", noti.plmn);
1200 g_free(long_plmn_name);
1201 g_free(short_plmn_name);
1207 static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
1209 struct tnoti_network_registration_status regist_status;
1210 enum telephony_network_service_domain_status cs_status;
1211 enum telephony_network_service_domain_status ps_status;
1212 enum telephony_network_service_type service_type;
1213 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1214 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1215 struct tnoti_ps_protocol_status noti = {0};
1216 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
1217 int stat = 0, AcT = 0;
1218 unsigned int lac = 0xffff, ci = 0xffff;
1219 unsigned int rac = 0xffff;
1220 GSList *tokens = NULL;
1223 GSList *lines = NULL;
1225 lines = (GSList *) data;
1226 if (1 != g_slist_length(lines)) {
1227 dbg("unsolicited msg but multiple line");
1230 line = (char *) (lines->data);
1231 dbg("+CGREG NOTI RECEIVED");
1234 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1236 Possible values of <stat> can be
1237 0 Not registered, ME is not currently searching a new operator to register to
1238 1 Registered, home network
1239 2 Not registered, but ME is currently searching a new operator to register
1240 3 Registration denied
1242 5 Registered, in roaming
1245 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1248 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1256 6 UTRAN w/HSDPA and HSUPA
1257 Note: <Act> is supporting from R7 and above Protocol Stack.
1259 <rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
1262 tokens = tcore_at_tok_new(line);
1263 if (g_slist_length(tokens) < 1) {
1264 msg("invalid message");
1268 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1269 dbg("No STAT in +CGREG");
1273 if ((pResp = g_slist_nth_data(tokens, 1))) {
1274 pResp = util_removeQuotes(pResp);
1275 lac = strtol(pResp, NULL, 16);
1279 if ((pResp = g_slist_nth_data(tokens, 2))) {
1280 pResp = util_removeQuotes(pResp);
1281 ci = strtol(pResp, NULL, 16);
1284 dbg("No ci in +CGREG");
1287 if ((pResp = g_slist_nth_data(tokens, 3)))
1290 dbg("No AcT in +CGREG");
1292 if ((pResp = g_slist_nth_data(tokens, 4))) {
1293 pResp = util_removeQuotes(pResp);
1294 rac = strtol(pResp, NULL, 16);
1297 dbg("No rac in +CGREG");
1302 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
1304 ps_status = lookup_tbl_net_status[stat];
1306 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
1307 _ps_set(tcore_object_ref_plugin(o), ps_status);
1309 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1311 act = lookup_tbl_access_technology[AcT];
1312 tcore_network_set_access_technology(o, act);
1314 if (stat == AT_CREG_STAT_REG_ROAM)
1315 tcore_network_set_roaming_state(o, TRUE);
1317 tcore_network_set_roaming_state(o, FALSE);
1319 tcore_network_get_service_type(o, &service_type);
1320 dbg("prev_service_type = 0x%x", service_type);
1321 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1322 dbg("new_service_type = 0x%x", service_type);
1323 tcore_network_set_service_type(o, service_type);
1325 tcore_network_set_lac(o, lac);
1326 tcore_network_set_cell_id(o, ci);
1327 tcore_network_set_rac(o, rac);
1329 net_lac_cell_info.lac = lac;
1330 net_lac_cell_info.cell_id = ci;
1332 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1333 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1335 regist_status.cs_domain_status = cs_status;
1336 regist_status.ps_domain_status = ps_status;
1337 regist_status.service_type = service_type;
1338 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1340 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1341 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(regist_status), ®ist_status);
1343 if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
1344 noti.status = TELEPHONY_HSDPA_ON;
1346 noti.status = TELEPHONY_HSDPA_OFF;
1349 case AT_COPS_ACT_GSM:/*Fall Through*/
1350 case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
1351 case AT_COPS_ACT_UTRAN:/*Fall Through*/
1352 case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
1353 case AT_COPS_ACT_E_UTRAN:
1355 dbg("Not required for Protocol Status Notification");
1358 case AT_COPS_ACT_UTRAN_HSDPA:
1361 noti.status = TELEPHONY_HSDPA_ON;
1364 case AT_COPS_ACT_UTRAN_HSUPA:
1367 noti.status = TELEPHONY_HSUPA_ON;
1370 case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
1373 noti.status = TELEPHONY_HSPA_ON;
1383 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
1384 sizeof(struct tnoti_ps_protocol_status), ¬i);
1386 /* Get PLMN ID needed to application */
1387 // get_serving_network(o, NULL);
1389 dbg("Response NOK");
1394 tcore_at_tok_free(tokens);
1398 static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
1400 GSList *lines = NULL;
1402 struct tnoti_network_registration_status regist_status;
1403 enum telephony_network_service_domain_status cs_status;
1404 enum telephony_network_service_domain_status ps_status;
1405 enum telephony_network_service_type service_type;
1406 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1407 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1410 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
1411 int stat = 0, AcT = 0;
1412 unsigned int lac = 0xffff, ci = 0xffff;
1413 GSList *tokens = NULL;
1416 lines = (GSList *) event_info;
1417 if (1 != g_slist_length(lines)) {
1418 dbg("unsolicited msg but multiple line");
1421 line = (char *) (lines->data);
1423 dbg("+CREG NOTI RECEIVED");
1426 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1428 Possible values of <stat> can be
1429 0 Not registered, ME is not currently searching a new operator to register to
1430 1 Registered, home network
1431 2 Not registered, but ME is currently searching a new operator to register
1432 3 Registration denied
1434 5 Registered, in roaming
1437 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1440 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1448 6 UTRAN w/HSDPA and HSUPA
1449 Note: <Act> is supporting from R7 and above Protocol Stack.
1452 tokens = tcore_at_tok_new(line);
1453 if (g_slist_length(tokens) < 1) {
1454 msg("invalid message");
1458 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1459 dbg("No STAT in +CREG");
1463 if ((pResp = g_slist_nth_data(tokens, 1))) {
1464 pResp = util_removeQuotes(pResp);
1465 lac = strtol(pResp, NULL, 16);
1469 if ((pResp = g_slist_nth_data(tokens, 2))) {
1470 pResp = util_removeQuotes(pResp);
1471 ci = strtol(pResp, NULL, 16);
1474 dbg("No ci in +CREG");
1477 if ((pResp = g_slist_nth_data(tokens, 3)))
1480 dbg("No AcT in +CREG");
1484 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
1486 cs_status = lookup_tbl_net_status[stat];
1487 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
1489 // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1490 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
1492 act = lookup_tbl_access_technology[AcT];
1493 tcore_network_set_access_technology(o, act);
1495 if (stat == AT_CREG_STAT_REG_ROAM)
1496 tcore_network_set_roaming_state(o, TRUE);
1498 tcore_network_set_roaming_state(o, FALSE);
1500 tcore_network_get_service_type(o, &service_type);
1501 dbg("prev_service_type = 0x%x", service_type);
1502 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1503 dbg("new_service_type = 0x%x", service_type);
1504 tcore_network_set_service_type(o, service_type);
1506 tcore_network_set_lac(o, lac);
1507 tcore_network_set_cell_id(o, ci);
1509 net_lac_cell_info.lac = lac;
1510 net_lac_cell_info.cell_id = ci;
1512 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1513 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1515 regist_status.cs_domain_status = cs_status;
1516 regist_status.ps_domain_status = ps_status;
1517 regist_status.service_type = service_type;
1518 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1520 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1521 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1523 /* Get PLMN ID needed to application */
1524 if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
1525 NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
1526 get_serving_network(o, NULL);
1528 dbg("Response NOK");
1533 tcore_at_tok_free(tokens);
1537 static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
1539 struct tnoti_network_icon_info net_icon_info = {0};
1541 char *rssiToken = NULL;
1542 char *batteryToken = NULL;
1543 GSList *tokens = NULL;
1544 GSList *lines = NULL;
1546 lines = (GSList *) event_info;
1547 if (1 != g_slist_length(lines)) {
1548 dbg("unsolicited msg but multiple line");
1551 line = (char *) (lines->data);
1552 dbg("+XCIEV Network Icon Info Noti Recieve");
1553 memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
1558 tokens = tcore_at_tok_new(line);
1559 if (g_slist_length(tokens) != 2) {
1560 msg("invalid message");
1564 rssiToken = (char *) g_slist_nth_data(tokens, 0);
1566 if (strlen(rssiToken) > 0) {
1567 net_icon_info.type = NETWORK_ICON_INFO_RSSI;
1568 net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
1569 dbg("rssi level : %d", net_icon_info.rssi);
1572 batteryToken = (char *) g_slist_nth_data(tokens, 1);
1573 if (strlen(batteryToken) > 0) {
1574 net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
1575 net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
1576 dbg("battery level : %d", net_icon_info.battery);
1579 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
1580 sizeof(struct tnoti_network_icon_info), &net_icon_info);
1582 dbg("Response NOK");
1588 tcore_at_tok_free(tokens);
1593 static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
1595 struct tnoti_network_timeinfo net_time_info = {0};
1597 GSList *tokens = NULL;
1599 char *time_zone = NULL;
1600 GSList *lines = NULL;
1601 char ptime_param[20] = {0};
1602 UserRequest *ur = NULL;
1603 dbg("Enter : on_event_network_ctzv_time_info");
1605 lines = (GSList *) event_info;
1606 if (1 != g_slist_length(lines)) {
1607 dbg("unsolicited msg but multiple line");
1610 line = (char *) (lines->data);
1614 <tz> integer value indicating the time zone (e.g. -22 or +34)
1615 <time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
1618 dbg("Network time info (+CTZV) recieved");
1622 dbg("noti line is %s", line);
1624 tokens = tcore_at_tok_new(line);
1626 if (g_slist_length(tokens) < 2) {
1627 msg("invalid message");
1631 if ((time_zone = g_slist_nth_data(tokens, 0))) {
1632 net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
1635 if (tcore_network_get_plmn(o) != NULL)
1636 strcpy(net_time_info.plmn, tcore_network_get_plmn(o));
1638 if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
1639 strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
1640 net_time_info.year = atoi(ptime_param);
1642 strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
1643 net_time_info.month = atoi(ptime_param);
1645 strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
1646 net_time_info.day = atoi(ptime_param);
1648 strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
1649 net_time_info.hour = atoi(ptime_param);
1651 strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
1652 net_time_info.minute = atoi(ptime_param);
1654 strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
1655 net_time_info.second = atoi(ptime_param);
1657 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_TIMEINFO, sizeof(struct tnoti_network_timeinfo), &net_time_info);
1659 dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
1661 /* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
1662 nwk_prepare_and_send_pending_request(o, "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
1664 dbg("line is NULL");
1669 tcore_at_tok_free(tokens);
1671 dbg("Exit: on_event_network_ctzv_time_info");
1675 static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
1676 const void *data, void *user_data)
1678 const struct tresp_sim_read *resp = data;
1679 CoreObject *o = user_data;
1681 if (command == TRESP_SIM_GET_SPN) {
1682 dbg("OK SPN GETTING!!");
1683 dbg("resp->result = 0x%x", resp->result);
1684 dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
1685 dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
1687 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *) resp->data.spn.spn);
1691 * bit[0]: 0 = display of registered PLMN name not required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
1692 * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
1693 * bit[1]: 0 = display of the service provider name is required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
1694 * 1 = display of the service provider name is not required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
1696 if (resp->data.spn.display_condition & 0x01) {
1697 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1699 if ((resp->data.spn.display_condition & 0x02) == 0) {
1700 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
1702 if ((resp->data.spn.display_condition & 0x03) == 0x01) {
1703 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
1706 // fallback in case no SPN name is provided
1707 if (resp->data.spn.spn[0] == '\0')
1708 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1712 static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
1713 unsigned int data_len, void *data, void *user_data)
1715 const struct tnoti_sim_status *sim = data;
1716 UserRequest *ur = NULL;
1718 if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
1719 ur = tcore_user_request_new(NULL, NULL);
1720 tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
1721 tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
1722 tcore_object_dispatch_request(source, ur);
1725 return TCORE_HOOK_RETURN_CONTINUE;
1728 static TReturn search_network(CoreObject *o, UserRequest *ur)
1731 TcorePending *pending = NULL;
1732 TcoreATRequest *atreq = NULL;
1733 char *cmd_str = NULL;
1734 dbg("search_network - ENTER!!");
1737 return TCORE_RETURN_EINVAL;
1739 h = tcore_object_get_hal(o);
1740 if(FALSE == tcore_hal_get_power_state(h)){
1741 dbg("cp not ready/n");
1742 return TCORE_RETURN_ENOSYS;
1745 pending = tcore_pending_new(o, 0);
1747 cmd_str = g_strdup_printf("AT+COPS=?");
1748 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1750 tcore_pending_set_request_data(pending, 0, atreq);
1751 tcore_pending_set_timeout(pending, 60);
1752 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1753 tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
1754 tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
1755 tcore_pending_link_user_request(pending, ur);
1756 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1758 tcore_hal_send_request(h, pending);
1760 return TCORE_RETURN_SUCCESS;
1763 static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1766 TcorePending *pending = NULL;
1767 TcoreATRequest *atreq;
1768 char *cmd_str = NULL;
1769 int format = 0; /* default value for long alphanumeric */
1774 const struct treq_network_set_plmn_selection_mode *req_data = NULL;
1777 dbg("set_plmn_selection_mode - ENTER!!");
1780 return TCORE_RETURN_EINVAL;
1782 req_data = tcore_user_request_ref_data(ur, NULL);
1783 h = tcore_object_get_hal(o);
1784 if(FALSE == tcore_hal_get_power_state(h)){
1785 dbg("cp not ready/n");
1786 return TCORE_RETURN_ENOSYS;
1788 pending = tcore_pending_new(o, 0);
1790 // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
1791 /* oper parameter format
1792 - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
1793 - 1 <oper> format presentation is set to short alphanumeric.
1794 - 2 <oper> format presentations set to numeric.
1797 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
1802 switch (req_data->mode) {
1803 case NETWORK_SELECT_MODE_MANUAL:
1805 mode = AT_COPS_MODE_MANUAL;
1806 format = AT_COPS_FORMAT_NUMERIC;
1809 memcpy(plmn, req_data->plmn, 6);
1811 if (strlen(req_data->plmn) == 6) {
1816 cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
1820 case NETWORK_SELECT_MODE_AUTOMATIC:
1822 cmd_str = g_strdup("AT+COPS=0");
1827 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
1829 tcore_pending_set_request_data(pending, 0, atreq);
1830 tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
1831 tcore_pending_link_user_request(pending, ur);
1832 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1834 tcore_hal_send_request(h, pending);
1836 return TCORE_RETURN_SUCCESS;
1839 static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1842 TcorePending *pending = NULL;
1843 TcoreATRequest *atreq;
1844 char *cmd_str = NULL;
1846 dbg("get_plmn_selection_mode - ENTER!!");
1849 return TCORE_RETURN_EINVAL;
1851 h = tcore_object_get_hal(o);
1852 if(FALSE == tcore_hal_get_power_state(h)){
1853 dbg("cp not ready/n");
1854 return TCORE_RETURN_ENOSYS;
1856 pending = tcore_pending_new(o, 0);
1858 cmd_str = g_strdup_printf("AT+COPS?");
1859 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1861 tcore_pending_set_request_data(pending, 0, atreq);
1862 tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
1863 tcore_pending_link_user_request(pending, ur);
1864 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1866 tcore_hal_send_request(h, pending);
1868 return TCORE_RETURN_SUCCESS;
1872 static TReturn set_band(CoreObject *o, UserRequest *ur)
1875 TcorePending *pending = NULL;
1876 TcorePending *pending_gsm = NULL;
1877 TcorePending *pending_umts = NULL;
1878 TcoreATRequest *atreq;
1879 char *cmd_str = NULL;
1880 const struct treq_network_set_band *req_data;
1881 gboolean set_gsm_band = 0;
1882 gboolean set_umts_band = 0;
1884 int gsm_band2 = 255;
1885 char *umts_band = NULL;
1886 UserRequest *dup_ur_gsm = NULL;
1887 UserRequest *dup_ur_umts = NULL;
1889 dbg("set_band - ENTER!!");
1892 return TCORE_RETURN_EINVAL;
1894 req_data = tcore_user_request_ref_data(ur, NULL);
1895 h = tcore_object_get_hal(o);
1896 if(FALSE == tcore_hal_get_power_state(h)){
1897 dbg("cp not ready/n");
1898 return TCORE_RETURN_ENOSYS;
1901 dbg("set_band - called with band = %d", req_data->band);
1903 switch (req_data->band) {
1904 case NETWORK_BAND_TYPE_GSM850:
1905 gsm_band = AT_GSM_XBANDSEL_850;
1906 set_gsm_band = TRUE;
1909 case NETWORK_BAND_TYPE_GSM_900_1800:
1910 gsm_band = AT_GSM_XBANDSEL_900;
1911 gsm_band2 = AT_GSM_XBANDSEL_1800;
1912 set_gsm_band = TRUE;
1915 case NETWORK_BAND_TYPE_GSM1900:
1916 gsm_band = AT_GSM_XBANDSEL_1900;
1917 set_gsm_band = TRUE;
1920 case NETWORK_BAND_TYPE_GSM1800:
1921 gsm_band = AT_GSM_XBANDSEL_1800;
1922 set_gsm_band = TRUE;
1925 case NETWORK_BAND_TYPE_GSM_850_1900:
1926 gsm_band = AT_GSM_XBANDSEL_850;
1927 gsm_band2 = AT_GSM_XBANDSEL_1900;
1928 set_gsm_band = TRUE;
1931 case NETWORK_BAND_TYPE_ANY:
1932 gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
1933 set_umts_band = TRUE;
1934 set_gsm_band = TRUE;
1937 case NETWORK_BAND_TYPE_WCDMA:
1938 set_umts_band = TRUE;
1941 case NETWORK_BAND_TYPE_WCDMA2100:
1942 umts_band = "UMTS_BAND_I";
1943 set_umts_band = TRUE;
1946 case NETWORK_BAND_TYPE_WCDMA1900:
1947 umts_band = "UMTS_BAND_II";
1948 set_umts_band = TRUE;
1951 case NETWORK_BAND_TYPE_WCDMA850:
1952 umts_band = "UMTS_BAND_V";
1953 set_umts_band = TRUE;
1960 dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
1962 if (set_umts_band == TRUE) {
1963 if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
1964 cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
1966 cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
1968 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
1969 pending_umts = tcore_pending_new(o, 0);
1971 tcore_pending_set_request_data(pending_umts, 0, atreq);
1972 tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
1973 tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
1975 /* duplicate user request for UMTS Band setting AT command for same UR */
1976 dup_ur_umts = tcore_user_request_ref(ur);
1977 tcore_pending_link_user_request(pending_umts, dup_ur_umts);
1978 tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
1980 tcore_hal_send_request(h, pending_umts);
1984 if (set_gsm_band == TRUE) {
1985 dbg("Entered set_gsm_band");
1986 if (gsm_band2 == 255)
1987 cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
1989 cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
1991 dbg("Command string: %s", cmd_str);
1992 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
1993 pending_gsm = tcore_pending_new(o, 0);
1995 tcore_pending_set_request_data(pending_gsm, 0, atreq);
1996 tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
1997 tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
1999 /* duplicate user request for GSM Band setting AT command for same UR */
2000 dup_ur_gsm = tcore_user_request_ref(ur);
2001 tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
2002 tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
2004 tcore_hal_send_request(h, pending_gsm);
2008 /* Lock device to specific RAT as requested by application */
2010 AT+XRAT=<Act>[,<PreferredAct>]
2011 <AcT> indicates the radio access technology and may be
2013 1 GSM / UMTS Dual mode
2016 if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
2017 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
2018 } else if (set_umts_band == TRUE) {
2019 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
2021 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
2023 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
2024 pending = tcore_pending_new(o, 0);
2026 tcore_pending_set_request_data(pending, 0, atreq);
2027 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2028 tcore_pending_set_response_callback(pending, on_response_set_xrat, NULL);
2029 tcore_pending_link_user_request(pending, ur);
2030 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2032 tcore_hal_send_request(h, pending);
2034 return TCORE_RETURN_SUCCESS;
2037 static TReturn get_band(CoreObject *o, UserRequest *ur)
2040 TcorePending *pending = NULL;
2041 TcoreATRequest *atreq;
2042 char *cmd_str = NULL;
2043 dbg("get_band - ENTER!!");
2046 return TCORE_RETURN_EINVAL;
2048 h = tcore_object_get_hal(o);
2049 if(FALSE == tcore_hal_get_power_state(h)){
2050 dbg("cp not ready/n");
2051 return TCORE_RETURN_ENOSYS;
2054 /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
2055 cmd_str = g_strdup_printf("AT+XRAT?");
2056 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
2057 pending = tcore_pending_new(o, 0);
2058 tcore_pending_set_request_data(pending, 0, atreq);
2059 tcore_pending_set_response_callback(pending, on_response_get_xrat, NULL);
2060 tcore_pending_link_user_request(pending, ur);
2061 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2062 tcore_hal_send_request(h, pending);
2065 return TCORE_RETURN_SUCCESS;
2068 static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
2071 TcorePlugin *p = NULL;
2072 TcorePending *pending = NULL;
2073 TcoreATRequest *atreq = NULL;
2074 struct treq_network_set_preferred_plmn *req_data = NULL;
2075 char *cmd_str = NULL;
2076 int format = 2; /* Alway use numeric format, as application gives data in this default format */
2078 int gsm_compact_act = 0;
2082 return TCORE_RETURN_EINVAL;
2084 p = tcore_object_ref_plugin(o);
2085 h = tcore_object_get_hal(o);
2086 if(FALSE == tcore_hal_get_power_state(h)){
2087 dbg("cp not ready/n");
2088 return TCORE_RETURN_ENOSYS;
2091 req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
2092 pending = tcore_pending_new(o, 0);
2094 dbg("Entry set_preferred_plmn");
2097 [<index>][,<format>[,<oper>[,<GSM_AcT>,
2098 <GSM_Compact_AcT>,<UTRAN_AcT>]]]
2101 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
2103 else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
2105 else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
2106 gsm_act = utran_act = TRUE;
2108 if (strlen(req_data->plmn) > 6) {
2109 req_data->plmn[6] = '\0';
2110 } else if (strlen(req_data->plmn) == 6) {
2111 if (req_data->plmn[5] == '#') {
2112 req_data->plmn[5] = '\0';
2115 cmd_str = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d", req_data->index + 1, format, req_data->plmn, gsm_act, gsm_compact_act, utran_act);
2117 dbg("cmd_str - %s", cmd_str);
2118 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
2120 tcore_pending_set_request_data(pending, 0, atreq);
2121 tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, NULL);
2122 tcore_pending_link_user_request(pending, ur);
2123 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2125 tcore_hal_send_request(h, pending);
2129 dbg("Exit set_preferred_plmn");
2131 return TCORE_RETURN_SUCCESS;
2134 static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
2137 TcorePending *pending = NULL;
2138 TcoreATRequest *atreq = NULL;
2140 char *cmd_str = NULL;
2142 dbg("get_preferred_plmn - ENTER!!");
2145 return TCORE_RETURN_EINVAL;
2147 h = tcore_object_get_hal(o);
2148 if(FALSE == tcore_hal_get_power_state(h)){
2149 dbg("cp not ready/n");
2150 return TCORE_RETURN_ENOSYS;
2153 pending = tcore_pending_new(o, 0);
2155 cmd_str = g_strdup_printf("AT+CPOL=,2;+CPOL?");
2156 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
2158 tcore_pending_set_request_data(pending, 0, atreq);
2159 tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
2160 tcore_pending_link_user_request(pending, ur);
2161 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2163 tcore_hal_send_request(h, pending);
2167 dbg("get_preferred_plmn - EXIT!!");
2169 return TCORE_RETURN_SUCCESS;
2172 static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
2174 dbg("get_serving_network - ENTER!!");
2177 return TCORE_RETURN_EINVAL;
2179 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2180 dbg("cp not ready/n");
2181 return TCORE_RETURN_ENOSYS;
2184 dbg("new pending(AT+COPS?)");
2186 nwk_prepare_and_send_pending_request(o, "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
2187 return TCORE_RETURN_SUCCESS;
2190 static struct tcore_network_operations network_ops = {
2191 .search = search_network,
2192 .set_plmn_selection_mode = set_plmn_selection_mode,
2193 .get_plmn_selection_mode = get_plmn_selection_mode,
2194 .set_service_domain = NULL,
2195 .get_service_domain = NULL,
2196 .set_band = set_band,
2197 .get_band = get_band,
2198 .set_preferred_plmn = set_preferred_plmn,
2199 .get_preferred_plmn = get_preferred_plmn,
2202 .set_power_on_attach = NULL,
2203 .get_power_on_attach = NULL,
2204 .set_cancel_manual_search = NULL,
2205 .get_serving_network = get_serving_network,
2208 gboolean s_network_init(TcorePlugin *cp, CoreObject *co_network)
2212 tcore_network_override_ops(co_network, &network_ops);
2214 tcore_object_override_callback(co_network, "+CREG", on_event_cs_network_regist, NULL);
2215 tcore_object_override_callback(co_network, "+CGREG", on_event_ps_network_regist, NULL);
2216 tcore_object_override_callback(co_network, "+XCIEV", on_event_network_icon_info, NULL);
2218 /* +CTZV: <tz>,<time> */
2219 tcore_object_override_callback(co_network, "+CTZV", on_event_network_ctzv_time_info, NULL);
2221 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co_network);
2223 _insert_mcc_mnc_oper_list(cp, co_network);
2230 void s_network_exit(TcorePlugin *cp, CoreObject *co_network)