blob: 7824fe8448e13628029e9918cea3f83fc31ee8b6 [file] [log] [blame]
#include <stdbool.h>
#include <dlfcn.h>
#include <time.h>
#include <pthread.h>
#include "gsw_nw_interface.h"
#include "gsw_log_interface.h"
#define SIG_TIMER 5
#define MODEM_TIMER 5
#define SERVING_TIMER 5
//mbtk include
#define LYNQ_AIR_PLANE_MODE_OFF 1 //at+cfun = 1
#define LYNQ_AIR_PLANE_MODE_ON 4 // at+cfun = 4
#define LYNQ_AIR_CFUN_MODE_OFF 0 // at+cfun = 0
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define FPLMN_STRING_LENGTH 120
#define ENTRY_LENGTH 6
#define FPLMN_ARRAY_SIZE (FPLMN_STRING_LENGTH / 6) + 1
#define MBTK_ERR_OK 0
#define GSW_IMEI_LENGTH 15+1
#define INT_32_MAX (0x7FFFFFFF)
#define INVALID_AT_SIGNAL_LEVEL (99)
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef void (*mbtk_info_callback_func)(const void* data, int data_len);
//#define MBTK_READY_UCI "persist.mbtk.sdk.state"
#define SDK_READY_CMD "uci get lynq_uci.sdk_ready"
#define MBTK_READY_STRING_SIZE_MAX (3+1)
typedef enum{
MBTK_READY_INIT = -1,
MBTK_READY_SUCCESS,
MBTK_READY_MODEM_FAIL,
MBTK_READY_RESPONSE_FAIL,
MBTK_READY_SOCKET_FAIL,
MBTK_READY_RIL_FAIL
}mbtk_ready_status_type;
typedef enum
{
MBTK_DEV_MODEM_MIN_FUN, //Modem 最小功能
MBTK_DEV_MODEM_FULL_FUN, //Modem 全功能
MBTK_DEV_MODEM_DISABLE_RECEIVE_RF_CIRCUITS = 3, //Modem 禁用射频接收电路
MBTK_DEV_MODEM_DISABLE_TRANSMIT_AND_RECEIVE_RF_CIRCUITS, //Modem禁用射频发射和接收电路
MBTK_DEV_MODEM_DISABLE_SIM, //Modem 禁用(U)SIM 卡
MBTK_DEV_MODEM_TURN_OFF_FULL_SECONDARY_RECEIVE, //Modem 完全禁用辅助接收
}MBTK_DEV_MODEM_FUNCTION;
typedef enum
{
MBTK_CELL_TYPE_GSM = 0,
MBTK_CELL_TYPE_UMTS,
MBTK_CELL_TYPE_LTE
} mbtk_cell_type_enum;
typedef struct
{
MBTK_DEV_MODEM_FUNCTION fun;
int rst;
} mbtk_modem_info_t;
typedef struct
{
int client_fd;
pthread_t read_thread_id;
int exit_fd[2];
bool is_waitting;
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_mutex_t send_mutex;
// Temp response data.
uint16 info_err;
uint16 data_len;
void *data;
//mbtk wyq for server_ready_status add start
char server_ready_status;
//mbtk wyq for server_ready_status add end
mbtk_info_callback_func net_state_cb;
mbtk_info_callback_func call_state_cb;
mbtk_info_callback_func sms_state_cb;
mbtk_info_callback_func radio_state_cb;
mbtk_info_callback_func sim_state_cb;
mbtk_info_callback_func pdp_state_cb;
//add signal by xr
mbtk_info_callback_func signal_state_cb;
} mbtk_info_handle_t;
typedef struct
{
// NR server cell:
// NR cell:
// LTE server cell: tac, PCI, dlEuarfcn, ulEuarfcn, band
// LTE cell: phyCellId,euArfcn,rsrp,rsrq
// WCDMA server cell: lac, ci, arfcn
// WCDMA cell: lac, ci, arfcn
// GSM server cell: lac, ci, arfcn, bsic
// GSM cell:
uint32 value1; //tac
uint32 value2; //pci
uint32 value3; //dlEuarfcn
uint32 value4; //bler
uint32 value5; //band
uint32 value6; //mcc
uint32 value7; //mnc
uint32 value8; //rsrp
uint32 value9; //rsrq
uint32 value10; //cell identiy
uint32 value11; //sinr
uint32 value12; //is tdd
uint32 value13;
uint32 value14;
uint32 value15;
} __attribute__((packed)) mbtk_cell_info_t;
typedef struct
{
uint8 net_pref; // mbtk_net_pref_enum
uint16 gsm_band; // mbtk_gsm_band_enum
uint16 umts_band; // mbtk_umts_band_enum
uint32 tdlte_band; // mbtk_tdlte_band_enum
uint32 fddlte_band; // mbtk_fddlte_band_enum
uint32 lte_ext_band; // mbtk_lte_ext_band_enum
} __attribute__((packed)) mbtk_band_info_t;
typedef struct list_arraynode
{
void *data;
struct list_arraynode *next;
} list_arraynode_t;
typedef struct list_treenode
{
list_arraynode_t *data;
int count;
struct list_treenode *left;
struct list_treenode *right;
} list_treenode_t;
typedef int (*list_sort_func)(void *data1, void *data2);
typedef void (*list_free_func)(void *data);
typedef struct list_node
{
uint32 size;
list_sort_func sort_func;
list_free_func free_func;
uint32 cur_index;
list_arraynode_t *cur_array_data;
list_arraynode_t array_data;
list_treenode_t tree_data;
} list_node_t;
/*
0: GSM
1: GSM Compact
2: UTRAN
3: GSM w/EGPRS
4: UTRAN w/HSDPA
5: UTRAN w/HSUPA
6: UTRAN w/HSDPA and HSUPA
7: E-UTRAN
8: UTRAN HSPA+
*/
typedef enum {
MBTK_RADIO_TECH_GSM = 0,
MBTK_RADIO_TECH_GSM_COMPACT,
MBTK_RADIO_TECH_UTRAN,
MBTK_RADIO_TECH_GSM_EGPRS,
MBTK_RADIO_TECH_UTRAN_HSDPA,
MBTK_RADIO_TECH_UTRAN_HSUPA,
MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA,
MBTK_RADIO_TECH_E_UTRAN, // LTE
MBTK_RADIO_TECH_UTRAN_HSPA
} mbtk_radio_technology_enum;
typedef struct
{
/*
0: automatic
1: manual
*/
uint8 net_sel_mode;
/*
0: GSM
1: GSM Compact
2: UTRAN
3: GSM w/EGPRS
4: UTRAN w/HSDPA
5: UTRAN w/HSUPA
6: UTRAN w/HSDPA and HSUPA
7: E-UTRAN
8: UTRAN HSPA+
0xFF: Unused
*/
uint8 net_type;
//uint8 plmn[10]; // 46000
/*
0: unknown
1: available
2: current
3: forbidden
*/
uint8 net_state;
uint32 plmn;
} __attribute__((packed)) mbtk_net_info_t;
typedef enum
{
MBTK_NET_REG_STATE_NON = 0,
MBTK_NET_REG_STATE_HOME,
MBTK_NET_REG_STATE_SEARCHING,
MBTK_NET_REG_STATE_DENIED,
MBTK_NET_REG_STATE_UNKNOWN,
MBTK_NET_REG_STATE_ROAMING,
MBTK_NET_REG_STATE_SMS_ONLY,
MBTK_NET_REG_STATE_ROAMING_SMS,
MBTK_NET_REG_STATE_ATTACHED_EMERGENCY,
MBTK_NET_REG_STATE_CSFB_HOME,
MBTK_NET_REG_STATE_CSFB_ROAMING,
MBTK_NET_REG_STATE_EMERGENCY_ONLY
} mbtk_net_reg_state_enum;
typedef struct
{
uint8 call_state;// mbtk_net_reg_state_enum
uint8 data_state;// mbtk_net_reg_state_enum
uint8 ims_state;// mbtk_net_reg_state_enum
uint8 type; // mbtk_radio_technology_enum
uint16 lac;
uint32 ci;
} __attribute__((packed)) mbtk_net_reg_info_t;
typedef struct
{
uint8 type; // mbtk_radio_technology_enum
uint8 rssi; // 0: 113 dBm or less
// 1: 111 dBm
// 2��30: 109��53 dBm
// 31: 51 dBm or greater
// 99: not known or not detectable
uint8 rxlev;// 0:rssi < -110 dBm
// 1: -110 dBm �� rssi < -109 dBm
// 2: -109 dBm �� rssi < -108 dBm
// ......
// 61: -50 dBm �� rssi < -49 dBm
// 62: -49 dBm �� rssi < -48 dBm
// 63: -48 dBm �� rssi
// 99: not known or not detectable
uint8 ber; // 0...7 as RXQUAL values in the table in 3GPP TS 45.008 [20] subclause 8.2.4
// 99 not known or not detectable
uint8 rscp; // 0: rscp < -120 dBm
// 1: -120 dBm �� rscp < -119 dBm
// 2: -119 dBm �� rscp < -118 dBm
// ......
// 94: -27 dBm �� rscp < -26 dBm
// 95: -26 dBm �� rscp < -25 dBm
// 96: - 25 dBm �� rscp
// 255: not known or not detectable
uint8 ecno; // 0: Ec/Io < -24 dB
// 1: -24 dB �� Ec/Io < -23.5 dB
// 2: -23.5 dB �� Ec/Io < -23 dB
// ......
// 47: -1 dB �� Ec/Io < -0.5 dB
// 48: -0.5 dB �� Ec/Io < 0 dB
// 49: 0 dB �� Ec/Io
// 255: not known or not detectable
uint8 rsrq; // 0: rsrq < -19.5 dB
// 1: -19.5 dB �� rsrq < -19 dB
// 2: -19 dB �� rsrq < -18.5 dB
// ......
// 32: -4 dB �� rsrq < -3.5 dB
// 33: -3.5 dB �� rsrq < -3 dB
// 34: -3 dB �� rsrq
// 255: not known or not detectable
uint8 rsrp; // 0: rsrp < -140 dBm
// 1: -140 dBm �� rsrp < -139 dBm
// 2: -139 dBm �� rsrp < -138 dBm
// ......
// 95: -46 dBm �� rsrp < -45 dBm
// 96: -45 dBm �� rsrp < -44 dBm
// 97: -44 dBm �� rsrp
// 255: not known or not detectable
int8 sinr; //-20-35 dbm
} __attribute__((packed)) mbtk_signal_info_t;
typedef struct{
uint8_t mode;
uint32_t oosPhase[3]; //单位为秒
} mbtk_oos_info;
typedef struct
{
/* Configuration parameters for MCM network full band network scan when OOS (out of service)*/
int t_min;
int t_step;
int t_max;
}GSW_NW_OOS_CONFIG_INFO_T;
#define lib_mbtk_path "/lib/libmbtk_lib.so"
mbtk_info_handle_t* nw_info_handle = NULL;
static GSW_NW_ServingInfoHandlePtr serving_cb=NULL;
static GSW_NW_SigInfoHandlePtr sig_cb=NULL;
static GSW_NW_RejectCauseHandlePtr reject_cb=NULL;
static GSW_NW_ModemStateHandlePtr modem_cb=NULL;
static GSW_NW_AirplaneModeHandlePtr airplane_cb=NULL;
static void *dlHandle_mbtk;
int nw_init_flag = 0;
int mode = -1;
int fplmn_max_length = 0;
gsw_nw_plmn_list_t gsw_nw_plmn_list;
char fplmn_array[FPLMN_ARRAY_SIZE][7];
int fplmn_index = 0;
static mbtk_info_handle_t* (*mbtk_info_handle_get)(void);
static int (*mbtk_info_handle_free)(mbtk_info_handle_t** handle);
int (*mbtk_net_sel_mode_get)(mbtk_info_handle_t* handle, mbtk_net_info_t *net);
int (*mbtk_net_reg_get)(mbtk_info_handle_t* handle, mbtk_net_reg_info_t *reg);
int (*mbtk_cell_get)(mbtk_info_handle_t* handle, mbtk_cell_type_enum *type, list_node_t **cell_list);
int (*mbtk_get_modem_fun)(mbtk_info_handle_t* handle, int* fun);
static int (*mbtk_set_modem_fun)(mbtk_info_handle_t* handle, mbtk_modem_info_t *info);
int (*mbtk_current_band_get)(mbtk_info_handle_t* handle, mbtk_band_info_t *band);
int (*mbtk_current_band_set)(mbtk_info_handle_t* handle, const mbtk_band_info_t *band);
int (*mbtk_net_signal_get)(mbtk_info_handle_t* handle, mbtk_signal_info_t *signal);
int (*mbtk_wakeup_state_set)(mbtk_info_handle_t* handle, uint32 wakeup_state);
int (*mbtk_signal_state_change_cb_reg)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb);
int (*mbtk_net_state_change_cb_reg)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb);
int (*mbtk_fplmn_get)(mbtk_info_handle_t *handle, void *fplmn);
int (*mbtk_fplmn_set)(mbtk_info_handle_t *handle, void *fplmn);
int (*mbtk_radio_state_change_cb_reg)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb);
int (*mbtk_oos_get)(mbtk_info_handle_t* handle, mbtk_oos_info *oos_info);
int (*mbtk_oos_set)(mbtk_info_handle_t* handle, mbtk_oos_info *oos_info);
int (*mbtk_imei_get)(mbtk_info_handle_t* handle, void *imei);
bool (*str_empty)(const void *str);
#define GSW_NW "[HAL][GSW_NW]"
typedef struct
{
char *lynq_operator_l;
char *lynq_operator_s;
uint32 lynq_mcc_mnc;
} lynq_operator_mcc_mnc_t;
static lynq_operator_mcc_mnc_t lynq_operator_mcc_mnc[] =
{
{"China Mobile","CMCC",46000},
{"China Unicom","CU",46001},
{"China Mobile","CMCC",46002},
{"China Telecom","CT",46003},
{"China Mobile","CMCC",46004},
{"China Telecom","CT",46005},
{"China Unicom","CU",46006},
{"China Mobile","CMCC",46007},
{"China Mobile","CMCC",46008},
{"China Unicom","CU",46009},
{"China Telecom","CT",46011}
};
//GSW include
typedef enum prefer_mode
{
GSW_PREFER_MODE_GSW = 1, /**<2G only*/
GSW_PREFER_MODE_WCDMA = 2, /**< 3G only*/
GSW_PREFER_MODE_WCDMA_GSM = 3, /**< 3G/2G*/
GSW_PREFER_MODE_LTE = 4, /**< 4G only*/
GSW_PREFER_MODE_NR5G = 5, /**< 5G only*/
GSW_PREFER_MODE_NR5G_LTE = 8, /**< 5G/4G*/
GSW_PREFER_MODE_LTE_WCDMA_GSM = 9, /**< 4G/3G/2G*/
GSW_PREFER_MODE_NR5G_LTE_WCDMA_GSM = 32, /**< 5G/4G/3G/2G*/
} PREFER_MODE_E;
#define NW_THEAD_NUM (3)
static int mbtk_nw_api_import()
{
dlHandle_mbtk = dlopen(lib_mbtk_path, RTLD_NOW);
if (dlHandle_mbtk == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
mbtk_info_handle_get = (mbtk_info_handle_t* (*)(void))dlsym(dlHandle_mbtk, "mbtk_info_handle_get");
if (mbtk_info_handle_get == NULL)
{
LOGE(GSW_NW,"mbtk_info_handle_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_info_handle_free = (int (*)(mbtk_info_handle_t** handle))dlsym(dlHandle_mbtk, "mbtk_info_handle_free");
if (mbtk_info_handle_free == NULL)
{
LOGE(GSW_NW,"mbtk_info_handle_free dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_net_sel_mode_get = (int (*)(mbtk_info_handle_t* handle, mbtk_net_info_t *net))dlsym(dlHandle_mbtk, "mbtk_net_sel_mode_get");
if (mbtk_net_sel_mode_get == NULL)
{
LOGE(GSW_NW,"mbtk_net_sel_mode_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_net_reg_get = (int (*)(mbtk_info_handle_t* handle, mbtk_net_reg_info_t *reg))dlsym(dlHandle_mbtk, "mbtk_net_reg_get");
if (mbtk_net_reg_get == NULL)
{
LOGE(GSW_NW,"mbtk_net_reg_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_get_modem_fun = (int (*)(mbtk_info_handle_t* handle, int* fun))dlsym(dlHandle_mbtk, "mbtk_get_modem_fun");
if (mbtk_get_modem_fun == NULL)
{
LOGE(GSW_NW,"mbtk_get_modem_fun dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_set_modem_fun = (int (*)(mbtk_info_handle_t* handle, mbtk_modem_info_t *info))dlsym(dlHandle_mbtk, "mbtk_set_modem_fun");
if (mbtk_set_modem_fun == NULL)
{
LOGE(GSW_NW,"mbtk_set_modem_fun dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_current_band_get = (int (*)(mbtk_info_handle_t* handle, mbtk_band_info_t *band))dlsym(dlHandle_mbtk, "mbtk_current_band_get");
if (mbtk_current_band_get == NULL)
{
LOGE(GSW_NW,"mbtk_current_band_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_current_band_set = (int (*)(mbtk_info_handle_t* handle, const mbtk_band_info_t *band))dlsym(dlHandle_mbtk, "mbtk_current_band_set");
if (mbtk_current_band_set == NULL)
{
LOGE(GSW_NW,"mbtk_current_band_set dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_net_signal_get = (int (*)(mbtk_info_handle_t* handle, mbtk_signal_info_t *signal))dlsym(dlHandle_mbtk, "mbtk_net_signal_get");
if (mbtk_net_signal_get == NULL)
{
LOGE(GSW_NW,"mbtk_net_signal_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_wakeup_state_set = (int (*)(mbtk_info_handle_t* handle, uint32 wakeup_state))dlsym(dlHandle_mbtk, "mbtk_wakeup_state_set");
if (mbtk_wakeup_state_set == NULL)
{
LOGE(GSW_NW,"mbtk_wakeup_state_set dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_cell_get = (int (*)(mbtk_info_handle_t* handle, mbtk_cell_type_enum *type, list_node_t **cell_list))dlsym(dlHandle_mbtk, "mbtk_cell_get");
if (mbtk_cell_get == NULL)
{
LOGE(GSW_NW,"mbtk_cell_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_signal_state_change_cb_reg = (int (*)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb))dlsym(dlHandle_mbtk, "mbtk_signal_state_change_cb_reg");
if (mbtk_signal_state_change_cb_reg == NULL)
{
LOGE(GSW_NW,"mbtk_signal_state_change_cb_reg dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_net_state_change_cb_reg = (int (*)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb))dlsym(dlHandle_mbtk, "mbtk_net_state_change_cb_reg");
if (mbtk_net_state_change_cb_reg == NULL)
{
LOGE(GSW_NW,"mbtk_net_state_change_cb_reg dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_fplmn_get = (int(*)(mbtk_info_handle_t *handle, void *fplmn))dlsym(dlHandle_mbtk, "mbtk_fplmn_get");
if (mbtk_fplmn_get == NULL)
{
LOGE(GSW_NW,"mbtk_fplmn_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_fplmn_set = (int(*)(mbtk_info_handle_t *handle, void *fplmn))dlsym(dlHandle_mbtk, "mbtk_fplmn_set");
if (mbtk_fplmn_set == NULL)
{
LOGE(GSW_NW,"mbtk_fplmn_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_radio_state_change_cb_reg = (int (*)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb))dlsym(dlHandle_mbtk, "mbtk_radio_state_change_cb_reg");
if (mbtk_radio_state_change_cb_reg == NULL)
{
LOGE(GSW_NW,"mbtk_radio_state_change_cb_reg dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_oos_get = (int (*)(mbtk_info_handle_t* handle, mbtk_oos_info *oos))dlsym(dlHandle_mbtk, "mbtk_oos_get");
if (mbtk_oos_get == NULL)
{
LOGE(GSW_NW,"mbtk_oos_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_oos_set = (int (*)(mbtk_info_handle_t* handle, mbtk_oos_info *oos))dlsym(dlHandle_mbtk, "mbtk_oos_set");
if (mbtk_oos_set == NULL)
{
LOGE(GSW_NW,"mbtk_oos_set dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_imei_get = (int (*)(mbtk_info_handle_t* handle, void *imei))dlsym(dlHandle_mbtk, "mbtk_imei_get");
if (mbtk_imei_get == NULL)
{
LOGE(GSW_NW,"mbtk_imei_get dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
str_empty = (bool (*)(const void *str))dlsym(dlHandle_mbtk, "str_empty");
if (str_empty == NULL)
{
LOGE(GSW_NW,"str_empty dlsym fail\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
void list_first(list_node_t *list)
{
if (list) {
list->cur_index = 0;
list->cur_array_data = list->array_data.next;
}
}
void* list_next(list_node_t *list)
{
if (list) {
list_arraynode_t *node = list->cur_array_data;
if (node) {
LOGE(GSW_NW,"node is not null\n");
list->cur_array_data = list->cur_array_data->next;
list->cur_index++;
return node->data;
} else {
LOGE(GSW_NW,"node is null\n");
return NULL;
}
} else {
LOGE(GSW_NW,"list is null\n");
return NULL;
}
}
void list_free(list_node_t *list)
{
if (list) {
list_arraynode_t *node = &(list->array_data); // Head node
list_arraynode_t *node_temp = NULL;
while (node->next) {
node_temp = node->next;
node->next = node->next->next;
if (list->free_func) {
list->free_func(node_temp->data);
} else {
free(node_temp->data);
}
free(node_temp);
}
free(list);
}
}
#if 0
static int32_t gsm_rssi_convert_to_dBm(uint8 rssi)
{
if(rssi <= 31)
{
return rssi * 2 - 113; //0 map -113
//31 map -51
}
else
{
return INT_32_MAX;
}
}
#endif
static int32_t rscp_convert_to_minus_dBm(uint8 rscp)
{
if(rscp <= 96)
{
return 121-rscp; // 96 map 25
// 0 map -121, below -120
}
else
{
return INT_32_MAX;
}
}
static int32_t rsrp_convert_to_minus_dBm(uint8 rsrp)
{
if(rsrp <= 97)
{
return 141-rsrp; // 97 map 44
// 0 map 141 below 140
}
else
{
return INT_32_MAX;
}
}
static int32_t rsrq_convert_to_minus_dB(uint8 rsrq)
{
if(rsrq <= 34)
{
return (40-rsrq)/2; //=20-rsrq / 2;
// 34 map 3
// 0 map 20
}
else
{
return INT_32_MAX;
}
}
static int32_t sinr_convert_to_10_times_dB(int8 sinr)
{
if(sinr <=35 && sinr>=-20)
{
return sinr*10; //35 map 350 db
// -20 map -2000 db
}
else
{
return INT_32_MAX;
}
}
//int ecno; /**< Valid values are positive integers. This value is the actual Ec/Io multiplied
// * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value
// * will be 125.*/
//uint8 ecno; // 0: Ec/Io < -24 dB
// 1: -24 dB �� Ec/Io < -23.5 dB
// 2: -23.5 dB �� Ec/Io < -23 dB
// ......
// 47: -1 dB �� Ec/Io < -0.5 dB
// 48: -0.5 dB �� Ec/Io < 0 dB
// 49: 0 dB �� Ec/Io
// 255: not known or not detectabl
static int32_t ecno_convert_to_minus_10_times_dB(uint8 ecno)
{
if(ecno <=49)
{
return 245-ecno*5; //49 map 0 db
// 1 map 240 db
// 0 map 245 below 240
}
else
{
return INT_32_MAX;
}
}
/* change realCsq to level */
static int rscpToLevel(int rscp)
{
if (rscp < -110) {
return 0;
} else if (rscp <= -95) {
return rscp+111; // to 16
} else if (rscp >=-93 && rscp <=-90) {
return rscp+110; // to 20
} else if (rscp >=-89 && rscp <=-59) {
return (rscp+152)/3; // =(rscp+89)/3+21 to 31
} else if (rscp ==- 94) { // Geely requirement, -94 map 16
return 16;
} else if(rscp <= -25) {
return 31;
}
return 99;
}
static int rsrpToLevel(int rsrp)
{
if (rsrp < -130) {
return 0;
} else if (rsrp <= -118) {
return (rsrp+132)/2; // to 7
} else if (rsrp <=-109) {
return rsrp+125; // to 16
} else if (rsrp <=-103) {
return (rsrp+141)/2; // =(rsrp+109)/2+16 to 19
} else if (rsrp <=- 85) {
return (rsrp+160)/3; // =(rsrp+103)/3+19 to 25
} else if(rsrp <= -55) {
return (rsrp+210)/5; // =(rsrp+85)/5+25 to 31
} else if(rsrp <=-44)
{
return 31;
}
return 99;
}
//uint8 rssi; // 0: 113 dBm or less
// 1: 111 dBm
// 2��30: 109��53 dBm
// 31: 51 dBm or greater
// 99: not known or not detectable
//uint8 rxlev;// 0:rssi < -110 dBm
// 1: -110 dBm �� rssi < -109 dBm
// 2: -109 dBm �� rssi < -108 dBm
// 60 ......
// 61: -50 dBm �� rssi < -49 dBm
// 62: -49 dBm �� rssi < -48 dBm
// 63: -48 dBm �� rssi
// 99: not known or not detectable
/* change realCsq to level */
static int rxlevToLevel(uint8 rxlev)
{
if (rxlev <=60) {
return (rxlev+3)/2; // =(rxlev+1)/2+1,
// 0 map 1
// 1,2 map 2
// 59,60 map 31
}
else if(rxlev <=63)
{
return 31;
}
return INVALID_AT_SIGNAL_LEVEL;
}
static int convert_reg_state(int reg_state_t)
{
LOGD(GSW_NW,"reg_state_t = %d\n",reg_state_t);
int reg_state = 0;
switch (reg_state_t)
{
case MBTK_NET_REG_STATE_NON:
{
reg_state = GSW_NETWORK_REG_NOT_REGISTERED;
break;
}
case MBTK_NET_REG_STATE_HOME:
{
reg_state = GSW_NETWORK_REG_REGISTERED;
break;
}
case MBTK_NET_REG_STATE_SEARCHING:
{
reg_state = GSW_NETWORK_REG_NOT_REGISTERED_SEARCHING;
break;
}
case MBTK_NET_REG_STATE_DENIED:
{
reg_state = GSW_NETWORK_REG_REGISTRATION_DENIED;
break;
}
case MBTK_NET_REG_STATE_UNKNOWN:
{
reg_state = GSW_NETWORK_REG_REGISTRATION_UNKNOWN;
break;
}
case MBTK_NET_REG_STATE_ROAMING:
{
reg_state = GSW_NETWORK_REG_REGISTRATION_ROAMING;
break;
}
case MBTK_NET_REG_STATE_SMS_ONLY:
case MBTK_NET_REG_STATE_ROAMING_SMS:
case MBTK_NET_REG_STATE_ATTACHED_EMERGENCY:
case MBTK_NET_REG_STATE_CSFB_HOME:
case MBTK_NET_REG_STATE_CSFB_ROAMING:
case MBTK_NET_REG_STATE_EMERGENCY_ONLY:
{
reg_state = GSW_NETWORK_REG_LIMITED_SERVICE;
break;
}
}
return reg_state;
}
static int convert_net_mode(int net_mode)
{
LOGD(GSW_NW,"net_mode = %d\n",net_mode);
switch(net_mode)
{
case MBTK_RADIO_TECH_GSM:
case MBTK_RADIO_TECH_GSM_COMPACT:
case MBTK_RADIO_TECH_GSM_EGPRS:
{
return GSW_NETWORK_RADIO_GSM;
}
case MBTK_RADIO_TECH_UTRAN:
case MBTK_RADIO_TECH_UTRAN_HSDPA:
case MBTK_RADIO_TECH_UTRAN_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSPA:
{
return GSW_NETWORK_RADIO_UMTS;
}
case MBTK_RADIO_TECH_E_UTRAN:
{
return GSW_NETWORK_RADIO_LTE;
}
default:
{
return GSW_NETWORK_RADIO_NO_SVC;
}
}
return GSW_NETWORK_RADIO_NO_SVC;
}
static int convert_mbtk_net_config(int config)
{
int net_pref = -1;
switch(config)
{
case GSW_PREFER_MODE_GSW:
{
net_pref = 0;
break;
}
case GSW_PREFER_MODE_WCDMA:
{
net_pref = 1;
break;
}
case GSW_PREFER_MODE_WCDMA_GSM:
{
net_pref = 2;
break;
}
case GSW_PREFER_MODE_LTE:
case GSW_PREFER_MODE_NR5G:
case GSW_PREFER_MODE_NR5G_LTE:
{
net_pref = 5;
break;
}
case GSW_PREFER_MODE_LTE_WCDMA_GSM:
case GSW_PREFER_MODE_NR5G_LTE_WCDMA_GSM:
{
net_pref = 15;
break;
}
}
return net_pref;
}
static int convert_gsw_net_config(int config)
{
int net_config = -1;
LOGD(GSW_NW,"config = %d\n",config);
switch (config)
{
case 0:
{
net_config = GSW_PREFER_MODE_GSW;
break;
}
case 1:
{
net_config = GSW_PREFER_MODE_WCDMA;
break;
}
case 2:
{
net_config = GSW_PREFER_MODE_WCDMA_GSM;
break;
}
case 5:
{
net_config = GSW_PREFER_MODE_LTE;
break;
}
case 15:
{
net_config = GSW_PREFER_MODE_LTE_WCDMA_GSM;
break;
}
}
return net_config;
}
//64F010 -> 46001 (64->46,F0->0,10->01)
static void transform_fplmn_str_to_plmn(char *entry)
{
if (strncmp(entry, "FFFFFF", ENTRY_LENGTH) == 0) {
return; //if FFFFFF,means invalid fplmn, do nothing
}
char temp = entry[0];
entry[0] = entry[1];
entry[1] = temp;
temp = entry[ENTRY_LENGTH - 2];
entry[ENTRY_LENGTH - 2] = entry[ENTRY_LENGTH - 1];
entry[ENTRY_LENGTH - 1] = temp;
memmove(entry + 2, entry + 3, ENTRY_LENGTH - 2);
LOGE(GSW_NW,"after transform_fplmn_str_to_plmn: %s\n", entry);
//valid fplmn
fplmn_index++;
}
static void extract_mcc_mnc(char *entry, char *mcc, char *mnc)
{
strncpy(mcc,entry,3);
mcc[3] = '\0';
strncpy(mnc,entry + 3,2);
mnc[2] = '\0';
LOGE(GSW_NW,"entry = %s, mcc = %s, mnc = %s\n", entry, mcc, mnc);
}
static void update_fplmn_list(char *fplmn_str)
{
LOGE(GSW_NW,"fplmn_str = %s\n",fplmn_str);
char temp_fplmn_array[FPLMN_ARRAY_SIZE][7];
memset(fplmn_array, 0, sizeof(fplmn_array));
memset(temp_fplmn_array, 0, sizeof(temp_fplmn_array));
fplmn_index = 0;
int array_length = 0;
for (int i = 0; i < strlen(fplmn_str); i += 6) {
int length = (i + 6 < strlen(fplmn_str)) ? 6 : strlen(fplmn_str) - i;
strncpy(temp_fplmn_array[array_length], fplmn_str + i, length);
temp_fplmn_array[array_length][length] = '\0';
array_length++;
if (i + 6 >= strlen(fplmn_str)) {
break;
}
}
for (int i = 0; i < array_length; i++) {
LOGE(GSW_NW,"array[%d] = %s\n", i, temp_fplmn_array[i]);
transform_fplmn_str_to_plmn(temp_fplmn_array[i]);
strncpy(fplmn_array[i], temp_fplmn_array[i], ENTRY_LENGTH);
LOGE(GSW_NW,"fplmn_array[%d] = %s\n", i, fplmn_array[i]);
}
}
static void format_plmn(char *result, char *plmn_entry)
{
strncpy(result, plmn_entry, strlen(plmn_entry));
LOGE(GSW_NW,"result = %s, numStr = %s\n",result, plmn_entry);
if (strlen(result) >= 2) {
char temp = result[0];
result[0] = result[1];
result[1] = temp;
}
LOGE(GSW_NW,"1.result = %s\n",result);
if (strlen(result) >= 3) {
memmove(&result[3], &result[2], strlen(result) - 2 + 1);
result[2] = 'F';
}
LOGE(GSW_NW,"2.result = %s\n",result);
if (strlen(result) >= 2) {
char temp = result[strlen(result) - 1];
result[strlen(result) - 1] = result[strlen(result) - 2];
result[strlen(result) - 2] = temp;
}
LOGE(GSW_NW,"3.result = %s\n",result);
}
static void convert_plmn_to_fplmn_str(char *fplmn_str)
{
char temp_fplmn_str[128] = {0};
char temp[20]; // 临时存储单个格式化后的数字
int index = 0;
for (int i = 0; i < fplmn_index; i++) {
memset(temp, 0x0, sizeof(temp));
format_plmn(temp, fplmn_array[i]);
strcat(temp_fplmn_str, temp);
index += strlen(temp);
}
while(index < (6 * fplmn_max_length))
{
temp_fplmn_str[index++] = 'F';
}
// 修剪或截断formattedNumbers,确保它不超过6 * fplmn_max_length个字符
if (index > (6 * fplmn_max_length)) {
temp_fplmn_str[(6 * fplmn_max_length)] = '\0';
}
LOGE(GSW_NW,"%s\n", temp_fplmn_str);
strncpy(fplmn_str, temp_fplmn_str, strlen(temp_fplmn_str));
LOGE(GSW_NW,"fplmn_str = %s\n", fplmn_str);
}
static int check_index(char *mcc, char *mnc)
{
int i = 0;
for(i = 0; i < fplmn_index; i++)
{
if(strncmp(fplmn_array[i], mcc, 3) == 0 && strncmp(fplmn_array[i] + 3, mnc, 2) == 0)
{
LOGE(GSW_NW,"index = %d\n", i);
return i;
}
}
LOGE(GSW_NW,"not find\n");
return -1;
}
static void remove_fplmn(int index)
{
int write_index = 0;
for (int i = 0; i < fplmn_index; i++) {
if (i != index) {
strncpy(fplmn_array[write_index++], fplmn_array[i], ENTRY_LENGTH);
}
}
fplmn_index--;
}
static void convert_mbtk_sig_info_to_gsw_sig_info(const mbtk_signal_info_t* signal, signalStrength_t* sig_strength)
{
LOGD(GSW_NW,"signal->type=%d", signal->type);
memset(sig_strength,0,sizeof (signalStrength_t));
switch(signal->type)
{
case MBTK_RADIO_TECH_E_UTRAN:
{
LOGI(GSW_NW,"rsrp = %d",signal->rsrp);
sig_strength->lte_sig_valid = 1;
sig_strength->rsrp = rsrp_convert_to_minus_dBm(signal->rsrp);
sig_strength->rsrq = rsrq_convert_to_minus_dB(signal->rsrq);
sig_strength->rssnr= sinr_convert_to_10_times_dB(signal->sinr);
break;
}
case MBTK_RADIO_TECH_UTRAN:
case MBTK_RADIO_TECH_UTRAN_HSDPA:
case MBTK_RADIO_TECH_UTRAN_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSPA:
{
LOGI(GSW_NW,"rscp = %d",signal->rscp);
sig_strength->wcdma_sig_valid = 1;
sig_strength->rscp = rscp_convert_to_minus_dBm(signal->rscp);
sig_strength->ecno = ecno_convert_to_minus_10_times_dB(signal->ecno);
break;
}
case MBTK_RADIO_TECH_GSM:
case MBTK_RADIO_TECH_GSM_COMPACT:
case MBTK_RADIO_TECH_GSM_EGPRS:
{
LOGI(GSW_NW,"g rxlev = %d",signal->rxlev);
sig_strength->gw_sig_valid = 1;
sig_strength->rssi = rxlevToLevel(signal->rxlev);
break;
}
default:
{
LOGE(GSW_NW,"[%s] unknown reg type.[%d]", __func__, signal->type);
}
}
}
/*
typedef enum{
MBTK_READY_INIT = -1,
MBTK_READY_SUCCESS,
MBTK_READY_MODEM_FAIL,
MBTK_READY_RESPONSE_FAIL,
MBTK_READY_SOCKET_FAIL,
MBTK_READY_RIL_FAIL
}mbtk_ready_status_type;
typedef enum gsw_hal_nw_mode_state_type
{
GSW_MODEM_STATE_UNKNOWN = 0,
GSW_MODEM_STATE_ONLINE,
GSW_MODEM_STATE_OFFLINE,
GSW_SDK_STATE_SERVICE_DOWN,
GSW_SDK_STATE_SERVICE_UP,// service down->up 需要routectl 重启
GSW_SDK_STATE_GPS_DOWN,
GSW_SDK_STATE_GPS_UP,
} gsw_mode_state_e;
*/
static void gsw_serving_info_callback_thread()
{
GSW_NW_SERVING_INFO serving_info;
int ret = gsw_get_nwinfo(&serving_info);
if(ret != 0)
{
LOGE(GSW_NW,"cb gsw_get_nwinfo failed");
return;
}
if(serving_cb!=NULL)
{
LOGE(GSW_NW,"serving cb called");
serving_cb(serving_info);
}
else
{
LOGE(GSW_NW,"serving cb is NULL");
}
}
static void gsw_serving_info_callback(const void* data, int data_len)
{
if (nw_init_flag == 0)
{
printf("%s, nw not init\n",__func__);
return;
}
pthread_t thread;
int ret=pthread_create(&thread, NULL, (void*)gsw_serving_info_callback_thread, NULL);
if(ret==0)
{
pthread_detach(thread);
}
else
{
LOGE(GSW_NW,"create thread fail, ret is %d",ret);
}
}
/*typedef struct
{
0 mbtk_radio_technology_enum type : 8; // mbtk_radio_technology_enum
1 uint8 rssi; // 0: 113 dBm or less
// 1: 111 dBm
// 2��30: 109��53 dBm
// 31: 51 dBm or greater
// 99: not known or not detectable
2 uint8 rxlev;// 0:rssi < -110 dBm
// 1: -110 dBm �� rssi < -109 dBm
// 2: -109 dBm �� rssi < -108 dBm
// ......
// 61: -50 dBm �� rssi < -49 dBm
// 62: -49 dBm �� rssi < -48 dBm
// 63: -48 dBm �� rssi
// 99: not known or not detectable
3 uint8 ber; // 0...7 as RXQUAL values in the table in 3GPP TS 45.008 [20] subclause 8.2.4
// 99 not known or not detectable
4 uint8 rscp; // 0: rscp < -120 dBm
// 1: -120 dBm �� rscp < -119 dBm
// 2: -119 dBm �� rscp < -118 dBm
// ......
// 94: -27 dBm �� rscp < -26 dBm
// 95: -26 dBm �� rscp < -25 dBm
// 96: - 25 dBm �� rscp
// 255: not known or not detectable
5 uint8 ecno; // 0: Ec/Io < -24 dB
// 1: -24 dB �� Ec/Io < -23.5 dB
// 2: -23.5 dB �� Ec/Io < -23 dB
// ......
// 47: -1 dB �� Ec/Io < -0.5 dB
// 48: -0.5 dB �� Ec/Io < 0 dB
// 49: 0 dB �� Ec/Io
// 255: not known or not detectable
6 uint8 rsrq; // 0: rsrq < -19.5 dB
// 1: -19.5 dB �� rsrq < -19 dB
// 2: -19 dB �� rsrq < -18.5 dB
// ......
// 32: -4 dB �� rsrq < -3.5 dB
// 33: -3.5 dB �� rsrq < -3 dB
// 34: -3 dB �� rsrq
// 255: not known or not detectable
7 uint8 rsrp; // 0: rsrp < -140 dBm
// 1: -140 dBm �� rsrp < -139 dBm
// 2: -139 dBm �� rsrp < -138 dBm
// ......
// 95: -46 dBm �� rsrp < -45 dBm
// 96: -45 dBm �� rsrp < -44 dBm
// 97: -44 dBm �� rsrp
// 255: not known or not detectable
8 uint8 ss_rsrq; // 0: ss_rsrq < -43 dB
// 1: -43 dB <= ss_rsrq < -42.5 dB
// 2: -42.5 dB <= ss_rsrq < -42 dB
// ......
// 125: 19 dB <= ss_rsrq < 19.5 dB
// 126: 19.5 dB <= ss_rsrq < 20 dB
// 255: not known or not detectable
uint8 ss_rsrp; // 0: ss_rsrp < -156 dBm
// 1: -156 dBm <= ss_rsrp < -155 dBm
// 2: -155 dBm <= ss_rsrp < -154 dBm
// ......
// 125: -32 dBm <= ss_rsrp < -31 dBm
// 126: -31 dBm <= ss_rsrp
// 255: not known or not detectable
uint8 ss_sinr; // 0: ss_sinr < -23 dB
// 1: -23 dB  ss_sinr < -22.5 dB
// 2: -22.5 dB  ss_sinr < -22 dB
// ......
// 125: 39 dB  ss_sinr < 39.5 dBm
// 126: 39.5 dB  ss_sinr < 40 dB
// 127: 40 dB  ss_sinr
// 255: not known or not detectable
} __attribute__((packed)) mbtk_signal_info_t;
*/
static void gsw_sig_info_callback(const void* data, int data_len)
{
if (nw_init_flag == 0)
{
printf("%s, nw not init\n",__func__);
return;
}
if(data && (data_len >= sizeof (mbtk_signal_info_t)))
{
signalStrength_t sig_strength;
convert_mbtk_sig_info_to_gsw_sig_info(( const mbtk_signal_info_t*) data,&sig_strength);
if(sig_cb != NULL)
{
sig_cb(sig_strength);
}
}
else
{
LOGE(GSW_NW,"data is NULL or data len %d error",data_len);
}
}
static void gsw_operating_mode_event_callback(const void* data, int data_len)
{
if (nw_init_flag == 0)
{
printf("%s nw not init\n",__func__);
return;
}
LOGE(GSW_NW,"gsw_operating_mode_event_callback start\n");
if(data && data_len > 0)
{
const uint8 *cfun_state = (const uint8*)data;
LOGE(GSW_NW,"gsw_operating_mode_event_callback,data = %d\n", *cfun_state);
if(airplane_cb != NULL)
{
airplane_cb(*cfun_state);
}
}
}
static void gsw_reject_callback(GSW_NW_RADIO_ACCESS_TECH_E rat, GSW_SERVICE_DOMAIN_E domain, int cause)
{
if (nw_init_flag == 0)
{
printf("%s nw not init\n",__func__);
return;
}
LOGE(GSW_NW,"gsw_reject_callback start,rat = %d,domain = %d,cause = %d\n",rat,domain,cause);
if(reject_cb != NULL)
{
GSW_NW_REJ_CAUSE_E rej_cause;
rej_cause.rej_cause = cause;
rej_cause.rej_rat = rat;
rej_cause.rej_domain = domain;
LOGE(GSW_NW,"reject_cb called\n");
reject_cb(&rej_cause);
}
else
{
LOGE(GSW_NW,"reject_cb is NULL\n");
}
}
void gsw_serving_info_timer()
{
if(nw_init_flag == 0 || nw_info_handle == NULL)
{
return;
}
while(nw_init_flag)
{
gsw_serving_info_callback_thread();
sleep(SERVING_TIMER);
}
}
void gsw_sig_info_timer()
{
if(nw_init_flag == 0 || nw_info_handle == NULL)
{
return;
}
mbtk_signal_info_t signal;
signalStrength_t sig_strength;
while(nw_init_flag)
{
int ret = mbtk_net_signal_get(nw_info_handle, &signal);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_net_signal_get fail, ret is %d\n",ret);
memset((void*) &sig_strength,0,sizeof (sig_strength));
}
else
{
convert_mbtk_sig_info_to_gsw_sig_info(&signal,&sig_strength);
}
if(sig_cb != NULL)
{
sig_cb(sig_strength);
}
sleep(SIG_TIMER);
}
}
int get_sdk_ready()
{
char buffer[MBTK_READY_STRING_SIZE_MAX];
FILE *fp = popen(SDK_READY_CMD, "r");
if(NULL == fp)
{
LOGE(GSW_NW,"popen sdk ready fail");
return -1;
}
memset(buffer,0,sizeof(buffer));
if(fgets(buffer, sizeof(buffer), fp) == NULL)
{
pclose(fp);
LOGE(GSW_NW,"fgets failed:");
return -1;
}
pclose(fp);
LOGE(GSW_NW,"get_sdk_ready:%s",buffer);
return atoi(buffer);
}
static int g_modem_state = ((int)(GSW_MODEM_STATE_UNKNOWN)) - 1;
static int g_gnss_state = ((int)(GSW_MODEM_STATE_UNKNOWN)) - 1;
void gsw_modem_state_timer()
{
int modem_state;
int gnss_state;
while (nw_init_flag)
{
int uci_value = get_sdk_ready();
if (uci_value < 0)
{
modem_state = GSW_MODEM_STATE_UNKNOWN;
gnss_state = GSW_SDK_STATE_GPS_DOWN;
}
else
{
if ((uci_value & 0x0F) == 0)
{
modem_state = GSW_MODEM_STATE_ONLINE;
}
else if (uci_value > 0 && uci_value <= 15)
{
modem_state = GSW_MODEM_STATE_OFFLINE;
}
else
{
modem_state = GSW_MODEM_STATE_UNKNOWN;
}
if (uci_value & (1 << 4))
{
gnss_state = GSW_SDK_STATE_GPS_DOWN;
}
else
{
gnss_state = GSW_SDK_STATE_GPS_UP;
}
}
if (modem_cb != NULL)
{
if (modem_state != g_modem_state)
{
LOGE(GSW_NW, "Modem state changed from %d to %d", g_modem_state, modem_state);
modem_cb(modem_state);
g_modem_state = modem_state;
}
if (gnss_state != g_gnss_state)
{
LOGE(GSW_NW, "GNSS state changed from %d to %d", g_gnss_state, gnss_state);
modem_cb(gnss_state);
g_gnss_state = gnss_state;
}
}
sleep(MODEM_TIMER);
}
}
/**
* @brief SDK interface to call back serving info
* @param [in] handle_ptr
* @retval 0: success
* @retval other: fail
*/
int gsw_reg_serving_info_callback(GSW_NW_ServingInfoHandlePtr handle_ptr)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
void* cb_func;
if(handle_ptr == NULL)
{
LOGE(GSW_NW,"serving info handle_ptr is NULL\n");
cb_func=NULL;
}
else
{
cb_func=(void*) gsw_serving_info_callback;
}
int ret = mbtk_net_state_change_cb_reg(nw_info_handle, cb_func);
if (ret != 0)
{
LOGW(GSW_NW,"mbtk_net_state_change_cb_reg fail, ret is %d",ret);
return GSW_HAL_NORMAL_FAIL;
}
serving_cb=handle_ptr;
return GSW_HAL_SUCCESS;
}
/**
* @brief SDK interface to call back sig info
* @param [in] handle_ptr
* @retval 0: success
* @retval other: fail
*/
int gsw_reg_sig_info_callback(GSW_NW_SigInfoHandlePtr handle_ptr)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
void* cb_func;
if(handle_ptr == NULL)
{
LOGE(GSW_NW,"serving info handle_ptr is NULL\n");
cb_func=NULL;
}
else
{
cb_func=(void*) gsw_sig_info_callback;
}
int ret = mbtk_signal_state_change_cb_reg(nw_info_handle, cb_func);
if (ret != 0)
{
LOGE(GSW_NW,"mbtk_signal_state_change_cb_reg fail, ret is %d", ret);
return GSW_HAL_NORMAL_FAIL;
}
sig_cb = handle_ptr;
return GSW_HAL_SUCCESS;
}
/**
* @brief SDK interface to call back rej cause
* @param [in] handle_ptr
* @retval 0: success
* @retval other: fail
*/
int gsw_reg_rej_cause_callback(GSW_NW_RejectCauseHandlePtr handle_ptr)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(handle_ptr == NULL)
{
LOGE(GSW_NW,"rej cause handle_ptr is NULL\n");
}
reject_cb = handle_ptr;
return GSW_HAL_SUCCESS;
}
static void gsw_un_reg_all()
{
gsw_reg_serving_info_callback(NULL);
gsw_reg_sig_info_callback(NULL);
gsw_reg_operating_mode_callback(NULL);
gsw_reg_set_modem_status_event_callback(NULL);
gsw_reg_rej_cause_callback(NULL);
}
pthread_t s_tid[NW_THEAD_NUM] = {-1,-1,-1};
void* s_thread_func[NW_THEAD_NUM]={
(void*)gsw_sig_info_timer,
(void*)gsw_modem_state_timer,
(void*)gsw_serving_info_timer
};
static void gsw_close_all_thread()
{
int i,ret;
nw_init_flag=0;
/* had better not use thread cancel, maybe handle->send_mutex is locked now, cancel will not release this mutex
for(i=0; i<NW_THEAD_NUM; i++)
{
if(s_tid[i]!=-1)
{
ret = pthread_cancel(s_tid[i]);
LOGE(GSW_NW,"pthread %d cancel, ret is %d",i, ret);
}
}
*/
for(i=0;i<NW_THEAD_NUM;i++)
{
if(s_tid[i]!=-1)
{
ret = pthread_join(s_tid[i],NULL);
LOGE(GSW_NW,"pthread %d join, ret is %d",i, ret);
s_tid[i]=-1;
}
}
}
static int gsw_start_all_thread()
{
int i,ret;
for(i=0; i<NW_THEAD_NUM;i++)
{
ret = pthread_create(&(s_tid[i]), NULL,s_thread_func[i], NULL);
if (ret != 0)
{
LOGE(GSW_NW,"pthread_create fail %d,ret is %d",i,ret);
gsw_close_all_thread();
return GSW_HAL_ERROR_GNSS_NO_THRESHOLDS;
}
}
return GSW_HAL_SUCCESS;
}
/**
* @brief network sdk init
* @param [in] token usr id define by who use
* @retval 0: success
* @retval other: fail
*/
int gsw_nw_sdk_init(int token)
{
if (nw_init_flag == 1 && nw_info_handle != NULL)
{
return GSW_HAL_SUCCESS;
}
int ret = mbtk_nw_api_import();
if (ret != 0)
{
printf("mbtk_nw_api_import fail");
return GSW_HAL_NORMAL_FAIL;
}
nw_info_handle = mbtk_info_handle_get();
if (nw_info_handle == NULL)
{
LOGE(GSW_NW,"mbtk_info_handle_get fail");
return GSW_HAL_NORMAL_FAIL;
}
char fplmn[256] = {0};
ret = mbtk_fplmn_get(nw_info_handle, fplmn);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_fplmn_get failed, ret is %d",ret);
return GSW_HAL_NORMAL_FAIL;
}
fplmn_max_length = (strlen(fplmn)/6);
LOGE(GSW_NW,"fplmn = %s, fplmn_max_length = %d",fplmn,fplmn_max_length);
nw_init_flag = 1;
ret=gsw_start_all_thread();
if(ret != 0)
{
nw_init_flag = 0;
LOGE(GSW_NW,"gsw_start_all_thread failed , ret is %d",ret);
return GSW_HAL_NORMAL_FAIL;
}
LOGE(GSW_NW,"gsw nw init suc");
return GSW_HAL_SUCCESS;
}
/**
* @brief network sdk deinit
* @param
* @retval 0: success
* @retval other: fail
*/
int gsw_nw_sdk_deinit(void)
{
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
gsw_un_reg_all();// had better un-reg before thread close
gsw_close_all_thread();//in it, nw_init_flag=0 and cb unreg
ret = mbtk_info_handle_free(&nw_info_handle);
if(ret != GSW_HAL_SUCCESS)
{
LOGE(GSW_NW,"mbtk_info_handle_free fail");
return GSW_HAL_NORMAL_FAIL;
}
dlclose(dlHandle_mbtk);
nw_info_handle = NULL;
LOGE(GSW_NW,"gsw_nw_sdk_deinit suc");
return GSW_HAL_SUCCESS;
}
/**
* @brief get current network reg info
* @param [out] serving_info struct for network info
* include regstate ps_state opreator name mcc mcn etc
* @retval 0: success
* @retval other: fail
*/
int gsw_get_nwinfo(GSW_NW_SERVING_INFO *serving_info)
{
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
printf("nw_sdk_deinit not init\n");
return GSW_HAL_NORMAL_FAIL;
}
LOGE(GSW_NW,"mbtk_net_reg_get start \n");
//regstate
mbtk_net_reg_info_t reg;
ret = mbtk_net_reg_get(nw_info_handle, &reg);
if(ret)
{
LOGE(GSW_NW,"mbtk_net_reg_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
LOGE(GSW_NW,"convert_cs_reg_state\n");
//cs_state
serving_info->reg_state = convert_reg_state(reg.call_state);
LOGE(GSW_NW,"convert_ps_reg_state\n");
//ps_state
serving_info->ps_state = convert_reg_state(reg.data_state);
LOGE(GSW_NW,"convert_rat_mode\n");
//reg_rat
serving_info->reg_rat = convert_net_mode(reg.type);
//srv_domain
if(serving_info->reg_state == GSW_NETWORK_REG_REGISTERED || serving_info->reg_state == GSW_NETWORK_REG_REGISTRATION_ROAMING)
{
if(serving_info->ps_state == GSW_NETWORK_REG_REGISTERED || serving_info->ps_state == GSW_NETWORK_REG_REGISTRATION_ROAMING)
{
serving_info->srv_domain = GSW_SRV_DOMAIN_CS_PS;
}
else
{
serving_info->srv_domain = GSW_SRV_DOMAIN_CS_ONLY;
}
}
else if (serving_info->ps_state == GSW_NETWORK_REG_REGISTERED || serving_info->ps_state == GSW_NETWORK_REG_REGISTRATION_ROAMING)
{
serving_info->srv_domain = GSW_SRV_DOMAIN_PS_ONLY;
}
else
{
serving_info->srv_domain = GSW_SRV_DOMAIN_NO_SVC;
//if ps and cs is both not registed, reg_rat seted to GSW_NETWORK_RADIO_NO_SVC
serving_info->reg_rat = GSW_NETWORK_RADIO_NO_SVC;
}
LOGD(GSW_NW,"roaming_ind\n");
//roaming_ind
if(serving_info->ps_state == GSW_NETWORK_REG_REGISTRATION_ROAMING)
{
serving_info->roaming_ind = GSW_NETWORK_ROAMING_ON;
}
else
{
serving_info->roaming_ind = GSW_NETWORK_ROAMING_OFF;
}
LOGD(GSW_NW,"reject\n");
//reject
if(serving_info->ps_state == GSW_NETWORK_REG_REGISTRATION_DENIED || serving_info->reg_state == GSW_NETWORK_REG_REGISTRATION_DENIED)
{
LOGD(GSW_NW,"reject_callback\n");
gsw_reject_callback(serving_info->reg_rat,serving_info->srv_domain,99);
}
LOGD(GSW_NW,"reg_plmn / operator name\n");
//reg_plmn / operator name
mbtk_net_info_t net;
LOGD(GSW_NW,"mbtk_net_sel_mode_get start \n");
ret = mbtk_net_sel_mode_get(nw_info_handle, &net);
LOGD(GSW_NW,"mbtk_net_sel_mode_get end \n");
if(ret == 0 && net.plmn > 0)
{
int i = 0;
LOGD(GSW_NW,"start to find mcc");
while(i < ARRAY_SIZE(lynq_operator_mcc_mnc))
{
if(lynq_operator_mcc_mnc[i].lynq_mcc_mnc == net.plmn)
{
LOGD(GSW_NW,"find mcc\n");
break;
}
i++;
}
if(i == ARRAY_SIZE(lynq_operator_mcc_mnc))
{
LOGD(GSW_NW,"not find mcc");
strcpy(serving_info->operator_name, "unknown");
sprintf(serving_info->reg_plmn, "%u", net.plmn);
}
else
{
LOGD(GSW_NW,"find mcc\n");
strcpy(serving_info->operator_name, lynq_operator_mcc_mnc[i].lynq_operator_l);
sprintf(serving_info->reg_plmn, "%u", net.plmn);
}
LOGE(GSW_NW,"operator_name = %s\n", serving_info->operator_name);
LOGE(GSW_NW,"reg_plmn = %s\n", serving_info->reg_plmn);
}
LOGD(GSW_NW,"get cell id/tac/lac/sid/nid\n");
//cell id/tac/lac/sid/nid
mbtk_cell_type_enum cell_type;
list_node_t* cell_list = NULL;
LOGD(GSW_NW,"mbtk_cell_get start\n");
ret = mbtk_cell_get(nw_info_handle, &cell_type, &cell_list);
if(ret != 0 || cell_list == NULL)
{
LOGE(GSW_NW,"mbtk_cell_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
else
{
LOGE(GSW_NW,"mbtk_cell_get end,start to get node\n");
list_first(cell_list);
LOGE(GSW_NW,"list_first end\n");
mbtk_cell_info_t* cell = (mbtk_cell_info_t*) list_next(cell_list);
if(cell)
{
LOGE(GSW_NW,"cell is not null,value2 = %u\n",cell->value2);
switch(cell_type)
{
case MBTK_CELL_TYPE_LTE:
{
LOGE(GSW_NW,"is lte\n");
//LOGE(GSW_NW,"LTE : tac=%x, PCI=%x, dlEuarfcn=%x, ulEuarfcn=%x, band=%x\n", cell->value1, cell->value2, cell->value3, cell->value4, cell->value5);
LOGE(GSW_NW,"LTE : tac=%d, PCI=%d, dlEuarfcn=%d, ulEuarfcn=%d, band=%d\n", cell->value1, cell->value2, cell->value3, cell->value4, cell->value5);
snprintf(serving_info->tac,sizeof(serving_info->tac),"%u",cell->value1);
strcpy(serving_info->lac,"");
snprintf(serving_info->cell_id,sizeof(serving_info->cell_id),"%u",cell->value10);
break;
}
case MBTK_CELL_TYPE_GSM:
{
LOGE(GSW_NW,"is gsm\n");
LOGE(GSW_NW,"GSM : lac=%d, ci=%d, arfcn=%d, bsic=%d\n", cell->value1, cell->value2, cell->value3, cell->value4);
sprintf(serving_info->lac,"%u",cell->value1);
memset(serving_info->tac,0,sizeof(serving_info->tac));
sprintf(serving_info->cell_id,"%u",cell->value2);
break;
}
case MBTK_CELL_TYPE_UMTS:
{
LOGE(GSW_NW,"is wcdma\n");
LOGE(GSW_NW,"UMTS : lac=%d, ci=%d, arfcn=%d\n", cell->value1, cell->value2, cell->value3);
sprintf(serving_info->lac,"%u",cell->value1);
memset(serving_info->tac,0,sizeof(serving_info->tac));
sprintf(serving_info->cell_id,"%u",cell->value2);
break;
}
default:
break;
}
}
else
{
LOGE(GSW_NW,"cell is null\n");
}
}
//not support now
serving_info->sid = 0;
serving_info->nid = 0;
return GSW_HAL_SUCCESS;
}
/**
* @brief get current network type
* @param [out] netype as GSW_NW_RADIO_ACCESS_TECH_E type
* @retval 0: success
* @retval other: fail
*/
int gsw_get_netype(int32_t *netype)
{
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
//regstate
mbtk_net_reg_info_t reg;
ret = mbtk_net_reg_get(nw_info_handle, &reg);
if(ret)
{
LOGE(GSW_NW,"mbtk_net_reg_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
if(reg.data_state == MBTK_NET_REG_STATE_HOME || reg.data_state == MBTK_NET_REG_STATE_ROAMING)
{
*netype = convert_net_mode(reg.type);
}
else
{
*netype = GSW_NETWORK_RADIO_NO_SVC;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief get radio opmode, as open and close airplane mode
* @param [out] op_mode 1 is radio on, 0 is radio off
* @retval 0: success
* @retval other: fail
*/
int gsw_get_opmode(int *op_mode)
{
int tmp_rf = -1;
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
ret = mbtk_get_modem_fun(nw_info_handle, &tmp_rf);
if (ret != 0)
{
LOGE(GSW_NW,"mbtk_get_modem_fun fail\n");
return GSW_HAL_NORMAL_FAIL;
}
if(tmp_rf == LYNQ_AIR_CFUN_MODE_OFF)
{
*op_mode = GSW_OP_MODE_LPM;
}
if(tmp_rf == LYNQ_AIR_PLANE_MODE_ON)
{
*op_mode = GSW_OP_MODE_OFFLINE;
}
if(tmp_rf == LYNQ_AIR_PLANE_MODE_OFF)
{
*op_mode = GSW_OP_MODE_ONLINE;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief set radio opmode, as open and close airplane mode
* @param [in] op_mode 1 is radio on, 0 is radio off
* @retval 0: success
* @retval other: fail
*/
int gsw_set_opmode(int32_t op_mode)
{
mbtk_modem_info_t info;
int rf_mode = -1;
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(op_mode == GSW_OP_MODE_LPM)
{
rf_mode = LYNQ_AIR_CFUN_MODE_OFF;
}
if(op_mode == GSW_OP_MODE_ONLINE)
{
rf_mode = LYNQ_AIR_PLANE_MODE_OFF;
}
if(op_mode == GSW_OP_MODE_OFFLINE)
{
rf_mode = LYNQ_AIR_PLANE_MODE_ON;
}
if (rf_mode != LYNQ_AIR_PLANE_MODE_ON && rf_mode != LYNQ_AIR_PLANE_MODE_OFF && rf_mode != LYNQ_AIR_CFUN_MODE_OFF)
{
LOGE(GSW_NW,"Input mode is error!\n");
return GSW_HAL_NORMAL_FAIL;
}
info.fun = rf_mode;
info.rst = 0;
ret = mbtk_set_modem_fun(nw_info_handle, &info);
if (ret != 0)
{
LOGE(GSW_NW,"gsw_set_opmode fail\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief get network mode preference of mdm search network scale
* @param [out] mode_pref net_work pref mode:
* enum prefer_mode
* @retval 0: success
* @retval other: fail
*/
int gsw_get_mode_preference(int32_t *mode_pref)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
int ret = -1;
mbtk_band_info_t band;
memset(&band, 0, sizeof(mbtk_band_info_t));
ret = mbtk_current_band_get(nw_info_handle, &band);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_current_band_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
*mode_pref = convert_gsw_net_config(band.net_pref);
LOGE(GSW_NW,"band.net_pref = %d\n", *mode_pref);
if(*mode_pref <= 0)
{
LOGE(GSW_NW,"no support mode\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief set network mode preference of mdm search network scale
* @param [in] mode_pref net_work pref mode:
* enum prefer_mode
* @retval 0: success
* @retval other: fail
*/
int gsw_set_mode_preference(int32_t mode_pref)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
int ret = -1;
mbtk_band_info_t band;
memset(&band, 0, sizeof(mbtk_band_info_t));
band.net_pref = convert_mbtk_net_config(mode_pref);
LOGE(GSW_NW,"band.net_pref = %d\n", band.net_pref);
if(band.net_pref < 0)
{
LOGE(GSW_NW,"no support mode\n");
return GSW_HAL_NORMAL_FAIL;
}
ret = mbtk_current_band_set(nw_info_handle, &band);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_current_band_set fail\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief get signal csq value
* @param [out] csq_value csq of signalstrengh 0 - 31, 99 invalid
* @retval 0: success
* @retval other: fail
*/
int gsw_get_sig_info(int32_t *csq_value)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
mbtk_signal_info_t signal;
int ret = mbtk_net_signal_get(nw_info_handle, &signal);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_net_signal_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
LOGD(GSW_NW,"signal.type=%d\n", signal.type);
switch(signal.type)
{
case MBTK_RADIO_TECH_E_UTRAN:
{
LOGD(GSW_NW,"lte rsrp = %d dbm",signal.rsrp-141);
*csq_value = rsrpToLevel(signal.rsrp-141);
break;
}
case MBTK_RADIO_TECH_UTRAN:
case MBTK_RADIO_TECH_UTRAN_HSDPA:
case MBTK_RADIO_TECH_UTRAN_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSDPA_HSUPA:
case MBTK_RADIO_TECH_UTRAN_HSPA:
{
LOGD(GSW_NW,"w rscp = %d dbm",signal.rscp-121);
*csq_value = rscpToLevel(signal.rscp-121);
break;
}
case MBTK_RADIO_TECH_GSM:
case MBTK_RADIO_TECH_GSM_COMPACT:
case MBTK_RADIO_TECH_GSM_EGPRS:
{
LOGD(GSW_NW,"gsm rxlev = %d (0-63)",signal.rxlev);
*csq_value = rxlevToLevel(signal.rxlev);
break;
}
default:
{
LOGE(GSW_NW,"[%s] unknown reg type.[%d]", __func__, signal.type);
return GSW_HAL_NORMAL_FAIL;
}
}
return GSW_HAL_SUCCESS;
}
/**
* @brief set nework power mode, for tcam enter standby or exit standby
* @param [in] mode TRUE(1) when enter standby, FALSE(0) after wake up
* @retval 0: success
* @retval other: fail
*/
int gsw_nw_power_mode = 0;
int gsw_network_set_power_mode(char mode)
{
int ret = -1;
if (nw_init_flag == 0)//nw_info_handle == NULL Don't need
{
return GSW_HAL_NORMAL_FAIL;
}
if(mode != 0 && mode != 1)
{
LOGE(GSW_NW,"Input mode is error!\n");
return GSW_HAL_NORMAL_FAIL;
}
if(mode == 1)
gsw_nw_power_mode = 3;
else
gsw_nw_power_mode = 1;
LOGE(GSW_NW,"mode is %d\n",gsw_nw_power_mode);
ret = mbtk_wakeup_state_set(nw_info_handle, gsw_nw_power_mode);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_wakeup_state_set fail\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief convert rsrp rscp rssi to csq value.
* @param [in] netType signal radio tech 2 means 2G 3 mens 3G,4 is 4G,5 is 5G
* @param [in] sigvalue input signal_strength for different nettype
* rsrp for 4G/5G, rscp for 3G, rssi for 2G
* @retval csq
* @retval other: fail
*/
int gsw_sigInfo_to_csq(int32_t netType, int32_t sigValue)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
switch(netType)
{
case 4:
{
return rsrpToLevel(-sigValue);
}
case 3: //WCDMA
{
return rscpToLevel(-sigValue);
}
case 2: //GSM
{
return sigValue;
}
default:
{
LOGE(GSW_NW,"parameter error\n");
return GSW_HAL_NORMAL_FAIL;
}
}
}
/*
* @brief get mobile operator name
@param [out] nw_operator_name_infos get the long and short operator name info
@retval 0: success
@retval 0: other: fail
*/
int gsw_get_mobile_operator_name(gsw_mobile_operator_name *nw_operator_name_infos)
{
char OperatorFN[128];
char OperatorSH[128];
char temp[12];
mbtk_net_info_t net;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(!mbtk_net_sel_mode_get(nw_info_handle, &net) && net.plmn > 0)
{
LOGE(GSW_NW,"Net : %d, %d, %d\n", net.net_sel_mode, net.net_type, net.plmn);
int i = 0;
while(i < ARRAY_SIZE(lynq_operator_mcc_mnc))
{
if(lynq_operator_mcc_mnc[i].lynq_mcc_mnc == net.plmn)
break;
i++;
}
if(i == ARRAY_SIZE(lynq_operator_mcc_mnc)) // No found mcc&mnc
{
strcpy(OperatorFN, "UNKNOWN");
strcpy(OperatorSH, "UNKNOWN");
}
else
{
strcpy(OperatorFN, lynq_operator_mcc_mnc[i].lynq_operator_l);
strcpy(OperatorSH, lynq_operator_mcc_mnc[i].lynq_operator_s);
sprintf(temp, "%u", (lynq_operator_mcc_mnc[i].lynq_mcc_mnc)/100);
strncpy(nw_operator_name_infos->mcc, temp, strlen(temp));
sprintf(temp, "%u", (lynq_operator_mcc_mnc[i].lynq_mcc_mnc)%100);
strncpy(nw_operator_name_infos->mnc, temp, strlen(temp));
}
memset(nw_operator_name_infos->long_eons,0,128);
memcpy(nw_operator_name_infos->long_eons,OperatorFN,strlen(OperatorFN));
memset(nw_operator_name_infos->short_eons,0,128);
memcpy(nw_operator_name_infos->short_eons,OperatorSH,strlen(OperatorSH));
return GSW_HAL_SUCCESS;
}
else
{
LOGE(GSW_NW,"mbtk_net_sel_mode_get fail\n");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/*
* @brief get current serving cell info
* @param cell_info: [out] struct for current cell info
* include earfcn mcc mnc pci psc tac lac etc.
* @return int: 0 is success, other failed
*/
int gsw_get_cell_info(GSW_NW_CELL_INFO *cell_info)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
printf("nw_sdk_deinit not init\n");
return GSW_HAL_NORMAL_FAIL;
}
list_node_t* cell_list = NULL;
mbtk_cell_type_enum type;
int ret = mbtk_cell_get(nw_info_handle, &type, &cell_list);
if(ret || cell_list == NULL) {
LOGE(GSW_NW,"mbtk_cell_get failed : %d\n", ret);
list_free(cell_list);
return GSW_HAL_NORMAL_FAIL;
} else {
memset(cell_info,0,sizeof(GSW_NW_CELL_INFO));
list_first(cell_list);
mbtk_cell_info_t* cell = (mbtk_cell_info_t*) list_next(cell_list);
if(cell) { // Current server cell.
switch(type)
{
case 0:
{
LOGD(GSW_NW,"GSM : lac=%d, ci=%d, arfcn=%d, bsic=%d\n", cell->value1, cell->value2, cell->value3, cell->value4);
char gsm_temp[12];
cell_info->rat = GSW_NETWORK_RADIO_GSM;
cell_info->mcc_valid = 1;
snprintf(gsm_temp, sizeof(gsm_temp) ,"%X", cell->value5);
strncpy(cell_info->mcc, gsm_temp, sizeof(cell_info->mcc));
cell_info->mnc_valid = 1;
snprintf(gsm_temp, sizeof(gsm_temp) ,"%X", cell->value6);
strncpy(cell_info->mnc, gsm_temp, sizeof(cell_info->mnc));
cell_info->cell_id_valid = 1;
cell_info->cell_id = cell->value2;
cell_info->lac_valid = 1;
cell_info->lac = cell->value1;
cell_info->arfcn_valid = 1;
cell_info->arfcn = cell->value3;
cell_info->rssi=rxlevToLevel(cell->value7);
cell_info->rssi_valid = (cell_info->rssi!=INVALID_AT_SIGNAL_LEVEL);
break;
}
case 1:
{
LOGD(GSW_NW,"UMTS : lac=%d, ci=%d, arfcn=%d\n", cell->value1, cell->value2, cell->value3);
char wcdma_temp[12];
cell_info->rat = GSW_NETWORK_RADIO_UMTS;
cell_info->mcc_valid = 1;
snprintf(wcdma_temp, sizeof(wcdma_temp) ,"%X", cell->value4);
strncpy(cell_info->mcc, wcdma_temp, sizeof(cell_info->mcc));
cell_info->mnc_valid = 1;
snprintf(wcdma_temp, sizeof(wcdma_temp) ,"%X", cell->value5);
strncpy(cell_info->mnc, wcdma_temp, sizeof(cell_info->mnc));
cell_info->lac_valid = 1;
cell_info->lac = cell->value1;
cell_info->cell_id_valid = 1;
cell_info->cell_id = cell->value2;
cell_info->uarfcn_valid = 1;
cell_info->uarfcn = cell->value3;
cell_info->psc_valid = 1;
cell_info->psc = cell->value6;
break;
}
case 2:
{
LOGE(GSW_NW,"LTE : tac=%d, PCI=%d, dlEuarfcn=%d, ulEuarfcn=%d, band=%d\n", cell->value1, cell->value2, cell->value3, cell->value4, cell->value5);
char lte_temp[12];
cell_info->rat = GSW_NETWORK_RADIO_LTE;
cell_info->mcc_valid = 1;
snprintf(lte_temp, sizeof(lte_temp) ,"%X", cell->value6);
strncpy(cell_info->mcc, lte_temp, sizeof(cell_info->mcc));
cell_info->mnc_valid = 1;
snprintf(lte_temp, sizeof(lte_temp) ,"%X", cell->value7);
strncpy(cell_info->mnc, lte_temp, sizeof(cell_info->mnc));
cell_info->tac_valid = 1;
cell_info->tac = cell->value1;
cell_info->pci_valid = 1;
cell_info->pci = cell->value2;
cell_info->earfcn_valid = 1;
cell_info->earfcn = cell->value3;
cell_info->bler_valid = 1;
cell_info->bler = cell->value4;
cell_info->band_valid = 1;
cell_info->band = cell->value5;
cell_info->rssnr = sinr_convert_to_10_times_dB(cell->value11);
cell_info->rssnr_valid=(cell_info->rssnr!=INT_32_MAX);
cell_info->lteMode_valid = 1;
cell_info->lteMode =(!(cell->value12));
cell_info->rsrp = rsrp_convert_to_minus_dBm(cell->value8);
cell_info->rsrp_valid = (cell_info->rsrp!=INT_32_MAX);
cell_info->rsrq = rsrq_convert_to_minus_dB(cell->value9);
cell_info->rsrq_valid = (cell_info->rsrq!=INT_32_MAX);
cell_info->cell_id_valid = 1;
cell_info->cell_id = cell->value10;
break;
}
default:
break;
}
}
int neibor_count = 0;
while ((cell = (mbtk_cell_info_t*) list_next(cell_list)) && neibor_count < 5)
{
switch(type)
{
//GSM
case 0:
{
}
//WCDMA
case 1:
{
LOGE(GSW_NW,"CELL : lac=%d, ci=%d, arfcn=%d\n", cell->value1, cell->value2, cell->value3);
//cell_info->ext_info[neibor_count]->lac = cell->value1;
cell_info->ext_info[neibor_count].cell_id_valid = 1;
cell_info->ext_info[neibor_count].cell_id = cell->value2;
cell_info->ext_info[neibor_count].arfcn_valid = 1;
cell_info->ext_info[neibor_count].arfcn = cell->value3;
cell_info->ext_info[neibor_count].rat = cell_info->rat = GSW_NETWORK_RADIO_UMTS;
neibor_count++;
}
//LTE
case 2:
{
LOGE(GSW_NW,"CELL : phyCellId=%d, euArfcn=%d, rsrp=%d, rsrq=%d\n", cell->value1, cell->value2, cell->value3, cell->value4);
char lte_temp[12] = {0};
cell_info->ext_info[neibor_count].rat = GSW_NETWORK_RADIO_LTE;
cell_info->ext_info[neibor_count].pci = cell->value1;
cell_info->ext_info[neibor_count].pci_valid = 1;
cell_info->ext_info[neibor_count].arfcn = cell->value2;
cell_info->ext_info[neibor_count].arfcn_valid = 1;
cell_info->ext_info[neibor_count].rsrp = rsrp_convert_to_minus_dBm(cell->value3);
cell_info->ext_info[neibor_count].rsrp_valid = (cell_info->ext_info[neibor_count].rsrp!=INT_32_MAX);
cell_info->ext_info[neibor_count].rsrq = rsrq_convert_to_minus_dB(cell->value4);
cell_info->ext_info[neibor_count].rsrq_valid = (cell_info->ext_info[neibor_count].rsrq!=INT_32_MAX);
if(cell->value7!=INT_32_MAX)
{
cell_info->ext_info[neibor_count].cell_id = cell->value5;
cell_info->ext_info[neibor_count].cell_id_valid = 1;
snprintf(lte_temp, sizeof(lte_temp) ,"%X", cell->value6);
strncpy(cell_info->ext_info[neibor_count].mcc, lte_temp, sizeof(cell_info->ext_info[neibor_count].mcc));
snprintf(lte_temp, sizeof(lte_temp) ,"%X", cell->value7);
strncpy(cell_info->ext_info[neibor_count].mnc, lte_temp, sizeof(cell_info->ext_info[neibor_count].mnc));
//value 8 is tac
cell_info->ext_info[neibor_count].band = cell->value9;
cell_info->ext_info[neibor_count].band_valid = 1;
}
neibor_count++;
}
default:
break;
}
}
cell_info->ext_info_len=neibor_count;
}
list_free(cell_list);
return GSW_HAL_SUCCESS;
}
/*
* @brief set modem status event callback
@param [in] handle_ptr callback function address
@retval 0: success
@retval 0: other: fail
*/
int gsw_reg_set_modem_status_event_callback(GSW_NW_ModemStateHandlePtr handle_ptr)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(handle_ptr == NULL)
{
LOGE(GSW_NW,"reg modem state cb, handle_ptr is NULL\n");
}
modem_cb = handle_ptr;
return GSW_HAL_SUCCESS;
}
/*
* @brief get PLMNs from the FPLMN list
* @param [inout] plmn_list:
* @retval 0: success
* @retval other: fail
*/
int gsw_get_forbidden_networks(gsw_nw_plmn_list_t *plmn_list)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
int ret = -1;
char fplmn[256] = {0};
LOGE(GSW_NW,"mbtk_fplmn_get enter\n");
ret = mbtk_fplmn_get(nw_info_handle, fplmn);
LOGE(GSW_NW,"mbtk_fplmn_get exit\n");
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_fplmn_get failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
update_fplmn_list(fplmn);
for(int i = 0; i < fplmn_index; i++)
{
if(strcmp(fplmn_array[i],"FFFFFF") == 0)
{
continue;
}
extract_mcc_mnc(fplmn_array[i], plmn_list->plmn_list[plmn_list->plmn_list_len].mcc, plmn_list->plmn_list[plmn_list->plmn_list_len].mnc);
LOGE(GSW_NW,"mcc = %s, mnc = %s\n", plmn_list->plmn_list[plmn_list->plmn_list_len].mcc, plmn_list->plmn_list[plmn_list->plmn_list_len].mnc);
plmn_list->plmn_list_len++;
}
LOGE(GSW_NW,"fplmn = %s\n", fplmn);
return GSW_HAL_SUCCESS;
}
/*
* @brief add PLMNs from the plmn_list to the FPLMN list
* @param [in] plmn_list:
* @retval 0: success
* @retval other: fail
*/
int gsw_add_forbidden_networks(gsw_nw_plmn_list_t *plmn_list)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(plmn_list->plmn_list_len >= fplmn_max_length)
{
LOGE(GSW_NW,"can't save all the plmn\n");
return GSW_HAL_NORMAL_FAIL;
}
int i = 0;
int index = -1;
for(i = 0; i < plmn_list->plmn_list_len; i++)
{
index = check_index(plmn_list->plmn_list[i].mcc, plmn_list->plmn_list[i].mnc);
if(index == -1)
{
LOGE(GSW_NW,"no this PLMN, add it\n");
if((fplmn_index + plmn_list->plmn_list_len) > fplmn_max_length)
{
LOGE(GSW_NW,"can't save all the plmn\n");
return GSW_HAL_NORMAL_FAIL;
}
else
{
memcpy(fplmn_array[fplmn_index], plmn_list->plmn_list[i].mcc, 3);
memcpy(fplmn_array[fplmn_index] + 3, plmn_list->plmn_list[i].mnc, 2);
fplmn_array[fplmn_index][5] = '\0';
LOGE(GSW_NW,"fplmn_array[%d] = %s\n", fplmn_index, fplmn_array[fplmn_index]);
fplmn_index++;
}
}
else
{
LOGE(GSW_NW,"already have this PLMN, don't add it\n");
}
}
char fplmn_str[256] = {0};
convert_plmn_to_fplmn_str(fplmn_str);
LOGE(GSW_NW,"fplmn_str = %s\n", fplmn_str);
int ret = mbtk_fplmn_set(nw_info_handle, fplmn_str);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_fplmn_set failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
LOGE(GSW_NW,"gsw_add_forbidden_networks exit\n");
return GSW_HAL_SUCCESS;
}
/*
* @brief Remove PLMNs from the plmn_list from the FPLMN list
* @param [in] plmn_list:
* @retval 0: success
* @retval other: fail
*/
int gsw_remove_forbidden_networks(gsw_nw_plmn_list_t *plmn_list)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
printf("nw sdk has not init\n");
return GSW_HAL_NORMAL_FAIL;
}
int i = 0;
int index = -1;
for(i = 0; i < plmn_list->plmn_list_len; i++)
{
index = check_index(plmn_list->plmn_list[i].mcc, plmn_list->plmn_list[i].mnc);
if(index != -1)
{
remove_fplmn(index);
}
else
{
LOGE(GSW_NW,"no this PLMN, can't remove it\n");
}
}
for(i = 0; i < fplmn_index; i++)
{
LOGE(GSW_NW,"fplmn_array[%d] = %s\n", i, fplmn_array[i]);
}
char fplmn_str[256] = {0};
convert_plmn_to_fplmn_str(fplmn_str);
LOGE(GSW_NW,"fplmn_str = %s\n", fplmn_str);
int ret = mbtk_fplmn_set(nw_info_handle, fplmn_str);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_fplmn_set failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
LOGE(GSW_NW,"gsw_remove_forbidden_networks exit\n");
return GSW_HAL_SUCCESS;
}
/*
* @brief clear FPLMN list
* @param
* @retval 0: success
* @retval other: fail
*/
int gsw_clear_forbidden_networks(void)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
char fplmn_str[FPLMN_STRING_LENGTH+1];
memset(fplmn_str, 'F', (6 * fplmn_max_length));
fplmn_str[(6 * fplmn_max_length)] = '\0';
LOGE(GSW_NW,"%s\n", fplmn_str);
int ret = mbtk_fplmn_set(nw_info_handle, fplmn_str);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_fplmn_set failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/*
* @brief get oos config
* @param [in] oos_config
* @retval 0: success
* @retval other: fail
*/
int gsw_oos_config_get(GSW_NW_OOS_CONFIG_INFO_T *pt_info)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(pt_info == NULL)
{
LOGE(GSW_NW,"pt_info is null\n");
return GSW_HAL_NORMAL_FAIL;
}
int ret = -1;
mbtk_oos_info oos_info;
memset(&oos_info, 0x00, sizeof(mbtk_oos_info));
ret = mbtk_oos_get(nw_info_handle, &oos_info);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_oos_get failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
if(oos_info.mode == 0)
{
pt_info->t_min = 0;
pt_info->t_step = 0;
pt_info->t_max = 0;
}
else
{
pt_info->t_min = (int)oos_info.oosPhase[0];
pt_info->t_step = (int)oos_info.oosPhase[1];
pt_info->t_max = (int)oos_info.oosPhase[2];
}
return GSW_HAL_SUCCESS;
}
/*
* @brief set oos config
* @param [in] oos_config
* @retval 0: success
* @retval other: fail
*/
int gsw_oos_config_set(GSW_NW_OOS_CONFIG_INFO_T *pt_info)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(pt_info == NULL)
{
LOGE(GSW_NW,"pt_info is null\n");
return GSW_HAL_NORMAL_FAIL;
}
int ret = -1;
mbtk_oos_info oos_info;
memset(&oos_info, 0x00, sizeof(mbtk_oos_info));
if (pt_info->t_min < 0 || pt_info->t_step < 0 || pt_info->t_max < 0)
{
LOGE(GSW_NW,"gsw_oos_config_set set time < 0 ");
return GSW_HAL_NORMAL_FAIL;
}
else if ((pt_info->t_min > 0 && pt_info->t_min <= 255) && pt_info->t_step == 0 && pt_info->t_max == 0)
{
oos_info.mode = 1;
oos_info.oosPhase[0] = pt_info->t_min;
}
else if ((pt_info->t_min > 0 && pt_info->t_min <= 255) && (pt_info->t_step > 0 && pt_info->t_step <= 255) && pt_info->t_max == 0)
{
oos_info.mode = 1;
oos_info.oosPhase[0] = pt_info->t_min;
oos_info.oosPhase[1] = pt_info->t_step;
}
else if ((pt_info->t_min > 0 && pt_info->t_min <= 255) && (pt_info->t_step > 0 && pt_info->t_step <= 255) && (pt_info->t_max > 0 && pt_info->t_max <= 255))
{
oos_info.mode = 1;
oos_info.oosPhase[0] = pt_info->t_min;
oos_info.oosPhase[1] = pt_info->t_step;
oos_info.oosPhase[2] = pt_info->t_max;
}
else if (pt_info->t_min == 0 && pt_info->t_step == 0 && pt_info->t_max == 0)
{
oos_info.mode = 0;
}
else
{
LOGE(GSW_NW,"gsw_oos_config_set set Format err");
return GSW_HAL_NORMAL_FAIL;
}
ret = mbtk_oos_set(nw_info_handle, &oos_info);
if(ret != 0)
{
LOGE(GSW_NW,"mbtk_oos_set failed : %d\n",ret);
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief get imei function
* @param [in] len imei length,max is 20
* @param [out] imei return imei from this func
* @retval 0: success
* @retval other: fail
*/
int gsw_get_imei(int len, char *imei)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
printf("nw sdk has been deinit\n");
return GSW_HAL_NORMAL_FAIL;
}
if(imei == NULL)
{
LOGE(GSW_NW,"imei is NULL.");
return GSW_HAL_ARG_INVALID;
}
if(len < GSW_IMEI_LENGTH)
{
LOGE(GSW_NW,"imei len is too short,len = %d\n", len);
return GSW_HAL_NORMAL_FAIL;
}
int ret = mbtk_imei_get(nw_info_handle, (void *)imei);
if(ret != MBTK_ERR_OK)
{
LOGE(GSW_NW,"[gsw_nw] mbtk_imei_get fail [err = %d].", ret);
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief reset modem stack only, notice: after use this method, all ril sdk
* need restart by app, means network, sim, sms, data need deinit then init!
* @param
* @retval 0: success
* @retval other: fail
*/
int gsw_reset_modem(void)
{
int ret = -1;
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
printf("nw sdk has been deinit\n");
return GSW_HAL_NORMAL_FAIL;
}
mbtk_modem_info_t info;
info.fun = MBTK_DEV_MODEM_MIN_FUN;
info.rst = 0;
ret = mbtk_set_modem_fun(nw_info_handle, &info);
if(ret)
{
LOGE(GSW_NW,"[gsw_nw] mbtk_set_modem_fun 0 fail [err = %d].", ret);
return GSW_HAL_NORMAL_FAIL;
}
sleep(1);
info.fun = MBTK_DEV_MODEM_FULL_FUN;
ret = mbtk_set_modem_fun(nw_info_handle, &info);
if(ret)
{
LOGE(GSW_NW,"[gsw_nw] mbtk_set_modem_fun 1 fail [err = %d].", ret);
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
int gsw_reg_operating_mode_callback(GSW_NW_AirplaneModeHandlePtr handle_ptr)
{
if (nw_init_flag == 0 || nw_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
void* cb_func;
if(handle_ptr == NULL)
{
LOGE(GSW_NW,"reg airplane mode cb is NULL");
cb_func=NULL;
}
else
{
cb_func=(void*) gsw_operating_mode_event_callback;
}
int ret = mbtk_radio_state_change_cb_reg(nw_info_handle, cb_func);
if (ret != 0)
{
LOGE(GSW_NW,"mbtk_radio_state_change_cb_reg fail, ret is %d",ret);
return GSW_HAL_NORMAL_FAIL;
}
airplane_cb = handle_ptr;
if(airplane_cb !=NULL)
{
int opmode;
ret = gsw_get_opmode(&opmode);
if(ret == 0)
{
airplane_cb(opmode);
}
else
{
LOGE(GSW_NW,"gsw_get_opmode fail, ret is%d", ret);
}
}
return GSW_HAL_SUCCESS;
}
int gsw_get_apn_reserved_id(const char *apn)
{
return 0;
}
int gsw_set_apn_reserved_id(int reserved_id, const char *apn)
{
return 0;
}
int gsw_data_call_clear_session(int linkid, Link_Info_s *LinkInf)
{
return 0;
}
void *gsw_onUnsolicited(void *arg)
{
return 0;
}
int gsw_sdk_init(void)
{
return 0;
}
int gsw_get_modem_state_exp(void)
{
return 0;
}