/*
* tel-plugin-imc
*
- * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Harish Bishnoi <hbishnoi@samsung.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <glib.h>
#include <tcore.h>
-#include <server.h>
-#include <plugin.h>
-#include <core_object.h>
#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <user_request.h>
#include <queue.h>
+#include <co_network.h>
+#include <co_ps.h>
+#include <server.h>
#include <storage.h>
+#include <util.h>
#include <at.h>
-#include <tzplatform_config.h>
+#include <vconf.h>
-#include <co_network.h>
-
-#include "imc_network.h"
#include "imc_common.h"
+#include "imc_network.h"
-#define IMC_NETWORK_BASE_16 16
+#define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
+#define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
+#define AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
+#define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
+#define AT_CREG_STAT_UNKNOWN 4 /* unknown */
+#define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
+
+#define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
+#define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
+#define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
+#define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
+#define AT_COPS_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
+
+#define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
+#define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
+#define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
+
+#define AT_COPS_ACT_GSM 0 /* GSM */
+#define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
+#define AT_COPS_ACT_UTRAN 2 /* UTRAN */
+#define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
+#define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
+#define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
+#define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
+#define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
+
+#define AT_GSM_XBANDSEL_AUTOMATIC 0
+#define AT_GSM_XBANDSEL_1800 1800
+#define AT_GSM_XBANDSEL_1900 1900
+#define AT_GSM_XBANDSEL_900 900
+#define AT_GSM_XBANDSEL_850 850
+#define AT_GSM_XBANDSEL_450 450
+#define AT_GSM_XBANDSEL_480 480
+#define AT_GSM_XBANDSEL_750 750
+#define AT_GSM_XBANDSEL_380 380
+#define AT_GSM_XBANDSEL_410 410
+
+#define AT_XRAT_GSM 0
+#define AT_XRAT_DUAL 1
+#define AT_XRAT_UMTS 2
+
+#define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
+#define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
+
+#define VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS "db/telephony/dualsim/default_data_service"
typedef enum {
IMC_NETWORK_SEARCH_STATE_NO_SEARCH,
ImcNetworkSearchState search_state;
} CustomData;
-typedef struct {
- CoreObject *co;
- TelNetworkResult result;
-} ImcNetworkCancelSearch;
+static unsigned int lookup_tbl_net_status[] = {
+ [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
+ [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
+ [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
+ [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
+ [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
+ [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
+};
-static TelNetworkAct __imc_network_map_act(guint act)
-{
- /*
- * <ACT>
- * 0 GSM
- * 2 UTRAN
- * 3 GSM w/EGPRS
- * 4 UTRAN w/HSDPA
- * 5 UTRAN w/HSUPA
- * 6 UTRAN w/HSDPA and HSUPA
- */
- switch (act) {
- case 0:
- return TEL_NETWORK_ACT_GSM;
- case 2:
- return TEL_NETWORK_ACT_UMTS;
- case 3:
- return TEL_NETWORK_ACT_EGPRS;
- case 4:
- return TEL_NETWORK_ACT_HSDPA;
- case 5:
- return TEL_NETWORK_ACT_HSUPA;
- case 6:
- return TEL_NETWORK_ACT_HSPA;
- default:
- return TEL_NETWORK_ACT_UNKNOWN;
- }
-}
+static unsigned int lookup_tbl_access_technology[] = {
+ [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
+ [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
+ [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
+ [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
+};
-static TelNetworkRegStatus __imc_network_map_stat(guint stat)
-{
- /*
- * <stat>
- * 0 Not registered, ME is not currently searching a
- * new operator to register to
- * 1 Registered, home network
- * 2 Not registered, but ME is currently searching a
- * new operator to register
- * 3 Registration denied
- * 4 Unknown
- * 5 Registered, in roaming
- */
- switch (stat) {
- case 0:
- return TEL_NETWORK_REG_STATUS_UNREGISTERED;
- case 1:
- return TEL_NETWORK_REG_STATUS_REGISTERED;
- case 2:
- return TEL_NETWORK_REG_STATUS_SEARCHING;
- case 3:
- return TEL_NETWORK_REG_STATUS_DENIED;
- case 4:
- return TEL_NETWORK_REG_STATUS_UNKNOWN;
- case 5:
- return TEL_NETWORK_REG_STATUS_ROAMING;
- default:
- return TEL_NETWORK_REG_STATUS_UNKNOWN;
- }
-}
+static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
-static void __on_response_imc_network_registration(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+
+static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- dbg("Entry");
+ dbg("on_confirmation_modem_message_send - msg out from queue.\n");
- if (at_resp && at_resp->success) {
- dbg("Network Registration - [OK]");
+ if (result == FALSE) {
+ /* Fail */
+ dbg("SEND FAIL");
} else {
- err("Network Registration - [NOK]");
+ dbg("SEND OK");
}
}
-static void __imc_network_register_to_network(CoreObject *co)
+static void nwk_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
{
- TelReturn ret;
+ TcoreATRequest *req = NULL;
+ TcoreHal *hal;
+ TcorePending *pending = NULL;
+ TReturn ret;
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- "AT+COPS=0", NULL,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- NULL,
- __on_response_imc_network_registration, NULL,
- on_send_imc_request, NULL);
- dbg("Sending Network Registration request: [%s]",
- (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAIL"));
+ hal = tcore_object_get_hal(co);
+
+ pending = tcore_pending_new(co, 0);
+ req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, callback, req->cmd);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ ret = tcore_hal_send_request(hal, pending);
+
+ if (ret != TCORE_RETURN_SUCCESS)
+ err("Failed to send AT request - ret: [0x%x]", ret);
+
+ return;
}
-static TelNetworkResult
-__imc_network_convert_cme_error_tel_network_result(const TcoreAtResponse *at_resp)
+
+static void _insert_mcc_mnc_oper_list(TcorePlugin *p, CoreObject *o)
{
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
- const gchar *line;
- GSList *tokens = NULL;
+ Server *s;
+ Storage *strg;
+ void *handle;
+ char query[255] = { 0, };
+ GHashTableIter iter;
+ gpointer key, value;
+ GHashTable *result = NULL, *row = NULL;
+ struct tcore_network_operator_info *noi = NULL;
+ int count = 0;
+
+ s = tcore_plugin_ref_server(p);
+ strg = tcore_server_find_storage(s, "database");
+
+ handle = tcore_storage_create_handle(strg, "/opt/dbspace/.mcc_mnc_oper_list.db");
+ if (!handle) {
+ dbg("fail to create database handle");
+ return;
+ }
- dbg("Entry");
+ snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
+
+ result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) g_hash_table_destroy);
+
+ tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
+
+ g_hash_table_iter_init(&iter, result);
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ row = value;
- if (!at_resp || !at_resp->lines) {
- err("Invalid response data");
- return result;
+ noi = calloc(sizeof(struct tcore_network_operator_info), 1);
+
+ snprintf(noi->mcc, 4, "%s", (char *) g_hash_table_lookup(row, "1"));
+ snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
+ snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
+ snprintf(noi->country, 4, "%s", (char *) g_hash_table_lookup(row, "0"));
+
+ tcore_network_operator_info_add(o, noi);
+ g_free(noi);
+ noi = NULL;
+
+ count++;
}
- line = (const gchar *)at_resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) > 0) {
- gchar *resp_str;
- gint cme_err;
+ dbg("count = %d", count);
- resp_str = g_slist_nth_data(tokens, 0);
- if (!resp_str) {
- err("Invalid CME Error data");
- tcore_at_tok_free(tokens);
- return result;
- }
- cme_err = atoi(resp_str);
- dbg("CME error[%d]", cme_err);
+ g_hash_table_destroy(result);
- switch (cme_err) {
- case 3:
- result = TEL_NETWORK_RESULT_OPERATION_NOT_PERMITTED;
- break;
+ tcore_storage_remove_handle(strg, handle);
+}
+
+static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
+ int domain, int act, int cs_status, int ps_status)
+{
+ enum telephony_network_service_type ret;
+
+ ret = prev_type;
- case 4:
- result = TEL_NETWORK_RESULT_OPERATION_NOT_SUPPORTED;
+ switch (act) {
+ case NETWORK_ACT_UNKNOWN:
+ ret = NETWORK_SERVICE_TYPE_UNKNOWN;
break;
- case 20:
- result = TEL_NETWORK_RESULT_MEMORY_FAILURE;
+ case NETWORK_ACT_GSM:
+ if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
+ ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
+ else
+ ret = NETWORK_SERVICE_TYPE_2G;
break;
- case 30:
- case 31:
- result = TEL_NETWORK_RESULT_FAILURE;
+ case NETWORK_ACT_EGPRS:
+ return NETWORK_SERVICE_TYPE_2_5G_EDGE;
break;
- case 50:
- result = TEL_NETWORK_RESULT_INVALID_PARAMETER;
+ case NETWORK_ACT_UMTS:
+ ret = NETWORK_SERVICE_TYPE_3G;
break;
+ }
- default:
- result = TEL_NETWORK_RESULT_FAILURE;
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
+ ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
+ } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
+ /* no change */
+ } else {
+ ret = NETWORK_SERVICE_TYPE_SEARCH;
+ }
+ } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
+ /* no change */
+ } else {
+ ret = NETWORK_SERVICE_TYPE_EMERGENCY;
}
}
- tcore_at_tok_free(tokens);
- return result;
+ return ret;
}
-static void __on_response_imc_network_fetch_nw_name_internal(CoreObject *co,
- gint result, const void *response, void *user_data)
+static void _ps_set(TcorePlugin *p, int status)
{
- TelNetworkIdentityInfo *identity = (TelNetworkIdentityInfo *)response;
+ CoreObject *co_ps;
+
+ co_ps = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PS);
+ if (co_ps == NULL) {
+ err("No PS Core Object on plugin");
+ return;
+ }
- /* Send notification if result is SUCCESS */
- if (result == TEL_NETWORK_RESULT_SUCCESS)
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_IDENTITY,
- sizeof(TelNetworkIdentityInfo), identity);
+ if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
+ tcore_ps_set_online(co_ps, TRUE);
+ else
+ tcore_ps_set_online(co_ps, FALSE);
}
-static TcoreHookReturn __on_response_imc_hook_set_flight_mode(CoreObject *co,
- gint result, TcoreCommand command, const void *response, const void *user_data)
+static void on_timeout_search_network(TcorePending *p, void *user_data)
{
+ UserRequest *ur;
+ struct tresp_network_search resp;
+ CustomData *custom_data;
- tcore_check_return_value(result == TEL_MODEM_RESULT_SUCCESS,
- TCORE_HOOK_RETURN_CONTINUE);
+ dbg("TIMEOUT !!!!! pending=%p", p);
- dbg("Flight mode 'disabled', register to Network");
+ memset(&resp, 0, sizeof(struct tresp_network_search));
- /*
- * TODO - Check for selection_mode
- * Need to check if it is Manual or Automatic and based on
- * that need to initiate Network Registratin accordingly.
- */
- __imc_network_register_to_network(co);
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.list_count = 0;
- return TCORE_HOOK_RETURN_CONTINUE;
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
+ }
}
-static void __on_response_imc_network_fetch_nw_name(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkIdentityInfo identity = {0, };
+ UserRequest *ur;
+ const TcoreATResponse *atResp = data;
+ // GSList *tokens = NULL;
+ // char * line = NULL;
+ struct tresp_network_set_plmn_selection_mode resp = {0};
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- dbg("Enter");
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
+ }
+}
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
+static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_get_plmn_selection_mode resp = {0};
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ char *line = NULL;
+ int mode = 0;
- if (at_resp && at_resp->success) {
- if (at_resp->lines) {
- const gchar *line;
- GSList *tokens = NULL;
- gchar *token_str;
- guint i, nol;
+ resp.result = TCORE_RETURN_FAILURE;
- /* Validate that only 3 lines of response is received */
- nol = g_slist_length(at_resp->lines);
- if (nol > 3) {
- err("Invalid response message");
- imc_destroy_resp_cb_data(resp_cb_data);
- return;
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ /* Format of output
+ +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ */
+
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
}
+ mode = atoi(tcore_at_tok_nth(tokens, 0));
+ dbg("mode = %d", mode);
+
+ switch (mode) {
+ case AT_COPS_MODE_AUTOMATIC:
+ resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
+ break;
+
+ case AT_COPS_MODE_MANUAL:
+ case AT_COPS_MODE_MANUAL_AUTOMATIC:
+ resp.mode = NETWORK_SELECT_MODE_MANUAL;
+ break;
+
+ case AT_COPS_MODE_DEREGISTER:
+ case AT_COPS_MODE_SET_ONLY:
+ resp.result = TCORE_RETURN_FAILURE;
+ goto OUT;
+ }
+ resp.result = TCORE_RETURN_SUCCESS;
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- /* Process the Multi-line response */
- for (i = 0; i < nol; i++) {
- line = g_slist_nth_data(at_resp->lines, i);
+OUT:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
+ }
- /*
- * Tokenize
- *
- * +XCOPS: <type>[,<name>[,<display_condition>]]
- */
- dbg("<line> : [%s]", line);
- tokens = tcore_at_tok_new(line);
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
- if ((token_str = tcore_at_tok_nth(tokens, 0))) {
- guint type = atoi(token_str);
- dbg("<type> : [%d]", type);
+ return;
+}
- switch (type) {
- case 0: /* PLMN (mcc, mnc) */
- if ((token_str = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(token_str) > 0) {
- identity.plmn = tcore_at_tok_extract((const char *)token_str);
+static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_search resp;
+ int i = 0;
+ char *line = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ GSList *network_token = NULL;
+ int AcT = 0;
+ char *temp_plmn_info = NULL;
+ char *alpha_name = NULL;
+ char *pResp = NULL;
+ int num_network_avail = 0;
+ CustomData *custom_data;
- /* Update PLMN */
- tcore_network_set_plmn( co, identity.plmn);
- }
- }
- break;
+ memset(&resp, 0, sizeof(struct tresp_network_search));
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.list_count = 0;
- case 1: /* Short Name in ROM (NV-RAM) */
- case 3: /* Short Network Operator Name (CPHS) */
- case 5: /* Short NITZ Name */
- if ((token_str = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(token_str) > 0) {
- identity.short_name = tcore_at_tok_extract((const char *)token_str);
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ if (!custom_data) {
+ err("Network Search Custom Data is Null");
+ return;
+ }
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
- /* Update Short name */
- tcore_network_set_short_name(co, identity.short_name);
- }
- }
- break;
+ /* If Request is Cancelled then return back SUCCESS/SEARCH_CANCELLED */
+ if (custom_data->search_state
+ == IMC_NETWORK_SEARCH_STATE_CANCELLED) {
+ dbg("Network Search has been Cancelled!!!");
+ goto OUT;
+ }
- case 2: /* Long Name in ROM (NV-RAM) */
- case 4: /* Long Network Operator Name (CPHS) */
- case 6: /* Full NITZ Name */
- if ((token_str = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(token_str) > 0) {
- identity.long_name = tcore_at_tok_extract((const char *)token_str);
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ num_network_avail = g_slist_length(tokens);
+ dbg(" length of tokens is %d\n", num_network_avail);
+ if (num_network_avail < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+ }
- /* Update Long name */
- tcore_network_set_long_name(co, identity.long_name);
- }
- }
- break;
+ resp.result = TCORE_RETURN_SUCCESS;
- default:
- break;
- }
- }
+ /*
+ * +COPS: [list of supported (<stat>,long alphanumeric <oper>,
+ * short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
+ * [,,(list of supported <mode>s),(list of supported <format>s)]
+ */
+ for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
+ network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
- /* Free resource */
- tcore_at_tok_free(tokens);
+ pResp = (tcore_at_tok_nth(network_token, 0));
+ if (pResp != NULL) {
+ dbg("status : %s", pResp);
+ resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
+ }
+
+ if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Alpha name */
+ dbg("Long Alpha name : %s", pResp);
+
+ if (strlen(pResp) > 0)
+ /* Strip off starting quote & ending quote */
+ strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
+ }
+
+ if ((pResp = tcore_at_tok_nth(network_token, 2))) {
+ dbg("Short Aplha name : %s", pResp);
+ /* Short Aplha name */
+ /* Strip off starting quote & ending quote */
+ if (strlen(pResp) > 0)
+ strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
+ }
+
+ /* PLMN ID */
+ pResp = tcore_at_tok_nth(network_token, 3);
+ if (pResp != NULL) {
+ dbg("PLMN ID : %s", pResp);
+ temp_plmn_info = tcore_at_tok_extract((const char *)pResp);
+ strncpy(resp.list[i].plmn, temp_plmn_info, 6);
+ resp.list[i].plmn[6] = '\0';
+ }
+
+ /* Parse Access Technology */
+ if ((pResp = tcore_at_tok_nth(network_token, 4))) {
+ if (strlen(pResp) > 0) {
+ AcT = atoi(pResp);
+
+ if (0 == AcT)
+ resp.list[i].act = NETWORK_ACT_GSM;
+ else if (2 == AcT)
+ resp.list[i].act = NETWORK_ACT_UMTS;
+ }
}
- /* Send Notification - Network identity */
- dbg("Network name - Long name: [%s] Short name: [%s] "
- "PLMN: [%s]", identity.long_name,
- identity.short_name, identity.plmn);
+ 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);
+ resp.list_count++;
- result = TEL_NETWORK_RESULT_SUCCESS;
+ tcore_at_tok_free(network_token);
+ g_free(alpha_name);
+ g_free(temp_plmn_info);
}
+ } else {
+ dbg("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
}
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, &identity, resp_cb_data->cb_data);
+OUT:
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
- /* Free resource */
- tcore_free(identity.long_name);
- tcore_free(identity.short_name);
- tcore_free(identity.plmn);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SEARCH,
+ sizeof(struct tresp_network_search), &resp);
+ }
- /* Free callback data */
- imc_destroy_resp_cb_data(resp_cb_data);
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
}
-/*
- * Operation - fetch_nw_name
- *
- * Request -
- * AT-Command: AT+XCOPS=<Type>
- *
- * <type> may be
- * 0 numeric format of network MCC/MNC (three BCD
- * digit country code and two/three BCD digit network code)
- * 1 Short Name in ROM (NV-RAM)
- * 2 Long Name in ROM (NV-RAM)
- * 3 Short Network Operator Name (CPHS)
- * 4 Long Network Operator Name (CPHS)
- * 5 Short NITZ Name
- * 6 Full NITZ Name
- * 7 Service Provider Name
- * 8 EONS short operator name from EF-PNN
- * 9 EONS long operator name from EF-PNN
- * 11 Short PLMN name (When PS or CS is registered)
- * 12 Long PLMN name (When PS or CS is registered)
- * 13 numeric format of network MCC/MNC even in limited service
- *
- * Response - Network name
- * Success: (Multiple Single line)
- * +XCOPS: <type>[,<name>[,<display_condition>]]
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn __imc_network_fetch_nw_name(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
{
- ImcRespCbData *resp_cb_data = NULL;
- TelReturn ret;
+ const TcoreATResponse *atResp = data;
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ dbg("On Response Set UMTS Band");
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS",
- TCORE_AT_COMMAND_TYPE_MULTILINE,
- NULL,
- __on_response_imc_network_fetch_nw_name, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Fetch Network name");
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ } else {
+ dbg("Response NOK");
+ }
- return ret;
+ dbg("Wait for response of XRAT before sending final band setting response to AP");
+ return;
}
-/* Hook functions */
-static TcoreHookReturn on_hook_imc_set_flight_mode(CoreObject *co,
- TcoreCommand command, const void *request, const void *user_data,
- TcoreObjectResponseCallback cb, const void *cb_data)
-{
- gboolean *flight_mode = (gboolean *)request;
- /*
- * Hook Set Flight mode request.
- *
- * Disable Flight mode - Hook response (if success Register to Network)
- * Enable Flight mode - return
- */
- if (*flight_mode != TRUE) {
- /* Add response hook */
- tcore_object_add_response_hook(co, command, request,
- __on_response_imc_hook_set_flight_mode, NULL);
+static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *atResp = data;
- return TCORE_HOOK_RETURN_CONTINUE;
+ dbg("On Response Set GSM Band");
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ } else {
+ dbg("Response NOK");
}
- dbg("Flight mode - [Enabled]");
- return TCORE_HOOK_RETURN_CONTINUE;
+ dbg("Wait for response of XRAT before sending final band setting response to AP");
+ return;
}
-static TcoreHookReturn on_hook_imc_sim_status(TcorePlugin *plugin,
- TcoreNotification command, guint data_len, void *data, void *user_data)
+static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
{
- const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int total_umts_bands = 0;
+ int i = 0;
+ char *band_token = NULL;
+ char umts_band[20] = {0};
+ char umts_band_1 = 0;
+ char umts_band_2 = 0;
+ char umts_band_5 = 0;
+ UserRequest *ur = NULL;
+ struct tresp_network_get_band resp = {0};
+
+ dbg("Entry on_response_get_umts_band");
+
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
+ resp.result = TCORE_RETURN_SUCCESS;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ total_umts_bands = g_slist_length(tokens);
+ dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
+ if (total_umts_bands < 1) {
+ goto OUT;
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ goto OUT;
+ }
- tcore_check_return_value(sim_status != NULL,
- TCORE_HOOK_RETURN_CONTINUE);
+ for (i = 0; i < total_umts_bands; i++) {
+ band_token = tcore_at_tok_nth(tokens, i);
- /*
- * Hook SIM initialization Notification
- *
- * SIM INIT complete - Attach to network (Register to network)
- * SIM INIT not complete - return
- */
- if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
- CoreObject *co = (CoreObject *)user_data;
- dbg("SIM Initialized!!! Attach to Network");
+ if (band_token == NULL)
+ continue;
- tcore_check_return_value_assert(co != NULL,
- TCORE_HOOK_RETURN_CONTINUE);
+ memset(umts_band, 0x00, sizeof(umts_band));
- /*
- * TODO - Check for selection_mode
- * Need to check if it is Manual or Automatic and based on
- * that need to initiate Network Registratin accordingly.
- */
- __imc_network_register_to_network(co);
+ if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
+ umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
+ break;
+ }
- return TCORE_HOOK_RETURN_CONTINUE;
- }
+ /* Strip off starting quotes & ending quotes */
+ strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
- dbg("SIM not yet initialized - SIM Status: [%d]", *sim_status);
- return TCORE_HOOK_RETURN_CONTINUE;
-}
+ if (!strcmp(umts_band, "UMTS_BAND_I")) {
+ umts_band_1 = TRUE;
+ } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
+ umts_band_2 = TRUE;
+ } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
+ umts_band_5 = TRUE;
+ } else {
+ /* Telephony is not interest */
+ dbg("Telephony is not interested in %s band", umts_band);
+ }
+ }
-/* Notification callbacks */
-/*
- * Notification: +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
- *
- * Possible values of <stat> can be
- * 0 Not registered, ME is not currently searching
- * a new operator to register to
- * 1 Registered, home network
- * 2 Not registered, but ME is currently searching
- * a new operator to register
- * 3 Registration denied
- * 4 Unknown
- * 5 Registered, in roaming
- *
- * <lac>
- * string type; two byte location area code in
- * hexadecimal format (e.g. 00C3)
- *
- * <ci>
- * string type; four byte cell ID in hexadecimal
- * format (e.g. 0000A13F)
- *
- * <ACT>
- * 0 GSM
- * 2 UTRAN
- * 3 GSM w/EGPRS
- * 4 UTRAN w/HSDPA
- * 5 UTRAN w/HSUPA
- * 6 UTRAN w/HSDPA and HSUPA
- */
-static gboolean on_notification_imc_cs_network_info(CoreObject *co,
- const void *event_info, void *user_data)
-{
- GSList *lines = NULL;
- gchar *line = NULL;
+OUT:
+ if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA;
+ } else if (umts_band_1) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA2100;
+ } else if (umts_band_2) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA1900;
+ } else if (umts_band_5) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA850;
+ } else {
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- dbg("Network notification - CS network info: [+CREG]");
+ dbg("Final resp.band sent to TS = %d", resp.band);
- lines = (GSList *)event_info;
- if (g_slist_length(lines) != 1) {
- err("+CREG unsolicited message expected to be Single line "
- "but received multiple lines");
- return TRUE;
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
}
- line = (gchar *) (lines->data);
- if (line != NULL) {
- TelNetworkRegStatusInfo registration_status = {0, };
- TelNetworkCellInfo cell_info = {0, };
- GSList *tokens = NULL;
- gchar *token_str;
- guint stat = 0, act = 0, lac = 0, ci = 0;
- gboolean roam_state = FALSE;
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
- /*
- * Tokenize
- *
- * +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
- */
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- err("Invalid notification message");
- goto out;
- }
+ dbg("Exit on_response_get_umts_band");
+ return;
+}
- /* <stat> */
- if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
- err("No <stat> in +CREG");
- goto out;
+static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ struct tresp_network_get_band resp = {0};
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ int total_gsm_bands = 0;
+ const char *line = NULL;
+ int i = 0;
+ char *band_token = NULL;
+ UserRequest *ur = NULL;
+ int gsm_850 = 0;
+ int gsm_900 = 0;
+ int gsm_1800 = 0;
+ int gsm_1900 = 0;
+
+ dbg("Entry on_response_get_gsm_band");
+
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
+ resp.result = TCORE_RETURN_SUCCESS;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ total_gsm_bands = g_slist_length(tokens);
+ dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
+ if (total_gsm_bands < 1)
+ goto OUT;
}
- stat = __imc_network_map_stat(atoi(token_str));
- (void)tcore_network_set_cs_reg_status(co, stat);
-
- /* <lac> */
- if ((token_str = g_slist_nth_data(tokens, 1))) {
- token_str = tcore_at_tok_extract((const gchar *)token_str);
+ }
- lac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
+ for (i = 0; i < total_gsm_bands; i++) {
+ band_token = tcore_at_tok_nth(tokens, i);
- /* Update Location Area Code (lac) information */
- (void)tcore_network_set_lac(co, lac);
+ if (band_token == NULL)
+ continue;
- tcore_free(token_str);
- } else {
- dbg("No <lac> in +CREG");
- (void)tcore_network_get_lac(co, &lac);
+ if (atoi(band_token) == 0) { /* 0 means GSM automatic */
+ gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
+ break;
}
- /* <ci> */
- if ((token_str = g_slist_nth_data(tokens, 2))) {
- token_str = tcore_at_tok_extract((const gchar *)token_str);
+ switch (atoi(band_token)) {
+ case AT_GSM_XBANDSEL_850:
+ gsm_850 = TRUE;
+ break;
- ci = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
+ case AT_GSM_XBANDSEL_900:
+ gsm_900 = TRUE;
+ break;
- /* Update Cell ID (ci) information */
- (void)tcore_network_set_cell_id(co, ci);
+ case AT_GSM_XBANDSEL_1800:
+ gsm_1800 = TRUE;
+ break;
- tcore_free(token_str);
- } else {
- dbg("No <ci> in +CREG");
- (void)tcore_network_get_cell_id(co, &ci);
- }
+ case AT_GSM_XBANDSEL_1900:
+ gsm_1900 = TRUE;
+ break;
- /* <AcT> */
- if ((token_str = g_slist_nth_data(tokens, 3))) {
- act = __imc_network_map_act(atoi(token_str));
- (void)tcore_network_set_access_technology(co, act);
- } else {
- dbg("No <AcT> in +CREG");
- (void)tcore_network_get_access_technology(co, &act);
- }
- dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d", stat, lac, ci, act);
-
- /* Send Notification - Network (CS) Registration status */
- registration_status.cs_status = stat;
- registration_status.act = act;
- (void)tcore_network_get_ps_reg_status(co, ®istration_status.ps_status);
-
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
- sizeof(TelNetworkRegStatusInfo), ®istration_status);
-
- switch (stat) {
- case TEL_NETWORK_REG_STATUS_ROAMING:
- roam_state = TRUE; // no break
- case TEL_NETWORK_REG_STATUS_REGISTERED:
- /* Fetch Network name - Internal request */
- (void)__imc_network_fetch_nw_name(co,
- __on_response_imc_network_fetch_nw_name_internal, NULL);
- break;
default:
- break;
+ break;
}
+ }
- /* Set Roaming state */
- tcore_network_set_roam_state(co, roam_state);
+OUT:
+
+ if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM;
+ } else if (gsm_850 && gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
+ } else if (gsm_900 && gsm_1800) {
+ resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
+ } else if (gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM1900;
+ } else if (gsm_850) {
+ resp.band = NETWORK_BAND_TYPE_GSM850;
+ } else if (gsm_1800) {
+ resp.band = NETWORK_BAND_TYPE_GSM1800;
+ } else if (gsm_900) {
+ resp.band = NETWORK_BAND_TYPE_GSM900;
+ } else {
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- /* Send Notification - Cell info */
- cell_info.lac = (gint)lac;
- cell_info.cell_id = (gint)ci;
- (void)tcore_network_get_rac(co, &cell_info.rac);
+ dbg("Final resp.band sent to TS = %d", resp.band);
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
- sizeof(TelNetworkCellInfo), &cell_info);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
-out:
- /* Free resource */
+ if (tokens != NULL)
tcore_at_tok_free(tokens);
- }
- return TRUE;
+ dbg("Exit on_response_get_gsm_band");
+ return;
}
-/*
- * Notification: +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
- *
- * Possible values of <stat> can be
- * 0 Not registered, ME is not currently searching a
- * new operator to register to
- * 1 Registered, home network
- * 2 Not registered, but ME is currently searching a
- * new operator to register
- * 3 Registration denied
- * 4 Unknown
- * 5 Registered, in roaming
- *
- * <lac>
- * string type; two byte location area code in
- * hexadecimal format (e.g. 00C3)
- *
- * <ci>
- * string type; four byte cell ID in hexadecimal
- * format (e.g. 0000A13F)
- *
- * <ACT>
- * 0 GSM
- * 2 UTRAN
- * 3 GSM w/EGPRS
- * 4 UTRAN w/HSDPA
- * 5 UTRAN w/HSUPA
- * 6 UTRAN w/HSDPA and HSUPA
- *
- * <rac>:
- * string type; one byte routing area code in hexadecimal format
- */
-static gboolean on_notification_imc_ps_network_info(CoreObject *co,
- const void *event_info, void *user_data)
-{
- GSList *lines = NULL;
- gchar *line = NULL;
- dbg("Network notification - PS network info: [+CGREG]");
+static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcoreHal *h = NULL;
+ UserRequest *ur = NULL;
+
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ UserRequest *dup_ur = NULL;
+ const TcoreATResponse *atResp = data;
+ const char *line = NULL;
+ char *pResp = NULL;
+ GSList *tokens = NULL;
+ TcorePending *pending = NULL;
+ CoreObject *o = NULL;
+ int cp_xrat = 0;
+ struct tresp_network_get_band resp = {0};
- lines = (GSList *)event_info;
- if (g_slist_length(lines) != 1) {
- err("+CGREG unsolicited message expected to be Single line "
- "but received multiple lines");
- return TRUE;
- }
+ dbg("Enter on_response_get_xrat !!");
- line = (gchar *) (lines->data);
- if (line != NULL) {
- TelNetworkRegStatusInfo registration_status = {0, };
- TelNetworkCellInfo cell_info = {0, };
- GSList *tokens = NULL;
- gchar *token_str;
- guint stat = 0, act = 0, lac = 0, ci = 0, rac = 0;
- gboolean roam_state = FALSE;
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
- /*
- * Tokenize
- *
- * +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
- */
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- err("Invalid notification message");
- goto out;
- }
+ ur = tcore_pending_ref_user_request(p);
+ h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
+ o = tcore_pending_ref_core_object(p);
- /* <stat> */
- if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
- err("No <stat> in +CGREG");
- goto out;
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
}
- stat = __imc_network_map_stat(atoi(token_str));
- (void)tcore_network_set_ps_reg_status(co, stat);
- /* <lac> */
- if ((token_str = g_slist_nth_data(tokens, 1))) {
- token_str = tcore_at_tok_extract((const gchar *)token_str);
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ cp_xrat = atoi(pResp);
- lac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
+ if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
+ resp.result = TCORE_RETURN_SUCCESS;
+ resp.band = NETWORK_BAND_TYPE_ANY;
- /* Update Location Area Code (lac) information */
- (void)tcore_network_set_lac(co, lac);
-
- tcore_free(token_str);
- } else {
- dbg("No <lac> in +CGREG");
- (void)tcore_network_get_lac(co, &lac);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+ goto OUT;
+ } else if ((cp_xrat == AT_XRAT_UMTS)) {
+ /* Get UMTS Band Information */
+ dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
+ cmd_str = g_strdup_printf("AT+XUBANDSEL?");
+ atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
+ pending = tcore_pending_new(o, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ } else if ((cp_xrat == AT_XRAT_UMTS)) {
+ /* Get GSM Band Information */
+ dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
+ cmd_str = g_strdup_printf("AT+XBANDSEL?");
+ atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
+ pending = tcore_pending_new(o, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
+ tcore_pending_link_user_request(pending, dup_ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ }
}
+ } else {
+ dbg("RESPONSE NOK");
- /* <ci> */
- if ((token_str = g_slist_nth_data(tokens, 2))) {
- token_str = tcore_at_tok_extract((const gchar *)token_str);
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.band = NETWORK_BAND_TYPE_ANY;
- ci = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+ }
+OUT:
- /* Update Cell ID (ci) information */
- (void)tcore_network_set_cell_id(co, ci);
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
- tcore_free(token_str);
- } else {
- dbg("No <ci> in +CGREG");
- (void)tcore_network_get_cell_id(co, &ci);
- }
+ dbg("Exit on_response_get_xrat !!");
- /* <AcT> */
- if ((token_str = g_slist_nth_data(tokens, 3))) {
- act = __imc_network_map_act(atoi(token_str));
- (void)tcore_network_set_access_technology(co, act);
- } else {
- dbg("No <AcT> in +CGREG");
- (void)tcore_network_get_access_technology(co, &act);
- }
+ return;
+}
- /* <rac> */
- if ((token_str = g_slist_nth_data(tokens, 4))) {
- token_str = tcore_at_tok_extract((const gchar *)token_str);
- rac = (guint)strtol(token_str, NULL, IMC_NETWORK_BASE_16);
+static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_band resp = {0};
+ const TcoreATResponse *atResp = data;
- /* Update Routing Area Code (rac) information */
- (void)tcore_network_set_rac(co, rac);
+ dbg("On Response Set XRAT");
- tcore_free(token_str);
- } else {
- err("No <ci> in +CGREG");
- (void)tcore_network_get_rac(co, &rac);
- }
- dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d <rac>: 0x%x", stat, lac, ci, act, rac);
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("Response NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- /* Send Notification - Network (PS) Registration status */
- registration_status.ps_status = stat;
- registration_status.act = act;
- (void)tcore_network_get_cs_reg_status(co, ®istration_status.cs_status);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
+ }
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
- sizeof(TelNetworkRegStatusInfo), ®istration_status);
+ return;
+}
- /* Set Roaming state */
- if (registration_status.ps_status == TEL_NETWORK_REG_STATUS_ROAMING)
- roam_state = TRUE;
+static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_preferred_plmn resp = {0};
+ const TcoreATResponse *atResp = data;
- tcore_network_set_roam_state(co, roam_state);
+ dbg("ENTER on_response_set_preferred_plmn");
- /* Send Notification - Cell info */
- cell_info.lac = lac;
- cell_info.cell_id = ci;
- cell_info.rac = rac;
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
- sizeof(TelNetworkCellInfo), &cell_info);
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("Response NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
-out:
- /* Free resource */
- tcore_at_tok_free(tokens);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
}
- return TRUE;
+ dbg("Exit on_response_set_preferred_plmn");
+ return;
}
-/*
- * Notification: +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
- *
- * <longname>
- * string type; Network name in long alphanumeric format.
- *
- * <shortname>
- * string type; Network name in short alphanumeric format.
- *
- * <LTZ>
- * Local Time Zone; represented as 1 unit = 15 minutes.
- *
- * <UT>
- * string type value; Universal Time
- * format is "yy/MM/dd,hh:mm:ss",
- * wherein characters indicates year, month, day, hour,
- * minutes, seconds.
- * <DST>
- * Daylight Saving Time; represented in hours.
- */
-static gboolean on_notification_imc_network_time_info(CoreObject *co,
- const void *event_info, void *user_data)
+static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
{
- GSList *lines = NULL;
- gchar *line = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ CoreObject *o = NULL;
+ struct tnoti_network_identity noti;
+ int nol = 0;
+ int count = 0;
+ int net_name_type = 0;
+ char *pResp = NULL;
+ char *net_name = NULL;
+
+ dbg("Entry on_response_get_nitz_name (+XCOPS)");
+ o = tcore_pending_ref_core_object(p);
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
- dbg("Network notification - Time info: [+XNITZINFO]");
+ if (atResp->lines) {
+ nol = g_slist_length(atResp->lines);
+ if (nol > 3) {
+ msg("invalid message");
+ goto OUT;
+ }
- lines = (GSList *)event_info;
- if (g_slist_length(lines) != 1) {
- err("+XNITZINFO unsolicited message expected to be Single line "
- "but received multiple lines");
- return TRUE;
- }
-
- line = (gchar *)lines->data;
- if (line != NULL) {
- GSList *tokens = NULL;
- TelNetworkNitzInfoNoti nitz_info = {0, };
- gchar *fullname, *shortname;
- gchar *ltz, *time;
- gchar tmp_time[8] = {0};
- gchar *dstoff;
+ memset(¬i, 0, sizeof(struct tnoti_network_identity));
- /*
- * Tokenize
- *
- * +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
- */
- tokens = tcore_at_tok_new(line);
+ for (count = 0; count < nol; count++) {
+ // parse each line
+ line = g_slist_nth_data(atResp->lines, count);
+ tokens = tcore_at_tok_new(line);
+ dbg("line %d start---------------", count);
+
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ net_name_type = atoi(pResp);
+ dbg("Net name type : %d", net_name_type);
+
+ switch (net_name_type) {
+ case 0: /* plmn_id (mcc, mnc) */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.plmn, net_name, 6);
+ noti.plmn[6] = '\0';
+ }
+ }
+ break;
+
+ case 5: /* Short NITZ name*/
+ case 3: /* Short Network Name (CPHS) */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.short_name, net_name, 16);
+ noti.short_name[16] = '\0';
+ }
+ }
+ break;
+
+ case 6: /* Full NITZ name */
+ case 4: /* Long Network Name (CPHS) */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.full_name, net_name, 32);
+ noti.full_name[32] = '\0';
+ }
+ }
+ break;
- /* <fullname> */
- if ((fullname = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(fullname) > 0) {
- fullname = tcore_at_tok_extract((const char *)fullname);
+ default:
+ break;
+ }
- /* Update Long name */
- tcore_network_set_long_name(co, fullname);
+ g_free(net_name);
+ net_name = NULL;
+ }
- tcore_free(fullname);
+ tcore_at_tok_free(tokens);
}
- }
- /* <shortname> */
- if ((shortname = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(shortname) > 0) {
- shortname = tcore_at_tok_extract((const char *)shortname);
+ dbg("plmn <%s> short NITZ name<%s> full NITZ name<%s>",
+ noti.plmn, noti.short_name, noti.full_name);
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
+ sizeof(struct tnoti_network_identity), ¬i);
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
- /* Update Short name */
- tcore_network_set_short_name(co, shortname);
+OUT:
+ dbg("Exit on_response_get_nitz_name");
+}
- tcore_free(shortname);
- }
- }
+static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ int i = 0;
+ char *line = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ char *pResp = NULL;
+ int plmn_format = 0;
- /* <LTZ> */
- if ((ltz = g_slist_nth_data(tokens, 2)))
- nitz_info.gmtoff = atoi(ltz) * 15;/* gmtoff in minutes */
+ struct tresp_network_get_preferred_plmn resp = {0};
+ int total_lines = 0;
+ int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
- if ((time = g_slist_nth_data(tokens, 3))
- && (strlen(time) > 18)) {
- /* (time + 1) - Skip past initial quote (") */
- g_strlcpy(tmp_time, time + 1, 2+1);
- nitz_info.year = atoi(tmp_time);
+ dbg("Entry");
- /* skip slash (/) after year param */
- g_strlcpy(tmp_time, time + 4, 2+1);
- nitz_info.month = atoi(tmp_time);
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ total_lines = g_slist_length(atResp->lines);
+ dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
- /* skip past slash (/) after month param */
- g_strlcpy(tmp_time, time + 7, 2+1);
- nitz_info.day = atoi(tmp_time);
+ if (total_lines < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
- /* skip past comma (,) after day param */
- g_strlcpy(tmp_time, time + 10, 2+1);
- nitz_info.hour = atoi(tmp_time);
+ if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
+ total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
- /* skip past colon (:) after hour param */
- g_strlcpy(tmp_time, time + 13, 2+1);
- nitz_info.minute = atoi(tmp_time);
+/*
++CPOL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
++CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
+*/
+ resp.result = TCORE_RETURN_SUCCESS;
+
+ for (i = 0; i < total_lines; i++) {
+ /* Take each line response at a time & parse it */
+ line = tcore_at_tok_nth(atResp->lines, i);
+ tokens = tcore_at_tok_new(line);
- /* skip past colon (:) after minute param */
- g_strlcpy(tmp_time, time + 16, 2+1);
- nitz_info.second = atoi(tmp_time);
- }
+ /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
- /* <DST> */
- if ((dstoff = g_slist_nth_data(tokens, 4))) {
- nitz_info.dstoff = atoi(dstoff);
- nitz_info.isdst = TRUE;
- }
+ /* EF Index */
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ dbg("Index : %s", pResp);
+ resp.list[i].ef_index = atoi(pResp);
+ }
+ /* Format */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ dbg("format : %s", pResp);
+ plmn_format = atoi(pResp);
+ }
- /* Get PLMN */
- tcore_network_get_plmn(co, &nitz_info.plmn);
+ /* Operator PLMN ID */
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("plmn ID : %s", pResp);
- /* Send Notification - Network time info */
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_TIMEINFO,
- sizeof(TelNetworkNitzInfoNoti), &nitz_info);
+ if (strlen(pResp) > 0) {
+ char *oper;
- /* Free resource */
- tcore_free(nitz_info.plmn);
- tcore_at_tok_free(tokens);
- }
+ oper = tcore_at_tok_extract((const char *)pResp);
+ dbg("operator <%s>", oper);
- return TRUE;
-}
+ // Get only PLMN ID
+ if (plmn_format == 2) {
+ strncpy(resp.list[i].plmn, oper, 6);
+ resp.list[i].plmn[6] = '\0';
+ }
-/*
- * Notification:
- * +XCIEV: <rssi>,
- * or
- * +XCIEV:,<battery_level>
- *
- * 'Radio Signal Strength' <rssi> can have the values
- * 0 -107 dBm or less or unknown
- * 1 -99 dBm or less
- * 2 -91 dBm or less
- * 3 -83 dBm or less
- * 4 -75 dBm or less
- * 5 -67 dBm or less
- * 6 -59 dBm or less
- * 7 -51 dBm or less
- *
- * 'Battery Level' <battery_level> can have the values
- * 0 0 % <= level < 5 %
- * 1 5 % <= level < 15 %
- * 2 15 % <= level < 25 %
- * 3 25 % <= level < 40 %
- * 4 40 % <= level < 55 %
- * 5 55 % <= level < 70 %
- * 6 70 % <= level < 85 %
- * 7 85 % <= level <= 100 %
- *
- * NOTE:
- * <battery_level> is not consider for
- * TCORE_NOTIFICATION_NETWORK_RSSI notification
- */
-static gboolean on_notification_imc_network_rssi(CoreObject *co,
- const void *event_info, void *user_data)
-{
- GSList *lines = NULL;
- gchar *line = NULL;
+ g_free (oper);
+ }
+ }
- dbg("Network notification - Icon (rssi) info: [+XCIEV]");
+ if ((pResp = tcore_at_tok_nth(tokens, 3))) {
+ dbg("GSM_AcT2 : %s", pResp);
+ GSM_AcT2 = atoi(pResp);
+ }
- lines = (GSList *)event_info;
- if (g_slist_length(lines) != 1) {
- err("+XCIEV unsolicited message expected to be Single line "
- "but received multiple lines");
- return TRUE;
- }
+ if ((pResp = tcore_at_tok_nth(tokens, 4))) {
+ dbg("GSM_Compact AcT2 : %s", pResp);
+ GSM_Compact_AcT2 = atoi(pResp);
+ }
- line = (gchar *)lines->data;
- if (line != NULL) {
- GSList *tokens = NULL;
- gchar *rssi_token;
+ if ((pResp = tcore_at_tok_nth(tokens, 5))) {
+ dbg("UTRAN_AcT2 : %s", pResp);
+ UTRAN_AcT2 = atoi(pResp);
+ }
- /*
- * Tokenize
- *
- * +XCIEV: <rssi>,
- */
- tokens = tcore_at_tok_new(line);
+ if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
+ resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
+ else if (UTRAN_AcT2)
+ resp.list[i].act = NETWORK_ACT_UMTS;
+ else if (GSM_AcT2 || GSM_Compact_AcT2)
+ resp.list[i].act = NETWORK_ACT_GPRS;
- rssi_token = (gchar *)g_slist_nth_data(tokens, 0);
- if (rssi_token && strlen(rssi_token)) {
- guint rssi_bar = atoi(rssi_token);
- dbg("RSSI Level: [%d]", rssi_bar);
+ (resp.list_count)++;
- /* Send Notification - Network Rssi */
- tcore_object_send_notification(co,
- TCORE_NOTIFICATION_NETWORK_RSSI,
- sizeof(guint), &rssi_bar);
+ tcore_at_tok_free(tokens);
+ }
}
-
- /* Free resource */
- tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOT OK");
+ // TODO: CMEE error mapping is required.
+ resp.result = TCORE_RETURN_FAILURE;
}
- return TRUE;
+OUT:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
+ }
+ dbg("Exit");
+ return;
}
-/* Network Responses */
-
-static void on_response_imc_network_search(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- CustomData *custom_data;
-
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
- TelNetworkPlmnList plmn_list = {0, };
- guint num_network_avail = 0;
- guint count;
+ const TcoreATResponse *resp = data;
+ UserRequest *ur;
+ struct tresp_network_get_serving_network Tresp = {0};
+ char *long_plmn_name = NULL;
+ char *short_plmn_name = NULL;
+ char *plmn_id = NULL;
+ CoreObject *o;
GSList *tokens = NULL;
-
- dbg("Enter");
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
-
- custom_data = tcore_object_ref_user_data(co);
- tcore_check_return_assert(custom_data != NULL);
-
- if (at_resp && at_resp->success) {
- const gchar *line;
- GSList *net_token = NULL;
- gchar *resp;
- gint act;
-
- /* If Request is Cancelled then return back SUCCESS/SEARCH_CANCELLED */
- if (custom_data->search_state
- == IMC_NETWORK_SEARCH_STATE_CANCELLED) {
- dbg("Network Search has been Cancelled!!!");
-
- /*
- * TODO:
- *
- * Need to introduce new Result -
- * TEL_NETWORK_RESULT_SEARCH_ABORTED/CANCELLED
- *
- * Presently sending TEL_NETWORK_RESULT_FAILURE
- */
- result = TEL_NETWORK_RESULT_FAILURE;
-
- goto END;
+ const char *line;
+ int network_mode = -1;
+ int plmn_format = -1;
+ int AcT = -1;
+ struct tnoti_network_identity noti;
+ char *pResp = NULL;
+ int nol, count = 0;
+
+ o = tcore_pending_ref_core_object(p);
+
+ if (resp->success <= 0) {
+ dbg("RESPONSE NOK");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ Tresp.result = TCORE_RETURN_FAILURE;
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
}
- if (!at_resp->lines) {
- err("invalid response received");
- goto END;
- }
-
- line = (char *) at_resp->lines->data;
- tokens = tcore_at_tok_new(line);
- num_network_avail = g_slist_length(tokens);
- if (num_network_avail < 1) {
- err("invalid message");
- goto END;
- }
-
- plmn_list.network_list = tcore_malloc0(sizeof(TelNetworkInfo) * num_network_avail);
+ return;
+ } else {
dbg("RESPONSE OK");
- plmn_list.count = 0;
- for (count = 0; count < num_network_avail; count++) {
+ nol = g_slist_length(resp->lines);
+ dbg("nol : %d", nol);
- net_token = tcore_at_tok_new(g_slist_nth_data(tokens, count));
- if (NULL == net_token)
- continue;
-
- resp = tcore_at_tok_nth(net_token, 0);
- if (resp != NULL) {
- plmn_list.network_list[count].plmn_status = atoi(resp);
- dbg("status[%d]", plmn_list.network_list[count].plmn_status);
+ for (count = 0; count < nol; count++) {
+ // parse each line
+ line = g_slist_nth_data(resp->lines, count);
+ tokens = tcore_at_tok_new(line);
+ dbg("line %d start---------------", count);
+ // mode
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ dbg("mode : %s", pResp);
+ network_mode = atoi(pResp);
}
- if ((resp = tcore_at_tok_nth(net_token, 1))) {
- /* Long Alpha name */
- dbg("long alpha name[%s]", resp);
- plmn_list.network_list[count].network_identity.long_name =
- tcore_at_tok_extract(resp);
+ // format (optional)
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ dbg("format : %s", pResp);
+ if (strlen(pResp) > 0)
+ plmn_format = atoi(pResp);
}
- if ((resp = tcore_at_tok_nth(net_token, 2))) {
- /* Short Alpha name */
- dbg("Short Alpha name[%s]", resp);
- plmn_list.network_list[count].network_identity.short_name =
- tcore_at_tok_extract(resp);
- }
+ // plmn
+ switch (plmn_format) {
+ case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("long PLMN : %s", pResp);
+ if (strlen(pResp) > 0) {
+ long_plmn_name = tcore_at_tok_extract((const char *)pResp);
- /* PLMN ID */
- if ((resp = tcore_at_tok_nth(net_token, 3))) {
- dbg("PLMN ID[%s]", resp);
- plmn_list.network_list[count].network_identity.plmn =
- tcore_at_tok_extract(resp);
- }
+ // set network name into po
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
+ }
+ }
+ break;
- /* Parse Access Technology */
- if ((resp = tcore_at_tok_nth(tokens, 4))) {
- act = atoi(resp);
- if (0 == act)
- plmn_list.network_list[count].act = TEL_NETWORK_ACT_GSM;
- else if (2 == act)
- plmn_list.network_list[count].act = TEL_NETWORK_ACT_UMTS;
+ case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("short PLMN : %s", pResp);
+ if (strlen(pResp) > 0) {
+ short_plmn_name = tcore_at_tok_extract((const char *)pResp);
+
+ // set network name into po
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
+ }
}
+ break;
- dbg("Operator [%d] :: status = %d, long_name = %s, short_name = %s plmn = %s, AcT=%d",
- plmn_list.count,
- plmn_list.network_list[count].plmn_status,
- plmn_list.network_list[count].network_identity.long_name,
- plmn_list.network_list[count].network_identity.short_name,
- plmn_list.network_list[count].network_identity.plmn,
- plmn_list.network_list[count].act);
+ case AT_COPS_FORMAT_NUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("numeric : %s", pResp);
+ if (strlen(pResp) > 0) {
+ plmn_id = tcore_at_tok_extract((const char *)pResp);
- plmn_list.count ++;
- tcore_at_tok_free(net_token);
- }
- result = TEL_NETWORK_RESULT_SUCCESS;
- } else {
- err("RESPONSE NOK");
- result = __imc_network_convert_cme_error_tel_network_result(at_resp);
- }
+ // set plmn id into po
+ tcore_network_set_plmn(o, plmn_id);
+ }
+ }
+ break;
-END:
- dbg("Network search : [%s]",
- (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ default:
+ break;
+ }
- /* Update Search state */
- custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+ // act
+ if ((pResp = tcore_at_tok_nth(tokens, 3))) {
+ dbg("AcT : %s", pResp);
+ if (strlen(pResp) > 0) {
+ AcT = atoi(pResp);
+ tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
+ }
+ }
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data);
+ tcore_at_tok_free(tokens);
+ }
- imc_destroy_resp_cb_data(resp_cb_data);
+ if(plmn_id)
+ memcpy(Tresp.plmn, plmn_id, strlen(plmn_id));
+ tcore_network_get_access_technology(o, &(Tresp.act));
+ tcore_network_get_lac(o, &(Tresp.gsm.lac));
- /* Free resources*/
- for (count = 0; count < num_network_avail; count++) {
- g_free(plmn_list.network_list[count].network_identity.long_name);
- g_free(plmn_list.network_list[count].network_identity.short_name);
- g_free(plmn_list.network_list[count].network_identity.plmn);
- }
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ Tresp.result = TCORE_RETURN_SUCCESS;
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
+ } else {
+ /* Network change noti */
+ struct tnoti_network_change network_change;
+
+ memset(&network_change, 0, sizeof(struct tnoti_network_change));
+ if(plmn_id)
+ memcpy(network_change.plmn, plmn_id, strlen(plmn_id));
+ tcore_network_get_access_technology(o, &(network_change.act));
+ tcore_network_get_lac(o, &(network_change.gsm.lac));
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
+ TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
+ dbg("dbg.. network_change.plmn : %s", network_change.plmn);
+ dbg("dbg.. network_change.act : %d", network_change.act);
+ dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
+
+ if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
+ (AT_COPS_MODE_SET_ONLY != network_mode)) {
+ /*Network identity noti*/
+ memset(¬i, 0x0, sizeof(struct tnoti_network_identity));
+ if (long_plmn_name)
+ memcpy(noti.full_name, long_plmn_name, MIN(32, strlen(long_plmn_name)));
+ if (short_plmn_name)
+ memcpy(noti.short_name, short_plmn_name, MIN(16, strlen(short_plmn_name)));
+ if (plmn_id)
+ memcpy(noti.plmn, plmn_id, strlen(plmn_id)); // plmn_id length is necessarily <= 6
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
+ dbg("dbg.. noti.short_name : %s", noti.short_name);
+ dbg("dbg.. noti.full_name : %s", noti.full_name);
+ dbg("dbg.. noti.plmn : %s", noti.plmn);
+ }
+ }
- tcore_free(plmn_list.network_list);
- tcore_at_tok_free(tokens);
+ g_free(long_plmn_name);
+ g_free(short_plmn_name);
+ g_free(plmn_id);
+ }
+ return;
}
-static gboolean on_response_imc_network_cancel_search(gpointer data)
+static void on_response_network_set_mode(TcorePending *p, int data_len, const void *data, void *user_data)
{
- ImcRespCbData *resp_cb_data = data;
- ImcNetworkCancelSearch *cancel_search =
- (ImcNetworkCancelSearch *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ UserRequest *ur = NULL;
+ struct tresp_network_set_mode resp = {0};
+ const TcoreATResponse *atResp = data;
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(cancel_search->co, (gint)cancel_search->result,
- NULL, resp_cb_data->cb_data);
+ dbg("ENTER on_response_network_set_mode");
- imc_destroy_resp_cb_data(resp_cb_data);
+ if (atResp && atResp->success) {
+ dbg("RESPONSE OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
- /* To stop the cycle, need to return FALSE */
- return FALSE;
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SET_MODE,
+ sizeof(struct tresp_network_set_mode), &resp);
+ }
}
-static void on_response_imc_network_get_selection_mode(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static void on_response_network_get_mode(TcorePending *p, int data_len, const void *data, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkSelectionMode selection_mode = -1;
+ UserRequest *ur = NULL;
+ struct tresp_network_get_mode resp = {0};
+ const TcoreATResponse *atResp = data;
GSList *tokens = NULL;
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
- dbg("Enter");
+ dbg("ENTER on_response_network_get_mode");
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
+ resp.result = TCORE_RETURN_FAILURE;
- if (at_resp && at_resp->success) {
+ if (atResp && atResp->success) {
const gchar *line;
- gint mode;
+ gint net_mode;
- if (!at_resp->lines) {
+ if (!atResp->lines) {
err("invalid response received");
goto END;
}
- line = (char *) at_resp->lines->data;
+ line = (char *) atResp->lines->data;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
- msg("invalid message");
+ err("invalid message");
goto END;
}
+
dbg("RESPONSE OK");
- mode = atoi(tcore_at_tok_nth(tokens, 0));
- if (mode == 0)
- selection_mode = TEL_NETWORK_SELECTION_MODE_AUTOMATIC;
- else if (mode == 1)
- selection_mode = TEL_NETWORK_SELECTION_MODE_MANUAL;
+ net_mode = atoi(tcore_at_tok_nth(tokens, 0));
+ dbg("mode = %d", net_mode);
- result = TEL_NETWORK_RESULT_SUCCESS;
- dbg("selection mode[%d]", selection_mode);
+ switch (net_mode) {
+ case 0:
+ resp.mode = NETWORK_MODE_GSM;
+ break;
+ case 1:
+ resp.mode = NETWORK_MODE_AUTO;
+ break;
+ case 2:
+ resp.mode = NETWORK_MODE_WCDMA;
+ break;
+ default:
+ err("Unsupported mode [%d]", net_mode);
+ goto END;
+ }
+ resp.result = TCORE_RETURN_SUCCESS;
} else {
err("RESPONSE NOK");
- result = __imc_network_convert_cme_error_tel_network_result(at_resp);
}
END:
- dbg("Get selection mode : [%s]",
- (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, &selection_mode, resp_cb_data->cb_data);
-
- /* Free callback data */
- imc_destroy_resp_cb_data(resp_cb_data);
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_GET_MODE,
+ sizeof(struct tresp_network_get_mode), &resp);
+ }
+
/* Free resource*/
tcore_at_tok_free(tokens);
}
-static void on_response_imc_network_default(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static void on_response_cancel_manual_search(TcorePending *p, int data_len, const void *data, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
+ UserRequest *ur = NULL;
+ struct tresp_network_set_cancel_manual_search resp = {0};
+ const TcoreATResponse *atResp = data;
+ CustomData *custom_data;
- dbg("Enter");
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
+ dbg("ENTER on_response_cancel_manual_search");
- if (at_resp && at_resp->success) {
- dbg("RESPONSE OK");
- result = TEL_NETWORK_RESULT_SUCCESS;
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
} else {
- err("RESPONSE NOK");
- result = __imc_network_convert_cme_error_tel_network_result(at_resp);
+ dbg("Response NOK");
+ resp.result = TCORE_RETURN_FAILURE;
}
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
- imc_destroy_resp_cb_data(resp_cb_data);
-}
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
+ sizeof(struct tresp_network_set_cancel_manual_search), &resp);
+ }
+ dbg("Exit on_response_cancel_manual_search");
+}
-static void on_response_imc_network_get_mode(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
- TelNetworkMode mode = -1;
+ struct tnoti_network_registration_status regist_status;
+ enum telephony_network_service_domain_status cs_status;
+ enum telephony_network_service_domain_status ps_status;
+ enum telephony_network_service_type service_type;
+ enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
+ struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
+ struct tnoti_ps_protocol_status noti = {0};
+ unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
+ int stat = 0, AcT = 0;
+ unsigned int lac = 0xffff, ci = 0xffff;
+ unsigned int rac = 0xffff;
GSList *tokens = NULL;
+ char *pResp;
+ char *line = NULL;
+ GSList *lines = NULL;
- dbg("Enter");
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+ dbg("+CGREG NOTI RECEIVED");
- if (at_resp && at_resp->success) {
- const gchar *line;
- gint net_mode;
+/*
++CREG: <stat> [[,<lac>,<ci>[AcT]]
+
+Possible values of <stat> can be
+0 Not registered, ME is not currently searching a new operator to register to
+1 Registered, home network
+2 Not registered, but ME is currently searching a new operator to register
+3 Registration denied
+4 Unknown
+5 Registered, in roaming
+
+<lac>
+string type; two byte location area code in hexadecimal format (e.g. 00C3)
+
+<ci>
+string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
+
+<ACT>
+0 GSM
+2 UTRAN
+3 GSM w/EGPRS
+4 UTRAN w/HSDPA
+5 UTRAN w/HSUPA
+6 UTRAN w/HSDPA and HSUPA
+Note: <Act> is supporting from R7 and above Protocol Stack.
+
+<rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
+*/
+ if (line != NULL) {
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
- if (!at_resp->lines) {
- err("invalid response received");
- goto END;
+ if (!(pResp = g_slist_nth_data(tokens, 0))) {
+ dbg("No STAT in +CGREG");
+ goto OUT;
+ } else {
+ stat = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1))) {
+ pResp = util_removeQuotes(pResp);
+ lac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+
+ if ((pResp = g_slist_nth_data(tokens, 2))) {
+ pResp = util_removeQuotes(pResp);
+ ci = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ } else {
+ dbg("No ci in +CGREG");
+ }
+
+ if ((pResp = g_slist_nth_data(tokens, 3)))
+ AcT = atoi(pResp);
+ else
+ dbg("No AcT in +CGREG");
+
+ if ((pResp = g_slist_nth_data(tokens, 4))) {
+ pResp = util_removeQuotes(pResp);
+ rac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ } else {
+ dbg("No rac in +CGREG");
+ }
+ }
+
+
+ dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
+
+ ps_status = lookup_tbl_net_status[stat];
+
+ tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
+ _ps_set(tcore_object_ref_plugin(o), ps_status);
+
+ tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
+
+ act = lookup_tbl_access_technology[AcT];
+ tcore_network_set_access_technology(o, act);
+
+ tcore_network_get_service_type(o, &service_type);
+ dbg("prev_service_type = 0x%x", service_type);
+ service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
+ dbg("new_service_type = 0x%x", service_type);
+ tcore_network_set_service_type(o, service_type);
+
+ tcore_network_set_lac(o, lac);
+ tcore_network_set_cell_id(o, ci);
+ tcore_network_set_rac(o, rac);
+
+ net_lac_cell_info.lac = lac;
+ net_lac_cell_info.cell_id = ci;
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
+ sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
+
+ regist_status.cs_domain_status = cs_status;
+ regist_status.ps_domain_status = ps_status;
+ regist_status.service_type = service_type;
+ regist_status.roaming_status = tcore_network_get_roaming_state(o);
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
+ TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(regist_status), ®ist_status);
+#if 0
+ if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
+ noti.status = TELEPHONY_HSDPA_ON;
+ else
+ noti.status = TELEPHONY_HSDPA_OFF;
+#else
+ switch(AcT){
+ case AT_COPS_ACT_GSM:/*Fall Through*/
+ case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
+ case AT_COPS_ACT_UTRAN:/*Fall Through*/
+ case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
+ case AT_COPS_ACT_E_UTRAN:
+ {
+ dbg("Not required for Protocol Status Notification");
+ goto OUT;
+ }
+ case AT_COPS_ACT_UTRAN_HSDPA:
+ {
+ dbg("HSDPA");
+ noti.status = TELEPHONY_HSDPA_ON;
+ break;
+ }
+ case AT_COPS_ACT_UTRAN_HSUPA:
+ {
+ dbg("HSUPA");
+ noti.status = TELEPHONY_HSUPA_ON;
+ break;
+ }
+ case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
+ {
+ dbg("HSPA");
+ noti.status = TELEPHONY_HSPA_ON;
+ break;
+ }
+ default:
+ {
+ dbg("Ignore");
+ goto OUT;
+ }
}
+#endif
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
+ sizeof(struct tnoti_ps_protocol_status), ¬i);
+
+ /* Get PLMN ID needed to application */
+ // get_serving_network(o, NULL);
+ } else {
+ dbg("Response NOK");
+ }
+
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ char *line = NULL;
+ struct tnoti_network_registration_status regist_status;
+ enum telephony_network_service_domain_status cs_status;
+ enum telephony_network_service_domain_status ps_status;
+ enum telephony_network_service_type service_type;
+ enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
+ struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
+
+
+ unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
+ int stat = 0, AcT = 0;
+ unsigned int lac = 0xffff, ci = 0xffff;
+ GSList *tokens = NULL;
+ char *pResp;
- line = (char *) at_resp->lines->data;
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+
+ dbg("+CREG NOTI RECEIVED");
+
+/*
++CREG: <stat> [[,<lac>,<ci>[AcT]]
+
+Possible values of <stat> can be
+0 Not registered, ME is not currently searching a new operator to register to
+1 Registered, home network
+2 Not registered, but ME is currently searching a new operator to register
+3 Registration denied
+4 Unknown
+5 Registered, in roaming
+
+<lac>
+string type; two byte location area code in hexadecimal format (e.g. 00C3)
+
+<ci>
+string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
+
+<ACT>
+0 GSM
+2 UTRAN
+3 GSM w/EGPRS
+4 UTRAN w/HSDPA
+5 UTRAN w/HSUPA
+6 UTRAN w/HSDPA and HSUPA
+Note: <Act> is supporting from R7 and above Protocol Stack.
+*/
+ if (line != NULL) {
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
- err("invalid message");
- goto END;
+ msg("invalid message");
+ goto OUT;
}
- dbg("RESPONSE OK");
- net_mode = atoi(tcore_at_tok_nth(tokens, 0));
- dbg("mode = %d", net_mode);
+ if (!(pResp = g_slist_nth_data(tokens, 0))) {
+ dbg("No STAT in +CREG");
+ goto OUT;
+ } else {
+ stat = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1))) {
+ pResp = util_removeQuotes(pResp);
+ lac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
- switch (net_mode) {
- case 0:
- mode = TEL_NETWORK_MODE_2G;
- break;
- case 1:
- mode = TEL_NETWORK_MODE_AUTO;
- break;
- case 2:
- mode = TEL_NETWORK_MODE_3G;
- break;
- default:
- err("Unsupported mode [%d]", net_mode);
- goto END;
+ if ((pResp = g_slist_nth_data(tokens, 2))) {
+ pResp = util_removeQuotes(pResp);
+ ci = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ } else {
+ dbg("No ci in +CREG");
+ }
+
+ if ((pResp = g_slist_nth_data(tokens, 3)))
+ AcT = atoi(pResp);
+ else
+ dbg("No AcT in +CREG");
}
- result = TEL_NETWORK_RESULT_SUCCESS;
+
+
+ dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
+
+ cs_status = lookup_tbl_net_status[stat];
+ tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
+
+ // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
+ tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
+
+ act = lookup_tbl_access_technology[AcT];
+ tcore_network_set_access_technology(o, act);
+
+ if (stat == AT_CREG_STAT_REG_ROAM) {
+ tcore_network_set_roaming_state(o, TRUE);
+ }else if ((stat == AT_CREG_STAT_REG_DENIED) && (TRUE == tcore_network_get_roaming_state(o))) {
+ dbg("Ignore roaming set with REG_DENIED when previous state is REG_ROAM");
+ }else {
+ tcore_network_set_roaming_state(o, FALSE);
+ }
+
+ tcore_network_get_service_type(o, &service_type);
+ dbg("prev_service_type = 0x%x", service_type);
+ service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
+ dbg("new_service_type = 0x%x", service_type);
+ tcore_network_set_service_type(o, service_type);
+
+ tcore_network_set_lac(o, lac);
+ tcore_network_set_cell_id(o, ci);
+
+ net_lac_cell_info.lac = lac;
+ net_lac_cell_info.cell_id = ci;
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
+ sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
+
+ regist_status.cs_domain_status = cs_status;
+ regist_status.ps_domain_status = ps_status;
+ regist_status.service_type = service_type;
+ regist_status.roaming_status = tcore_network_get_roaming_state(o);
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
+ TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
+
+ /* Get PLMN ID needed to application */
+ if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
+ NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
+ get_serving_network(o, NULL);
} else {
- err("RESPONSE NOK");
- result = __imc_network_convert_cme_error_tel_network_result(at_resp);
+ dbg("Response NOK");
}
-END:
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, &mode, resp_cb_data->cb_data);
- /* Free callback data */
- imc_destroy_resp_cb_data(resp_cb_data);
- /* Free resource*/
- tcore_at_tok_free(tokens);
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+ return TRUE;
}
-static void on_response_imc_network_get_preferred_plmn(TcorePending *p,
- guint data_len, const void *data, void *user_data)
+static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
{
- const TcoreAtResponse *at_resp = data;
- CoreObject *co = tcore_pending_ref_core_object(p);
- ImcRespCbData *resp_cb_data = user_data;
- TelNetworkPreferredPlmnList plmn_list = {0,};
- guint count = 0, total_lines = 0;
- TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
- dbg("Enter");
+ struct tnoti_network_icon_info net_icon_info = {0};
+ char *line = NULL;
+ char *rssiToken = NULL;
+ char *batteryToken = NULL;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
- tcore_check_return_assert(co != NULL);
- tcore_check_return_assert(resp_cb_data != NULL);
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+ dbg("+XCIEV Network Icon Info Noti Recieve");
+ memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
- if (at_resp && at_resp->success) {
- GSList *tokens;
- gchar *resp;
- gchar *line;
- gboolean gsm_act2 = FALSE, gsm_compact_act2 = FALSE;
- gboolean utran_act2 = FALSE;
+ if (line != NULL) {
+ dbg("Response OK");
- if (!at_resp->lines) {
- err("invalid response received");
- goto END;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ msg("invalid message");
+ goto OUT;
}
- total_lines = g_slist_length(at_resp->lines);
- if (total_lines < 1) {
- msg("invalid message");
- goto END;
+ rssiToken = (char *) g_slist_nth_data(tokens, 0);
+
+ if (strlen(rssiToken) > 0) {
+ net_icon_info.type = NETWORK_ICON_INFO_RSSI;
+ net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
+ dbg("rssi level : %d", net_icon_info.rssi);
}
- dbg("RESPONSE OK");
- result = TEL_NETWORK_RESULT_SUCCESS;
+ batteryToken = (char *) g_slist_nth_data(tokens, 1);
+ if (strlen(batteryToken) > 0) {
+ net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
+ net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
+ dbg("battery level : %d", net_icon_info.battery);
+ }
- plmn_list.list = tcore_malloc0(sizeof(TelNetworkPreferredPlmnInfo) * total_lines);
- plmn_list.count = 0;
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
+ sizeof(struct tnoti_network_icon_info), &net_icon_info);
+ } else {
+ dbg("Response NOK");
+ }
- for (count = 0; count < total_lines; count++) {
- /* Take each line response at a time & parse it */
- line = tcore_at_tok_nth(at_resp->lines, count);
- tokens = tcore_at_tok_new(line);
- /*Index */
- if ((resp = tcore_at_tok_nth(tokens, 0))) {
- plmn_list.list[count].index = atoi(resp);
- }
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
- /* PLMN ID */
- if ((resp = tcore_at_tok_nth(tokens, 2))) {
- plmn_list.list[count].plmn = tcore_at_tok_extract(resp);
- }
+ return TRUE;
+}
- /*GSM_AcT1 */
- if ((resp = tcore_at_tok_nth(tokens, 3))) {
- gsm_act2 = atoi(resp);
- }
+static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
+{
+ struct tnoti_network_timeinfo net_time_info = {0};
+ char *line = NULL;
+ GSList *tokens = NULL;
+ char *time = NULL;
+ char *time_zone = NULL;
+ GSList *lines = NULL;
+ char ptime_param[20] = {0};
+ UserRequest *ur = NULL;
+ dbg("Enter : on_event_network_ctzv_time_info");
+
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
- /*GSM_Compact_AcT2 */
- if ((resp = tcore_at_tok_nth(tokens, 4))) {
- gsm_compact_act2 = atoi(resp);
- }
+/*
++CTZV: <tz>,<time>
+<tz> integer value indicating the time zone (e.g. -22 or +34)
+<time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
+minutes, seconds.*/
- /*UTRAN_AcT2 */
- if ((resp = tcore_at_tok_nth(tokens, 5))) {
- utran_act2 = atoi(resp);
- }
+ dbg("Network time info (+CTZV) recieved");
- if (gsm_act2)
- plmn_list.list[count].act = TEL_NETWORK_ACT_UMTS;
- else if (utran_act2 || gsm_compact_act2)
- plmn_list.list[count].act = TEL_NETWORK_ACT_GSM;
+ if (line != NULL) {
+ gchar *plmn_str = NULL;
+ dbg("Response OK");
+ dbg("noti line is %s", line);
- /* free tokens*/
- tcore_at_tok_free(tokens);
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 2) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ if ((time_zone = g_slist_nth_data(tokens, 0))) {
+ net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
+ }
+
+ plmn_str = tcore_network_get_plmn(o);
+ if (plmn_str != NULL) {
+ g_strlcpy(net_time_info.plmn, plmn_str, sizeof(net_time_info.plmn));
+ g_free(plmn_str);
+ }
+
+ if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
+ strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
+ net_time_info.year = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
+ net_time_info.month = atoi(ptime_param);
- dbg("index[%d], plmn[%s], act[%d]",
- plmn_list.list[count].index,
- plmn_list.list[count].plmn,
- plmn_list.list[count].act);
+ strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
+ net_time_info.day = atoi(ptime_param);
+ strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
+ net_time_info.hour = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
+ net_time_info.minute = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
+ net_time_info.second = atoi(ptime_param);
}
- plmn_list.count = count;
+ 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);
+
+ dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
+
+ /* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
+ nwk_prepare_and_send_pending_request(o, "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
} else {
- err("RESPONSE NOK");
- result = __imc_network_convert_cme_error_tel_network_result(at_resp);
+ dbg("line is NULL");
}
-END:
- dbg("get preferred plmn : [%s]",
- (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
- /* Invoke callback */
- if (resp_cb_data->cb)
- resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data);
+ dbg("Exit: on_event_network_ctzv_time_info");
+ return TRUE;
+}
- /* Free callback data */
- imc_destroy_resp_cb_data(resp_cb_data);
+static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
+ const void *data, void *user_data)
+{
+ const struct tresp_sim_read *resp = data;
+ CoreObject *o = user_data;
+
+ if (command == TRESP_SIM_GET_SPN) {
+ dbg("OK SPN GETTING!!");
+ dbg("resp->result = 0x%x", resp->result);
+ dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
+ dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
+
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *) resp->data.spn.spn);
+
+ /**
+ * display condition
+ * 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
+ * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
+ * 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
+ * 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
+ */
+ if (resp->data.spn.display_condition & 0x01) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
+ }
+ if ((resp->data.spn.display_condition & 0x02) == 0) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
+ }
+ if ((resp->data.spn.display_condition & 0x03) == 0x01) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
+ }
- for(count = 0; count < total_lines; count++) {
- g_free(plmn_list.list[count].plmn);
+ // fallback in case no SPN name is provided
+ if (resp->data.spn.spn[0] == '\0')
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
}
- tcore_free(plmn_list.list);
}
-
-/* Network Operations */
-/*
- * Operation - set_power_status
- *
- * Request -
- * AT-Command: AT+XCOPS=<Type>
- *
- * <type> may be
- * 0 numeric format of network MCC/MNC (three BCD
- * digit country code and two/three BCD digit network code)
- * 1 Short Name in ROM (NV-RAM)
- * 2 Long Name in ROM (NV-RAM)
- * 3 Short Network Operator Name (CPHS)
- * 4 Long Network Operator Name (CPHS)
- * 5 Short NITZ Name
- * 6 Full NITZ Name
- * 7 Service Provider Name
- * 8 EONS short operator name from EF-PNN
- * 9 EONS long operator name from EF-PNN
- * 11 Short PLMN name (When PS or CS is registered)
- * 12 Long PLMN name (When PS or CS is registered)
- * 13 numeric format of network MCC/MNC even in limited service
- *
- * Response - Network name
- * Success: (Multiple Single line)
- * +XCOPS: <type>[,<name>[,<display_condition>]]
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_network_get_identity_info(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
{
- return __imc_network_fetch_nw_name(co, cb, cb_data);
-}
+ const struct tnoti_sim_status *sim = data;
+ UserRequest *ur = NULL;
+
+ if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
+ ur = tcore_user_request_new(NULL, NULL);
+ tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
+ tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
+ tcore_object_dispatch_request(source, ur);
+ }
-/*
- * Operation - network search
- * Request -
- * AT-Command: AT+COPS=?
- *
- * Response -
- * Success: (Single line)
- * +COPS: [list of supported (<stat>,long alphanumeric <oper>
- * ,short alphanumeric <oper>,numeric <oper>[,< AcT>]
- * [,,(list of supported <mode>s),(list of supported <format>s)]
-
- * <format>
- * describes the format in which operator name is to be displayed. Different values of <format> can be:
- * 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays
- * combination of Mcc and MNC in string format.
- * 1 <oper> format presentation is set to short alphanumeric.
- * 2 <oper> format presentations set to numeric.
- * <oper>:
- * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
- * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
- * <stat>:
- * describes the status of the network. It is one of the response parameter for test command.
- * 0 Unknown Networks
- * 1 Network Available
- * 2 Current
- * 3 Forbidden Network
- * <AcT>
- * indicates the radio access technology and values can be:
- * 0 GSM
- * 2 UMTS
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
-static TelReturn imc_network_search(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn search_network(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
CustomData *custom_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ char *cmd_str = NULL;
+
+ dbg("search_network - ENTER!!");
- custom_data = tcore_object_ref_user_data(co);
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ custom_data = tcore_object_ref_user_data(o);
if (custom_data->search_state
== IMC_NETWORK_SEARCH_STATE_IN_PROGRESS) {
warn("Network Search: [ALREADY IN PROGRESS]");
- return TEL_RETURN_FAILURE;
+ return TCORE_RETURN_FAILURE;
}
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
-
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request_ex(co,
- "AT+COPS=?", "+COPS",
- TCORE_AT_COMMAND_TYPE_SINGLELINE,
- TCORE_PENDING_PRIORITY_DEFAULT,
- NULL,
- on_response_imc_network_search, resp_cb_data,
- on_send_imc_request, NULL,
- 0, NULL, NULL,
- FALSE, TRUE);
- if (ret != TEL_RETURN_SUCCESS) {
- err("Failed to process request - [%s]", "Network Search");
- imc_destroy_resp_cb_data(resp_cb_data);
- }
- else {
- custom_data->search_state = IMC_NETWORK_SEARCH_STATE_IN_PROGRESS;
- dbg("Search State: [IN PROGRESS]");
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
}
- return ret;
+ pending = tcore_pending_new(o, 0);
+
+ cmd_str = g_strdup_printf("AT+COPS=?");
+ atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_timeout(pending, 60);
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
+ tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_IN_PROGRESS;
+ dbg("Search State: [IN PROGRESS]");
+
+ return TCORE_RETURN_SUCCESS;
}
-static TelReturn imc_network_cancel_search(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
{
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
- ImcRespCbData *resp_cb_data;
- CustomData *custom_data;
- ImcNetworkCancelSearch cancel_search = {0, };
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ int format = 0; /* default value for long alphanumeric */
+ int mode = 0;
+ char plmn[7] = {0};
+ int act = 0;
- custom_data = tcore_object_ref_user_data(co);
- if (custom_data->search_state
- == IMC_NETWORK_SEARCH_STATE_IN_PROGRESS) {
- dbg("Search in Progress...");
+ const struct treq_network_set_plmn_selection_mode *req_data = NULL;
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request_ex(co,
- "\e", NULL,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- TCORE_PENDING_PRIORITY_IMMEDIATELY,
- NULL,
- NULL, NULL,
- on_send_imc_request, NULL,
- 0, NULL, NULL,
- TRUE, FALSE);
- if (ret != TEL_RETURN_SUCCESS) {
- err("Failed to process request - [%s]", "Cancel network search");
- goto out;
- }
- else {
- custom_data->search_state = IMC_NETWORK_SEARCH_STATE_CANCELLED;
- dbg("Search State: [CANCELLED]");
+
+ dbg("set_plmn_selection_mode - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ pending = tcore_pending_new(o, 0);
+
+ // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
+ /* oper parameter format
+ - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
+ - 1 <oper> format presentation is set to short alphanumeric.
+ - 2 <oper> format presentations set to numeric.
+ */
+
+ if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
+ act = 0;
+ else
+ act = 2;
+
+ switch (req_data->mode) {
+ case NETWORK_SELECT_MODE_MANUAL:
+ {
+ mode = AT_COPS_MODE_MANUAL;
+ format = AT_COPS_FORMAT_NUMERIC;
+
+ memset(plmn, 0, 7);
+ memcpy(plmn, req_data->plmn, 6);
+
+ if (strlen(req_data->plmn) == 6) {
+ if (plmn[5] == '#')
+ plmn[5] = 0;
}
+
+ cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
}
- else {
- dbg("No Search in Progress...");
- ret = TEL_RETURN_SUCCESS;
+ break;
+
+ case NETWORK_SELECT_MODE_AUTOMATIC:
+ default:
+ cmd_str = g_strdup("AT+COPS=0");
+ break;
}
- cancel_search.co = co;
- cancel_search.result = TEL_NETWORK_RESULT_SUCCESS;
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
- &cancel_search, sizeof(ImcNetworkCancelSearch));
+ atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
- /* Send response */
- g_idle_add(on_response_imc_network_cancel_search, (gpointer)resp_cb_data);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-out:
- return ret;
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
}
-/*
- * Operation - automatic network selection
- * Request -
- * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
- * where
- * <mode>
- * is used to select, whether the selection is done automatically by the ME or is forced by this command to
- * operator <oper> given in the format <format>.
- * The values of <mode> can be:
- * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
- * 1 Manual. Other parameters like format and operator need to be passed
- * 2 Deregister from network
- * 3 It sets <format> value. In this case <format> becomes a mandatory input
- * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
- *
- * Response -
- * Success:(No result)
- * OK or
- * +CME ERROR: <err>
- */
-static TelReturn imc_network_select_automatic(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
- dbg("entry");
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ dbg("get_plmn_selection_mode - ENTER!!");
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- "AT+COPS=0", NULL,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- NULL,
- on_response_imc_network_default, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Automatic network selection");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
- return ret;
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ pending = tcore_pending_new(o, 0);
+
+ cmd_str = g_strdup_printf("AT+COPS?");
+ atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
}
-/*
- * Operation - manual network selection
- * Request -
- * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
- * where
- * <mode>
- * is used to select, whether the selection is done automatically by the ME or is forced by this command to
- * operator <oper> given in the format <format>.
- * The values of <mode> can be:
- * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
- * 1 Manual. Other parameters like format and operator need to be passed
- * 2 Deregister from network
- * 3 It sets <format> value. In this case <format> becomes a mandatory input
- * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered.
- * <oper>
- * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
- * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
- * <AcT>
- * indicates the radio access technology and values can be:
- * 0 GSM
- * 2 UMTS
- *
- * Response -
- * Success:(No result)
- * OK or
- * +CME ERROR: <err>
- */
-static TelReturn imc_network_select_manual(CoreObject *co,
- const TelNetworkSelectManualInfo *sel_manual,
- TcoreObjectResponseCallback cb, void *cb_data)
+
+static TReturn set_band(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
- gchar *at_cmd;
- gint act;
- dbg("entry");
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcorePending *pending_gsm = NULL;
+ TcorePending *pending_umts = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ const struct treq_network_set_band *req_data;
+ gboolean set_gsm_band = 0;
+ gboolean set_umts_band = 0;
+ int gsm_band = 255;
+ int gsm_band2 = 255;
+ char *umts_band = NULL;
+ UserRequest *dup_ur_gsm = NULL;
+ UserRequest *dup_ur_umts = NULL;
+
+ dbg("set_band - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- switch (sel_manual->act) {
- case TEL_NETWORK_ACT_GSM:
- case TEL_NETWORK_ACT_GPRS:
- case TEL_NETWORK_ACT_EGPRS:
- act = 0;
+ dbg("set_band - called with band = %d", req_data->band);
+
+ switch (req_data->band) {
+ case NETWORK_BAND_TYPE_GSM850:
+ gsm_band = AT_GSM_XBANDSEL_850;
+ set_gsm_band = TRUE;
break;
- case TEL_NETWORK_ACT_UMTS:
- case TEL_NETWORK_ACT_GSM_AND_UMTS:
- case TEL_NETWORK_ACT_HSDPA:
- case TEL_NETWORK_ACT_HSPA:
- act = 2;
+
+ case NETWORK_BAND_TYPE_GSM_900_1800:
+ gsm_band = AT_GSM_XBANDSEL_900;
+ gsm_band2 = AT_GSM_XBANDSEL_1800;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM1900:
+ gsm_band = AT_GSM_XBANDSEL_1900;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM1800:
+ gsm_band = AT_GSM_XBANDSEL_1800;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM_850_1900:
+ gsm_band = AT_GSM_XBANDSEL_850;
+ gsm_band2 = AT_GSM_XBANDSEL_1900;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_ANY:
+ gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
+ set_umts_band = TRUE;
+ set_gsm_band = TRUE;
break;
+
+ case NETWORK_BAND_TYPE_WCDMA:
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA2100:
+ umts_band = "UMTS_BAND_I";
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA1900:
+ umts_band = "UMTS_BAND_II";
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA850:
+ umts_band = "UMTS_BAND_V";
+ set_umts_band = TRUE;
+ break;
+
default:
- err("unsupported AcT");
- return ret;
+ break;
}
- /* AT-Command */
- at_cmd = g_strdup_printf("AT+COPS=1,2,\"%s\",%d", sel_manual->plmn, act);
+ dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ if (set_umts_band == TRUE) {
+ if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
+ cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
+ else
+ cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- at_cmd, NULL,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- NULL,
- on_response_imc_network_default, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Manual network selection");
+ atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
+ pending_umts = tcore_pending_new(o, 0);
- /* Free resources*/
- g_free(at_cmd);
- return ret;
-}
+ tcore_pending_set_request_data(pending_umts, 0, atreq);
+ tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
+ /* duplicate user request for UMTS Band setting AT command for same UR */
+ dup_ur_umts = tcore_user_request_ref(ur);
+ tcore_pending_link_user_request(pending_umts, dup_ur_umts);
+ tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending_umts);
+ g_free(cmd_str);
+ }
+
+ if (set_gsm_band == TRUE) {
+ dbg("Entered set_gsm_band");
+ if (gsm_band2 == 255)
+ cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
+ else
+ cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
+
+ dbg("Command string: %s", cmd_str);
+ atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
+ pending_gsm = tcore_pending_new(o, 0);
+
+ tcore_pending_set_request_data(pending_gsm, 0, atreq);
+ tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
+
+ /* duplicate user request for GSM Band setting AT command for same UR */
+ dup_ur_gsm = tcore_user_request_ref(ur);
+ tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
+ tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending_gsm);
+ g_free(cmd_str);
+ }
+
+ /* Lock device to specific RAT as requested by application */
/*
- * Operation - get network selection mode
- * Request -
- * AT-Command: AT+COPS?
- *
- * Response -
- * Success: (Single line)
- * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
- * <mode>
- * is used to select, whether the selection is done automatically by the ME or is forced by this command to
- * operator <oper> given in the format <format>.
- * The values of <mode> can be:
- * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
- * 1 Manual. Other parameters like format and operator need to be passed
- * 2 Deregister from network
- * 3 It sets <format> value. In this case <format> becomes a mandatory input
- * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_network_get_selection_mode(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+AT+XRAT=<Act>[,<PreferredAct>]
+<AcT> indicates the radio access technology and may be
+0 GSM single mode
+1 GSM / UMTS Dual mode
+2 UTRAN (UMTS)
+*/
+ if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
+ } else if (set_umts_band == TRUE) {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
+ } else {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
+ }
+ atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
+ pending = tcore_pending_new(o, 0);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending, on_response_set_xrat, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_band(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ dbg("get_band - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
+ cmd_str = g_strdup_printf("AT+XRAT?");
+ atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
+ pending = tcore_pending_new(o, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_xrat, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+ tcore_hal_send_request(h, pending);
+
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+}
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- "AT+COPS?", "+COPS",
- TCORE_AT_COMMAND_TYPE_SINGLELINE,
- NULL,
- on_response_imc_network_get_selection_mode, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get selection mode");
+static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
+ struct treq_network_set_preferred_plmn *req_data = NULL;
+ char *cmd_str = NULL;
+ int format = 2; /* Alway use numeric format, as application gives data in this default format */
+ int gsm_act = 0;
+ int gsm_compact_act = 0;
+ int utran_act = 0;
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- return ret;
-}
+ req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
+ pending = tcore_pending_new(o, 0);
+ dbg("Entry set_preferred_plmn");
/*
- * Operation - set preferred plmn
- * Request -
- * AT-Command: AT+CPOL=<index>][,<format>[,<oper>[,<GSM_AcT>,<GSM_Compact_AcT>,<UTRAN_AcT>]]]
- * where
- * <indexn> integer type; the order number of operator in the SIM/USIM preferred operator list
- * <format>
- * 0 long format alphanumeric <oper>
- * 1 short format alphanumeric <oper>
- * 2 numeric <oper>
- * <opern> string type; <format> indicates if the format is alphanumeric or numeric (see +COPS)
- * <GSM_AcTn>: GSM access technology
- * 0 access technology not selected
- * 1 access technology selected
- * <GSM_Compact_AcTn>: GSM compact access technology
- * 0 access technology not selected
- * 1 access technology selected
- * <UTRA_AcTn>: UTRA access technology
- * 0 access technology not selected
- * 1 access technology selected
- *
- * Response -
- * Success:(No Result)
- * OK
- * Failure:
- * +CME ERROR: <error>
+AT+CPOL=
+[<index>][,<format>[,<oper>[,<GSM_AcT>,
+<GSM_Compact_AcT>,<UTRAN_AcT>]]]
*/
-static TelReturn imc_network_set_preferred_plmn(CoreObject *co,
- const TelNetworkPreferredPlmnInfo *pref_plmn,
- TcoreObjectResponseCallback cb, void *cb_data)
-{
- ImcRespCbData *resp_cb_data;
- gchar *at_cmd;
- gboolean gsm_act = FALSE;
- gboolean gsm_compact_act = FALSE;
- gboolean utran_act = FALSE;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
- dbg("entry");
-
- switch (pref_plmn->act) {
- case TEL_NETWORK_ACT_GSM:
- case TEL_NETWORK_ACT_GPRS:
- case TEL_NETWORK_ACT_EGPRS:
+
+ if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
gsm_act = TRUE;
- break;
- case TEL_NETWORK_ACT_UMTS:
- case TEL_NETWORK_ACT_HSDPA:
- case TEL_NETWORK_ACT_HSPA:
+ else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
utran_act = TRUE;
- break;
- case TEL_NETWORK_ACT_GSM_AND_UMTS:
+ else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
gsm_act = utran_act = TRUE;
- break;
- default:
- warn("unsupported AcT");
+
+ if (strlen(req_data->plmn) > 6) {
+ req_data->plmn[6] = '\0';
+ } else if (strlen(req_data->plmn) == 6) {
+ if (req_data->plmn[5] == '#') {
+ req_data->plmn[5] = '\0';
+ }
}
+ 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);
- /* AT-Command */
- at_cmd = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d",
- pref_plmn->index, 2, pref_plmn->plmn, gsm_act, gsm_compact_act, utran_act);
+ dbg("cmd_str - %s", cmd_str);
+ atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- at_cmd, NULL,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- NULL,
- on_response_imc_network_default, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set preferred plmn");
+ tcore_hal_send_request(h, pending);
- g_free(at_cmd);
- return ret;
+ g_free(cmd_str);
+
+ dbg("Exit set_preferred_plmn");
+
+ return TCORE_RETURN_SUCCESS;
}
-/*
- * Operation - get preferred plmn
- * Request -
- * AT-Command: AT+CPOL?
- * Response -
- * Success: (multiline)
- * +CPOL: <index1>,<format>,<oper1>
- * [,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>][<CR><LF>
- * +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>] [\85]]
- * OK
- * Failure
- * +CME ERROR: <err>
- */
-static TelReturn imc_network_get_preferred_plmn(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
- dbg("entry");
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ char *cmd_str = NULL;
- /* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- "AT+CPOL=,2;+CPOL?", "+CPOL", //to make sure <oper> is numeric type in reponse.
- TCORE_AT_COMMAND_TYPE_MULTILINE,
- NULL,
- on_response_imc_network_get_preferred_plmn, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get preferred plmn");
+ dbg("get_preferred_plmn - ENTER!!");
- return ret;
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ pending = tcore_pending_new(o, 0);
+
+ cmd_str = g_strdup_printf("AT+CPOL=,2;+CPOL?");
+ atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending);
+
+ g_free(cmd_str);
+
+ dbg("get_preferred_plmn - EXIT!!");
+
+ return TCORE_RETURN_SUCCESS;
}
-/*
- * Operation - set network mode
- * Request -
- * AT-Command: AT+XRAT=<AcT> [, <PreferredAct>]
- * where
- * <AcT> indicates the radio access technology and may be
- * 0 GSM single mode
- * 1 GSM / UMTS Dual mode
- * 2 UTRAN (UMTS)
- * 3-7 Reserved for future use.
- * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
- * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
- * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
- * <PreferredAct>
- * This parameter is used for network registration in case of <AcT>=1.
- * 0 RAT GSM
- * 2 RAT UMTS
- * Response -
- * Success: (No result)
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_network_set_mode(CoreObject *co, TelNetworkMode mode,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn cancel_manual_search (CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
+ CustomData *custom_data;
+
+ dbg("cancel_manual_search - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ h = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(h)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ custom_data = tcore_object_ref_user_data(o);
+ if (custom_data->search_state
+ == IMC_NETWORK_SEARCH_STATE_IN_PROGRESS) {
+ dbg("Search in Progress...");
+
+ pending = tcore_pending_new(o, 0);
+ atreq = tcore_at_request_new("\e", NULL, TCORE_AT_NO_RESULT);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_cancel_manual_search, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ /*Set the Search State to Cancelled*/
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_CANCELLED;
+ dbg("Search State: [CANCELLED]");
+ } else {
+ dbg("No Search in Progress...");
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
+{
+ dbg("get_serving_network - ENTER!!");
+
+ if (!o)
+ return TCORE_RETURN_EINVAL;
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ dbg("new pending(AT+COPS?)");
+
+ nwk_prepare_and_send_pending_request(o, "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn network_set_mode(CoreObject *o, UserRequest *ur)
+{
+ struct treq_network_set_mode *set_mode = NULL;
+ TReturn ret = TCORE_RETURN_EINVAL;
int act;
gchar *at_cmd;
- switch (mode) {
- case TEL_NETWORK_MODE_AUTO:
+ dbg("network_set_mode - ENTER!!");
+
+ set_mode = (struct treq_network_set_mode *)tcore_user_request_ref_data(ur, NULL);
+
+ switch (set_mode->mode) {
+ case NETWORK_MODE_AUTO:
act = 1;
- break;
- case TEL_NETWORK_MODE_2G:
+ break;
+ case NETWORK_MODE_GSM:
act = 0;
- break;
- case TEL_NETWORK_MODE_3G:
+ break;
+ case NETWORK_MODE_WCDMA:
act = 2;
- break;
- case TEL_NETWORK_MODE_LTE:
+ break;
+ case NETWORK_MODE_LTE:
default:
- err("Unsupported mode");
+ err("Unsupported mode: [%d]", set_mode->mode);
return ret;
}
/* AT-Command */
at_cmd = g_strdup_printf("AT+XRAT=%d", act);
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
-
/* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
- at_cmd, NULL ,
- TCORE_AT_COMMAND_TYPE_NO_RESULT,
- NULL,
- on_response_imc_network_default, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set network mode");
+ ret = tcore_prepare_and_send_at_request(o,
+ at_cmd, NULL,
+ TCORE_AT_NO_RESULT,
+ ur,
+ on_response_network_set_mode, NULL,
+ on_confirmation_network_message_send, NULL,
+ 0, NULL, NULL);
g_free(at_cmd);
return ret;
}
-/*
- * Operation - get network mode
- * Request -
- * AT-Command: AT+XRAT?
- *
- * Response -
- * Success: (Single line)
- * +XRAT : <Act>,<PreferredAct>
- * <AcT> indicates the radio access technology and may be
- * 0 GSM single mode
- * 1 GSM / UMTS Dual mode
- * 2 UTRAN (UMTS)
- * 3-7 Reserved for future use.
- * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
- * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
- * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
- * <PreferredAct>
- * This parameter is used for network registration in case of <AcT>=1.
- * 0 RAT GSM
- * 2 RAT UMTS
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-
-static TelReturn imc_network_get_mode(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn network_get_mode(CoreObject *o, UserRequest *ur)
{
- ImcRespCbData *resp_cb_data;
- TelReturn ret;
- dbg("entry");
+ TReturn ret;
- /* Response callback data */
- resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ dbg("network_get_mode - ENTER!!");
/* Send Request to modem */
- ret = tcore_at_prepare_and_send_request(co,
+ ret = tcore_prepare_and_send_at_request(o,
"AT+XRAT?", "+XRAT",
- TCORE_AT_COMMAND_TYPE_SINGLELINE,
- NULL,
- on_response_imc_network_get_mode, resp_cb_data,
- on_send_imc_request, NULL);
- IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get network mode");
+ TCORE_AT_SINGLELINE,
+ ur,
+ on_response_network_get_mode, NULL,
+ on_confirmation_network_message_send, NULL,
+ 0, NULL, NULL);
return ret;
}
-static TelReturn imc_network_get_neighboring_cell_info(CoreObject *co,
- TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn set_default_subscription(CoreObject *co, UserRequest *ur)
{
- /* TODO*/
- dbg("entry");
- return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ struct treq_network_set_default_subscription *req_data = NULL;
+ Server *server;
+ Storage *strg = NULL;
+ TReturn ret = TCORE_RETURN_FAILURE;
+ TcorePlugin *plugin = tcore_object_ref_plugin(co);
+
+ dbg("Enter");
+
+ server = tcore_plugin_ref_server(plugin);
+ strg = tcore_server_find_storage(server, "vconf");
+
+ req_data = (struct treq_network_set_default_subscription *) tcore_user_request_ref_data(ur, NULL);
+ dbg("'default' Subscription for CS (Voice): [%d]", req_data->default_subs);
+
+ /* Update VCONF through Storage - req_data->current_network is aligned to VCONFKEY values */
+ if (tcore_storage_set_int(strg,
+ STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_SERVICE_INT, req_data->default_subs)) {
+ struct tresp_network_set_default_subs resp_data = {0, };
+ struct tnoti_network_default_subs default_subs_noti_data = {0, };
+
+ /*
+ * Send Response
+ */
+ resp_data.result = TCORE_RETURN_SUCCESS;
+ ret = tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SET_DEFAULT_SUBSCRIPTION,
+ sizeof(struct tresp_network_set_default_subs), &resp_data);
+ /*
+ * Send Notification
+ */
+ default_subs_noti_data.default_subs = req_data->default_subs;
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin), co,
+ TNOTI_NETWORK_DEFAULT_SUBSCRIPTION,
+ sizeof(struct tnoti_network_default_subs), &default_subs_noti_data);
+ }
+
+ dbg("ret: [0x%x]", ret);
+ return ret;
}
-/* Network Operations */
-static TcoreNetworkOps imc_network_ops = {
- .get_identity_info = imc_network_get_identity_info,
- .search = imc_network_search,
- .cancel_search = imc_network_cancel_search,
- .select_automatic = imc_network_select_automatic,
- .select_manual = imc_network_select_manual,
- .get_selection_mode = imc_network_get_selection_mode,
- .set_preferred_plmn = imc_network_set_preferred_plmn,
- .get_preferred_plmn = imc_network_get_preferred_plmn,
- .set_mode = imc_network_set_mode,
- .get_mode = imc_network_get_mode,
- .get_neighboring_cell_info = imc_network_get_neighboring_cell_info
+static TReturn get_default_subscription(CoreObject *co, UserRequest *ur)
+{
+ struct tresp_network_get_default_subs resp_data = {0, };
+ TReturn ret = TCORE_RETURN_FAILURE;
+ Server *server;
+ Storage *strg = NULL;
+ TcorePlugin *plugin = tcore_object_ref_plugin(co);
+
+ dbg("Enter");
+
+ server = tcore_plugin_ref_server(plugin);
+ strg = tcore_server_find_storage(server, "vconf");
+
+ /* VCONFKEY is aligned to req_data->current_network type */
+ resp_data.default_subs = tcore_storage_get_int(strg,
+ STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_SERVICE_INT);
+
+ resp_data.result = TCORE_RETURN_SUCCESS;
+
+ /* Send Response */
+ ret = tcore_user_request_send_response(ur,
+ TRESP_NETWORK_GET_DEFAULT_SUBSCRIPTION,
+ sizeof(struct tresp_network_get_default_subs), &resp_data);
+
+ dbg("ret: [0x%x]", ret);
+ return ret;
+}
+
+static TReturn get_default_data_subscription(CoreObject *co, UserRequest *ur)
+{
+ struct tresp_network_get_default_data_subs resp = {0,};
+ int ret;
+ int subscription = -1;
+
+ dbg("Enter");
+
+ ret = vconf_get_int(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS , &subscription);
+ if (ret < 0) {
+ err("vconf_get_int() failed - DDS");
+ resp.result = TCORE_RETURN_FAILURE;
+ } else {
+ resp.result = TCORE_RETURN_SUCCESS;
+ resp.default_subs = subscription;
+ if (subscription == NETWORK_DEFAULT_DATA_SUBS_UNKNOWN)
+ resp.default_subs = NETWORK_DEFAULT_DATA_SUBS_UNKNOWN;
+ }
+
+ if( TCORE_RETURN_SUCCESS == tcore_user_request_send_response(ur,
+ TRESP_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION,
+ sizeof(struct tresp_network_get_default_data_subs), &resp)){
+ tcore_user_request_unref(ur);
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_network_operations network_ops = {
+ .search = search_network,
+ .set_plmn_selection_mode = set_plmn_selection_mode,
+ .get_plmn_selection_mode = get_plmn_selection_mode,
+ .set_service_domain = NULL,
+ .get_service_domain = NULL,
+ .set_band = set_band,
+ .get_band = get_band,
+ .set_preferred_plmn = set_preferred_plmn,
+ .get_preferred_plmn = get_preferred_plmn,
+ .set_order = NULL,
+ .get_order = NULL,
+ .set_power_on_attach = NULL,
+ .get_power_on_attach = NULL,
+ .set_cancel_manual_search = cancel_manual_search,
+ .get_serving_network = get_serving_network,
+ .set_mode = network_set_mode,
+ .get_mode = network_get_mode,
+ .set_default_subscription = set_default_subscription,
+ .get_default_subscription = get_default_subscription,
+ .set_default_data_subscription = NULL,
+ .get_default_data_subscription =get_default_data_subscription,
};
-gboolean imc_network_init(TcorePlugin *p, CoreObject *co)
+gboolean imc_network_init(TcorePlugin *cp, CoreObject *co_network)
{
CustomData *custom_data;
dbg("Enter");
/* Set operations */
- tcore_network_set_ops(co, &imc_network_ops);
+ tcore_network_set_ops(co_network, &network_ops);
/* Custom data */
- custom_data = tcore_malloc0(sizeof(CustomData));
+ custom_data = g_malloc0(sizeof(CustomData));
custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
- /* Link Custom data */
- tcore_object_link_user_data(co, custom_data);
+ tcore_object_link_user_data(co_network, custom_data);
+
+ tcore_object_add_callback(co_network, "+CREG", on_event_cs_network_regist, NULL);
+ tcore_object_add_callback(co_network, "+CGREG", on_event_ps_network_regist, NULL);
+ tcore_object_add_callback(co_network, "+XCIEV", on_event_network_icon_info, NULL);
- /* Add Callbacks */
- tcore_object_add_callback(co, "+CREG", on_notification_imc_cs_network_info, NULL);
- tcore_object_add_callback(co, "+CGREG", on_notification_imc_ps_network_info, NULL);
- tcore_object_add_callback(co, "+XNITZINFO", on_notification_imc_network_time_info, NULL);
- tcore_object_add_callback(co, "+XCIEV", on_notification_imc_network_rssi, NULL);
+ /* +CTZV: <tz>,<time> */
+ tcore_object_add_callback(co_network, "+CTZV", on_event_network_ctzv_time_info, NULL);
- /*
- * Add Hooks - Request and Notification
- */
- tcore_plugin_add_request_hook(p,
- TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
- on_hook_imc_set_flight_mode, NULL);
- tcore_plugin_add_notification_hook(p,
- TCORE_NOTIFICATION_SIM_STATUS,
- on_hook_imc_sim_status, co);
+ tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co_network);
- //_insert_mcc_mnc_oper_list(cp, co_network);
+ _insert_mcc_mnc_oper_list(cp, co_network);
dbg("Exit");
+
return TRUE;
}
-void imc_network_exit(TcorePlugin *p, CoreObject *co)
+void imc_network_exit(TcorePlugin *cp, CoreObject *co_network)
{
CustomData *custom_data;
- custom_data = tcore_object_ref_user_data(co);
+ custom_data = tcore_object_ref_user_data(co_network);
if (custom_data != NULL)
- tcore_free(custom_data);
+ g_free(custom_data);
dbg("Exit");
}