4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hayoon Ko <hayoon.ko@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.
30 #include <core_object.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_XBANDSEL_0 0
70 #define AT_XBANDSEL_1800 1800
71 #define AT_XBANDSEL_1900 1900
72 #define AT_XBANDSEL_850 850
73 #define AT_XBANDSEL_450 450
74 #define AT_XBANDSEL_480 480
75 #define AT_XBANDSEL_750 750
76 #define AT_XBANDSEL_380 380
77 #define AT_XBANDSEL_410 410
79 #define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
80 #define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
82 static unsigned int lookup_tbl_net_status[] = {
83 [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
84 [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
85 [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
86 [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
87 [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
88 [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
91 static unsigned int lookup_tbl_access_technology[] = {
92 [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
93 [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
94 [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
95 [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
96 [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
97 [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
98 [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
99 [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
102 static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
105 static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
107 dbg("on_confirmation_modem_message_send - msg out from queue.\n");
109 if (result == FALSE) {
118 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, TcorePendingResponseCallback callback)
120 TcoreATRequest *req = NULL;
123 TcorePending *pending = NULL;
126 o = tcore_plugin_ref_core_object(plugin, co_name);
127 hal = tcore_object_get_hal(o);
129 pending = tcore_pending_new(o, 0);
130 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
132 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
134 tcore_pending_set_request_data(pending, 0, req);
135 tcore_pending_set_response_callback(pending, callback, req->cmd);
136 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
138 ret = tcore_hal_send_request(hal, pending);
143 static void _insert_mcc_mnc_oper_list(TcorePlugin *p, CoreObject *o)
148 char query[255] = { 0, };
151 GHashTable *result = NULL, *row = NULL;
152 struct tcore_network_operator_info *noi = NULL;
155 s = tcore_plugin_ref_server(p);
156 strg = tcore_server_find_storage(s, "database");
158 handle = tcore_storage_create_handle(strg, "/opt/dbspace/.mcc_mnc_oper_list.db");
160 dbg("fail to create database handle");
164 snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
166 result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
167 (GDestroyNotify) g_hash_table_destroy);
169 tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
171 g_hash_table_iter_init(&iter, result);
172 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
175 noi = calloc(sizeof(struct tcore_network_operator_info), 1);
177 snprintf(noi->mcc, 4, "%s", (char *)g_hash_table_lookup(row, "1"));
178 snprintf(noi->mnc, 4, "%s", (char *)g_hash_table_lookup(row, "2"));
179 snprintf(noi->name, 41, "%s", (char *)g_hash_table_lookup(row, "3"));
180 snprintf(noi->country, 4, "%s", (char *)g_hash_table_lookup(row, "0"));
182 tcore_network_operator_info_add(o, noi);
187 dbg("count = %d", count);
189 g_hash_table_destroy(result);
191 tcore_storage_remove_handle(strg, handle);
194 static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
195 int domain, int act, int cs_status, int ps_status)
197 enum telephony_network_service_type ret;
202 case NETWORK_ACT_UNKNOWN:
203 ret = NETWORK_SERVICE_TYPE_UNKNOWN;
206 case NETWORK_ACT_GSM:
207 if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
208 ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
210 ret = NETWORK_SERVICE_TYPE_2G;
213 case NETWORK_ACT_EGPRS:
214 return NETWORK_SERVICE_TYPE_2_5G_EDGE;
217 case NETWORK_ACT_UMTS:
218 ret = NETWORK_SERVICE_TYPE_3G;
223 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
224 ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
226 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)
234 ret = NETWORK_SERVICE_TYPE_SEARCH;
237 else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY)
239 if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
245 ret = NETWORK_SERVICE_TYPE_EMERGENCY;
252 static void _ps_set(TcorePlugin *p, int status)
254 GSList *co_list = NULL;
256 co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_PS);
258 CoreObject *o = NULL;
259 o = (CoreObject *) co_list->data;
263 if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
264 tcore_ps_set_online(o, TRUE);
267 tcore_ps_set_online(o, FALSE);
269 } while ((co_list = g_slist_next(co_list)));
271 g_slist_free(co_list);
274 static void on_timeout_search_network(TcorePending *p, void *user_data)
277 struct tresp_network_search resp;
279 dbg("TIMEOUT !!!!! pending=%p", p);
281 memset(&resp, 0, sizeof(struct tresp_network_search));
285 ur = tcore_pending_ref_user_request(p);
287 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
291 static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
294 const TcoreATResponse *atResp = data;
295 //GSList *tokens = NULL;
296 //char * line = NULL;
297 struct tresp_network_set_plmn_selection_mode resp = {0};
299 if(atResp->success > 0)
302 resp.result = TCORE_RETURN_SUCCESS;
307 resp.result = TCORE_RETURN_FAILURE;
310 ur = tcore_pending_ref_user_request(p);
312 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
316 static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
319 struct tresp_network_get_plmn_selection_mode resp = {0};
320 const TcoreATResponse *atResp = data;
321 GSList *tokens = NULL;
325 resp.result = TCORE_RETURN_FAILURE;
327 if(atResp->success > 0)
331 +COPS: <mode>[,<format>,<oper>[,< AcT>]]
336 line = (char*)atResp->lines->data;
337 tokens = tcore_at_tok_new(line);
338 if (g_slist_length(tokens) < 1){
339 msg("invalid message");
342 mode = atoi(tcore_at_tok_nth(tokens, 0));
343 dbg("mode = %d", mode);
346 case AT_COPS_MODE_AUTOMATIC:
347 resp.mode = NETWORK_SELECT_MODE_GLOBAL_AUTOMATIC;
349 case AT_COPS_MODE_MANUAL:
350 case AT_COPS_MODE_MANUAL_AUTOMATIC:
351 resp.mode = NETWORK_SELECT_MODE_GSM_MANUAL;
353 case AT_COPS_MODE_DEREGISTER:
354 case AT_COPS_MODE_SET_ONLY:
355 resp.result = TCORE_RETURN_FAILURE;
358 resp.result = TCORE_RETURN_SUCCESS;
364 resp.result = TCORE_RETURN_FAILURE;
368 ur = tcore_pending_ref_user_request(p);
370 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
374 tcore_at_tok_free(tokens);
380 static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
383 struct tresp_network_search resp;
386 const TcoreATResponse *atResp = data;
387 GSList *tokens = NULL;
388 GSList *network_token = NULL;
389 int AcT=0 , stat = 0;
391 char* temp_plmn_info =NULL;
393 int num_network_avail = 0;
395 memset(&resp, 0, sizeof(struct tresp_network_search));
396 resp.result = TCORE_RETURN_FAILURE;
399 if(atResp->success > 0)
403 line = (char*)atResp->lines->data;
404 tokens = tcore_at_tok_new(line);
405 num_network_avail = g_slist_length(tokens);
406 dbg(" length of tokens is %d\n", num_network_avail);
407 if (num_network_avail < 1) {
408 msg("invalid message");
413 resp.result = TCORE_RETURN_SUCCESS;
415 * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
416 * [,,(list of supported <mode>s),(list of supported <format>s)]
419 /* (2,"IND airtel","airtel","40445",2,),(1,"IND airtel","airtel","40445",0,),(3,"TATA DOCOMO","TATA DO","405034",2,) */
421 for(i=0; ((i<num_network_avail) && (i<MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++)
423 /* (2,"IND airtel","airtel","40445",2,) */
424 network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
426 pResp = (tcore_at_tok_nth(network_token, 0));
428 dbg("status : %s",pResp);
429 resp.list[i].status = (enum telephony_network_plmn_status)atoi(pResp);
432 if (pResp = (tcore_at_tok_nth(network_token, 1)))
433 { /* Long Aplha name */
434 dbg("Long Aplha name : %s",pResp);
436 if(strlen(pResp) > 0)
437 /* Strip off starting quote & ending quote */
438 strncpy(resp.list[i].name, pResp+1, strlen(pResp)-2);
440 else if (pResp = (tcore_at_tok_nth(network_token, 2)))
442 dbg("Short Aplha name : %s",pResp);
443 /* Short Aplha name */
444 /* Strip off starting quote & ending quote */
445 if(strlen(pResp) > 0)
446 strncpy(resp.list[i].name, pResp+1, strlen(pResp)-2);
450 pResp = tcore_at_tok_nth(network_token, 3);
453 dbg("PLMN ID : %s",pResp);
454 if(strlen(pResp) > 0){
455 temp_plmn_info = malloc((strlen(pResp) - 2)+1); /* 1 extra character for NULL storage */
456 memset(temp_plmn_info, 0x00, strlen(pResp) -2+1);
458 /* Strip off starting quotes & ending quotes */
459 strncpy(temp_plmn_info, pResp+1, strlen(pResp)-2);
463 /* Decode PLMN ID from Hexa String to Hexa bytes */
464 //cp_plmn = util_hexStringToBytes(temp_plmn_info);
466 memcpy(resp.list[i].plmn, temp_plmn_info, 6);
467 if (resp.list[i].plmn[5] == '#')
468 resp.list[i].plmn[5] = '\0';
470 /* Parse Access Technology */
471 if(pResp = tcore_at_tok_nth(tokens, 4))
473 if(strlen(pResp) > 0){
477 resp.list[i].act = NETWORK_ACT_GSM;
479 resp.list[i].act = NETWORK_ACT_UMTS;
483 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, AcT);
486 tcore_at_tok_free(network_token);
487 free(temp_plmn_info);
494 resp.result = TCORE_RETURN_FAILURE;
498 ur = tcore_pending_ref_user_request(p);
500 tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
502 tcore_at_tok_free(tokens);
506 static void on_response_set_service_domain(TcorePending *p, int data_len, const void *data, void *user_data)
514 static void on_response_get_service_domain(TcorePending *p, int data_len, const void *data, void *user_data)
522 static void on_response_set_band(TcorePending *p, int data_len, const void *data, void *user_data)
525 struct tresp_network_set_band resp;
528 const TcoreATResponse *atResp = data;
530 dbg("On Response Set Band");
531 if(atResp->success > 0)
534 resp.result = TCORE_RETURN_SUCCESS;
538 resp.result = TCORE_RETURN_FAILURE;
541 ur = tcore_pending_ref_user_request(p);
543 tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
547 static void on_response_get_band(TcorePending *p, int data_len, const void *data, void *user_data)
555 static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
563 static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
568 const TcoreATResponse *atResp = data;
569 GSList *tokens = NULL;
571 char temp_plmn_info[17] = {0};
573 int num_network_avail = 0;
576 struct tresp_network_get_preferred_plmn resp = {0};
578 int GSM_AcT2 = 0, GSM_Compact_AcT2= 0, UTRAN_AcT2 = 0;
582 if(atResp->success > 0)
586 total_lines = g_slist_length(atResp->lines);
587 dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
589 if (total_lines < 1) {
590 msg("invalid message");
594 if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
595 total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
598 +COPL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
599 +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
602 resp.result = TCORE_RETURN_SUCCESS;
604 for (i=0; i<total_lines; i++) {
605 /* Take each line response at a time & parse it */
606 line = tcore_at_tok_nth(atResp->lines, i);
607 tokens = tcore_at_tok_new(line);
609 /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
612 if (pResp = tcore_at_tok_nth(tokens, 0))
614 dbg("Index : %s",pResp);
615 resp.list[i].ef_index = atoi(pResp);
618 if(pResp = tcore_at_tok_nth(tokens, 1))
620 dbg("format : %s",pResp);
621 plmn_format = atoi(pResp);
624 /* Operator PLMN ID */
625 if(pResp = tcore_at_tok_nth(tokens, 2));
627 dbg("plmn ID : %s",pResp);
629 if(strlen(pResp) > 0){
630 strncmp(temp_plmn_info, pResp+1, strlen(pResp)-2);
633 if (plmn_format == 2)
635 //cp_plmn = util_hexStringToBytes(temp_plmn_info);
637 if (strncmp((char *)temp_plmn_info, "000000", 6) == 0)
640 memcpy(resp.list[i].plmn, temp_plmn_info, 6);
641 if (resp.list[i].plmn[5] == '#')
642 resp.list[i].plmn[5] = '\0';
649 if(pResp = tcore_at_tok_nth(tokens, 3)){
650 dbg("GSM_AcT2 : %s",pResp);
651 GSM_AcT2 = atoi(pResp);
654 if(pResp = tcore_at_tok_nth(tokens, 4)){
655 dbg("GSM_Compact AcT2 : %s",pResp);
656 GSM_Compact_AcT2 = atoi(pResp);
659 if(pResp = tcore_at_tok_nth(tokens, 5)){
660 dbg("UTRAN_AcT2 : %s",pResp);
661 UTRAN_AcT2 = atoi(pResp);
664 if(UTRAN_AcT2 && (GSM_AcT2 ||GSM_Compact_AcT2))
665 resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
667 resp.list[i].act = NETWORK_ACT_UMTS;
668 else if (GSM_AcT2 || GSM_Compact_AcT2)
669 resp.list[i].act = NETWORK_ACT_GPRS;
673 tcore_at_tok_free(tokens);
678 ur = tcore_pending_ref_user_request(p);
680 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
686 static void on_response_set_order(TcorePending *p, int data_len, const void *data, void *user_data)
694 static void on_response_get_order(TcorePending *p, int data_len, const void *data, void *user_data)
702 static void on_response_set_power_on_attach(TcorePending *p, int data_len, const void *data, void *user_data)
710 static void on_response_get_power_on_attach(TcorePending *p, int data_len, const void *data, void *user_data)
718 static void on_response_set_cancel_manual_search(TcorePending *p, int data_len, const void *data, void *user_data)
727 static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
729 const TcoreATResponse* resp = data;
731 struct tresp_network_get_serving_network Tresp = {0};
733 char *long_plmn_name, *short_plmn_name = NULL;
737 int network_mode = -1;
738 int plmn_format = -1;
739 enum telephony_network_access_technology AcT = NETWORK_ACT_UNKNOWN;
740 struct tnoti_network_identity noti ={0};
744 o = tcore_pending_ref_core_object(p);
746 if(resp->success <= 0){
749 ur = tcore_pending_ref_user_request(p);
751 Tresp.result = TCORE_RETURN_FAILURE;
752 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
758 nol = g_slist_length(resp->lines);
759 dbg("nol : %d", nol);
761 for(count =0; count < nol; count++){
763 line = g_slist_nth_data(resp->lines, count);
764 tokens = tcore_at_tok_new(line);
765 dbg("line %d start---------------",count);
767 if (pResp = tcore_at_tok_nth(tokens, 0)){
768 dbg("mode : %s",pResp);
769 network_mode = atoi(pResp);
773 if(pResp = tcore_at_tok_nth(tokens, 1))
775 dbg("format : %s",pResp);
777 plmn_format = atoi(pResp);
783 case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
784 if(pResp = tcore_at_tok_nth(tokens, 2))
786 dbg("long PLMN : %s",pResp);
787 if(strlen(pResp) > 0){
788 long_plmn_name = malloc((strlen(pResp) - 2)+1); /* 1 extra character for NULL storage */
789 memset(long_plmn_name, 0x00, strlen(pResp) -2+1);
790 /* Strip off starting quotes & ending quotes */
791 strncpy(long_plmn_name, pResp+1, strlen(pResp)-2);
793 //set network name into po
794 tcore_network_set_network_name(o,TCORE_NETWORK_NAME_TYPE_FULL,long_plmn_name);
799 case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
800 if(pResp = tcore_at_tok_nth(tokens, 2))
802 dbg("short PLMN : %s",pResp);
804 short_plmn_name = malloc((strlen(pResp) - 2)+1); /* 1 extra character for NULL storage */
805 memset(short_plmn_name, 0x00, strlen(pResp) -2+1);
806 /* Strip off starting quotes & ending quotes */
807 strncpy(short_plmn_name, pResp+1, strlen(pResp)-2);
809 //set network name into po
810 tcore_network_set_network_name(o,TCORE_NETWORK_NAME_TYPE_SHORT,short_plmn_name);
815 case AT_COPS_FORMAT_NUMERIC:
816 if(pResp = tcore_at_tok_nth(tokens, 2))
818 dbg("numeric : %s", pResp);
821 /* Strip off starting quotes & ending quotes */
822 strncpy(plmn, pResp+1, strlen(pResp)-2);
824 tcore_network_set_plmn(o,plmn);
834 if(pResp = tcore_at_tok_nth(tokens, 3))
837 dbg("act : %s",pResp);
838 AcT = lookup_tbl_access_technology[atoi(pResp)];
841 tcore_network_set_access_technology(o, AcT);
845 tcore_at_tok_free(tokens);
848 memcpy(Tresp.plmn, plmn, 7);
849 tcore_network_get_access_technology(o, &(Tresp.act));
850 tcore_network_get_lac(o, &(Tresp.gsm.lac));
852 ur = tcore_pending_ref_user_request(p);
854 Tresp.result = TCORE_RETURN_SUCCESS;
855 tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
859 /* Network change noti */
860 struct tnoti_network_change network_change;
862 memset(&network_change, 0, sizeof(struct tnoti_network_change));
863 memcpy(network_change.plmn, plmn, 7);
864 tcore_network_get_access_technology(o, &(network_change.act));
865 tcore_network_get_lac(o, &(network_change.gsm.lac));
867 tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
868 TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
870 dbg("dbg.. network_change.plmn : %s",network_change.plmn);
871 dbg("dbg.. network_change.act : %d",network_change.act);
872 dbg("dbg.. network_change.gsm.lac : %d",network_change.gsm.lac);
875 if((AT_COPS_MODE_DEREGISTER !=network_mode) &&
876 (AT_COPS_MODE_SET_ONLY != network_mode)){
877 /*Network identity noti*/
878 memset(¬i, 0, sizeof(struct tnoti_network_change));
880 memcpy(noti.full_name, long_plmn_name, MIN(33, strlen(long_plmn_name)) );
882 memcpy(noti.short_name, short_plmn_name, MIN(17, strlen(long_plmn_name)) );
883 memcpy(noti.plmn, plmn,7);
884 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
885 o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
887 dbg("dbg.. noti.short_name : %s",noti.short_name);
888 dbg("dbg.. noti.full_name : %s",noti.full_name);
889 dbg("dbg.. noti.plmn : %s",noti.plmn);
894 free(long_plmn_name);
896 free(short_plmn_name);
903 static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
905 struct tnoti_network_registration_status regist_status;
906 enum telephony_network_service_domain_status cs_status;
907 enum telephony_network_service_domain_status ps_status;
908 enum telephony_network_service_type service_type;
909 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
910 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
911 struct tnoti_ps_protocol_status noti = {0};
913 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
915 unsigned int lac=0xffff, ci=0xffff;
916 unsigned int rac = 0xffff;
917 GSList* tokens = NULL;
920 GSList *lines = NULL;
922 lines = (GSList*)data;
923 if (1 != g_slist_length(lines)) {
924 dbg("unsolicited msg but multiple line");
927 line = (char*)(lines->data);
928 dbg("+CGREG NOTI RECEIVED");
931 +CREG: <stat> [[,<lac>,<ci>[AcT]]
933 Possible values of <stat> can be
934 0 Not registered, ME is not currently searching a new operator to register to
935 1 Registered, home network
936 2 Not registered, but ME is currently searching a new operator to register
937 3 Registration denied
939 5 Registered, in roaming
942 string type; two byte location area code in hexadecimal format (e.g. �00C3�)
945 string type; four byte cell ID in hexadecimal format (e.g. �0000A13F�)
953 6 UTRAN w/HSDPA and HSUPA
954 Note: <Act> is supporting from R7 and above Protocol Stack.
956 <rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
960 tokens = tcore_at_tok_new(line);
961 if(g_slist_length(tokens) < 1) {
962 msg("invalid message");
966 if(!(pResp = g_slist_nth_data(tokens, 0)))
968 dbg("No STAT in +CGREG");
974 if(pResp = g_slist_nth_data(tokens, 1))
977 if((pResp = g_slist_nth_data(tokens, 2)))
980 dbg("No ci in +CGREG");
982 if(pResp = g_slist_nth_data(tokens, 3))
985 dbg("No AcT in +CGREG");
987 if(pResp = g_slist_nth_data(tokens, 4))
990 dbg("No rac in +CGREG");
994 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
996 ps_status = lookup_tbl_net_status[stat];
998 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
999 _ps_set(tcore_object_ref_plugin(o), ps_status);
1001 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1003 act = lookup_tbl_access_technology[AcT];
1004 tcore_network_set_access_technology(o, act);
1006 if (stat == AT_CREG_STAT_REG_ROAM)
1007 tcore_network_set_roaming_state(o, TRUE);
1009 tcore_network_set_roaming_state(o, FALSE);
1011 tcore_network_get_service_type(o, &service_type);
1012 dbg("prev_service_type = 0x%x", service_type);
1013 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1014 dbg("new_service_type = 0x%x", service_type);
1015 tcore_network_set_service_type(o, service_type);
1017 tcore_network_set_lac(o, lac);
1018 tcore_network_set_cell_id(o, ci);
1019 tcore_network_set_rac(o, rac);
1021 net_lac_cell_info.lac = lac;
1022 net_lac_cell_info.cell_id = ci;
1024 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1025 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1027 regist_status.cs_domain_status = cs_status;
1028 regist_status.ps_domain_status = ps_status;
1029 regist_status.service_type = service_type;
1030 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1032 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1033 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1035 if(service_type == NETWORK_SERVICE_TYPE_HSDPA)
1036 noti.status = TELEPHONY_HSDPA_ON;
1038 noti.status = TELEPHONY_HSDPA_OFF;
1040 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
1041 sizeof(struct tnoti_ps_protocol_status), ¬i);
1043 /* Get PLMN ID needed to application */
1044 //get_serving_network(o, NULL);
1050 dbg("Response NOK");
1055 tcore_at_tok_free(tokens);
1059 static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
1061 GSList *lines = NULL;
1063 struct tnoti_network_registration_status regist_status;
1064 enum telephony_network_service_domain_status cs_status;
1065 enum telephony_network_service_domain_status ps_status;
1066 enum telephony_network_service_type service_type;
1067 enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
1068 struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
1071 unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
1073 unsigned int lac=0xffff, ci=0xffff;
1074 GSList* tokens = NULL;
1077 lines = (GSList*)event_info;
1078 if (1 != g_slist_length(lines)) {
1079 dbg("unsolicited msg but multiple line");
1082 line = (char*)(lines->data);
1084 dbg("+CREG NOTI RECEIVED");
1087 +CREG: <stat> [[,<lac>,<ci>[AcT]]
1089 Possible values of <stat> can be
1090 0 Not registered, ME is not currently searching a new operator to register to
1091 1 Registered, home network
1092 2 Not registered, but ME is currently searching a new operator to register
1093 3 Registration denied
1095 5 Registered, in roaming
1098 string type; two byte location area code in hexadecimal format (e.g. �00C3�)
1101 string type; four byte cell ID in hexadecimal format (e.g. �0000A13F�)
1109 6 UTRAN w/HSDPA and HSUPA
1110 Note: <Act> is supporting from R7 and above Protocol Stack.
1114 tokens = tcore_at_tok_new(line);
1115 if(g_slist_length(tokens) < 1) {
1116 msg("invalid message");
1120 if(!(pResp = g_slist_nth_data(tokens, 0)))
1122 dbg("No STAT in +CREG");
1128 if(pResp = g_slist_nth_data(tokens, 1))
1131 if((pResp = g_slist_nth_data(tokens, 2)))
1134 dbg("No ci in +CREG");
1136 if(pResp = g_slist_nth_data(tokens, 3))
1139 dbg("No AcT in +CREG");
1143 dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
1145 cs_status = lookup_tbl_net_status[stat];
1146 tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
1148 // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
1149 tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
1151 act = lookup_tbl_access_technology[AcT];
1152 tcore_network_set_access_technology(o, act);
1154 if (stat == AT_CREG_STAT_REG_ROAM)
1155 tcore_network_set_roaming_state(o, TRUE);
1157 tcore_network_set_roaming_state(o, FALSE);
1159 tcore_network_get_service_type(o, &service_type);
1160 dbg("prev_service_type = 0x%x", service_type);
1161 service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
1162 dbg("new_service_type = 0x%x", service_type);
1163 tcore_network_set_service_type(o, service_type);
1165 tcore_network_set_lac(o, lac);
1166 tcore_network_set_cell_id(o, ci);
1168 net_lac_cell_info.lac = lac;
1169 net_lac_cell_info.cell_id = ci;
1171 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
1172 sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
1174 regist_status.cs_domain_status = cs_status;
1175 regist_status.ps_domain_status = ps_status;
1176 regist_status.service_type = service_type;
1177 regist_status.roaming_status = tcore_network_get_roaming_state(o);
1179 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
1180 TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
1182 /* Get PLMN ID needed to application */
1183 if((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status )||
1184 NETWORK_SERVICE_DOMAIN_STATUS_FULL ==ps_status )
1185 get_serving_network(o, NULL);
1189 dbg("Response NOK");
1194 tcore_at_tok_free(tokens);
1199 static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
1201 struct tnoti_network_icon_info net_icon_info = {0};
1204 int rssi = 0, battery = 0;
1205 char * rssiToken = NULL;
1206 char *batteryToken = NULL;
1207 GSList* tokens = NULL;
1208 GSList *lines = NULL;
1210 lines = (GSList*)event_info;
1211 if (1 != g_slist_length(lines)) {
1212 dbg("unsolicited msg but multiple line");
1215 line = (char*)(lines->data);
1216 dbg("+XCIEV Network Icon Info Noti Recieve");
1217 memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
1223 tokens = tcore_at_tok_new(line);
1224 if (g_slist_length(tokens) != 2) {
1225 msg("invalid message");
1229 rssiToken = (char *)g_slist_nth_data(tokens, 0);
1231 if (strlen(rssiToken)>0)
1233 net_icon_info.type = NETWORK_ICON_INFO_RSSI;
1234 net_icon_info.rssi= atoi(g_slist_nth_data(tokens, 0));
1235 dbg("rssi level : %d",net_icon_info.rssi);
1239 dbg("No rssi value");
1242 batteryToken = (char *)g_slist_nth_data(tokens,1);
1243 if (strlen(batteryToken)>0)
1245 net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
1246 net_icon_info.battery= 1 + atoi(g_slist_nth_data(tokens, 1)); // 1 level added for proper battery indication
1247 dbg("battery level : %d",net_icon_info.battery);
1251 dbg("No battery level recieved");
1254 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
1255 sizeof(struct tnoti_network_icon_info), &net_icon_info);
1259 dbg("Response NOK");
1265 tcore_at_tok_free(tokens);
1270 static gboolean on_event_network_time_info(CoreObject *o, const void *event_info, void *user_data)
1272 struct tnoti_network_timeinfo net_time_info = {0};
1275 GSList* tokens = NULL;
1276 char *time= NULL, *time_zone_variance = NULL;
1277 GSList *lines = NULL;
1279 dbg("Network Time Info Noti Recieved");
1280 memset(&net_time_info, 0, sizeof(struct tnoti_network_icon_info));
1282 lines = (GSList*)event_info;
1283 if (1 != g_slist_length(lines)) {
1284 dbg("unsolicited msg but multiple line");
1287 line = (char*)(lines->data);
1290 <time> string type value; format is \93yy/MM/dd,hh:mms\94, wherein characters indicates year, month, day, hour, minutes, seconds.
1291 <timzone_variance> is a string \93GMT+HH:MM\94 or \93GMT-HH:MM\94 e.g. \93GMT+5:30\94
1293 dbg("Network time info noti recieved");
1298 dbg("noti line is %s", line);
1300 tokens = tcore_at_tok_new(line);
1301 strcpy(time, g_slist_nth_data(tokens, 0));
1302 strcpy(time_zone_variance , g_slist_nth_data(tokens, 1));
1304 strncpy(net_time_info.hour,time ,2);
1305 strncpy(net_time_info.month, time+3, 2);
1306 strncpy(net_time_info.day, time+6, 2);
1307 strncpy(net_time_info.hour, time+9 ,2);
1308 strncpy(net_time_info.minute, time+12,3);
1309 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);
1313 dbg("line is NULL");
1317 tcore_at_tok_free(tokens);
1321 static gboolean on_event_network_identity(CoreObject *o, const void *event_info, void *user_data)
1323 struct tnoti_network_identity noti;
1324 char plmn[7] = { 0, };
1327 GSList *lines = NULL;
1329 GSList* tokens = NULL;
1331 dbg("NOTI RECEIVED");
1332 lines = (GSList*)event_info;
1334 if (1 != g_slist_length(lines)) {
1335 dbg("unsolicited msg but multiple line");
1339 line = (char*)(lines->data);
1341 memset(¬i, 0, sizeof(struct tnoti_network_identity));
1342 dbg("Network identity noti recieved");
1347 dbg("noti line is %s", line);
1348 tokens = tcore_at_tok_new(line);
1350 strcpy(noti.plmn, g_slist_nth_data(tokens, 0));
1351 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
1355 dbg("Response NOK");
1360 tcore_at_tok_free(tokens);
1365 static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
1366 const void *data, void *user_data)
1368 const struct tresp_sim_read *resp = data;
1369 CoreObject *o = user_data;
1371 if (command == TRESP_SIM_GET_SPN) {
1372 dbg("OK SPN GETTING!!");
1373 dbg("resp->result = 0x%x", resp->result);
1374 dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
1375 dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
1377 tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *)resp->data.spn.spn);
1381 * 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
1382 * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
1383 * 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
1384 * 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
1386 if (resp->data.spn.display_condition & 0x01) {
1387 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
1389 if ((resp->data.spn.display_condition & 0x02) == 0) {
1390 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
1392 if ((resp->data.spn.display_condition & 0x03) == 0x01) {
1393 tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
1398 static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
1399 unsigned int data_len, void *data, void *user_data)
1401 const struct tnoti_sim_status *sim = data;
1402 UserRequest *ur = NULL;
1404 if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
1405 ur = tcore_user_request_new(NULL, NULL);
1406 tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
1407 tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
1408 tcore_object_dispatch_request(source, ur);
1411 return TCORE_HOOK_RETURN_CONTINUE;
1414 static TReturn search_network(CoreObject *o, UserRequest *ur)
1416 TcorePlugin *p = NULL;
1418 TcorePending *pending = NULL;
1419 TcoreATRequest *atreq = NULL;
1421 char*cmd_str = NULL;
1422 dbg("search_network - ENTER!!");
1425 return TCORE_RETURN_EINVAL;
1427 h = tcore_object_get_hal(o);
1428 pending = tcore_pending_new(o, 0);
1430 cmd_str = g_strdup_printf("AT+COPS=?\r");
1431 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1433 tcore_pending_set_request_data(pending, 0, atreq);
1434 //tcore_pending_set_timeout(pending, 60);
1435 //tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1436 tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
1437 //tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
1438 tcore_pending_link_user_request(pending, ur);
1439 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1441 tcore_hal_send_request(h, pending);
1443 return TCORE_RETURN_SUCCESS;
1446 static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1448 TcorePlugin *p = NULL;
1450 TcorePending *pending = NULL;
1451 TcoreATRequest *atreq;
1452 char*cmd_str = NULL;
1453 int format = 0; /* default value for long alphanumeric */
1457 const struct treq_network_set_plmn_selection_mode *req_data;
1460 dbg("set_plmn_selection_mode - ENTER!!");
1463 return TCORE_RETURN_EINVAL;
1465 req_data = tcore_user_request_ref_data(ur, NULL);
1466 h = tcore_object_get_hal(o);
1467 pending = tcore_pending_new(o, 0);
1469 // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
1470 /* oper parameter format
1471 - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
1472 - 1 <oper> format presentation is set to short alphanumeric.
1473 - 2 <oper> format presentations set to numeric.
1476 switch(req_data->mode) {
1477 case NETWORK_SELECT_MODE_GSM_MANUAL:
1479 mode = AT_COPS_MODE_MANUAL;
1480 format = AT_COPS_FORMAT_NUMERIC;
1483 memcpy(plmn, req_data->plmn, 6);
1485 if (strlen(req_data->plmn) == 5) {
1489 cmd_str = g_strdup_printf("AT+COPS=%d,%d,%s\r", mode, format, plmn);
1493 case NETWORK_SELECT_MODE_GLOBAL_AUTOMATIC:
1495 cmd_str = g_strdup("AT+COPS=0\r");
1500 atreq = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1502 tcore_pending_set_request_data(pending, 0, atreq);
1503 tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
1504 tcore_pending_link_user_request(pending, ur);
1505 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1508 tcore_hal_send_request(h, pending);
1510 return TCORE_RETURN_SUCCESS;
1513 static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
1515 TcorePlugin *p = NULL;
1517 TcorePending *pending = NULL;
1518 TcoreATRequest *atreq;
1519 char*cmd_str = NULL;
1521 dbg("get_plmn_selection_mode - ENTER!!");
1524 return TCORE_RETURN_EINVAL;
1526 h = tcore_object_get_hal(o);
1527 pending = tcore_pending_new(o, 0);
1529 cmd_str = g_strdup_printf("AT+COPS?\r");
1530 atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
1532 tcore_pending_set_request_data(pending, 0, atreq);
1533 tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
1534 tcore_pending_link_user_request(pending, ur);
1535 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1537 tcore_hal_send_request(h, pending);
1539 return TCORE_RETURN_SUCCESS;
1543 static TReturn set_band(CoreObject *o, UserRequest *ur)
1545 TcorePlugin *p = NULL;
1547 TcorePending *pending = NULL;
1548 TcoreATRequest *atreq;
1549 char*cmd_str = NULL;
1550 const struct treq_network_set_band *req_data;
1552 dbg("set_band - ENTER!!");
1555 return TCORE_RETURN_EINVAL;
1557 req_data = tcore_user_request_ref_data(ur, NULL);
1559 h = tcore_object_get_hal(o);
1560 pending = tcore_pending_new(o, 0);
1562 switch (req_data->band)
1564 case NETWORK_BAND_TYPE_GSM850:
1565 band = AT_XBANDSEL_850;
1568 case NETWORK_BAND_TYPE_GSM_900_1800:
1569 band = AT_XBANDSEL_1800; //summerize 900 + 1800
1572 case NETWORK_BAND_TYPE_GSM1900:
1573 band = AT_XBANDSEL_1900;
1575 case NETWORK_BAND_TYPE_GSM1800:
1576 band = AT_XBANDSEL_1800;
1578 case NETWORK_BAND_TYPE_GSM_850_1900:
1579 band = AT_XBANDSEL_1900; //summerize 850 + 1900
1585 pending = tcore_pending_new(o, 0);
1587 //TODO - Done only for UMTS case, need to do for GSM seperately?
1588 cmd_str = g_strdup_printf("AT+XUBANDSEL=%d", req_data->band);
1589 atreq = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
1591 tcore_pending_set_request_data(pending, 0, atreq);
1592 tcore_pending_set_timeout(pending, 0);
1593 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
1594 tcore_pending_set_response_callback(pending, on_response_set_band, NULL);
1595 tcore_pending_link_user_request(pending, ur);
1596 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1599 tcore_hal_send_request(h, pending);
1601 return TCORE_RETURN_SUCCESS;
1604 static TReturn get_band(CoreObject *o, UserRequest *ur)
1606 TcorePlugin *p = NULL;
1608 TcorePending *pending = NULL;
1610 TcoreATRequest *atreq;
1611 char*cmd_str = NULL;
1612 dbg("get_band - ENTER!!");
1615 return TCORE_RETURN_EINVAL;
1617 h = tcore_object_get_hal(o);
1618 pending = tcore_pending_new(o, 0);
1620 cmd_str = g_strdup_printf("AT+XUBANDSEL?\r");
1621 atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
1623 pending = tcore_pending_new(o, 0);
1624 tcore_pending_set_request_data(pending, 0, atreq);
1625 tcore_pending_set_response_callback(pending, on_response_get_band, NULL);
1626 tcore_pending_link_user_request(pending, ur);
1627 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1628 tcore_hal_send_request(h, pending);
1632 return TCORE_RETURN_SUCCESS;
1635 static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
1640 return TCORE_RETURN_SUCCESS;
1643 static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
1645 TcorePlugin *p = NULL;
1647 TcorePending *pending = NULL;
1648 TcoreATRequest *atreq = NULL;
1650 char*cmd_str = NULL;
1652 dbg("get_preferred_plmn - ENTER!!");
1655 return TCORE_RETURN_EINVAL;
1657 h = tcore_object_get_hal(o);
1658 pending = tcore_pending_new(o, 0);
1660 cmd_str = g_strdup_printf("AT+CPOL?\r");
1661 atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
1663 tcore_pending_set_request_data(pending, 0, atreq);
1664 tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
1665 tcore_pending_link_user_request(pending, ur);
1666 tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
1668 tcore_hal_send_request(h, pending);
1670 return TCORE_RETURN_SUCCESS;
1674 static TReturn set_cancel_manual_search(CoreObject *o, UserRequest *ur)
1679 return TCORE_RETURN_SUCCESS;
1682 static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
1684 TcorePlugin *p = NULL;
1686 TcorePending *pending = NULL;
1687 dbg("get_serving_network - ENTER!!");
1690 return TCORE_RETURN_EINVAL;
1692 dbg("new pending(AT+COPS?)");
1694 nwk_prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?\r", "+COPS", TCORE_AT_MULTILINE,on_response_get_serving_network);
1695 return TCORE_RETURN_SUCCESS;
1698 static struct tcore_network_operations network_ops = {
1699 .search = search_network,
1700 .set_plmn_selection_mode = set_plmn_selection_mode,
1701 .get_plmn_selection_mode = get_plmn_selection_mode,
1702 .set_service_domain = NULL,
1703 .get_service_domain = NULL,
1704 .set_band = set_band,
1705 .get_band = get_band,
1706 .set_preferred_plmn = set_preferred_plmn,
1707 .get_preferred_plmn = get_preferred_plmn,
1710 .set_power_on_attach = NULL,
1711 .get_power_on_attach = NULL,
1712 .set_cancel_manual_search = set_cancel_manual_search,
1713 .get_serving_network = get_serving_network,
1716 gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
1718 CoreObject *o = NULL;
1720 o = tcore_network_new(p, "umts_network", &network_ops, h);
1724 tcore_object_add_callback(o,"+CREG", on_event_cs_network_regist, NULL);
1725 tcore_object_add_callback(o,"+CGREG", on_event_ps_network_regist, NULL);
1726 tcore_object_add_callback(o, "+XCIEV", on_event_network_icon_info, NULL);
1728 //XNITZINFO is for <time><timezone variance>
1729 //CTZDST is for <dst>
1730 tcore_object_add_callback(o, "+XNITZINFO", on_event_network_time_info, NULL);
1731 tcore_object_add_callback(o, "+CTZDST", on_event_network_time_info, NULL);
1733 //tcore_object_add_callback(o, "+XCOPS", on_event_network_identity, NULL);
1735 //need to check whether the following is needed
1737 //tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_SIM_STATUS, on_hook_sim_init, o);
1739 _insert_mcc_mnc_oper_list(p, o);
1744 void s_network_exit(TcorePlugin *p)
1748 o = tcore_plugin_ref_core_object(p, "umts_network");
1750 tcore_network_free(o);