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>
41 #include "s_network.h"
43 #define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
44 #define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
45 #define AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
46 #define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
47 #define AT_CREG_STAT_UNKNOWN 4 /* unknown */
48 #define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
50 #define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
51 #define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
52 #define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
53 #define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
54 #define AT_COPS_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
56 #define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
57 #define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
58 #define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
60 #define AT_COPS_ACT_GSM 0 /* GSM */
61 #define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
62 #define AT_COPS_ACT_UTRAN 2 /* UTRAN */
63 #define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
64 #define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
65 #define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
66 #define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
67 #define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
69 #define AT_GSM_XBANDSEL_AUTOMATIC 0
70 #define AT_GSM_XBANDSEL_1800 1800
71 #define AT_GSM_XBANDSEL_1900 1900
72 #define AT_GSM_XBANDSEL_900 900
73 #define AT_GSM_XBANDSEL_850 850
74 #define AT_GSM_XBANDSEL_450 450
75 #define AT_GSM_XBANDSEL_480 480
76 #define AT_GSM_XBANDSEL_750 750
77 #define AT_GSM_XBANDSEL_380 380
78 #define AT_GSM_XBANDSEL_410 410
81 #define AT_XRAT_DUAL 1
82 #define AT_XRAT_UMTS 2
84 #define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
85 #define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
87 static unsigned int lookup_tbl_net_status[] = {
88 [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
89 [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
90 [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
91 [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
92 [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
93 [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
96 static unsigned int lookup_tbl_access_technology[] = {
97 [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
98 [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
99 [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
100 [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
101 [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
102 [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
103 [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
104 [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
107 static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
110 static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
112 dbg("on_confirmation_modem_message_send - msg out from queue.\n");
114 if (result == FALSE) {
122 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)
124 TcoreATRequest *req = NULL;
126 TcorePending *pending = NULL;
129 hal = tcore_object_get_hal(co);
131 pending = tcore_pending_new(co, 0);
132 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
134 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
136 tcore_pending_set_request_data(pending, 0, req);
137 tcore_pending_set_response_callback(pending, callback, req->cmd);
138 tcore_pending_link_user_request(pending, ur);
139 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
141 ret = tcore_hal_send_request(hal, pending);
146 static void _insert_mcc_mnc_oper_list(TcorePlugin *p, CoreObject *o)
151 char query[255] = { 0, };
154 GHashTable *result = NULL, *row = NULL;
155 struct tcore_network_operator_info *noi = NULL;
158 s = tcore_plugin_ref_server(p);
159 strg = tcore_server_find_storage(s, "database");
161 handle = tcore_storage_create_handle(strg, "/opt/dbspace/.mcc_mnc_oper_list.db");
163 dbg("fail to create database handle");
167 snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
169 result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
170 (GDestroyNotify) g_hash_table_destroy);
172 tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
174 g_hash_table_iter_init(&iter, result);
175 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
178 noi = calloc(sizeof(struct tcore_network_operator_info), 1);
180 snprintf(noi->mcc, 4, "%s", (char *) g_hash_table_lookup(row, "1"));
181 snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
182 snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
183 snprintf(noi->country, 4, "%s", (char *) g_hash_table_lookup(row, "0"));
185 tcore_network_operator_info_add(o, noi);
190 dbg("count = %d", count);
192 g_hash_table_destroy(result);
194 tcore_storage_remove_handle(strg, handle);
197 static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
198 int domain, int act, int cs_status, int ps_status)
200 enum telephony_network_service_type ret;
205 case NETWORK_ACT_UNKNOWN:
206 ret = NETWORK_SERVICE_TYPE_UNKNOWN;
209 case NETWORK_ACT_GSM:
210 if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
211 ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
213 ret = NETWORK_SERVICE_TYPE_2G;
216 case NETWORK_ACT_EGPRS:
217 return NETWORK_SERVICE_TYPE_2_5G_EDGE;
220 case NETWORK_ACT_UMTS:
221 ret = NETWORK_SERVICE_TYPE_3G;
225 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
226 ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
227 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
228 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
231 ret = NETWORK_SERVICE_TYPE_SEARCH;
233 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
234 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
237 ret = NETWORK_SERVICE_TYPE_EMERGENCY;
244 static void _ps_set(TcorePlugin *p, int status)
248 co_ps = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PS);
250 err("No PS Core Object on plugin");
254 if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
255 tcore_ps_set_online(co_ps, TRUE);
257 tcore_ps_set_online(co_ps, FALSE);
260 static void on_timeout_search_network(TcorePending *p, void *user_data)
263 struct tresp_network_search resp;
265 dbg("TIMEOUT !!!!! pending=%p", p);
267 memset(&resp, 0, sizeof(struct tresp_network_search));
269 resp.result = TCORE_RETURN_FAILURE;
272 ur = tcore_pending_ref_user_request(p);
274 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
278 static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
281 const TcoreATResponse *atResp = data;
282 // GSList *tokens = NULL;
283 // char * line = NULL;
284 struct tresp_network_set_plmn_selection_mode resp = {0};
286 if (atResp->success > 0) {
288 resp.result = TCORE_RETURN_SUCCESS;
291 resp.result = TCORE_RETURN_FAILURE;
294 ur = tcore_pending_ref_user_request(p);
296 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
300 static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
303 struct tresp_network_get_plmn_selection_mode resp = {0};
304 const TcoreATResponse *atResp = data;
305 GSList *tokens = NULL;
309 resp.result = TCORE_RETURN_FAILURE;
311 if (atResp->success > 0) {
314 +COPS: <mode>[,<format>,<oper>[,< AcT>]]
318 line = (char *) atResp->lines->data;
319 tokens = tcore_at_tok_new(line);
320 if (g_slist_length(tokens) < 1) {
321 msg("invalid message");
324 mode = atoi(tcore_at_tok_nth(tokens, 0));
325 dbg("mode = %d", mode);
328 case AT_COPS_MODE_AUTOMATIC:
329 resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
332 case AT_COPS_MODE_MANUAL:
333 case AT_COPS_MODE_MANUAL_AUTOMATIC:
334 resp.mode = NETWORK_SELECT_MODE_MANUAL;
337 case AT_COPS_MODE_DEREGISTER:
338 case AT_COPS_MODE_SET_ONLY:
339 resp.result = TCORE_RETURN_FAILURE;
342 resp.result = TCORE_RETURN_SUCCESS;
346 resp.result = TCORE_RETURN_FAILURE;
350 ur = tcore_pending_ref_user_request(p);
352 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
356 tcore_at_tok_free(tokens);
361 static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
364 struct tresp_network_search resp;
367 const TcoreATResponse *atResp = data;
368 GSList *tokens = NULL;
369 GSList *network_token = NULL;
371 char *temp_plmn_info = NULL;
372 char *alpha_name = NULL;
374 int num_network_avail = 0;
376 memset(&resp, 0, sizeof(struct tresp_network_search));
377 resp.result = TCORE_RETURN_FAILURE;
380 if (atResp->success > 0) {
383 line = (char *) atResp->lines->data;
384 tokens = tcore_at_tok_new(line);
385 num_network_avail = g_slist_length(tokens);
386 dbg(" length of tokens is %d\n", num_network_avail);
387 if (num_network_avail < 1) {
388 msg("invalid message");
393 resp.result = TCORE_RETURN_SUCCESS;
395 * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
396 * [,,(list of supported <mode>s),(list of supported <format>s)]
399 for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
400 network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
402 pResp = (tcore_at_tok_nth(network_token, 0));
404 dbg("status : %s", pResp);
405 resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
408 if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Alpha name */
409 dbg("Long Alpha name : %s", pResp);
411 if (strlen(pResp) > 0)
412 /* Strip off starting quote & ending quote */
413 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
416 if ((pResp = tcore_at_tok_nth(network_token, 2))) {
417 dbg("Short Aplha name : %s", pResp);
418 /* Short Aplha name */
419 /* Strip off starting quote & ending quote */
420 if (strlen(pResp) > 0)
421 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
425 pResp = tcore_at_tok_nth(network_token, 3);
427 dbg("PLMN ID : %s", pResp);
428 temp_plmn_info = tcore_at_tok_extract((const char *)pResp);
429 strncpy(resp.list[i].plmn, temp_plmn_info, 6);
430 resp.list[i].plmn[6] = '\0';
433 /* Parse Access Technology */
434 if ((pResp = tcore_at_tok_nth(network_token, 4))) {
435 if (strlen(pResp) > 0) {
439 resp.list[i].act = NETWORK_ACT_GSM;
441 resp.list[i].act = NETWORK_ACT_UMTS;
445 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);
448 tcore_at_tok_free(network_token);
450 g_free(temp_plmn_info);
454 resp.result = TCORE_RETURN_FAILURE;
458 ur = tcore_pending_ref_user_request(p);
460 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
464 tcore_at_tok_free(tokens);
467 static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
469 const TcoreATResponse *atResp = data;
471 dbg("On Response Set UMTS Band");
473 if (atResp->success > 0) {
479 dbg("Wait for response of XRAT before sending final band setting response to AP");
484 static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
486 const TcoreATResponse *atResp = data;
488 dbg("On Response Set GSM Band");
489 if (atResp->success > 0) {
495 dbg("Wait for response of XRAT before sending final band setting response to AP");
499 static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
501 const TcoreATResponse *atResp = data;
502 GSList *tokens = NULL;
503 const char *line = NULL;
504 int total_umts_bands = 0;
506 char *band_token = NULL;
507 char umts_band[20] = {0};
508 char umts_band_1 = 0;
509 char umts_band_2 = 0;
510 char umts_band_5 = 0;
511 UserRequest *ur = NULL;
512 struct tresp_network_get_band resp = {0};
514 dbg("Entry on_response_get_umts_band");
516 resp.mode = NETWORK_BAND_MODE_PREFERRED;
517 resp.result = TCORE_RETURN_SUCCESS;
519 if (atResp->success > 0) {
522 line = (char *) atResp->lines->data;
523 tokens = tcore_at_tok_new(line);
524 total_umts_bands = g_slist_length(tokens);
525 dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
526 if (total_umts_bands < 1) {
535 for (i = 0; i < total_umts_bands; i++) {
536 band_token = tcore_at_tok_nth(tokens, i);
538 if (band_token == NULL)
541 memset(umts_band, 0x00, sizeof(umts_band));
543 if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
544 umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
548 /* Strip off starting quotes & ending quotes */
549 strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
551 if (!strcmp(umts_band, "UMTS_BAND_I")) {
553 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
555 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
558 /* Telephony is not interest */
559 dbg("Telephony is not interested in %s band", umts_band);
564 if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
565 resp.band = NETWORK_BAND_TYPE_WCDMA;
566 } else if (umts_band_1) {
567 resp.band = NETWORK_BAND_TYPE_WCDMA2100;
568 } else if (umts_band_2) {
569 resp.band = NETWORK_BAND_TYPE_WCDMA1900;
570 } else if (umts_band_5) {
571 resp.band = NETWORK_BAND_TYPE_WCDMA850;
573 resp.result = TCORE_RETURN_FAILURE;
576 dbg("Final resp.band sent to TS = %d", resp.band);
578 ur = tcore_pending_ref_user_request(p);
580 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
584 tcore_at_tok_free(tokens);
586 dbg("Exit on_response_get_umts_band");
590 static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
592 struct tresp_network_get_band resp = {0};
593 const TcoreATResponse *atResp = data;
594 GSList *tokens = NULL;
595 int total_gsm_bands = 0;
596 const char *line = NULL;
598 char *band_token = NULL;
599 UserRequest *ur = NULL;
605 dbg("Entry on_response_get_gsm_band");
607 resp.mode = NETWORK_BAND_MODE_PREFERRED;
608 resp.result = TCORE_RETURN_SUCCESS;
610 if (atResp->success > 0) {
613 line = (char *) atResp->lines->data;
614 tokens = tcore_at_tok_new(line);
615 total_gsm_bands = g_slist_length(tokens);
616 dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
617 if (total_gsm_bands < 1)
622 for (i = 0; i < total_gsm_bands; i++) {
623 band_token = tcore_at_tok_nth(tokens, i);
625 if (band_token == NULL)
628 if (atoi(band_token) == 0) { /* 0 means GSM automatic */
629 gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
633 switch (atoi(band_token)) {
634 case AT_GSM_XBANDSEL_850:
638 case AT_GSM_XBANDSEL_900:
642 case AT_GSM_XBANDSEL_1800:
646 case AT_GSM_XBANDSEL_1900:
657 if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
658 resp.band = NETWORK_BAND_TYPE_GSM;
659 } else if (gsm_850 && gsm_1900) {
660 resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
661 } else if (gsm_900 && gsm_1800) {
662 resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
663 } else if (gsm_1900) {
664 resp.band = NETWORK_BAND_TYPE_GSM1900;
665 } else if (gsm_850) {
666 resp.band = NETWORK_BAND_TYPE_GSM850;
667 } else if (gsm_1800) {
668 resp.band = NETWORK_BAND_TYPE_GSM1800;
669 } else if (gsm_900) {
670 resp.band = NETWORK_BAND_TYPE_GSM900;
672 resp.result = TCORE_RETURN_FAILURE;
675 dbg("Final resp.band sent to TS = %d", resp.band);
677 ur = tcore_pending_ref_user_request(p);
679 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
683 tcore_at_tok_free(tokens);
685 dbg("Exit on_response_get_gsm_band");
690 static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
693 UserRequest *ur = NULL;
695 TcoreATRequest *atreq;
696 char *cmd_str = NULL;
697 UserRequest *dup_ur = NULL;
698 const TcoreATResponse *atResp = data;
699 const char *line = NULL;
701 GSList *tokens = NULL;
702 TcorePending *pending = NULL;
703 CoreObject *o = NULL;
705 struct tresp_network_get_band resp = {0};
707 dbg("Enter on_response_get_xrat !!");
709 resp.mode = NETWORK_BAND_MODE_PREFERRED;
711 ur = tcore_pending_ref_user_request(p);
712 h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
713 o = tcore_pending_ref_core_object(p);
715 if (atResp->success > 0) {
718 line = (char *) atResp->lines->data;
719 tokens = tcore_at_tok_new(line);
720 if (g_slist_length(tokens) < 1) {
721 msg("invalid message");
726 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
727 cp_xrat = atoi(pResp);
729 if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
730 resp.result = TCORE_RETURN_SUCCESS;
731 resp.band = NETWORK_BAND_TYPE_ANY;
733 ur = tcore_pending_ref_user_request(p);
735 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
738 } else if ((cp_xrat == AT_XRAT_UMTS)) {
739 /* Get UMTS Band Information */
740 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
741 cmd_str = g_strdup_printf("AT+XUBANDSEL?");
742 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
743 pending = tcore_pending_new(o, 0);
744 tcore_pending_set_request_data(pending, 0, atreq);
745 tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
746 tcore_pending_link_user_request(pending, ur);
747 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
748 tcore_hal_send_request(h, pending);
750 } else if ((cp_xrat == AT_XRAT_UMTS)) {
751 /* Get GSM Band Information */
752 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
753 cmd_str = g_strdup_printf("AT+XBANDSEL?");
754 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
755 pending = tcore_pending_new(o, 0);
756 tcore_pending_set_request_data(pending, 0, atreq);
757 tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
758 tcore_pending_link_user_request(pending, dup_ur);
759 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
760 tcore_hal_send_request(h, pending);
767 resp.result = TCORE_RETURN_FAILURE;
768 resp.band = NETWORK_BAND_TYPE_ANY;
770 ur = tcore_pending_ref_user_request(p);
772 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
778 tcore_at_tok_free(tokens);
780 dbg("Exit on_response_get_xrat !!");
786 static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
788 UserRequest *ur = NULL;
789 struct tresp_network_set_band resp = {0};
790 const TcoreATResponse *atResp = data;
792 dbg("On Response Set XRAT");
794 if (atResp->success > 0) {
796 resp.result = TCORE_RETURN_SUCCESS;
799 resp.result = TCORE_RETURN_FAILURE;
802 ur = tcore_pending_ref_user_request(p);
804 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
810 static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
812 UserRequest *ur = NULL;
813 struct tresp_network_set_preferred_plmn resp = {0};
814 const TcoreATResponse *atResp = data;
816 dbg("ENTER on_response_set_preferred_plmn");
818 if (atResp->success > 0) {
820 resp.result = TCORE_RETURN_SUCCESS;
823 resp.result = TCORE_RETURN_FAILURE;
826 ur = tcore_pending_ref_user_request(p);
828 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
831 dbg("Exit on_response_set_preferred_plmn");
835 static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
837 const TcoreATResponse *atResp = data;
838 GSList *tokens = NULL;
839 const char *line = NULL;
840 CoreObject *o = NULL;
841 struct tnoti_network_identity noti;
844 int net_name_type = 0;
846 char *net_name = NULL;
848 dbg("Entry on_response_get_nitz_name (+XCOPS)");
849 o = tcore_pending_ref_core_object(p);
850 if (atResp->success > 0) {
854 nol = g_slist_length(atResp->lines);
856 msg("invalid message");
860 memset(¬i, 0, sizeof(struct tnoti_network_identity));
862 for (count = 0; count < nol; count++) {
864 line = g_slist_nth_data(atResp->lines, count);
865 tokens = tcore_at_tok_new(line);
866 dbg("line %d start---------------", count);
868 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
869 net_name_type = atoi(pResp);
870 dbg("Net name type : %d", net_name_type);
872 switch (net_name_type) {
873 case 0: /* plmn_id (mcc, mnc) */
874 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
875 if (strlen(pResp) > 0) {
876 net_name = tcore_at_tok_extract((const char *)pResp);
877 strncpy(noti.plmn, net_name, 6);
883 case 5: /* Short NITZ name*/
884 case 3: /* Short Network Name (CPHS) */
885 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
886 if (strlen(pResp) > 0) {
887 net_name = tcore_at_tok_extract((const char *)pResp);
888 strncpy(noti.short_name, net_name, 16);
889 noti.short_name[16] = '\0';
894 case 6: /* Full NITZ name */
895 case 4: /* Long Network Name (CPHS) */
896 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
897 if (strlen(pResp) > 0) {
898 net_name = tcore_at_tok_extract((const char *)pResp);
899 strncpy(noti.full_name, net_name, 32);
900 noti.full_name[32] = '\0';
913 tcore_at_tok_free(tokens);
916 dbg("plmn <%s> short NITZ name<%s> full NITZ name<%s>",
917 noti.plmn, noti.short_name, noti.full_name);
918 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
919 sizeof(struct tnoti_network_identity), ¬i);
926 dbg("Exit on_response_get_nitz_name");
929 static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
934 const TcoreATResponse *atResp = data;
935 GSList *tokens = NULL;
939 struct tresp_network_get_preferred_plmn resp = {0};
941 int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
945 if (atResp->success > 0) {
948 total_lines = g_slist_length(atResp->lines);
949 dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
951 if (total_lines < 1) {
952 msg("invalid message");
956 if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
957 total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
960 +CPOL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
961 +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
963 resp.result = TCORE_RETURN_SUCCESS;
965 for (i = 0; i < total_lines; i++) {
966 /* Take each line response at a time & parse it */
967 line = tcore_at_tok_nth(atResp->lines, i);
968 tokens = tcore_at_tok_new(line);
970 /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
973 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
974 dbg("Index : %s", pResp);
975 resp.list[i].index = atoi(pResp);
978 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
979 dbg("format : %s", pResp);
980 plmn_format = atoi(pResp);
983 /* Operator PLMN ID */
984 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
985 dbg("plmn ID : %s", pResp);
987 if (strlen(pResp) > 0) {
990 oper = tcore_at_tok_extract((const char *)pResp);
991 dbg("operator <%s>", oper);
994 if (plmn_format == 2) {
995 strncpy(resp.list[i].plmn, oper, 6);
996 resp.list[i].plmn[6] = '\0';
1003 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
1004 dbg("GSM_AcT2 : %s", pResp);
1005 GSM_AcT2 = atoi(pResp);
1008 if ((pResp = tcore_at_tok_nth(tokens, 4))) {
1009 dbg("GSM_Compact AcT2 : %s", pResp);
1010 GSM_Compact_AcT2 = atoi(pResp);
1013 if ((pResp = tcore_at_tok_nth(tokens, 5))) {
1014 dbg("UTRAN_AcT2 : %s", pResp);
1015 UTRAN_AcT2 = atoi(pResp);
1018 if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
1019 resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
1020 else if (UTRAN_AcT2)
1021 resp.list[i].act = NETWORK_ACT_UMTS;
1022 else if (GSM_AcT2 || GSM_Compact_AcT2)
1023 resp.list[i].act = NETWORK_ACT_GPRS;
1025 (resp.list_count)++;
1027 tcore_at_tok_free(tokens);
1031 dbg("RESPONSE NOT OK");
1032 // TODO: CMEE error mapping is required.
1033 resp.result = TCORE_RETURN_FAILURE;
1037 ur = tcore_pending_ref_user_request(p);
1039 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
1045 static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
1047 const TcoreATResponse *resp = data;
1049 struct tresp_network_get_serving_network Tresp = {0};
1050 char *long_plmn_name = NULL;
1051 char *short_plmn_name = NULL;
1052 char *plmn_id = NULL;
1054 GSList *tokens = NULL;
1056 int network_mode = -1;
1057 int plmn_format = -1;
1059 struct tnoti_network_identity noti;
1063 o = tcore_pending_ref_core_object(p);
1065 if (resp->success <= 0) {
1066 dbg("RESPONSE NOK");
1068 ur = tcore_pending_ref_user_request(p);
1070 Tresp.result = TCORE_RETURN_FAILURE;
1071 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1077 nol = g_slist_length(resp->lines);
1078 dbg("nol : %d", nol);
1080 for (count = 0; count < nol; count++) {
1082 line = g_slist_nth_data(resp->lines, count);
1083 tokens = tcore_at_tok_new(line);
1084 dbg("line %d start---------------", count);
1086 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
1087 dbg("mode : %s", pResp);
1088 network_mode = atoi(pResp);
1091 // format (optional)
1092 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
1093 dbg("format : %s", pResp);
1094 if (strlen(pResp) > 0)
1095 plmn_format = atoi(pResp);
1099 switch (plmn_format) {
1100 case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
1101 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1102 dbg("long PLMN : %s", pResp);
1103 if (strlen(pResp) > 0) {
1104 long_plmn_name = tcore_at_tok_extract((const char *)pResp);
1106 // set network name into po
1107 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
1112 case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
1113 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1114 dbg("short PLMN : %s", pResp);
1115 if (strlen(pResp) > 0) {
1116 short_plmn_name = tcore_at_tok_extract((const char *)pResp);
1118 // set network name into po
1119 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
1124 case AT_COPS_FORMAT_NUMERIC:
1125 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1126 dbg("numeric : %s", pResp);
1127 if (strlen(pResp) > 0) {
1128 plmn_id = tcore_at_tok_extract((const char *)pResp);
1130 // set plmn id into po
1131 tcore_network_set_plmn(o, plmn_id);
1141 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
1142 dbg("AcT : %s", pResp);
1143 if (strlen(pResp) > 0) {
1145 tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
1149 tcore_at_tok_free(tokens);
1153 memcpy(Tresp.plmn, plmn_id, strlen(plmn_id));
1154 tcore_network_get_access_technology(o, &(Tresp.act));
1155 tcore_network_get_lac(o, &(Tresp.gsm.lac));
1157 ur = tcore_pending_ref_user_request(p);
1159 Tresp.result = TCORE_RETURN_SUCCESS;
1160 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1162 /* Network change noti */
1163 struct tnoti_network_change network_change;
1165 memset(&network_change, 0, sizeof(struct tnoti_network_change));
1167 memcpy(network_change.plmn, plmn_id, strlen(plmn_id));
1168 tcore_network_get_access_technology(o, &(network_change.act));
1169 tcore_network_get_lac(o, &(network_change.gsm.lac));
1171 tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
1172 TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
1173 dbg("dbg.. network_change.plmn : %s", network_change.plmn);
1174 dbg("dbg.. network_change.act : %d", network_change.act);
1175 dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
1177 if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
1178 (AT_COPS_MODE_SET_ONLY != network_mode)) {
1179 /*Network identity noti*/
1180 memset(¬i, 0x0, sizeof(struct tnoti_network_identity));
1182 memcpy(noti.full_name, long_plmn_name, MIN(32, strlen(long_plmn_name)));
1183 if (short_plmn_name)
1184 memcpy(noti.short_name, short_plmn_name, MIN(16, strlen(short_plmn_name)));
1186 memcpy(noti.plmn, plmn_id, strlen(plmn_id)); // plmn_id length is necessarily <= 6
1188 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1189 o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
1190 dbg("dbg.. noti.short_name : %s", noti.short_name);
1191 dbg("dbg.. noti.full_name : %s", noti.full_name);
1192 dbg("dbg.. noti.plmn : %s", noti.plmn);
1196 g_free(long_plmn_name);
1197 g_free(short_plmn_name);
1203 static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
1205 struct tnoti_network_registration_status regist_status;
1206 enum telephony_network_service_domain_status cs_status;
1207 enum telephony_network_service_domain_status ps_status;
1208 enum telephony_network_service_type service_type;
1209 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1210 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1211 struct tnoti_ps_protocol_status noti = {0};
1212 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
1213 int stat = 0, AcT = 0;
1214 unsigned int lac = 0xffff, ci = 0xffff;
1215 unsigned int rac = 0xffff;
1216 GSList *tokens = NULL;
1219 GSList *lines = NULL;
1221 lines = (GSList *) data;
1222 if (1 != g_slist_length(lines)) {
1223 dbg("unsolicited msg but multiple line");
1226 line = (char *) (lines->data);
1227 dbg("+CGREG NOTI RECEIVED");
1230 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1232 Possible values of <stat> can be
1233 0 Not registered, ME is not currently searching a new operator to register to
1234 1 Registered, home network
1235 2 Not registered, but ME is currently searching a new operator to register
1236 3 Registration denied
1238 5 Registered, in roaming
1241 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1244 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1252 6 UTRAN w/HSDPA and HSUPA
1253 Note: <Act> is supporting from R7 and above Protocol Stack.
1255 <rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
1258 tokens = tcore_at_tok_new(line);
1259 if (g_slist_length(tokens) < 1) {
1260 msg("invalid message");
1264 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1265 dbg("No STAT in +CGREG");
1269 if ((pResp = g_slist_nth_data(tokens, 1))) {
1270 pResp = util_removeQuotes(pResp);
1271 lac = strtol(pResp, NULL, 16);
1275 if ((pResp = g_slist_nth_data(tokens, 2))) {
1276 pResp = util_removeQuotes(pResp);
1277 ci = strtol(pResp, NULL, 16);
1280 dbg("No ci in +CGREG");
1283 if ((pResp = g_slist_nth_data(tokens, 3)))
1286 dbg("No AcT in +CGREG");
1288 if ((pResp = g_slist_nth_data(tokens, 4))) {
1289 pResp = util_removeQuotes(pResp);
1290 rac = strtol(pResp, NULL, 16);
1293 dbg("No rac in +CGREG");
1298 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
1300 ps_status = lookup_tbl_net_status[stat];
1302 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
1303 _ps_set(tcore_object_ref_plugin(o), ps_status);
1305 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1307 act = lookup_tbl_access_technology[AcT];
1308 tcore_network_set_access_technology(o, act);
1310 if (stat == AT_CREG_STAT_REG_ROAM)
1311 tcore_network_set_roaming_state(o, TRUE);
1313 tcore_network_set_roaming_state(o, FALSE);
1315 tcore_network_get_service_type(o, &service_type);
1316 dbg("prev_service_type = 0x%x", service_type);
1317 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1318 dbg("new_service_type = 0x%x", service_type);
1319 tcore_network_set_service_type(o, service_type);
1321 tcore_network_set_lac(o, lac);
1322 tcore_network_set_cell_id(o, ci);
1323 tcore_network_set_rac(o, rac);
1325 net_lac_cell_info.lac = lac;
1326 net_lac_cell_info.cell_id = ci;
1328 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1329 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1331 regist_status.cs_domain_status = cs_status;
1332 regist_status.ps_domain_status = ps_status;
1333 regist_status.service_type = service_type;
1334 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1336 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1337 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(regist_status), ®ist_status);
1339 if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
1340 noti.status = TELEPHONY_HSDPA_ON;
1342 noti.status = TELEPHONY_HSDPA_OFF;
1345 case AT_COPS_ACT_GSM:/*Fall Through*/
1346 case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
1347 case AT_COPS_ACT_UTRAN:/*Fall Through*/
1348 case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
1349 case AT_COPS_ACT_E_UTRAN:
1351 dbg("Not required for Protocol Status Notification");
1354 case AT_COPS_ACT_UTRAN_HSDPA:
1357 noti.status = TELEPHONY_HSDPA_ON;
1360 case AT_COPS_ACT_UTRAN_HSUPA:
1363 noti.status = TELEPHONY_HSUPA_ON;
1366 case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
1369 noti.status = TELEPHONY_HSPA_ON;
1379 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
1380 sizeof(struct tnoti_ps_protocol_status), ¬i);
1382 /* Get PLMN ID needed to application */
1383 // get_serving_network(o, NULL);
1385 dbg("Response NOK");
1390 tcore_at_tok_free(tokens);
1394 static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
1396 GSList *lines = NULL;
1398 struct tnoti_network_registration_status regist_status;
1399 enum telephony_network_service_domain_status cs_status;
1400 enum telephony_network_service_domain_status ps_status;
1401 enum telephony_network_service_type service_type;
1402 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1403 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1406 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
1407 int stat = 0, AcT = 0;
1408 unsigned int lac = 0xffff, ci = 0xffff;
1409 GSList *tokens = NULL;
1412 lines = (GSList *) event_info;
1413 if (1 != g_slist_length(lines)) {
1414 dbg("unsolicited msg but multiple line");
1417 line = (char *) (lines->data);
1419 dbg("+CREG NOTI RECEIVED");
1422 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1424 Possible values of <stat> can be
1425 0 Not registered, ME is not currently searching a new operator to register to
1426 1 Registered, home network
1427 2 Not registered, but ME is currently searching a new operator to register
1428 3 Registration denied
1430 5 Registered, in roaming
1433 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1436 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1444 6 UTRAN w/HSDPA and HSUPA
1445 Note: <Act> is supporting from R7 and above Protocol Stack.
1448 tokens = tcore_at_tok_new(line);
1449 if (g_slist_length(tokens) < 1) {
1450 msg("invalid message");
1454 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1455 dbg("No STAT in +CREG");
1459 if ((pResp = g_slist_nth_data(tokens, 1))) {
1460 pResp = util_removeQuotes(pResp);
1461 lac = strtol(pResp, NULL, 16);
1465 if ((pResp = g_slist_nth_data(tokens, 2))) {
1466 pResp = util_removeQuotes(pResp);
1467 ci = strtol(pResp, NULL, 16);
1470 dbg("No ci in +CREG");
1473 if ((pResp = g_slist_nth_data(tokens, 3)))
1476 dbg("No AcT in +CREG");
1480 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
1482 cs_status = lookup_tbl_net_status[stat];
1483 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
1485 // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1486 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
1488 act = lookup_tbl_access_technology[AcT];
1489 tcore_network_set_access_technology(o, act);
1491 if (stat == AT_CREG_STAT_REG_ROAM)
1492 tcore_network_set_roaming_state(o, TRUE);
1494 tcore_network_set_roaming_state(o, FALSE);
1496 tcore_network_get_service_type(o, &service_type);
1497 dbg("prev_service_type = 0x%x", service_type);
1498 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1499 dbg("new_service_type = 0x%x", service_type);
1500 tcore_network_set_service_type(o, service_type);
1502 tcore_network_set_lac(o, lac);
1503 tcore_network_set_cell_id(o, ci);
1505 net_lac_cell_info.lac = lac;
1506 net_lac_cell_info.cell_id = ci;
1508 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1509 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1511 regist_status.cs_domain_status = cs_status;
1512 regist_status.ps_domain_status = ps_status;
1513 regist_status.service_type = service_type;
1514 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1516 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1517 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1519 /* Get PLMN ID needed to application */
1520 if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
1521 NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
1522 get_serving_network(o, NULL);
1524 dbg("Response NOK");
1529 tcore_at_tok_free(tokens);
1533 static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
1535 struct tnoti_network_icon_info net_icon_info = {0};
1537 char *rssiToken = NULL;
1538 char *batteryToken = NULL;
1539 GSList *tokens = NULL;
1540 GSList *lines = NULL;
1542 lines = (GSList *) event_info;
1543 if (1 != g_slist_length(lines)) {
1544 dbg("unsolicited msg but multiple line");
1547 line = (char *) (lines->data);
1548 dbg("+XCIEV Network Icon Info Noti Recieve");
1549 memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
1554 tokens = tcore_at_tok_new(line);
1555 if (g_slist_length(tokens) != 2) {
1556 msg("invalid message");
1560 rssiToken = (char *) g_slist_nth_data(tokens, 0);
1562 if (strlen(rssiToken) > 0) {
1563 net_icon_info.type = NETWORK_ICON_INFO_RSSI;
1564 net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
1565 dbg("rssi level : %d", net_icon_info.rssi);
1568 batteryToken = (char *) g_slist_nth_data(tokens, 1);
1569 if (strlen(batteryToken) > 0) {
1570 net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
1571 net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
1572 dbg("battery level : %d", net_icon_info.battery);
1575 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
1576 sizeof(struct tnoti_network_icon_info), &net_icon_info);
1578 dbg("Response NOK");
1584 tcore_at_tok_free(tokens);
1589 static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
1591 struct tnoti_network_timeinfo net_time_info = {0};
1593 GSList *tokens = NULL;
1595 char *time_zone = NULL;
1596 GSList *lines = NULL;
1597 char ptime_param[20] = {0};
1598 UserRequest *ur = NULL;
1599 dbg("Enter : on_event_network_ctzv_time_info");
1601 lines = (GSList *) event_info;
1602 if (1 != g_slist_length(lines)) {
1603 dbg("unsolicited msg but multiple line");
1606 line = (char *) (lines->data);
1610 <tz> integer value indicating the time zone (e.g. -22 or +34)
1611 <time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
1614 dbg("Network time info (+CTZV) recieved");
1618 dbg("noti line is %s", line);
1620 tokens = tcore_at_tok_new(line);
1622 if (g_slist_length(tokens) < 2) {
1623 msg("invalid message");
1627 if ((time_zone = g_slist_nth_data(tokens, 0))) {
1628 net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
1631 if (tcore_network_get_plmn(o) != NULL)
1632 strcpy(net_time_info.plmn, tcore_network_get_plmn(o));
1634 if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
1635 strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
1636 net_time_info.year = atoi(ptime_param);
1638 strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
1639 net_time_info.month = atoi(ptime_param);
1641 strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
1642 net_time_info.day = atoi(ptime_param);
1644 strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
1645 net_time_info.hour = atoi(ptime_param);
1647 strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
1648 net_time_info.minute = atoi(ptime_param);
1650 strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
1651 net_time_info.second = atoi(ptime_param);
1653 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);
1655 dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
1657 /* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
1658 nwk_prepare_and_send_pending_request(o, "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
1660 dbg("line is NULL");
1665 tcore_at_tok_free(tokens);
1667 dbg("Exit: on_event_network_ctzv_time_info");
1671 static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
1672 const void *data, void *user_data)
1674 const struct tresp_sim_read *resp = data;
1675 CoreObject *o = user_data;
1677 if (command == TRESP_SIM_GET_SPN) {
1678 dbg("OK SPN GETTING!!");
1679 dbg("resp->result = 0x%x", resp->result);
1680 dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
1681 dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
1683 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *) resp->data.spn.spn);
1687 * 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
1688 * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
1689 * 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
1690 * 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
1692 if (resp->data.spn.display_condition & 0x01) {
1693 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1695 if ((resp->data.spn.display_condition & 0x02) == 0) {
1696 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
1698 if ((resp->data.spn.display_condition & 0x03) == 0x01) {
1699 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
1702 // fallback in case no SPN name is provided
1703 if (resp->data.spn.spn[0] == '\0')
1704 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1708 static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
1709 unsigned int data_len, void *data, void *user_data)
1711 const struct tnoti_sim_status *sim = data;
1712 UserRequest *ur = NULL;
1714 if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
1715 ur = tcore_user_request_new(NULL, NULL);
1716 tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
1717 tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
1718 tcore_object_dispatch_request(source, ur);
1721 return TCORE_HOOK_RETURN_CONTINUE;
1724 static TReturn search_network(CoreObject *o, UserRequest *ur)
1727 TcorePending *pending = NULL;
1728 TcoreATRequest *atreq = NULL;
1729 char *cmd_str = NULL;
1730 dbg("search_network - ENTER!!");
1733 return TCORE_RETURN_EINVAL;
1735 h = tcore_object_get_hal(o);
1736 if(FALSE == tcore_hal_get_power_state(h)){
1737 dbg("cp not ready/n");
1738 return TCORE_RETURN_ENOSYS;
1741 pending = tcore_pending_new(o, 0);
1743 cmd_str = g_strdup_printf("AT+COPS=?");
1744 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1746 tcore_pending_set_request_data(pending, 0, atreq);
1747 tcore_pending_set_timeout(pending, 60);
1748 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1749 tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
1750 tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
1751 tcore_pending_link_user_request(pending, ur);
1752 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1754 tcore_hal_send_request(h, pending);
1756 return TCORE_RETURN_SUCCESS;
1759 static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1762 TcorePending *pending = NULL;
1763 TcoreATRequest *atreq;
1764 char *cmd_str = NULL;
1765 int format = 0; /* default value for long alphanumeric */
1770 const struct treq_network_set_plmn_selection_mode *req_data = NULL;
1773 dbg("set_plmn_selection_mode - ENTER!!");
1776 return TCORE_RETURN_EINVAL;
1778 req_data = tcore_user_request_ref_data(ur, NULL);
1779 h = tcore_object_get_hal(o);
1780 if(FALSE == tcore_hal_get_power_state(h)){
1781 dbg("cp not ready/n");
1782 return TCORE_RETURN_ENOSYS;
1784 pending = tcore_pending_new(o, 0);
1786 // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
1787 /* oper parameter format
1788 - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
1789 - 1 <oper> format presentation is set to short alphanumeric.
1790 - 2 <oper> format presentations set to numeric.
1793 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
1798 switch (req_data->mode) {
1799 case NETWORK_SELECT_MODE_MANUAL:
1801 mode = AT_COPS_MODE_MANUAL;
1802 format = AT_COPS_FORMAT_NUMERIC;
1805 memcpy(plmn, req_data->plmn, 6);
1807 if (strlen(req_data->plmn) == 6) {
1812 cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
1816 case NETWORK_SELECT_MODE_AUTOMATIC:
1818 cmd_str = g_strdup("AT+COPS=0");
1823 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
1825 tcore_pending_set_request_data(pending, 0, atreq);
1826 tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
1827 tcore_pending_link_user_request(pending, ur);
1828 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1830 tcore_hal_send_request(h, pending);
1832 return TCORE_RETURN_SUCCESS;
1835 static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1838 TcorePending *pending = NULL;
1839 TcoreATRequest *atreq;
1840 char *cmd_str = NULL;
1842 dbg("get_plmn_selection_mode - ENTER!!");
1845 return TCORE_RETURN_EINVAL;
1847 h = tcore_object_get_hal(o);
1848 if(FALSE == tcore_hal_get_power_state(h)){
1849 dbg("cp not ready/n");
1850 return TCORE_RETURN_ENOSYS;
1852 pending = tcore_pending_new(o, 0);
1854 cmd_str = g_strdup_printf("AT+COPS?");
1855 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1857 tcore_pending_set_request_data(pending, 0, atreq);
1858 tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
1859 tcore_pending_link_user_request(pending, ur);
1860 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1862 tcore_hal_send_request(h, pending);
1864 return TCORE_RETURN_SUCCESS;
1868 static TReturn set_band(CoreObject *o, UserRequest *ur)
1871 TcorePending *pending = NULL;
1872 TcorePending *pending_gsm = NULL;
1873 TcorePending *pending_umts = NULL;
1874 TcoreATRequest *atreq;
1875 char *cmd_str = NULL;
1876 const struct treq_network_set_band *req_data;
1877 gboolean set_gsm_band = 0;
1878 gboolean set_umts_band = 0;
1880 int gsm_band2 = 255;
1881 char *umts_band = NULL;
1882 UserRequest *dup_ur_gsm = NULL;
1883 UserRequest *dup_ur_umts = NULL;
1885 dbg("set_band - ENTER!!");
1888 return TCORE_RETURN_EINVAL;
1890 req_data = tcore_user_request_ref_data(ur, NULL);
1891 h = tcore_object_get_hal(o);
1892 if(FALSE == tcore_hal_get_power_state(h)){
1893 dbg("cp not ready/n");
1894 return TCORE_RETURN_ENOSYS;
1897 dbg("set_band - called with band = %d", req_data->band);
1899 switch (req_data->band) {
1900 case NETWORK_BAND_TYPE_GSM850:
1901 gsm_band = AT_GSM_XBANDSEL_850;
1902 set_gsm_band = TRUE;
1905 case NETWORK_BAND_TYPE_GSM_900_1800:
1906 gsm_band = AT_GSM_XBANDSEL_900;
1907 gsm_band2 = AT_GSM_XBANDSEL_1800;
1908 set_gsm_band = TRUE;
1911 case NETWORK_BAND_TYPE_GSM1900:
1912 gsm_band = AT_GSM_XBANDSEL_1900;
1913 set_gsm_band = TRUE;
1916 case NETWORK_BAND_TYPE_GSM1800:
1917 gsm_band = AT_GSM_XBANDSEL_1800;
1918 set_gsm_band = TRUE;
1921 case NETWORK_BAND_TYPE_GSM_850_1900:
1922 gsm_band = AT_GSM_XBANDSEL_850;
1923 gsm_band2 = AT_GSM_XBANDSEL_1900;
1924 set_gsm_band = TRUE;
1927 case NETWORK_BAND_TYPE_ANY:
1928 gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
1929 set_umts_band = TRUE;
1930 set_gsm_band = TRUE;
1933 case NETWORK_BAND_TYPE_WCDMA:
1934 set_umts_band = TRUE;
1937 case NETWORK_BAND_TYPE_WCDMA2100:
1938 umts_band = "UMTS_BAND_I";
1939 set_umts_band = TRUE;
1942 case NETWORK_BAND_TYPE_WCDMA1900:
1943 umts_band = "UMTS_BAND_II";
1944 set_umts_band = TRUE;
1947 case NETWORK_BAND_TYPE_WCDMA850:
1948 umts_band = "UMTS_BAND_V";
1949 set_umts_band = TRUE;
1956 dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
1958 if (set_umts_band == TRUE) {
1959 if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
1960 cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
1962 cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
1964 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
1965 pending_umts = tcore_pending_new(o, 0);
1967 tcore_pending_set_request_data(pending_umts, 0, atreq);
1968 tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
1969 tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
1971 /* duplicate user request for UMTS Band setting AT command for same UR */
1972 dup_ur_umts = tcore_user_request_ref(ur);
1973 tcore_pending_link_user_request(pending_umts, dup_ur_umts);
1974 tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
1976 tcore_hal_send_request(h, pending_umts);
1980 if (set_gsm_band == TRUE) {
1981 dbg("Entered set_gsm_band");
1982 if (gsm_band2 == 255)
1983 cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
1985 cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
1987 dbg("Command string: %s", cmd_str);
1988 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
1989 pending_gsm = tcore_pending_new(o, 0);
1991 tcore_pending_set_request_data(pending_gsm, 0, atreq);
1992 tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
1993 tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
1995 /* duplicate user request for GSM Band setting AT command for same UR */
1996 dup_ur_gsm = tcore_user_request_ref(ur);
1997 tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
1998 tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
2000 tcore_hal_send_request(h, pending_gsm);
2004 /* Lock device to specific RAT as requested by application */
2006 AT+XRAT=<Act>[,<PreferredAct>]
2007 <AcT> indicates the radio access technology and may be
2009 1 GSM / UMTS Dual mode
2012 if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
2013 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
2014 } else if (set_umts_band == TRUE) {
2015 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
2017 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
2019 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
2020 pending = tcore_pending_new(o, 0);
2022 tcore_pending_set_request_data(pending, 0, atreq);
2023 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2024 tcore_pending_set_response_callback(pending, on_response_set_xrat, NULL);
2025 tcore_pending_link_user_request(pending, ur);
2026 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2028 tcore_hal_send_request(h, pending);
2030 return TCORE_RETURN_SUCCESS;
2033 static TReturn get_band(CoreObject *o, UserRequest *ur)
2036 TcorePending *pending = NULL;
2037 TcoreATRequest *atreq;
2038 char *cmd_str = NULL;
2039 dbg("get_band - ENTER!!");
2042 return TCORE_RETURN_EINVAL;
2044 h = tcore_object_get_hal(o);
2045 if(FALSE == tcore_hal_get_power_state(h)){
2046 dbg("cp not ready/n");
2047 return TCORE_RETURN_ENOSYS;
2050 /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
2051 cmd_str = g_strdup_printf("AT+XRAT?");
2052 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
2053 pending = tcore_pending_new(o, 0);
2054 tcore_pending_set_request_data(pending, 0, atreq);
2055 tcore_pending_set_response_callback(pending, on_response_get_xrat, NULL);
2056 tcore_pending_link_user_request(pending, ur);
2057 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2058 tcore_hal_send_request(h, pending);
2061 return TCORE_RETURN_SUCCESS;
2064 static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
2067 TcorePlugin *p = NULL;
2068 TcorePending *pending = NULL;
2069 TcoreATRequest *atreq = NULL;
2070 struct treq_network_set_preferred_plmn *req_data = NULL;
2071 char *cmd_str = NULL;
2072 int format = 2; /* Alway use numeric format, as application gives data in this default format */
2074 int gsm_compact_act = 0;
2078 return TCORE_RETURN_EINVAL;
2080 p = tcore_object_ref_plugin(o);
2081 h = tcore_object_get_hal(o);
2082 if(FALSE == tcore_hal_get_power_state(h)){
2083 dbg("cp not ready/n");
2084 return TCORE_RETURN_ENOSYS;
2087 req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
2088 pending = tcore_pending_new(o, 0);
2090 dbg("Entry set_preferred_plmn");
2093 [<index>][,<format>[,<oper>[,<GSM_AcT>,
2094 <GSM_Compact_AcT>,<UTRAN_AcT>]]]
2097 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
2099 else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
2101 else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
2102 gsm_act = utran_act = TRUE;
2104 if (strlen(req_data->plmn) > 6) {
2105 req_data->plmn[6] = '\0';
2106 } else if (strlen(req_data->plmn) == 6) {
2107 if (req_data->plmn[5] == '#') {
2108 req_data->plmn[5] = '\0';
2111 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);
2113 dbg("cmd_str - %s", cmd_str);
2114 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
2116 tcore_pending_set_request_data(pending, 0, atreq);
2117 tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, NULL);
2118 tcore_pending_link_user_request(pending, ur);
2119 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2121 tcore_hal_send_request(h, pending);
2125 dbg("Exit set_preferred_plmn");
2127 return TCORE_RETURN_SUCCESS;
2130 static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
2133 TcorePending *pending = NULL;
2134 TcoreATRequest *atreq = NULL;
2136 char *cmd_str = NULL;
2138 dbg("get_preferred_plmn - ENTER!!");
2141 return TCORE_RETURN_EINVAL;
2143 h = tcore_object_get_hal(o);
2144 if(FALSE == tcore_hal_get_power_state(h)){
2145 dbg("cp not ready/n");
2146 return TCORE_RETURN_ENOSYS;
2149 pending = tcore_pending_new(o, 0);
2151 cmd_str = g_strdup_printf("AT+CPOL=,2;+CPOL?");
2152 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
2154 tcore_pending_set_request_data(pending, 0, atreq);
2155 tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
2156 tcore_pending_link_user_request(pending, ur);
2157 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2159 tcore_hal_send_request(h, pending);
2163 dbg("get_preferred_plmn - EXIT!!");
2165 return TCORE_RETURN_SUCCESS;
2168 static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
2170 dbg("get_serving_network - ENTER!!");
2173 return TCORE_RETURN_EINVAL;
2175 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2176 dbg("cp not ready/n");
2177 return TCORE_RETURN_ENOSYS;
2180 dbg("new pending(AT+COPS?)");
2182 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);
2183 return TCORE_RETURN_SUCCESS;
2186 static struct tcore_network_operations network_ops = {
2187 .search = search_network,
2188 .set_plmn_selection_mode = set_plmn_selection_mode,
2189 .get_plmn_selection_mode = get_plmn_selection_mode,
2190 .set_service_domain = NULL,
2191 .get_service_domain = NULL,
2192 .set_band = set_band,
2193 .get_band = get_band,
2194 .set_preferred_plmn = set_preferred_plmn,
2195 .get_preferred_plmn = get_preferred_plmn,
2198 .set_power_on_attach = NULL,
2199 .get_power_on_attach = NULL,
2200 .set_cancel_manual_search = NULL,
2201 .get_serving_network = get_serving_network,
2204 gboolean s_network_init(TcorePlugin *cp, CoreObject *co_network)
2208 tcore_network_override_ops(co_network, &network_ops);
2210 tcore_object_override_callback(co_network, "+CREG", on_event_cs_network_regist, NULL);
2211 tcore_object_override_callback(co_network, "+CGREG", on_event_ps_network_regist, NULL);
2212 tcore_object_override_callback(co_network, "+XCIEV", on_event_network_icon_info, NULL);
2214 /* +CTZV: <tz>,<time> */
2215 tcore_object_override_callback(co_network, "+CTZV", on_event_network_ctzv_time_info, NULL);
2217 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co_network);
2219 _insert_mcc_mnc_oper_list(cp, co_network);
2226 void s_network_exit(TcorePlugin *cp, CoreObject *co_network)