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>
32 #include <co_network.h>
40 #include "s_network.h"
42 #define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
43 #define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
44 #define AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
45 #define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
46 #define AT_CREG_STAT_UNKNOWN 4 /* unknown */
47 #define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
49 #define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
50 #define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
51 #define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
52 #define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
53 #define AT_COPS_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
55 #define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
56 #define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
57 #define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
59 #define AT_COPS_ACT_GSM 0 /* GSM */
60 #define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
61 #define AT_COPS_ACT_UTRAN 2 /* UTRAN */
62 #define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
63 #define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
64 #define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
65 #define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
66 #define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
68 #define AT_GSM_XBANDSEL_AUTOMATIC 0
69 #define AT_GSM_XBANDSEL_1800 1800
70 #define AT_GSM_XBANDSEL_1900 1900
71 #define AT_GSM_XBANDSEL_900 900
72 #define AT_GSM_XBANDSEL_850 850
73 #define AT_GSM_XBANDSEL_450 450
74 #define AT_GSM_XBANDSEL_480 480
75 #define AT_GSM_XBANDSEL_750 750
76 #define AT_GSM_XBANDSEL_380 380
77 #define AT_GSM_XBANDSEL_410 410
80 #define AT_XRAT_DUAL 1
81 #define AT_XRAT_UMTS 2
83 #define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
84 #define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
86 static unsigned int lookup_tbl_net_status[] = {
87 [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
88 [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
89 [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
90 [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
91 [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
92 [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
95 static unsigned int lookup_tbl_access_technology[] = {
96 [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
97 [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
98 [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
99 [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
100 [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
101 [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
102 [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
103 [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
106 static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
109 static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
111 dbg("on_confirmation_modem_message_send - msg out from queue.\n");
113 if (result == FALSE) {
121 static void nwk_prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
123 TcoreATRequest *req = NULL;
125 CoreObject *o = NULL;
126 TcorePending *pending = NULL;
129 o = tcore_plugin_ref_core_object(plugin, co_name);
130 hal = tcore_object_get_hal(o);
132 pending = tcore_pending_new(o, 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;
159 s = tcore_plugin_ref_server(p);
160 strg = tcore_server_find_storage(s, "database");
162 handle = tcore_storage_create_handle(strg, "/opt/dbspace/.mcc_mnc_oper_list.db");
164 dbg("fail to create database handle");
168 snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
170 result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
171 (GDestroyNotify) g_hash_table_destroy);
173 tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
175 g_hash_table_iter_init(&iter, result);
176 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
179 noi = calloc(sizeof(struct tcore_network_operator_info), 1);
181 snprintf(noi->mcc, 4, "%s", (char *) g_hash_table_lookup(row, "1"));
182 snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
183 snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
184 snprintf(noi->country, 4, "%s", (char *) g_hash_table_lookup(row, "0"));
186 tcore_network_operator_info_add(o, noi);
191 dbg("count = %d", count);
193 g_hash_table_destroy(result);
195 tcore_storage_remove_handle(strg, handle);
198 static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
199 int domain, int act, int cs_status, int ps_status)
201 enum telephony_network_service_type ret;
206 case NETWORK_ACT_UNKNOWN:
207 ret = NETWORK_SERVICE_TYPE_UNKNOWN;
210 case NETWORK_ACT_GSM:
211 if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
212 ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
214 ret = NETWORK_SERVICE_TYPE_2G;
217 case NETWORK_ACT_EGPRS:
218 return NETWORK_SERVICE_TYPE_2_5G_EDGE;
221 case NETWORK_ACT_UMTS:
222 ret = NETWORK_SERVICE_TYPE_3G;
226 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
227 ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
228 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
229 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
232 ret = NETWORK_SERVICE_TYPE_SEARCH;
234 } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
235 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
238 ret = NETWORK_SERVICE_TYPE_EMERGENCY;
245 static void _ps_set(TcorePlugin *p, int status)
247 GSList *co_list = NULL;
249 co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_PS);
251 CoreObject *o = NULL;
252 o = (CoreObject *) co_list->data;
256 if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
257 tcore_ps_set_online(o, TRUE);
259 tcore_ps_set_online(o, FALSE);
261 } while ((co_list = g_slist_next(co_list)));
263 g_slist_free(co_list);
266 static void on_timeout_search_network(TcorePending *p, void *user_data)
269 struct tresp_network_search resp;
271 dbg("TIMEOUT !!!!! pending=%p", p);
273 memset(&resp, 0, sizeof(struct tresp_network_search));
275 resp.result = TCORE_RETURN_FAILURE;
278 ur = tcore_pending_ref_user_request(p);
280 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
284 static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
287 const TcoreATResponse *atResp = data;
288 // GSList *tokens = NULL;
289 // char * line = NULL;
290 struct tresp_network_set_plmn_selection_mode resp = {0};
292 if (atResp->success > 0) {
294 resp.result = TCORE_RETURN_SUCCESS;
297 resp.result = TCORE_RETURN_FAILURE;
300 ur = tcore_pending_ref_user_request(p);
302 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
306 static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
309 struct tresp_network_get_plmn_selection_mode resp = {0};
310 const TcoreATResponse *atResp = data;
311 GSList *tokens = NULL;
315 resp.result = TCORE_RETURN_FAILURE;
317 if (atResp->success > 0) {
320 +COPS: <mode>[,<format>,<oper>[,< AcT>]]
324 line = (char *) atResp->lines->data;
325 tokens = tcore_at_tok_new(line);
326 if (g_slist_length(tokens) < 1) {
327 msg("invalid message");
330 mode = atoi(tcore_at_tok_nth(tokens, 0));
331 dbg("mode = %d", mode);
334 case AT_COPS_MODE_AUTOMATIC:
335 resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
338 case AT_COPS_MODE_MANUAL:
339 case AT_COPS_MODE_MANUAL_AUTOMATIC:
340 resp.mode = NETWORK_SELECT_MODE_MANUAL;
343 case AT_COPS_MODE_DEREGISTER:
344 case AT_COPS_MODE_SET_ONLY:
345 resp.result = TCORE_RETURN_FAILURE;
348 resp.result = TCORE_RETURN_SUCCESS;
352 resp.result = TCORE_RETURN_FAILURE;
356 ur = tcore_pending_ref_user_request(p);
358 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
362 tcore_at_tok_free(tokens);
367 static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
370 struct tresp_network_search resp;
373 const TcoreATResponse *atResp = data;
374 GSList *tokens = NULL;
375 GSList *network_token = NULL;
377 char *temp_plmn_info = NULL;
379 int num_network_avail = 0;
381 memset(&resp, 0, sizeof(struct tresp_network_search));
382 resp.result = TCORE_RETURN_FAILURE;
385 if (atResp->success > 0) {
388 line = (char *) atResp->lines->data;
389 tokens = tcore_at_tok_new(line);
390 num_network_avail = g_slist_length(tokens);
391 dbg(" length of tokens is %d\n", num_network_avail);
392 if (num_network_avail < 1) {
393 msg("invalid message");
398 resp.result = TCORE_RETURN_SUCCESS;
400 * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
401 * [,,(list of supported <mode>s),(list of supported <format>s)]
404 for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
405 network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
407 pResp = (tcore_at_tok_nth(network_token, 0));
409 dbg("status : %s", pResp);
410 resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
413 if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Aplha name */
414 dbg("Long Aplha name : %s", pResp);
416 if (strlen(pResp) > 0)
417 /* Strip off starting quote & ending quote */
418 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
419 } else if ((pResp = tcore_at_tok_nth(network_token, 2))) {
420 dbg("Short Aplha name : %s", pResp);
421 /* Short Aplha name */
422 /* Strip off starting quote & ending quote */
423 if (strlen(pResp) > 0)
424 strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
428 pResp = tcore_at_tok_nth(network_token, 3);
430 dbg("PLMN ID : %s", pResp);
431 temp_plmn_info = util_removeQuotes(pResp);
434 memcpy(resp.list[i].plmn, temp_plmn_info, 6);
435 if (resp.list[i].plmn[5] == '#')
436 resp.list[i].plmn[5] = '\0';
438 /* Parse Access Technology */
439 if ((pResp = tcore_at_tok_nth(tokens, 4))) {
440 if (strlen(pResp) > 0) {
444 resp.list[i].act = NETWORK_ACT_GSM;
446 resp.list[i].act = NETWORK_ACT_UMTS;
450 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);
453 tcore_at_tok_free(network_token);
457 resp.result = TCORE_RETURN_FAILURE;
461 ur = tcore_pending_ref_user_request(p);
463 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
467 tcore_at_tok_free(tokens);
470 free(temp_plmn_info);
475 static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
477 const TcoreATResponse *atResp = data;
479 dbg("On Response Set UMTS Band");
481 if (atResp->success > 0) {
487 dbg("Wait for response of XRAT before sending final band setting response to AP");
492 static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
494 const TcoreATResponse *atResp = data;
496 dbg("On Response Set GSM Band");
497 if (atResp->success > 0) {
503 dbg("Wait for response of XRAT before sending final band setting response to AP");
507 static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
509 const TcoreATResponse *atResp = data;
510 GSList *tokens = NULL;
511 const char *line = NULL;
512 int total_umts_bands = 0;
514 char *band_token = NULL;
515 char umts_band[20] = {0};
516 char umts_band_1 = 0;
517 char umts_band_2 = 0;
518 char umts_band_5 = 0;
519 UserRequest *ur = NULL;
520 struct tresp_network_get_band resp = {0};
522 dbg("Entry on_response_get_umts_band");
524 resp.mode = NETWORK_BAND_MODE_PREFERRED;
525 resp.result = TCORE_RETURN_SUCCESS;
527 if (atResp->success > 0) {
530 line = (char *) atResp->lines->data;
531 tokens = tcore_at_tok_new(line);
532 total_umts_bands = g_slist_length(tokens);
533 dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
534 if (total_umts_bands < 1) {
543 for (i = 0; i < total_umts_bands; i++) {
544 band_token = tcore_at_tok_nth(tokens, i);
546 if (band_token == NULL)
549 memset(umts_band, 0x00, sizeof(umts_band));
551 if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
552 umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
556 /* Strip off starting quotes & ending quotes */
557 strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
559 if (!strcmp(umts_band, "UMTS_BAND_I")) {
561 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
563 } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
566 /* Telephony is not interest */
567 dbg("Telephony is not interested in %s band", umts_band);
572 if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
573 resp.band = NETWORK_BAND_TYPE_WCDMA;
574 } else if (umts_band_1) {
575 resp.band = NETWORK_BAND_TYPE_WCDMA2100;
576 } else if (umts_band_2) {
577 resp.band = NETWORK_BAND_TYPE_WCDMA1900;
578 } else if (umts_band_5) {
579 resp.band = NETWORK_BAND_TYPE_WCDMA850;
581 resp.result = TCORE_RETURN_FAILURE;
584 dbg("Final resp.band sent to TS = %d", resp.band);
586 ur = tcore_pending_ref_user_request(p);
588 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
592 tcore_at_tok_free(tokens);
594 dbg("Exit on_response_get_umts_band");
598 static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
600 struct tresp_network_get_band resp = {0};
601 const TcoreATResponse *atResp = data;
602 GSList *tokens = NULL;
603 int total_gsm_bands = 0;
604 const char *line = NULL;
606 char *band_token = NULL;
607 UserRequest *ur = NULL;
613 dbg("Entry on_response_get_gsm_band");
615 resp.mode = NETWORK_BAND_MODE_PREFERRED;
616 resp.result = TCORE_RETURN_SUCCESS;
618 if (atResp->success > 0) {
621 line = (char *) atResp->lines->data;
622 tokens = tcore_at_tok_new(line);
623 total_gsm_bands = g_slist_length(tokens);
624 dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
625 if (total_gsm_bands < 1)
630 for (i = 0; i < total_gsm_bands; i++) {
631 band_token = tcore_at_tok_nth(tokens, i);
633 if (band_token == NULL)
636 if (atoi(band_token) == 0) { /* 0 means GSM automatic */
637 gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
641 switch (atoi(band_token)) {
642 case AT_GSM_XBANDSEL_850:
646 case AT_GSM_XBANDSEL_900:
650 case AT_GSM_XBANDSEL_1800:
654 case AT_GSM_XBANDSEL_1900:
665 if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
666 resp.band = NETWORK_BAND_TYPE_GSM;
667 } else if (gsm_850 && gsm_1900) {
668 resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
669 } else if (gsm_900 && gsm_1800) {
670 resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
671 } else if (gsm_1900) {
672 resp.band = NETWORK_BAND_TYPE_GSM1900;
673 } else if (gsm_850) {
674 resp.band = NETWORK_BAND_TYPE_GSM850;
675 } else if (gsm_1800) {
676 resp.band = NETWORK_BAND_TYPE_GSM1800;
677 } else if (gsm_900) {
678 resp.band = NETWORK_BAND_TYPE_GSM900;
680 resp.result = TCORE_RETURN_FAILURE;
683 dbg("Final resp.band sent to TS = %d", resp.band);
685 ur = tcore_pending_ref_user_request(p);
687 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
691 tcore_at_tok_free(tokens);
693 dbg("Exit on_response_get_gsm_band");
698 static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
701 UserRequest *ur = NULL;
703 TcoreATRequest *atreq;
704 char *cmd_str = NULL;
705 UserRequest *dup_ur = NULL;
706 const TcoreATResponse *atResp = data;
707 const char *line = NULL;
709 GSList *tokens = NULL;
710 TcorePending *pending = NULL;
711 CoreObject *o = NULL;
713 struct tresp_network_get_band resp = {0};
715 dbg("Enter on_response_get_xrat !!");
717 resp.mode = NETWORK_BAND_MODE_PREFERRED;
719 ur = tcore_pending_ref_user_request(p);
720 h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
721 o = tcore_pending_ref_core_object(p);
723 if (atResp->success > 0) {
726 line = (char *) atResp->lines->data;
727 tokens = tcore_at_tok_new(line);
728 if (g_slist_length(tokens) < 1) {
729 msg("invalid message");
734 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
735 cp_xrat = atoi(pResp);
737 if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
738 resp.result = TCORE_RETURN_SUCCESS;
739 resp.band = NETWORK_BAND_TYPE_ANY;
741 ur = tcore_pending_ref_user_request(p);
743 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
746 } else if ((cp_xrat == AT_XRAT_UMTS)) {
747 /* Get UMTS Band Information */
748 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
749 cmd_str = g_strdup_printf("AT+XUBANDSEL?");
750 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
751 pending = tcore_pending_new(o, 0);
752 tcore_pending_set_request_data(pending, 0, atreq);
753 tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
754 tcore_pending_link_user_request(pending, ur);
755 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
756 tcore_hal_send_request(h, pending);
758 } else if ((cp_xrat == AT_XRAT_UMTS)) {
759 /* Get GSM Band Information */
760 dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
761 cmd_str = g_strdup_printf("AT+XBANDSEL?");
762 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
763 pending = tcore_pending_new(o, 0);
764 tcore_pending_set_request_data(pending, 0, atreq);
765 tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
766 tcore_pending_link_user_request(pending, dup_ur);
767 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
768 tcore_hal_send_request(h, pending);
775 resp.result = TCORE_RETURN_FAILURE;
776 resp.band = NETWORK_BAND_TYPE_ANY;
778 ur = tcore_pending_ref_user_request(p);
780 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
786 tcore_at_tok_free(tokens);
788 dbg("Exit on_response_get_xrat !!");
794 static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
796 UserRequest *ur = NULL;
797 struct tresp_network_set_band resp = {0};
798 const TcoreATResponse *atResp = data;
800 dbg("On Response Set XRAT");
802 if (atResp->success > 0) {
804 resp.result = TCORE_RETURN_SUCCESS;
807 resp.result = TCORE_RETURN_FAILURE;
810 ur = tcore_pending_ref_user_request(p);
812 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
818 static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
820 UserRequest *ur = NULL;
821 struct tresp_network_set_preferred_plmn resp = {0};
822 const TcoreATResponse *atResp = data;
824 dbg("ENTER on_response_set_preferred_plmn");
826 if (atResp->success > 0) {
828 resp.result = TCORE_RETURN_SUCCESS;
831 resp.result = TCORE_RETURN_FAILURE;
834 ur = tcore_pending_ref_user_request(p);
836 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
839 dbg("Exit on_response_set_preferred_plmn");
843 static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
845 const TcoreATResponse *atResp = data;
846 GSList *tokens = NULL;
847 const char *line = NULL;
848 CoreObject *o = NULL;
849 struct tnoti_network_identity noti;
852 int net_name_type = 0;
855 dbg("Entry on_response_get_nitz_name (+XCOPS)");
856 o = tcore_pending_ref_core_object(p);
857 if (atResp->success > 0) {
861 nol = g_slist_length(atResp->lines);
863 msg("invalid message");
867 for (count = 0; count < nol; count++) {
869 line = g_slist_nth_data(atResp->lines, count);
870 tokens = tcore_at_tok_new(line);
871 dbg("line %d start---------------", count);
873 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
874 net_name_type = atoi(pResp);
875 dbg("Net name type : %d", net_name_type);
877 switch (net_name_type) {
878 case 0: /* plmn_id (mcc, mnc) */
879 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
880 strncpy(noti.plmn, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
884 case 5: /* Short Nitz name*/
885 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
886 strncpy(noti.short_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
890 case 6: /* Full Nitz name */
891 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
892 strncpy(noti.full_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
901 tcore_at_tok_free(tokens);
904 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
905 sizeof(struct tnoti_network_identity), ¬i);
912 dbg("Exit on_response_get_nitz_name");
915 static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
920 const TcoreATResponse *atResp = data;
921 GSList *tokens = NULL;
922 char temp_plmn_info[17] = {0};
926 struct tresp_network_get_preferred_plmn resp = {0};
928 int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
930 dbg("Entry on_response_get_preferred_plmn");
932 if (atResp->success > 0) {
935 total_lines = g_slist_length(atResp->lines);
936 dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
938 if (total_lines < 1) {
939 msg("invalid message");
943 if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
944 total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
947 +COPL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
948 +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
951 resp.result = TCORE_RETURN_SUCCESS;
953 for (i = 0; i < total_lines; i++) {
954 /* Take each line response at a time & parse it */
955 line = tcore_at_tok_nth(atResp->lines, i);
956 tokens = tcore_at_tok_new(line);
958 /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
961 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
962 dbg("Index : %s", pResp);
963 resp.list[i].ef_index = atoi(pResp);
966 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
967 dbg("format : %s", pResp);
968 plmn_format = atoi(pResp);
971 /* Operator PLMN ID */
972 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
973 dbg("plmn ID : %s", pResp);
975 if (strlen(pResp) > 0) {
976 strncpy(temp_plmn_info, pResp + 1, (strlen(pResp)) - 2);
979 if (plmn_format == 2) {
980 // cp_plmn = util_hexStringToBytes(temp_plmn_info);
982 if (strncmp((char *) temp_plmn_info, "000000", 6) == 0)
985 memcpy(resp.list[i].plmn, temp_plmn_info, 6);
986 if (resp.list[i].plmn[5] == '#')
987 resp.list[i].plmn[5] = '\0';
994 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
995 dbg("GSM_AcT2 : %s", pResp);
996 GSM_AcT2 = atoi(pResp);
999 if ((pResp = tcore_at_tok_nth(tokens, 4))) {
1000 dbg("GSM_Compact AcT2 : %s", pResp);
1001 GSM_Compact_AcT2 = atoi(pResp);
1004 if ((pResp = tcore_at_tok_nth(tokens, 5))) {
1005 dbg("UTRAN_AcT2 : %s", pResp);
1006 UTRAN_AcT2 = atoi(pResp);
1009 if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
1010 resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
1011 else if (UTRAN_AcT2)
1012 resp.list[i].act = NETWORK_ACT_UMTS;
1013 else if (GSM_AcT2 || GSM_Compact_AcT2)
1014 resp.list[i].act = NETWORK_ACT_GPRS;
1016 (resp.list_count)++;
1018 tcore_at_tok_free(tokens);
1023 ur = tcore_pending_ref_user_request(p);
1025 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
1031 static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
1033 const TcoreATResponse *resp = data;
1035 struct tresp_network_get_serving_network Tresp = {0};
1037 char *long_plmn_name = NULL;
1038 char *short_plmn_name = NULL;
1040 GSList *tokens = NULL;
1042 int network_mode = -1;
1043 int plmn_format = -1;
1045 struct tnoti_network_identity noti;
1049 o = tcore_pending_ref_core_object(p);
1051 if (resp->success <= 0) {
1052 dbg("RESPONSE NOK");
1054 ur = tcore_pending_ref_user_request(p);
1056 Tresp.result = TCORE_RETURN_FAILURE;
1057 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1063 nol = g_slist_length(resp->lines);
1064 dbg("nol : %d", nol);
1066 for (count = 0; count < nol; count++) {
1068 line = g_slist_nth_data(resp->lines, count);
1069 tokens = tcore_at_tok_new(line);
1070 dbg("line %d start---------------", count);
1072 if ((pResp = tcore_at_tok_nth(tokens, 0))) {
1073 dbg("mode : %s", pResp);
1074 network_mode = atoi(pResp);
1077 // format (optional)
1078 if ((pResp = tcore_at_tok_nth(tokens, 1))) {
1079 dbg("format : %s", pResp);
1080 if (strlen(pResp) > 0)
1081 plmn_format = atoi(pResp);
1085 switch (plmn_format) {
1086 case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
1087 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1088 dbg("long PLMN : %s", pResp);
1089 if (strlen(pResp) > 0) {
1090 long_plmn_name = util_removeQuotes(pResp);
1092 // set network name into po
1093 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
1098 case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
1099 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1100 dbg("short PLMN : %s", pResp);
1101 if (strlen(pResp) > 0) {
1102 short_plmn_name = util_removeQuotes(pResp);
1104 // set network name into po
1105 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
1110 case AT_COPS_FORMAT_NUMERIC:
1111 if ((pResp = tcore_at_tok_nth(tokens, 2))) {
1112 dbg("numeric : %s", pResp);
1113 if (strlen(pResp) > 0) {
1116 /* Strip off starting quotes & ending quotes */
1117 strncpy(plmn, pResp + 1, strlen(pResp) - 2);
1118 tcore_network_set_plmn(o, plmn);
1128 if ((pResp = tcore_at_tok_nth(tokens, 3))) {
1129 dbg("AcT : %s", pResp);
1130 if (strlen(pResp) > 0) {
1132 tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
1136 tcore_at_tok_free(tokens);
1139 memcpy(Tresp.plmn, plmn, 7);
1140 tcore_network_get_access_technology(o, &(Tresp.act));
1141 tcore_network_get_lac(o, &(Tresp.gsm.lac));
1143 ur = tcore_pending_ref_user_request(p);
1145 Tresp.result = TCORE_RETURN_SUCCESS;
1146 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
1148 /* Network change noti */
1149 struct tnoti_network_change network_change;
1151 memset(&network_change, 0, sizeof(struct tnoti_network_change));
1152 memcpy(network_change.plmn, plmn, 7);
1153 tcore_network_get_access_technology(o, &(network_change.act));
1154 tcore_network_get_lac(o, &(network_change.gsm.lac));
1156 tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
1157 TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
1158 dbg("dbg.. network_change.plmn : %s", network_change.plmn);
1159 dbg("dbg.. network_change.act : %d", network_change.act);
1160 dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
1162 if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
1163 (AT_COPS_MODE_SET_ONLY != network_mode)) {
1164 /*Network identity noti*/
1165 memset(¬i, 0x0, sizeof(struct tnoti_network_change));
1167 memcpy(noti.full_name, long_plmn_name, MIN(33, strlen(long_plmn_name)));
1168 if (short_plmn_name)
1169 memcpy(noti.short_name, short_plmn_name, MIN(17, strlen(long_plmn_name)));
1170 memcpy(noti.plmn, plmn, 7);
1171 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1172 o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
1173 dbg("dbg.. noti.short_name : %s", noti.short_name);
1174 dbg("dbg.. noti.full_name : %s", noti.full_name);
1175 dbg("dbg.. noti.plmn : %s", noti.plmn);
1179 free(long_plmn_name);
1180 if (short_plmn_name)
1181 free(short_plmn_name);
1186 static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
1188 struct tnoti_network_registration_status regist_status;
1189 enum telephony_network_service_domain_status cs_status;
1190 enum telephony_network_service_domain_status ps_status;
1191 enum telephony_network_service_type service_type;
1192 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1193 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1194 struct tnoti_ps_protocol_status noti = {0};
1195 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
1196 int stat = 0, AcT = 0;
1197 unsigned int lac = 0xffff, ci = 0xffff;
1198 unsigned int rac = 0xffff;
1199 GSList *tokens = NULL;
1202 GSList *lines = NULL;
1204 lines = (GSList *) data;
1205 if (1 != g_slist_length(lines)) {
1206 dbg("unsolicited msg but multiple line");
1209 line = (char *) (lines->data);
1210 dbg("+CGREG NOTI RECEIVED");
1213 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1215 Possible values of <stat> can be
1216 0 Not registered, ME is not currently searching a new operator to register to
1217 1 Registered, home network
1218 2 Not registered, but ME is currently searching a new operator to register
1219 3 Registration denied
1221 5 Registered, in roaming
1224 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1227 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1235 6 UTRAN w/HSDPA and HSUPA
1236 Note: <Act> is supporting from R7 and above Protocol Stack.
1238 <rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
1241 tokens = tcore_at_tok_new(line);
1242 if (g_slist_length(tokens) < 1) {
1243 msg("invalid message");
1247 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1248 dbg("No STAT in +CGREG");
1252 if ((pResp = g_slist_nth_data(tokens, 1)))
1255 if ((pResp = g_slist_nth_data(tokens, 2)))
1258 dbg("No ci in +CGREG");
1260 if ((pResp = g_slist_nth_data(tokens, 3)))
1263 dbg("No AcT in +CGREG");
1265 if ((pResp = g_slist_nth_data(tokens, 4)))
1268 dbg("No rac in +CGREG");
1272 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
1274 ps_status = lookup_tbl_net_status[stat];
1276 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
1277 _ps_set(tcore_object_ref_plugin(o), ps_status);
1279 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1281 act = lookup_tbl_access_technology[AcT];
1282 tcore_network_set_access_technology(o, act);
1284 if (stat == AT_CREG_STAT_REG_ROAM)
1285 tcore_network_set_roaming_state(o, TRUE);
1287 tcore_network_set_roaming_state(o, FALSE);
1289 tcore_network_get_service_type(o, &service_type);
1290 dbg("prev_service_type = 0x%x", service_type);
1291 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1292 dbg("new_service_type = 0x%x", service_type);
1293 tcore_network_set_service_type(o, service_type);
1295 tcore_network_set_lac(o, lac);
1296 tcore_network_set_cell_id(o, ci);
1297 tcore_network_set_rac(o, rac);
1299 net_lac_cell_info.lac = lac;
1300 net_lac_cell_info.cell_id = ci;
1302 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1303 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1305 regist_status.cs_domain_status = cs_status;
1306 regist_status.ps_domain_status = ps_status;
1307 regist_status.service_type = service_type;
1308 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1310 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1311 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1313 if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
1314 noti.status = TELEPHONY_HSDPA_ON;
1316 noti.status = TELEPHONY_HSDPA_OFF;
1319 case AT_COPS_ACT_GSM:/*Fall Through*/
1320 case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
1321 case AT_COPS_ACT_UTRAN:/*Fall Through*/
1322 case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
1323 case AT_COPS_ACT_E_UTRAN:
1325 dbg("Not required for Protocol Status Notification");
1328 case AT_COPS_ACT_UTRAN_HSDPA:
1331 noti.status = TELEPHONY_HSDPA_ON;
1334 case AT_COPS_ACT_UTRAN_HSUPA:
1337 noti.status = TELEPHONY_HSUPA_ON;
1340 case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
1343 noti.status = TELEPHONY_HSPA_ON;
1353 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
1354 sizeof(struct tnoti_ps_protocol_status), ¬i);
1356 /* Get PLMN ID needed to application */
1357 // get_serving_network(o, NULL);
1359 dbg("Response NOK");
1364 tcore_at_tok_free(tokens);
1368 static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
1370 GSList *lines = NULL;
1372 struct tnoti_network_registration_status regist_status;
1373 enum telephony_network_service_domain_status cs_status;
1374 enum telephony_network_service_domain_status ps_status;
1375 enum telephony_network_service_type service_type;
1376 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1377 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1380 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
1381 int stat = 0, AcT = 0;
1382 unsigned int lac = 0xffff, ci = 0xffff;
1383 GSList *tokens = NULL;
1386 lines = (GSList *) event_info;
1387 if (1 != g_slist_length(lines)) {
1388 dbg("unsolicited msg but multiple line");
1391 line = (char *) (lines->data);
1393 dbg("+CREG NOTI RECEIVED");
1396 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1398 Possible values of <stat> can be
1399 0 Not registered, ME is not currently searching a new operator to register to
1400 1 Registered, home network
1401 2 Not registered, but ME is currently searching a new operator to register
1402 3 Registration denied
1404 5 Registered, in roaming
1407 string type; two byte location area code in hexadecimal format (e.g. 00C3)
1410 string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
1418 6 UTRAN w/HSDPA and HSUPA
1419 Note: <Act> is supporting from R7 and above Protocol Stack.
1422 tokens = tcore_at_tok_new(line);
1423 if (g_slist_length(tokens) < 1) {
1424 msg("invalid message");
1428 if (!(pResp = g_slist_nth_data(tokens, 0))) {
1429 dbg("No STAT in +CREG");
1433 if ((pResp = g_slist_nth_data(tokens, 1)))
1436 if ((pResp = g_slist_nth_data(tokens, 2)))
1439 dbg("No ci in +CREG");
1441 if ((pResp = g_slist_nth_data(tokens, 3)))
1444 dbg("No AcT in +CREG");
1448 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
1450 cs_status = lookup_tbl_net_status[stat];
1451 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
1453 // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1454 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
1456 act = lookup_tbl_access_technology[AcT];
1457 tcore_network_set_access_technology(o, act);
1459 if (stat == AT_CREG_STAT_REG_ROAM)
1460 tcore_network_set_roaming_state(o, TRUE);
1462 tcore_network_set_roaming_state(o, FALSE);
1464 tcore_network_get_service_type(o, &service_type);
1465 dbg("prev_service_type = 0x%x", service_type);
1466 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1467 dbg("new_service_type = 0x%x", service_type);
1468 tcore_network_set_service_type(o, service_type);
1470 tcore_network_set_lac(o, lac);
1471 tcore_network_set_cell_id(o, ci);
1473 net_lac_cell_info.lac = lac;
1474 net_lac_cell_info.cell_id = ci;
1476 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1477 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1479 regist_status.cs_domain_status = cs_status;
1480 regist_status.ps_domain_status = ps_status;
1481 regist_status.service_type = service_type;
1482 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1484 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1485 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1487 /* Get PLMN ID needed to application */
1488 if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
1489 NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
1490 get_serving_network(o, NULL);
1492 dbg("Response NOK");
1497 tcore_at_tok_free(tokens);
1501 static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
1503 struct tnoti_network_icon_info net_icon_info = {0};
1505 char *rssiToken = NULL;
1506 char *batteryToken = NULL;
1507 GSList *tokens = NULL;
1508 GSList *lines = NULL;
1510 lines = (GSList *) event_info;
1511 if (1 != g_slist_length(lines)) {
1512 dbg("unsolicited msg but multiple line");
1515 line = (char *) (lines->data);
1516 dbg("+XCIEV Network Icon Info Noti Recieve");
1517 memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
1522 tokens = tcore_at_tok_new(line);
1523 if (g_slist_length(tokens) != 2) {
1524 msg("invalid message");
1528 rssiToken = (char *) g_slist_nth_data(tokens, 0);
1530 if (strlen(rssiToken) > 0) {
1531 net_icon_info.type = NETWORK_ICON_INFO_RSSI;
1532 net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
1533 dbg("rssi level : %d", net_icon_info.rssi);
1536 batteryToken = (char *) g_slist_nth_data(tokens, 1);
1537 if (strlen(batteryToken) > 0) {
1538 net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
1539 net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
1540 dbg("battery level : %d", net_icon_info.battery);
1543 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
1544 sizeof(struct tnoti_network_icon_info), &net_icon_info);
1546 dbg("Response NOK");
1552 tcore_at_tok_free(tokens);
1557 static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
1559 struct tnoti_network_timeinfo net_time_info = {0};
1561 GSList *tokens = NULL;
1563 char *time_zone = NULL;
1564 GSList *lines = NULL;
1565 char ptime_param[20] = {0};
1566 UserRequest *ur = NULL;
1567 dbg("Enter : on_event_network_ctzv_time_info");
1569 lines = (GSList *) event_info;
1570 if (1 != g_slist_length(lines)) {
1571 dbg("unsolicited msg but multiple line");
1574 line = (char *) (lines->data);
1578 <tz> integer value indicating the time zone (e.g. -22 or +34)
1579 <time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
1582 dbg("Network time info (+CTZV) recieved");
1586 dbg("noti line is %s", line);
1588 tokens = tcore_at_tok_new(line);
1590 if (g_slist_length(tokens) < 2) {
1591 msg("invalid message");
1595 if ((time_zone = g_slist_nth_data(tokens, 0))) {
1596 net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
1599 if (tcore_network_get_plmn(o) != NULL)
1600 strcpy(net_time_info.plmn, tcore_network_get_plmn(o));
1602 if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
1603 strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
1604 net_time_info.year = atoi(ptime_param);
1606 strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
1607 net_time_info.month = atoi(ptime_param);
1609 strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
1610 net_time_info.day = atoi(ptime_param);
1612 strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
1613 net_time_info.hour = atoi(ptime_param);
1615 strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
1616 net_time_info.minute = atoi(ptime_param);
1618 strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
1619 net_time_info.second = atoi(ptime_param);
1621 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);
1623 dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
1625 /* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
1626 nwk_prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
1628 dbg("line is NULL");
1633 tcore_at_tok_free(tokens);
1635 dbg("Exit: on_event_network_ctzv_time_info");
1639 static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
1640 const void *data, void *user_data)
1642 const struct tresp_sim_read *resp = data;
1643 CoreObject *o = user_data;
1645 if (command == TRESP_SIM_GET_SPN) {
1646 dbg("OK SPN GETTING!!");
1647 dbg("resp->result = 0x%x", resp->result);
1648 dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
1649 dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
1651 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *) resp->data.spn.spn);
1655 * 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
1656 * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
1657 * 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
1658 * 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
1660 if (resp->data.spn.display_condition & 0x01) {
1661 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1663 if ((resp->data.spn.display_condition & 0x02) == 0) {
1664 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
1666 if ((resp->data.spn.display_condition & 0x03) == 0x01) {
1667 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
1672 static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
1673 unsigned int data_len, void *data, void *user_data)
1675 const struct tnoti_sim_status *sim = data;
1676 UserRequest *ur = NULL;
1678 if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
1679 ur = tcore_user_request_new(NULL, NULL);
1680 tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
1681 tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
1682 tcore_object_dispatch_request(source, ur);
1685 return TCORE_HOOK_RETURN_CONTINUE;
1688 static TReturn search_network(CoreObject *o, UserRequest *ur)
1691 TcorePending *pending = NULL;
1692 TcoreATRequest *atreq = NULL;
1693 char *cmd_str = NULL;
1694 dbg("search_network - ENTER!!");
1697 return TCORE_RETURN_EINVAL;
1699 h = tcore_object_get_hal(o);
1700 if(FALSE == tcore_hal_get_power_state(h)){
1701 dbg("cp not ready/n");
1702 return TCORE_RETURN_ENOSYS;
1705 pending = tcore_pending_new(o, 0);
1707 cmd_str = g_strdup_printf("AT+COPS=?");
1708 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1710 tcore_pending_set_request_data(pending, 0, atreq);
1711 tcore_pending_set_timeout(pending, 60);
1712 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1713 tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
1714 tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
1715 tcore_pending_link_user_request(pending, ur);
1716 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1718 tcore_hal_send_request(h, pending);
1720 return TCORE_RETURN_SUCCESS;
1723 static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1726 TcorePending *pending = NULL;
1727 TcoreATRequest *atreq;
1728 char *cmd_str = NULL;
1729 int format = 0; /* default value for long alphanumeric */
1734 const struct treq_network_set_plmn_selection_mode *req_data = NULL;
1737 dbg("set_plmn_selection_mode - ENTER!!");
1740 return TCORE_RETURN_EINVAL;
1742 req_data = tcore_user_request_ref_data(ur, NULL);
1743 h = tcore_object_get_hal(o);
1744 if(FALSE == tcore_hal_get_power_state(h)){
1745 dbg("cp not ready/n");
1746 return TCORE_RETURN_ENOSYS;
1748 pending = tcore_pending_new(o, 0);
1750 // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
1751 /* oper parameter format
1752 - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
1753 - 1 <oper> format presentation is set to short alphanumeric.
1754 - 2 <oper> format presentations set to numeric.
1757 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
1762 switch (req_data->mode) {
1763 case NETWORK_SELECT_MODE_MANUAL:
1765 mode = AT_COPS_MODE_MANUAL;
1766 format = AT_COPS_FORMAT_NUMERIC;
1769 memcpy(plmn, req_data->plmn, 6);
1771 if (strlen(req_data->plmn) == 6) {
1776 cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
1780 case NETWORK_SELECT_MODE_AUTOMATIC:
1782 cmd_str = g_strdup("AT+COPS=0");
1787 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
1789 tcore_pending_set_request_data(pending, 0, atreq);
1790 tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
1791 tcore_pending_link_user_request(pending, ur);
1792 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1794 tcore_hal_send_request(h, pending);
1796 return TCORE_RETURN_SUCCESS;
1799 static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1802 TcorePending *pending = NULL;
1803 TcoreATRequest *atreq;
1804 char *cmd_str = NULL;
1806 dbg("get_plmn_selection_mode - ENTER!!");
1809 return TCORE_RETURN_EINVAL;
1811 h = tcore_object_get_hal(o);
1812 if(FALSE == tcore_hal_get_power_state(h)){
1813 dbg("cp not ready/n");
1814 return TCORE_RETURN_ENOSYS;
1816 pending = tcore_pending_new(o, 0);
1818 cmd_str = g_strdup_printf("AT+COPS?");
1819 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1821 tcore_pending_set_request_data(pending, 0, atreq);
1822 tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
1823 tcore_pending_link_user_request(pending, ur);
1824 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1826 tcore_hal_send_request(h, pending);
1828 return TCORE_RETURN_SUCCESS;
1832 static TReturn set_band(CoreObject *o, UserRequest *ur)
1835 TcorePending *pending = NULL;
1836 TcorePending *pending_gsm = NULL;
1837 TcorePending *pending_umts = NULL;
1838 TcoreATRequest *atreq;
1839 char *cmd_str = NULL;
1840 const struct treq_network_set_band *req_data;
1841 gboolean set_gsm_band = 0;
1842 gboolean set_umts_band = 0;
1844 int gsm_band2 = 255;
1845 char *umts_band = NULL;
1846 UserRequest *dup_ur_gsm = NULL;
1847 UserRequest *dup_ur_umts = NULL;
1849 dbg("set_band - ENTER!!");
1852 return TCORE_RETURN_EINVAL;
1854 req_data = tcore_user_request_ref_data(ur, NULL);
1855 h = tcore_object_get_hal(o);
1856 if(FALSE == tcore_hal_get_power_state(h)){
1857 dbg("cp not ready/n");
1858 return TCORE_RETURN_ENOSYS;
1861 dbg("set_band - called with band = %d", req_data->band);
1863 switch (req_data->band) {
1864 case NETWORK_BAND_TYPE_GSM850:
1865 gsm_band = AT_GSM_XBANDSEL_850;
1866 set_gsm_band = TRUE;
1869 case NETWORK_BAND_TYPE_GSM_900_1800:
1870 gsm_band = AT_GSM_XBANDSEL_900;
1871 gsm_band2 = AT_GSM_XBANDSEL_1800;
1872 set_gsm_band = TRUE;
1875 case NETWORK_BAND_TYPE_GSM1900:
1876 gsm_band = AT_GSM_XBANDSEL_1900;
1877 set_gsm_band = TRUE;
1880 case NETWORK_BAND_TYPE_GSM1800:
1881 gsm_band = AT_GSM_XBANDSEL_1800;
1882 set_gsm_band = TRUE;
1885 case NETWORK_BAND_TYPE_GSM_850_1900:
1886 gsm_band = AT_GSM_XBANDSEL_850;
1887 gsm_band2 = AT_GSM_XBANDSEL_1900;
1888 set_gsm_band = TRUE;
1891 case NETWORK_BAND_TYPE_ANY:
1892 gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
1893 set_umts_band = TRUE;
1894 set_gsm_band = TRUE;
1897 case NETWORK_BAND_TYPE_WCDMA:
1898 set_umts_band = TRUE;
1901 case NETWORK_BAND_TYPE_WCDMA2100:
1902 umts_band = "UMTS_BAND_I";
1903 set_umts_band = TRUE;
1906 case NETWORK_BAND_TYPE_WCDMA1900:
1907 umts_band = "UMTS_BAND_II";
1908 set_umts_band = TRUE;
1911 case NETWORK_BAND_TYPE_WCDMA850:
1912 umts_band = "UMTS_BAND_V";
1913 set_umts_band = TRUE;
1920 dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
1922 if (set_umts_band == TRUE) {
1923 if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
1924 cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
1926 cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
1928 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
1929 pending_umts = tcore_pending_new(o, 0);
1931 tcore_pending_set_request_data(pending_umts, 0, atreq);
1932 tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
1933 tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
1935 /* duplicate user request for UMTS Band setting AT command for same UR */
1936 dup_ur_umts = tcore_user_request_ref(ur);
1937 tcore_pending_link_user_request(pending_umts, dup_ur_umts);
1938 tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
1940 tcore_hal_send_request(h, pending_umts);
1944 if (set_gsm_band == TRUE) {
1945 dbg("Entered set_gsm_band");
1946 if (gsm_band2 == 255)
1947 cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
1949 cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
1951 dbg("Command string: %s", cmd_str);
1952 atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
1953 pending_gsm = tcore_pending_new(o, 0);
1955 tcore_pending_set_request_data(pending_gsm, 0, atreq);
1956 tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
1957 tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
1959 /* duplicate user request for GSM Band setting AT command for same UR */
1960 dup_ur_gsm = tcore_user_request_ref(ur);
1961 tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
1962 tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
1964 tcore_hal_send_request(h, pending_gsm);
1968 /* Lock device to specific RAT as requested by application */
1970 AT+XRAT=<Act>[,<PreferredAct>]
1971 <AcT> indicates the radio access technology and may be
1973 1 GSM / UMTS Dual mode
1976 if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
1977 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
1978 } else if (set_umts_band == TRUE) {
1979 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
1981 cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
1983 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
1984 pending = tcore_pending_new(o, 0);
1986 tcore_pending_set_request_data(pending, 0, atreq);
1987 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1988 tcore_pending_set_response_callback(pending, on_response_set_xrat, NULL);
1989 tcore_pending_link_user_request(pending, ur);
1990 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1992 tcore_hal_send_request(h, pending);
1994 return TCORE_RETURN_SUCCESS;
1997 static TReturn get_band(CoreObject *o, UserRequest *ur)
2000 TcorePending *pending = NULL;
2001 TcoreATRequest *atreq;
2002 char *cmd_str = NULL;
2003 dbg("get_band - ENTER!!");
2006 return TCORE_RETURN_EINVAL;
2008 h = tcore_object_get_hal(o);
2009 if(FALSE == tcore_hal_get_power_state(h)){
2010 dbg("cp not ready/n");
2011 return TCORE_RETURN_ENOSYS;
2014 /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
2015 cmd_str = g_strdup_printf("AT+XRAT?");
2016 atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
2017 pending = tcore_pending_new(o, 0);
2018 tcore_pending_set_request_data(pending, 0, atreq);
2019 tcore_pending_set_response_callback(pending, on_response_get_xrat, NULL);
2020 tcore_pending_link_user_request(pending, ur);
2021 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2022 tcore_hal_send_request(h, pending);
2025 return TCORE_RETURN_SUCCESS;
2028 static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
2031 TcorePlugin *p = NULL;
2032 TcorePending *pending = NULL;
2033 TcoreATRequest *atreq = NULL;
2034 struct treq_network_set_preferred_plmn *req_data = NULL;
2035 char *cmd_str = NULL;
2036 int format = 2; /* Alway use numeric format, as application gives data in this default format */
2038 int gsm_compact_act = 0;
2042 return TCORE_RETURN_EINVAL;
2044 p = tcore_object_ref_plugin(o);
2045 h = tcore_object_get_hal(o);
2046 if(FALSE == tcore_hal_get_power_state(h)){
2047 dbg("cp not ready/n");
2048 return TCORE_RETURN_ENOSYS;
2051 req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
2052 pending = tcore_pending_new(o, 0);
2054 dbg("Entry set_preferred_plmn");
2057 [<index>][,<format>[,<oper>[,<GSM_AcT>,
2058 <GSM_Compact_AcT>,<UTRAN_AcT>]]]
2061 if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
2063 else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
2065 else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
2066 gsm_act = utran_act = TRUE;
2068 if (strlen(req_data->plmn) > 6) {
2069 req_data->plmn[6] = '\0';
2070 } else if (strlen(req_data->plmn) == 6) {
2071 if (req_data->plmn[5] == '#') {
2072 req_data->plmn[5] = '\0';
2075 cmd_str = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d", req_data->ef_index + 1, format, req_data->plmn, gsm_act, gsm_compact_act, utran_act);
2077 dbg("cmd_str - %s", cmd_str);
2078 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
2080 tcore_pending_set_request_data(pending, 0, atreq);
2081 tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, NULL);
2082 tcore_pending_link_user_request(pending, ur);
2083 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2085 tcore_hal_send_request(h, pending);
2089 dbg("Exit set_preferred_plmn");
2091 return TCORE_RETURN_SUCCESS;
2094 static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
2097 TcorePending *pending = NULL;
2098 TcoreATRequest *atreq = NULL;
2100 char *cmd_str = NULL;
2102 dbg("get_preferred_plmn - ENTER!!");
2105 return TCORE_RETURN_EINVAL;
2107 h = tcore_object_get_hal(o);
2108 if(FALSE == tcore_hal_get_power_state(h)){
2109 dbg("cp not ready/n");
2110 return TCORE_RETURN_ENOSYS;
2113 pending = tcore_pending_new(o, 0);
2115 cmd_str = g_strdup_printf("AT+CPOL?");
2116 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
2118 tcore_pending_set_request_data(pending, 0, atreq);
2119 tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
2120 tcore_pending_link_user_request(pending, ur);
2121 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
2123 tcore_hal_send_request(h, pending);
2127 dbg("get_preferred_plmn - EXIT!!");
2129 return TCORE_RETURN_SUCCESS;
2132 static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
2134 dbg("get_serving_network - ENTER!!");
2137 return TCORE_RETURN_EINVAL;
2139 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2140 dbg("cp not ready/n");
2141 return TCORE_RETURN_ENOSYS;
2144 dbg("new pending(AT+COPS?)");
2146 nwk_prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
2147 return TCORE_RETURN_SUCCESS;
2150 static struct tcore_network_operations network_ops = {
2151 .search = search_network,
2152 .set_plmn_selection_mode = set_plmn_selection_mode,
2153 .get_plmn_selection_mode = get_plmn_selection_mode,
2154 .set_service_domain = NULL,
2155 .get_service_domain = NULL,
2156 .set_band = set_band,
2157 .get_band = get_band,
2158 .set_preferred_plmn = set_preferred_plmn,
2159 .get_preferred_plmn = get_preferred_plmn,
2162 .set_power_on_attach = NULL,
2163 .get_power_on_attach = NULL,
2164 .set_cancel_manual_search = NULL,
2165 .get_serving_network = get_serving_network,
2168 gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
2170 CoreObject *o = NULL;
2172 o = tcore_network_new(p, "umts_network", &network_ops, h);
2176 tcore_object_add_callback(o, "+CREG", on_event_cs_network_regist, NULL);
2177 tcore_object_add_callback(o, "+CGREG", on_event_ps_network_regist, NULL);
2178 tcore_object_add_callback(o, "+XCIEV", on_event_network_icon_info, NULL);
2180 /* +CTZV: <tz>,<time> */
2181 tcore_object_add_callback(o, "+CTZV", on_event_network_ctzv_time_info, NULL);
2183 tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_SIM_STATUS, on_hook_sim_init, o);
2185 _insert_mcc_mnc_oper_list(p, o);
2190 void s_network_exit(TcorePlugin *p)
2194 o = tcore_plugin_ref_core_object(p, "umts_network");
2196 tcore_network_free(o);