blob: 6a50b6cb00bf0814ad6ef43428c33040ad78c1be [file] [log] [blame]
#include "profile_management.h"
//////////////////////////////////////////////////////////////////////
// local Prototypes
//////////////////////////////////////////////////////////////////////
struct uci_context *get_uci_profile_ctx(void);
void free_uci_profile_ctx(void);
struct uci_package *new_uci_package(struct uci_context *ctx, char *package_name);
int free_uci_package(struct uci_context *ctx, char *package_name);
int uci_delete_section(struct uci_context *ctx, char *package_name, char *section_name);
int uci_set_list(struct uci_context *ctx, char *package_name, char *section_type, char *section_name, char *list_name,
char *list_value);
int uci_delete_list(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *list_name, char *list_value);
int uci_delete_package(struct uci_context *ctx, char *package_name);
int update_actived_profile(s_profile_param * info, int delete);
int is_actived_profile(s_profile_param * info);
int update_pdp_to_uci(struct blob_attr *msg, s_profile_param * info);
struct uci_package *get_uci_package(struct uci_context *ctx, char *package_name, int flag);
Mnc_Apn *get_mnc_apn_info();
s_type_connNum type_connNum[TYPE_CONNNUM_PAIR_NUM] = {
{"default", CM_DEFAULT_ATTACH_CID}
,
{"ims", IMS}
,
{"mms", MMS}
,
{"supl", SUPL}
,
{"fota", FOTA}
,
{"bip", BIP}
};
#define PROC_CMDLINE "/proc/cmdline"
#define GETELFLG_NAME "GEFL="
#define CMDLINE_LEN 1024
Mnc_Apn *g_work_apn;
extern Mnc_Apn *IMSI_APN;
extern struct blob_buf cm_b;
extern bool IsRoaming;
struct uci_context *get_uci_profile_ctx(void)
{
return (struct uci_context *)uci_wan_ctx_get();
}
void free_uci_profile_ctx(void)
{
free_wan_uci_ctx();
}
static bool uci_validate_name(char *name, bool flag)
{
if (!*name)
return false;
while (*name) {
unsigned char c = *name;
if (!isalnum(c) && c != '_' && c != '.') {
if (flag || (c < 33) || (c > 126))
return false;
}
name++;
}
return true;
}
struct uci_package *new_uci_package(struct uci_context *ctx, char *package_name)
{
struct uci_package *p = NULL;
FILE *uci_fd = NULL;
char path[MAX_STR_LEN] = { 0 };
int ret = UCI_OK;
if (!ctx || !package_name || !uci_validate_name(package_name, false)) {
return NULL;
}
snprintf(path, MAX_STR_LEN - 1, "/etc/config/%s", package_name);
uci_fd = fopen(path, "w");
if (uci_fd != NULL)
fclose(uci_fd);
else {
return NULL;
}
ret = uci_load(ctx, package_name, &p);
if (ret == UCI_OK)
return p;
else
return NULL;
}
struct uci_package *get_uci_package(struct uci_context *ctx, char *package_name, int flag)
{
struct uci_package *p = NULL;
struct uci_element *e = NULL;
int ret = UCI_OK;
if (!ctx || !package_name) {
return NULL;
}
uci_foreach_element(&ctx->root, e) {
if (strcmp(e->name, package_name))
continue;
p = uci_to_package(e);
break;
}
if (!p) {
ret = uci_load(ctx, package_name, &p);
if (ret) {
return NULL;
}
}
if (p)
return p;
else {
if (flag) {
p = new_uci_package(ctx, package_name);
if (!p) {
return NULL;
}
return p;
} else {
return NULL;
}
}
}
int uci_commit_package(struct uci_context *ctx, char *package_name)
{
struct uci_package *p;
int ret;
if (!ctx || !package_name) {
return UCI_ERR_INVAL;
}
p = get_uci_package(ctx, package_name, false);
if (p) {
//free_uci_package(ctx, package_name);
ret = uci_commit(ctx, &p, false);
} else {
ret = UCI_ERR_INVAL;
return ret;
}
//free_uci_package(ctx, package_name);
free_uci_profile_ctx();
return ret;
}
int free_uci_package(struct uci_context *ctx, char *package_name)
{
struct uci_package *p = NULL;
int ret;
if (!ctx || !package_name) {
return UCI_ERR_INVAL;
}
p = get_uci_package(ctx, package_name, false);
if (!p) {
return UCI_ERR_INVAL;
}
ret = uci_unload(ctx, p);
return ret;
}
struct uci_section *get_uci_section(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
int flag)
{
struct uci_package *p = NULL;
struct uci_section *s = NULL;
struct uci_ptr ptr;
int ret = UCI_OK;
if (!ctx || !package_name || !section_type || !section_name) {
return NULL;
}
p = get_uci_package(ctx, package_name, true);
if (!p) {
if (flag) {
p = new_uci_package(ctx, package_name);
if (!p) {
return NULL;
}
} else {
return NULL;
}
}
if ((s = uci_lookup_section(ctx, p, section_name)) != NULL) {
return s;
}
else if (flag == false)
return NULL;
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.section = section_name;
ptr.value = section_type;
ptr.flags |= UCI_LOOKUP_DONE;
ret = uci_set(ctx, &ptr);
if (ret == UCI_OK)
return ptr.s;
else
return NULL;
}
int uci_set_option(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *option_name, char *option_value)
{
struct uci_package *p = NULL;
struct uci_section *s = NULL;
struct uci_ptr ptr;
int ret = UCI_OK;
if (!package_name || !section_type || !section_name || !option_name || !option_value) {
return UCI_ERR_INVAL;
}
#if 0
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, false)
|| !uci_validate_name(option_name, false)) {
CM_Log_E(uci_set_option1, "uci_set_option: invalid input name\n");
return UCI_ERR_INVAL;
}
#endif
p = get_uci_package(ctx, package_name, true);
if (!p) {
return UCI_ERR_INVAL;
}
s = get_uci_section(ctx, package_name, section_type, section_name, true);
if (s) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = s;
ptr.package = package_name;
ptr.section = section_name;
ptr.option = option_name;
ptr.value = option_value;
//ptr.flags |= UCI_LOOKUP_DONE;
ptr.flags |= UCI_LOOKUP_COMPLETE;
ret = uci_set(ctx, &ptr);
ret = uci_commit(ctx, &p, false);
return ret;
} else {
return UCI_ERR_INVAL;
}
}
char *uci_get_option(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *option_name)
{
struct uci_section *s = NULL;
char *str = NULL;
if (!ctx || !package_name || !section_type || !section_name || !option_name) {
return NULL;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)
|| !uci_validate_name(option_name, true)) {
return NULL;
}
s = get_uci_section(ctx, package_name, section_type, section_name, false);
if (s) {
str = (char *)uci_lookup_option_string(ctx, s, option_name);
return str;
} else {
return NULL;
}
}
int uci_delete_section(struct uci_context *ctx, char *package_name, char *section_name)
{
struct uci_package *p = NULL;
struct uci_ptr ptr;
int ret = UCI_OK;
if (!package_name || !section_name) {
return UCI_ERR_INVAL;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)) {
return UCI_ERR_INVAL;
}
p = get_uci_package(ctx, package_name, true);
if (!p) {
return UCI_ERR_INVAL;
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.package = package_name;
ptr.section = section_name;
ret = uci_delete(ctx, &ptr);
return ret;
}
int uci_get_list_number(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *list_name)
{
struct uci_section *s = NULL;
struct uci_option *o = NULL;
struct uci_element *e = NULL;
int count = 0;
if (!ctx || !package_name || !section_type || !section_name || !list_name) {
return 0;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)
|| !uci_validate_name(list_name, true)) {
return 0;
}
s = get_uci_section(ctx, package_name, section_type, section_name, false);
if (s) {
o = uci_lookup_option(ctx, s, list_name);
if (!o) {
return 0;
}
if (o->type != UCI_TYPE_LIST) {
return 0;
}
uci_foreach_element(&o->v.list, e) {
//lookup each list item
count++;
}
} else {
return 0;
}
// the total count
CM_Log(uci_get_list_number2, "uci_get_list_number: list %s count %d\n", list_name, count);
return count;
}
char *uci_get_list_value(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *list_name, int index)
{
struct uci_section *s = NULL;
struct uci_option *o = NULL, *list_o = NULL;
struct uci_element *e = NULL;
char *str = NULL;
int count = 0;
if (!ctx || !package_name || !section_type || !section_name || !list_name) {
return NULL;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)
|| !uci_validate_name(list_name, true)) {
return NULL;
}
s = get_uci_section(ctx, package_name, section_type, section_name, false);
if (s) {
o = uci_lookup_option(ctx, s, list_name);
if (!o) {
return NULL;
}
if (o->type != UCI_TYPE_LIST) {
return NULL;
}
uci_foreach_element(&o->v.list, e) {
//lookup each list item
if (count == index) {
list_o = uci_to_option(e);
str = list_o->e.name;
return str;
}
count++;
}
} else {
return NULL;
}
// not find the list with specific index
return NULL;
}
int uci_set_list(struct uci_context *ctx, char *package_name, char *section_type, char *section_name, char *list_name,
char *list_value)
{
struct uci_section *s = NULL;
struct uci_package *p = NULL;
struct uci_ptr ptr;
if (!ctx || !package_name || !section_type || !section_name || !list_name) {
return UCI_ERR_INVAL;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)
|| !uci_validate_name(list_name, true)) {
return UCI_ERR_INVAL;
}
p = get_uci_package(ctx, package_name, true);
if (!p) {
return UCI_ERR_INVAL;
}
s = get_uci_section(ctx, package_name, section_type, section_name, false);
if (!s) {
return UCI_ERR_INVAL;
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.package = package_name;
ptr.s = s;
ptr.section = section_name;
ptr.option = list_name;
ptr.value = list_value;
return uci_add_list(ctx, &ptr);
}
int uci_delete_list(struct uci_context *ctx, char *package_name, char *section_type, char *section_name,
char *list_name, char *list_value)
{
struct uci_section *s = NULL;
struct uci_package *p = NULL;
struct uci_ptr ptr;
if (!ctx || !package_name || !section_type || !section_name || !list_name) {
return UCI_ERR_INVAL;
}
if (!uci_validate_name(package_name, false) || !uci_validate_name(section_name, true)
|| !uci_validate_name(list_name, true)) {
return UCI_ERR_INVAL;
}
p = get_uci_package(ctx, package_name, true);
if (!p) {
return UCI_ERR_INVAL;
}
s = get_uci_section(ctx, package_name, section_type, section_name, false);
if (!s) {
return UCI_ERR_INVAL;
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.package = package_name;
ptr.s = s;
ptr.section = section_name;
ptr.option = list_name;
ptr.value = list_value;
return uci_del_list(ctx, &ptr);
}
int uci_delete_package(struct uci_context *ctx, char *package_name)
{
UNUSED(ctx);
char path[MAX_STR_LEN] = { 0 };
if (!package_name) {
return UCI_ERR_INVAL;
}
if (!uci_validate_name(package_name, false)) {
return UCI_ERR_INVAL;
}
snprintf(path, MAX_STR_LEN - 1, "/etc/config/%s", package_name);
if (remove(path)) {
return UCI_ERR_INVAL;
}
free_uci_profile_ctx();
return UCI_OK;
}
int fill_uci_apn(char *package_name, Mnc_Apn * uci_apn)
{
struct uci_context *ctx = NULL;
struct uci_package *p = NULL;
struct uci_section *s = NULL;
struct uci_element *e = NULL;
char *str = NULL;
int i;
int index = -1;
Apn_Info *apn_info = NULL;
int ret = CM_OK;
if (!uci_apn) {
ret = UCI_ERR_MEM;
goto END;
}
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = UCI_ERR_INVAL;
goto END;
}
p = get_uci_package(ctx, package_name, false);
if (!p) {
ret = UCI_ERR_INVAL;
goto END;
}
uci_foreach_element(&p->sections, e) {
s = uci_to_section(e);
if (strcmp(s->type, PDP_CONF_TYPE_STR)) {
continue;
}
index = -1;
str = (char *)uci_lookup_option_string(ctx, s, APN_TYPE_STR);
if (str) {
for (i = 0; i < MAX_APN_NUM; i++) {
apn_info = &(uci_apn->apn_info_list[i]);
if (!strcmp(s->e.name, str))
{
if (!strlen(apn_info->type)) {
strncpy(apn_info->type, str, MAX_STR_LEN - 1);
apn_info->basic_set = 1;
index = i;
break;
} else {
if (!strcmp(str, apn_info->type)) {
index = i;
break;
}
}
}
}
} else {
goto END;
}
if (index < 0)
{
goto END;
}
str = (char *)uci_lookup_option_string(ctx, s, CONN_NUM_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->connection_num = atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, AUTO_APN_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->auto_apn = atoi(str);
}
if (apn_info->auto_apn)
{
str = (char *)uci_lookup_option_string(ctx, s, AUTO_APN_IPTYPE_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->autoapn_iptype = atoi(str);
apn_info->autoapn_iptype_present = true;
}
}
str = (char *)uci_lookup_option_string(ctx, s, CONN_MODE_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->Extra_params.autoconnect = (bool) atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, LTE_DEFAULT_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->Extra_params.lte_default = (bool) atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, DATA_ON_ROAMING_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->Extra_params.data_on_roaming = (bool) atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, ALWAYS_ON_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->Extra_params.always_on = (bool) atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, PDP_NAME_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->carrier, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, ENABLE_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->enable = atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, IP_TYPE_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->iptype = (unsigned char)atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, APN_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->apn, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, LTE_APN_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->lte_apn, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, USR_2G3G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->usrname, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, PSWD_2G3G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->paswd, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, AUTHTYPE_2G3G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->authtype, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, USR_4G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->lte_usrname, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, PSWD_4G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->lte_paswd, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, AUTHTYPE_4G_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
strncpy(apn_info->lte_authtype, str, MAX_STR_LEN - 1);
}
str = (char *)uci_lookup_option_string(ctx, s, NET_MTU_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->mtu = atoi(str);
}
str = (char *)uci_lookup_option_string(ctx, s, APN_CLASS);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->apn_class = atoi(str);
}
#ifdef CONFIG_ZGDCONT_MULTI_PDP
if (!strcmp(apn_info->type, "default") && apn_info->connection_num == 0)
apn_info->cid = CM_DEFAULT_ATTACH_CID;
#endif
str = (char *)uci_lookup_option_string(ctx, s, CONFIG_BY_STR);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->config_by = atoi(str);
if (atoi(str) == 1)
apn_info->cid = CM_DEFAULT_ATTACH_CID;
}
if (0 == apn_info->connection_num)
apn_info->connection_num = CM_DEFAULT_ATTACH_CID;
str = (char *)uci_lookup_option_string(ctx, s, DATA_BLOCK);
if (str) {
apn_info = &(uci_apn->apn_info_list[index]);
apn_info->data_block = atoi(str);
}
CM_Log(fill_uci_apn719, "fill_uci_apn: section name %s, type %s, auto apn %d, enable %d, connect mode %d, apn %s, cid %d connection_num %d\n",
s->e.name, apn_info->type, apn_info->auto_apn, apn_info->enable, apn_info->Extra_params.autoconnect, apn_info->apn, apn_info->cid, apn_info->connection_num);
}
END:
return ret;
}
void update_apn_info_connnum(Apn_Info *apn_info)
{
int i = 0;
for (i = 0; i < TYPE_CONNNUM_PAIR_NUM; i++) {
if (!strcmp(apn_info->type, type_connNum[i].apn_type)) {
apn_info->connection_num = type_connNum[i].connection_num;
break;
}
}
return;
}
static void update_apn_info_iptype(Apn_Info *apn_info)
{
if (strlen(apn_info->protocol)) {
if (!strcasecmp(apn_info->protocol, "IPV4V6"))
apn_info->iptype = 0;
else if (!strcasecmp(apn_info->protocol, "IPV4"))
apn_info->iptype = 1;
else if (!strcasecmp(apn_info->protocol, "IPV6"))
apn_info->iptype = 2;
else
apn_info->iptype = 1;
}
else
apn_info->iptype = 1;
return;
}
void update_apn_info_iptype_int(Apn_Info *apn_info, char *type)
{
if (!strcasecmp(type, "IPV4V6"))
apn_info->iptype = 0;
else if (!strcasecmp(type, "IPV4"))
apn_info->iptype = 1;
else if (!strcasecmp(type, "IPV6"))
apn_info->iptype = 2;
else
apn_info->iptype = 1;
return;
}
void update_apn_info_authtype_str(Apn_Info *apn_info, int type)
{
memset(apn_info->authtype, 0 , MAX_STR_LEN);
switch (type)
{
case 0:
strcpy(apn_info->authtype, "NONE");
strcpy(apn_info->lte_authtype, "NONE");
break;
case 1:
strcpy(apn_info->authtype, "PAP");
strcpy(apn_info->lte_authtype, "PAP");
break;
case 2:
strcpy(apn_info->authtype, "CHAP");
strcpy(apn_info->lte_authtype, "CHAP");
break;
default:
strcpy(apn_info->authtype, "NONE");
strcpy(apn_info->lte_authtype, "NONE");
break;
}
return;
}
int convert_authtype_by_str(char *auth_type)
{
int auth;
if (strlen(auth_type) == 0)
auth = 0;
else if (strcasecmp(auth_type, "NONE") == 0)
auth = 0;
else if (strcasecmp(auth_type, "PAP") == 0)
auth = 1;
else if (strcasecmp(auth_type, "CHAP") == 0)
auth = 2;
else
auth = 0;
return auth;
}
static int _update_work_apn(Mnc_Apn * uci_apn, Mnc_Apn * auto_apn, Mnc_Apn * work_apn)
{
#define TMP_BUF_SIZE 128
int i = 0, j = 0;
Apn_Info *uci_apn_info = NULL;
Apn_Info *auto_apn_info = NULL;
Apn_Info *work_apn_info = NULL;
char *p = NULL, *q = NULL;
char tmp_str[TMP_BUF_SIZE] = { 0 };
int len = 0;
int ret = CM_ERR_UNKNOWN;
if ((!uci_apn && !auto_apn) || !work_apn) {
return UCI_ERR_INVAL;
}
memset(work_apn, 0, sizeof(Mnc_Apn));
if (!auto_apn) {
CM_Log(_update_work_apn820, "_update_work_apn: no auto apn info, copy uci apn to work apn");
for (i = 0; i < MAX_APN_NUM; i++) {
uci_apn_info = &(uci_apn->apn_info_list[i]);
/* find a valid uci entry*/
if (!strlen(uci_apn_info->type))
continue;
for (j = 0; j < MAX_APN_NUM; j++) {
work_apn_info = &(work_apn->apn_info_list[j]);
/*find a empty entry*/
if (!strlen(work_apn_info->type) && !uci_apn_info->auto_apn ) {
memcpy(work_apn_info, uci_apn_info, sizeof(Apn_Info));
ret = CM_OK;
break;
}
}
}
goto end;
}
//fill auto apn list into work apn list, splilt different type to different PDP
//example:type=default,ims,mms will split to 3 different Apn_Info structs
//type= default, type = ims, type = mms
//set all auto_apn option to 1
//set connetion num according to type.
for (i = 0; i < MAX_APN_NUM; i++) {
auto_apn_info = &(auto_apn->apn_info_list[i]);
if (!strlen(auto_apn_info->type))
continue;
strncpy(tmp_str, auto_apn_info->type, TMP_BUF_SIZE - 1);
p = tmp_str;
// split different apn type into differnent Apn_Info struct
do {
//coverity[string_null:SUPPRESS]
q = strstr(p, ",");
if (q) {
len = q - p;
} else {
len = strlen(p);
}
//find empty Apn_Info, then fill it
for (j = 0; j < MAX_APN_NUM; j++) {
work_apn_info = &(work_apn->apn_info_list[j]);
if (strlen(work_apn_info->type))
continue;
if (len > MAX_APN_NUM - 1) {
CM_Log_E(_update_work_apn, "_update_work_apn: [should not be here] apn type len %d exceed max size",
len);
break;
}
memcpy(work_apn_info, auto_apn_info, sizeof(Apn_Info));
memcpy(work_apn_info->type, p, len);
work_apn_info->type[len] = '\0';
strcpy(work_apn_info->pdp_name, work_apn_info->type);
//set auto_apn, connection_num here
work_apn_info->auto_apn = 1;
update_apn_info_connnum(work_apn_info);
CM_Log(_update_work_apn1, "_update_work_apn: index %d, type %s, connection_num %d, protocol %s, apn %s", j,
work_apn_info->type, work_apn_info->connection_num, work_apn_info->protocol, work_apn_info->apn);
// set ip_type here according to protocol
update_apn_info_iptype(work_apn_info);
/*set mtu from extra to Apn_Info*/
if (auto_apn_info->extra_set)
work_apn_info->mtu = auto_apn_info->Extra_params.mtu;
break;
}
if (j == MAX_APN_NUM) {
CM_Log_E(_update_work_apn2, "_update_work_apn: work apn lis is full");
break;
}
if (q)
p = q + 1;
} while (q);
}
//merge uci apn list into work apn list
for (i = 0; i < MAX_APN_NUM; i++) {
uci_apn_info = &(uci_apn->apn_info_list[i]);
if (!strlen(uci_apn_info->type))
continue;
CM_Log(_update_work_apn3, "_update_work_apn: uci apn type %s, auto apn %d", uci_apn_info->type, uci_apn_info->auto_apn);
for (j = 0; j < MAX_APN_NUM; j++) {
work_apn_info = &(work_apn->apn_info_list[j]);
if (!strlen(work_apn_info->type))
continue;
if (!strstr(work_apn_info->type, uci_apn_info->type))
continue;
if (uci_apn_info->auto_apn) {
if (uci_apn_info->enable) {
// set enable option
work_apn_info->enable = 1;
}
/*copy apn_class here*/
work_apn_info->apn_class = uci_apn_info->apn_class;
/*update autoapn iptype here*/
if (uci_apn_info->autoapn_iptype_present)
{
work_apn_info->autoapn_iptype_present = uci_apn_info->autoapn_iptype_present;
work_apn_info->autoapn_iptype = uci_apn_info->autoapn_iptype;
work_apn_info->iptype = uci_apn_info->autoapn_iptype;
CM_Log(_update_work_apn4, "_update_work_apn: auto apn iptype %d", work_apn_info->autoapn_iptype);
}
/* updata datablock according to uci */
work_apn_info->data_block = uci_apn_info->data_block;
continue;
}
// non auto_apn, merge the UCI apn to work apn
memcpy(work_apn_info, uci_apn_info, sizeof(Apn_Info));
break;
}
if (j == MAX_APN_NUM) {
//insert the uci apn type into work apn list
for (j = 0; j < MAX_APN_NUM; j++) {
work_apn_info = &(work_apn->apn_info_list[j]);
if (!strlen(work_apn_info->type) && !uci_apn_info->auto_apn) {
CM_Log(_update_work_apn4, "_update_work_apn: insert non auto apn uci Apn_Info into empty Apn_Info", j);
// empty Apn_Info, insert
memcpy(work_apn_info, uci_apn_info, sizeof(Apn_Info));
break;
}
}
}
}
ret = CM_OK;
end:
return ret;
}
int update_work_apn(Mnc_Apn * auto_apn_list)
{
int ret = CM_OK;
Mnc_Apn *uci_apn = NULL;
char package_name[MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
char *str = NULL;
uci_apn = malloc(sizeof(Mnc_Apn));
if (!uci_apn) {
ret = CM_ERR_MEM;
goto END;
}
memset(uci_apn, 0, sizeof(Mnc_Apn));
if (!g_work_apn) {
g_work_apn = malloc(sizeof(Mnc_Apn));
if (!g_work_apn) {
ret = CM_ERR_MEM;
goto END;
}
}
snprintf(package_name, MAX_STR_LEN - 1, "wan");
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_MEM;
goto END;
}
str = uci_get_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, ACTIVE_PROFILE_STR);
if (!str) {
snprintf(package_name, MAX_STR_LEN - 1, "wan_default");
#if 0
ret = CM_ERR_MEM;
goto END;
#endif
}
else {
snprintf(package_name, MAX_STR_LEN - 1, "wan_%s", str);
}
ret = fill_uci_apn(package_name, uci_apn);
if (ret != CM_OK) {
goto END;
}
ret = _update_work_apn(uci_apn, auto_apn_list, g_work_apn);
if (ret != CM_OK) {
goto END;
}
END:
if (uci_apn)
free(uci_apn);
free_uci_profile_ctx();
return ret;
}
int connection_handler(Mnc_Apn * work_apn)
{
int i;
Apn_Info *apn_info = NULL;
int ret_val = UBUS_STATUS_OK;
if (!work_apn) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
for (i = 0; i < MAX_APN_NUM; i++) {
apn_info = &(work_apn->apn_info_list[i]);
if (strcmp(apn_info->type, "default") == 0) {
if (apn_info->enable) {
//create_pdp
ret_val = create_connection();
} else {
//destroy_pdp
ret_val = destroy_connection(apn_info->connection_num, 0);
}
break;
} else if (strlen(apn_info->type)) {
if (strstr(apn_info->type, "ims")) {
//configure APN to IMSD
}
}
}
EXIT:
CM_Log(connection_handler, "connection_handler: leave\n");
return ret_val;
}
int update_actived_profile(s_profile_param * info, int flag)
{
char *str = NULL;
int ret = CM_OK;
char package_name[MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int profile_count, index;
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, MAX_STR_LEN - 1, "wan");
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_MEM;
goto END;
}
str = uci_get_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, ACTIVE_PROFILE_STR);
if (!str) {
ret = CM_ERR_INVAL;
goto END;
}
if (flag == DELETE_PROFILE) {
if (!strcmp(str, info->profile_name)) {
//update actived profile to "default"
ret =
uci_set_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR,
ACTIVE_PROFILE_STR, "default");
if (ret != CM_OK) {
goto END;
}
}
//delete it from list profile_names
ret =
uci_delete_list(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR,
PROFILE_LIST_STR, info->profile_name);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
} else if(flag == ADD_PROFILE) {
if (strcmp(str, info->profile_name)) {
//update actived profile
ret =
uci_set_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR,
ACTIVE_PROFILE_STR, info->profile_name);
if (ret != CM_OK) {
goto END;
}
}
//add it into list profile_names
ret =
uci_set_list(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, PROFILE_LIST_STR,
info->profile_name);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
} else {
if (strcmp(str, info->profile_name)) {
//update actived profile
ret =
uci_set_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR,
ACTIVE_PROFILE_STR, info->profile_name);
if (ret != CM_OK) {
goto END;
}
profile_count = uci_get_list_number(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, PROFILE_LIST_STR);
for (index = 0; index < profile_count; index++) {
str = uci_get_list_value(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, PROFILE_LIST_STR, index);
if (str) {
if (strcmp(str, info->profile_name) == 0)
break;
}
}
if (index == profile_count)
{
/* the switch profile not in list, add the switch profile name into list */
uci_set_list(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, PROFILE_LIST_STR,
info->profile_name);
}
uci_commit_package(ctx, package_name);
}
}
END:
return ret;
}
int is_actived_profile(s_profile_param * info)
{
char *str = NULL;
char package_name[MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
if (!info) {
return false;
}
snprintf(package_name, MAX_STR_LEN - 1, "wan");
ctx = get_uci_profile_ctx();
if (!ctx) {
return false;
}
str = uci_get_option(ctx, package_name, PROFILE_CONFIG_TYPE_STR, PROFILE_CONFIG_NAME_STR, ACTIVE_PROFILE_STR);
if (str) {
if (!strcmp(str, info->profile_name)) {
return true;
}
}
return false;
}
int add_profile(s_profile_param * info)
{
int ret = CM_OK;
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
struct uci_package *p = NULL;
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", info->profile_name);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
p = new_uci_package(ctx, package_name);
if (!p) {
ret = CM_ERR_UNKNOWN;
goto END;
}
ret = update_actived_profile(info, ADD_PROFILE);
if (ret != CM_OK) {
goto END;
}
END:
return ret;
}
int delete_profile(s_profile_param * info)
{
int ret = CM_OK;
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", info->profile_name);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
if (!is_actived_profile(info)) {
ret = uci_delete_package(ctx, package_name);
if (ret != CM_OK) {
CM_Log_E(delete_profile3, "delete_profile: delete package failed %d\n", ret);
}
goto END;
}
ret = update_actived_profile(info, DELETE_PROFILE);
if (ret != CM_OK) {
CM_Log_E(delete_profile4, "delete_profile: update_actived_profile failed %d\n", ret);
goto END;
}
ret = uci_delete_package(ctx, package_name);
if (ret != CM_OK) {
CM_Log_E(delete_profile5, "delete_profile: delete package failed %d\n", ret);
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
CM_Log_E(delete_profile6, "delete_profile: update work apn failed %d\n", ret);
goto END;
}
ret = connection_handler(g_work_apn);
if (ret != CM_OK) {
CM_Log_E(delete_profile7, "delete_profile: connection_handler failed %d\n", ret);
goto END;
}
END:
return ret;
}
int switch_profile(s_profile_param * info)
{
int ret = CM_OK;
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
ret = update_actived_profile(info, SWITCH_PROFILE);
if (ret != CM_OK) {
CM_Log_E(switch_profile1, "switch_profile: update_actived_profile failed %d\n", ret);
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
CM_Log_E(switch_profile2, "switch_profile: update work apn failed %d\n", ret);
goto END;
}
ret = connection_handler(g_work_apn);
if (ret != CM_OK) {
CM_Log_E(switch_profile3, "switch_profile: connection_handler failed %d\n", ret);
goto END;
}
END:
return ret;
}
int update_pdp_to_uci(struct blob_attr *msg, s_profile_param * info)
{
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int ret;
Apn_Info apn_info;
char tmp_buf[MAX_STR_LEN] = { 0 };
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(info->profile_name)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", info->profile_name);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
memset(&apn_info, 0, sizeof(Apn_Info));
ret = pdp_info_parse(msg, &apn_info);
if (ret != CM_OK) {
ret = CM_ERR_PARSE;
goto END;
}
if (!strlen(apn_info.type)) {
ret = CM_ERR_INVAL;
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.connection_num);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, CONN_NUM_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, APN_TYPE_STR, apn_info.type);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.auto_apn);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, AUTO_APN_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.Extra_params.autoconnect);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, CONN_MODE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.Extra_params.lte_default);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, LTE_DEFAULT_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.Extra_params.data_on_roaming);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, DATA_ON_ROAMING_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.enable);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, ENABLE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.iptype);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, IP_TYPE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info.mtu);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, NET_MTU_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, APN_STR, apn_info.apn);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, LTE_APN_STR, apn_info.lte_apn);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, USR_2G3G_STR, apn_info.usrname);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, PSWD_2G3G_STR, apn_info.paswd);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, AUTHTYPE_2G3G_STR, apn_info.authtype);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, USR_4G_STR, apn_info.lte_usrname);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, PSWD_4G_STR, apn_info.lte_paswd);
if (ret != CM_OK) {
goto END;
}
ret =
uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, apn_info.type, AUTHTYPE_4G_STR, apn_info.lte_authtype);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
END:
return ret;
}
static int delete_pdp_from_uci(s_profile_param * info)
{
int ret = CM_OK;
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
if (!info) {
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(info->profile_name)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", info->profile_name);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_MEM;
goto END;
}
if (!strlen(info->type)) {
ret = CM_ERR_INVAL;
goto END;
}
ret = uci_delete_section(ctx, package_name, info->type);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
END:
return ret;
}
int add_pdp(struct blob_attr *msg, s_profile_param * info)
{
int ret = CM_OK;
ret = update_pdp_to_uci(msg, info);
if (ret != CM_OK) {
CM_Log_E(add_pdp, "add_pdp: add_pdp_to_uci failed %d\n", ret);
goto END;
}
if (!is_actived_profile(info)) {
CM_Log_E(add_pdp1, "add_pdp: not actived profiled\n");
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
CM_Log_E(add_pdp2, "add_pdp: update work apn failed %d\n", ret);
goto END;
}
ret = connection_handler(g_work_apn);
if (ret != CM_OK) {
CM_Log_E(add_pdp3, "add_pdp: connection_handler failed %d\n", ret);
goto END;
}
END:
return ret;
}
int delete_pdp(s_profile_param * info)
{
int ret = CM_OK;
ret = delete_pdp_from_uci(info);
if (ret != CM_OK) {
CM_Log_E(delete_pdp, "delete_pdp: delete_pdp_from_uci failed %d\n", ret);
goto END;
}
if (!is_actived_profile(info)) {
CM_Log_E(delete_pdp1, "delete_pdp: not actived profiled\n");
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
CM_Log_E(delete_pdp2, "delete_pdp: update work apn failed %d\n", ret);
goto END;
}
ret = connection_handler(g_work_apn);
if (ret != CM_OK) {
CM_Log_E(delete_pdp3, "delete_pdp: connection_handler failed %d\n", ret);
goto END;
}
END:
return ret;
}
int get_auto_apn_info_by_type(char *type, Apn_Info *info, int *apn_num)
{
int i, num = 0;
Apn_Info *apn_info = NULL;
int ret = CM_OK;
Mnc_Apn *mnc_apn = NULL;
if (!info || !type) {
ret = CM_ERR_INVAL;
goto END;
}
mnc_apn = get_mnc_apn_info();
if (!mnc_apn)
{
ret = CM_ERR_INVAL;
goto END;
}
for (i = 0; i < MAX_APN_NUM; i++) {
apn_info = &(mnc_apn->apn_info_list[i]);
if (strlen(apn_info->type)) {
if (strstr(apn_info->type, type)) {
memcpy(&info[num], apn_info, sizeof(Apn_Info));
num++;
}
}
}
if (num == 0) {
ret = CM_ERR_INVAL;
goto END;
}
END:
CM_Log(get_auto_apn_info_by_type4, "get_auto_apn_info_by_type: apn num %d \n", num);
*apn_num = num;
return ret;
}
int get_apn_info_by_type(char *type, Apn_Info * info)
{
int i;
Apn_Info *apn_info = NULL;
int ret = CM_OK;
if (!info || !type || !g_work_apn) {
ret = CM_ERR_INVAL;
goto END;
}
for (i = 0; i < MAX_APN_NUM; i++) {
apn_info = &(g_work_apn->apn_info_list[i]);
if (strlen(apn_info->type)) {
if (strstr(apn_info->type, type)) {
memcpy(info, apn_info, sizeof(Apn_Info));
break;
}
}
}
if (i == MAX_APN_NUM) {
ret = CM_ERR_INVAL;
goto END;
}
END:
return ret;
}
int edit_pdp(struct blob_attr *msg, s_profile_param * info)
{
int ret = CM_OK;
ret = update_pdp_to_uci(msg, info);
if (ret != CM_OK) {
CM_Log_E(edit_pdp, "edit_pdp: delete_pdp_from_uci failed %d\n", ret);
goto END;
}
if (!is_actived_profile(info)) {
CM_Log_E(edit_pdp1, "edit_pdp: not actived profiled\n");
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
CM_Log_E(edit_pdp2, "edit_pdp: update work apn failed %d\n", ret);
goto END;
}
ret = connection_handler(g_work_apn);
if (ret != CM_OK) {
CM_Log_E(edit_pdp4, "edit_pdp: connection_handler failed %d\n", ret);
goto END;
}
END:
return ret;
}
int add_pdp_info_into_uci(Apn_Info *apn_info)
{
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int ret = CM_OK;
char tmp_buf[MAX_STR_LEN] = { 0 };
char section_name[2*MAX_STR_LEN] = { 0 };
if (!apn_info) {
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(apn_info->type)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", apn_info->type);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
memset(section_name, 0, sizeof(section_name));
if (apn_info->cid == 1)
snprintf(section_name, sizeof(section_name) - 1, "%s", apn_info->type);
else
snprintf(section_name, sizeof(section_name) - 1, "%s%d", apn_info->type, apn_info->cid);
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf) - 1, "%d", apn_info->connection_num);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONN_NUM_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, APN_TYPE_STR, apn_info->type);
if (ret != CM_OK) {
goto END;
}
/* should not save auto_apn here */
#if 0
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->auto_apn);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTO_APN_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_info_into_default_uci6, "add_pdp_info_into_default_uci: set option %s value %s failed\n", AUTO_APN_STR, tmp_buf);
goto END;
}
#endif
/* configured by zgdcont */
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "1");
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONFIG_BY_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
#if 0
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->Extra_params.autoconnect);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONN_MODE_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_info_into_default_uci7, "add_pdp_info_into_default_uci: set option %s value %s failed\n", CONN_MODE_STR, tmp_buf);
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->Extra_params.lte_default);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, LTE_DEFAULT_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_info_into_default_uci8, "add_pdp_info_into_default_uci: set option %s value %s failed\n", LTE_DEFAULT_STR, tmp_buf);
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->Extra_params.data_on_roaming);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, DATA_ON_ROAMING_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_info_into_default_uci9, "add_pdp_info_into_default_uci: set option %s value %s failed\n", DATA_ON_ROAMING_STR, tmp_buf);
goto END;
}
#endif
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->enable);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, ENABLE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->iptype);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, IP_TYPE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
#if 0
memset(tmp_buf, 0, MAX_STR_LEN);
snprintf(tmp_buf, MAX_STR_LEN - 1, "%d", apn_info->mtu);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, NET_MTU_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_info_into_default_uci12, "add_pdp_info_into_default_uci: set option %s value %s failed\n", NET_MTU_STR, tmp_buf);
goto END;
}
#endif
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, APN_STR, apn_info->apn);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, LTE_APN_STR, apn_info->lte_apn);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
END:
return ret;
}
int add_pdp_ext_info_into_uci(Apn_Info *apn_info)
{
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int ret = CM_OK;
char tmp_buf[MAX_STR_LEN] = { 0 };
char section_name[2*MAX_STR_LEN] = { 0 };
if (!apn_info) {
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(apn_info->type)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", apn_info->type);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
memset(section_name, 0, sizeof(section_name));
if (apn_info->cid == 1)
snprintf(section_name, sizeof(section_name) - 1, "%s", apn_info->type);
else
snprintf(section_name, sizeof(section_name) - 1, "%s%d", apn_info->type, apn_info->cid);
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf) - 1, "%d", apn_info->Extra_params.autoconnect);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONN_MODE_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf) - 1, "%d", apn_info->Extra_params.always_on);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, ALWAYS_ON_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf) - 1, "%d", apn_info->Extra_params.data_on_roaming);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, DATA_ON_ROAMING_STR, tmp_buf);
if (ret != CM_OK) {
goto END;
}
#if 0
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf) - 1, "%d", apn_info->mtu);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, NET_MTU_STR, tmp_buf);
if (ret != CM_OK) {
CM_Log_E(add_pdp_ext_info_into_uci7, "add_pdp_ext_info_into_uci: set option %s value %s failed\n", NET_MTU_STR, tmp_buf);
goto END;
}
#endif
uci_commit_package(ctx, package_name);
END:
return ret;
}
int add_pdp_auth_info_into_uci(Apn_Info *apn_info)
{
char package_name[2*MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int ret = CM_OK;
char section_name[2*MAX_STR_LEN] = { 0 };
if (!apn_info) {
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(apn_info->type)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(package_name) - 1, "wan_%s", apn_info->type);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
memset(section_name, 0, sizeof(section_name));
if (apn_info->cid == 1)
snprintf(section_name, sizeof(section_name) - 1, "%s", apn_info->type);
else
snprintf(section_name, sizeof(section_name) - 1, "%s%d", apn_info->type, apn_info->cid);
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, USR_2G3G_STR, apn_info->usrname);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, PSWD_2G3G_STR, apn_info->paswd);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTHTYPE_2G3G_STR, apn_info->authtype);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, USR_4G_STR, apn_info->lte_usrname);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, PSWD_4G_STR, apn_info->lte_paswd);
if (ret != CM_OK) {
goto END;
}
ret = uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTHTYPE_4G_STR, apn_info->lte_authtype);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
END:
return ret;
}
int delete_pdp_info_from_uci(Apn_Info *apn_info)
{
int ret = CM_OK;
struct uci_context *ctx = NULL;
char package_name[2*MAX_STR_LEN] = { 0 };
char section_name[2*MAX_STR_LEN] = {0};
if (!apn_info) {
ret = CM_ERR_INVAL;
goto END;
}
if (apn_info->cid <= 1)
{
ret = CM_ERR_INVAL;
goto END;
}
if (!strlen(apn_info->type)) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, sizeof(section_name) - 1, "wan_%s", apn_info->type);
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_MEM;
goto END;
}
snprintf(section_name, sizeof(section_name) - 1, "%s%d", apn_info->type, apn_info->cid);
ret = uci_delete_section(ctx, package_name, section_name);
if (ret != CM_OK) {
goto END;
}
uci_commit_package(ctx, package_name);
END:
return ret;
}
int load_pdp_info_from_uci(Apn_Info *apn_info, int cid)
{
char package_name[MAX_STR_LEN] = { 0 };
struct uci_context *ctx = NULL;
int ret = CM_OK;
char section_name[MAX_STR_LEN] = { 0 };
char *option_value = NULL;
if (!apn_info) {
ret = CM_ERR_INVAL;
goto END;
}
snprintf(package_name, MAX_STR_LEN - 1, "wan_default");
ctx = get_uci_profile_ctx();
if (!ctx) {
ret = CM_ERR_UNKNOWN;
goto END;
}
memset(section_name, 0, sizeof(section_name));
if (cid == 1)
snprintf(section_name, sizeof(section_name) - 1, "default");
else
snprintf(section_name, sizeof(section_name) - 1, "default%d", cid);
if (get_uci_section(ctx, package_name, PDP_CONF_TYPE_STR, section_name, false) == NULL)
{
ret = CM_ERR_INVAL;
return ret;
}
/* always set cid==1 config by zgdcont */
if (cid == 1)
{
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONFIG_BY_STR);
if (option_value == NULL ||atoi(option_value) != 1 )
{
uci_set_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONFIG_BY_STR, "1");
}
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONFIG_BY_STR);
if (cid != 1 && (option_value == NULL ||atoi(option_value) != 1 )) {
CM_Log(load_pdp_info_from_uci4, "load_pdp_info_from_uci: section %s, config not by zgdcont\n", section_name);
ret = CM_ERR_INVAL;
return ret;
}
strcpy(apn_info->type, "default");
apn_info->cid = cid;
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONN_NUM_STR);
if (option_value != NULL) {
apn_info->connection_num = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, APN_TYPE_STR);
if (option_value != NULL) {
strncpy(apn_info->type, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTO_APN_STR);
if (option_value != NULL) {
apn_info->auto_apn = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, CONN_MODE_STR);
if (option_value != NULL) {
apn_info->Extra_params.autoconnect = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, LTE_DEFAULT_STR);
if (option_value != NULL) {
apn_info->Extra_params.lte_default = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, DATA_ON_ROAMING_STR);
if (option_value != NULL) {
apn_info->Extra_params.data_on_roaming = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, ALWAYS_ON_STR);
if (option_value != NULL) {
apn_info->Extra_params.always_on = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, ENABLE_STR);
if (option_value != NULL) {
apn_info->enable = atoi(option_value);
}
else
apn_info->enable = 1;
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, IP_TYPE_STR);
if (option_value != NULL) {
apn_info->iptype = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, NET_MTU_STR);
if (option_value != NULL) {
apn_info->mtu = atoi(option_value);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, APN_STR);
if (option_value != NULL) {
strncpy(apn_info->apn, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, LTE_APN_STR);
if (option_value != NULL) {
strncpy(apn_info->lte_apn, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, USR_2G3G_STR);
if (option_value != NULL) {
strncpy(apn_info->usrname, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, PSWD_2G3G_STR);
if (option_value != NULL) {
strncpy(apn_info->paswd, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTHTYPE_2G3G_STR);
if (option_value != NULL) {
strncpy(apn_info->authtype, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, USR_4G_STR);
if (option_value != NULL) {
strncpy(apn_info->lte_usrname, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, PSWD_4G_STR);
if (option_value != NULL) {
strncpy(apn_info->lte_paswd, option_value, MAX_STR_LEN - 1);
}
option_value = uci_get_option(ctx, package_name, PDP_CONF_TYPE_STR, section_name, AUTHTYPE_4G_STR);
if (option_value != NULL) {
strncpy(apn_info->lte_authtype, option_value, MAX_STR_LEN - 1);
}
CM_Log(load_pdp_info_from_uci21,"load_pdp_info_from_uci: [%s = %d] [%s = %d] [%s = %d] [%s = %d] [%s = %d] [%s = %s] [%s = %s] [%s = %d] [%s = %d]", \
ENABLE_STR, apn_info->enable, AUTO_APN_STR, apn_info->auto_apn, CONN_MODE_STR, apn_info->Extra_params.autoconnect,LTE_DEFAULT_STR, apn_info->Extra_params.lte_default, \
ALWAYS_ON_STR, apn_info->Extra_params.always_on, APN_STR, strlen(apn_info->apn) ? apn_info->apn : "NULL", LTE_APN_STR, strlen(apn_info->lte_apn) ? apn_info->lte_apn: "NULL", \
IP_TYPE_STR, apn_info->iptype, NET_MTU_STR, apn_info->mtu );
END:
return ret;
}
int set_dial_switch_to_cellular()
{
int ret = CM_OK;
struct uci_context *local_ctx = NULL;
local_ctx = (struct uci_context *)uci_wan_ctx_get();
if (!local_ctx) {
ret = CM_ERR_MEM;
return ret;
}
ret = uci_set_option(local_ctx, WAN_PACKAGE_NAME, SEC_CONNECT_SWITCH_T, SEC_CONNECT_SWITCH_N, OPT_DIAL_SWITCH,
"cellular");
ret = uci_commit_package(local_ctx, WAN_PACKAGE_NAME);
if (ret != UCI_OK) {
CM_Log_E(set_dial_switch_to_cellular2, "set_dial_switch_to_cellular: uci_commit_package failed %d\n", ret);
}
return ret;
}
int update_vzw_work_apn()
{
int ret = CM_OK;
s_profile_param vzw_profile_param = {"vzw", SWITCH_PROFILE, 0, "default"};
ret = update_actived_profile(&vzw_profile_param, SWITCH_PROFILE);
if (ret != CM_OK) {
goto END;
}
ret = update_work_apn(IMSI_APN);
if (ret != CM_OK) {
goto END;
}
END:
return ret;
}
int get_apn_list_number(Mnc_Apn * work_apn)
{
int i, count = 0;
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 (strlen(apn_info->type))
count++;
}
CM_Log(get_apn_list_number2, "get_apn_list_number: leave, count %d\n", count);
return count;
}
static int get_kernel_cmdline(char *buf, int len)
{
static char cmdline[CMDLINE_LEN];
static int is_init = 0;
int ret = -1;
int fd;
if(!buf || len <= 0) return -1;
if(is_init)
goto INITED;
fd = open(PROC_CMDLINE, O_RDONLY);
if (fd < 0)
goto ERR_RET;
ret = read(fd, cmdline, CMDLINE_LEN);
close(fd);
if(ret <= 0 || ret > CMDLINE_LEN)
goto ERR_RET;
cmdline[ret - 1] = '\0';
INITED:
ret = strlen(cmdline) + 1;
if(ret > len)
ret = len;
strncpy(buf, cmdline, ret);
buf[ret - 1] = '\0';
is_init = 1;
return ret;
ERR_RET:
return -1;
}
/***
0: GETELCOM off
1: GETELCOM on
-1: Error
***/
int getGETELFlag(void)
{
char cmdline[CMDLINE_LEN];
char *pstr;
int ret = -1;
static int is_init = 0;
static int flag = 0;
if(is_init) return flag;
ret = get_kernel_cmdline(cmdline, CMDLINE_LEN);
if (ret < 0)
{
/* read error, goto err_ret */
goto ERR_RET;
}
ret = 0;
/* find the string "GEFL=" in cmdline*/
pstr = strstr(cmdline, GETELFLG_NAME);
if(pstr)
ret = 1;
else
ret = 0;
flag = ret;
is_init = 1;
ERR_RET:
return ret;
}