| ////////////////////////////////////////////////////////////////////// |
| // INCLUDE FILES FOR MODULE |
| ////////////////////////////////////////////////////////////////////// |
| |
| #include "cm_service.h" |
| #include "dialer_task.h" |
| #include "ml_utils.h" |
| #include <time.h> |
| #ifdef CONFIG_CM_URSP |
| #include "ursp.h" |
| #endif |
| #include "cm_tft.h" |
| #include <math.h> |
| #include <fcntl.h> |
| |
| ////////////////////////////////////////////////////////////////////// |
| // local Prototypes |
| ////////////////////////////////////////////////////////////////////// |
| #if 0 |
| static void tftinfo_parse(struct blob_attr *msg, PacketFilterInfo * tftinfo); |
| #endif |
| int CreatePdp_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| static int GetLinkContext_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| static int SetImageType_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| static int GetImageType_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| static int get_wan_configs(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| int connection_reload(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| int get_apn_info(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| int configs_handler(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| int connection_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| |
| int set_auto_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| int get_auto_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg); |
| |
| |
| int cm_start_thread(); |
| int is_pdp_auto_mode(Mnc_Apn * work_apn, char *apn_type); |
| void cm_log_test(void); |
| void *redial_task(void *argv); |
| |
| void complete_create_pdp_async_cb(struct ubus_request *req, int ret); |
| void complete_destroy_pdp_async_cb(struct ubus_request *req, int ret); |
| void accept_cl_receive_cb(struct uloop_fd *u, unsigned int events); |
| void cm_query_enginfo_timeout_cb(struct uloop_timeout *timeout); |
| |
| void cm_process_cgdcont_msg(fifo_msg_cgdcont_s *msg); |
| void cm_process_auth_msg(fifo_msg_auth_s *msg); |
| void cm_process_act_msg(fifo_msg_act_s *msg); |
| void cm_process_confex_msg(fifo_msg_confex_s *msg); |
| void fifo_read_cb(struct uloop_fd *u, unsigned int events); |
| int cm_fifo_init(void); |
| #ifdef CONFIG_CM_P701 |
| static int cm_get_imsi_mccmnc(char *mccmnc); |
| static int cm_get_zroam_list_ril(); |
| #endif |
| void send_zgdcont_info_2atcmd(Apn_Info *apn_info); |
| void cm_toe_tuple_send(void); |
| static int cm_imsi_special_handle(); |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Macros |
| ////////////////////////////////////////////////////////////////////// |
| #define IMSI_FILE "tmp/imsi_file" |
| |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Global Variables |
| ////////////////////////////////////////////////////////////////////// |
| s_cellular_info g_cell_basic_info; |
| |
| #if 0 |
| static const struct blobmsg_policy cm_tftinfo_policy[] = { |
| [TFT1] = {.name = "direction",.type = BLOBMSG_TYPE_STRING}, |
| [TFT2] = {.name = "directionPresent",.type = BLOBMSG_TYPE_STRING}, |
| [TFT3_MIN] = {.name = "localPortRangeMin",.type = BLOBMSG_TYPE_STRING}, |
| [TFT3_MAX] = {.name = "localPortRangeMax",.type = BLOBMSG_TYPE_STRING}, |
| [TFT4_MIN] = {.name = "RemotePortRangeMin",.type = BLOBMSG_TYPE_STRING}, |
| [TFT4_MAX] = {.name = "RemotePortRangeMax",.type = BLOBMSG_TYPE_STRING}, |
| [TFT5] = {.name = "localPortRangePresent",.type = BLOBMSG_TYPE_STRING}, |
| [TFT6] = {.name = "RemotelPortRangePresent",.type = BLOBMSG_TYPE_STRING}, |
| [TFT7] = {.name = "SecondaryCID",.type = BLOBMSG_TYPE_STRING}, |
| [TFT8] = {.name = "PfIdx",.type = BLOBMSG_TYPE_STRING}, |
| [TFT9] = {.name = "EpIdx",.type = BLOBMSG_TYPE_STRING}, |
| }; |
| #endif |
| |
| //destroyConnection |
| static const struct blobmsg_policy destroy_connection_policy[] = { |
| [CM_ID] = {.name = "id",.type = BLOBMSG_TYPE_INT32}, |
| [CM_MSG1] = {.name = "connectionNum",.type = BLOBMSG_TYPE_INT32}, |
| [CM_MSG2] = {.name = "deleteall",.type = BLOBMSG_TYPE_INT32}, |
| }; |
| |
| //getLinkcontext |
| static const struct blobmsg_policy get_link_context_policy[] = { |
| [CM_ID] = {.name = "id",.type = BLOBMSG_TYPE_INT32}, |
| //[CM_MSG1] = {.name = "msglen", .type = BLOBMSG_TYPE_INT32 }, |
| //[CM_MSG2] = {.name = "connecitonnum", .type = BLOBMSG_TYPE_INT32 }, |
| }; |
| |
| static const struct blobmsg_policy cm_set_image_policy[] = { |
| [CM_MSG1] = {.name = "Image_type",.type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy pdpinfo_table_pol[] = { |
| [CONNECTION_NUM] = { |
| .name = "connection_num", |
| .type = BLOBMSG_TYPE_STRING}, |
| [ENABLE] = { |
| .name = "enable", |
| .type = BLOBMSG_TYPE_STRING}, |
| [PDP_NAME] = { |
| .name = "pdp_name", |
| .type = BLOBMSG_TYPE_STRING}, |
| [IP_TYPE] = { |
| .name = "ip_type", |
| .type = BLOBMSG_TYPE_STRING}, |
| [QCI] = { |
| .name = "qci", |
| .type = BLOBMSG_TYPE_STRING}, |
| [APN] = { |
| .name = "apn", |
| .type = BLOBMSG_TYPE_STRING}, |
| [LTE_APN] = { |
| .name = "lte_apn", |
| .type = BLOBMSG_TYPE_STRING}, |
| [USR_2G3G] = { |
| .name = "usr_2g3g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [PSWD_2G3G] = { |
| .name = "pswd_2g3g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [AUTHTYPE_2G3G] = { |
| .name = "authtype_2g3g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [USR_4G] = { |
| .name = "usr_4g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [PSWD_4G] = { |
| .name = "pswd_4g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [AUTHTYPE_4G] = { |
| .name = "authtype_4g", |
| .type = BLOBMSG_TYPE_STRING}, |
| [TYPE] = { |
| .name = "type", |
| .type = BLOBMSG_TYPE_STRING}, |
| [AUTO_APN] = { |
| .name = "auto_apn", |
| .type = BLOBMSG_TYPE_STRING}, |
| [CONNECT_MODE] = { |
| .name = "connect_mode", |
| .type = BLOBMSG_TYPE_STRING}, |
| [LTE_DEFAULT] = { |
| .name = "lte_default", |
| .type = BLOBMSG_TYPE_STRING}, |
| [DATA_ON_ROAMING] = { |
| .name = "data_on_roaming", |
| .type = BLOBMSG_TYPE_STRING}, |
| [MTU] = { |
| .name = "mtu", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy profile_tabel_pol[] = { |
| [PRO_NAME] = { |
| .name = "profile_name", |
| .type = BLOBMSG_TYPE_STRING}, |
| [PRO_ACTION] = { |
| .name = "action", |
| .type = BLOBMSG_TYPE_STRING}, |
| [CONN_NUM] = { |
| .name = "connection_num", |
| .type = BLOBMSG_TYPE_STRING}, |
| [APN_TYPE] = { |
| .name = "type", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy configs_handler_pol[] = { |
| [PROFILE] = { |
| .name = "profile", |
| .type = BLOBMSG_TYPE_TABLE}, |
| [PDPINFO] = { |
| .name = "pdp_info", |
| .type = BLOBMSG_TYPE_TABLE}, |
| }; |
| |
| static const struct blobmsg_policy connection_switch_pol[] = { |
| [CONNECT_SWITCH] = { |
| .name = "connect_switch", |
| .type = BLOBMSG_TYPE_TABLE}, |
| }; |
| |
| static const struct blobmsg_policy auto_switch_pol[] = { |
| [CONNECT_SWITCH] = { |
| .name = "enable", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy eng_mode_pol[] = { |
| [ENG_MODE] = { |
| .name = "mode", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy connection_switch_table_pol[] = { |
| [PROTO] = { |
| .name = "proto", |
| .type = BLOBMSG_TYPE_STRING}, |
| [DIAL_SWITCH] = { |
| .name = "dial_switch", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy get_apn_info_pol[] = { |
| [APN_TYPE_QUERY] = { |
| .name = "type", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy del_nwactivity_pol[] = { |
| [NWACTIVITY_DEL_INDEX] = { |
| .name = "index", |
| .type = BLOBMSG_TYPE_STRING}, |
| [NWACTIVITY_DEL_FLAG] = { |
| .name = "flag", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy mcc_mnc_pol[] = { |
| [E_MCC] = { |
| .name = "mcc", |
| .type = BLOBMSG_TYPE_STRING}, |
| [E_MNC] = { |
| .name = "mnc", |
| .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static const struct blobmsg_policy cm_get_ccinet_pol[] = { |
| [0] = { |
| .name = "ccinet_cid", |
| .type = BLOBMSG_TYPE_INT32, |
| }, |
| }; |
| |
| static struct uloop_timeout cm_query_enginfo_timeout = { |
| .cb = cm_query_enginfo_timeout_cb, |
| }; |
| |
| #if 0 |
| static struct uloop_timeout cm_toe_tuple_timeout = { |
| .cb = cm_query_enginfo_timeout_cb, |
| }; |
| #endif |
| |
| |
| Apn_Info atcmd_apn_info[16]; |
| int atcmd_apn_state[16]; |
| struct ubus_context *cm_ctx; |
| struct blob_buf cm_b; |
| static struct uci_context *uci_ctx_wan = NULL; |
| |
| static network_activity_array nwactivity_array[MAX_NWACTIVITY_ARRAYNUM]; |
| static int cur_nwarray_index = 0; |
| static int cur_nwarray_num = 0; |
| static struct ml_fifo cm_fifo; |
| static network_duration_s nw_duration[MAX_CID_LIMITATION]; |
| |
| int g_auto_apn_parsed = 0; |
| |
| bool NWLac; |
| bool NWReady = FALSE; |
| bool IsRoaming = FALSE; |
| int NW_status = -1; |
| bool last_NWReady = FALSE; |
| int last_NWstatus = -1; |
| bool last_IsRoaming = FALSE; |
| bool pipe_mode = FALSE; |
| unsigned char RegStatus = 0; |
| bool imsi_changed = FALSE; |
| bool data_on_roaming_configed = FALSE; |
| |
| pthread_t redial_tid; |
| #ifdef CONFIG_CM_URSP |
| pthread_t ursp_server_tid; |
| #endif |
| |
| struct uloop_fd cm_server_fd; |
| struct uloop_fd cm_client_fd; |
| struct uloop_fd cm_accept_fd; |
| |
| struct uloop_fd cm_conn_fd; |
| struct uloop_fd cm_conn_accept_fd; |
| |
| #ifdef CM_CONFIG_TOE |
| struct uloop_fd cm_genl_fd; |
| #endif |
| |
| #ifdef CONFIG_CM_URSP |
| struct uloop_fd cm_ursp_server_fd; |
| struct uloop_fd cm_ursp_server_accept_fd; |
| #endif |
| |
| char gGetelNullApnImsi[4][6] = { |
| "29401", |
| "29702", |
| "22603", |
| "22606" |
| }; |
| |
| #ifdef CONFIG_CM_P701 |
| #define MAX_ZROAM_COUNT 100 |
| RIL_ZROAM g_zroam_list[MAX_ZROAM_COUNT]; |
| #endif |
| |
| #define CM_INVALID_CID 0xFF |
| struct toe_tft_param g_toe_tft_param[MAX_CID_LIMITATION]; |
| |
| extern bool may_need_reload; |
| |
| |
| static void cm_activity_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| } |
| |
| static struct blob_buf cm_notify_blob; |
| static struct ubus_object_type service_object_type; |
| static struct ubus_object network_activity_obj = |
| {.name = "cm.nwactivity",.type = &service_object_type,.subscribe_cb = cm_activity_subscribe_cb }; |
| |
| static bool cm_fail_cause_has_subscriber = false; |
| static void cm_fail_cause_subscribe_cb(struct ubus_context *ctx, |
| struct ubus_object *obj) |
| { |
| UNUSED(ctx); |
| if (obj->has_subscribers && !cm_fail_cause_has_subscriber) { |
| cm_fail_cause_has_subscriber = true; |
| } else if (!obj->has_subscribers && cm_fail_cause_has_subscriber) { |
| cm_fail_cause_has_subscriber = false; |
| } |
| } |
| |
| static struct ubus_object cm_fail_cause_obj = { |
| .name = "cm.fail.cause", |
| .type = &service_object_type, |
| .subscribe_cb = cm_fail_cause_subscribe_cb |
| }; |
| |
| extern Mnc_Apn *g_work_apn; |
| extern Mnc_Apn *IMSI_APN; |
| extern cm_ubus_ctx_id cm_ubus_id; |
| extern CM_Connection_Context *g_CM_Context; |
| |
| static CMSimID gSimID = CM_SIM_0; |
| #ifdef CM_DUAL_SIM_SUPPORT |
| SimSwitchCtx gCmSimSwitchCtx; |
| int CM_DeactiveDataCallAll(void); |
| int CM_SetMasterSimID(CMSimID simID, SwitchSimDoneCb cb); |
| |
| static int SetRadioPowerState(int cfun_value) |
| { |
| return cm_set_cfun(cfun_value); |
| } |
| |
| static int PSServiceOption(int enable) |
| { |
| return cm_set_psdc(enable); |
| } |
| |
| int CM_DeactiveDataCallAll(void) |
| { |
| DisconnectInfo disInfo; |
| |
| disInfo.connectionNum = 0; |
| disInfo.deleteall = 1; |
| CM_DestroyConnection(&disInfo); |
| |
| return 0; |
| } |
| |
| static void CM_UpdateActivedProfile(void) |
| { |
| s_profile_param profile = { 0 }; |
| |
| if (isMasterSim0()) |
| snprintf(profile.profile_name, sizeof(profile.profile_name), "default"); |
| else |
| snprintf(profile.profile_name, sizeof(profile.profile_name), "default_SIM2"); |
| |
| update_actived_profile(&profile, SWITCH_PROFILE); |
| } |
| |
| static int CM_SimSwitchDone(void) |
| { |
| /* need to update SPN name */ |
| g_cell_basic_info.spn_info.spn_exist = false; |
| CM_UpdateActivedProfile(); |
| return get_imsi(true, true); |
| } |
| |
| int CM_SetMasterSimID(CMSimID simID, SwitchSimDoneCb cb) |
| { |
| SimSwitchCtx *ctx = &gCmSimSwitchCtx; |
| int dualSimType = getDualSimType(); |
| int ret = 0; |
| |
| CM_Log(CM_SetMasterSimID1, "%s: simID %d, gSimID %d, state %d", __func__, simID, gSimID, ctx->state); |
| |
| if (gSimID == simID) |
| return -1; |
| |
| if (ctx->state != CM_SIM_SWITCH_INIT) |
| return -1; |
| |
| ctx->currSim = simID; |
| ctx->switchDone = cb; |
| ctx->state = CM_SIM_SWITCH_START; |
| //CM_SimSwitchStateMachine(ctx); |
| |
| CM_DeactiveDataCallAll(); |
| ctx->state = CM_SIM_SWITCH_PRESIM_PDP_DOWN; |
| |
| if (dualSimType == (int)CM_DUAL_SIM_SGIT) |
| SetRadioPowerState(0); |
| else if (dualSimType == (int)CM_DUAL_SIM_SINGLE_STANDBY) |
| SetRadioPowerState(4); |
| else |
| PSServiceOption(0); |
| |
| ctx->state = CM_SIM_SWITCH_PRESIM_PSDC_DOWN; |
| |
| gSimID = ctx->currSim; |
| #if 0 |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| ret = CM_ERR_MEM; |
| goto end; |
| } |
| |
| snprintf(buf, sizeof(buf), "%d", ctx->currSim); |
| ret = uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_SIM_SWITCH_T, SEC_SIM_SWITCH_N, MASTER_SIM, buf); |
| if (!ret) { |
| ret = CM_ERR_INVAL; |
| goto end; |
| } |
| #endif |
| |
| setMasterSimID(gSimID); |
| if (dualSimType == (int)CM_DUAL_SIM_SGIT) |
| SetRadioPowerState(1); |
| else if (dualSimType == (int)CM_DUAL_SIM_SINGLE_STANDBY) |
| SetRadioPowerState(1); |
| else |
| PSServiceOption(1); |
| |
| ctx->state = CM_SIM_SWITCH_CURRSIM_PSDC_UP; |
| |
| ctx->state = CM_SIM_SWITCH_INIT; |
| CM_SimSwitchDone(); |
| |
| return ret; |
| } |
| #endif |
| |
| bool isMasterSim0(void) |
| { |
| return (gSimID == CM_SIM_0) ? TRUE : FALSE; |
| } |
| |
| void setMasterSimID(int simID) |
| { |
| if (simID == CM_SIM_1) |
| setSim2Master(1); |
| else |
| setSim2Master(0); |
| } |
| |
| int getMasterSimID(void) |
| { |
| int sim2_master; |
| |
| sim2_master = isSim2Master(); |
| |
| if (sim2_master) |
| gSimID = CM_SIM_1; |
| else |
| gSimID = CM_SIM_0; |
| |
| CM_Log(getMasterSimID1, "%s: %d", __func__, gSimID); |
| return (int)gSimID; |
| } |
| |
| //TRUE --allow datalink, FALSE-- don't allow datalink |
| bool cm_allow_datalink(void) |
| { |
| bool ret; |
| struct uci_context *local_ctx = NULL; |
| char *value = NULL; |
| Apn_Info * apninfo = NULL; |
| |
| ret = TRUE; |
| |
| #ifdef PIPE_MANUAL_CONNECT |
| if (pipe_mode) |
| { |
| ret = FALSE; |
| goto END; |
| } |
| #endif |
| /*load /etc/config/wan */ |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| value = uci_get_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_PROTO); |
| if (!value) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| if (!strcmp(value, "disabled")) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| value = |
| uci_get_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_DIAL_SWITCH); |
| if (!value) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| if (!strcmp(value, "disabled")) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| apninfo = get_default_apninfo(g_work_apn, NULL); |
| if(apninfo != NULL) { |
| if(apninfo->Extra_params.autoconnect == CM_CONTYPE_MANUAL) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| if(apninfo->Extra_params.data_on_roaming == 0 && check_roamStatus() == TRUE) { |
| ret = FALSE; |
| goto END; |
| } |
| |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| if (g_CM_Context == NULL && apninfo->Extra_params.always_on == 0) { |
| ret = FALSE; |
| goto END; |
| } |
| #endif |
| } |
| else |
| ret = FALSE; |
| |
| END: |
| CM_Log(cm_allow_datalink1, "cm_allow_datalink: ret %d", ret); |
| return ret; |
| } |
| |
| static void cm_nw_duration_set(int cid, int status, int ticks) |
| { |
| network_duration_s *item = NULL; |
| if (cid < 0 || cid >= MAX_CID_LIMITATION) |
| return; |
| |
| item = &nw_duration[cid]; |
| item->cid = cid; |
| item->connect_status = status; |
| if(status == CM_CONNECT_CONSUCCESS) |
| { |
| if (item->connect_ticks == 0) |
| { |
| item->connect_ticks = ticks; |
| CM_Log(cm_nw_duration_set454, "cm_nw_duration_set: [connect]cid %d, connect ticks %d", cid, ticks); |
| } |
| } |
| else if (status == CM_CONNECT_DISCON || status == CM_CONNECT_DEACTIVATED || status == CM_CONNECT_WAIT_PS_ATTACH) |
| { |
| if (ticks >= item->connect_ticks && item->connect_ticks > 0) |
| { |
| item->current_duration_time = ticks - item->connect_ticks; |
| item->duration_time += (ticks - item->connect_ticks); |
| CM_Log(cm_nw_duration_set455, "cm_nw_duration_set: [disconnect]cid %d, current_duration_time %d, duration_time %d", cid, |
| item->current_duration_time, item->duration_time); |
| } |
| item->connect_ticks = 0; |
| } |
| } |
| |
| void nwactivity_arrary_init(void) |
| { |
| int idx = 0; |
| cur_nwarray_index = 0; |
| cur_nwarray_num = 0; |
| memset(&nwactivity_array, 0, sizeof(network_activity_array)*MAX_NWACTIVITY_ARRAYNUM); |
| |
| //indicate unused |
| for(idx = 0; idx < MAX_NWACTIVITY_ARRAYNUM; idx++) |
| nwactivity_array[idx].index = -1; |
| } |
| |
| int cm_find_nwarrayindex(int cid) |
| { |
| int index; |
| |
| for(index = cur_nwarray_index - 1; index >= 0; index--) { |
| if(nwactivity_array[index].cid == cid) |
| return index; |
| } |
| |
| if((cur_nwarray_num == MAX_NWACTIVITY_ARRAYNUM) && (cur_nwarray_index != (MAX_NWACTIVITY_ARRAYNUM - 1))) { |
| for(index = MAX_NWACTIVITY_ARRAYNUM - 1; index != cur_nwarray_index; index--) { |
| if(nwactivity_array[index].cid == cid) |
| return index; |
| } |
| } |
| |
| return -1; |
| } |
| |
| void cm_nwactivity_notify_complete_cb(struct ubus_request *req, int ret) |
| { |
| UNUSED(ret); |
| CM_Log(cm_nwactivity_notify_complete_cb, "cm_nwactivity_notify_complete_cb(ret=%d)", ret); |
| |
| if (req) { |
| free(req); |
| req = NULL; |
| } |
| } |
| |
| static void cm_get_activity_duration(int cid, network_activity_msg *activity) |
| { |
| network_duration_s *item = NULL; |
| |
| if (cid < 0 || cid >= MAX_CID_LIMITATION || activity == NULL) |
| return; |
| |
| item = &nw_duration[cid]; |
| if (item->connect_ticks > 0) |
| { |
| if (activity->notify_ticks >= item->connect_ticks) |
| activity->current_duration_time = activity->notify_ticks - item->connect_ticks; |
| |
| activity->duration_time = activity->current_duration_time + item->duration_time; |
| } |
| else |
| { |
| activity->current_duration_time = item->current_duration_time; |
| activity->duration_time = item->duration_time; |
| } |
| CM_Log(cm_get_activity_duration531, "cm_get_activity_duration, cid %d, current_duration %d, duration %d", cid, activity->current_duration_time, activity->duration_time); |
| return; |
| } |
| |
| int cm_nwactivity_notify(network_activity_msg * msg, bool sync) |
| { |
| int ret; |
| struct ubus_notify_request * nreq = NULL; |
| if (msg == NULL) { |
| return -1; |
| } |
| |
| blob_buf_init(&cm_notify_blob, 0); |
| |
| blobmsg_add_u32(&cm_notify_blob, "connectstatus", msg->connect_status); |
| blobmsg_add_u32(&cm_notify_blob, "cid", msg->cid); |
| blobmsg_add_u32(&cm_notify_blob, "iptype", msg->iptype); |
| blobmsg_add_u32(&cm_notify_blob, "current_duration_time", msg->current_duration_time); |
| blobmsg_add_u32(&cm_notify_blob, "duration_time", msg->duration_time); |
| blobmsg_add_u32(&cm_notify_blob, "notify_ticks", msg->notify_ticks); |
| CM_Log(cm_nwactivity_notify1, "cm_nwactivity_notify: connect status %d, iptype %d, cid %d, current_duration_time %d, duration_time %d, notify_ticks %d, sync %d", |
| msg->connect_status, msg->iptype, msg->cid, msg->current_duration_time, msg->duration_time, msg->notify_ticks, sync); |
| |
| if (sync) |
| { |
| ret = ubus_notify(cm_ctx,&network_activity_obj, network_activity_obj.name, cm_notify_blob.head, 5000); |
| if (ret) |
| { |
| CM_Log(cm_nwactivity_notify2, "cm_nwactivity_notify: ubus_notify failed [err=%s]\n", ubus_strerror(ret)); |
| } |
| } |
| else |
| { |
| nreq = (struct ubus_notify_request*)malloc(sizeof(struct ubus_notify_request)); |
| ret = ubus_notify_async(cm_ctx,&network_activity_obj, network_activity_obj.name, cm_notify_blob.head, nreq); |
| |
| if(ret != 0) { |
| free(nreq); |
| return ret; |
| }else { |
| nreq->complete_cb = (void *)&cm_nwactivity_notify_complete_cb; |
| //ubus_complete_request(cm_ctx, &(nreq->req), 5000); |
| |
| ubus_complete_request_async(cm_ctx, &(nreq->req)) ; |
| } |
| } |
| return ret; |
| } |
| |
| void cm_record_nwactivity(CM_Connection_Context * coninfo, bool sync) |
| { |
| int index, cid; |
| network_activity_msg nwmsg={0}; |
| time_t cur_tim; |
| |
| if(coninfo->pdpinfo->PDP_Type == 1) |
| cid = coninfo->pdpinfo->primaryCid; |
| else |
| cid = coninfo->pdpinfo->secondaryCid; |
| |
| time(&cur_tim); |
| cm_nw_duration_set(cid - 1, coninfo->connectStatus, cur_tim); |
| |
| //notify the network activity |
| nwmsg.connect_status = coninfo->connectStatus; |
| nwmsg.cid = cid; |
| nwmsg.iptype = coninfo->pdpinfo->IP_Type; |
| nwmsg.notify_ticks = cur_tim; |
| |
| CM_Log(cm_record_nwactivity, "cm_record_nwactivity, connect status %d, cid %d, iptype %d", nwmsg.connect_status, nwmsg.cid, nwmsg.iptype); |
| cm_get_activity_duration(cid - 1, &nwmsg); |
| cm_nwactivity_notify(&nwmsg, sync); |
| |
| if(coninfo->connectStatus == CM_CONNECT_CONSUCCESS) { |
| CM_Log(cm_record_nwactivity1, "cm_record_nwactivity, [connected] cur_nwarray_index:%d, connect_ticks %d",cur_nwarray_index, cur_tim); |
| strcpy(nwactivity_array[cur_nwarray_index].PDP_name, coninfo->pdpinfo->PDP_name); |
| strncpy(nwactivity_array[cur_nwarray_index].start_tim, ctime(&cur_tim), sizeof(nwactivity_array[cur_nwarray_index].start_tim) - 1); |
| nwactivity_array[cur_nwarray_index].connect_ticks = cur_tim; |
| |
| //nwactivity_array[cur_nwarray_index].end_tim = 0; |
| nwactivity_array[cur_nwarray_index].cid = cid; |
| nwactivity_array[cur_nwarray_index].index = cur_nwarray_index; |
| |
| if(coninfo->pdpinfo->PDP_Type == 1) { |
| nwactivity_array[cur_nwarray_index].iptype = coninfo->pdpinfo->IP_Type; |
| |
| if(coninfo->ipv4info != NULL) |
| nwactivity_array[cur_nwarray_index].ipv4addr = coninfo->ipv4info->IPAddr; |
| if(coninfo->ipv6info != NULL) { |
| nwactivity_array[cur_nwarray_index].ipv6addr[0] = coninfo->ipv6info->IPV6Addr[0]; |
| nwactivity_array[cur_nwarray_index].ipv6addr[1] = coninfo->ipv6info->IPV6Addr[1]; |
| nwactivity_array[cur_nwarray_index].ipv6addr[2] = coninfo->ipv6info->IPV6Addr[2]; |
| nwactivity_array[cur_nwarray_index].ipv6addr[3] = coninfo->ipv6info->IPV6Addr[3]; |
| } |
| |
| } |
| |
| if(cur_nwarray_num < MAX_NWACTIVITY_ARRAYNUM) |
| cur_nwarray_num ++; |
| |
| if(cur_nwarray_index < MAX_NWACTIVITY_ARRAYNUM - 1) |
| cur_nwarray_index ++; |
| else |
| cur_nwarray_index = 0; |
| |
| }else if(coninfo->connectStatus == CM_CONNECT_DISCON || coninfo->connectStatus == CM_CONNECT_DEACTIVATED || coninfo->connectStatus == CM_CONNECT_WAIT_PS_ATTACH) { |
| index = cm_find_nwarrayindex(cid); |
| CM_Log(cm_record_nwactivity2, "cm_record_nwactivity: [disconnected] index:%d", index); |
| |
| if(index != -1) |
| { |
| strncpy(nwactivity_array[index].end_tim, ctime(&cur_tim), sizeof(nwactivity_array[cur_nwarray_index].end_tim) - 1); |
| if (cur_tim >= nwactivity_array[index].connect_ticks && nwactivity_array[index].connect_ticks > 0) |
| { |
| nwactivity_array[index].current_duration_time = cur_tim - nwactivity_array[index].connect_ticks; |
| nwactivity_array[index].duration_time += (cur_tim - nwactivity_array[index].connect_ticks); |
| CM_Log(cm_record_nwactivity575, "cm_record_nwactivity: index %d, current_duration_time %d, duration_time %d", index, |
| nwactivity_array[index].current_duration_time, nwactivity_array[index].duration_time); |
| } |
| nwactivity_array[cur_nwarray_index].connect_ticks = 0; |
| } |
| } |
| } |
| |
| static void cm_dial_failure_cause_notify_complete(struct ubus_notify_request *req, int idx, int ret) |
| { |
| UNUSED(idx); |
| UNUSED(ret); |
| CM_Log(cm_dial_failure_cause_notify_complete, "cm_dial_failure_cause_notify_complete %d", ret); |
| |
| if (req) { |
| free(req); |
| req = NULL; |
| } |
| } |
| |
| static int cm_dial_failure_cause_notify(s_cause_msg *msg) |
| { |
| int ret; |
| struct ubus_notify_request * nreq = NULL; |
| |
| if (msg == NULL || !cm_fail_cause_has_subscriber) { |
| return -1; |
| } |
| |
| blob_buf_init(&cm_notify_blob, 0); |
| |
| blobmsg_add_u32(&cm_notify_blob, "connect_num", msg->connect_num); |
| blobmsg_add_u32(&cm_notify_blob, "cause", msg->cause); |
| CM_Log(cm_dial_failure_cause_notify, "cm_dial_failure_cause_notify: connect num %d, cause %d", msg->connect_num, msg->cause); |
| |
| nreq = (struct ubus_notify_request*)malloc(sizeof(struct ubus_notify_request)); |
| ret = ubus_notify_async(cm_ctx, &cm_fail_cause_obj, cm_fail_cause_obj.name, cm_notify_blob.head, nreq); |
| |
| if (ret != 0) { |
| free(nreq); |
| return ret; |
| } else { |
| nreq->complete_cb = cm_dial_failure_cause_notify_complete; |
| //ubus_complete_request(cm_ctx, &(nreq->req), 5000); |
| ubus_complete_request_async(cm_ctx, &(nreq->req)); |
| } |
| return ret; |
| } |
| |
| void cm_notify_dial_failure(int connect_num, int status, int cause) |
| { |
| s_cause_msg cause_ind_msg = { 0 }; |
| |
| cause_ind_msg.connect_num = connect_num; |
| |
| if (status == -2) |
| cause_ind_msg.cause = PDP_FAIL_NO_CCINET; |
| else if (status == -3) |
| cause_ind_msg.cause = PDP_FAIL_DHCP_SERVER_ERR_PIPE; |
| else |
| cause_ind_msg.cause = cause; |
| |
| cm_dial_failure_cause_notify(&cause_ind_msg); |
| } |
| |
| void spn_info_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno = 0; |
| void *response_data = NULL; |
| int response_len = 0; |
| char *spn_data; |
| char tmp[64] = { 0 }; |
| char temp[3] = { 0 }; |
| char *p, *endptr = NULL; |
| char ascii_char; |
| int i; |
| int ret = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| ret = 1; |
| goto end; |
| } |
| |
| if (response_data && (response_len > 0)) { |
| |
| if (rilerrno != RIL_E_SUCCESS) { |
| g_cell_basic_info.status = rilerrno; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 2; |
| goto end; |
| } |
| spn_data = (char *)response_data; |
| if (sscanf(spn_data, "%*[^,],%*[^,],%s", tmp) != 1) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| g_cell_basic_info.status = rilerrno; |
| ret = 3; |
| goto end; |
| } |
| memcpy(temp, tmp, 2); |
| temp[2] = '\0'; |
| g_cell_basic_info.spn_info.dis_cond = atoi(temp); |
| p = tmp + 2; |
| memset(g_cell_basic_info.spn_info.spn_name, 0, MAX_SIM_INFO_STR_LEN); |
| for (i = 0; i < 16; i++) { |
| memcpy(temp, p, 2); |
| temp[2] = '\0'; |
| if (strcmp(temp, "FF") == 0) { |
| break; |
| } |
| g_cell_basic_info.spn_info.spn_exist = 1; |
| ascii_char = (char)strtoul(temp, &endptr, 16); |
| g_cell_basic_info.spn_info.spn_name[i] = ascii_char; |
| CM_Log(spn_info_request_cb3, "spn_info_request_cb: spn ascii char %d\n", ascii_char); |
| p += 2; |
| } |
| g_cell_basic_info.status = 0; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } else { |
| if (response_data) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| g_cell_basic_info.status = rilerrno; |
| } |
| end: |
| CM_Log(spn_info_request_cb1, "spn_info_request_cb: ret %d, rilerrno %d\n", ret, rilerrno); |
| } |
| |
| void rssi_info_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno = 0; |
| void *response_data = NULL; |
| int response_len = 0; |
| s_signal_quality *rssi_data; |
| int ret = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| ret = 1; |
| goto end; |
| } |
| |
| if (response_data && (response_len > 0)) { |
| |
| if (rilerrno != RIL_E_SUCCESS) { |
| g_cell_basic_info.status = rilerrno; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 2; |
| goto end; |
| } |
| rssi_data = (s_signal_quality *) response_data; |
| if (g_cell_basic_info.sys_mode == E_2G_3G) { |
| g_cell_basic_info.rssi = rssi_data->GW_SignalStrength.signalStrength; |
| } else if (g_cell_basic_info.sys_mode == E_LTE ||g_cell_basic_info.sys_mode == E_LTEP) { |
| //g_cell_basic_info.rssi = rssi_data->LTE_SignalStrength.signalStrength; |
| if ( rssi_data->LTE_SignalStrength.rsrp >= 44 && rssi_data->LTE_SignalStrength.rsrp <= 141) |
| g_cell_basic_info.rssi =141 - rssi_data->LTE_SignalStrength.rsrp; |
| else |
| g_cell_basic_info.rssi = 0; |
| } |
| |
| g_cell_basic_info.status = 0; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } else { |
| if (response_data) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| g_cell_basic_info.status = rilerrno; |
| } |
| end: |
| CM_Log(rssi_info_request_cb1, "rssi_info_request_cb: ret %d rilerrno %d\n", ret, rilerrno); |
| } |
| |
| static void ims_reg_state_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| int *state; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| |
| if (response_data && (response_len > 0)) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| state = (int *) response_data; |
| g_cell_basic_info.ims_state = *state; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } else { |
| if (response_data) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| } |
| } |
| |
| static void get_etiflag_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| char *response_data = NULL; |
| int response_len = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, (void *)&response_data, &response_len)) { |
| return; |
| } |
| |
| if (response_data && (response_len > 0)) { |
| |
| if (rilerrno != RIL_E_SUCCESS) { |
| g_cell_basic_info.etiflag = -1; |
| goto end; |
| } |
| |
| if (requestid != RIL_REQUEST_GET_ETIFLAG) |
| { |
| g_cell_basic_info.etiflag = -1; |
| goto end; |
| } |
| |
| g_cell_basic_info.etiflag = *(int *)response_data; |
| CM_Log_E(get_etiflag_request_cb2, "%s: etiflag %d\n", __func__, g_cell_basic_info.etiflag); |
| } |
| |
| end: |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| void save_imsi_into_tmp_file(char *imsi) |
| { |
| int fd = 0, size = 0; |
| char buf[MAX_SIM_INFO_STR_LEN] = { 0 }; |
| |
| if (!imsi || !strlen(imsi)) { |
| CM_Log_E(save_imsi_into_tmp_file, "NO IMSI"); |
| return; |
| } |
| |
| fd = open(IMSI_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR|S_IWUSR); |
| |
| if (fd < 0) { |
| return; |
| } |
| size = strlen(imsi) + 1; |
| strncpy(buf, imsi, MAX_SIM_INFO_STR_LEN - 1); |
| size = write(fd, buf, size); |
| |
| close(fd); |
| return; |
| } |
| |
| char *cm_get_cellular_imsi(void) |
| { |
| if (strlen(g_cell_basic_info.IMSI) > 0) |
| return g_cell_basic_info.IMSI; |
| else |
| return NULL; |
| } |
| |
| void sim_info_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno = 0; |
| char *response_data = NULL; |
| int response_len = 0; |
| int ret = 0; |
| int *req_priv = 0; |
| int switch_sim = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, (void *)&response_data, &response_len)) { |
| ret = 1; |
| goto end; |
| } |
| if (response_data && (response_len > 0)) { |
| |
| if (rilerrno != RIL_E_SUCCESS) { |
| g_cell_basic_info.status = rilerrno; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 2; |
| goto end; |
| } |
| |
| if (response_len >= MAX_SIM_INFO_STR_LEN) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| g_cell_basic_info.status = -1; |
| ret = 3; |
| goto end; |
| } |
| if (requestid == RIL_REQUEST_GET_IMEI) { |
| memset(g_cell_basic_info.IMEI, 0, MAX_SIM_INFO_STR_LEN); |
| memcpy(g_cell_basic_info.IMEI, response_data, response_len); |
| } else if (requestid == RIL_REQUEST_GET_IMEISV) { |
| memset(g_cell_basic_info.IMEI_SV, 0, MAX_SIM_INFO_STR_LEN); |
| memcpy(g_cell_basic_info.IMEI_SV, response_data, response_len); |
| } else if (requestid == RIL_REQUEST_GET_IMSI) { |
| imsi_changed = FALSE; |
| if (strlen(g_cell_basic_info.IMSI)) { |
| CM_Log_E(sim_info_request_cb5, "sim_info_request_cb: last imsi %s, new imsi[%d] %s\n", g_cell_basic_info.IMSI, response_len, response_data); |
| if (strncmp(g_cell_basic_info.IMSI, response_data, sizeof(g_cell_basic_info.IMSI) - 1)) { |
| imsi_changed = TRUE; |
| } |
| } |
| |
| memset(g_cell_basic_info.IMSI, 0, MAX_SIM_INFO_STR_LEN); |
| memcpy(g_cell_basic_info.IMSI, response_data, response_len); |
| save_imsi_into_tmp_file(g_cell_basic_info.IMSI); |
| |
| req_priv = req->priv; |
| if (req_priv && *req_priv != RIL_REQUEST_GET_IMSI) |
| { |
| switch_sim = *req_priv; |
| free(req_priv); |
| } |
| |
| if (imsi_changed) |
| { |
| if (is_ctcc_sim(g_cell_basic_info.IMSI) && switch_sim == 0) |
| { |
| cm_save_default_apn(NULL, NULL); |
| CM_Clear_ETIFlag(false); |
| } |
| reinit_apn_list(); |
| } |
| } |
| g_cell_basic_info.status = 0; |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } else { |
| if (response_data) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| ret = 4; |
| g_cell_basic_info.status = -1; |
| } |
| end: |
| CM_Log(sim_info_request_cb1, "sim_info_request_cb: ret %d rilerrno %d\n", ret, rilerrno); |
| } |
| |
| void plmn_operator_request_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| rilutilstrings *response = NULL; |
| int i = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_OPERATOR) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| response = (rilutilstrings *) response_data; |
| i = 0; |
| |
| for (i = 0; i < response->num; i++) { |
| CM_Log(plmn_operator_request_cb3, "plmn_operator_request_cb: response->str[%d] %s\n", i, response->str[i] ? response->str[i] : "NULL"); |
| } |
| |
| if (response->num > 1) { |
| if (response->str[1] && strlen(response->str[1]) > 0) |
| strncpy(g_cell_basic_info.ons_info.ons, response->str[1], MAX_SIM_INFO_STR_LEN - 1); // short ons |
| else if (response->str[0]) |
| strncpy(g_cell_basic_info.ons_info.ons, response->str[0], MAX_SIM_INFO_STR_LEN - 1); // long ons |
| } |
| |
| if (response->num > 2 && response->str[2]) |
| strncpy(g_cell_basic_info.ons_info.plmn, response->str[2], 6); |
| |
| // should free buffer this point |
| for (i = 0; i < response->num; i++) { |
| if (response->str[i]) { |
| free(response->str[i]); |
| response->str[i] = NULL; |
| } |
| } |
| if (response->str) { |
| free(response->str); |
| response->str = NULL; |
| } |
| free(response_data); |
| CM_Log(plmn_operator_request_cb989, "plmn_operator_request_cb: done\n"); |
| } |
| } |
| |
| int cm_get_nw_status_cache() |
| { |
| return NW_status; |
| } |
| |
| void cm_reset_nw_last_param(void) |
| { |
| last_NWReady = FALSE; |
| last_NWstatus = 0; |
| last_IsRoaming = FALSE; |
| } |
| |
| void CheckDataCallRegisterStatus_IndCall_data_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| UNUSED(req); |
| unsigned int requestid; |
| unsigned int rilerrno = 0; |
| void *response_data = NULL; |
| int response_len = 0; |
| |
| int lac = 0; |
| int cid = -1; |
| int gprsState = 0; |
| int RejectCause = 0; |
| rilutilstrings *response = NULL; |
| int i = 0; |
| bool need_redial = TRUE; |
| may_need_reload = FALSE; |
| int ret = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| ret = 1; |
| goto end; |
| } |
| |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 2; |
| goto end; |
| } |
| |
| if (requestid != RIL_REQUEST_DATA_REGISTRATION_STATE) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 3; |
| goto end; |
| } |
| |
| response = (rilutilstrings *) response_data; |
| i = 0; |
| |
| if (response->num > i) |
| RegStatus = atoi(response->str[i++]); |
| if (response->num > i) |
| lac = atoi(response->str[i++]); |
| if (response->num > i) |
| cid = atoi(response->str[i++]); |
| if (response->num > i) |
| gprsState = atoi(response->str[i++]); |
| if (response->num > i) |
| RejectCause = atoi(response->str[i++]); |
| |
| // should free buffer this point |
| for (i = 0; i < response->num; i++) { |
| if (response->str[i]) { |
| free(response->str[i]); |
| response->str[i] = NULL; |
| } |
| } |
| if (response->str) { |
| free(response->str); |
| response->str = NULL; |
| } |
| free(response); |
| } else { |
| ret = 4; |
| goto end; |
| } |
| |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb5, "IndRegStatus_data_cb: RegStatus is %d, lac is %d, cid is %d, gprsState is %d, RejectCause is %d\n", |
| RegStatus, lac, cid, gprsState, RejectCause); |
| |
| if (lac != 0 && lac != NWLac) |
| { |
| NWLac = lac; |
| stop_2hours_redial_timer(); |
| } |
| |
| if (RegStatus == 5) |
| IsRoaming = TRUE; |
| else |
| IsRoaming = FALSE; |
| |
| if ((RegStatus == 1) || (RegStatus == 5)) |
| NWReady = TRUE; |
| else |
| NWReady = FALSE; |
| |
| if (last_IsRoaming != IsRoaming) { |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb6, "IndRegStatus_data_cb: roam changed %d->%d", last_IsRoaming, IsRoaming); |
| if (last_IsRoaming == TRUE && IsRoaming == FALSE) { |
| send_redialmsg_to_redialthread(-1, REDIAL_ROAMCHANGE); |
| } else { |
| CM_Handle_ChangetoRoam(); |
| } |
| |
| last_IsRoaming = IsRoaming; |
| |
| /*If roaming status changed, no need to redial accordding to network status, just update the network status*/ |
| need_redial = FALSE; |
| } |
| |
| g_cell_basic_info.roaming = IsRoaming; |
| g_cell_basic_info.data_mode = gprsState; |
| |
| if ((RegStatus != 1) && (RegStatus != 5)) { |
| NW_status = CM_NW_STATUS_NOT_REGISTERED; //not registered |
| g_cell_basic_info.sys_mode = E_NO_SERVICE; |
| } else if (gprsState == RADIO_TECH_LTE || gprsState == RADIO_TECH_LTEP) { |
| NW_status = CM_NW_STATUS_LTE; //registered on 4G |
| g_cell_basic_info.sys_mode = E_LTE; |
| if (gprsState == RADIO_TECH_LTEP) |
| g_cell_basic_info.sys_mode = E_LTEP; |
| } else if ((gprsState == RADIO_TECH_GPRS) || (gprsState == RADIO_TECH_EDGE) || (gprsState == RADIO_TECH_GSM) |
| || (gprsState == RADIO_TECH_UMTS) || (gprsState == RADIO_TECH_HSDPA) |
| || (gprsState == RADIO_TECH_HSUPA) || (gprsState == RADIO_TECH_HSPA)) { |
| NW_status = CM_NW_STATUS_23G;//registered on 2/3G |
| g_cell_basic_info.sys_mode = E_2G_3G; |
| } else if (gprsState == RADIO_TECH_EUTRAN_TO_5GCN ||gprsState == RADIO_TECH_NR_TO_5GCN || |
| gprsState == RADIO_TECH_NGRAN || gprsState == RADIO_TECH_EUTRAN_NR_DUAL_LINK) { |
| NW_status = CM_NW_STATUS_5G;//registered 5G |
| g_cell_basic_info.sys_mode = E_5G; |
| } |
| else |
| NW_status = -1; |
| |
| if (last_NWstatus != NW_status) { |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb9, "IndRegStatus_data_cb: NWstatus changed %d -> %d {0: 2/3G, 1: LTE, 2: 5G, 3: Not registered, -1: Init}", last_NWstatus, NW_status); |
| if (last_NWstatus == 0 && need_redial == TRUE && |
| (NW_status == CM_NW_STATUS_NOT_REGISTERED || NW_status == CM_NW_STATUS_LTE || NW_status == CM_NW_STATUS_5G)) { |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb10, "IndCall_data_cb, network status change from 2/3g to LTE/5G or not registered"); |
| send_redialmsg_to_redialthread(-1, REDIAL_NWCHANGE); |
| } |
| last_NWstatus = NW_status; |
| } |
| |
| if (last_NWReady != NWReady) { |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb11, "IndRegStatus_data_cb: NWReady changed %d-> %d", last_NWReady, NWReady); |
| if (last_NWReady == FALSE && NWReady == TRUE && need_redial == TRUE) { |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb12, "IndRegStatus_data_cb, network registered, send redial here!"); |
| stop_2hours_redial_timer(); |
| send_redialmsg_to_redialthread(-1, REDIAL_NWCHANGE); |
| } |
| last_NWReady = NWReady; |
| } |
| end: |
| if (ret != 0 || rilerrno != 0) |
| CM_Log(CheckDataCallRegisterStatus_IndCall_data_cb13, "IndRegStatus_data_cb: ret %d, rilerrno %d", ret, rilerrno); |
| } |
| |
| void CheckDataCallRegisterStatus_data_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| UNUSED(req); |
| unsigned int requestid; |
| unsigned int rilerrno = 0; |
| void *response_data = NULL; |
| int response_len = 0; |
| |
| int lac = 0; |
| int cid = -1; |
| int gprsState = 0; |
| int RejectCause = 0; |
| rilutilstrings *response = NULL; |
| int i = 0; |
| int ret = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| ret = 1; |
| goto end; |
| } |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 2; |
| goto end; |
| } |
| if (requestid != RIL_REQUEST_DATA_REGISTRATION_STATE_NOCACHE) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| ret = 3; |
| goto end; |
| } |
| response = (rilutilstrings *) response_data; |
| CM_Log_E(CheckDataCallRegisterStatus_data_cb12, "CheckDataCallRegisterStatus_data_cb: response->num %d \n", response->num ); |
| i = 0; |
| |
| if (response->num > i && response->str[i]) |
| RegStatus = atoi(response->str[i++]); |
| |
| if (response->num > i && response->str[i]) |
| lac = atoi(response->str[i++]); |
| |
| if (response->num > i && response->str[i]) |
| cid = atoi(response->str[i++]); |
| |
| if (response->num > i && response->str[i]) |
| gprsState = atoi(response->str[i++]); |
| |
| if (response->num > i && response->str[i]) |
| RejectCause = atoi(response->str[i++]); |
| |
| // should free buffer this point |
| for (i = 0; i < response->num; i++) { |
| if (response->str[i]) { |
| free(response->str[i]); |
| response->str[i] = NULL; |
| } |
| } |
| |
| if (response->str) { |
| free(response->str); |
| response->str = NULL; |
| } |
| |
| free(response); |
| } else { |
| ret = 4; |
| goto end; |
| } |
| |
| CM_Log(CheckDataCallRegisterStatus_data_cb5, "data_cb: RegStatus is %d, lac is %d, cid is %d, gprsState is %d, RejectCause is %d\n", |
| RegStatus, lac, cid, gprsState, RejectCause); |
| |
| if (RegStatus == 5) |
| IsRoaming = TRUE; |
| else |
| IsRoaming = FALSE; |
| |
| if ((RegStatus == 1) || (RegStatus == 5)) |
| NWReady = TRUE; |
| else |
| NWReady = FALSE; |
| |
| if (last_IsRoaming != IsRoaming) { |
| CM_Log(CheckDataCallRegisterStatus_data_cb6, "data_cb, roam change %d -> %d", last_IsRoaming, IsRoaming); |
| if (last_IsRoaming == TRUE && IsRoaming == FALSE) { |
| send_redialmsg_to_redialthread(-1, REDIAL_ROAMCHANGE); |
| } else { |
| CM_Handle_ChangetoRoam(); |
| } |
| |
| last_IsRoaming = IsRoaming; |
| } |
| |
| g_cell_basic_info.roaming = IsRoaming; |
| g_cell_basic_info.data_mode = gprsState; |
| |
| if ((RegStatus != 1) && (RegStatus != 5)) { |
| NW_status = CM_NW_STATUS_NOT_REGISTERED; //not registered |
| g_cell_basic_info.sys_mode = E_NO_SERVICE; |
| } else if (gprsState == RADIO_TECH_LTE || gprsState == RADIO_TECH_LTEP) { |
| NW_status = CM_NW_STATUS_LTE; //registered on 4G |
| g_cell_basic_info.sys_mode = E_LTE; |
| } else if ((gprsState == RADIO_TECH_GPRS) || (gprsState == RADIO_TECH_EDGE) || (gprsState == RADIO_TECH_GSM) |
| || (gprsState == RADIO_TECH_UMTS) || (gprsState == RADIO_TECH_HSDPA) |
| || (gprsState == RADIO_TECH_HSUPA) || (gprsState == RADIO_TECH_HSPA ) ||(gprsState == RADIO_TECH_HSPAP)) { |
| NW_status = CM_NW_STATUS_23G; //registered on 2/3G |
| g_cell_basic_info.sys_mode = E_2G_3G; |
| } else if (gprsState == RADIO_TECH_EUTRAN_TO_5GCN ||gprsState == RADIO_TECH_NR_TO_5GCN || |
| gprsState == RADIO_TECH_NGRAN || gprsState == RADIO_TECH_EUTRAN_NR_DUAL_LINK) { |
| NW_status = CM_NW_STATUS_5G;//registered 5G |
| g_cell_basic_info.sys_mode = E_5G; |
| } |
| else |
| NW_status = -1; |
| |
| CM_Log(CheckDataCallRegisterStatus_data_cb8, "data_cb: NWReady %d, IsRoaming is %d, NW_status %d\n", NWReady, IsRoaming, NW_status); |
| |
| if (last_NWReady != NWReady) |
| last_NWReady = NWReady; |
| end: |
| if (ret != 0 || rilerrno != 0) |
| CM_Log(CheckDataCallRegisterStatus_data_cb9, "data_cb: ret %d, rilerrno %d", ret, rilerrno); |
| } |
| |
| void CheckDataCallRegisterStatus() |
| { |
| int ret_val; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_DATA_REGISTRATION_STATE_NOCACHE, NULL, 0); |
| |
| CM_Log(CheckDataCallRegisterStatus1, "CheckDataCallRegisterStatus: enter"); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, CheckDataCallRegisterStatus_data_cb, |
| 0, 0)) != UBUS_STATUS_OK) { |
| CM_Log_E(CheckDataCallRegisterStatus, "CheckDataCallRegisterStatus, ubus_invoke RIL_REQUEST_DATA_REGISTRATION_STATE failed %s\n", |
| ubus_strerror(ret_val)); |
| } |
| |
| } |
| |
| |
| void CheckDataCallRegisterStatus_complete_cb(struct ubus_request *req, int ret) |
| { |
| UNUSED(ret); |
| CM_Log(CheckDataCallRegisterStatus_complete_cb, "CheckDataCallRegisterStatus_complete_cb: enter, ret = %d", ret); |
| |
| if (req) { |
| free(req); |
| req = NULL; |
| } |
| } |
| |
| |
| void CheckDataCallRegisterStatus_IndCallback() |
| { |
| int ret_val; |
| struct ubus_request *req = NULL; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_DATA_REGISTRATION_STATE, NULL, 0); |
| |
| req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); |
| |
| if ((ret_val = |
| ubus_invoke_async(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, req)) != UBUS_STATUS_OK) { |
| free(req); |
| return; |
| } else { |
| req->data_cb = CheckDataCallRegisterStatus_IndCall_data_cb; |
| req->complete_cb = CheckDataCallRegisterStatus_complete_cb; |
| ubus_complete_request_async(cm_ctx, req); |
| } |
| } |
| |
| #define RULE_SHOW_PLMN 0x01 |
| #define RULE_SHOW_SPN 0x02 |
| |
| #define NETWORK_NAME_TYPE 0 |
| #define ROAMING_NETWORK_NAME_TYPE 1 |
| |
| char *ucs2_to_utf8(unsigned char *ucs2) |
| { |
| unsigned short ucs2_code = 0; |
| int len = 0, i = 0, j = 0; |
| int ucs2_count = 0; |
| int nbytes = 0; |
| unsigned char bytes[4] = { 0 }; |
| char *utf8 = NULL; |
| if (!ucs2) |
| return NULL; |
| ucs2_count = strlen((const char *)ucs2); |
| if (ucs2_count <= 0 && ucs2_count % 2 != 0) |
| return NULL; |
| nbytes = (ucs2_count / 2) * 3 + 1; |
| utf8 = malloc(nbytes); |
| if (!utf8) |
| return NULL; |
| memset(utf8, 0, nbytes); |
| for (i = 0; i < ucs2_count; i=i+2) { |
| ucs2_code = (ucs2[i] << 8) + ucs2[i + 1]; |
| if (ucs2_code < 0x80) { |
| bytes[0] = ucs2_code; |
| nbytes = 1; |
| } else if (ucs2_code < 0x800) { |
| bytes[1] = (ucs2_code & 0x3F) | 0x80; |
| bytes[0] = (((ucs2_code << 2) & 0x1F00) | 0xC000) >> 8; |
| nbytes = 2; |
| } else { |
| bytes[2] = (ucs2_code & 0x3F) | 0x80; |
| bytes[1] = (((ucs2_code << 2) & 0x3F00) | 0x8000) >> 8; |
| bytes[0] = (((ucs2_code << 4) & 0x0F0000) | 0xE00000) >> 16; |
| nbytes = 3; |
| } |
| for (j = 0; j < nbytes; j++) { |
| utf8[len] = bytes[j]; |
| len++; |
| } |
| } |
| utf8[len] = '\0'; |
| |
| CM_Log(ucs2_to_utf8, "ucs2_to_utf8: utf8 str[%d] %s", len, utf8); |
| return utf8; |
| } |
| |
| int get_network_display_rule(s_cellular_info * info) |
| { |
| int rule; |
| if (!info->spn_info.spn_exist) { |
| rule = RULE_SHOW_PLMN; |
| return rule; |
| } |
| if (!info->roaming) { |
| rule = RULE_SHOW_SPN; |
| if ((info->spn_info.dis_cond & RULE_SHOW_PLMN) == RULE_SHOW_PLMN) |
| rule |= RULE_SHOW_PLMN; |
| } else { |
| rule = RULE_SHOW_PLMN; |
| if ((info->spn_info.dis_cond & RULE_SHOW_SPN) == 0x00) |
| rule |= RULE_SHOW_SPN; |
| } |
| |
| return rule; |
| } |
| |
| int get_register_plmn() |
| { |
| int ret_val; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_OPERATOR, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, plmn_operator_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| CM_Log_E(get_register_plmn, "get_register_plmn, ubus_invoke RIL_REQUEST_OPERATOR failed %s\n", ubus_strerror(ret_val)); |
| } |
| |
| return ret_val; |
| } |
| |
| char *get_network_name(int type) |
| { |
| #define PLMN_NAME_SIZE 32 |
| RIL_SIM_IO_v6 sim_io_data; |
| int ret_val; |
| int rule; |
| unsigned char ucs2_str[16] = { 0 }; |
| char *ret_plmn_name = NULL; |
| int len = 0; |
| |
| //send sim io ril to get SPN |
| if (!g_cell_basic_info.spn_info.spn_exist) { |
| memset(&sim_io_data, 0, sizeof(RIL_SIM_IO_v6)); |
| sim_io_data.command = 176; |
| len += sizeof(int); |
| sim_io_data.fileid = 28486; |
| len += sizeof(int); |
| sim_io_data.p1 = 0; |
| len += sizeof(int); |
| sim_io_data.p2 = 0; |
| len += sizeof(int); |
| sim_io_data.p3 = 17; |
| len += sizeof(int); |
| sim_io_data.path = strdup("3F007FFF"); // USIM pathid |
| len += strlen(sim_io_data.path) + 1; |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_SIM_IO, (void *)&sim_io_data, len); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, spn_info_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| CM_Log_E(get_network_name, "get_network_name, ubus_invoke RIL_REQUEST_SIM_IO failed %s\n", |
| ubus_strerror(ret_val)); |
| goto EXIT; |
| } |
| //free buffer this point |
| free(sim_io_data.path); |
| } |
| |
| rule = get_network_display_rule(&g_cell_basic_info); |
| |
| ret_plmn_name = malloc(PLMN_NAME_SIZE); |
| if (!ret_plmn_name) |
| return NULL; |
| |
| memset(ret_plmn_name, 0, PLMN_NAME_SIZE); |
| |
| if (g_cell_basic_info.roaming) { |
| if ((rule & RULE_SHOW_SPN) == RULE_SHOW_SPN && type == NETWORK_NAME_TYPE) { |
| if (g_cell_basic_info.spn_info.spn_exist) { |
| if (g_cell_basic_info.spn_info.spn_name[0] == 0x80) { |
| memcpy(ucs2_str, &g_cell_basic_info.spn_info.spn_name[1], 15); |
| free(ret_plmn_name); |
| ret_plmn_name = ucs2_to_utf8(ucs2_str); |
| } else { |
| strncpy(ret_plmn_name, g_cell_basic_info.spn_info.spn_name, PLMN_NAME_SIZE - 1); |
| } |
| } else { |
| if (get_register_plmn() == 0) |
| strncpy(ret_plmn_name, g_cell_basic_info.ons_info.ons, PLMN_NAME_SIZE - 1); |
| else { |
| free(ret_plmn_name); |
| ret_plmn_name = NULL; |
| } |
| } |
| } else { |
| if (get_register_plmn() == 0) |
| strncpy(ret_plmn_name, g_cell_basic_info.ons_info.ons, PLMN_NAME_SIZE - 1); |
| else { |
| free(ret_plmn_name); |
| ret_plmn_name = NULL; |
| } |
| } |
| } else { |
| if ((rule & RULE_SHOW_PLMN) == RULE_SHOW_PLMN && type == ROAMING_NETWORK_NAME_TYPE) { |
| if (get_register_plmn() == 0) |
| strncpy(ret_plmn_name, g_cell_basic_info.ons_info.ons, PLMN_NAME_SIZE - 1); |
| else { |
| free(ret_plmn_name); |
| ret_plmn_name = NULL; |
| } |
| } else { |
| if (g_cell_basic_info.spn_info.spn_exist) { |
| if (g_cell_basic_info.spn_info.spn_name[0] == 0x80) { |
| memcpy(ucs2_str, &g_cell_basic_info.spn_info.spn_name[1], 15); |
| free(ret_plmn_name); |
| ret_plmn_name = ucs2_to_utf8(ucs2_str); |
| } else { |
| strncpy(ret_plmn_name, g_cell_basic_info.spn_info.spn_name, PLMN_NAME_SIZE - 1); |
| } |
| } else { |
| if (get_register_plmn() == 0) |
| strncpy(ret_plmn_name, g_cell_basic_info.ons_info.ons, PLMN_NAME_SIZE - 1); |
| else { |
| free(ret_plmn_name); |
| ret_plmn_name = NULL; |
| } |
| } |
| } |
| } |
| EXIT: |
| return ret_plmn_name; |
| } |
| |
| static int set_modem_version_ril(int version) |
| { |
| struct blob_buf *b = &cm_b; |
| int modem_ver = version, size = 0; |
| int ret = UBUS_STATUS_OK; |
| |
| /* send EEMOPT to enable/disable enginerring mode */ |
| blob_buf_init(b, 0); |
| size = 1; |
| rilutil_makeRequestBlobDSMaster(b, RIL_REQUEST_SET_MODEM_VERSION, (void *)&modem_ver, size); |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", b->head, NULL, 0, 10000); |
| if (ret) { |
| goto exit; |
| } |
| exit: |
| return ret; |
| |
| } |
| |
| struct uci_context *uci_wan_ctx_get(void) |
| { |
| if (uci_ctx_wan) { |
| return uci_ctx_wan; |
| } |
| uci_ctx_wan = uci_alloc_context(); |
| if (!uci_ctx_wan) { |
| CM_Log_E(uci_wan_ctx_get, "uci_wan_ctx_get, malloc failed"); |
| return NULL; |
| } |
| return uci_ctx_wan; |
| } |
| |
| void free_wan_uci_ctx(void) |
| { |
| if (uci_ctx_wan) |
| uci_free_context(uci_ctx_wan); |
| uci_ctx_wan = NULL; |
| } |
| |
| #if 0 |
| static void tftinfo_parse(struct blob_attr *msg, PacketFilterInfo * tftinfo) |
| { |
| struct blob_attr *tb[TFT_MAX]; |
| blobmsg_parse(cm_tftinfo_policy, ARRAY_SIZE(cm_tftinfo_policy), tb, blobmsg_data(msg), blobmsg_data_len(msg)); |
| |
| if (tb[TFT1]) |
| tftinfo->direction = atoi(blobmsg_get_string(tb[TFT1])); |
| |
| if (tb[TFT2]) |
| tftinfo->directionPresent = atoi(blobmsg_get_string(tb[TFT2])); |
| |
| if (tb[TFT3_MIN]) |
| tftinfo->localPortRange.min = atoi(blobmsg_get_string(tb[TFT3_MIN])); |
| |
| if (tb[TFT3_MAX]) |
| tftinfo->localPortRange.max = atoi(blobmsg_get_string(tb[TFT3_MAX])); |
| |
| CM_Log("tftinfo_parse, %d,%d,%d", tftinfo->direction, tftinfo->directionPresent, tftinfo->localPortRange); |
| |
| if (tb[TFT4_MIN]) |
| tftinfo->remotePortRange.min = atoi(blobmsg_get_string(tb[TFT4_MIN])); |
| |
| if (tb[TFT4_MAX]) |
| tftinfo->remotePortRange.max = atoi(blobmsg_get_string(tb[TFT4_MAX])); |
| |
| if (tb[TFT5]) |
| tftinfo->localPortRangePresent = atoi(blobmsg_get_string(tb[TFT5])); |
| |
| if (tb[TFT6]) |
| tftinfo->remotePortRangePresent = atoi(blobmsg_get_string(tb[TFT6])); |
| |
| if (tb[TFT7]) |
| tftinfo->secondaryCid = atoi(blobmsg_get_string(tb[TFT7])); |
| |
| if (tb[TFT8]) |
| tftinfo->PfIdx = atoi(blobmsg_get_string(tb[TFT8])); |
| |
| if (tb[TFT9]) |
| tftinfo->EpIdx = atoi(blobmsg_get_string(tb[TFT9])); |
| } |
| #endif |
| |
| void complete_create_pdp_async_cb(struct ubus_request *req, int ret) |
| { |
| UNUSED(ret); |
| if (req) { |
| free(req); |
| } |
| CM_Log(complete_create_pdp_async_cb, "complete_create_pdp_async_cb(%d)\n", ret); |
| } |
| |
| int create_connection(void) |
| { |
| struct ubus_request *req = NULL; |
| int ret_val = UBUS_STATUS_OK; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| req = malloc(sizeof(struct ubus_request)); |
| if (!req) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| memset(req, 0, sizeof(struct ubus_request)); |
| if ((ret_val = ubus_invoke_async(cm_ctx, cm_ubus_id.cm_id, "create_pdp", cm_b.head, req)) != UBUS_STATUS_OK) { |
| free(req); |
| } else { |
| req->complete_cb = complete_create_pdp_async_cb; |
| ubus_complete_request_async(cm_ctx, req); |
| } |
| EXIT: |
| return ret_val; |
| } |
| |
| void complete_destroy_pdp_async_cb(struct ubus_request *req, int ret) |
| { |
| UNUSED(ret); |
| if (req) { |
| free(req); |
| } |
| CM_Log(complete_destroy_pdp_async_cb, "complete_destroy_pdp_async_cb(%d)\n", ret); |
| } |
| |
| int destroy_connection(int connection_num, int delete_all) |
| { |
| struct ubus_request *req = NULL; |
| int ret_val = UBUS_STATUS_OK; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); |
| if (!req) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| memset(req, 0, sizeof(struct ubus_request)); |
| |
| blobmsg_add_u32(&cm_b, "connectionNum", connection_num); |
| blobmsg_add_u32(&cm_b, "deleteall", delete_all); |
| CM_Log(destroy_connection1, "destroy_connection: connection num %d, deleteall %d\n", connection_num, delete_all); |
| |
| if ((ret_val = ubus_invoke_async(cm_ctx, cm_ubus_id.cm_id, "destroy_pdp", cm_b.head, req)) != UBUS_STATUS_OK) { |
| free(req); |
| } else { |
| req->complete_cb = complete_destroy_pdp_async_cb; |
| ubus_complete_request_async(cm_ctx, req); |
| } |
| EXIT: |
| return ret_val; |
| } |
| |
| static int DestroyConnecion_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| UNUSED(req); |
| UNUSED(method); |
| |
| DisconnectInfo *p_info; |
| struct blob_attr *tb[CM_MAX]; |
| |
| p_info = malloc(sizeof(DisconnectInfo)); |
| if (!p_info) { |
| return 0; |
| } |
| |
| memset(p_info, 0, sizeof(*p_info)); |
| |
| blobmsg_parse(destroy_connection_policy, ARRAY_SIZE(destroy_connection_policy), tb, blob_data(msg), |
| blob_len(msg)); |
| if (tb[CM_MSG1]) |
| p_info->connectionNum = blobmsg_get_u32(tb[CM_MSG1]); |
| if (tb[CM_MSG2]) |
| p_info->deleteall = blobmsg_get_u32(tb[CM_MSG2]); |
| |
| CM_DestroyConnection(p_info); |
| return 0; |
| } |
| |
| static int GetLinkContext_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| |
| Link_Context *p_linkcontext = NULL; |
| Link_Context *tmp_linkcontext = NULL; |
| void *array = NULL; |
| void *table = NULL; |
| char tmp[68] = { 0 }; |
| int ret_val = UBUS_STATUS_OK; |
| char *oper_name = NULL; |
| char *roaming_oper_name = NULL; |
| Apn_Info *default_apn = NULL; |
| int ret = 0; |
| |
| //p_linkcontext = malloc(sizeof(Link_Context)); |
| |
| blob_buf_init(&cm_b, 0); |
| |
| CheckDataCallRegisterStatus(); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_IMEI, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, sim_info_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| ret = 1; |
| goto EXIT; |
| } |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_IMEISV, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, sim_info_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| ret = 2; |
| goto EXIT; |
| } |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_IMSI, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, sim_info_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| ret = 3; |
| goto EXIT; |
| } |
| |
| /*open the power ind*/ |
| SetCPPowerInd(0); |
| /*sleep 1ms to wait or the ind report to RIL*/ |
| usleep(1000); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_SIGNAL_STRENGTH, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, rssi_info_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| ret = 4; |
| goto EXIT; |
| } |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_IMS_REGISTRATION_STATE, NULL, 0); |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, ims_reg_state_request_cb, 0, |
| 0)) != UBUS_STATUS_OK) { |
| ret = 5; |
| goto EXIT; |
| } |
| |
| SetCPPowerInd(1); |
| //send reply |
| oper_name = get_network_name(NETWORK_NAME_TYPE); |
| roaming_oper_name = get_network_name(ROAMING_NETWORK_NAME_TYPE); |
| |
| blob_buf_init(&cm_b, 0); |
| blobmsg_add_u32(&cm_b, "id", 4); |
| table = blobmsg_open_table(&cm_b, "celluar_basic_info"); |
| blobmsg_add_u32(&cm_b, "sys_mode", g_cell_basic_info.sys_mode); |
| blobmsg_add_u32(&cm_b, "data_mode", g_cell_basic_info.data_mode); |
| blobmsg_add_u32(&cm_b, "rssi", g_cell_basic_info.rssi); |
| blobmsg_add_u32(&cm_b, "ims_state", g_cell_basic_info.ims_state); |
| |
| blobmsg_add_string(&cm_b, "IMEI", g_cell_basic_info.IMEI); |
| //blobmsg_add_string(&cm_b, "IMEI_SV", g_cell_basic_info.IMEI_SV); |
| blobmsg_add_string(&cm_b, "IMSI", g_cell_basic_info.IMSI); |
| CM_Log(GetLinkContext_method4, "GetLinkContext_method: IMEI %s, IMSI %s", g_cell_basic_info.IMEI, g_cell_basic_info.IMSI); |
| |
| if (oper_name) { |
| blobmsg_add_string(&cm_b, "network_name", oper_name); |
| free(oper_name); |
| } |
| if (roaming_oper_name) { |
| blobmsg_add_string(&cm_b, "roaming_network_name", roaming_oper_name); |
| free(roaming_oper_name); |
| } |
| blobmsg_close_table(&cm_b, table); |
| |
| p_linkcontext = (Link_Context *) CM_GetLinkContext(); |
| //send reply |
| array = blobmsg_open_array(&cm_b, "contextlist"); |
| |
| tmp_linkcontext = p_linkcontext; |
| while (tmp_linkcontext) { |
| table = blobmsg_open_table(&cm_b, "list"); |
| CM_Log(GetLinkContext_method5, "GetLinkContext_method:connection_num %d connection_status %d pdp_type %d ip_type %d create_by %d\n", tmp_linkcontext->connectionNum, |
| tmp_linkcontext->connectStatus, tmp_linkcontext->pdpinfo.PDP_Type, tmp_linkcontext->pdpinfo.IP_Type, tmp_linkcontext->create_by); |
| |
| blobmsg_add_u32(&cm_b, "connection_num", tmp_linkcontext->connectionNum); |
| if ( tmp_linkcontext->connectStatus == CM_CONNECT_GET_GLOBALIP_ERR) |
| { |
| if ((tmp_linkcontext->pdpinfo.IP_Type == 0) && tmp_linkcontext->ipv4info.IPAddr) |
| blobmsg_add_u32(&cm_b, "connection_status", CM_CONNECT_CONSUCCESS); |
| else |
| blobmsg_add_u32(&cm_b, "connection_status", CM_CONNECT_DISCON); |
| } |
| else |
| blobmsg_add_u32(&cm_b, "connection_status", tmp_linkcontext->connectStatus); |
| |
| blobmsg_add_u32(&cm_b, "pdp_type", tmp_linkcontext->pdpinfo.PDP_Type); |
| blobmsg_add_u32(&cm_b, "ip_type", tmp_linkcontext->pdpinfo.IP_Type); |
| blobmsg_add_u32(&cm_b, "primary_cid", tmp_linkcontext->pdpinfo.primaryCid); |
| blobmsg_add_u32(&cm_b, "qci", tmp_linkcontext->pdpinfo.QCI); |
| blobmsg_add_string(&cm_b, "apn", tmp_linkcontext->pdpinfo.APN); |
| blobmsg_add_string(&cm_b, "lte_apn", tmp_linkcontext->pdpinfo.LteAPN); |
| blobmsg_add_string(&cm_b, "usr_2g3g", tmp_linkcontext->pdpinfo.Usr2G3G); |
| blobmsg_add_string(&cm_b, "pswd_2g3g", tmp_linkcontext->pdpinfo.PASWD2G3G); |
| blobmsg_add_string(&cm_b, "authtype_2g3g", tmp_linkcontext->pdpinfo.Authtype2G3G); |
| blobmsg_add_string(&cm_b, "usr_4g", tmp_linkcontext->pdpinfo.Usr4G); |
| blobmsg_add_string(&cm_b, "pswd_4g", tmp_linkcontext->pdpinfo.PASWD4G); |
| blobmsg_add_string(&cm_b, "authtype_4g", tmp_linkcontext->pdpinfo.Authtype4G); |
| blobmsg_add_u32(&cm_b, "mtu", tmp_linkcontext->pdpinfo.mtu); |
| if (tmp_linkcontext->create_by == 1) { |
| /*Context Create By CM*/ |
| default_apn = get_default_apninfo(g_work_apn, NULL); |
| if (default_apn) { |
| blobmsg_add_u32(&cm_b, "auto_apn", default_apn->auto_apn); |
| if (strlen(default_apn->mmsc) > 0) |
| blobmsg_add_string(&cm_b, "mmsc", default_apn->mmsc); |
| if (strlen(default_apn->mmsproxy) > 0) |
| blobmsg_add_string(&cm_b, "mmsproxy", default_apn->mmsproxy); |
| if (strlen(default_apn->mmsport) > 0) |
| blobmsg_add_string(&cm_b, "mmsport", default_apn->mmsport); |
| |
| blobmsg_add_u32(&cm_b, CONN_MODE_STR, default_apn->Extra_params.autoconnect); |
| blobmsg_add_u32(&cm_b, DATA_ON_ROAMING_STR, default_apn->Extra_params.data_on_roaming); |
| } |
| } else { |
| blobmsg_add_u32(&cm_b, "auto_apn", tmp_linkcontext->pdpinfo.autoapn); |
| if (strlen(tmp_linkcontext->pdpinfo.mmsc) > 0) |
| blobmsg_add_string(&cm_b, "mmsc", tmp_linkcontext->pdpinfo.mmsc); |
| if (strlen(tmp_linkcontext->pdpinfo.mmsproxy) > 0) |
| blobmsg_add_string(&cm_b, "mmsproxy", tmp_linkcontext->pdpinfo.mmsproxy); |
| if (strlen(tmp_linkcontext->pdpinfo.mmsport) > 0) |
| blobmsg_add_string(&cm_b, "mmsport", tmp_linkcontext->pdpinfo.mmsport); |
| |
| blobmsg_add_u32(&cm_b, CONN_MODE_STR, tmp_linkcontext->pdpinfo.autoconnect); |
| blobmsg_add_u32(&cm_b, DATA_ON_ROAMING_STR, tmp_linkcontext->pdpinfo.data_on_roaming); |
| } |
| |
| if ((tmp_linkcontext->pdpinfo.IP_Type != 2) && tmp_linkcontext->ipv4info.IPAddr) { |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET, &(tmp_linkcontext->ipv4info.IPAddr), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method6, "ipv4info.IPAddr is 0x%x %s", tmp_linkcontext->ipv4info.IPAddr, tmp); |
| blobmsg_add_string(&cm_b, "ipv4_ip", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET, &(tmp_linkcontext->ipv4info.PrimaryDNS), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method7, "ipv4info.PrimaryDNS is 0x%x %s", tmp_linkcontext->ipv4info.PrimaryDNS, tmp); |
| blobmsg_add_string(&cm_b, "ipv4_dns1", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET, &(tmp_linkcontext->ipv4info.SecondaryDNS), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method8, "ipv4info.SecondaryDNS is 0x%x %s", tmp_linkcontext->ipv4info.SecondaryDNS, tmp); |
| blobmsg_add_string(&cm_b, "ipv4_dns2", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET, &(tmp_linkcontext->ipv4info.GateWay), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method9, "ipv4info.GateWay is 0x%x %s", tmp_linkcontext->ipv4info.GateWay, tmp); |
| blobmsg_add_string(&cm_b, "ipv4_gateway", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET, &(tmp_linkcontext->ipv4info.Mask), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method10, "ipv4info.Mask is 0x%x %s", tmp_linkcontext->ipv4info.Mask, tmp); |
| blobmsg_add_string(&cm_b, "ipv4_submask", tmp); |
| } |
| |
| if ((tmp_linkcontext->pdpinfo.IP_Type != 1) |
| && (tmp_linkcontext->ipv6info.IPV6Addr[0] || tmp_linkcontext->ipv6info.IPV6Addr[1] |
| || tmp_linkcontext->ipv6info.IPV6Addr[2] || tmp_linkcontext->ipv6info.IPV6Addr[3])) { |
| |
| char interface_name[32]; |
| char ipaddress[INET6_ADDRSTRLEN]; |
| int IPV6Addr[4]; |
| |
| snprintf(interface_name, sizeof(interface_name), "ccinet%d", tmp_linkcontext->pdpinfo.primaryCid - 1); |
| if (getInterfaceAddr6(interface_name, ipaddress, sizeof(ipaddress)) == 0) |
| { |
| inet_pton(AF_INET6, ipaddress, IPV6Addr); |
| CM_Log(GetLinkContext_method1944, "%s: get global ip [%s]", __func__, ipaddress); |
| tmp_linkcontext->ipv6info.IPV6Addr[0] = IPV6Addr[0]; |
| tmp_linkcontext->ipv6info.IPV6Addr[1] = IPV6Addr[1]; |
| } |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET6, &(tmp_linkcontext->ipv6info.IPV6Addr), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method11, "ipv6info.IPV6Addr is 0x%x 0x%x 0x%x 0x%x", tmp_linkcontext->ipv6info.IPV6Addr[0], |
| tmp_linkcontext->ipv6info.IPV6Addr[1], tmp_linkcontext->ipv6info.IPV6Addr[2], |
| tmp_linkcontext->ipv6info.IPV6Addr[3]); |
| CM_Log(GetLinkContext_method12, "ipv6info.IPV6Addr %s", tmp); |
| blobmsg_add_string(&cm_b, "ipv6_ip", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET6, &(tmp_linkcontext->ipv6info.PrimaryDNS), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method13, "ipv6info.PrimaryDNS is 0x%x 0x%x 0x%x 0x%x", tmp_linkcontext->ipv6info.PrimaryDNS[0], |
| tmp_linkcontext->ipv6info.PrimaryDNS[1], tmp_linkcontext->ipv6info.PrimaryDNS[2], |
| tmp_linkcontext->ipv6info.PrimaryDNS[3]); |
| CM_Log(GetLinkContext_method14, "ipv6info.PrimaryDNS %s", tmp); |
| blobmsg_add_string(&cm_b, "ipv6_dns1", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET6, &(tmp_linkcontext->ipv6info.SecondaryDNS), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method15, "ipv6info.SecondaryDNS is 0x%x 0x%x 0x%x 0x%x", |
| tmp_linkcontext->ipv6info.SecondaryDNS[0], tmp_linkcontext->ipv6info.SecondaryDNS[1], |
| tmp_linkcontext->ipv6info.SecondaryDNS[2], tmp_linkcontext->ipv6info.SecondaryDNS[3]); |
| CM_Log(GetLinkContext_method16, "ipv6info.SecondaryDNS %s", tmp); |
| blobmsg_add_string(&cm_b, "ipv6_dns2", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET6, &(tmp_linkcontext->ipv6info.GateWay), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method17, "ipv6info.GateWay is 0x%x 0x%x 0x%x 0x%x", tmp_linkcontext->ipv6info.SecondaryDNS[0], |
| tmp_linkcontext->ipv6info.SecondaryDNS[1], tmp_linkcontext->ipv6info.SecondaryDNS[2], |
| tmp_linkcontext->ipv6info.SecondaryDNS[3]); |
| CM_Log(GetLinkContext_method18, "ipv6info.GateWay %s", tmp); |
| blobmsg_add_string(&cm_b, "ipv6_gateway", tmp); |
| |
| memset(tmp, 0, sizeof(tmp)); |
| inet_ntop(AF_INET6, &(tmp_linkcontext->ipv6info.Mask), tmp, sizeof(tmp)); |
| CM_Log(GetLinkContext_method19, "ipv6info.Mask is 0x%x 0x%x 0x%x 0x%x", tmp_linkcontext->ipv6info.Mask[0], |
| tmp_linkcontext->ipv6info.Mask[1], tmp_linkcontext->ipv6info.Mask[2], |
| tmp_linkcontext->ipv6info.Mask[3]); |
| CM_Log(GetLinkContext_method20, "ipv6info.Mask %s", tmp); |
| blobmsg_add_string(&cm_b, "ipv6_submask", tmp); |
| } |
| |
| blobmsg_close_table(&cm_b, table); |
| |
| tmp_linkcontext = tmp_linkcontext->next; |
| } |
| |
| blobmsg_close_array(&cm_b, array); |
| EXIT: |
| ubus_send_reply(ctx, req, cm_b.head); |
| |
| LinkContext_free(p_linkcontext); |
| if (ret > 0 && ret_val > 0) |
| CM_Log_E(GetLinkContext_method1980, "GetLinkContext_method, ret %d, ubus_invoke fail with %s\n", |
| ret, ubus_strerror(ret_val)); |
| return 0; |
| } |
| |
| |
| int CreatePdp_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| UNUSED(req); |
| UNUSED(method); |
| UNUSED(msg); |
| |
| CM_Create_Pdp(g_work_apn); |
| return 0; |
| } |
| |
| static int SetImageType_method(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| UNUSED(req); |
| UNUSED(method); |
| |
| struct blob_attr *tb[CM_MAX]; |
| struct blob_buf *b_rsp = &cm_b; |
| unsigned int type = 0; |
| char old_value[4] = { 0 }; |
| int ret = UBUS_STATUS_OK; |
| void *table = NULL; |
| |
| if (blobmsg_parse(cm_set_image_policy, ARRAY_SIZE(cm_set_image_policy), tb, blob_data(msg), blob_len(msg)) != 0) { |
| ret = UBUS_STATUS_INVALID_ARGUMENT; |
| goto exit; |
| } |
| |
| if (!tb[CM_MSG1]) { |
| ret = UBUS_STATUS_INVALID_ARGUMENT; |
| goto exit; |
| } |
| type = atoi(blobmsg_get_string(tb[CM_MSG1])); |
| CM_Log(SetImageType_method3, "SetImageType_method: WebUI set type %d", type); |
| |
| property_get(SYS_CURRENT_CP, old_value, LTG_CP); |
| |
| if (type == 0) { |
| ret = set_modem_version_ril(4); |
| } else if (type == 1) { |
| ret = set_modem_version_ril(3); |
| } |
| |
| property_get(SYS_CURRENT_CP, old_value, LTG_CP); |
| CM_Log(SetImageType_method7, "SetImageType_method: get type %s", old_value); |
| |
| exit: |
| blob_buf_init(b_rsp, 0); |
| table = blobmsg_open_table(b_rsp, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(b_rsp, "setting_response", "OK"); |
| } else { |
| blobmsg_add_string(b_rsp, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(b_rsp, table); |
| |
| ubus_send_reply(ctx, req, b_rsp->head); |
| |
| CM_Log(SetImageType_method8, "SetImageType_method: leave %d\n", ret); |
| return ret; |
| } |
| |
| static int GetImageType_method(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(msg); |
| UNUSED(method); |
| |
| char value[4] = { '\0' }; |
| char exist_value[4] = { '\0' }; |
| |
| //send reply |
| blob_buf_init(&cm_b, 0); |
| blobmsg_add_u32(&cm_b, "id", 6); |
| |
| property_get(SYS_CURRENT_CP, value, "0"); |
| property_get(SYS_EXIST_CP, exist_value, "0"); |
| |
| CM_Log(GetImageType_method, "GetImageType_method value %s exist value %s\n", value, exist_value); |
| /*LWG*/ |
| if (atoi(value) == 4) { |
| blobmsg_add_u32(&cm_b, "Image_type", 0); |
| } |
| else if(atoi(value) == 3) { |
| blobmsg_add_u32(&cm_b, "Image_type", 1); |
| } |
| else { |
| if ((atoi(exist_value)>>4) & 0x0F) |
| blobmsg_add_u32(&cm_b, "Image_type", 0); |
| else if (atoi(exist_value) & 0x0F) |
| blobmsg_add_u32(&cm_b, "Image_type", 1); |
| else |
| blobmsg_add_u32(&cm_b, "Image_type", 1); |
| } |
| |
| ubus_send_reply(ctx, req, cm_b.head); |
| return 0; |
| } |
| |
| void CM_disable_pdplist_touci(CM_Connection_Context * ConInfo) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_ptr ptr; |
| char *option_value = NULL; |
| char need_commit = 0; |
| |
| /*load /etc/config/wan */ |
| local_ctx = uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto EXIT_disablepdp; |
| } |
| |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| if (!p) { |
| goto EXIT_disablepdp; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WAN_SECTION_PDP_CONFIG) == 0) { |
| option_value = (char *)uci_lookup_option_string(local_ctx, uci_sec, "connectionNum"); |
| |
| if (!option_value) |
| goto EXIT_disablepdp; |
| |
| if (atoi(option_value) == ConInfo->pdpinfo->connectionNum) { |
| CM_Log(CM_disable_pdplist_touci2, "CM_disable_pdplist_touci: set option enable to 0"); |
| //enable |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "enable"; |
| ptr.value = "0"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //IsCreated |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| //ptr.package = WAN_PACKAGE_NAME; |
| //ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "IsCreated"; |
| ptr.value = "0"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| need_commit = 1; |
| |
| } else |
| continue; |
| } |
| } |
| |
| EXIT_disablepdp: |
| if (need_commit == 1) |
| uci_commit(local_ctx, &p, false); |
| |
| free_wan_uci_ctx(); |
| } |
| |
| void CM_add_pdplist_touci(CM_Connection_Context * ConInfo) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_ptr ptr; |
| char *option_value = NULL; |
| char sec_name[30]; |
| char tmp_buf[10]; |
| char match = 0; |
| char need_commit = 0; |
| |
| /*load /etc/config/wan */ |
| local_ctx = uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto EXIT_addpdp; |
| } |
| |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| if (!p) { |
| CM_Log_E(CM_add_pdplist_touci3, "CM_add_pdplist_touci,load wan config failed!"); |
| goto EXIT_addpdp; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WAN_SECTION_PDP_CONFIG) == 0) { |
| option_value = (char *)uci_lookup_option_string(local_ctx, uci_sec, "connectionNum"); |
| |
| if (!option_value) |
| goto EXIT_addpdp; |
| |
| if (atoi(option_value) == ConInfo->pdpinfo->connectionNum) { |
| match = 1; |
| option_value = (char *)uci_lookup_option_string(local_ctx, uci_sec, "enable"); |
| if (atoi(option_value) == 0) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| //ptr.package = WAN_PACKAGE_NAME; |
| //ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "enable"; |
| ptr.value = "1"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| |
| option_value = (char *)uci_lookup_option_string(local_ctx, uci_sec, "IsCreated"); |
| if (atoi(option_value) == 0) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| //ptr.package = WAN_PACKAGE_NAME; |
| //ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "IsCreated"; |
| ptr.value = "1"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| need_commit = 1; |
| } |
| goto EXIT_addpdp; |
| } |
| } |
| } |
| |
| if (match == 0) { |
| need_commit = 1; |
| //add pdplist to uci |
| //add section firstly |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| strcpy(sec_name, "pdp_config"); |
| sprintf(tmp_buf, "%x", ConInfo->pdpinfo->connectionNum); |
| strcat(sec_name, tmp_buf); |
| ptr.section = sec_name; |
| ptr.flags = UCI_LOOKUP_DONE; |
| ptr.value = WAN_SECTION_PDP_CONFIG; |
| uci_set(local_ctx, &ptr); |
| |
| //backup uci_section |
| uci_sec = ptr.s; |
| |
| //add <connectionNum/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.option = "connectionNum"; |
| ptr.value = tmp_buf; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <enable/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.option = "enable"; |
| ptr.value = "1"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <IsCreated/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.option = "IsCreated"; |
| ptr.value = "1"; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <PDP_name/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.option = "PDP_name"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <IP_Type/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.option = "IP_Type"; |
| memset(tmp_buf, 0, 10); |
| sprintf(tmp_buf, "%d", ConInfo->pdpinfo->IP_Type); |
| ptr.value = tmp_buf; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <QCI/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "QCI"; |
| memset(tmp_buf, 0, 10); |
| sprintf(tmp_buf, "%d", ConInfo->pdpinfo->QCI); |
| ptr.value = tmp_buf; |
| |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <APN/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "APN"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <LteAPN/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "LteAPN"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <Usr2G3G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "Usr2G3G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <PASWD2G3G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "PASWD2G3G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <Authtype2G3G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "Authtype2G3G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <Usr4G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "Usr4G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <PASWD4G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "PASWD4G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| //add <Authtype4G/> |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.s = uci_sec; |
| ptr.option = "Authtype4G"; |
| ptr.value = ConInfo->pdpinfo->PDP_name; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| uci_set(local_ctx, &ptr); |
| |
| } |
| |
| EXIT_addpdp: |
| |
| if (need_commit == 1) { |
| uci_commit(local_ctx, &p, false); |
| } |
| free_wan_uci_ctx(); |
| } |
| |
| //match_type |
| void CM_modify_pdplist_touci(CM_Connection_Context * ConInfo, char match_type) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_ptr ptr; |
| char *option_value = NULL; |
| |
| /*load /etc/config/wan */ |
| local_ctx = uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto EXIT_modifypdp; |
| } |
| |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| if (!p) { |
| CM_Log_E(CM_modify_pdplist_touci3, "CM_modify_pdplist_touci,load wan config failed!"); |
| goto EXIT_modifypdp; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WAN_SECTION_PDP_CONFIG) == 0) { |
| option_value = (char *)uci_lookup_option_string(local_ctx, uci_sec, "connectionNum"); |
| |
| if (!option_value) |
| goto EXIT_modifypdp; |
| |
| if (atoi(option_value) == ConInfo->pdpinfo->connectionNum) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.package = WAN_PACKAGE_NAME; |
| ptr.s = uci_sec; |
| ptr.section = WAN_SECTION_PDP_CONFIG; |
| ptr.flags |= UCI_LOOKUP_DONE; |
| CM_Log(CM_modify_pdplist_touci4, "match_type:%d, IP_Type:%d", match_type, ConInfo->pdpinfo->IP_Type); |
| |
| switch (match_type) { |
| case IP_TYPE: |
| ptr.option = "IP_Type"; |
| if (ConInfo->pdpinfo->IP_Type == 0) |
| ptr.value = "0"; |
| else if (ConInfo->pdpinfo->IP_Type == 1) |
| ptr.value = "1"; |
| else if (ConInfo->pdpinfo->IP_Type == 2) |
| ptr.value = "2"; |
| |
| break; |
| |
| case APN: |
| ptr.option = "APN"; |
| ptr.value = ConInfo->pdpinfo->APN; |
| break; |
| |
| case LTE_APN: |
| ptr.option = "LteAPN"; |
| ptr.value = ConInfo->pdpinfo->LteAPN; |
| break; |
| |
| case USR_2G3G: |
| ptr.option = "Usr2G3G"; |
| ptr.value = ConInfo->pdpinfo->Usr2G3G; |
| break; |
| |
| case PSWD_2G3G: |
| ptr.option = "PASWD2G3G"; |
| ptr.value = ConInfo->pdpinfo->PASWD2G3G; |
| break; |
| |
| case AUTHTYPE_2G3G: |
| ptr.option = "Authtype2G3G"; |
| ptr.value = ConInfo->pdpinfo->Authtype2G3G; |
| break; |
| |
| case USR_4G: |
| ptr.option = "Usr4G"; |
| ptr.value = ConInfo->pdpinfo->Usr4G; |
| break; |
| |
| case PSWD_4G: |
| ptr.option = "PASWD4G"; |
| ptr.value = ConInfo->pdpinfo->PASWD4G; |
| break; |
| |
| case AUTHTYPE_4G: |
| ptr.option = "Authtype4G"; |
| ptr.value = ConInfo->pdpinfo->Authtype4G; |
| break; |
| |
| default: |
| goto EXIT_modifypdp; |
| } |
| |
| uci_set(local_ctx, &ptr); |
| } else |
| continue; |
| } |
| } |
| |
| CM_Log(CM_modify_pdplist_touci5, "before uci_commit, package addr:0x%x", p); |
| uci_commit(local_ctx, &p, false); |
| |
| EXIT_modifypdp: |
| free_wan_uci_ctx(); |
| |
| } |
| |
| static int profile_info_parse(struct blob_attr *msg, s_profile_param * info) |
| { |
| struct blob_attr *tb[_PRO_MAX]; |
| char *str = NULL; |
| int ret; |
| |
| if (!info) { |
| return CM_ERR_INVAL; |
| } |
| |
| ret = |
| blobmsg_parse(profile_tabel_pol, ARRAY_SIZE(profile_tabel_pol), tb, blobmsg_data(msg), |
| blobmsg_data_len(msg)); |
| |
| if (ret != CM_OK) { |
| return CM_ERR_PARSE; |
| } |
| |
| if (tb[PRO_NAME]) { |
| str = blobmsg_get_string(tb[PRO_NAME]); |
| |
| if (str) { |
| CM_Log(profile_info_parse3, "profile_info_parse: profile name %s\n", str); |
| strncpy(info->profile_name, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[PRO_ACTION]) { |
| str = blobmsg_get_string(tb[PRO_ACTION]); |
| |
| if (str) { |
| CM_Log(profile_info_parse4, "profile_info_parse: profile action %s\n", str); |
| info->action = atoi(str); |
| } |
| } |
| |
| if (tb[CONN_NUM]) { |
| str = blobmsg_get_string(tb[CONN_NUM]); |
| |
| if (str) { |
| CM_Log(profile_info_parse5, "profile_info_parse: connection num %s\n", str); |
| info->connection_num = atoi(str); |
| } |
| } |
| |
| if (tb[APN_TYPE]) { |
| str = blobmsg_get_string(tb[APN_TYPE]); |
| |
| if (str) { |
| CM_Log(profile_info_parse6, "profile_info_parse: apn type %s\n", str); |
| strncpy(info->type, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| return CM_OK; |
| } |
| |
| int pdp_info_parse(struct blob_attr *msg, Apn_Info * info) |
| { |
| struct blob_attr *tb[_PARAM_MAX]; |
| char *str = NULL; |
| int ret; |
| |
| if (!info) { |
| return CM_ERR_INVAL; |
| } |
| |
| ret = |
| blobmsg_parse(pdpinfo_table_pol, ARRAY_SIZE(pdpinfo_table_pol), tb, blobmsg_data(msg), |
| blobmsg_data_len(msg)); |
| |
| if (ret != CM_OK) { |
| return CM_ERR_PARSE; |
| } |
| |
| if (tb[CONNECTION_NUM]) { |
| str = blobmsg_get_string(tb[CONNECTION_NUM]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse3, "pdp_info_parse: connection number %s\n", str); |
| info->connection_num = atoi(str); |
| } |
| } |
| |
| if (tb[ENABLE]) { |
| str = blobmsg_get_string(tb[ENABLE]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse4, "pdp_info_parse: enable %s\n", str); |
| info->enable = atoi(str); |
| } |
| } |
| |
| if (tb[PDP_NAME]) { |
| str = blobmsg_get_string(tb[PDP_NAME]); |
| |
| if (str) { |
| strncpy(info->pdp_name, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[IP_TYPE]) { |
| str = blobmsg_get_string(tb[IP_TYPE]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse6, "pdp_info_parse: ip type %s\n", str); |
| info->iptype = atoi(str); |
| } |
| } |
| |
| if (tb[QCI]) { |
| str = blobmsg_get_string(tb[QCI]); |
| |
| if (str) { |
| info->qci = atoi(str); |
| } |
| } |
| |
| if (tb[APN]) { |
| str = blobmsg_get_string(tb[APN]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse8, "pdp_info_parse: apn %s\n", str); |
| strncpy(info->apn, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[LTE_APN]) { |
| str = blobmsg_get_string(tb[LTE_APN]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse9, "pdp_info_parse: lte apn %s\n", str); |
| strncpy(info->lte_apn, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[USR_2G3G]) { |
| str = blobmsg_get_string(tb[USR_2G3G]); |
| |
| if (str) { |
| strncpy(info->usrname, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[PSWD_2G3G]) { |
| str = blobmsg_get_string(tb[PSWD_2G3G]); |
| |
| if (str) { |
| strncpy(info->paswd, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[AUTHTYPE_2G3G]) { |
| str = blobmsg_get_string(tb[AUTHTYPE_2G3G]); |
| |
| if (str) { |
| strncpy(info->authtype, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[USR_4G]) { |
| str = blobmsg_get_string(tb[USR_4G]); |
| |
| if (str) { |
| strncpy(info->lte_usrname, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[PSWD_4G]) { |
| str = blobmsg_get_string(tb[PSWD_4G]); |
| |
| if (str) { |
| strncpy(info->lte_paswd, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[AUTHTYPE_4G]) { |
| str = blobmsg_get_string(tb[AUTHTYPE_4G]); |
| |
| if (str) { |
| strncpy(info->lte_authtype, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[TYPE]) { |
| str = blobmsg_get_string(tb[TYPE]); |
| |
| if (str) { |
| strncpy(info->type, str, MAX_STR_LEN - 1); |
| } |
| } |
| |
| if (tb[AUTO_APN]) { |
| str = blobmsg_get_string(tb[AUTO_APN]); |
| |
| if (str) { |
| info->auto_apn = atoi(str); |
| } |
| } |
| |
| if (tb[CONNECT_MODE]) { |
| str = blobmsg_get_string(tb[CONNECT_MODE]); |
| |
| if (str) { |
| info->Extra_params.autoconnect = atoi(str); |
| } |
| } |
| |
| if (tb[LTE_DEFAULT]) { |
| str = blobmsg_get_string(tb[LTE_DEFAULT]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse19, "pdp_info_parse: lte default %s\n", str); |
| info->Extra_params.lte_default = atoi(str); |
| } |
| } |
| |
| if (tb[DATA_ON_ROAMING]) { |
| str = blobmsg_get_string(tb[DATA_ON_ROAMING]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse20, "pdp_info_parse: data on roaming %s\n", str); |
| info->Extra_params.data_on_roaming = atoi(str); |
| } |
| } |
| |
| if (tb[MTU]) { |
| str = blobmsg_get_string(tb[MTU]); |
| |
| if (str) { |
| CM_Log(pdp_info_parse21, "pdp_info_parse: mtu %s\n", str); |
| info->mtu = atoi(str); |
| } |
| } |
| |
| return CM_OK; |
| } |
| |
| /*********************************************************************** |
| ubus method, config PDP |
| |
| request: |
| a. add profile |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>1</action> |
| </profile> |
| |
| b. delete profile |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>2</action> |
| </profile> |
| |
| c. switch profile |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>3</action> |
| </profile> |
| |
| d. add pdp |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>4</action> |
| <connection_num/> |
| <type/><!-- apn type --> |
| </profile> |
| <pdp_info> |
| <connection_num/> |
| <type/> |
| <auto_apn/> |
| <connect_mode/> |
| <lte_default/> |
| <data_on_roaming/> |
| <pdp_name/> |
| <enable/> |
| <ip_type/> |
| <apn/> |
| <lte_apn/> |
| <usr_2g3g/> |
| <pswd_2g3g/> |
| <authtype_2g3g/> |
| <usr_4g/> |
| <pswd_4g/> |
| <authtype_4g/> |
| <mtu/> |
| </pdp_info> |
| |
| e. delete pdp |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>5</action> |
| <connection_num/> |
| <type/><!-- apn type --> |
| </profile> |
| |
| f. edit pdp |
| <profile> |
| <profile_name/><!-- unique profile name, can not be NULL --> |
| <action>6</action> |
| <connection_num/> |
| <type/><!-- apn type --> |
| </profile> |
| <pdp_info> |
| <connection_num/> |
| <type/> |
| <auto_apn/> |
| <connect_mode/> |
| <lte_default/> |
| <data_on_roaming/> |
| <pdp_name/> |
| <enable/> |
| <ip_type/> |
| <apn/> |
| <lte_apn/> |
| <usr_2g3g/> |
| <pswd_2g3g/> |
| <authtype_2g3g/> |
| <usr_4g/> |
| <pswd_4g/> |
| <authtype_4g/> |
| <mtu/> |
| </pdp_info> |
| response: |
| <response> |
| <response_status>OK/ERROR</response_status> |
| </reponse> |
| |
| *************************************************************************/ |
| int configs_handler(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(method); |
| UNUSED(obj); |
| |
| s_profile_param profile_param; |
| int ret = CM_OK; |
| struct blob_attr *tb[_TABLE_MAX]; |
| void *table = NULL; |
| |
| memset(&profile_param, 0, sizeof(s_profile_param)); |
| |
| ret = blobmsg_parse(configs_handler_pol, ARRAY_SIZE(configs_handler_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[PROFILE]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| ret = profile_info_parse(tb[PROFILE], &profile_param); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| switch (profile_param.action) { |
| case ADD_PROFILE: |
| ret = add_profile(&profile_param); |
| break; |
| |
| case DELETE_PROFILE: |
| ret = delete_profile(&profile_param); |
| break; |
| |
| case SWITCH_PROFILE: |
| ret = switch_profile(&profile_param); |
| break; |
| |
| case ADD_PDP: |
| if (!(tb[PDPINFO])) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| ret = add_pdp(tb[PDPINFO], &profile_param); |
| |
| break; |
| |
| case DELETE_PDP: |
| ret = delete_pdp(&profile_param); |
| break; |
| |
| case EDIT_PDP: |
| if (!(tb[PDPINFO])) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| ret = edit_pdp(tb[PDPINFO], &profile_param); |
| break; |
| |
| default: |
| break; |
| } |
| |
| END: |
| blob_buf_init(&cm_b, 0); |
| table = blobmsg_open_table(&cm_b, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(&cm_b, "response_status", "OK"); |
| } else { |
| blobmsg_add_string(&cm_b, "response_status", "ERROR"); |
| } |
| blobmsg_close_table(&cm_b, table); |
| ubus_send_reply(ctx, req, cm_b.head); |
| |
| CM_Log(configs_handler6, "configs_handler: leave with ret %d\n", ret); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| ubus method, get auto_switch value |
| |
| request: |
| <auto-switch> |
| <enable/><!--1 enbale, 0-disable --> |
| </auto-switch> |
| |
| *************************************************************************/ |
| int get_auto_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(msg); |
| UNUSED(method); |
| |
| int ret = CM_OK; |
| struct uci_context *local_ctx = NULL; |
| const char * value = NULL; |
| int val = 0, single_version = 0; |
| char version[4] = { 0 }; |
| |
| |
| /*load /etc/config/wan */ |
| local_ctx = uci_alloc_context(); |
| if (!local_ctx) { |
| ret = CM_ERR_MEM; |
| goto END; |
| } |
| |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_element *e = NULL; |
| |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| |
| if(!p) |
| { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| uci_foreach_element(&p->sections, e) |
| { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WAN_SECTION_AUTO_SWITCH) == 0) |
| { |
| value = uci_lookup_option_string(local_ctx, uci_sec, "enable"); |
| break; |
| } |
| } |
| |
| property_get(SYS_CURRENT_CP, version, "0"); |
| |
| if (!strcmp(version, LTG_CP) || !strcmp(version, LWG_CP)) |
| single_version = 0; |
| else |
| single_version = 1; |
| |
| |
| if(!value) |
| { |
| uci_add_section(local_ctx, p, WAN_SECTION_AUTO_SWITCH, &uci_sec); |
| if(!uci_sec) |
| { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| struct uci_ptr ptr; |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "enable"; |
| ptr.value = "0"; |
| uci_set(local_ctx, &ptr); |
| uci_commit(local_ctx, &p, false); |
| } |
| else |
| { |
| val = (atoi(value) == 1)?1:0; |
| } |
| |
| if (single_version) |
| val = 2; |
| |
| blob_buf_init(&cm_b, 0); |
| blobmsg_add_u32(&cm_b, "enable", val); |
| ubus_send_reply(ctx, req, cm_b.head); |
| END: |
| uci_free_context(local_ctx); |
| return ret; |
| } |
| |
| static int get_eng_mode_uci() |
| { |
| struct uci_context *local_ctx; |
| char *option_value = NULL; |
| int ret = 0; |
| |
| /*get /etc/config/wan UCI context */ |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto exit; |
| } |
| |
| option_value = |
| uci_get_option(local_ctx, WAN_PACKAGE_NAME, WAN_SECTION_TYPE_ENG_MODE, WAN_SECTION_NAME_ENG_MODE, |
| WAN_ENG_MODE_OPTION); |
| if (option_value) { |
| ret = atoi(option_value); |
| } |
| |
| exit: |
| return ret; |
| } |
| |
| static void blobmsg_lte_svc_info(struct blob_buf *b, s_cellular_info *info) |
| { |
| void *t, *mode_t; |
| |
| t = blobmsg_open_table(b, "eng"); |
| mode_t = blobmsg_open_table(b, "lte"); |
| |
| blobmsg_add_u32(b, "mcc", info->lte_info.params.mcc); |
| blobmsg_add_u32(b, "mnc_len", info->lte_info.params.lenOfMnc); |
| blobmsg_add_u32(b, "mnc", info->lte_info.params.mnc); |
| blobmsg_add_u32(b, "tac", info->lte_info.params.tac); |
| blobmsg_add_u32(b, "phy_cell_id", info->lte_info.params.phyCellId); |
| blobmsg_add_u32(b, "cell_id", info->lte_info.params.cellId); |
| blobmsg_add_u32(b, "dl_euarfcn", info->lte_info.params.dlEuArfcn); |
| blobmsg_add_u32(b, "ul_euarfcn", info->lte_info.params.ulEuArfcn); |
| blobmsg_add_u32(b, "band", info->lte_info.params.band); |
| blobmsg_add_u32(b, "dl_bandwidth", info->lte_info.params.dlBandwidth); |
| blobmsg_add_u32(b, "transmission_mode", info->lte_info.params.transMode); |
| |
| blobmsg_add_u32(b, "rsrp", info->lte_info.meas.rsrp); |
| blobmsg_add_u32(b, "rsrq", info->lte_info.meas.rsrq); |
| blobmsg_add_u32(b, "sinr", info->lte_info.meas.sinr); |
| blobmsg_add_u32(b, "main_rsrp", info->lte_info.meas.mainRsrp); |
| blobmsg_add_u32(b, "diversity_rsrp", info->lte_info.meas.diversityRsrp); |
| blobmsg_add_u32(b, "main_rsrq", info->lte_info.meas.mainRsrq); |
| blobmsg_add_u32(b, "diversity_rsrq", info->lte_info.meas.diversityRsrq); |
| blobmsg_add_u32(b, "rssi", info->lte_info.meas.rssi); |
| blobmsg_add_u32(b, "cqi", info->lte_info.meas.cqi); |
| blobmsg_add_u32(b, "dl_bler", info->lte_info.meas.dlBler); |
| blobmsg_add_u32(b, "ul_bler", info->lte_info.meas.ulBler); |
| blobmsg_add_u32(b, "dl_throughput", info->lte_info.meas.dlThroughPut); |
| blobmsg_add_u32(b, "dl_peak_throughput", info->lte_info.meas.dlPeakThroughPut); |
| blobmsg_add_u32(b, "ul_throughput", info->lte_info.meas.ulThroughPut); |
| blobmsg_add_u32(b, "ul_peak_throughput", info->lte_info.meas.ulPeakThroughPut); |
| blobmsg_add_u32(b, "tx_power", info->lte_info.meas.currPuschTxPower); |
| |
| blobmsg_close_table(b, mode_t); |
| blobmsg_close_table(b, t); |
| } |
| |
| static void blobmsg_umts_svc_info(struct blob_buf *b, s_cellular_info *info) |
| { |
| void *t, *mode_t; |
| |
| t = blobmsg_open_table(b, "eng"); |
| mode_t = blobmsg_open_table(b, "umts"); |
| |
| blobmsg_add_u32(b, "mcc", info->umts_info.sCellParam.mcc); |
| blobmsg_add_u32(b, "mnc_len", info->umts_info.sCellParam.lenOfMnc); |
| blobmsg_add_u32(b, "mnc", info->umts_info.sCellParam.mnc); |
| blobmsg_add_u32(b, "rac", info->umts_info.sCellParam.rac); |
| blobmsg_add_u32(b, "lac", info->umts_info.sCellParam.lac); |
| blobmsg_add_u32(b, "cell_id", info->umts_info.sCellParam.ci); |
| blobmsg_add_u32(b, "arfcn", info->umts_info.sCellParam.arfcn); |
| |
| blobmsg_add_u32(b, "rscp", info->umts_info.sCellMeas.rscp); |
| blobmsg_add_u32(b, "rssi", info->umts_info.sCellMeas.utraRssi); |
| blobmsg_add_u32(b, "tx_power", info->umts_info.sCellMeas.txPower); |
| |
| blobmsg_close_table(b, mode_t); |
| blobmsg_close_table(b, t); |
| } |
| |
| #ifdef EEMOPT_QUERY_MODE |
| static int set_eng_mode_ril(int mode) |
| { |
| struct blob_buf *b = &cm_b; |
| int eemopt = mode, size = 0; |
| int ret = UBUS_STATUS_OK; |
| |
| /* send EEMOPT to enable/disable enginerring mode */ |
| blob_buf_init(b, 0); |
| size = 1; |
| rilutil_makeRequestBlobDSMaster(b, RIL_REQUEST_SET_EEMOPT, (void *)&eemopt, size); |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", b->head, NULL, 0, 5000); |
| if (ret) { |
| goto exit; |
| } |
| exit: |
| return ret; |
| } |
| #endif |
| |
| static void force_eng_info_timeout() |
| { |
| uloop_timeout_set(&cm_query_enginfo_timeout, 0); |
| } |
| |
| |
| static void cancel_eng_info_timeout() |
| { |
| uloop_timeout_cancel(&cm_query_enginfo_timeout); |
| } |
| |
| static int query_eng_info_ril() |
| { |
| struct blob_buf *b = &cm_b; |
| int ret = UBUS_STATUS_OK; |
| |
| /* send EEMGINGO request */ |
| blob_buf_init(b, 0); |
| rilutil_makeRequestBlobDSMaster(b, RIL_REQUEST_GET_EEMGINFO, NULL, 0); |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", b->head, NULL, 0, 5000); |
| if (ret) { |
| goto exit; |
| } |
| exit: |
| return ret; |
| } |
| |
| static int match_auto_apn(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| Mnc_Apn *get_Apn = NULL; |
| struct blob_buf *b_rsp = &cm_b; |
| struct blob_attr *tb[E_MCC_MNC_MAX]; |
| void *table; |
| int ret = UBUS_STATUS_OK; |
| |
| ret = |
| blobmsg_parse(mcc_mnc_pol, ARRAY_SIZE(mcc_mnc_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto exit; |
| } |
| |
| if (!tb[E_MCC] || !tb[E_MNC] ) { |
| CM_Log_E(match_auto_apn1, "match_auto_apn: no NCC or MNC\n"); |
| ret = CM_ERR_INVAL; |
| goto exit; |
| } |
| |
| get_Apn = malloc(sizeof(Mnc_Apn)); |
| if (!get_Apn) { |
| CM_Log_E(match_auto_apn2, "match_auto_apn: malloc size %d failed\n", sizeof(Mnc_Apn)); |
| return UBUS_STATUS_UNKNOWN_ERROR; |
| } |
| memset(get_Apn, 0, sizeof(Mnc_Apn)); |
| fillApnInfo(blobmsg_get_string(tb[E_MCC]), blobmsg_get_string(tb[E_MNC]), get_Apn); |
| |
| exit: |
| ret = blob_buf_init(b_rsp, 0); |
| table = blobmsg_open_table(b_rsp, "response"); |
| if (ret != UBUS_STATUS_OK) { |
| blobmsg_add_string(b_rsp, "response_status", "ERROR"); |
| } else { |
| blobmsg_add_string(b_rsp, "response_status", "OK"); |
| } |
| blobmsg_close_table(b_rsp, table); |
| |
| ubus_send_reply(ctx, req, b_rsp->head); |
| return ret; |
| } |
| |
| static int get_eng_info(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| s_cellular_info *info = &g_cell_basic_info; |
| struct blob_buf *b_rsp = &cm_b; |
| int mode, net_mode; |
| int ret = UBUS_STATUS_OK; |
| char sys_mode[16] = { 0 }; |
| void *table; |
| |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| |
| blob_buf_init(b_rsp, 0); |
| |
| mode = get_eng_mode_uci(); |
| if (!mode) { |
| ret = UBUS_STATUS_NO_DATA; |
| goto exit; |
| } |
| |
| /* prepare Engneering param to blob */ |
| if (info->sys_mode == E_NO_SERVICE) { |
| ret = UBUS_STATUS_NO_DATA; |
| goto exit; |
| } else if (info->sys_mode == E_LTE) { |
| strcpy(sys_mode, "lte"); |
| net_mode = MODE_LTE; |
| } else { |
| if ((info->data_mode == RADIO_TECH_GPRS) || (info->data_mode == RADIO_TECH_EDGE) \ |
| || (info->data_mode == RADIO_TECH_GSM)) { |
| strcpy(sys_mode, "gsm"); |
| net_mode = MODE_GSM; |
| |
| } else if (info->data_mode == RADIO_TECH_TD_SCDMA) { |
| strcpy(sys_mode, "td"); |
| net_mode = MODE_TD; |
| } else { |
| strcpy(sys_mode, "umts"); |
| net_mode = MODE_UMTS; |
| } |
| } |
| |
| switch (net_mode) { |
| case MODE_LTE: |
| blobmsg_lte_svc_info(b_rsp, info); |
| |
| /* force to refresh the data */ |
| force_eng_info_timeout(); |
| break; |
| |
| case MODE_UMTS: |
| blobmsg_umts_svc_info(b_rsp, info); |
| |
| /* force to refresh the data */ |
| force_eng_info_timeout(); |
| break; |
| case MODE_TD: |
| case MODE_GSM: |
| default: |
| break; |
| } |
| |
| exit: |
| table = blobmsg_open_table(b_rsp, "response"); |
| if (ret != UBUS_STATUS_OK) { |
| blobmsg_add_string(b_rsp, "response_status", "ERROR"); |
| } else { |
| blobmsg_add_string(b_rsp, "response_status", "OK"); |
| } |
| blobmsg_close_table(b_rsp, table); |
| |
| ubus_send_reply(ctx, req, b_rsp->head); |
| return ret; |
| } |
| |
| static void eng_mode_init() |
| { |
| int mode; |
| |
| mode = get_eng_mode_uci(); |
| |
| if (mode) { |
| uloop_timeout_set(&cm_query_enginfo_timeout, 0); |
| } else { |
| uloop_timeout_cancel(&cm_query_enginfo_timeout); |
| } |
| } |
| |
| |
| |
| static int set_eng_mode(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct blob_buf *b_rsp = &cm_b; |
| struct blob_attr *tb[_ENG_MODE_MAX]; |
| |
| char * value = NULL; |
| void *table = NULL; |
| int ret = CM_OK, val = 0; |
| |
| UNUSED(obj); |
| UNUSED(method); |
| |
| ret = |
| blobmsg_parse(eng_mode_pol, ARRAY_SIZE(eng_mode_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto exit; |
| } |
| |
| if (!tb[ENG_MODE]) { |
| ret = CM_ERR_INVAL; |
| goto exit; |
| } |
| |
| value = blobmsg_get_string(tb[ENG_MODE]); |
| |
| val = atoi(value); |
| if(val != 0 && val != 1) { |
| CM_Log_E(set_eng_mode2, "set_eng_mode: invalid eng-mode value %d \n", val); |
| val = 0; |
| } |
| |
| /*load /etc/config/wan */ |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| ret = CM_ERR_MEM; |
| goto exit; |
| } |
| |
| ret = uci_set_option(local_ctx, WAN_PACKAGE_NAME, WAN_SECTION_TYPE_ENG_MODE, WAN_SECTION_NAME_ENG_MODE, WAN_ENG_MODE_OPTION, value); |
| CM_Log(set_eng_mode4, "set_eng_mode: eng mode:%d \n", val); |
| if (val) { |
| force_eng_info_timeout(); |
| } else { |
| cancel_eng_info_timeout(); |
| } |
| |
| exit: |
| blob_buf_init(b_rsp, 0); |
| table = blobmsg_open_table(b_rsp, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(b_rsp, "setting_response", "OK"); |
| } else { |
| blobmsg_add_string(b_rsp, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(b_rsp, table); |
| |
| ubus_send_reply(ctx, req, b_rsp->head); |
| |
| CM_Log(set_eng_mode5, "set_eng_mode: leave %d\n", ret); |
| return ret; |
| } |
| |
| void cm_query_enginfo_timeout_cb(struct uloop_timeout *timeout) |
| { |
| /* enhance mode to get eng info */ |
| #ifdef EEMOPT_QUERY_MODE |
| set_eng_mode_ril(1); |
| #endif |
| query_eng_info_ril(); |
| #ifdef EEMOPT_QUERY_MODE |
| set_eng_mode_ril(0); |
| #endif |
| |
| uloop_timeout_set(timeout, QUERY_ENG_INFO_TIMEOUT); |
| CM_Log(cm_query_enginfo_timeout_cb1, "cm_query_enginfo_timeout_cb: leave\n"); |
| return; |
| } |
| |
| int set_auto_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(ctx); |
| UNUSED(req); |
| UNUSED(method); |
| |
| int ret = CM_OK; |
| struct uci_context *local_ctx = NULL; |
| struct blob_attr *tb[_CONN_SWITCH_MAX]; |
| int val = 0; |
| |
| ret = |
| blobmsg_parse(auto_switch_pol, ARRAY_SIZE(auto_switch_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[CONNECT_SWITCH]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| val = atoi(blobmsg_get_string(tb[CONNECT_SWITCH])); |
| if(val !=0 && val!=1) |
| { |
| CM_Log_E(set_auto_switch2, "set_auto_switch: invalid auto-switch value %d \n", val); |
| val =0; |
| } |
| |
| /*load /etc/config/wan */ |
| local_ctx = uci_alloc_context(); |
| if (!local_ctx) { |
| ret = CM_ERR_MEM; |
| goto END; |
| } |
| |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_element *e = NULL; |
| struct uci_ptr ptr; |
| const char * value = NULL; |
| |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| |
| if(!p) |
| { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| uci_foreach_element(&p->sections, e) |
| { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WAN_SECTION_AUTO_SWITCH) == 0) |
| { |
| value = uci_lookup_option_string(local_ctx, uci_sec, "enable"); |
| break; |
| } |
| } |
| if(!value) |
| { |
| uci_add_section(local_ctx, p, WAN_SECTION_AUTO_SWITCH, &uci_sec); |
| if(!uci_sec) |
| { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "enable"; |
| ptr.value = (val==1)?"1":"0"; |
| uci_set(local_ctx, &ptr); |
| uci_commit(local_ctx, &p, false); |
| } |
| else |
| { |
| if(uci_sec) |
| { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "enable"; |
| ptr.value = (val==1)?"1":"0"; |
| uci_set(local_ctx, &ptr); |
| uci_commit(local_ctx, &p, false); |
| } |
| } |
| CM_Log_E(set_auto_switch7, "set_auto_switch: auto_switch enable:%d \n", val); |
| if (val) { |
| /*here force to switch if needed*/ |
| blob_buf_init(&cm_b, 0); |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_IMSI, NULL, 0); |
| if ((ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, sim_info_request_cb, 0, 0)) != UBUS_STATUS_OK) { |
| CM_Log_E(set_auto_switch8, "set_auto_switch, ubus_invoke RIL_REQUEST_GET_IMSI failed %s\n", ubus_strerror(ret)); |
| goto END; |
| } |
| } |
| END: |
| uci_free_context(local_ctx); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| ubus method, enable/disable PDP |
| |
| request: |
| <connect_switch> |
| <proto/><!-- cellular/disabled always take effect --> |
| <dial_switch/><!--cellular/disabled only take effect in this boot --> |
| </connect_switch> |
| |
| response: |
| <response> |
| <response_status>OK/ERROR</response_status> |
| </reponse> |
| |
| *************************************************************************/ |
| int connection_switch(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| int ret = CM_OK; |
| struct blob_attr *tb[_CONN_SWITCH_MAX]; |
| struct uci_context *local_ctx = NULL; |
| void *table = NULL; |
| char *value = NULL; |
| char *proto_value = NULL; |
| char *dial_value = NULL; |
| int need_commit = 0; |
| enum e_proto_switch proto_switch = 0; |
| enum e_dial_switch dial_switch = 0; |
| |
| ret = |
| blobmsg_parse(connection_switch_pol, ARRAY_SIZE(connection_switch_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[CONNECT_SWITCH]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| ret = blobmsg_parse(connection_switch_table_pol, ARRAY_SIZE(connection_switch_table_pol), tb, |
| blobmsg_data(tb[CONNECT_SWITCH]), blobmsg_data_len(tb[CONNECT_SWITCH])); |
| |
| if (ret != CM_OK) { |
| goto END; |
| } |
| |
| if (!tb[PROTO]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| if (!tb[DIAL_SWITCH]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| proto_value = blobmsg_get_string(tb[PROTO]); |
| dial_value = blobmsg_get_string(tb[DIAL_SWITCH]); |
| |
| CM_Log(connection_switch5, "connection_switch: post proto [%s] dial_switch [%s] \n", proto_value ? proto_value: "NULL", dial_value ? dial_value:"NULL"); |
| /*load /etc/config/wan */ |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| ret = CM_ERR_MEM; |
| goto END; |
| } |
| |
| value = uci_get_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_PROTO); |
| if (!value) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| CM_Log(connection_switch8, "connection_switch: uci proto %s \n", value); |
| if (!strcmp(value, "cellular")) { |
| if (!strcmp(proto_value, "cellular")) { |
| // proto not changed |
| proto_switch = PROTO_CELLULAR_NO_CHANGE; |
| } else if (!strcmp(proto_value, "disabled")) { |
| // proto change from celluar to disabled |
| proto_switch = PROTO_TO_DISABLED; |
| } else { |
| proto_switch = PROTO_ERROR; |
| } |
| } else if (!strcmp(value, "disabled")) { |
| if (!strcmp(proto_value, "disabled")) { |
| // proto not changed |
| proto_switch = PROTO_DISABLED_NO_CHANGE; |
| } else if (!strcmp(proto_value, "cellular")) { |
| // proto change from disabled to cellular |
| proto_switch = PROTO_TO_CELLULAR; |
| } else { |
| proto_switch = PROTO_ERROR; |
| } |
| } |
| |
| value = |
| uci_get_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_DIAL_SWITCH); |
| if (!value) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| CM_Log(connection_switch10, "connection_switch: uci dial_switch %s \n", value); |
| if (!strcmp(value, "cellular")) { |
| if (!strcmp(dial_value, "cellular")) { |
| // dial not changed |
| dial_switch = DIAL_CELLULAR_NO_CHANGE; |
| } else if (!strcmp(dial_value, "disabled")) { |
| // dial change from celluar to disabled |
| dial_switch = DIAL_TO_DISABLED; |
| } else { |
| dial_switch = DIAL_ERROR; |
| } |
| } else if (!strcmp(value, "disabled")) { |
| if (!strcmp(dial_value, "disabled")) { |
| // dial not changed |
| dial_switch = DIAL_DISABLED_NO_CHANGE; |
| } else if (!strcmp(dial_value, "cellular")) { |
| // dial change from disabled to cellular |
| dial_switch = DIAL_TO_CELLULAR; |
| } else { |
| dial_switch = DIAL_ERROR; |
| } |
| } |
| |
| switch (proto_switch) { |
| case PROTO_TO_DISABLED: |
| ret = destroy_connection(0, 1); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_PROTO, |
| "disabled"); |
| if (ret != UCI_OK) {; |
| goto END; |
| } |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_DIAL_SWITCH, |
| "disabled"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| break; |
| case PROTO_TO_CELLULAR: |
| ret = create_connection(); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_PROTO, |
| "cellular"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_DIAL_SWITCH, |
| "cellular"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| break; |
| case PROTO_CELLULAR_NO_CHANGE: |
| switch (dial_switch) { |
| case DIAL_TO_DISABLED: |
| ret = destroy_connection(0, 1); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, |
| OPT_DIAL_SWITCH, "disabled"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| break; |
| case DIAL_TO_CELLULAR: |
| ret = create_connection(); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| ret = uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, |
| OPT_DIAL_SWITCH, "cellular"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| break; |
| default: |
| break; |
| } |
| break; |
| case PROTO_DISABLED_NO_CHANGE: |
| switch (dial_switch) { |
| case DIAL_TO_DISABLED: |
| ret = |
| uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, |
| OPT_DIAL_SWITCH, "disabled"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| break; |
| case DIAL_TO_CELLULAR: |
| ret = uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, |
| OPT_DIAL_SWITCH, "cellular"); |
| if (ret != UCI_OK) { |
| goto END; |
| } |
| need_commit = 1; |
| default: |
| break; |
| } |
| break; |
| default: |
| break; |
| } |
| |
| END: |
| #if 1 |
| if (need_commit) { |
| ret = uci_commit_package(local_ctx, WAN_PACKAGE_NAME); |
| } |
| #endif |
| blob_buf_init(&cm_b, 0); |
| table = blobmsg_open_table(&cm_b, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(&cm_b, "response_status", "OK"); |
| } else { |
| blobmsg_add_string(&cm_b, "response_status", "ERROR"); |
| } |
| blobmsg_close_table(&cm_b, table); |
| ubus_send_reply(ctx, req, cm_b.head); |
| free_wan_uci_ctx(); |
| CM_Log(connection_switch24, "connection_switch: leave ret %d\n", ret); |
| return 0; |
| } |
| |
| static void prop_set_ril_default_cid(void) |
| { |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| Apn_Info *default_apn = NULL; |
| char tmp[4] = { 0 }; |
| |
| default_apn = get_default_apninfo(g_work_apn, NULL); |
| if (default_apn && (default_apn->auto_apn || default_apn->config_by == PDP_CONFIG_ZGDCONT || default_apn->cid == CM_DEFAULT_ATTACH_CID)) |
| { |
| snprintf(tmp, sizeof(tmp) - 1, "%d", CM_DEFAULT_ATTACH_CID); |
| property_set(PROP_DEFINED_CID, tmp); |
| } |
| #endif |
| return; |
| } |
| |
| /*********************************************************************** |
| ubus method, other modules modify the default UCI file, can call this method to reload |
| the PDP configuration and perform connection handler for those new PDP parameters. |
| |
| *************************************************************************/ |
| int connection_reload(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| UNUSED(req); |
| UNUSED(method); |
| UNUSED(msg); |
| int ret = CM_OK; |
| |
| free_wan_uci_ctx(); |
| if (g_work_apn) |
| memset(g_work_apn, 0, sizeof (*g_work_apn)); |
| |
| ret = update_work_apn(IMSI_APN); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| |
| ret = CM_update_redialinterval(g_cell_basic_info.IMSI); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| |
| #ifdef CONFIG_ZGDCONT_SAVE_PDP |
| init_zgdcont_default_pdp_info(); |
| #endif |
| property_set(PROP_DEFINED_CID, "-1"); |
| prop_set_ril_default_cid(); |
| ret = connection_handler(g_work_apn); |
| if (ret != CM_OK) { |
| goto END; |
| } |
| |
| END: |
| return ret; |
| } |
| |
| /************************************************************* |
| ubus method, for other modules to get the APN info |
| request: |
| <type/><!-- apn type like "default", "ims"--> |
| |
| reponse: |
| <apn_info> |
| <type> <!-- same name as input type --> |
| <apn/> |
| <lte_apn/> |
| <usrname/> |
| <paswd/> |
| <authtype/> |
| <lte_usrname/> |
| <lte_paswd/> |
| <lte_authtype/> |
| <ip_type/> |
| </type> |
| </apn_info> |
| <response> |
| <response_status>OK/ERROR</response_status> |
| </reponse> |
| |
| **************************************************************/ |
| int get_apn_info(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| int ret = CM_OK; |
| struct blob_attr *tb[_APN_TYPE_MAX]; |
| char *apn_type = NULL; |
| Apn_Info apn_info; |
| void *table = NULL; |
| |
| memset(&apn_info, 0, sizeof(Apn_Info)); |
| |
| blob_buf_init(&cm_b, 0); |
| ret = blobmsg_parse(get_apn_info_pol, ARRAY_SIZE(get_apn_info_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[APN_TYPE_QUERY]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| apn_type = blobmsg_get_string(tb[APN_TYPE_QUERY]); |
| |
| CM_Log(get_apn_info3, "get_apn_info: apn type %s\n", apn_type); |
| ret = get_apn_info_by_type(apn_type, &apn_info); |
| if (ret != CM_OK) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| table = blobmsg_open_table(&cm_b, "apn_info"); |
| blobmsg_add_string(&cm_b, "apn", apn_info.apn); |
| blobmsg_add_string(&cm_b, "lte_apn", apn_info.lte_apn); |
| blobmsg_add_string(&cm_b, "usrname", apn_info.usrname); |
| blobmsg_add_string(&cm_b, "paswd", apn_info.paswd); |
| blobmsg_add_string(&cm_b, "authtype", apn_info.authtype); |
| blobmsg_add_string(&cm_b, "lte_usrname", apn_info.lte_usrname); |
| blobmsg_add_string(&cm_b, "lte_paswd", apn_info.lte_paswd); |
| blobmsg_add_string(&cm_b, "lte_authtype", apn_info.lte_authtype); |
| blobmsg_add_u32(&cm_b, "ip_type", apn_info.iptype); |
| blobmsg_close_table(&cm_b, table); |
| |
| END: |
| table = blobmsg_open_table(&cm_b, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(&cm_b, "response_status", "OK"); |
| } else { |
| blobmsg_add_string(&cm_b, "response_status", "ERROR"); |
| } |
| blobmsg_close_table(&cm_b, table); |
| ubus_send_reply(ctx, req, cm_b.head); |
| CM_Log(get_apn_info5, "get_apn_info: leave\n"); |
| return 0; |
| } |
| |
| |
| /************************************************************* |
| ubus method to get the auto APN info |
| request: |
| <type/><!-- apn type like "default", "ims"..., if type="all", will return all types info--> |
| |
| reponse: |
| <type> <!-- same name as input type --> |
| <Item index="0"> |
| <Item0> |
| <apn/> |
| <lte_apn/> |
| <usrname/> |
| <paswd/> |
| <authtype/> |
| <lte_usrname/> |
| <lte_paswd/> |
| <lte_authtype/> |
| <ip_type/> |
| </Item0> |
| </Item> |
| ... |
| </type> |
| <response> |
| <response_status>OK/ERROR</response_status> |
| </reponse> |
| |
| **************************************************************/ |
| static int get_auto_apn_info(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| int ret = CM_OK; |
| struct blob_attr *tb[_APN_TYPE_MAX]; |
| char *apn_type = NULL; |
| Apn_Info *apn_info; |
| int apn_num = 0, index = 0, i; |
| void *table = NULL, *array = NULL; |
| char item_buf[16] = { '\0' }; |
| Mnc_Apn *mnc_apn = NULL; |
| |
| apn_info = malloc(MAX_APN_NUM * sizeof(Apn_Info)); |
| if(!apn_info){ |
| ret = CM_ERR_MEM; |
| goto END; |
| } |
| memset(apn_info, 0, MAX_APN_NUM * sizeof(Apn_Info)); |
| |
| blob_buf_init(&cm_b, 0); |
| ret = blobmsg_parse(get_apn_info_pol, ARRAY_SIZE(get_apn_info_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[APN_TYPE_QUERY]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| apn_type = blobmsg_get_string(tb[APN_TYPE_QUERY]); |
| |
| if (!strcmp(apn_type, "all")) { |
| mnc_apn = get_mnc_apn_info(); |
| if (!mnc_apn) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| for (i = 0; i < MAX_APN_NUM; i++) { |
| if (strlen(mnc_apn->apn_info_list[i].type) && strlen(mnc_apn->apn_info_list[i].apn)) { |
| array = blobmsg_open_array(&cm_b, mnc_apn->apn_info_list[i].type); |
| sprintf(item_buf, "Item0"); |
| table = blobmsg_open_table(&cm_b, item_buf); |
| |
| blobmsg_add_string(&cm_b, APN_TYPE_STR, mnc_apn->apn_info_list[i].type); |
| blobmsg_add_u32(&cm_b, CONN_MODE_STR, mnc_apn->apn_info_list[i].Extra_params.autoconnect); |
| blobmsg_add_u32(&cm_b, LTE_DEFAULT_STR, mnc_apn->apn_info_list[i].Extra_params.lte_default); |
| blobmsg_add_u32(&cm_b, DATA_ON_ROAMING_STR, mnc_apn->apn_info_list[i].Extra_params.data_on_roaming); |
| blobmsg_add_string(&cm_b, PDP_NAME_STR, mnc_apn->apn_info_list[i].pdp_name); |
| blobmsg_add_u32(&cm_b, IP_TYPE_STR, mnc_apn->apn_info_list[i].iptype); |
| blobmsg_add_string(&cm_b, APN_STR,mnc_apn->apn_info_list[i].apn); |
| blobmsg_add_string(&cm_b, LTE_APN_STR, mnc_apn->apn_info_list[i].lte_apn); |
| blobmsg_add_string(&cm_b, USR_2G3G_STR, mnc_apn->apn_info_list[i].usrname); |
| blobmsg_add_string(&cm_b, PSWD_2G3G_STR,mnc_apn->apn_info_list[i].paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_2G3G_STR, mnc_apn->apn_info_list[i].authtype); |
| blobmsg_add_string(&cm_b, USR_4G_STR, mnc_apn->apn_info_list[i].lte_usrname); |
| blobmsg_add_string(&cm_b, PSWD_4G_STR, mnc_apn->apn_info_list[i].lte_paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_4G_STR, mnc_apn->apn_info_list[i].lte_authtype); |
| blobmsg_add_u32(&cm_b, NET_MTU_STR, mnc_apn->apn_info_list[i].mtu); |
| blobmsg_add_string(&cm_b, MMSC_STR, mnc_apn->apn_info_list[i].mmsc); |
| blobmsg_add_string(&cm_b, MMS_PROXY_STR, mnc_apn->apn_info_list[i].mmsproxy); |
| blobmsg_add_string(&cm_b, MMS_PORT_STR, mnc_apn->apn_info_list[i].mmsport); |
| |
| blobmsg_close_table(&cm_b, table); |
| blobmsg_close_array(&cm_b, array); |
| } |
| } |
| goto END; |
| } |
| |
| mnc_apn = get_mnc_apn_info(); |
| |
| CM_Log(get_auto_apn_info4, "get_auto_apn_info: apn type %s\n", apn_type); |
| ret = get_auto_apn_info_by_type(apn_type, apn_info, &apn_num); |
| if (ret != CM_OK) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| array = blobmsg_open_array(&cm_b, apn_type); |
| |
| for (index = 0; index < apn_num; index++) |
| { |
| sprintf(item_buf, "Item%d", index); |
| table = blobmsg_open_table(&cm_b, item_buf); |
| |
| blobmsg_add_string(&cm_b, APN_TYPE_STR, apn_info[index].type); |
| blobmsg_add_u32(&cm_b, CONN_MODE_STR, apn_info[index].Extra_params.autoconnect); |
| blobmsg_add_u32(&cm_b, LTE_DEFAULT_STR, apn_info[index].Extra_params.lte_default); |
| blobmsg_add_u32(&cm_b, DATA_ON_ROAMING_STR, apn_info[index].Extra_params.data_on_roaming); |
| blobmsg_add_string(&cm_b, PDP_NAME_STR, apn_info[index].pdp_name); |
| blobmsg_add_u32(&cm_b, IP_TYPE_STR, apn_info[index].iptype); |
| blobmsg_add_string(&cm_b, APN_STR, apn_info[index].apn); |
| blobmsg_add_string(&cm_b, LTE_APN_STR, apn_info[index].lte_apn); |
| blobmsg_add_string(&cm_b, USR_2G3G_STR, apn_info[index].usrname); |
| blobmsg_add_string(&cm_b, PSWD_2G3G_STR, apn_info[index].paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_2G3G_STR, apn_info[index].authtype); |
| blobmsg_add_string(&cm_b, USR_4G_STR, apn_info[index].lte_usrname); |
| blobmsg_add_string(&cm_b, PSWD_4G_STR, apn_info[index].lte_paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_4G_STR, apn_info[index].lte_authtype); |
| blobmsg_add_u32(&cm_b, NET_MTU_STR, apn_info[index].mtu); |
| blobmsg_add_string(&cm_b, MMSC_STR, apn_info[index].mmsc); |
| blobmsg_add_string(&cm_b, MMS_PROXY_STR, apn_info[index].mmsproxy); |
| blobmsg_add_string(&cm_b, MMS_PORT_STR, apn_info[index].mmsport); |
| |
| blobmsg_close_table(&cm_b, table); |
| } |
| |
| blobmsg_close_array(&cm_b, array); |
| |
| END: |
| if(apn_info){ |
| free(apn_info); |
| apn_info = NULL; |
| } |
| table = blobmsg_open_table(&cm_b, "response"); |
| if (ret == CM_OK) { |
| blobmsg_add_string(&cm_b, "response_status", "OK"); |
| } else { |
| blobmsg_add_string(&cm_b, "response_status", "ERROR"); |
| } |
| blobmsg_close_table(&cm_b, table); |
| ubus_send_reply(ctx, req, cm_b.head); |
| |
| CM_Log(get_auto_apn_info6, "get_auto_apn_info: done\n"); |
| return 0; |
| } |
| |
| /************************************************************* |
| ubus method, for get all PDP configuration parameters with all profiles which |
| are located in /etc/config/ |
| |
| response: |
| <connect_switch> |
| <proto/> |
| <dial_switch/> |
| </connect_switch> |
| <profile> |
| <actived_profile/> |
| <profile_names/> <!-- profile0, profile1,profile2--> |
| </profile> |
| <profile_name> <!--named profile name if exist> |
| <Item index="1"> |
| <type><!-- apn type --> |
| <connection_num/> |
| <type/> |
| <auto_apn/> |
| <connect_mode/> |
| <lte_default/> |
| <data_on_roaming/> |
| <pdp_name/> |
| <enable/> |
| <ip_type/> |
| <apn/> |
| <lte_apn/> |
| <usr_2g3g/> |
| <pswd_2g3g/> |
| <authtype_2g3g/> |
| <usr_4g/> |
| <pswd_4g/> |
| <authtype_4g/> |
| <mtu/> |
| </type> |
| </Item> |
| <Item index="2"> |
| <type><!-- apn type --> |
| <connection_num/> |
| <type/> |
| <auto_apn/> |
| <connect_mode/> |
| <lte_default/> |
| <data_on_roaming/> |
| <pdp_name/> |
| <enable/> |
| <ip_type/> |
| <apn/> |
| <lte_apn/> |
| <usr_2g3g/> |
| <pswd_2g3g/> |
| <authtype_2g3g/> |
| <usr_4g/> |
| <pswd_4g/> |
| <authtype_4g/> |
| <mtu/> |
| </type> |
| </Item> |
| ... |
| </profile_name> |
| <profile_name1><!--named profile name if exist> |
| ... |
| </profile_name1> |
| ... |
| **************************************************************/ |
| static int get_wan_configs(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| const char *option_value = NULL; |
| void *tb = NULL, *array_tb = NULL; |
| int ret_val = 0; |
| char default_name[MAX_STR_LEN] = { 0 }; |
| char package_name[MAX_STR_LEN] = { 0 }; |
| int profile_count = 0, i, j, n = 0; |
| char tmp_buf[MAX_PROFILE_NUM * MAX_STR_LEN] = { 0 }; |
| Mnc_Apn *uci_apn[MAX_APN_NUM] = { NULL }; |
| char *profile_name[MAX_APN_NUM] = { NULL }; |
| Apn_Info *apn_info = NULL; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| /*load /etc/config/wan */ |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto END; |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WAN_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| |
| if (!p) { |
| uci_load(local_ctx, WAN_PACKAGE_NAME, &p); |
| } |
| |
| if (!p) { |
| goto END; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| |
| if (strcmp(uci_sec->type, WAN_SECTION_WAN_CONNECT_WITCH) == 0) { |
| if (uci_sec->e.name) { |
| tb = blobmsg_open_table(&cm_b, uci_sec->e.name); |
| } else { |
| memset(default_name, 0, MAX_STR_LEN); |
| snprintf(default_name, MAX_STR_LEN - 1, "connect_switch"); |
| tb = blobmsg_open_table(&cm_b, default_name); |
| } |
| |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "proto"); |
| if (option_value) { |
| /*get proto */ |
| blobmsg_add_string(&cm_b, "proto", option_value); |
| } |
| |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "dial_switch"); |
| if (option_value) { |
| /*get dial_switch */ |
| CM_Log(get_wan_configs3, "get dial_switch %s", option_value); |
| blobmsg_add_string(&cm_b, "dial_switch", option_value); |
| } |
| |
| if (tb) { |
| blobmsg_close_table(&cm_b, tb); |
| tb = NULL; |
| } |
| }else if (strcmp(uci_sec->type, WAN_SECTION_TYPE_ENG_MODE) == 0) { |
| if (uci_sec->e.name) { |
| tb = blobmsg_open_table(&cm_b, uci_sec->e.name); |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, WAN_ENG_MODE_OPTION); |
| if (option_value) { |
| /*get enable option */ |
| blobmsg_add_string(&cm_b, WAN_ENG_MODE_OPTION, option_value); |
| } |
| blobmsg_close_table(&cm_b, tb); |
| } |
| } |
| } |
| |
| //get profile info |
| option_value = |
| uci_get_option(local_ctx, WAN_PACKAGE_NAME, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, |
| ACTIVE_PROFILE_STR); |
| tb = blobmsg_open_table(&cm_b, "profile"); |
| if(option_value != NULL) |
| blobmsg_add_string(&cm_b, "actived_profile", option_value); |
| |
| profile_count = |
| uci_get_list_number(local_ctx, WAN_PACKAGE_NAME, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, |
| PROFILE_LIST_STR); |
| if (profile_count > 0 && profile_count <= MAX_APN_NUM) { |
| for (i = 0; i < profile_count; i++) { |
| option_value = |
| uci_get_list_value(local_ctx, WAN_PACKAGE_NAME, PROFILE_CONFIG_TYPE_STR, |
| PROFILE_CONFIG_NAME_STR, PROFILE_LIST_STR, i); |
| |
| if (option_value != NULL) { |
| CM_Log(get_wan_configs5, "list[%d] %s\n", i, option_value); |
| profile_name[i] = malloc(MAX_STR_LEN); |
| if (!profile_name[i]) { |
| goto END; |
| } |
| memset(profile_name[i], 0, MAX_STR_LEN); |
| strncpy(profile_name[i], option_value, MAX_STR_LEN - 1); |
| |
| n += snprintf(tmp_buf + n, MAX_PROFILE_NUM * MAX_STR_LEN - n - 1, "%s,", option_value); |
| |
| uci_apn[i] = malloc(sizeof(Mnc_Apn)); |
| if (!uci_apn[i]) { |
| goto END; |
| } |
| memset(uci_apn[i], 0, sizeof(Mnc_Apn)); |
| snprintf(package_name, MAX_STR_LEN - 1, "wan_%s", option_value); |
| ret_val = fill_uci_apn(package_name, uci_apn[i]); |
| |
| if (ret_val != CM_OK) { |
| goto END; |
| } |
| |
| } |
| } |
| CM_Log(get_wan_configs9, "profile_names %s\n", tmp_buf); |
| blobmsg_add_string(&cm_b, "profile_names", tmp_buf); |
| } else { |
| CM_Log_E(get_wan_configs10, "get_wan_configs:[ERROR] no profile_names list\n"); |
| goto END; |
| } |
| |
| if (tb) { |
| blobmsg_close_table(&cm_b, tb); |
| tb = NULL; |
| } |
| |
| for (i = 0; i < profile_count; i++) { |
| array_tb = blobmsg_open_array(&cm_b, profile_name[i]); |
| |
| for (j = 0; j < MAX_APN_NUM; j++) { |
| apn_info = &(uci_apn[i]->apn_info_list[j]); |
| |
| if (!strlen(apn_info->type)) |
| continue; |
| |
| tb = blobmsg_open_table(&cm_b, apn_info->type); |
| |
| blobmsg_add_u32(&cm_b, CONN_NUM_STR, apn_info->connection_num); |
| blobmsg_add_string(&cm_b, APN_TYPE_STR, apn_info->type); |
| blobmsg_add_u32(&cm_b, AUTO_APN_STR, apn_info->auto_apn); |
| blobmsg_add_u32(&cm_b, CONN_MODE_STR, apn_info->Extra_params.autoconnect); |
| blobmsg_add_u32(&cm_b, LTE_DEFAULT_STR, apn_info->Extra_params.lte_default); |
| blobmsg_add_u32(&cm_b, DATA_ON_ROAMING_STR, apn_info->Extra_params.data_on_roaming); |
| blobmsg_add_string(&cm_b, PDP_NAME_STR, apn_info->pdp_name); |
| blobmsg_add_u32(&cm_b, ENABLE_STR, apn_info->enable); |
| blobmsg_add_u32(&cm_b, IP_TYPE_STR, apn_info->iptype); |
| blobmsg_add_string(&cm_b, APN_STR, apn_info->apn); |
| blobmsg_add_string(&cm_b, LTE_APN_STR, apn_info->lte_apn); |
| blobmsg_add_string(&cm_b, USR_2G3G_STR, apn_info->usrname); |
| blobmsg_add_string(&cm_b, PSWD_2G3G_STR, apn_info->paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_2G3G_STR, apn_info->authtype); |
| blobmsg_add_string(&cm_b, USR_4G_STR, apn_info->lte_usrname); |
| blobmsg_add_string(&cm_b, PSWD_4G_STR, apn_info->lte_paswd); |
| blobmsg_add_string(&cm_b, AUTHTYPE_4G_STR, apn_info->lte_authtype); |
| blobmsg_add_u32(&cm_b, NET_MTU_STR, apn_info->mtu); |
| |
| if (tb) { |
| blobmsg_close_table(&cm_b, tb); |
| tb = NULL; |
| } |
| } |
| |
| if (array_tb) { |
| blobmsg_close_array(&cm_b, array_tb); |
| array_tb = NULL; |
| } |
| } |
| |
| END: |
| for (i = 0; i < profile_count; i++) { |
| if (profile_name[i]) { |
| free(profile_name[i]); |
| profile_name[i] = NULL; |
| } |
| |
| if (uci_apn[i]) { |
| free(uci_apn[i]); |
| uci_apn[i] = NULL; |
| } |
| } |
| |
| if (tb) { |
| blobmsg_close_table(&cm_b, tb); |
| tb = NULL; |
| } |
| |
| if (array_tb) { |
| blobmsg_close_array(&cm_b, array_tb); |
| array_tb = NULL; |
| } |
| |
| ubus_send_reply(ctx, req, cm_b.head); |
| //free_uci_profile_ctx(); |
| CM_Log(get_wan_configs11, "get_wan_configs: leave %d\n", ret_val); |
| return ret_val; |
| } |
| |
| /* |
| <network_activity> |
| <Item index="1"> |
| <Item0> |
| <pdp_name/> |
| <cid/> |
| <index/> |
| <start_time/> |
| <end_time/> |
| <ip_type/> |
| <ipv4addr/> |
| <ipv6addr/> |
| </Item0> |
| </Item> |
| <Item index="2"> |
| <Item1> |
| <pdp_name/> |
| <cid/> |
| <index/> |
| <start_time/> |
| <end_time/> |
| <ip_type/> |
| <ipv4addr/> |
| <ipv6addr/> |
| </Item1> |
| </Item> |
| ... |
| </network_activity> |
| |
| */ |
| static int get_network_activity(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| |
| void * array; |
| void * table; |
| int index, array_idx; |
| char item_buf[16]; |
| char ip_buf[68]; |
| time_t cur_time; |
| unsigned int connect_seconds = 0; |
| unsigned int total_seconds = 0; |
| |
| blob_buf_init(&cm_b, 0); |
| array = blobmsg_open_array(&cm_b, "network_activity"); |
| |
| index = 0; |
| |
| time(&cur_time); |
| while(index < cur_nwarray_num) { |
| if(index < cur_nwarray_index) |
| array_idx = cur_nwarray_index - index - 1; |
| else |
| array_idx = MAX_NWACTIVITY_ARRAYNUM - (index - cur_nwarray_index) - 1; |
| |
| CM_Log(get_network_activity1, "get_network_activity, index:%d, array index:%d", index, array_idx); |
| if(nwactivity_array[array_idx].index == -1) { |
| index++; |
| continue; |
| } |
| sprintf(item_buf, "Item%d", index); |
| table = blobmsg_open_table(&cm_b, item_buf); |
| |
| blobmsg_add_string(&cm_b, "pdp_name", nwactivity_array[array_idx].PDP_name); |
| blobmsg_add_u32(&cm_b, "cid", nwactivity_array[array_idx].cid); |
| blobmsg_add_u32(&cm_b, "index", nwactivity_array[array_idx].index); |
| blobmsg_add_string(&cm_b, "start_time", nwactivity_array[array_idx].start_tim); |
| blobmsg_add_string(&cm_b, "end_time", nwactivity_array[array_idx].end_tim); |
| blobmsg_add_u32(&cm_b, "ip_type", nwactivity_array[array_idx].iptype); |
| |
| if (nwactivity_array[array_idx].connect_ticks > 0) |
| { |
| if (cur_time >= nwactivity_array[array_idx].connect_ticks) |
| connect_seconds = cur_time - nwactivity_array[array_idx].connect_ticks; |
| |
| total_seconds = connect_seconds + nwactivity_array[array_idx].duration_time; |
| } |
| else |
| { |
| connect_seconds = nwactivity_array[array_idx].current_duration_time; |
| total_seconds = nwactivity_array[array_idx].duration_time; |
| } |
| |
| blobmsg_add_u32(&cm_b, "current_duration", connect_seconds); |
| blobmsg_add_u32(&cm_b, "duration", total_seconds); |
| CM_Log(get_network_activity4425, "get_network_activity, current_duration %d, duration %d", connect_seconds, total_seconds); |
| |
| |
| memset(ip_buf, 0, 68); |
| inet_ntop(AF_INET, &(nwactivity_array[array_idx].ipv4addr), ip_buf, 68); |
| blobmsg_add_string(&cm_b, "ipv4addr", ip_buf); |
| |
| memset(ip_buf, 0, 68); |
| inet_ntop(AF_INET6, &(nwactivity_array[array_idx].ipv6addr), ip_buf, 68); |
| blobmsg_add_string(&cm_b, "ipv6addr", ip_buf); |
| |
| blobmsg_close_table(&cm_b, table); |
| index ++; |
| } |
| |
| blobmsg_close_array(&cm_b, array); |
| |
| ubus_send_reply(ctx, req, cm_b.head); |
| |
| return 0; |
| } |
| |
| /* |
| <network_duration> |
| <Item index="1"> |
| <Item0> |
| <current_duration/> |
| <duration/> |
| </Item0> |
| </Item> |
| <Item index="2"> |
| <Item1> |
| <current_duration/> |
| <duration/> |
| </Item1> |
| </Item> |
| ... |
| </network_duration> |
| |
| */ |
| static int get_network_duration(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| UNUSED(msg); |
| |
| void * array; |
| void * table; |
| int index; |
| char item_buf[8]; |
| time_t cur_time; |
| unsigned int connect_seconds = 0; |
| unsigned int total_seconds = 0; |
| network_duration_s *item = NULL; |
| |
| blob_buf_init(&cm_b, 0); |
| array = blobmsg_open_array(&cm_b, "network_duration"); |
| |
| index = 0; |
| time(&cur_time); |
| |
| while(index < MAX_CID_LIMITATION) { |
| item = &nw_duration[index]; |
| if(item->cid != index && item->connect_ticks == 0 && item->duration_time == 0) { |
| index++; |
| continue; |
| } |
| sprintf(item_buf, "Item%d", index); |
| table = blobmsg_open_table(&cm_b, item_buf); |
| blobmsg_add_u32(&cm_b, "cid", item->cid); |
| |
| if (item->connect_ticks > 0) |
| { |
| if (cur_time >= item->connect_ticks) |
| connect_seconds = cur_time - item->connect_ticks; |
| |
| total_seconds = connect_seconds + item->duration_time; |
| } |
| else |
| { |
| connect_seconds = item->current_duration_time; |
| total_seconds = item->duration_time; |
| } |
| |
| blobmsg_add_u32(&cm_b, "current_duration", connect_seconds); |
| blobmsg_add_u32(&cm_b, "duration", total_seconds); |
| CM_Log(get_network_duration4572, "get_network_duration, current_duration %d, duration %d", connect_seconds, total_seconds); |
| |
| blobmsg_close_table(&cm_b, table); |
| index ++; |
| } |
| |
| blobmsg_close_array(&cm_b, array); |
| |
| ubus_send_reply(ctx, req, cm_b.head); |
| |
| return 0; |
| } |
| |
| static int get_network_duration_ccinet(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(obj); |
| UNUSED(method); |
| |
| struct blob_attr *cm_ccinet[ARRAY_SIZE(cm_get_ccinet_pol)]; |
| void * table; |
| int cid; |
| time_t cur_time; |
| unsigned int connect_seconds = 0; |
| unsigned int total_seconds = 0; |
| network_duration_s *item = NULL; |
| |
| if (blobmsg_parse |
| (cm_get_ccinet_pol, ARRAY_SIZE(cm_get_ccinet_pol), cm_ccinet, blob_data(msg), |
| blob_len(msg)) != 0) { |
| return UBUS_STATUS_INVALID_ARGUMENT; |
| } |
| if (!cm_ccinet[0]) { |
| return UBUS_STATUS_NO_DATA; |
| } |
| |
| cid = blobmsg_get_u32(cm_ccinet[0]); |
| item = &nw_duration[cid]; |
| |
| blob_buf_init(&cm_b, 0); |
| table = blobmsg_open_table(&cm_b, "network_duration"); |
| |
| time(&cur_time); |
| if (item->connect_ticks > 0) |
| { |
| if (cur_time >= item->connect_ticks) |
| connect_seconds = cur_time - item->connect_ticks; |
| |
| total_seconds = connect_seconds + item->duration_time; |
| } |
| else |
| { |
| connect_seconds = item->current_duration_time; |
| total_seconds = item->duration_time; |
| } |
| |
| blobmsg_add_u32(&cm_b, "current_duration", connect_seconds); |
| blobmsg_add_u32(&cm_b, "duration", total_seconds); |
| CM_Log(get_network_duration_ccinet4676, "get_network_duration_ccinet: current_duration %d, duration %d", connect_seconds, total_seconds); |
| blobmsg_close_table(&cm_b, table); |
| ubus_send_reply(ctx, req, cm_b.head); |
| blob_buf_free(&cm_b); |
| return 0; |
| } |
| |
| static int delete_network_activity(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| UNUSED(ctx); |
| UNUSED(obj); |
| UNUSED(req); |
| UNUSED(method); |
| |
| int ret, index, flag, idx; |
| char * str = NULL; |
| struct blob_attr *tb[NWACTIVITY_MAX]; |
| |
| blob_buf_init(&cm_b, 0); |
| ret = blobmsg_parse(del_nwactivity_pol, ARRAY_SIZE(del_nwactivity_pol), tb, blob_data(msg), blob_len(msg)); |
| |
| if (ret != CM_OK) { |
| ret = CM_ERR_PARSE; |
| goto END; |
| } |
| |
| if (!tb[NWACTIVITY_DEL_INDEX]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| str = blobmsg_get_string(tb[NWACTIVITY_DEL_INDEX]); |
| index = atoi(str); |
| |
| if (!tb[NWACTIVITY_DEL_FLAG]) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| str = blobmsg_get_string(tb[NWACTIVITY_DEL_FLAG]); |
| flag = atoi(str); |
| |
| if(flag == 0){ |
| //delete the index |
| CM_Log(delete_network_activity4, "delete_network_activity, delete index:%d", index); |
| if(index >= cur_nwarray_num) { |
| ret = CM_ERR_INVAL; |
| goto END; |
| } |
| |
| for(idx = 0; idx < MAX_NWACTIVITY_ARRAYNUM; idx++) { |
| if(nwactivity_array[idx].index == index) { |
| CM_Log(delete_network_activity6, "find the index in array:%d",idx); |
| memset(&nwactivity_array[idx], 0, sizeof(network_activity_array)); |
| nwactivity_array[idx].index = -1; |
| break; |
| } |
| } |
| |
| }else if(flag == 1) { |
| CM_Log(delete_network_activity7, "delete_network_activity, delete all items"); |
| nwactivity_arrary_init(); |
| } |
| |
| END: |
| return ret; |
| } |
| |
| int is_pdp_auto_apn(Mnc_Apn * work_apn, char *apn_type) |
| { |
| int i; |
| Apn_Info *apn_info = NULL; |
| |
| if (!work_apn) { |
| return 0; |
| } |
| |
| for (i = 0; i < MAX_APN_NUM; i++) { |
| apn_info = &(work_apn->apn_info_list[i]); |
| |
| if (strstr(apn_info->type, apn_type)) { |
| CM_Log(is_pdp_auto_apn, "is_pdp_auto_apn: leave, auto apn %d\n", apn_info->auto_apn); |
| return apn_info->auto_apn; |
| } |
| } |
| return 0; |
| |
| } |
| |
| int is_pdp_auto_mode(Mnc_Apn * work_apn, char *apn_type) |
| { |
| int i; |
| Apn_Info *apn_info = NULL; |
| |
| #ifdef PIPE_MANUAL_CONNECT |
| if (pipe_mode) |
| return 0; |
| #endif |
| |
| if (!work_apn) { |
| return 0; |
| } |
| |
| for (i = 0; i < MAX_APN_NUM; i++) { |
| apn_info = &(work_apn->apn_info_list[i]); |
| |
| if (strstr(apn_info->type, apn_type)) { |
| if (apn_info->enable) { |
| CM_Log(is_pdp_auto_mode, "is_pdp_auto_mode: leave, autoconnect %d\n", apn_info->Extra_params.autoconnect); |
| return apn_info->Extra_params.autoconnect; |
| } |
| } |
| } |
| return 0; |
| } |
| |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| static int is_pdp_data_on_boot(Mnc_Apn * work_apn, char *apn_type) |
| { |
| int i; |
| Apn_Info *apn_info = NULL; |
| |
| #ifdef PIPE_MANUAL_CONNECT |
| if (pipe_mode) |
| return 0; |
| #endif |
| |
| if (!work_apn) { |
| return 0; |
| } |
| |
| for (i = 0; i < MAX_APN_NUM; i++) { |
| apn_info = &(work_apn->apn_info_list[i]); |
| |
| if (strstr(apn_info->type, apn_type)) { |
| if (apn_info->enable) { |
| CM_Log(is_pdp_data_on_boot, "is_pdp_data_on_boot: leave, always_on(data_on_boot) %d\n", apn_info->Extra_params.always_on); |
| return apn_info->Extra_params.always_on; |
| } |
| } |
| } |
| return 0; |
| } |
| #endif |
| int set_default_data_call() |
| { |
| int ret = CM_OK; |
| |
| |
| #ifdef CONFIG_CM_P701 |
| #ifdef PIPE_MANUAL_CONNECT |
| if (pipe_mode) |
| ret = cm_get_zroam_list_ril(); |
| #endif |
| #endif |
| |
| ret = init_apn_list(); |
| if (ret != CM_OK) { |
| CM_Log_E(set_default_data_call1, "set_default_data_call: init APN list failed\n"); |
| goto end; |
| } |
| |
| property_set(PROP_DEFINED_CID, "-1"); |
| prop_set_ril_default_cid(); |
| if (!cm_allow_datalink()) |
| { |
| CM_Log(set_default_data_call4834, "set_default_data_call: cm not allow datalink\n"); |
| return ret; |
| } |
| |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| if (is_pdp_data_on_boot(g_work_apn, "default")) |
| #else |
| if (is_pdp_auto_mode(g_work_apn, "default")) |
| #endif |
| { |
| CM_Log(set_default_data_call2, "set_default_data_call: auto connect\n"); |
| ret = connection_handler(g_work_apn); |
| return ret; |
| } |
| end: |
| |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| if (!is_pdp_data_on_boot(g_work_apn, "default")) |
| { |
| CM_Log(set_default_data_call4612, "set_default_data_call: data on boot disabled\n"); |
| return ret; |
| } |
| #else |
| dialer_query_defaultdatacall(); |
| if (ret != CM_OK && !CM_IsDefaultCtxExist()) |
| { |
| send_redialmsg_to_redialthread(-1, REDIAL_DEFAULT_DATACALL); |
| } |
| #endif |
| CM_Log(set_default_data_call4, "set_default_data_call: ret %d\n", ret); |
| return ret; |
| } |
| |
| extern pthread_mutex_t cm_mutex; |
| static void set_single_stack_data_call() |
| { |
| CM_Connection_Context *ctx = NULL; |
| CM_Connection_Context *connect_ctx = NULL; |
| Apn_Info apn_info; |
| char value_buf[16]; |
| |
| |
| CM_Log(set_single_stack_data_call4876, "set_single_stack_data_call: current cid %d\n", get_current_cid()); |
| connect_ctx = cm_get_ctx_by_cid(get_current_cid()); |
| if (connect_ctx == NULL || connect_ctx->pdpinfo == NULL) |
| return; |
| |
| memset(&apn_info, 0, sizeof(apn_info)); |
| |
| CM_Log(set_single_stack_data_call4876, "set_single_stack_data_call: IP_Type %d\n", connect_ctx->pdpinfo->IP_Type); |
| if (connect_ctx->pdpinfo->IP_Type == IPV4V6 ) |
| { |
| CM_Log(set_single_stack_data_call4876, "set_single_stack_data_call: eps_ipType %d\n", connect_ctx->pdpinfo->eps_ipType); |
| if (connect_ctx->pdpinfo->eps_ipType == IPV4) |
| apn_info.iptype = IPV6; |
| else if (connect_ctx->pdpinfo->eps_ipType == IPV6) |
| apn_info.iptype = IPV4; |
| else |
| return; |
| } |
| else if (connect_ctx->pdpinfo->eps_ipType == IPV4) |
| apn_info.iptype = IPV6; |
| else if (connect_ctx->pdpinfo->eps_ipType == IPV6) |
| apn_info.iptype = IPV4; |
| |
| strncpy(apn_info.apn, connect_ctx->pdpinfo->APN, sizeof(apn_info.apn) - 1); |
| strncpy(apn_info.lte_apn, connect_ctx->pdpinfo->LteAPN, sizeof(apn_info.lte_apn) - 1); |
| strncpy(apn_info.pdp_name, connect_ctx->pdpinfo->PDP_name, sizeof(apn_info.pdp_name) - 1); |
| strncpy(apn_info.authtype, connect_ctx->pdpinfo->Authtype2G3G, sizeof(apn_info.authtype) - 1); |
| strncpy(apn_info.usrname, connect_ctx->pdpinfo->Usr2G3G, sizeof(apn_info.usrname) - 1); |
| strncpy(apn_info.paswd, connect_ctx->pdpinfo->PASWD2G3G, sizeof(apn_info.paswd) - 1); |
| strncpy(apn_info.lte_authtype, connect_ctx->pdpinfo->Authtype4G, sizeof(apn_info.lte_authtype) - 1); |
| strncpy(apn_info.lte_usrname, connect_ctx->pdpinfo->Usr4G, sizeof(apn_info.lte_usrname) - 1); |
| strncpy(apn_info.lte_paswd, connect_ctx->pdpinfo->PASWD4G, sizeof(apn_info.lte_paswd) - 1); |
| apn_info.mtu = connect_ctx->pdpinfo->mtu; |
| |
| apn_info.Extra_params.autoconnect = 0; |
| apn_info.Extra_params.always_on = 0; |
| apn_info.Extra_params.data_on_roaming = connect_ctx->pdpinfo->data_on_roaming; |
| apn_info.auto_apn = 0; |
| |
| if (get_current_cid() > 1) |
| apn_info.cid = get_current_cid() - 1; |
| else |
| apn_info.cid = get_current_cid() + 1; |
| |
| pthread_mutex_lock(&cm_mutex); |
| CM_Log(set_single_stack_data_call4964, "set_single_stack_data_call: cm_mutex locked\n"); |
| //coverity[string_null:SUPPRESS] |
| ctx = create_new_pdp_ctx(&apn_info); |
| if (ctx == NULL) |
| return; |
| |
| ctx->pdpinfo->parent_cid = get_current_cid(); |
| ctx->connectStatus = CM_CONNECT_CONNING; |
| |
| snprintf(value_buf, sizeof(value_buf), "%d", apn_info.cid); |
| property_set(PROP_DEFINED_CID, value_buf); |
| property_set(PROP_SINGLE_STACK_CID, value_buf); |
| pthread_mutex_unlock(&cm_mutex); |
| CM_Log(set_single_stack_data_call4976, "set_single_stack_data_call: cm_mutex unlocked\n"); |
| SetupDataCall(ctx); |
| QueryDataCall(ctx); |
| property_set(PROP_DEFINED_CID, "-1"); |
| } |
| |
| static const struct ubus_method cm_methods[] = { |
| UBUS_METHOD_NOARG("create_pdp", CreatePdp_method), |
| UBUS_METHOD("destroy_pdp", DestroyConnecion_method, destroy_connection_policy), |
| UBUS_METHOD("get_link_context", GetLinkContext_method, get_link_context_policy), |
| UBUS_METHOD("cm_set_image_type", SetImageType_method, cm_set_image_policy), |
| UBUS_METHOD_NOARG("cm_get_image_type", GetImageType_method), |
| UBUS_METHOD_NOARG("get_wan_configs", get_wan_configs), |
| UBUS_METHOD_NOARG("reload", connection_reload), |
| UBUS_METHOD("connection_switch", connection_switch, connection_switch_pol), |
| UBUS_METHOD("configs_handler", configs_handler, configs_handler_pol), |
| UBUS_METHOD("get_apn_info", get_apn_info, get_apn_info_pol), |
| UBUS_METHOD_NOARG("get_network_activity", get_network_activity), |
| UBUS_METHOD("delete_network_activity", delete_network_activity, del_nwactivity_pol), |
| UBUS_METHOD("set_auto_switch", set_auto_switch, auto_switch_pol), |
| UBUS_METHOD_NOARG("get_auto_switch",get_auto_switch), |
| UBUS_METHOD("set_eng_mode", set_eng_mode, eng_mode_pol), |
| UBUS_METHOD_NOARG("get_eng_info",get_eng_info), |
| UBUS_METHOD("match_auto_apn", match_auto_apn, mcc_mnc_pol), |
| UBUS_METHOD("get_auto_apn", get_auto_apn_info, get_apn_info_pol), |
| UBUS_METHOD_NOARG("get_network_duration", get_network_duration), |
| UBUS_METHOD("get_network_duration_ccinet", get_network_duration_ccinet, cm_get_ccinet_pol), |
| }; |
| |
| static struct ubus_object_type cm_object_type = UBUS_OBJECT_TYPE("test", cm_methods); |
| |
| static struct ubus_object cm_object = { |
| .name = "cm", |
| .type = &cm_object_type, |
| .methods = cm_methods, |
| .n_methods = ARRAY_SIZE(cm_methods), |
| //.subscribe_cb = cm_subscribe_cb, |
| }; |
| |
| void *redial_task(void *argv) |
| { |
| UNUSED(argv); |
| msg_hdr receive_msg; |
| int read_len = 0; |
| |
| cm_client_fd.fd = usock(USOCK_UNIX, CM_INNER_CONN_SOCKET, NULL); |
| if (cm_client_fd.fd < 0) { |
| CM_Log_E(redial_task, "Failed to connect to server\n"); |
| return NULL; |
| } |
| CM_Log(redial_task1, "client fd %d", cm_client_fd.fd); |
| |
| while (1) { |
| |
| CM_Log(redial_task2, "redial_task:[client] pending to read the data from socket %d\n", cm_client_fd.fd); |
| read_len = read(cm_client_fd.fd, &receive_msg, sizeof(msg_hdr)); |
| if (read_len <= 0) |
| continue; |
| |
| if (read_len != sizeof(msg_hdr)) { |
| continue; |
| } |
| CM_Log(redial_task3, "redial_task:[<<<<][client] receive msg id [0x%x] type [%d] done\n", receive_msg.id, receive_msg.msgtype); |
| //logic handle here |
| CM_Redial_Function(&receive_msg); |
| } |
| } |
| |
| void send_dialmsg_to_mainthread(int connectionNum, redialmsg_type msgtype) |
| { |
| int writen = 0; |
| msg_hdr send_msg; |
| struct timeval tv; |
| gettimeofday(&tv, NULL); |
| |
| send_msg.id = ((UINT32)((tv.tv_sec % 86400) << 15) + (tv.tv_usec >> 5)); |
| send_msg.connectionNum = connectionNum; |
| send_msg.msgtype = msgtype; |
| |
| // send msg to server |
| writen = write(cm_client_fd.fd, &send_msg, sizeof(msg_hdr)); |
| CM_Log(send_dialmsg_to_mainthread, "[>>>][client] send msg id [0x%x] type [%d] size [%d] to mainthread via socket %d done\n", send_msg.id, msgtype, writen, cm_client_fd.fd); |
| } |
| |
| void send_redialmsg_to_redialthread(int connectionNum, redialmsg_type msgtype) |
| { |
| int writen = 0; |
| msg_hdr send_msg; |
| struct timeval tv; |
| gettimeofday(&tv, NULL); |
| |
| send_msg.id = ((UINT32)((tv.tv_sec % 86400) << 15) + (tv.tv_usec >> 5)); |
| send_msg.connectionNum = connectionNum; |
| send_msg.msgtype = msgtype; |
| |
| // send msg to server |
| writen = write(cm_accept_fd.fd, &send_msg, sizeof(msg_hdr)); |
| CM_Log(send_redialmsg_to_redialthread, "[>>>>][server] send msg id [0x%x] type [%d] size [%d] to redialthread via socket %d done\n", send_msg.id, msgtype, writen, cm_accept_fd.fd); |
| |
| } |
| |
| #ifdef CONFIG_CM_P701 |
| static void cm_get_zroam_list_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| UNUSED(req); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| RIL_ZROAM *response = NULL; |
| RIL_ZROAM *zroam_list = g_zroam_list; |
| int i = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| CM_Log_E(cm_get_zroam_list_cb, "cm_get_zroam_list_cb: Parse failed\n"); |
| return; |
| } |
| |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| CM_Log_E(cm_get_zroam_list_cb1, "cm_get_zroam_list_cb: rilerrno %d\n", rilerrno); |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_GET_ZROAM) { |
| CM_Log_E(cm_get_zroam_list_cb2, "cm_get_zroam_list_cb: The response not for the request\n"); |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| if (response_len > MAX_ZROAM_COUNT) |
| { |
| CM_Log_E(cm_get_zroam_list_cb3, "cm_get_zroam_list_cb: The response not for the request\n"); |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| for ( i = 0; i < MAX_ZROAM_COUNT; i++) |
| { |
| if (zroam_list[i].mccmnc) |
| free(zroam_list[i].mccmnc); |
| |
| memset(&zroam_list[i], 0, sizeof(RIL_ZROAM)); |
| } |
| response = (RIL_ZROAM *) response_data; |
| CM_Log(cm_get_zroam_list_cb4, "cm_get_zroam_list_cb: count %d \n", response_len); |
| |
| for (i = 0; i < response_len; i++) { |
| zroam_list->mccmnc = strdup(response->mccmnc); |
| zroam_list->pdptype = response->pdptype; |
| CM_Log(cm_get_zroam_list_cb4312, "cm_get_zroam_list_cb: mccmnc %s, iptype %d \n", zroam_list->mccmnc, zroam_list->pdptype); |
| response++; |
| zroam_list++; |
| } |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } else { |
| CM_Log_E(cm_get_zroam_list_cb5, "cm_get_zroam_list_cb:rilerror code %d\n", rilerrno); |
| } |
| |
| return; |
| } |
| |
| static int cm_get_zroam_list_ril() |
| { |
| int ret_val; |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_ZROAM, NULL, 0); |
| ret_val = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, cm_get_zroam_list_cb, 0, 0); |
| if (ret_val != UBUS_STATUS_OK) { |
| CM_Log_E(cm_get_zroam_list_ril, "cm_get_zroam_list_ril: ubus_invoke RIL_REQUEST_GET_ZROAM failed %s\n", ubus_strerror(ret_val)); |
| } |
| |
| CM_Log(cm_get_zroam_list_ril1, "cm_get_zroam_list_ril: ret %d \n", ret_val); |
| return ret_val; |
| } |
| #endif |
| |
| int cm_get_zroam_iptype() |
| { |
| int iptype = 0; /* 0 means invalid*/ |
| #ifdef CONFIG_CM_P701 |
| RIL_ZROAM *zroam_list = g_zroam_list; |
| char mccmnc[7] = {0}; |
| |
| if (!pipe_mode) |
| goto end; |
| |
| if (!IsRoaming) |
| goto end; |
| |
| if ( cm_get_imsi_mccmnc(mccmnc) != UBUS_STATUS_OK) |
| { |
| CM_Log_E(cm_get_zroam_iptype, "%s: FATAL ERROR!\n", __func__); |
| goto end; |
| } |
| |
| CM_Log(cm_get_zroam_iptype1, "%s:mccmnc %s", __func__, mccmnc); |
| CM_Log(cm_get_zroam_iptype4362, "%s:zroam_list mccmnc %s, iptype %d", __func__, zroam_list->mccmnc, zroam_list->pdptype); |
| while(zroam_list->mccmnc) |
| { |
| if (!strcmp(mccmnc, zroam_list->mccmnc)) |
| { |
| iptype = zroam_list->pdptype; |
| CM_Log(cm_get_zroam_iptyp2, "%s: roaming iptype %d", __func__, zroam_list->pdptype); |
| break; |
| } |
| |
| zroam_list++; |
| } |
| #else |
| goto end; |
| #endif |
| |
| end: |
| return iptype; |
| } |
| |
| void accept_cl_receive_cb(struct uloop_fd *u, unsigned int events) |
| { |
| UNUSED(events); |
| int data_len = 0; |
| msg_hdr msg_buffer; |
| CM_Connection_Context *ConInfo = NULL; |
| Apn_Info *apninfo; |
| |
| memset(&msg_buffer, 0, sizeof(msg_hdr)); |
| data_len = read(u->fd, &msg_buffer, sizeof(msg_hdr)); |
| |
| if (data_len != sizeof(msg_hdr)) { |
| CM_Log_E(accept_cl_receive_cb1, "[server] receive data failed\n"); |
| return; |
| } |
| CM_Log(accept_cl_receive_cb2, "accept_cl_receive_cb: [<<<][server] receive msg id [0x%x], msg type [%d], connectionNum:0x%x", msg_buffer.id, msg_buffer.msgtype, |
| msg_buffer.connectionNum); |
| |
| //invoke dial func call here |
| if (msg_buffer.msgtype == REDIAL_IMMED) { |
| ConInfo = findContextByConnum(msg_buffer.connectionNum); |
| if (ConInfo != NULL) |
| { |
| CM_Log(accept_cl_receive_cb4759, "accept_cl_receive_cb:[server] find context 0x%x, connectStatus %d", ConInfo, ConInfo->connectStatus); |
| if (ConInfo->connectStatus != CM_CONNECT_CONSUCCESS) |
| { |
| CM_StartDialer(ConInfo); |
| if (CM_CheckContextValid(ConInfo)) |
| { |
| if ((ConInfo->dialFailureCode != 0) && (ConInfo->dialFailureCode != PDP_FAIL_GET_GLOBALIP) && |
| (ConInfo->dialFailureCode != PDP_FAIL_BACKOFF_TIME)) { |
| if (ConInfo->retryTime != CM_INT_MAX) { |
| ConInfo->connectStatus = CM_CONNECT_REDIAL; |
| //call redial method here |
| send_redialmsg_to_redialthread(ConInfo->pdpinfo->connectionNum, REDIAL_IMMED); |
| } else { |
| ConInfo->connectStatus = CM_CONNECT_REDIAL; |
| //call redial method here |
| send_redialmsg_to_redialthread(ConInfo->pdpinfo->connectionNum, REDIAL_NEWAPN); |
| } |
| } |
| } |
| } |
| } |
| } else if (msg_buffer.msgtype == REDIAL_NEWAPN) { |
| ConInfo = findContextByConnum(msg_buffer.connectionNum); |
| |
| if (ConInfo != NULL) { |
| apninfo = get_apninfo_from_LteAPN(g_work_apn, ConInfo->pdpinfo->LteAPN); |
| |
| if (apninfo != NULL) |
| SetInitialAttachAPN(apninfo, true); |
| } |
| } else if (msg_buffer.msgtype == REDIAL_NEWAPN_CLEARETIF) { |
| CM_Clear_ETIFlag(true); |
| cm_set_cfun(4); |
| sleep(1); |
| cm_set_cfun(1); |
| } |
| else if (msg_buffer.msgtype == REDIAL_DEFAULT_DATACALL) { |
| set_default_data_call(); |
| } else if (msg_buffer.msgtype == REDIAL_SINGLE_STACK) { |
| set_single_stack_data_call(); |
| } |
| |
| CM_Log(accept_cl_receive_cb3, "accept_cl_receive_cb:[server] done"); |
| } |
| |
| #ifdef CONFIG_CM_URSP |
| extern int cm_get_current_cid(void); |
| |
| static struct list_head g_ursp_list_head = LIST_HEAD_INIT(g_ursp_list_head); |
| static struct list_head *cm_get_ursp_list_head(void) |
| { |
| return &g_ursp_list_head; |
| } |
| |
| static ursp_list_s *cm_new_ursp_list(void) |
| { |
| struct list_head *head = cm_get_ursp_list_head(); |
| |
| /*malloc ursp memory*/ |
| ursp_list_s *ursp_list = malloc(sizeof(ursp_list_s)); |
| if (!ursp_list) |
| goto fail; |
| |
| memset(ursp_list, 0, sizeof(ursp_list_s)); |
| |
| INIT_LIST_HEAD(&ursp_list->list); |
| |
| list_add_tail(&ursp_list->list, head); |
| |
| return ursp_list; |
| |
| fail: |
| return NULL; |
| } |
| |
| static void cm_free_ursp_list(void) |
| { |
| struct list_head *head = cm_get_ursp_list_head(); |
| ursp_list_s *ursp_list = NULL; |
| |
| while (!list_empty(head)) { |
| ursp_list = list_first_entry(head, ursp_list_s, list); |
| list_del(&ursp_list->list); |
| free(ursp_list); |
| } |
| } |
| |
| static ursp_list_s *cm_find_ursp_by_qos(int curr_preceduce) |
| { |
| ursp_list_s *ursp_list = NULL, *high_pri_ursp_list = NULL; |
| struct list_head *head = cm_get_ursp_list_head(); |
| int precedence = curr_preceduce; |
| int precedence_processed = -1; |
| int next = 0; |
| |
| if (precedence) |
| precedence_processed = precedence; |
| |
| list_for_each_entry(ursp_list, head, list) { |
| if (ursp_list) |
| { |
| if (precedence == -1) |
| { |
| precedence = ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule; |
| high_pri_ursp_list = ursp_list; |
| |
| CM_Log(cm_find_ursp_by_qos4915, "cm_find_ursp_by_qos: first precedence %d, ursp_list %x", precedence, high_pri_ursp_list); |
| } |
| else if (precedence_processed == -1) |
| { |
| if (ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule < precedence) |
| { |
| precedence = ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule; |
| high_pri_ursp_list = ursp_list; |
| |
| CM_Log(cm_find_ursp_by_qos4922, "cm_find_ursp_by_qos: find high precedence %d, ursp_list %x", precedence, high_pri_ursp_list); |
| } |
| } |
| else |
| { |
| if (next == 0) |
| { |
| if (ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule > precedence) |
| { |
| precedence = ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule; |
| high_pri_ursp_list = ursp_list; |
| next = 1; |
| CM_Log(cm_find_ursp_by_qos4941, "cm_find_ursp_by_qos: find next high precedence %d, ursp_list %x", precedence, high_pri_ursp_list); |
| } |
| } |
| else |
| { |
| if (ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule > precedence_processed && ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule < precedence) |
| { |
| precedence = ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule; |
| high_pri_ursp_list = ursp_list; |
| CM_Log(cm_find_ursp_by_qos4950, "cm_find_ursp_by_qos: find next higher precedence %d, ursp_list %x", precedence, high_pri_ursp_list); |
| } |
| } |
| } |
| } |
| } |
| |
| return high_pri_ursp_list; |
| } |
| |
| static int cm_find_rsd_by_qos(ursp_list_s *ursp, int curr_index) |
| { |
| int i = 0; |
| int precedence = -1, precedence_processed = -1; |
| int high_pri_index = -1; |
| |
| if (!ursp) |
| return -1; |
| |
| if (curr_index >= 0) |
| precedence = ursp->ursp.matchedUrspInfo.rsd[curr_index].precedenceOfRSD; |
| |
| CM_Log(cm_find_rsd_by_qos4939, "cm_find_rsd_by_qos: numOfRSD %d, curr precedence %d", ursp->ursp.matchedUrspInfo.numOfRSD, precedence); |
| for (i = 0; i < ursp->ursp.matchedUrspInfo.numOfRSD; i++) |
| { |
| CM_Log(cm_find_rsd_by_qos4944, "cm_find_rsd_by_qos: matchedUrspInfo.rsd[%d].precedenceOfRSD %d", i, ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD); |
| if (precedence == -1) |
| { |
| precedence = ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD; |
| high_pri_index = i; |
| CM_Log(cm_find_rsd_by_qos4945, "cm_find_rsd_by_qos: first precedence %d, high_pri_index %d", precedence, high_pri_index); |
| } |
| else if (curr_index == -1) |
| { |
| if (ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD < precedence) |
| { |
| precedence = ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD; |
| high_pri_index = i; |
| CM_Log(cm_find_rsd_by_qos4952, "cm_find_rsd_by_qos: find higher precedence %d, high_pri_index %d", precedence, high_pri_index); |
| } |
| } |
| else if (i != curr_index) |
| { |
| if (precedence_processed == -1) |
| { |
| if (ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD > precedence) |
| { |
| precedence_processed = precedence; |
| precedence = ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD; |
| high_pri_index = i; |
| CM_Log(cm_find_rsd_by_qos4970, "cm_find_rsd_by_qos: find next high precedence %d, high_pri_index %d", precedence, high_pri_index); |
| } |
| } |
| else |
| { |
| if (ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD > precedence_processed && ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD < precedence) |
| { |
| precedence = ursp->ursp.matchedUrspInfo.rsd[i].precedenceOfRSD; |
| high_pri_index = i; |
| CM_Log(cm_find_rsd_by_qos4980, "cm_find_rsd_by_qos: find next higher precedence %d, high_pri_index %d", precedence, high_pri_index); |
| } |
| } |
| } |
| } |
| |
| if (high_pri_index >= 0) |
| return high_pri_index; |
| else |
| return -1; |
| } |
| |
| static void ConvertApn2Ap(char *pOutString, const char *pInString, int *pOutLen, int inLen) |
| { |
| int indx = 0; |
| char tmpLen = *pInString; |
| |
| for (indx = 0; indx < inLen; indx++) |
| *(pOutString+indx) = *(pInString+indx+1); |
| |
| while((tmpLen+1) < inLen) |
| { |
| *(pOutString+tmpLen) = 0x2e; |
| tmpLen += *(pInString+tmpLen+1)+1; |
| } |
| |
| *pOutLen = inLen - 1; |
| |
| return; |
| } |
| |
| static BOOL update_pdp_ctx_by_ursp(CM_Connection_Context *cm_ctx) |
| { |
| ursp_list_s *high_pri_ursp_list = NULL; |
| int precedence = -1; |
| RSD *rsd = NULL; |
| BOOL changed = FALSE; |
| int rsd_index = 0; |
| Apn_Info apnInfo, *apninfo = NULL; |
| |
| memset(&apnInfo, 0, sizeof(Apn_Info)); |
| apninfo = &apnInfo; |
| |
| if (cm_ctx->pdpinfo->ursp_list) |
| { |
| precedence = cm_ctx->pdpinfo->ursp_list->ursp.matchedUrspInfo.precedenceOfURSPRule; |
| } |
| |
| high_pri_ursp_list = cm_find_ursp_by_qos(precedence); |
| if (high_pri_ursp_list) |
| { |
| rsd_index = cm_find_rsd_by_qos(high_pri_ursp_list, precedence); |
| if (rsd_index >= 0) |
| { |
| rsd = &high_pri_ursp_list->ursp.matchedUrspInfo.rsd[rsd_index]; |
| if (rsd->rsdComponents.dnnPresent) |
| { |
| int apnLen; |
| ConvertApn2Ap(apninfo->apn, (char *)rsd->rsdComponents.dnn.name, &apnLen, rsd->rsdComponents.dnn.length); |
| strncpy(apninfo->lte_apn, (char *)apninfo->apn, sizeof(apninfo->lte_apn) - 1); |
| } |
| |
| if (rsd->rsdComponents.pduSessionTypePresent) |
| apninfo->iptype = rsd->rsdComponents.pduSessionType; |
| |
| apninfo->Extra_params.data_on_roaming = 1; |
| |
| changed = check_merger_pdpcontext(apninfo, cm_ctx, 0); |
| cm_ctx->pdpinfo->ursp_list = high_pri_ursp_list; |
| cm_ctx->pdpinfo->ursp_processed++; |
| cm_ctx->pdpinfo->rsd_index = rsd_index; |
| cm_ctx->pdpinfo->rsd_processed = 1; |
| } |
| } |
| |
| return changed; |
| } |
| |
| static BOOL update_pdp_ctx_by_rsd(CM_Connection_Context *cm_ctx) |
| { |
| ursp_list_s *high_pri_ursp_list = NULL; |
| Apn_Info apnInfo, *apninfo = NULL; |
| int rsd_index = -1; |
| RSD *rsd = NULL; |
| bool changed = TRUE; |
| |
| memset(&apnInfo, 0, sizeof(Apn_Info)); |
| apninfo = &apnInfo; |
| |
| apninfo->connection_num = INVALID_CID; |
| apninfo->cid = INVALID_CID; |
| |
| high_pri_ursp_list = cm_ctx->pdpinfo->ursp_list; |
| rsd_index = cm_find_rsd_by_qos(high_pri_ursp_list, cm_ctx->pdpinfo->rsd_index); |
| if (rsd_index >= 0) |
| { |
| rsd = &high_pri_ursp_list->ursp.matchedUrspInfo.rsd[rsd_index]; |
| if (rsd->rsdComponents.dnnPresent) |
| { |
| int apnLen; |
| ConvertApn2Ap(apninfo->apn, (char *)rsd->rsdComponents.dnn.name, &apnLen, rsd->rsdComponents.dnn.length); |
| strncpy(apninfo->lte_apn, (char *)apninfo->apn, sizeof(apninfo->lte_apn) - 1); |
| } |
| |
| if (rsd->rsdComponents.pduSessionTypePresent) |
| apninfo->iptype = rsd->rsdComponents.pduSessionType; |
| |
| apninfo->Extra_params.data_on_roaming = 1; |
| |
| changed = check_merger_pdpcontext(apninfo, cm_ctx, 0); |
| cm_ctx->pdpinfo->ursp_list = high_pri_ursp_list; |
| cm_ctx->pdpinfo->rsd_index = rsd_index; |
| cm_ctx->pdpinfo->rsd_processed++; |
| } |
| |
| return changed; |
| } |
| |
| static CM_Connection_Context *create_new_pdp_ctx_by_ursp(int ursp_num, AppInfo *app_info) |
| { |
| CM_Connection_Context *cm_ctx = NULL; |
| ursp_list_s *high_pri_ursp_list = NULL; |
| Apn_Info apnInfo, *apninfo = NULL; |
| int rsd_index = -1; |
| RSD *rsd = NULL; |
| |
| high_pri_ursp_list = cm_find_ursp_by_qos(-1); |
| |
| memset(&apnInfo, 0, sizeof(Apn_Info)); |
| apninfo = &apnInfo; |
| |
| CM_Log(create_new_pdp_ctx_by_ursp5050, "create_new_pdp_ctx_by_ursp: high_pri_ursp_list %x", high_pri_ursp_list); |
| if (high_pri_ursp_list) |
| { |
| apninfo->connection_num = INVALID_CID; |
| apninfo->cid = INVALID_CID; |
| rsd_index = cm_find_rsd_by_qos(high_pri_ursp_list, -1); |
| if (rsd_index >= 0) |
| { |
| rsd = &high_pri_ursp_list->ursp.matchedUrspInfo.rsd[rsd_index]; |
| if (rsd->rsdComponents.dnnPresent) |
| { |
| int apnLen; |
| ConvertApn2Ap(apninfo->apn, (char *)rsd->rsdComponents.dnn.name, &apnLen, rsd->rsdComponents.dnn.length); |
| strncpy(apninfo->lte_apn, (char *)apninfo->apn, sizeof(apninfo->lte_apn) - 1); |
| } |
| else if (app_info->DNNPresent) |
| { |
| strncpy(apninfo->apn, (char *)app_info->DNN, sizeof(apninfo->apn) - 1); |
| strncpy(apninfo->lte_apn, (char *)apninfo->apn, sizeof(apninfo->lte_apn) - 1); |
| } |
| |
| if (rsd->rsdComponents.pduSessionTypePresent) |
| { |
| if (rsd->rsdComponents.pduSessionType == 3) |
| apninfo->iptype = IPV4V6; |
| else if (rsd->rsdComponents.pduSessionType > 3) |
| apninfo->iptype = TYPE_ETH; |
| else |
| apninfo->iptype = rsd->rsdComponents.pduSessionType; |
| } |
| |
| apninfo->Extra_params.data_on_roaming = 1; |
| |
| cm_ctx = create_new_pdp_ctx(apninfo); |
| if (cm_ctx) |
| { |
| cm_ctx->pdpinfo->ursp_list = high_pri_ursp_list; |
| cm_ctx->pdpinfo->rsd_index = rsd_index; |
| cm_ctx->pdpinfo->ursp_total = ursp_num; |
| cm_ctx->pdpinfo->ursp_processed = 1; |
| cm_ctx->pdpinfo->rsd_processed = 1; |
| |
| CM_Log(create_new_pdp_ctx_by_ursp5094, "create_new_pdp_ctx_by_ursp: rsd_index %d", rsd_index); |
| } |
| } |
| } |
| |
| return cm_ctx; |
| } |
| |
| static void cm_send_ursp_rsp_2atcmd(int fd, UrspCommRsp *rsp) |
| { |
| if (rsp && fd > 0) |
| { |
| write(fd, rsp, sizeof(*rsp)); |
| CM_Log(cm_send_ursp_rsp_2atcmd5134, "cm_send_ursp_rsp_2atcmd: send done with fd %d", fd); |
| } |
| } |
| |
| static UrspCommRsp *cm_prepare_ursp_rsp(CM_Connection_Context *ctx, int fail_code) |
| { |
| int cid = cm_get_current_cid(); |
| RSD *rsd = NULL; |
| |
| UrspCommRsp *rsp = NULL; |
| |
| rsp = malloc(sizeof(UrspCommRsp)); |
| |
| if (!rsp) |
| return NULL; |
| |
| memset(rsp, 0, sizeof(UrspCommRsp)); |
| if (ctx && fail_code == 0) |
| { |
| rsp->result = 1; |
| rsp->cid = cid; |
| if (ctx->pdpinfo && ctx->pdpinfo->ursp_req) |
| rsp->reqID = ctx->pdpinfo->ursp_req->reqID; |
| |
| if (ctx->pdpinfo && ctx->pdpinfo->ursp_list) |
| { |
| rsd = &(ctx->pdpinfo->ursp_list->ursp.matchedUrspInfo.rsd[ctx->pdpinfo->rsd_index]); |
| memcpy(&(rsp->active_rsd), rsd, sizeof(rsp->active_rsd)); |
| } |
| } |
| else |
| { |
| rsp->result = 0; |
| rsp->cid = cid; |
| } |
| |
| CM_Log(cm_prepare_ursp_rsp5167, "cm_prepare_ursp_rsp: result %d for cid %d", rsp->result, cid); |
| return rsp; |
| } |
| |
| static void accept_ursp_receive_cb(struct uloop_fd *u, unsigned int events) |
| { |
| UNUSED(events); |
| int data_len = 0; |
| ursp_req_s msg_buffer; |
| char *urspBuf = NULL; |
| UrspCtx *urspCtx = NULL; |
| int urspDataLen = 0; |
| CM_Connection_Context *ConInfo = NULL; |
| ursp_list_s *ursp_list = NULL; |
| int i = 0; |
| UrspCommRsp *rsp = NULL; |
| char discard_buffer[100]; |
| int fail_code = 1; |
| |
| memset(&msg_buffer, 0, sizeof(msg_buffer)); |
| data_len = read(u->fd, &msg_buffer, sizeof(msg_buffer)); |
| CM_Log(accept_ursp_receive_cb5146, "accept_ursp_receive_cb: socket fd %d data len %d, urspCtxNum %d, mode %d", u->fd, data_len, msg_buffer.urspCtxNum, msg_buffer.mode); |
| |
| urspDataLen = VALID_URSP_NUM * sizeof(UrspCtx); |
| urspBuf = malloc(urspDataLen); |
| if (urspBuf == NULL) |
| goto end; |
| memset(urspBuf, 0, urspDataLen); |
| |
| data_len = read(u->fd, urspBuf, urspDataLen); |
| while (data_len != urspDataLen) |
| { |
| i = read(u->fd, urspBuf + data_len, urspDataLen - data_len); |
| if (i < 0) |
| break; |
| |
| data_len += i; |
| } |
| CM_Log(accept_ursp_receive_cb5535, "accept_ursp_receive_cb: read more date_len %d", data_len); |
| /* create pdp */ |
| if (msg_buffer.mode == URSP_ACTION_CREATE_PDP) |
| { |
| urspCtx = (UrspCtx *)urspBuf; |
| for (i = 0; i < msg_buffer.urspCtxNum; i++) |
| { |
| ursp_list = cm_new_ursp_list(); |
| if (ursp_list) |
| { |
| memcpy(&(ursp_list->ursp), urspCtx, sizeof(UrspCtx)); |
| urspCtx++; |
| } |
| } |
| |
| ConInfo = create_new_pdp_ctx_by_ursp(msg_buffer.urspCtxNum, &msg_buffer.appInfo); |
| if (ConInfo) |
| { |
| ConInfo->pdpinfo->ursp_req = malloc(sizeof(ursp_req_s)); |
| if ( ConInfo->pdpinfo->ursp_req == NULL) |
| goto end; |
| |
| memset(ConInfo->pdpinfo->ursp_req, 0, sizeof(ursp_req_s)); |
| memcpy(ConInfo->pdpinfo->ursp_req, &msg_buffer, sizeof(ursp_req_s)); |
| start_dialer: |
| CM_StartDialer(ConInfo); |
| if (CM_CheckContextValid(ConInfo)) |
| { |
| if ((ConInfo->dialFailureCode != 0) && (ConInfo->dialFailureCode != PDP_FAIL_GET_GLOBALIP)) { |
| if (ConInfo->pdpinfo->rsd_processed < ConInfo->pdpinfo->ursp_list->ursp.matchedUrspInfo.numOfRSD) { |
| ConInfo->connectStatus = CM_CONNECT_CONNING; |
| //call redial method here |
| //send_redialmsg_to_redialthread(ConInfo->pdpinfo->connectionNum, REDIAL_NEXT_RSD); |
| if (update_pdp_ctx_by_rsd(ConInfo)) |
| goto start_dialer; |
| |
| } else if (ConInfo->pdpinfo->ursp_processed < ConInfo->pdpinfo->ursp_total){ |
| ConInfo->connectStatus = CM_CONNECT_CONNING; |
| //call redial method here |
| //send_redialmsg_to_redialthread(ConInfo->pdpinfo->rsd_index, REDIAL_NEXT_RSD); |
| if (update_pdp_ctx_by_ursp(ConInfo)) |
| goto start_dialer; |
| } |
| } |
| else |
| { |
| fail_code = 0; |
| } |
| } |
| } |
| } |
| else if (msg_buffer.mode == URSP_ACTION_DESTROY_PDP) |
| { |
| DeleteIPInfo(msg_buffer.cid, IPV4); |
| DeleteIPInfo(msg_buffer.cid, IPV6); |
| StopDialer(msg_buffer.cid + 1); |
| //send_disconnect_2host(msg_buffer.cid, IPV4V6); |
| } |
| else if (msg_buffer.mode == URSP_ACTION_ADD_ROUTER) |
| { |
| |
| } |
| |
| end: |
| /*read all data in socket*/ |
| data_len = read(u->fd, discard_buffer, sizeof(discard_buffer)); |
| while (data_len > 0) |
| { |
| data_len = read(u->fd, discard_buffer, sizeof(discard_buffer)); |
| } |
| |
| rsp = cm_prepare_ursp_rsp(ConInfo, fail_code); |
| if (rsp) |
| { |
| cm_send_ursp_rsp_2atcmd(u->fd, rsp); |
| free(rsp); |
| } |
| |
| cm_free_ursp_list(); |
| if (ConInfo && ConInfo->pdpinfo) |
| { |
| ConInfo->pdpinfo->ursp_list = NULL; |
| ConInfo->pdpinfo->ursp_total = 0; |
| ConInfo->pdpinfo->ursp_processed = 0; |
| ConInfo->pdpinfo->rsd_index = -1; |
| ConInfo->pdpinfo->rsd_processed = 0; |
| |
| if (ConInfo->pdpinfo->ursp_req) |
| { |
| free(ConInfo->pdpinfo->ursp_req); |
| ConInfo->pdpinfo->ursp_req = NULL; |
| } |
| } |
| |
| CM_Log(accept_ursp_receive_cb5271, "accept_ursp_receive_cb: done "); |
| } |
| |
| static void *ursp_server_task(void *argv) |
| { |
| UNUSED(argv); |
| int connected_fd = -1; |
| int sleep_msec = 0; |
| int accept_fail_times = 0; |
| |
| unlink(CM_URSP_CONN_SOCKET); |
| umask(0177); |
| |
| cm_ursp_server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, CM_URSP_CONN_SOCKET, NULL); |
| if (cm_ursp_server_fd.fd < 0) { |
| CM_Log_E(ursp_server_task, "[ursp] usock failed\n"); |
| return NULL; |
| } |
| |
| while (1) { |
| connected_fd = accept(cm_ursp_server_fd.fd, NULL, 0); |
| if (connected_fd < 0) { |
| accept_fail_times++; |
| if (accept_fail_times < 22) |
| sleep_msec = pow(2, accept_fail_times); |
| else |
| sleep_msec = 1000*3600; |
| CM_Log_E(ursp_server_task4682, "[ursp] accept socket failed times %d, sleep_msec %d\n", accept_fail_times, sleep_msec); |
| usleep(sleep_msec*1000); |
| } else |
| break; |
| } |
| CM_Log(ursp_server_task4687, "[ursp] accept client fd %d", connected_fd); |
| cm_ursp_server_accept_fd.fd = connected_fd; |
| cm_ursp_server_accept_fd.cb = accept_ursp_receive_cb; |
| |
| uloop_fd_add(&cm_ursp_server_accept_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); |
| return NULL; |
| } |
| |
| static int ursp_trigger_atcmd_connect(void) |
| { |
| char at_str[MAX_STR_LEN]; |
| int size = 0, ret = 0; |
| |
| memset(at_str, 0, MAX_STR_LEN); |
| snprintf(at_str, sizeof(at_str), "AT+LOG=15"); |
| |
| size = strlen(at_str) + 1; |
| CM_Log(ursp_trigger_atcmd_connect5639, "ursp_trigger_atcmd_connect:send_atcmd %s\n", at_str); |
| blob_buf_init(&cm_b, 0); |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_SEND_ATCMD, (void *)at_str, size); |
| |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, NULL, 0, 0); |
| if (ret != UBUS_STATUS_OK) { |
| CM_Log_E(ursp_trigger_atcmd_connect5649, "ursp_trigger_atcmd_connect, ubus_invoke failed %s\n", ubus_strerror(ret)); |
| } |
| |
| return ret; |
| } |
| #endif |
| |
| static void cm_ursp_init(void) |
| { |
| #ifdef CONFIG_CM_URSP |
| pthread_create(&ursp_server_tid, NULL, ursp_server_task, NULL); |
| usleep(1000); |
| ursp_trigger_atcmd_connect(); |
| #endif |
| } |
| |
| #ifdef CM_CONFIG_TOE |
| static void cm_trigger_tft_query_complete_cb(struct ubus_request *req, int ret) |
| { |
| UNUSED(ret); |
| CM_Log(cm_trigger_tft_query_complete_cb, "cm_trigger_tft_query_complete_cb: ret = %d", ret); |
| |
| if (req) { |
| free(req); |
| req = NULL; |
| } |
| } |
| |
| int cm_trigger_tft_query(bool force) |
| { |
| int ret_val = UBUS_STATUS_OK; |
| struct ubus_request *req = NULL; |
| CM_Connection_Context *ctx = NULL; |
| int i = 0; |
| bool need_query = false; |
| |
| if (!cm_ctx) |
| return -1; |
| |
| if (force == false) { |
| for (i = 1; i < MAX_CID_LIMITATION; i++) { |
| ctx = cm_get_ctx_by_cid(i); |
| if (ctx && (ctx->connectStatus == CM_CONNECT_CONSUCCESS ||ctx->connectStatus == CM_CONNECT_GET_GLOBALIP_ERR)) { |
| if (g_toe_tft_param[i-1].mcid != CM_INVALID_CID && g_toe_tft_param[i-1].pdu != 0) |
| { |
| CM_Log(cm_trigger_tft_query5663, "cm_trigger_tft_query: cid [%d] qfi [%d] pdu [%d] not changed", |
| g_toe_tft_param[i-1].mcid, g_toe_tft_param[i-1].qfi, g_toe_tft_param[i-1].pdu); |
| } |
| else { |
| need_query = true; |
| } |
| } |
| } |
| if (need_query == false) |
| { |
| CM_Log(cm_trigger_tft_query56635674, "cm_trigger_tft_query: all tft not changed, no need CGTFT query, config toe directly"); |
| cm_toe_tuple_send(); |
| return 0; |
| } |
| } |
| |
| blob_buf_init(&cm_b, 0); |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_QUERY_TFT, NULL, 0); |
| |
| req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); |
| if (!req) |
| return -1; |
| |
| if ((ret_val = |
| ubus_invoke_async(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, req)) != UBUS_STATUS_OK) { |
| CM_Log_E(cm_trigger_tft_query5331, "cm_trigger_tft_query: fail: %s\n", ubus_strerror(ret_val)); |
| free(req); |
| return -1; |
| } else { |
| req->data_cb = NULL; |
| req->complete_cb = cm_trigger_tft_query_complete_cb; |
| ubus_complete_request_async(cm_ctx, req); |
| } |
| |
| if (ret_val != UBUS_STATUS_OK) |
| ret_val = -1; |
| |
| CM_Log(cm_trigger_tft_query5343, "cm_trigger_tft_query: ret %d\n", ret_val); |
| return ret_val; |
| } |
| |
| static void genl_receive_cb(struct uloop_fd *u, unsigned int events) |
| { |
| UNUSED(events); |
| |
| CM_Log(genl_receive_cb, "genl_receive_cb sock_fd %d", u->fd); |
| genl_parse_msg(u->fd); |
| cm_trigger_tft_query(false); |
| } |
| #endif |
| |
| int get_etiflag() |
| { |
| int ret_val = UBUS_STATUS_OK; |
| |
| blob_buf_init(&cm_b, 0); |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_ETIFLAG, NULL, 0); |
| |
| if ((ret_val = |
| ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, get_etiflag_request_cb, 0, 0)) != UBUS_STATUS_OK) { |
| CM_Log_E(get_etiflag1, "get_etiflag: ubus_invoke RIL_REQUEST_GET_ETIFLAG failed %s\n", ubus_strerror(ret_val)); |
| goto end; |
| } |
| |
| if (ret_val == UBUS_STATUS_OK) |
| ret_val = g_cell_basic_info.etiflag; |
| else |
| ret_val = -1; |
| |
| end: |
| CM_Log(get_etiflag2, "get_etiflag: %d\n", ret_val); |
| return ret_val; |
| } |
| |
| #ifdef CONFIG_CM_P701 |
| static int cm_get_imsi_mccmnc(char *mccmnc) |
| { |
| int ret = UBUS_STATUS_OK; |
| if (strlen(g_cell_basic_info.IMSI) > 0) |
| { |
| /*mnc is 2 digitals*/ |
| memcpy(mccmnc, g_cell_basic_info.IMSI, 5); |
| } |
| else |
| { |
| ret = get_imsi(true, false); |
| if (ret != UBUS_STATUS_OK) { |
| goto exit; |
| } |
| memcpy(mccmnc, g_cell_basic_info.IMSI, 5); |
| } |
| |
| exit: |
| CM_Log_E(cm_get_imsi_mccmnc1, "cm_get_imsi_mccmnc: get mccmnc %s with ret %d\n", strlen(mccmnc)?mccmnc:"NULL", ret); |
| return ret; |
| } |
| #endif |
| |
| /*@return 0: no need special handle 1: need NULL APN attach*/ |
| static int cm_imsi_special_handle() |
| { |
| int ret; |
| #if 0 |
| char mccmnc[7] = {0}; |
| int i; |
| |
| if ( cm_get_imsi_mccmnc(mccmnc) != UBUS_STATUS_OK) |
| { |
| CM_Log_E(cm_imsi_special_handle, "%s: FATAL ERROR!\n", __func__); |
| goto end; |
| } |
| |
| for (i = 0; i < 4; i++) |
| { |
| if (!strcmp(mccmnc, gGetelNullApnImsi[i])) |
| { |
| ret = 1; |
| break; |
| } |
| } |
| end: |
| CM_Log(cm_imsi_special_handle, "cm_imsi_special_handle: return with ret %d\n", ret); |
| #endif |
| |
| /*0: NULL APN attach*/ |
| ret = get_etiflag(); |
| |
| return (ret == 0)?1:0; |
| } |
| |
| int g_pdn_type_zcfg = 0; |
| static void cm_get_pdn_type_zcfg_ril_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| UNUSED(req); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_GET_ZCFGBYID) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| g_pdn_type_zcfg = *(int *)response_data; |
| CM_Log(cm_get_pdn_type_zcfg_ril_cb3, "cm_get_pdn_type_zcfg_ril_cb: g_pdn_type_zcfg %d\n", g_pdn_type_zcfg); |
| |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| } |
| |
| /*1 : zgdcont will modify attach apn, 0: zgdcont not modify attach apn*/ |
| int g_zgdcont_attach_zcfg = 1; |
| static void cm_get_zgdcont_attach_zcfg_ril_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(type); |
| UNUSED(req); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_GET_ZCFGBYID) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| if (*(int *)response_data == 1) |
| g_zgdcont_attach_zcfg = 0; |
| else |
| g_zgdcont_attach_zcfg = 1; |
| |
| CM_Log(cm_get_zgdcont_attach_zcfg_ril_cb3, "%s: g_pdn_type_zcfg %d\n", __func__, g_zgdcont_attach_zcfg); |
| |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| } |
| |
| static int cm_get_pdn_type_zcfg_ril() |
| { |
| int ret_val = 0; |
| int zcfg_id = 11; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_ZCFGBYID, (void *)&zcfg_id, sizeof(zcfg_id)/sizeof(int)); |
| ret_val = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, cm_get_pdn_type_zcfg_ril_cb, 0, 0); |
| if (ret_val != UBUS_STATUS_OK) { |
| CM_Log_E(cm_get_pdn_type_zcfg_ril, "cm_get_pdn_type_zcfg_ril: ubus_invoke RIL_REQUEST_GET_ZCFGBYID failed %s\n", ubus_strerror(ret_val)); |
| } |
| |
| ret_val = g_pdn_type_zcfg; |
| CM_Log(cm_get_pdn_type_zcfg_ril1, "cm_get_pdn_type_zcfg_ril: ret %d \n", ret_val); |
| return ret_val; |
| } |
| |
| /** |
| @return: 0 - ZGDCONT will not modify attach APN, 1 - ZGDCONT will modify attach APN |
| */ |
| static int cm_get_zgdcont_attach_zcfg_ril() |
| { |
| int ret_val = 0; |
| int zcfg_id = 14; |
| |
| blob_buf_init(&cm_b, 0); |
| |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_GET_ZCFGBYID, (void *)&zcfg_id, sizeof(zcfg_id)/sizeof(int)); |
| ret_val = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, cm_get_zgdcont_attach_zcfg_ril_cb, 0, 0); |
| if (ret_val != UBUS_STATUS_OK) { |
| CM_Log_E(cm_get_zgdcont_attach_zcfg_ril, "%s: ubus_invoke RIL_REQUEST_GET_ZCFGBYID failed %s\n", __func__, ubus_strerror(ret_val)); |
| } |
| |
| ret_val = g_zgdcont_attach_zcfg; |
| CM_Log(cm_get_zgdcont_attach_zcfg_ril1, "%s: ret %d \n",__func__, ret_val); |
| return ret_val; |
| } |
| |
| static int cm_get_special_handle_flag() |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *s = NULL; |
| int ret = 0; |
| |
| local_ctx = (struct uci_context *)uci_wan_ctx_get(); |
| if (!local_ctx) { |
| goto end; |
| } |
| |
| p = get_uci_package(local_ctx, WAN_PACKAGE_NAME, false); |
| if (!p) { |
| goto end; |
| } |
| |
| s = uci_lookup_section(local_ctx, p, SEC_GETELCOM); |
| if (!s) { |
| goto end; |
| } |
| |
| CM_Log(cm_get_special_handle_flag3, "%s: section type %s\n", __func__, s->type); |
| if (!strcmp(s->type, "1")) |
| ret = 1; |
| |
| end: |
| CM_Log(cm_get_special_handle_flag4, "%s: ret %d\n", __func__, ret); |
| return ret; |
| } |
| |
| void init_zgdcont_pdp_info(void) |
| { |
| unsigned int i = 1; |
| Apn_Info *apn_info = NULL, *default_apn = NULL; |
| for ( i = 1; i < (sizeof(atcmd_apn_info) / sizeof(atcmd_apn_info[0])); i++) |
| { |
| apn_info = &atcmd_apn_info[i]; |
| if (load_pdp_info_from_uci(apn_info, i) == CM_OK) |
| { |
| CM_Log(init_zgdcont_pdp_info, "%s: load pdp info for cid %d done\n", __func__, i); |
| if ( i == CM_DEFAULT_ATTACH_CID) |
| { |
| |
| default_apn = get_default_apninfo(g_work_apn, NULL); |
| if (default_apn && default_apn->auto_apn) |
| { |
| CM_Log(init_zgdcont_pdp_info5070, "[AT DIAL] init_zgdcont_pdp_info: auto apn , cid %d, connection_num %d", default_apn->cid, default_apn->connection_num); |
| default_apn->cid = CM_DEFAULT_ATTACH_CID; |
| CM_Log(init_zgdcont_pdp_info5072, "[AT DIAL] init_zgdcont_pdp_info: auto apn , cid %d, apn %s, iptype %d", default_apn->cid, strlen(default_apn->apn) ? default_apn->apn : "NULL", default_apn->iptype); |
| send_zgdcont_info_2atcmd(default_apn); |
| continue; |
| } |
| } |
| send_zgdcont_info_2atcmd(apn_info); |
| } |
| } |
| } |
| |
| void init_zgdcont_default_pdp_info(void) |
| { |
| Apn_Info *apn_info = NULL, *default_apn = NULL; |
| unsigned int default_cid = CM_DEFAULT_ATTACH_CID; |
| |
| if (default_cid >= (sizeof(atcmd_apn_info) / sizeof(atcmd_apn_info[0]))) |
| return; |
| |
| apn_info = &atcmd_apn_info[default_cid]; |
| |
| if (load_pdp_info_from_uci(apn_info, CM_DEFAULT_ATTACH_CID) == CM_OK) |
| { |
| default_apn = get_default_apninfo(g_work_apn, NULL); |
| if (default_apn && default_apn->auto_apn) |
| { |
| default_apn->cid = CM_DEFAULT_ATTACH_CID; |
| send_zgdcont_info_2atcmd(default_apn); |
| return; |
| } |
| send_zgdcont_info_2atcmd(apn_info); |
| } |
| } |
| |
| int cm_save_default_apn(char *apn, char *lte_apn) |
| { |
| Apn_Info *apn_info = NULL; |
| unsigned int default_cid = CM_DEFAULT_ATTACH_CID; |
| bool need_save = false; |
| int ret = 0; |
| |
| if (default_cid >= (sizeof(atcmd_apn_info) / sizeof(atcmd_apn_info[0]))) |
| return ret; |
| |
| apn_info = &atcmd_apn_info[default_cid]; |
| |
| if (apn == NULL && lte_apn == NULL) |
| { |
| /* which means SIM changed to reset APN to NULL*/ |
| if (strlen(apn_info->apn) > 0) |
| { |
| apn_info->apn[0] = '\0'; |
| need_save = true; |
| } |
| |
| if (strlen(apn_info->lte_apn) > 0) |
| { |
| apn_info->lte_apn[0] = '\0'; |
| need_save = true; |
| } |
| |
| } |
| |
| if (apn && strlen(apn)) |
| { |
| if (strlen(apn_info->apn) == 0) |
| { |
| strncpy(apn_info->apn, apn, sizeof(apn_info->apn) - 1); |
| if (strlen(apn_info->lte_apn) == 0) |
| strncpy(apn_info->lte_apn, apn, sizeof(apn_info->lte_apn) - 1); |
| need_save = true; |
| } |
| } |
| |
| if (lte_apn && strlen(lte_apn)) |
| { |
| if (strlen(apn_info->lte_apn) == 0) |
| { |
| strncpy(apn_info->lte_apn, lte_apn, sizeof(apn_info->lte_apn) - 1); |
| if (strlen(apn_info->apn) == 0) |
| strncpy(apn_info->apn, lte_apn, sizeof(apn_info->apn) - 1); |
| need_save = true; |
| } |
| } |
| |
| if (need_save) |
| { |
| ret = add_pdp_info_into_uci(apn_info); |
| CM_Log(cm_save_default_apn1, "%s: add pdp info with cid %d done with ret %d",__func__, apn_info->cid, ret); |
| } |
| |
| return ret; |
| } |
| |
| void cm_process_cgdcont_msg(fifo_msg_cgdcont_s *msg) |
| { |
| Apn_Info *apn_info = &atcmd_apn_info[msg->cid]; |
| |
| if (msg->is_delete) |
| { |
| /* clear up uci*/ |
| #ifdef CONFIG_ZGDCONT_SAVE_PDP |
| if (delete_pdp_info_from_uci(apn_info) != CM_OK) |
| CM_Log(cm_process_cgdcont_msg5053, "[AT DIAL] %s: delete pdp info with cid %d failed",__func__, msg->cid); |
| #endif |
| memset(apn_info, 0 , sizeof(Apn_Info)); |
| |
| return; |
| } |
| |
| strcpy(apn_info->apn, msg->apn); |
| strcpy(apn_info->lte_apn, msg->apn); |
| strcpy(apn_info->type, "default"); |
| |
| if (strlen(msg->netif) > 0) |
| strcpy(apn_info->netif, msg->netif); |
| else |
| memset(apn_info->netif, 0, MAX_STR_LEN); |
| |
| apn_info->cid = msg->cid; |
| apn_info->iptype = msg->ip_type; |
| apn_info->Extra_params.lte_default = msg->is_default; |
| |
| #ifdef CONFIG_CM_URSP |
| memcpy(&(apn_info->config_rsd), &(msg->config_rsd), sizeof(apn_info->config_rsd)); |
| |
| CM_Log(cm_process_cgdcont_msg6221, "[AT DIAL] %s: sscModePresent %d, sscMode %d, snssaiPresent %d, snssai %s, preferredAccessTypePresent %d, preferredAccessType %d ", |
| __func__,apn_info->config_rsd.sscModePresent, apn_info->config_rsd.sscMode, apn_info->config_rsd.snssaiPresent, |
| strlen(apn_info->config_rsd.snssai) ? apn_info->config_rsd.snssai : "NULL", apn_info->config_rsd.prefAccessTypePresent, apn_info->config_rsd.prefAccessType); |
| #endif |
| #if 0 |
| #ifndef PIPE_MANUAL_CONNECT |
| apn_info->Extra_params.autoconnect = CM_CONTYPE_AUTO; |
| apn_info->Extra_params.always_on = 1; |
| #endif |
| apn_info->Extra_params.data_on_roaming = 1; |
| update_apn_info_connnum(apn_info); |
| #endif |
| |
| /* enable data on roaming by default */ |
| if (data_on_roaming_configed == FALSE) |
| apn_info->Extra_params.data_on_roaming = 1; |
| |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| if (apn_info->cid == CM_DEFAULT_ATTACH_CID) |
| { |
| apn_info->Extra_params.lte_default = 1; |
| apn_info->auto_apn = is_pdp_auto_apn(g_work_apn, apn_info->type); |
| } |
| else |
| { |
| apn_info->Extra_params.lte_default = 0; |
| apn_info->auto_apn = 0; |
| //apn_info->Extra_params.autoconnect = CM_CONTYPE_MANUAL; |
| } |
| #else |
| if (cm_get_special_handle_flag() == 1) |
| { |
| if (cm_get_pdn_type_zcfg_ril() == 1 ||cm_imsi_special_handle() == 1) |
| { |
| apn_info->connection_num = apn_info->cid; |
| goto end; |
| } |
| } |
| else |
| { |
| if (cm_imsi_special_handle() == 1) |
| { |
| apn_info->connection_num = apn_info->cid; |
| goto end; |
| } |
| } |
| |
| if (cm_get_zgdcont_attach_zcfg_ril() == 0) |
| { |
| apn_info->connection_num = apn_info->cid; |
| goto end; |
| } |
| #endif |
| |
| apn_info->connection_num = apn_info->cid; |
| if (!apn_info->Extra_params.lte_default) |
| { |
| goto end; |
| } |
| else |
| { |
| #ifdef CONFIG_ZGDCONT_MULTI_PDP |
| if ( is_pdp_auto_apn(g_work_apn, apn_info->type)) |
| goto end; |
| #endif |
| |
| SetInitialAttachAPN(apn_info, true); |
| } |
| |
| end: |
| #ifdef CONFIG_ZGDCONT_SAVE_PDP |
| apn_info->enable = 1; |
| if (add_pdp_info_into_uci(apn_info) != CM_OK) |
| CM_Log(cm_process_cgdcont_msg5137, "[AT DIAL] %s: add pdp info with cid %d failed",__func__, msg->cid); |
| #endif |
| CM_Log(cm_process_cgdcont_msg, "[AT DIAL] %s: cid %d, ip_type %d, is_default %d, lte apn [%s], data_on_roaming[%d],auto_connect[%d],always_on[%d], mtu [%d]", __func__, |
| apn_info->cid, apn_info->iptype, apn_info->Extra_params.lte_default, apn_info->lte_apn, apn_info->Extra_params.data_on_roaming, |
| apn_info->Extra_params.autoconnect, apn_info->Extra_params.always_on, apn_info->mtu); |
| } |
| |
| void cm_process_auth_msg(fifo_msg_auth_s *msg) |
| { |
| Apn_Info *apn_info = &atcmd_apn_info[msg->cid]; |
| |
| strcpy(apn_info->type, "default"); |
| apn_info->cid = msg->cid; |
| update_apn_info_authtype_str(apn_info, msg->auth_type); |
| if (msg->auth_type != 0) { |
| strcpy(apn_info->usrname, msg->username); |
| strcpy(apn_info->lte_usrname, msg->username); |
| strcpy(apn_info->paswd, msg->password); |
| strcpy(apn_info->lte_paswd, msg->password); |
| } |
| else |
| { |
| strcpy(apn_info->usrname, "any"); |
| strcpy(apn_info->lte_usrname, "any"); |
| strcpy(apn_info->paswd, "any"); |
| strcpy(apn_info->lte_paswd, "any"); |
| } |
| |
| if (cm_get_special_handle_flag() == 1) |
| { |
| if (cm_get_pdn_type_zcfg_ril() == 1 ||cm_imsi_special_handle() == 1) |
| { |
| goto end; |
| } |
| } |
| |
| if (cm_get_zgdcont_attach_zcfg_ril() == 0) |
| goto end; |
| |
| if (apn_info->Extra_params.lte_default) |
| SetInitialAttachAPN(apn_info, true); |
| |
| end: |
| #ifdef CONFIG_ZGDCONT_SAVE_PDP |
| if (add_pdp_auth_info_into_uci(apn_info) != CM_OK) |
| CM_Log(cm_process_auth_msg5182, "[AT DIAL] %s: update auth info into uci failed",__func__); |
| #endif |
| CM_Log(cm_process_auth_msg, "[AT DIAL] %s: [cid] [%d] auth [%d] username [%s] password [%s]", __func__, msg->cid, msg->auth_type, |
| strlen(msg->username)?msg->username:"NULL", strlen(msg->password)?msg->password:"NULL"); |
| |
| } |
| |
| void cm_set_atcmd_apn_state(int cid, int state) |
| { |
| if (cid <= 0 ||(unsigned int)cid >= sizeof(atcmd_apn_state)/sizeof(atcmd_apn_state[0])) |
| return; |
| |
| atcmd_apn_state[cid] = state; |
| } |
| |
| int cm_get_atcmd_apn_state(int cid) |
| { |
| if (cid <= 0 || (unsigned int)cid >= sizeof(atcmd_apn_state)/sizeof(atcmd_apn_state[0])) |
| return 0; |
| |
| return atcmd_apn_state[cid]; |
| } |
| |
| void cm_process_act_msg(fifo_msg_act_s *msg) |
| { |
| Apn_Info *apn_info = &atcmd_apn_info[msg->cid]; |
| |
| apn_info->enable = msg->state; |
| apn_info->cid = msg->cid; |
| if (apn_info->connection_num == 0) |
| apn_info->connection_num = apn_info->cid; |
| cm_set_atcmd_data_call(apn_info); |
| } |
| |
| void cm_process_confex_msg(fifo_msg_confex_s *msg) |
| { |
| int i = 0; |
| Apn_Info *apn_info = NULL; |
| |
| if (msg->cid == 0xFF) |
| { |
| for (i = 0; i < (signed)ARRAY_SIZE(atcmd_apn_info) - 1; i++) |
| { |
| apn_info = &atcmd_apn_info[i+1]; |
| if (msg->data_on_roaming_present) |
| { |
| apn_info->Extra_params.data_on_roaming = msg->data_on_roaming; |
| data_on_roaming_configed = TRUE; |
| } |
| |
| if (msg->auto_connect_present) |
| apn_info->Extra_params.autoconnect = msg->auto_connect; |
| |
| if (msg->data_on_boot_present) |
| apn_info->Extra_params.always_on = msg->data_on_boot; |
| |
| if (add_pdp_ext_info_into_uci(apn_info) != CM_OK) |
| CM_Log(cm_process_confex_msg1, "[AT DIAL] %s: add pdp ext info with cid %d failed",__func__, msg->cid); |
| } |
| } |
| else if (msg->cid < (signed)ARRAY_SIZE(atcmd_apn_info)) |
| { |
| |
| apn_info = &atcmd_apn_info[msg->cid]; |
| |
| if (msg->data_on_roaming_present) |
| apn_info->Extra_params.data_on_roaming = msg->data_on_roaming; |
| |
| if (msg->auto_connect_present) |
| apn_info->Extra_params.autoconnect = msg->auto_connect; |
| |
| if (msg->data_on_boot_present) |
| apn_info->Extra_params.always_on = msg->data_on_boot; |
| |
| if (add_pdp_ext_info_into_uci(apn_info) != CM_OK) |
| CM_Log(cm_process_confex_msg2, "[AT DIAL] %s: add pdp ext info with cid %d failed",__func__, msg->cid); |
| } |
| } |
| |
| void cm_process_mtu_msg(fifo_msg_mtu_s *msg) |
| { |
| Apn_Info *apn_info = NULL; |
| CM_Connection_Context *ctx = NULL; |
| |
| if (msg == NULL) |
| return; |
| |
| if (msg->cid < (signed)ARRAY_SIZE(atcmd_apn_info)) |
| { |
| apn_info = &atcmd_apn_info[msg->cid]; |
| apn_info->cid = msg->cid; |
| apn_info->mtu = msg->mtu; |
| |
| ctx = cm_get_ctx_by_cid(msg->cid); |
| if (ctx && ctx->pdpinfo) |
| ctx->pdpinfo->mtu = msg->mtu; |
| |
| CM_Log(cm_process_mtu_msg, "[AT DIAL] %s: config mtu %d for cid %d",__func__, msg->mtu, msg->cid); |
| } |
| return; |
| } |
| |
| int cm_get_config_mtu(int cid) |
| { |
| Apn_Info *apn_info = NULL; |
| |
| if (cid < (signed)ARRAY_SIZE(atcmd_apn_info)) |
| { |
| apn_info = &atcmd_apn_info[cid]; |
| return apn_info->mtu; |
| } |
| |
| return 0; |
| } |
| |
| void cm_process_switchsim_msg(fifo_msg_switchsim_s *msg) |
| { |
| if (msg == NULL) |
| return; |
| |
| #ifdef CM_DUAL_SIM_SUPPORT |
| int ret; |
| ret = CM_SetMasterSimID(msg->sim_id, NULL); |
| CM_Log(cm_process_mtu_msg, "[AT DIAL] %s: switch sim_id %d done with ret %d",__func__, msg->sim_id, ret); |
| #endif |
| return; |
| } |
| |
| int g_netmask = 0; |
| static void cm_set_netmask_last_oct(int netmask) |
| { |
| g_netmask = netmask; |
| } |
| |
| int cm_get_netmask_last_oct(void) |
| { |
| return g_netmask; |
| } |
| |
| static void cm_process_netmask_msg(fifo_msg_netmask_s *msg) |
| { |
| CM_Log(cm_process_netmask_msg, "[AT DIAL] %s: netmask %d", __func__, msg->mask); |
| cm_set_netmask_last_oct(msg->mask); |
| } |
| |
| extern unsigned char UnknownPdpCause; |
| static void cm_query_reject_cause_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| char *response = NULL; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_SEND_ATCMD) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| response = (char *) response_data; |
| CM_Log(cm_query_reject_cause_cb5078, "cm_query_reject_cause_cb: response %s\n", response); |
| |
| while(*response++ != '\0') |
| { |
| if (*response == ':') |
| { |
| response++; |
| UnknownPdpCause = atoi(response); |
| CM_Log(cm_query_reject_cause_cb5087, "cm_query_reject_cause_cb: UnknownPdpCause %d\n", UnknownPdpCause); |
| if (UnknownPdpCause == 50) |
| set_ipv4_only_allowed(true); |
| else if (UnknownPdpCause == 51) |
| set_ipv6_only_allowed(true); |
| |
| break; |
| } |
| } |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| } |
| |
| static int cm_query_reject_cause(void) |
| { |
| int ret = 0, size = 0; |
| char at_str[MAX_STR_LEN] = { 0 }; |
| |
| snprintf(at_str, sizeof(at_str) - 1, "AT*REJECTCAUSE=%d", CM_DEFAULT_ATTACH_CID); |
| |
| size = strlen(at_str) + 1; |
| CM_Log(cm_query_reject_cause5056, "cm_query_reject_cause: send %s\n", at_str); |
| blob_buf_init(&cm_b, 0); |
| rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_SEND_ATCMD, (void *)at_str, size); |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, cm_query_reject_cause_cb, 0, 0); |
| |
| return ret; |
| } |
| |
| int g_mnc_length = 2; |
| |
| int cm_get_mnc_length(void) |
| { |
| return g_mnc_length; |
| } |
| |
| static void cm_query_admindata_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSED(req); |
| UNUSED(type); |
| unsigned int requestid; |
| unsigned int rilerrno; |
| void *response_data = NULL; |
| int response_len = 0; |
| char *response = NULL; |
| int comma_count = 0; |
| int mnc_length; |
| |
| if (rilutil_parseResponseDSMaster(msg, &requestid, &rilerrno, &response_data, &response_len)) { |
| return; |
| } |
| |
| if (response_data) { |
| if (rilerrno != RIL_E_SUCCESS) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| if (requestid != RIL_REQUEST_SEND_ATCMD) { |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| return; |
| } |
| |
| response = (char *) response_data; |
| CM_Log(cm_query_admindata_cb1, "%s: response %s\n", __func__, response); |
| |
| while(*response++ != '\0') |
| { |
| if (*response == ',') |
| { |
| comma_count++; |
| if (comma_count == 1) |
| { |
| response++; |
| if (*response == 0x20) |
| response++; |
| |
| { |
| mnc_length = *response - 0x30; |
| CM_Log(cm_query_admindata_cb2, "%s: mnc length %d %d\n", __func__, mnc_length, *response); |
| if (mnc_length == 2 || mnc_length == 3) |
| g_mnc_length = mnc_length; |
| |
| goto end; |
| } |
| } |
| } |
| } |
| end: |
| rilutil_freeResponseData(requestid, response_data, response_len); |
| } |
| } |
| |
| int cm_query_admindata(void) |
| { |
| int ret = 0, size = 0; |
| char at_str[MAX_STR_LEN] = { 0 }; |
| |
| |
| snprintf(at_str, sizeof(at_str) - 1, "AT*ADMINDATA?"); |
| |
| size = strlen(at_str) + 1; |
| CM_Log(cm_query_admindata6396, "%s:: send %s\n", __func__, at_str); |
| blob_buf_init(&cm_b, 0); |
| ret = rilutil_makeRequestBlobDSMaster(&cm_b, RIL_REQUEST_SEND_ATCMD, (void *)at_str, size); |
| if (ret != UBUS_STATUS_OK) { |
| ret = UBUS_STATUS_UNKNOWN_ERROR; |
| goto end; |
| } |
| |
| ret = ubus_invoke(cm_ctx, cm_ubus_id.ril_id, "ril_request", cm_b.head, cm_query_admindata_cb, 0, 0); |
| |
| end: |
| return ret; |
| } |
| |
| static void dump_buffer(char *buf, int buf_size) |
| { |
| char *printf_buf = NULL; |
| char temp_buf[8] = { '\0' }; |
| int i = 0; |
| |
| printf_buf = malloc(buf_size * 2 + 1); |
| memset(printf_buf, 0, buf_size * 2 + 1); |
| for (i = 0; i < buf_size; i++) |
| { |
| sprintf(temp_buf, "%02x", buf[i]); |
| strcat(printf_buf, temp_buf); |
| //sprintf(printf_buf + 2*i, "%02x", *(pbuf+i)); |
| } |
| CM_Log(dump_buffer, "[AT DIAL] %s: size %d, hex %s", __func__, buf_size, printf_buf); |
| free(printf_buf); |
| } |
| |
| void fifo_read_cb(struct uloop_fd *u, unsigned int events) |
| { |
| UNUSED(events); |
| char buf[512] = { 0 }; |
| fifo_msg_cgdcont_s *msg_cgdcont_p; |
| fifo_msg_auth_s *msg_auth_p; |
| fifo_msg_act_s *msg_act_p; |
| fifo_msg_confex_s *msg_confex_p; |
| fifo_msg_netmask_s *msg_netmask_p; |
| fifo_msg_mtu_s *msg_mtu_p; |
| fifo_msg_switchsim_s *msg_switchsim_p; |
| fifo_msg_type_e msg_type = FIFO_MSG_MAX; |
| int data_len = 0; |
| char *pbuf = NULL; |
| |
| while(1) |
| { |
| if (u->error) |
| { |
| CM_Log_E(fifo_read_cbe5056, "[AT DIAL] %s: met error for fd %d, registered %d", __func__, u->fd, u->registered); |
| return; |
| } |
| |
| data_len = read(u->fd, &msg_type, sizeof(fifo_msg_type_e)); |
| if (data_len != sizeof(fifo_msg_type_e)) |
| { |
| CM_Log_E(fifo_read_cbe, "[AT DIAL] %s: error read size %d, receive done", __func__, data_len); |
| return; |
| } |
| |
| CM_Log(fifo_read_cb10, "[AT DIAL] %s: receive msg size %d, type %d", __func__, data_len, msg_type); |
| pbuf = buf; |
| memset(buf, 0, 512); |
| switch(msg_type) |
| { |
| case MSG_CGDCONT: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_cgdcont_s)); |
| if (data_len != sizeof(fifo_msg_cgdcont_s)) |
| { |
| CM_Log_E(fifo_read_cbe1, "[AT DIAL] %s: error MSG CGDCONT read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_cgdcont_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| |
| msg_cgdcont_p = (fifo_msg_cgdcont_s *)pbuf; |
| |
| CM_Log(fifo_read_cb, "[AT DIAL] %s: receive [cgdcont] msg, [cid] - %d,[apn] - %s,[ip_type] - %d", __func__, msg_cgdcont_p->cid, msg_cgdcont_p->apn, msg_cgdcont_p->ip_type); |
| //coverity[string_null:SUPPRESS] |
| //coverity[tainted_data:SUPPRESS] |
| cm_process_cgdcont_msg(msg_cgdcont_p); |
| break; |
| case MSG_AUTH: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_auth_s)); |
| if (data_len != sizeof(fifo_msg_auth_s)) |
| { |
| CM_Log_E(fifo_read_cbe2, "[AT DIAL] %s: error MSG AUTH read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_auth_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_auth_p = (fifo_msg_auth_s *)pbuf; |
| CM_Log(fifo_read_cb1, "[AT DIAL] %s: receive [auth] msg, [cid] %d [auth] %d", __func__, msg_auth_p->cid, msg_auth_p->auth_type); |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_auth_msg(msg_auth_p); |
| break; |
| case MSG_ACT: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_act_s)); |
| if (data_len != sizeof(fifo_msg_act_s)) |
| { |
| CM_Log_E(fifo_read_cbe3, "[AT DIAL] %s: error MSG ACT read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_act_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_act_p = (fifo_msg_act_s *)pbuf; |
| CM_Log(fifo_read_cb2, "[AT DIAL] %s: receive [act] msg, [cid] %d [state] %d", __func__, msg_act_p->cid, msg_act_p->state); |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_act_msg(msg_act_p); |
| break; |
| case MSG_ZROAM: |
| #ifdef CONFIG_CM_P701 |
| cm_get_zroam_list_ril(); |
| #endif |
| break; |
| case MSG_CONFEX: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_confex_s)); |
| if (data_len != sizeof(fifo_msg_confex_s)) |
| { |
| CM_Log_E(fifo_read_cbe3, "[AT DIAL] %s: error MSG CONFEX read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_confex_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_confex_p = (fifo_msg_confex_s *)pbuf; |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_confex_msg(msg_confex_p); |
| break; |
| case MSG_NETMASK: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_netmask_s)); |
| if (data_len != sizeof(fifo_msg_netmask_s)) |
| { |
| CM_Log_E(fifo_read_cbe5518, "[AT DIAL] %s: error MSG NETMASK read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_netmask_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_netmask_p = (fifo_msg_netmask_s *)pbuf; |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_netmask_msg(msg_netmask_p); |
| break; |
| case MSG_MTU: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_mtu_s)); |
| if (data_len != sizeof(fifo_msg_mtu_s)) |
| { |
| CM_Log_E(fifo_read_cbe5519, "[AT DIAL] %s: error MSG_MTU read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_mtu_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_mtu_p = (fifo_msg_mtu_s *)pbuf; |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_mtu_msg(msg_mtu_p); |
| break; |
| case MSG_SWITCHSIM: |
| data_len = read(u->fd, pbuf, sizeof(fifo_msg_switchsim_s)); |
| if (data_len != sizeof(fifo_msg_switchsim_s)) |
| { |
| CM_Log_E(fifo_read_cbe5519, "[AT DIAL] %s: error MSG_SWITCHSIM read size %d, msg size %d", __func__, data_len, sizeof(fifo_msg_switchsim_s)); |
| return; |
| } |
| dump_buffer(pbuf, data_len); |
| msg_switchsim_p = (fifo_msg_switchsim_s *)pbuf; |
| //coverity[tainted_data:SUPPRESS] |
| //coverity[string_null:SUPPRESS] |
| cm_process_switchsim_msg(msg_switchsim_p); |
| break; |
| default: |
| CM_Log(fifo_read_cbe4, "[AT DIAL] %s: wong msg, read fifo", __func__, msg_act_p->cid, msg_act_p->state); |
| while((data_len = read(u->fd, pbuf, sizeof(buf))) > 0) |
| { |
| dump_buffer(pbuf, data_len);; |
| } |
| CM_Log_E(fifo_read_cbe5, "[AT DIAL] %s: read fifo data done", __func__); |
| return; |
| |
| break; |
| } |
| } |
| } |
| |
| int cm_fifo_init(void) |
| { |
| int ret, retries; |
| struct stat buf; |
| cm_fifo.fname = CM_FIFO_NAME; |
| |
| CM_Log(cm_fifo_init4, "cm_fifo_init with name %s\n", cm_fifo.fname); |
| unlink(cm_fifo.fname); |
| ret = mkfifo(cm_fifo.fname, 0666); |
| if (ret != 0) { |
| if (errno == EEXIST) { |
| if (stat(cm_fifo.fname, &buf) != 0 || !S_ISFIFO(buf.st_mode)) { |
| CM_Log_E(cm_fifo_init, "%s is not fifo\n", cm_fifo.fname); |
| return -1; |
| } |
| } else { |
| CM_Log_E(cm_fifo_init1, "fifo not created %s\n", strerror(errno)); |
| return -1; |
| } |
| } |
| retries = 5; |
| while ((cm_fifo.fdr = open(cm_fifo.fname, O_RDONLY | O_NONBLOCK)) == -1) { |
| if (errno == EINTR && --retries > 0) |
| continue; |
| CM_Log_E(cm_fifo_init2, "failed open %s %s\n", cm_fifo.fname, strerror(errno)); |
| return -1; |
| } |
| |
| cm_conn_fd.fd = cm_fifo.fdr; |
| cm_conn_fd.cb = fifo_read_cb; |
| uloop_fd_add(&cm_conn_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); |
| |
| CM_Log(cm_fifo_init3, "fifo init done with read fd %d\n", cm_fifo.fdr); |
| return 0; |
| } |
| |
| int cm_start_thread() |
| { |
| int connected_fd = -1; |
| int flags = 0; |
| |
| unlink(CM_INNER_CONN_SOCKET); |
| umask(0177); |
| |
| cm_server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, CM_INNER_CONN_SOCKET, NULL); |
| if (cm_server_fd.fd < 0) { |
| CM_Log_E(cm_start_thread, "usock failed\n"); |
| return -1; |
| } |
| #if 0 |
| cm_server_fd.cb = server_receive_cb; |
| LOG_OUT("server fd %d", cm_server_fd.fd); |
| |
| uloop_fd_add(&cm_server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); |
| #endif |
| pthread_create(&redial_tid, NULL, redial_task, NULL); |
| |
| while (1) { |
| connected_fd = accept(cm_server_fd.fd, NULL, 0); |
| if (connected_fd < 0) { |
| CM_Log_E(cm_start_thread1, "accept socket failed\n"); |
| usleep(1000); |
| } else |
| break; |
| } |
| CM_Log(cm_start_thread2, "accept client fd %d", connected_fd); |
| flags = fcntl(connected_fd, F_GETFL, 0); |
| fcntl(connected_fd, F_SETFL, flags|O_NONBLOCK); |
| cm_accept_fd.fd = connected_fd; |
| cm_accept_fd.cb = accept_cl_receive_cb; |
| |
| uloop_fd_add(&cm_accept_fd, ULOOP_READ); |
| |
| return 0; |
| } |
| |
| #if 0 |
| static void cm_toe_tuple_set_timeout(int msec) |
| { |
| uloop_timeout_set(&cm_toe_tuple_timeout, msec); |
| } |
| |
| static void cm_toe_tuple_cancel_timeout() |
| { |
| uloop_timeout_cancel(&cm_toe_tuple_timeout); |
| } |
| |
| #define CM_TOE_TUPLE_COUNT_UNSEND 10 |
| |
| int cm_toe_tuple_count(void) |
| { |
| struct list_head *head = cm_get_toe_tuple_list_head(); |
| struct toe_tuple_list *tuple = NULL; |
| int count = 0; |
| |
| list_for_each_entry(tuple, head, list) { |
| if (tuple) { |
| count++; |
| } |
| } |
| } |
| #endif |
| |
| #ifdef CM_CONFIG_TOE |
| void cm_toe_tft_param_init(void) |
| { |
| unsigned int i = 0; |
| memset(g_toe_tft_param, 0, sizeof(g_toe_tft_param)); |
| |
| for ( i = 0; i < ARRAY_SIZE(g_toe_tft_param); i++) |
| g_toe_tft_param[i].mcid = CM_INVALID_CID; |
| } |
| |
| static void cm_toe_tft_param_update_entry(struct toe_tft_param *paras) |
| { |
| unsigned int i = 0; |
| |
| if (!paras) |
| return; |
| |
| for (i = 0; i < ARRAY_SIZE(g_toe_tft_param); i++) |
| { |
| if (paras->mcid == CM_INVALID_CID) |
| g_toe_tft_param[i].mcid = CM_INVALID_CID; |
| else |
| { |
| if (i == paras->mcid - 1) |
| { |
| memcpy(&g_toe_tft_param[i], paras, sizeof(struct toe_tft_param)); |
| CM_Log(cm_toe_tft_param_update_entry5508, "cm_toe_tft_param_update_entry: tft_param[%d] cid %d, qfi %d, pdu %d\n", i, g_toe_tft_param[i].mcid, g_toe_tft_param[i].qfi, g_toe_tft_param[i].pdu); |
| break; |
| } |
| } |
| } |
| |
| return; |
| } |
| |
| TftInfoList g_tft_pf_list; |
| void cm_toe_tft_pf_prepare(PacketFilterInfo *data, int data_len) |
| { |
| PacketFilterInfo *ptr = NULL, *target_pf = NULL; |
| TftInfoList *tft_list_head = &g_tft_pf_list; |
| int len = 0; |
| |
| target_pf = &tft_list_head->packetinfo; |
| |
| for (ptr = data, len = 0; len < data_len; len += sizeof(PacketFilterInfo), ptr++) |
| { |
| if (target_pf->PfIdx == 0 && target_pf->EpIdx == 0) |
| { |
| memcpy(target_pf, ptr, sizeof(PacketFilterInfo)); |
| tft_list_head->filter_num = 1; |
| target_pf->next = NULL; |
| } |
| else |
| { |
| while (target_pf->next) |
| { |
| target_pf = target_pf->next; |
| } |
| target_pf->next = malloc(sizeof(PacketFilterInfo)); |
| if (target_pf->next == NULL) |
| goto end; |
| |
| target_pf = target_pf->next; |
| memset(target_pf, 0, sizeof(PacketFilterInfo)); |
| memcpy(target_pf, ptr, sizeof(PacketFilterInfo)); |
| tft_list_head->filter_num++; |
| target_pf->next = NULL; |
| } |
| |
| CM_Log(cm_toe_tft_pf_prepare6787, "cm_toe_tft_pf_prepare: add PfIdx %d, EpIdx %d\n", target_pf->PfIdx, target_pf->EpIdx); |
| } |
| |
| end: |
| tft_list_head->cid = tft_list_head->packetinfo.secondaryCid - 1; |
| CM_Log(cm_toe_tft_pf_prepare6683, "cm_toe_tft_pf_prepare: filter_num %d, cid %d\n", tft_list_head->filter_num, tft_list_head->cid); |
| } |
| |
| void cm_toe_tft_pf_list_clear(void) |
| { |
| TftInfoList *tft_list_head = &g_tft_pf_list; |
| PacketFilterInfo *pf_list = NULL; |
| PacketFilterInfo *pf_list_next = NULL; |
| |
| pf_list = &tft_list_head->packetinfo; |
| pf_list_next = pf_list->next; |
| while(pf_list_next) |
| { |
| pf_list = pf_list_next->next; |
| free(pf_list_next); |
| pf_list_next = pf_list; |
| } |
| |
| memset(tft_list_head, 0, sizeof(TftInfoList)); |
| } |
| |
| void cm_toe_tft_pf_delete(int p_cid, int cid) |
| { |
| qos_delete_qos((unsigned char)p_cid, (unsigned char)cid, false); |
| } |
| |
| void cm_toe_tft_pf_update(TftExtendInfo *data, int data_len) |
| { |
| TftExtendInfo *ptr = NULL; |
| TftInfoList *tft_list_head = &g_tft_pf_list; |
| int i = 0; |
| int len = 0; |
| struct toe_tft_param toe_param = { 0 }; |
| |
| for (ptr = data, len = 0; len < data_len; len += sizeof(TftExtendInfo), ptr++, i++) |
| { |
| memcpy(&toe_param, ptr, sizeof(toe_param)); |
| cm_toe_tft_param_update_entry(&toe_param); |
| |
| if ((ptr->mcid - 1) == tft_list_head->cid) |
| { |
| memcpy(&tft_list_head->extend_info, ptr, sizeof(TftExtendInfo)); |
| tft_list_head->bearer_type = 1; |
| if (ptr->p_cid != INVALID_CID && ptr->mcid != ptr->p_cid) |
| { |
| tft_list_head->bearer_type = 2; |
| tft_list_head->Pcid = ptr->p_cid - 1; |
| } |
| else |
| { |
| tft_list_head->bearer_type = 1; |
| tft_list_head->Pcid = INVALID_CID; |
| } |
| break; |
| } |
| } |
| |
| cm_qos_update_pf(tft_list_head, false); |
| } |
| |
| void cm_toe_tft_param_update(void *data, int len) |
| { |
| struct toe_tft_param toe_param = { 0 }; |
| unsigned int nums = len/sizeof(struct toe_tft_param) ; |
| unsigned int i; |
| struct toe_tft_param *p = ( struct toe_tft_param *)data; |
| |
| CM_Log(cm_toe_tft_param_update5524, "cm_toe_tft_param_update: len %d\n", len); |
| for( i = 0; i < nums; i++) |
| { |
| memcpy(&toe_param, p, sizeof(toe_param)); |
| p++; |
| cm_toe_tft_param_update_entry(&toe_param); |
| } |
| |
| /* only report one cid once, no need to clean other cid entry */ |
| #if 0 |
| for (i = 0; i < ARRAY_SIZE(g_toe_tft_param); i++) |
| { |
| unsigned int j; |
| p = ( struct toe_tft_param *)data; |
| for (j = 0; j < nums; j++) |
| { |
| if (g_toe_tft_param[i].mcid == p->mcid) |
| break; |
| |
| p++; |
| } |
| |
| /* clean entry */ |
| if ( j == nums) |
| g_toe_tft_param[i].mcid = CM_INVALID_CID; |
| |
| } |
| #endif |
| CM_Log(cm_toe_tft_param_update6048, "cm_toe_tft_param_update: done\n"); |
| } |
| |
| extern CM_Connection_Context *g_CM_Context; |
| bool cm_ctx_toe_tuple_match(int cid, struct toe_tuple_list *tuple) |
| { |
| #define TOE_SNAT 1 |
| CM_Connection_Context *ctx = g_CM_Context; |
| bool match = false; |
| |
| while(ctx) |
| { |
| if ((ctx->connectStatus == CM_CONNECT_CONSUCCESS ||ctx->connectStatus == CM_CONNECT_GET_GLOBALIP_ERR) |
| && (ctx->pdpinfo->primaryCid -1) == cid) |
| { |
| if (ctx->pdpinfo->IP_Type == tuple->type ||ctx->pdpinfo->IP_Type == IPV4V6) |
| { |
| if (tuple->type == IPV4) |
| { |
| CM_Log(cm_ctx_toe_tuple_match, "cm_ctx_toe_tuple_match: V4 nat %d, nat_ip 0x%x, src_ip 0x%x, dst_ip 0x%x, cm.ip 0x%x\n", |
| tuple->tuple.nat, tuple->tuple.nat_ip, tuple->tuple.src_ip, tuple->tuple.dst_ip, ctx->ipv4info->IPAddr); |
| if (tuple->tuple.nat == TOE_SNAT) |
| { |
| if ( tuple->tuple.in_pkt == 0) |
| { |
| if (ctx->ipv4info && (unsigned)ctx->ipv4info->IPAddr == tuple->tuple.dst_ip) |
| { |
| match = true; |
| break; |
| } |
| } |
| else if ( tuple->tuple.out_pkt == 0) |
| { |
| if (ctx->ipv4info && (unsigned)ctx->ipv4info->IPAddr == tuple->tuple.nat_ip) |
| { |
| match = true; |
| break; |
| } |
| } |
| |
| } |
| else if (tuple->tuple.nat == 0) |
| { |
| if ( tuple->tuple.in_pkt == 0) |
| { |
| if (ctx->ipv4info && (unsigned)ctx->ipv4info->IPAddr == tuple->tuple.dst_ip) |
| { |
| match = true; |
| break; |
| } |
| } |
| else if ( tuple->tuple.out_pkt == 0) |
| { |
| if (ctx->ipv4info && (unsigned)ctx->ipv4info->IPAddr == tuple->tuple.src_ip) |
| { |
| match = true; |
| break; |
| } |
| } |
| } |
| } |
| else if (tuple->type == IPV6) |
| { |
| if (ctx->connectStatus == CM_CONNECT_GET_GLOBALIP_ERR) |
| { |
| char interface_name[32]; |
| char ipaddress[INET6_ADDRSTRLEN]; |
| |
| snprintf(interface_name, sizeof(interface_name), "ccinet%d", cid); |
| if (ctx->ipv6info && getInterfaceAddr6(interface_name, ipaddress, sizeof(ipaddress)) == 0) |
| { |
| inet_pton(AF_INET6, ipaddress, ctx->ipv6info->IPV6Addr); |
| CM_Log(cm_ctx_toe_tuple_match6684, "cm_ctx_toe_tuple_match: get global ip successfully for %s", interface_name); |
| } |
| else |
| goto next; |
| } |
| CM_Log(cm_ctx_toe_tuple_match5585, "cm_ctx_toe_tuple_match: V6 in %d, out %d, src_ip %x.%x.%x.%x\n, dst_ip %x.%x.%x.%x", |
| tuple->tuple.in_pkt, tuple->tuple.out_pkt, |
| tuple->tuple.src_ip6[0], tuple->tuple.src_ip6[1], tuple->tuple.src_ip6[2], tuple->tuple.src_ip6[3], |
| tuple->tuple.dst_ip6[0], tuple->tuple.dst_ip6[1], tuple->tuple.dst_ip6[2], tuple->tuple.dst_ip6[3]); |
| if (ctx->ipv6info) |
| { |
| CM_Log(cm_ctx_toe_tuple_match6679, "cm_ctx_toe_tuple_match: cm.ipv6 %x.%x.%x.%x\n", |
| ctx->ipv6info->IPV6Addr[0], ctx->ipv6info->IPV6Addr[1], ctx->ipv6info->IPV6Addr[2], ctx->ipv6info->IPV6Addr[3]); |
| } |
| /* inpkt from pdu, downlink */ |
| if ( tuple->tuple.in_pkt == 0) |
| { |
| if (ctx->ipv6info && memcmp(ctx->ipv6info->IPV6Addr, tuple->tuple.dst_ip6, 8) == 0) |
| { |
| match = true; |
| break; |
| } |
| } |
| else if ( tuple->tuple.out_pkt == 0) |
| { |
| if (ctx->ipv6info && memcmp(ctx->ipv6info->IPV6Addr, tuple->tuple.src_ip6, 8) == 0) |
| { |
| match = true; |
| break; |
| } |
| } |
| } |
| else |
| break; |
| } |
| } |
| next: |
| ctx = ctx->next; |
| } |
| |
| CM_Log(cm_ctx_toe_tuple_match6104, "cm_ctx_toe_tuple_match: cid %d, match %d", cid, match); |
| return match; |
| } |
| |
| void cm_toe_tuple_send(void) |
| { |
| struct list_head *head = cm_get_toe_tuple_list_head(); |
| struct toe_tuple_list *tuple = NULL; |
| struct toe_tuple_list *n_tuple = NULL; |
| unsigned int i = 0; |
| int ret = 0; |
| struct toe_tft_param toe_param; |
| bool param_updated = false; |
| |
| list_for_each_entry_safe(tuple, n_tuple, head, list) { |
| if (tuple) |
| { |
| param_updated = false; |
| CM_Log(cm_toe_tuple_send5669, "cm_toe_tuple_send: current tuple %x, in_pkt %d, mcid %d, qri %d, pdu %d, update_tuple %d", |
| tuple, tuple->tuple.in_pkt, tuple->tuple.mcid, tuple->tuple.qfi, tuple->tuple.pdu, tuple->tuple.update_tuple); |
| for (i = 0; i < MAX_CID_LIMITATION; i++) |
| if (cm_ctx_toe_tuple_qos_match(i, tuple, &toe_param) == TRUE) |
| break; |
| |
| if (i < MAX_CID_LIMITATION) { |
| if (tuple->type == IPV4) { |
| |
| #if 0 |
| if (g_toe_tft_param[i].mcid - 1 == i) { |
| tuple->tuple.mcid = i; |
| tuple->tuple.qfi = g_toe_tft_param[i].qfi; |
| tuple->tuple.pdu = g_toe_tft_param[i].pdu; |
| } |
| else { |
| tuple->tuple.mcid = 0xFF; |
| tuple->tuple.qfi = 0; |
| tuple->tuple.pdu = 0; |
| } |
| #endif |
| if (tuple->tuple.mcid != toe_param.mcid) { |
| tuple->tuple.mcid = toe_param.mcid; |
| param_updated = true; |
| } |
| |
| if (tuple->tuple.qfi != toe_param.qfi) { |
| tuple->tuple.qfi = toe_param.qfi; |
| param_updated = true; |
| } |
| |
| |
| if (tuple->tuple.pdu != toe_param.pdu) { |
| tuple->tuple.pdu = toe_param.pdu; |
| param_updated = true; |
| } |
| |
| if (param_updated) { |
| CM_Log(cm_toe_tuple_send6133, "cm_toe_tuple_send: send v4 tuple %x to kernel with socket fd %d, cid %d, qfi %d, pdu %d", tuple, cm_genl_fd.fd, tuple->tuple.mcid, tuple->tuple.qfi, tuple->tuple.pdu); |
| ret = genl_set_tuplev4_to_kernel(cm_genl_fd.fd, &tuple->tuple, tuple->src_mac, tuple->dst_mac, tuple->dev_name); |
| if (ret < 0){ |
| CM_Log_E(cm_toe_tuple_send5631, "cm_toe_tuple_send: send v4 tuple to kernel failed %d", ret); |
| } |
| else { |
| if (tuple->tuple.update_tuple == 0) |
| tuple->tuple.update_tuple = 1; |
| } |
| } |
| } |
| else if (tuple->type == IPV6) { |
| |
| #if 0 |
| if (g_toe_tft_param[i].mcid - 1 == i) { |
| tuple->tuple.mcid = i; |
| tuple->tuple.qfi = g_toe_tft_param[i].qfi; |
| tuple->tuple.pdu = g_toe_tft_param[i].pdu; |
| } |
| else { |
| tuple->tuple.mcid = 0xFF; |
| tuple->tuple.qfi = 0; |
| tuple->tuple.pdu = 0; |
| } |
| #endif |
| if (tuple->tuple.mcid != toe_param.mcid) { |
| tuple->tuple.mcid = toe_param.mcid; |
| param_updated = true; |
| } |
| |
| if (tuple->tuple.qfi != toe_param.qfi) { |
| tuple->tuple.qfi = toe_param.qfi; |
| param_updated = true; |
| } |
| |
| |
| if (tuple->tuple.pdu != toe_param.pdu) { |
| tuple->tuple.pdu = toe_param.pdu; |
| param_updated = true; |
| } |
| |
| if (param_updated) { |
| if (tuple->tuple.xlat_en) |
| { |
| CM_Log(cm_toe_tuple_send6149, "cm_toe_tuple_send: xlat enabled, send v4 tuple %x to kernel with socket fd %d, cid %d, qfi %d, pdu %d", tuple, cm_genl_fd.fd, tuple->tuple.mcid, tuple->tuple.qfi, tuple->tuple.pdu); |
| ret = genl_set_tuplev4_to_kernel(cm_genl_fd.fd, &tuple->tuple, tuple->src_mac, tuple->dst_mac, tuple->dev_name); |
| } |
| else |
| { |
| CM_Log(cm_toe_tuple_send6149, "cm_toe_tuple_send: send v6 tuple %x to kernel with socket fd %d, cid %d, qfi %d, pdu %d", tuple, cm_genl_fd.fd, tuple->tuple.mcid, tuple->tuple.qfi, tuple->tuple.pdu); |
| ret = genl_set_tuplev6_to_kernel(cm_genl_fd.fd, &tuple->tuple, tuple->src_mac, tuple->dst_mac, tuple->dev_name); |
| } |
| if (ret < 0){ |
| CM_Log_E(cm_toe_tuple_send5639, "cm_toe_tuple_send: send v6 tuple to kernel failed %d", ret); |
| } |
| else { |
| if (tuple->tuple.update_tuple == 0) |
| tuple->tuple.update_tuple = 1; |
| } |
| } |
| } |
| } |
| |
| if (tuple->tuple.in_pkt == PDU_PKT) { |
| list_del(&tuple->list); |
| free(tuple); |
| } |
| } |
| } |
| |
| #if 0 |
| while (!list_empty(head)) { |
| tuple = list_for_each(head, struct toe_tuple_list, list); |
| list_del(&tuple->list); |
| free(tuple); |
| } |
| #endif |
| CM_Log(cm_toe_tuple_send6162, "cm_toe_tuple_send: done"); |
| } |
| |
| static int cm_gnel_init(void) |
| { |
| cm_toe_tft_param_init(); |
| |
| cm_genl_fd.fd = genl_prepare(); |
| if (cm_genl_fd.fd < 0) { |
| CM_Log_E(cm_start_gnel, "genl_prepare failed\n"); |
| return -1; |
| } |
| cm_genl_fd.cb = genl_receive_cb; |
| |
| uloop_fd_add(&cm_genl_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); |
| return 0; |
| } |
| #endif |
| |
| int g_kernel_version_code = 0; |
| static int get_linux_kernel_version(void) |
| { |
| FILE *file = NULL; |
| char line[300] = { 0 }; |
| char major_verison[50]; |
| char minor_verison[50]; |
| int ret = 0; |
| |
| file = fopen("/proc/version", "r"); |
| if (!file) |
| return -1; |
| |
| if (fgets(line, sizeof(line), file) != NULL) { |
| CM_Log(get_linux_kernel_version80, "%s: line %s", __func__, line); |
| memset(major_verison, 0, sizeof(major_verison)); |
| memset(minor_verison, 0, sizeof(minor_verison)); |
| if (sscanf(line, "%[^.].%[^.].%*s", major_verison, minor_verison) != 2) { |
| ret = -1; |
| CM_Log(get_linux_kernel_version85,"%s: parse line failed\n", __func__); |
| goto end; |
| } |
| CM_Log(get_linux_kernel_version88, "%s: major_verison %s\n", __func__, major_verison); |
| CM_Log(get_linux_kernel_version89, "%s: minor_verison %s\n", __func__, minor_verison); |
| g_kernel_version_code = major_verison[strlen(major_verison) - 1] - '0'; |
| g_kernel_version_code = g_kernel_version_code << 16; |
| g_kernel_version_code += (atoi(minor_verison) << 8); |
| CM_Log(get_linux_kernel_version93, "%s: g_kernel_version_code 0x%x\n", __func__, g_kernel_version_code); |
| } |
| end: |
| fclose(file); |
| return ret; |
| } |
| |
| int main(int argc, char **argv) |
| { |
| const char *ubus_socket = NULL; |
| int ch, ret, retries = 0; |
| |
| //set tag name |
| set_service_log_tag("cm"); |
| |
| while ((ch = getopt(argc, argv, "pcs:")) != -1) { |
| switch (ch) { |
| case 's': |
| ubus_socket = optarg; |
| break; |
| case 'p': |
| pipe_mode = TRUE; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| argc -= optind; |
| argv += optind; |
| |
| CM_Log(main, "Start CM task,time:%s, date:%s\n",__TIME__,__DATE__); |
| get_linux_kernel_version(); |
| uloop_init(); |
| cm_ctx = ubus_connect(ubus_socket); |
| if (!cm_ctx) { |
| goto out; |
| } |
| |
| do { |
| if (RilIdReady()) |
| break; |
| sleep(1); |
| } while (retries++ < RIL_MAX_RETRIES); |
| |
| if (retries >= RIL_MAX_RETRIES) { |
| goto out1; |
| } |
| |
| ubus_add_uloop(cm_ctx); |
| |
| ret = ubus_add_object(cm_ctx, &cm_object); |
| if (ret) { |
| goto out1; |
| } |
| |
| ret = ubus_add_object(cm_ctx, &network_activity_obj); |
| if (ret) { |
| goto out1; |
| } |
| |
| ret = ubus_add_object(cm_ctx, &cm_fail_cause_obj); |
| if (ret) { |
| goto out1; |
| } |
| |
| ret = WaitForSimReady(); |
| if (ret < 0) { |
| goto out2; |
| } |
| |
| CM_UpdateActivedProfile(); |
| cm_ursp_init(); |
| |
| #ifdef CM_CONFIG_TOE |
| cm_tftinfo_init(); |
| ret = cm_gnel_init(); |
| #endif |
| |
| cm_query_reject_cause(); |
| nwactivity_arrary_init(); |
| cm_fifo_init(); |
| //start redial thread |
| ret = cm_start_thread(); |
| ret = dialer_init(); |
| ret = set_default_data_call(); |
| |
| eng_mode_init(); |
| |
| uloop_run(); |
| |
| out2: |
| ubus_remove_object(cm_ctx, &cm_object); |
| out1: |
| ubus_free(cm_ctx); |
| out: |
| uloop_done(); |
| CM_Log_E(main11, "main: exitl\n"); |
| return 0; |
| } |