| #include "ql_type.h" |
| #include "ql_data_call.h" |
| #include "mbtk_info_api.h" |
| |
| typedef struct { |
| int apn_id; |
| ql_data_call_apn_config_t apn_info; |
| } mbtk_data_call_apn_param_info_t; |
| |
| typedef struct { |
| QL_NET_DATA_CALL_RECONNECT_MODE_E reconnect_mode; |
| int time_num; |
| int time_list[QL_NET_MAX_RECONNECT_INTERVAL_LEN]; |
| mbtk_data_call_apn_param_info_t *apn_param; // Point to data_call_apn_param_list. |
| } mbtk_data_call_param_info_t; |
| |
| typedef struct { |
| ql_data_call_item_t call_info; |
| int is_background; |
| |
| ql_data_call_status_t call_state; |
| |
| mbtk_data_call_param_info_t call_param_info; |
| } mbtk_data_call_info_t; |
| |
| static mbtk_info_handle_t* ql_info_handle = NULL; |
| static mbtk_data_call_info_t data_call_info[QL_NET_MAX_DATA_CALL_NUM]; |
| static mbtk_data_call_apn_param_info_t data_call_apn_param_list[QL_NET_MAX_DATA_CALL_NUM]; |
| static ql_data_call_service_error_cb_f data_call_service_error_cb = NULL; |
| static ql_data_call_status_ind_cb_f data_call_status_ind_cb = NULL; |
| |
| static int call_index_get_by_call_id(int call_id) |
| { |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { |
| return -1; |
| } else { |
| return i; |
| } |
| } |
| |
| static int call_index_get_by_apn_id(int apn_id) |
| { |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_param_info.apn_param && |
| data_call_info[i].call_param_info.apn_param->apn_id == apn_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { |
| return -1; |
| } else { |
| return i; |
| } |
| } |
| |
| static void data_call_info_list_print() |
| { |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id > 0) { |
| LOGD("CALL START : call_id - %d, call_name - %s, is_background - %d", data_call_info[i].call_info.call_id, data_call_info[i].call_info.call_name, |
| data_call_info[i].is_background); |
| LOGD("call_state : ip_ver - %d, call_status - %d, device - %s", data_call_info[i].call_state.ip_ver, |
| data_call_info[i].call_state.call_status, data_call_info[i].call_state.device); |
| LOGD("param_info : reconnect_mode - %d, time_num - %d", data_call_info[i].call_param_info.reconnect_mode, |
| data_call_info[i].call_param_info.time_num); |
| int j = 0; |
| while(j < data_call_info[i].call_param_info.time_num) { |
| LOGD("time_item[%d] - %d", j, data_call_info[i].call_param_info.time_list[j]); |
| j++; |
| } |
| |
| if(data_call_info[i].call_param_info.apn_param) { |
| LOGD("apn_param : apn_id - %d, auth_pref - %d, ip_ver - %d, apn_name - %s, username - %s, password - %s", data_call_info[i].call_param_info.apn_param->apn_id, |
| data_call_info[i].call_param_info.apn_param->apn_info.auth_pref, |
| data_call_info[i].call_param_info.apn_param->apn_info.ip_ver, |
| data_call_info[i].call_param_info.apn_param->apn_info.apn_name, |
| data_call_info[i].call_param_info.apn_param->apn_info.username, |
| data_call_info[i].call_param_info.apn_param->apn_info.password); |
| } else { |
| LOGE("data_call_info[i]->call_param_info->apn_param is NULL."); |
| } |
| } |
| i++; |
| } |
| } |
| |
| static void data_call_info_item_print(int call_id) |
| { |
| int i = call_index_get_by_call_id(call_id); |
| if(i >= 0) { |
| LOGD("CALL START : call_id - %d, call_name - %s, is_background - %d", data_call_info[i].call_info.call_id, data_call_info[i].call_info.call_name, |
| data_call_info[i].is_background); |
| LOGD("call_state : ip_ver - %d, call_status - %d, device - %s", data_call_info[i].call_state.ip_ver, |
| data_call_info[i].call_state.call_status, data_call_info[i].call_state.device); |
| LOGD("param_info : reconnect_mode - %d, time_num - %d", data_call_info[i].call_param_info.reconnect_mode, |
| data_call_info[i].call_param_info.time_num); |
| int j = 0; |
| while(j < data_call_info[i].call_param_info.time_num) { |
| LOGD("time_item[%d] - %d", j, data_call_info[i].call_param_info.time_list[j]); |
| j++; |
| } |
| |
| if(data_call_info[i].call_param_info.apn_param) { |
| LOGD("apn_param : apn_id - %d, auth_pref - %d, ip_ver - %d, apn_name - %s, username - %s, password - %s", data_call_info[i].call_param_info.apn_param->apn_id, |
| data_call_info[i].call_param_info.apn_param->apn_info.auth_pref, |
| data_call_info[i].call_param_info.apn_param->apn_info.ip_ver, |
| data_call_info[i].call_param_info.apn_param->apn_info.apn_name, |
| data_call_info[i].call_param_info.apn_param->apn_info.username, |
| data_call_info[i].call_param_info.apn_param->apn_info.password); |
| } else { |
| LOGE("data_call_info[i]->call_param_info->apn_param is NULL."); |
| } |
| } |
| } |
| |
| |
| static void ril_server_state_cb(const void* data, int data_len) |
| { |
| if(data != NULL && data_len == sizeof(int)) { |
| const int *state = (const int*)data; |
| if(*state) { |
| if(data_call_service_error_cb) { |
| data_call_service_error_cb(QL_ERR_ABORTED); |
| } |
| } |
| } |
| } |
| |
| static void data_call_state_change_cb(const void* data, int data_len) |
| { |
| LOGD("data_call_state_change_cb() start."); |
| if(data == NULL || data_len == 0) |
| { |
| return; |
| } |
| |
| // data_call_info_print(); |
| |
| uint8 *net_data = NULL; |
| net_data = (uint8 *)data; |
| |
| if(*net_data > 100 && *net_data < 200) |
| { |
| int apn_id = *net_data - 100; |
| if(apn_id <= QL_NET_MAX_DATA_CALL_NUM) |
| { |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| |
| if(data_call_info[i].call_param_info.apn_param) { |
| if(data_call_info[i].call_param_info.apn_param->apn_id == apn_id) { |
| break; |
| } else { |
| LOGD("call_id = %d, apn_id = %d", data_call_info[i].call_info.call_id, |
| data_call_info[i].call_param_info.apn_param->apn_id); |
| } |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this apn_id. |
| LOGW("Unknown apn_id : %d", apn_id); |
| return; |
| } else { |
| QL_NET_DATA_CALL_STATUS_E pre_call_status = data_call_info[i].call_state.call_status; |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| if(data_call_status_ind_cb) { |
| data_call_status_ind_cb(data_call_info[i].call_info.call_id, pre_call_status, |
| &(data_call_info[i].call_state)); |
| } |
| } |
| } |
| else |
| { |
| LOGE("[qser_data] cb fail,idx is %d.", apn_id); |
| } |
| |
| } |
| else if(*net_data > 200 && *net_data < 220) |
| { |
| LOGE("[qser_data] cid[%d] is open.", *net_data - 200); |
| } |
| else if(*net_data > 220) |
| { |
| LOGE("[qser_data] cid[%d] is reopen.", *net_data - 220); |
| int apn_id = *net_data - 220; |
| if(apn_id <= QL_NET_MAX_DATA_CALL_NUM) |
| { |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_param_info.apn_param |
| && data_call_info[i].call_param_info.apn_param->apn_id == apn_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this apn_id. |
| LOGW("Unknown apn_id : %d", apn_id); |
| return; |
| } else { |
| QL_NET_DATA_CALL_STATUS_E pre_call_status = data_call_info[i].call_state.call_status; |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTED; |
| if(data_call_status_ind_cb) { |
| data_call_status_ind_cb(data_call_info[i].call_info.call_id, pre_call_status, |
| &(data_call_info[i].call_state)); |
| } |
| } |
| } |
| } |
| else if(*net_data == 1) |
| { |
| LOGE("[qser_data] pdp is open."); |
| } |
| else |
| { |
| LOGE("[qser_data] unkonwn param [%d].", *net_data); |
| } |
| } |
| |
| static int data_call_state_query(int call_id) |
| { |
| int i = call_index_get_by_call_id(call_id); |
| if(i < 0) { |
| LOGE("Unknown call_id : %d", call_id); |
| return -1; |
| } |
| |
| // Get network information. |
| mbtk_ipv4_info_t ipv4; |
| mbtk_ipv6_info_t ipv6; |
| QL_NET_DATA_CALL_STATUS_E pre_call_status = data_call_info[i].call_state.call_status; |
| int ret = mbtk_data_call_state_get(ql_info_handle, data_call_info[i].call_param_info.apn_param->apn_id, &ipv4, &ipv6); |
| if(ret != 0) |
| { |
| LOGE("mbtk_data_call_state_get fail.[ret = %d]", ret); |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_ERROR; |
| return -1; |
| } |
| else |
| { |
| data_call_info[i].call_state.has_addr = ipv4.valid; |
| if(ipv4.valid) |
| { |
| if(inet_ntop(AF_INET, &(ipv4.IPAddr), data_call_info[i].call_state.addr.addr , QL_NET_MAX_ADDR_LEN) == NULL) { |
| LOGE("IPv4 error."); |
| } else { |
| LOGD("IPv4 : %s", data_call_info[i].call_state.addr.addr); |
| } |
| |
| if(inet_ntop(AF_INET, &(ipv4.NetMask), data_call_info[i].call_state.addr.netmask , QL_NET_MAX_ADDR_LEN) == NULL) { |
| LOGE("NetMask error."); |
| } else { |
| LOGD("NetMask : %s", data_call_info[i].call_state.addr.netmask); |
| } |
| |
| if(inet_ntop(AF_INET, &(ipv4.GateWay), data_call_info[i].call_state.addr.gateway , QL_NET_MAX_ADDR_LEN) == NULL) { |
| LOGE("GateWay error."); |
| } else { |
| LOGD("GateWay : %s", data_call_info[i].call_state.addr.gateway); |
| } |
| |
| if(inet_ntop(AF_INET, &(ipv4.PrimaryDNS), data_call_info[i].call_state.addr.dnsp , QL_NET_MAX_ADDR_LEN) == NULL) { |
| LOGE("PrimaryDNS error."); |
| } else { |
| LOGD("PrimaryDNS : %s", data_call_info[i].call_state.addr.dnsp); |
| } |
| |
| if(inet_ntop(AF_INET, &(ipv4.SecondaryDNS), data_call_info[i].call_state.addr.dnss , QL_NET_MAX_ADDR_LEN) == NULL) { |
| LOGE("SecondaryDNS error."); |
| } else { |
| LOGD("SecondaryDNS : %s", data_call_info[i].call_state.addr.dnss); |
| } |
| } |
| |
| data_call_info[i].call_state.has_addr6 = ipv6.valid; |
| if(ipv6.valid) |
| { |
| if(ipv6_2_str(&(ipv6.IPV6Addr), data_call_info[i].call_state.addr6.addr)) { |
| LOGE("IPv6 error."); |
| } else { |
| LOGD("IPv6 : %s", data_call_info[i].call_state.addr6.addr); |
| } |
| |
| if(ipv6_2_str(&(ipv6.NetMask), data_call_info[i].call_state.addr6.prefix)) { |
| LOGE("prefix error."); |
| } else { |
| LOGD("prefix : %s", data_call_info[i].call_state.addr6.prefix); |
| } |
| |
| if(ipv6_2_str(&(ipv6.GateWay), data_call_info[i].call_state.addr6.gateway)) { |
| LOGE("GateWay error."); |
| } else { |
| LOGD("GateWay : %s", data_call_info[i].call_state.addr6.gateway); |
| } |
| |
| if(ipv6_2_str(&(ipv6.PrimaryDNS), data_call_info[i].call_state.addr6.dnsp)) { |
| LOGE("PrimaryDNS error."); |
| } else { |
| LOGD("PrimaryDNS : %s", data_call_info[i].call_state.addr6.dnsp); |
| } |
| |
| if(ipv6_2_str(&(ipv6.SecondaryDNS), data_call_info[i].call_state.addr6.dnsp)) { |
| LOGE("SecondaryDNS error."); |
| } else { |
| LOGD("SecondaryDNS : %s", data_call_info[i].call_state.addr6.dnsp); |
| } |
| } |
| |
| pre_call_status = data_call_info[i].call_state.call_status; |
| #if 1 |
| if(data_call_info[i].call_state.ip_ver == QL_NET_IP_VER_V4V6) { |
| if(ipv4.valid && !ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_PARTIAL_V4_CONNECTED; |
| } else if(!ipv4.valid && ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_PARTIAL_V6_CONNECTED; |
| } else if(ipv4.valid && ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTED; |
| } else { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| } |
| } else if(data_call_info[i].call_state.ip_ver == QL_NET_IP_VER_V4) { |
| if(ipv4.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTED; |
| } else { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| } |
| } else if(data_call_info[i].call_state.ip_ver == QL_NET_IP_VER_V6) { |
| if(ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTED; |
| } else { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| } |
| } else { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| } |
| #else |
| if(ipv4.valid && ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTED; |
| } else if(!ipv4.valid && ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_PARTIAL_V6_CONNECTED; |
| } else if(ipv4.valid && !ipv6.valid) { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_PARTIAL_V4_CONNECTED; |
| } else { |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_DISCONNECTED; |
| } |
| #endif |
| |
| if(data_call_status_ind_cb) { |
| data_call_status_ind_cb(call_id, pre_call_status, |
| &(data_call_info[i].call_state)); |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Initialize the data call service |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_INVALID_ARG - as defined |
| QL_ERR_UNKNOWN - unknown error, failed to connect to service |
| QL_ERR_SERVICE_NOT_READY - service is not ready, need to retry |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_init(void) |
| { |
| if(ql_info_handle == NULL) |
| { |
| |
| mbtk_log_init("radio", "QL_DATA_CALL"); |
| |
| ql_info_handle = mbtk_info_handle_get(); |
| if(ql_info_handle) |
| { |
| memset(&data_call_info, 0, sizeof(data_call_info)); |
| memset(&data_call_apn_param_list, 0, sizeof(data_call_apn_param_list)); |
| return QL_ERR_OK; |
| } else { |
| LOGE("mbtk_info_handle_get() fail."); |
| return QL_ERR_UNKNOWN; |
| } |
| } else { |
| return QL_ERR_UNKNOWN; |
| } |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Create a data call instance |
| @param[in] call_id The unique identifier of the data call instance, specified by the user |
| @param[in] call_name Friendly data call name, specified by the user |
| @param[in] is_background Whether the data call status is maintained by the data call service daemon. |
| If it is 0, the data call instance will be deleted after the data call process exits. |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_INVALID_ARG - as defined |
| QL_ERR_UNKNOWN - unknown error, failed to connect to service |
| QL_ERR_SERVICE_NOT_READY - service is not ready, need to retry |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_create(int call_id, const char *call_name, int is_background) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(call_id <= 0 || call_name == NULL || strlen(call_name) == 0 |
| || strlen(call_name) > QL_NET_MAX_NAME_LEN) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == 0) { // Not use. |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // data_call item full. |
| LOGW("data_call instance is full."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| data_call_info[i].call_info.call_id = call_id; |
| memcpy(data_call_info[i].call_info.call_name, call_name, strlen(call_name)); |
| data_call_info[i].call_state.call_id = call_id; |
| memcpy(data_call_info[i].call_state.call_name, call_name, strlen(call_name)); |
| |
| data_call_info[i].is_background = is_background; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Alloc for a data call configuration instance |
| @return |
| NULL - Not enough memory |
| Other - successful |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| ql_data_call_param_t *ql_data_call_param_alloc(void) |
| { |
| ql_data_call_param_t *result = malloc(sizeof(mbtk_data_call_param_info_t)); |
| if(result) { |
| memset(result, 0, sizeof(mbtk_data_call_param_info_t)); |
| } |
| |
| return result; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Initialize the data call configuration instance |
| @param[in] param Point to the data call configuration instance |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_init(ql_data_call_param_t *param) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| memset(info, 0, sizeof(mbtk_data_call_param_info_t)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Release the data call configuration instance |
| @param[in] param Point to the data call configuration instance |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_free(ql_data_call_param_t *param) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| free(param); |
| |
| return QL_ERR_OK; |
| } |
| |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Bind APN ID, range:1-16 |
| @param[in] param Point to the data call configuration instance |
| @param[in] apn_id APN ID, range:1-16 |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_apn_id(ql_data_call_param_t *param, int apn_id) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| // 1 - 7 |
| if(param == NULL || apn_id <= 0 || apn_id > QL_NET_MAX_APN_ID) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_apn_param_list[i].apn_id == apn_id) { |
| break; |
| } |
| i++; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param != NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { |
| LOGW("No found apn_id : %d.", apn_id); |
| // Found next empty apn item. |
| int j = 0; |
| while(j < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_apn_param_list[j].apn_id <= 0) { |
| break; |
| } |
| j++; |
| } |
| if(j == QL_NET_MAX_DATA_CALL_NUM) { // Full |
| return QL_ERR_UNKNOWN; |
| } |
| |
| info->apn_param = &(data_call_apn_param_list[j]); |
| info->apn_param->apn_id = apn_id; |
| } else { |
| // Found apn_id |
| info->apn_param = &(data_call_apn_param_list[i]); |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get APN name from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] buf APN ID |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_apn_id(ql_data_call_param_t *param, int *apn_id) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || apn_id == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| *apn_id = info->apn_param->apn_id; |
| |
| return QL_ERR_OK; |
| } |
| |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure APN name |
| @param[in] param Point to the data call configuration instance |
| @param[in] apn_name APN name |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_apn_name(ql_data_call_param_t *param, const char *apn_name) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || apn_name == NULL || strlen(apn_name) == 0 |
| || strlen(apn_name) > QL_NET_MAX_APN_NAME_LEN) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(info->apn_param->apn_info.apn_name, apn_name, strlen(apn_name)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get APN name from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] buf APN name buffer |
| @param[in] buf_len APN name buffer size |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_apn_name(ql_data_call_param_t *param, char *buf, int buf_len) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || buf == NULL || buf_len <= 0) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| if(strlen(info->apn_param->apn_info.apn_name) + 1 > buf_len) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(buf, info->apn_param->apn_info.apn_name, strlen(info->apn_param->apn_info.apn_name)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure APN user name |
| @param[in] param Point to the data call configuration instance |
| @param[in] user_name APN user name |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_user_name(ql_data_call_param_t *param, const char *user_name) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || user_name == NULL || strlen(user_name) == 0 |
| || strlen(user_name) > QL_NET_MAX_APN_USERNAME_LEN) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(info->apn_param->apn_info.username, user_name, strlen(user_name)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get APN user name from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] buf APN user name buffer |
| @param[in] buf_len APN user name buffer size |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_user_name(ql_data_call_param_t *param, char *buf, int buf_len) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || buf == NULL || buf_len <= 0) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| if(strlen(info->apn_param->apn_info.username) + 1 > buf_len) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(buf, info->apn_param->apn_info.username, strlen(info->apn_param->apn_info.username)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure APN user password |
| @param[in] param Point to the data call configuration instance |
| @param[in] user_password APN user password |
| @return |
| QL_ERR_OK - Not enough memory |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_user_password(ql_data_call_param_t *param, const char *user_password) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || user_password == NULL || strlen(user_password) == 0 |
| || strlen(user_password) > QL_NET_MAX_APN_PASSWORD_LEN) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(info->apn_param->apn_info.password, user_password, strlen(user_password)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get APN user password from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] buf APN user password buffer |
| @param[in] buf_len APN user password buffer size |
| @return |
| QL_ERR_OK - Not enough memory |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_user_password(ql_data_call_param_t *param, char *buf, int buf_len) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || buf == NULL || buf_len <= 0) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| if(strlen(info->apn_param->apn_info.password) + 1 > buf_len) { |
| return QL_ERR_INVALID_ARG; |
| } |
| memcpy(buf, info->apn_param->apn_info.password, strlen(info->apn_param->apn_info.password)); |
| |
| return QL_ERR_OK; |
| } |
| |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the data call authentication method |
| @param[in] param Point to the data call configuration instance |
| @param[in] auth_pref Defined by QL_DATA_CALL_AUTH_PREF_E |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_auth_pref(ql_data_call_param_t *param, int auth_pref) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| info->apn_param->apn_info.auth_pref = (QL_NET_AUTH_PREF_E)auth_pref; |
| |
| return QL_ERR_OK; |
| |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the data call authentication method |
| @param[in] param Point to the data call configuration instance |
| @param[out] p_data Store return value |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_auth_pref(ql_data_call_param_t *param, int *p_data) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || p_data == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| *p_data = info->apn_param->apn_info.auth_pref; |
| |
| return QL_ERR_OK; |
| } |
| |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the data call IP version |
| @param[in] param Point to the data call configuration instance |
| @param[in] ip_ver Defined by QL_NET_IP_VER_E |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_ip_version(ql_data_call_param_t *param, int ip_ver) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| info->apn_param->apn_info.ip_ver = (QL_NET_IP_VER_E)ip_ver; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get IP version from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] p_ver Store return value |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_ip_version(ql_data_call_param_t *param, int *p_ver) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || p_ver == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| if(info->apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| *p_ver = info->apn_param->apn_info.ip_ver; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the data call auto reconnection mode |
| @param[in] param Point to the data call configuration instance |
| @param[in] mode Defined by QL_NET_DATA_CALL_RECONNECT_MODE_E |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_reconnect_mode(ql_data_call_param_t *param, int reconnect_mode) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| info->reconnect_mode = reconnect_mode; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get auto reconnection mode from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] p_mode Store return value |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_reconnect_mode(ql_data_call_param_t *param, int *p_mode) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || p_mode == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| *p_mode = info->reconnect_mode; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the data call auto reconnection interval |
| @param[in] param Point to the data call configuration instance |
| @param[in] time_list Interval time list in ms |
| @param[in] num Number of time list |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_set_reconnect_interval(ql_data_call_param_t *param, int *time_list, int num) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || time_list == NULL || num <= 0 || num > QL_NET_MAX_RECONNECT_INTERVAL_LEN) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| info->time_num = num; |
| memcpy(&(info->time_list), time_list, sizeof(int) * num); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get auto reconnection interval from configuration instance |
| @param[in] param Point to the data call configuration instance |
| @param[out] time_list Store return value |
| @param[in,out] p_num |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_param_get_reconnect_interval(ql_data_call_param_t *param, int *time_list, int *p_num) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL || time_list == NULL || p_num == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| mbtk_data_call_param_info_t *info = (mbtk_data_call_param_info_t*)param; |
| *p_num = info->time_num; |
| int i = 0; |
| for(; i < info->time_num; i++) { |
| *(time_list + i) = info->time_list[i]; |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Configure the specified data call instance |
| @param[in] call_id Specify a data call instance |
| @param[in] param Point to the data call configuration instance |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_config(int call_id, ql_data_call_param_t *param) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this call_id. |
| LOGW("Unknown call_id : %d", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| memcpy(&(data_call_info[i].call_param_info), param, sizeof(mbtk_data_call_param_info_t));; |
| |
| if(data_call_info[i].call_param_info.apn_param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| snprintf(data_call_info[i].call_state.device, QL_NET_MAX_NAME_LEN, "ccinet%d", |
| data_call_info[i].call_param_info.apn_param->apn_id - 1); |
| data_call_info[i].call_state.ip_ver = data_call_info[i].call_param_info.apn_param->apn_info.ip_ver; |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_IDLE; |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get the specified data call configuration instance |
| @param[in] call_id Specify a data call instance |
| @param[in] param Point to the data call configuration instance |
| @return |
| QL_ERR_OK - Successful |
| QL_ERR_INVALID_ARG - Invalid arguments |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_get_config(int call_id, ql_data_call_param_t *param) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(param == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this call_id. |
| LOGW("Unknown call_id : %d", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| memcpy(param, &(data_call_info[i].call_param_info), sizeof(mbtk_data_call_param_info_t)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Start data call |
| @param[in] call_id Specify a data call instance |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_start(int call_id) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| int i = call_index_get_by_call_id(call_id); |
| if(i < 0) { |
| LOGE("Unknown call_id : %d", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| if(data_call_info[i].call_param_info.apn_param == NULL) { |
| LOGE("data_call_info[i]->call_param_info->apn_param is NULL."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| int ret = data_call_state_query(call_id); |
| if(ret) { |
| LOGE("data_call_state_query fail."); |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_IDLE; |
| // return QL_ERR_UNKNOWN; |
| } |
| |
| if(data_call_info[i].call_state.call_status == QL_NET_DATA_CALL_STATUS_PARTIAL_V4_CONNECTED |
| || data_call_info[i].call_state.call_status == QL_NET_DATA_CALL_STATUS_PARTIAL_V6_CONNECTED |
| || data_call_info[i].call_state.call_status == QL_NET_DATA_CALL_STATUS_CONNECTED) { |
| LOGW("call_id %d has connected.", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| LOGD("Start Data Call : %d", call_id); |
| data_call_info_item_print(call_id); |
| |
| // Set APN in the first. |
| mbtk_ip_type_enum ip_type; |
| switch(data_call_info[i].call_param_info.apn_param->apn_info.ip_ver) { |
| case QL_NET_IP_VER_V4: |
| ip_type = MBTK_IP_TYPE_IP; |
| break; |
| case QL_NET_IP_VER_V6: |
| ip_type = MBTK_IP_TYPE_IPV6; |
| break; |
| case QL_NET_IP_VER_V4V6: |
| ip_type = MBTK_IP_TYPE_IPV4V6; |
| break; |
| default: |
| LOGE("Unknown ip_ver."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| char auth_type[64]={0}; |
| switch(data_call_info[i].call_param_info.apn_param->apn_info.auth_pref) { |
| case QL_NET_AUTH_PREF_PAP_CHAP_NOT_ALLOWED: |
| memcpy(auth_type,"NONE",strlen("NONE")); |
| break; |
| case QL_NET_AUTH_PREF_PAP_ONLY_ALLOWED: |
| memcpy(auth_type,"PAP",strlen("PAP")); |
| break; |
| case QL_NET_AUTH_PREF_CHAP_ONLY_ALLOWED: |
| memcpy(auth_type,"CHAP",strlen("CHAP")); |
| break; |
| #if 0 |
| case QL_NET_AUTH_PREF_PAP_CHAP_BOTH_ALLOWED: |
| apninfo.auth_proto = MBTK_APN_AUTH_PROTO_PAP_CHAP; |
| break; |
| #endif |
| default: |
| LOGE("Unknown auth_pref."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| ret = mbtk_apn_set(ql_info_handle, data_call_info[i].call_param_info.apn_param->apn_id, ip_type, |
| data_call_info[i].call_param_info.apn_param->apn_info.apn_name, |
| data_call_info[i].call_param_info.apn_param->apn_info.username, |
| data_call_info[i].call_param_info.apn_param->apn_info.password, auth_type); |
| if(ret) { |
| LOGE("mbtk_apn_set fail."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| // Start data call. |
| int auto_conn_interval = 0; |
| QL_NET_DATA_CALL_STATUS_E pre_call_status = data_call_info[i].call_state.call_status; |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_CONNECTING; |
| if(data_call_status_ind_cb) { |
| data_call_status_ind_cb(call_id, pre_call_status, |
| &(data_call_info[i].call_state)); |
| } |
| |
| if(data_call_info[i].call_param_info.reconnect_mode == QL_NET_DATA_CALL_RECONNECT_NORMAL |
| || data_call_info[i].call_param_info.reconnect_mode == QL_NET_DATA_CALL_RECONNECT_MODE_1 |
| || data_call_info[i].call_param_info.reconnect_mode == QL_NET_DATA_CALL_RECONNECT_MODE_2) { |
| if(data_call_info[i].call_param_info.time_num > 0) { |
| auto_conn_interval = data_call_info[i].call_param_info.time_list[0]; |
| } |
| } else { |
| auto_conn_interval = 0; |
| } |
| |
| ret = mbtk_data_call_start(ql_info_handle, data_call_info[i].call_param_info.apn_param->apn_id, auto_conn_interval, |
| FALSE, 0); |
| if(ret) { |
| LOGE("mbtk_data_call_start fail."); |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_ERROR; |
| return QL_ERR_UNKNOWN; |
| } |
| |
| ret = data_call_state_query(call_id); |
| if(ret) { |
| LOGE("data_call_state_query fail."); |
| data_call_info[i].call_state.call_status = QL_NET_DATA_CALL_STATUS_ERROR; |
| return QL_ERR_UNKNOWN; |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Stop data call |
| @param[in] call_id Specify a data call instance |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_stop(int call_id) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(data_call_info[i].call_param_info.apn_param) { |
| int ret = mbtk_data_call_stop(ql_info_handle, data_call_info[i].call_param_info.apn_param->apn_id, 15); |
| if(ret) { |
| LOGE("mbtk_data_call_stop() fail."); |
| return QL_ERR_UNKNOWN; |
| } |
| } else { |
| LOGE("data_call_info[i]->call_param_info->apn_param is NULL."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Delete a data call instance |
| @param[in] call_id Specify a data call instance |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_delete(int call_id) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this call_id. |
| LOGW("Unknown call_id : %d", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| if(data_call_info[i].call_param_info.apn_param) { |
| memset(data_call_info[i].call_param_info.apn_param, 0, sizeof(mbtk_data_call_apn_param_info_t)); |
| } |
| memset(&(data_call_info[i]), 0, sizeof(mbtk_data_call_info_t)); |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get the current data call instance list |
| @param[out] list Data call instance array |
| @param[in,out] list_len, in-> Data call instance array size, out->current data call instance number |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_get_list(ql_data_call_item_t *list, int *list_len) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(list == NULL || list_len == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| *list_len = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id > 0) { |
| memset(&(list[*list_len]), 0, sizeof(ql_data_call_item_t)); |
| list[*list_len].call_id = data_call_info[i].call_info.call_id; |
| memcpy(list[*list_len].call_name, data_call_info[i].call_info.call_name, |
| strlen(data_call_info[i].call_info.call_name)); |
| |
| (*list_len)++; |
| } |
| i++; |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Get the data call status |
| @param[in] call_id Specify a data call instance |
| @param[out] p_sta Point to status instance |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_get_status(int call_id, ql_data_call_status_t *p_sta) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(p_sta == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_info.call_id == call_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this call_id. |
| LOGW("Unknown call_id : %d", call_id); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| memcpy(p_sta, &(data_call_info[i].call_state), sizeof(ql_data_call_status_t)); |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Register data call status change event |
| @param[in] cb |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_set_status_ind_cb(ql_data_call_status_ind_cb_f cb) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_UNKNOWN; |
| } else { |
| if(mbtk_pdp_state_change_cb_reg(ql_info_handle, data_call_state_change_cb)) |
| { |
| return QL_ERR_UNKNOWN; |
| } |
| |
| data_call_status_ind_cb = cb; |
| return QL_ERR_OK; |
| } |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Set APN related configuration.If the apn does not exist, it is automatically created. |
| @param[in] apn_id APN ID, range:1-16 |
| @param[in] p_info APN configuration |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_set_apn_config(int apn_id, ql_data_call_apn_config_t *p_info) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(p_info == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_param_info.apn_param |
| && data_call_info[i].call_param_info.apn_param->apn_id == apn_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this apn_id. |
| LOGW("New apn_id : %d", apn_id); |
| // New data call param. |
| int j = 0; |
| while(j < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_apn_param_list[j].apn_id <= 0) { |
| break; |
| } |
| j++; |
| } |
| |
| if(j == QL_NET_MAX_DATA_CALL_NUM) { // Full |
| LOGW("data_call_apn_param_list is full."); |
| return QL_ERR_UNKNOWN; |
| } |
| |
| data_call_apn_param_list[j].apn_id = apn_id; |
| memcpy(&(data_call_apn_param_list[j].apn_info), p_info, sizeof(ql_data_call_apn_config_t)); |
| } else { |
| memcpy(&(data_call_info[i].call_param_info.apn_param->apn_info), p_info, sizeof(ql_data_call_apn_config_t)); |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Set APN related configuration. If the apn does not exist, it is automatically created and |
| the default parameters are set. |
| @param[in] apn_id APN ID, range:1-16 |
| @param[out] p_info APN configuration |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_get_apn_config(int apn_id, ql_data_call_apn_config_t *p_info) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_SERVICE_NOT_READY; |
| } |
| |
| if(p_info == NULL || p_info == NULL) { |
| return QL_ERR_INVALID_ARG; |
| } |
| |
| int i = 0; |
| while(i < QL_NET_MAX_DATA_CALL_NUM) { |
| if(data_call_info[i].call_param_info.apn_param |
| && data_call_info[i].call_param_info.apn_param->apn_id == apn_id) { |
| break; |
| } |
| i++; |
| } |
| |
| if(i == QL_NET_MAX_DATA_CALL_NUM) { // No found this apn_id. |
| LOGE("Unknown apn_id : %d", apn_id); |
| return QL_ERR_UNKNOWN; |
| } else { |
| memcpy(p_info, &(data_call_info[i].call_param_info.apn_param->apn_info), sizeof(ql_data_call_apn_config_t)); |
| } |
| |
| return QL_ERR_OK; |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Set APN related configuration,APN ID:1 |
| @param[in] p_info APN configuration |
| @return |
| QL_ERR_OK - successful |
| QL_ERR_NOT_INIT - uninitialized |
| QL_ERR_SERVICE_NOT_READY - service is not ready |
| QL_ERR_INVALID_ARG - Invalid arguments |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_set_attach_apn_config(ql_data_call_apn_config_t *p_info) |
| { |
| return ql_data_call_set_apn_config(1, p_info); |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Registration server error callback. Currently, only if the server exits abnormally, |
| the callback function will be executed, and the error code is QL_ERR_ABORTED; |
| @param[in] cb Callback function |
| @return |
| QL_ERR_OK - successful |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_set_service_error_cb(ql_data_call_service_error_cb_f cb) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_UNKNOWN; |
| } else { |
| if(mbtk_ril_server_state_change_reg(ql_info_handle, ril_server_state_cb)) |
| { |
| return QL_ERR_UNKNOWN; |
| } |
| |
| data_call_service_error_cb = cb; |
| return QL_ERR_OK; |
| } |
| } |
| |
| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @brief Deinitialize the data call service |
| @return |
| QL_ERR_OK - successful |
| Other - error code defined by ql_type.h |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| int ql_data_call_deinit(void) |
| { |
| if(ql_info_handle == NULL) |
| { |
| return QL_ERR_UNKNOWN; |
| } else { |
| if(mbtk_info_handle_free(&ql_info_handle)) |
| { |
| return QL_ERR_UNKNOWN; |
| } |
| |
| return QL_ERR_OK; |
| } |
| } |