/*============================================================================ Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. =============================================================================*/ /*=========================================================================== EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. WHEN WHO WHAT, WHERE, WHY ---------- ------------ ---------------------------------------------------- =============================================================================*/ #include #include #include #include "ql_app_feature_config.h" #include "ql_api_osi.h" #include "ql_log.h" #include "ql_api_nw.h" #define QL_NW_LOG_LEVEL QL_LOG_LEVEL_INFO #define QL_NW_DEMO_LOG(msg, ...) QL_LOG(QL_NW_LOG_LEVEL, "ql_nw_demo", msg, ##__VA_ARGS__) ql_task_t nw_task = NULL; static void ql_nw_cause_print(ql_nw_cause_s *cause_info) { struct { ql_nw_cause_type_e type; char *str; }cause[]= { {QUEC_NW_CS_INTERNAL_CAUSE ,"No Cause"}, {QUEC_NW_CS_NETWORK_REJECT ,"GMM Cause "}, {QUEC_NW_PS_LTE_CAUSE ,"ESM Cause "}, {QUEC_NW_PS_LTE_LOCAL_CAUSE ,"EMM Cause "}, {QUEC_NW_PS_GPRS_CAUSE ,"SM Cause "}, }; uint8 size = sizeof(cause)/sizeof(cause[0]); for(int i = 0 ; i < size; i++) { if(cause_info->causeId == cause[i].type) { QL_NW_DEMO_LOG("%s#%d",cause[i].str,cause_info->causeDetail); break; } } } void ql_nw_notify_cb(uint8_t sim_id, unsigned int ind_type, void *ind_msg_buf) { switch(ind_type) { case QUEC_NW_VOICE_REG_STATUS_IND: { ql_nw_common_reg_status_info_s *voice_reg_status=(ql_nw_common_reg_status_info_s *)ind_msg_buf; QL_NW_DEMO_LOG("Sim%d voice: state:%d; lac:0x%X; cid:0x%X; act:%d; ue_stat:%d", sim_id, voice_reg_status->state, voice_reg_status->lac, voice_reg_status->cid, voice_reg_status->act, voice_reg_status->ue_state); break; } case QUEC_NW_DATA_REG_STATUS_IND: { ql_nw_common_reg_status_info_s *data_reg_status=(ql_nw_common_reg_status_info_s *)ind_msg_buf; QL_NW_DEMO_LOG("Sim%d data: state:%d; lac:0x%X; cid:0x%X; act:%d; ue_stat:%d", sim_id, data_reg_status->state, data_reg_status->lac, data_reg_status->cid, data_reg_status->act, data_reg_status->ue_state); break; } #if 0 //If you care about the changes of signal quality, you can change "#if 0" to "#if 1" case QUEC_NW_SIGNAL_QUALITY_IND: { ql_nw_signal_strength_info_s *signal_info=(ql_nw_signal_strength_info_s *)ind_msg_buf; QL_NW_DEMO_LOG("Sim%d signal: rssi:%d, bitErrorRate:%d, rsrp:%d, rsrq:%d", sim_id, signal_info->rssi, signal_info->bitErrorRate, signal_info->rsrp, signal_info->rsrq); break; } #endif case QUEC_NW_NITZ_TIME_UPDATE_IND: { ql_nw_nitz_time_info_s *nitz_info=(ql_nw_nitz_time_info_s *)ind_msg_buf; QL_NW_DEMO_LOG("nitz update: nitz_time:%s, abs_time:%ld", nitz_info->nitz_time, nitz_info->abs_time); break; } case QUEC_NW_CAUSE_IND: { ql_nw_cause_s *cause_info=(ql_nw_cause_s *)ind_msg_buf; QL_NW_DEMO_LOG("cause info: causeId:%d, causeDetail:%d", cause_info->causeId, cause_info->causeDetail); ql_nw_cause_print(cause_info); break; } #ifdef QL_APP_FEATURE_JAMDET case QUEC_NW_JAMMING_DETECT_IND: { uint8_t *jamming_status=(uint8_t *)ind_msg_buf; QL_NW_DEMO_LOG("jamming detect status:%d", *jamming_status); break; } #endif case QUEC_NW_CELL_INFO_IND: { ql_nw_cell_info_s *cell_info = NULL; cell_info = (ql_nw_cell_info_s *)calloc(1,sizeof(ql_nw_cell_info_s)); memcpy(cell_info,(ql_nw_cell_info_s *)ind_msg_buf,sizeof(ql_nw_cell_info_s)); if(cell_info->gsm_info_valid) { for(int cell_index = 0; cell_index < cell_info->gsm_info_num; cell_index++) { QL_NW_DEMO_LOG("Cell_%d [GSM] flag:%d, cid:0x%X, mcc:%d, mnc:%02d, lac:0x%X, arfcn:%d, bsic:%d, rssi:%d", cell_index, cell_info->gsm_info[cell_index].flag, cell_info->gsm_info[cell_index].cid, cell_info->gsm_info[cell_index].mcc, cell_info->gsm_info[cell_index].mnc, cell_info->gsm_info[cell_index].lac, cell_info->gsm_info[cell_index].arfcn, cell_info->gsm_info[cell_index].bsic, cell_info->gsm_info[cell_index].rssi); } } if(cell_info->lte_info_valid) { for(int cell_index = 0; cell_index < cell_info->lte_info_num; cell_index++) { QL_NW_DEMO_LOG("Cell_%d [LTE] flag:%d, cid:0x%X, mcc:%d, mnc:%02d, tac:0x%X, pci:%d, earfcn:%d, rssi:%d", cell_index, cell_info->lte_info[cell_index].flag, cell_info->lte_info[cell_index].cid, cell_info->lte_info[cell_index].mcc, cell_info->lte_info[cell_index].mnc, cell_info->lte_info[cell_index].tac, cell_info->lte_info[cell_index].pci, cell_info->lte_info[cell_index].earfcn, cell_info->lte_info[cell_index].rssi); } } free(cell_info); cell_info = NULL; break; } } } static void nw_app_thread(void * arg) { QlOSStatus err = 0; int ret = 0; uint8_t sim_id = 0; unsigned char cell_index = 0, csq = 0; ql_nw_mode_type_e nw_mode = 0; ql_nw_reg_status_info_s *reg_info = (ql_nw_reg_status_info_s *)calloc(1, sizeof(ql_nw_reg_status_info_s)); ql_nw_signal_strength_info_s *signal_info = (ql_nw_signal_strength_info_s *)calloc(1, sizeof(ql_nw_signal_strength_info_s)); ql_nw_operator_info_s *oper_info = (ql_nw_operator_info_s *)calloc(1, sizeof(ql_nw_operator_info_s)); ql_nw_seclection_info_s *select_info = (ql_nw_seclection_info_s *)calloc(1, sizeof(ql_nw_seclection_info_s)); ql_nw_nitz_time_info_s *nitz_info = (ql_nw_nitz_time_info_s *)calloc(1, sizeof(ql_nw_nitz_time_info_s)); ql_nw_cell_info_s *cell_info = (ql_nw_cell_info_s *)calloc(1, sizeof(ql_nw_cell_info_s)); ql_nw_cause_s cause = {0}; if((NULL == reg_info) || (NULL == signal_info) || (NULL == oper_info) || (NULL == select_info) || (NULL == nitz_info) || (NULL == cell_info)) { QL_NW_DEMO_LOG("calloc fail"); goto exit; } if(ql_nw_register_cb(ql_nw_notify_cb) != QL_NW_SUCCESS) { QL_NW_DEMO_LOG("register network callback fail"); goto exit; } #ifdef QL_APP_FEATURE_JAMDET ql_nw_jamdet_state_e jamdet_status = QL_NO_JAMMING; ret = ql_nw_set_jamdet_mode(sim_id, true); QL_NW_DEMO_LOG("ret=0x%x", ret); #endif ret = ql_nw_get_cell_info_async(sim_id); QL_NW_DEMO_LOG("get cell info,ret=0x%x", ret); while(1) { ql_rtos_task_sleep_ms(10000); QL_NW_DEMO_LOG("====================nw demo start==================="); ret = ql_nw_get_mode(sim_id, &nw_mode); QL_NW_DEMO_LOG("ret=0x%x, nw_mode:%d", ret, nw_mode); ret = ql_nw_get_reg_status(sim_id, reg_info); QL_NW_DEMO_LOG("ret=0x%x", ret); QL_NW_DEMO_LOG("voice: state:%d, lac:0x%X, cid:0x%X, act:%d, ue_stat:%d", reg_info->voice_reg.state, reg_info->voice_reg.lac, reg_info->voice_reg.cid, reg_info->voice_reg.act, reg_info->voice_reg.ue_state); QL_NW_DEMO_LOG("data: state:%d, lac:0x%X, cid:0x%X, act:%d, ue_stat:%d", reg_info->data_reg.state, reg_info->data_reg.lac, reg_info->data_reg.cid, reg_info->data_reg.act, reg_info->data_reg.ue_state); ret = ql_nw_get_csq(sim_id, &csq); QL_NW_DEMO_LOG("ret=0x%x, csq:%d", ret, csq); ret = ql_nw_get_signal_strength(sim_id, signal_info); QL_NW_DEMO_LOG("ret=0x%x, rssi:%d, bitErrorRate:%d, rsrp:%d, rsrq:%d", ret, signal_info->rssi, signal_info->bitErrorRate, signal_info->rsrp, signal_info->rsrq); ret = ql_nw_get_operator_name(sim_id, oper_info); QL_NW_DEMO_LOG("ret=0x%x, long_oper_name:%s, short_oper_name:%s, mcc:%s, mnc:%s", ret, oper_info->long_oper_name, oper_info->short_oper_name, oper_info->mcc, oper_info->mnc); ret = ql_nw_get_selection(sim_id, select_info); QL_NW_DEMO_LOG("ret=0x%x, nw_selection_mode:%d, mcc:%s, mnc:%s, act:%d", ret, select_info->nw_selection_mode, select_info->mcc, select_info->mnc, select_info->act); ret = ql_nw_get_nitz_time_info(nitz_info); QL_NW_DEMO_LOG("ret=0x%x, nitz_time:%s, abs_time:%ld", ret, nitz_info->nitz_time, nitz_info->abs_time); ret = ql_nw_get_cell_info(sim_id, cell_info); QL_NW_DEMO_LOG("ret=0x%x", ret); if(cell_info->gsm_info_valid) { for(cell_index = 0; cell_index < cell_info->gsm_info_num; cell_index++) { QL_NW_DEMO_LOG("Cell_%d [GSM] flag:%d, cid:0x%X, mcc:%d, mnc:%02d, lac:0x%X, arfcn:%d, bsic:%d, rssi:%d", cell_index, cell_info->gsm_info[cell_index].flag, cell_info->gsm_info[cell_index].cid, cell_info->gsm_info[cell_index].mcc, cell_info->gsm_info[cell_index].mnc, cell_info->gsm_info[cell_index].lac, cell_info->gsm_info[cell_index].arfcn, cell_info->gsm_info[cell_index].bsic, cell_info->gsm_info[cell_index].rssi); } } if(cell_info->lte_info_valid) { for(cell_index = 0; cell_index < cell_info->lte_info_num; cell_index++) { QL_NW_DEMO_LOG("Cell_%d [LTE] flag:%d, cid:0x%X, mcc:%d, mnc:%02d, tac:0x%X, pci:%d, earfcn:%d, rssi:%d", cell_index, cell_info->lte_info[cell_index].flag, cell_info->lte_info[cell_index].cid, cell_info->lte_info[cell_index].mcc, cell_info->lte_info[cell_index].mnc, cell_info->lte_info[cell_index].tac, cell_info->lte_info[cell_index].pci, cell_info->lte_info[cell_index].earfcn, cell_info->lte_info[cell_index].rssi); } } #ifdef QL_APP_FEATURE_JAMDET ret = ql_nw_get_jamdet_status(sim_id, &jamdet_status); QL_NW_DEMO_LOG("ret=0x%x, jamdet_status:%d", ret, jamdet_status); #endif ret = ql_nw_get_emm_gmm_cause(&cause); QL_NW_DEMO_LOG("get emm/gmm cause,ret=0x%x",ret); ql_nw_cause_print(&cause); ret = ql_nw_get_esm_sm_cause(&cause); QL_NW_DEMO_LOG("get esm/sm cause,ret=0x%x",ret); ql_nw_cause_print(&cause); QL_NW_DEMO_LOG("====================nw demo end==================="); } exit: if(NULL != reg_info) free(reg_info); if(NULL != signal_info) free(signal_info); if(NULL != oper_info) free(oper_info); if(NULL != select_info) free(select_info); if(NULL != nitz_info) free(nitz_info); if(NULL != cell_info) free(cell_info); err = ql_rtos_task_delete(NULL); if(err != QL_OSI_SUCCESS) { QL_NW_DEMO_LOG("task deleted failed"); } } void ql_nw_app_init(void) { QlOSStatus err = QL_OSI_SUCCESS; err = ql_rtos_task_create(&nw_task, 1024*4, APP_PRIORITY_NORMAL, "QNWDEMO", nw_app_thread, NULL, 5); if(err != QL_OSI_SUCCESS) { QL_NW_DEMO_LOG("created task failed"); } }