Эх сурвалжийг харах

add:自定义apn列表,用于多个已知海外卡切换,需要用户提供相关APN信息

alienwalker 1 жил өмнө
parent
commit
b9fec5e6d3

+ 43 - 0
components/mobile/luat_lib_mobile.c

@@ -1076,6 +1076,47 @@ static int l_mobile_vsim_onoff(lua_State* L) {
     }
     return 0;
 }
+/**
+初始化自定义APN列表,主要用于海外SIM卡
+@api mobile.apnTableInit()
+@return nil 无返回值
+@usage
+mobile.vsimInit()
+ */
+static int l_mobile_init_apn_table(lua_State* L) {
+	luat_mobile_init_auto_apn_by_plmn();
+    return 0;
+}
+/**
+往自定义APN列表添加一条APN信息,主要用于海外SIM卡
+@api mobile.apnTableAdd(mcc, mnc, ip_type, protocol, apn_name, user_name, password)
+@int MCC码,16进制BCD码
+@int MNC码,16进制BCD码
+@int 激活APN时的IP TYPE,1=IPV4 2=IPV6 3=IPV4V6,默认是1
+@int 激活APN时,如果需要username和password,就要写鉴权协议类型,1~3,默认3,代表1和2都尝试一下。不需要鉴权的写0
+@string APN name,不能为空
+@string APN的username
+@string APN的password
+@return nil 无返回值
+@usage
+mobile.apnTableAdd(0x460,00,3,0,"cmiot","","") -- 单独添加一条APN信息,移动公网卡设置APN为cmiot,一般不用设置
+
+ */
+static int l_mobile_add_apn_table(lua_State* L) {
+
+	size_t name_len = 0;
+	size_t user_len = 0;
+	size_t password_len = 0;
+	uint16_t mcc = luaL_optinteger(L, 1, 0x460);
+	uint16_t mnc = luaL_optinteger(L, 2, 0);
+	uint8_t ip_type = luaL_optinteger(L, 3, 3);
+	uint8_t protocol = luaL_optinteger(L, 4, 3);
+	const char* name = luaL_checklstring(L, 5, &name_len);
+	const char* user = luaL_optlstring(L, 6, "", &user_len);
+	const char* password = luaL_optlstring(L, 7, "", &password_len);
+	luat_mobile_add_auto_apn_item(mcc, mnc, ip_type, protocol, name, name_len, user, user_len, password, password_len, 1);
+    return 0;
+}
 
 #include "rotable2.h"
 static const rotable_Reg_t reg_mobile[] = {
@@ -1115,6 +1156,8 @@ static const rotable_Reg_t reg_mobile[] = {
 	{"syncTime",          ROREG_FUNC(l_mobile_sync_time)},
 	{"vsimInit",          ROREG_FUNC(l_mobile_init_vsim)},
 	{"vsimOnOff",          ROREG_FUNC(l_mobile_vsim_onoff)},
+	{"apnTableInit",          ROREG_FUNC(l_mobile_init_apn_table)},
+	{"apnTableAdd",          ROREG_FUNC(l_mobile_add_apn_table)},
 	//@const UNREGISTER number 未注册
     {"UNREGISTER",                  ROREG_INT(LUAT_MOBILE_STATUS_UNREGISTER)},
     //@const REGISTERED number 已注册

+ 35 - 0
components/mobile/luat_mobile.h

@@ -955,5 +955,40 @@ int luat_mobile_get_extern_service_cell_info(luat_mobile_scell_extern_info_t *in
 void luat_mobile_vsim_user_heartbeat_once(void);
 uint32_t luat_mobile_get_search_plmn(void);
 void luat_mobile_data_ip_mode(uint8_t on_off);
+
+void luat_mobile_init_auto_apn_by_plmn(void);
+void luat_mobile_init_auto_apn(void);
+typedef struct
+{
+	char  *data;	//包含apn name,user,password信息
+	uint8_t ip_type;
+	uint8_t protocol;
+	uint8_t name_len;
+	uint8_t user_len;
+	uint8_t password_len;
+}apn_info_t;
+/**
+ * 添加一条APN信息到全球APN列表,列表每次重启后都需要重建
+ * @param mcc
+ * @param mnc
+ * @param ip_type 激活的IP类型,以下参数参考luat_mobile_user_apn_auto_active
+ * @param protocol
+ * @param name
+ * @param name_len
+ * @param user
+ * @param user_len
+ * @param password
+ * @param password_len
+ * @param task_safe 是否做task安全保护,如果只输入一条写1,如果输入N条,可在开始和结束自行进行保护处理,这里写0
+ */
+void luat_mobile_add_auto_apn_item(uint16_t mcc, uint16_t mnc, uint8_t ip_type, uint8_t protocol, char *name, uint8_t name_len, char *user, uint8_t user_len, char *password, uint8_t password_len, uint8_t task_safe);
+/**
+ * 通过MCC,MNC查询APN信息
+ * @param mcc
+ * @param mnc
+ * @param apn APN信息
+ * @return =0找到匹配的信息,其他未找到
+ */
+int luat_mobile_find_apn_by_mcc_mnc(uint16_t mcc, uint16_t mnc, apn_info_t *apn);
 /** @}*/
 #endif

+ 125 - 1
components/mobile/luat_mobile_common.c

@@ -1,10 +1,134 @@
 #include "luat_base.h"
 #include "luat_mobile.h"
+#include "luat_rtos.h"
+#include "luat_fs.h"
+#if defined(LUAT_EC7XX_CSDK) || defined(CHIP_EC618) || defined(__AIR105_BSP__)
+#include "bsp_common.h"
+#endif
+#ifndef __BSP_COMMON_H__
+#include "c_common.h"
+#endif
 
+#define LUAT_LOG_TAG "mobile"
+#include "luat_log.h"
+
+typedef struct
+{
+	llist_head node;
+	PV_Union plmn;
+	uint8_t ip_type;
+	uint8_t protocol;
+	uint8_t name_len;
+	uint8_t user_len;
+	uint8_t password_len;
+	uint8_t unused[3];
+	char data[0];
+}apn_node_t;
+
+
+typedef struct
+{
+	llist_head dynamic_list;
+}auto_apn_ctrl_t;
+
+static auto_apn_ctrl_t luat_auto_apn;
+
+void luat_mobile_init_auto_apn_by_plmn(void)
+{
+	luat_mobile_init_auto_apn();
+	INIT_LLIST_HEAD(&luat_auto_apn.dynamic_list);
+}
+
+static int luat_mobile_find_apn(void *node, void *param)
+{
+	apn_node_t *apn = (apn_node_t *)node;
+	if (apn->plmn.p == param)
+	{
+		return LIST_FIND;
+	}
+	return LIST_PASS;
+}
+
+void luat_mobile_add_auto_apn_item(uint16_t mcc, uint16_t mnc, uint8_t ip_type, uint8_t protocol, char *name, uint8_t name_len, char *user, uint8_t user_len, char *password, uint8_t password_len, uint8_t task_safe)
+{
+	apn_node_t *apn;
+	if (task_safe)
+	{
+		luat_rtos_task_suspend_all();
+	}
+	if (!luat_auto_apn.dynamic_list.next)
+	{
+		luat_mobile_init_auto_apn_by_plmn();
+	}
+	PV_Union plmn;
+	plmn.u16[1] = mcc;
+	plmn.u16[0] = mnc;
+	apn = llist_traversal(&luat_auto_apn.dynamic_list, luat_mobile_find_apn, plmn.p);
+	if (apn)
+	{
+		llist_del(&apn->node);
+		free(apn);
+	}
+	apn = calloc(1, sizeof(apn_node_t) + name_len + user_len + password_len);
+	apn->plmn.u16[1] = mcc;
+	apn->plmn.u16[0] = mnc;
+	apn->ip_type = ip_type;
+	apn->protocol = protocol;
+	apn->name_len = name_len;
+	apn->user_len = user_len;
+	apn->password_len = password_len;
+	memcpy(apn->data, name, name_len);
+	if (user && user_len)
+	{
+		memcpy(apn->data + name_len, user, user_len);
+	}
+	if (password && password_len)
+	{
+		memcpy(apn->data + name_len + user_len, password, password_len);
+	}
+	llist_add_tail(&apn->node, &luat_auto_apn.dynamic_list);
+	if (task_safe)
+	{
+		luat_rtos_task_resume_all();
+	}
+}
+
+int luat_mobile_find_apn_by_mcc_mnc(uint16_t mcc, uint16_t mnc, apn_info_t *info)
+{
+	if (!luat_auto_apn.dynamic_list.next)
+	{
+		LLOGE("no apn table");
+		return -1;
+	}
+	apn_node_t *apn;
+	PV_Union plmn;
+	plmn.u16[1] = mcc;
+	plmn.u16[0] = mnc;
+	int result;
+	luat_rtos_task_suspend_all();
+	apn = llist_traversal(&luat_auto_apn.dynamic_list, luat_mobile_find_apn, plmn.p);
+
+	if (apn)
+	{
+		info->data = apn->data;
+		info->ip_type = apn->ip_type;
+		info->protocol = apn->protocol;
+		info->name_len = apn->name_len;
+		info->user_len = apn->user_len;
+		info->password_len = apn->password_len;
+		result = 0;
+	}
+	else
+	{
+		result = -1;
+	}
+	luat_rtos_task_resume_all();
+	return result;
+}
 
 int luat_mobile_get_isp_from_plmn(uint16_t mcc, uint8_t mnc)
 {
-	uint8_t cmcc[] = {0, 2, 4, 7, 8, 13, 24};
+	uint8_t cmcc[] = {0, 2, 4, 7, 8, 13, 23, 24};
 	uint8_t cucc[] = {1, 6, 9, 10};
 	uint8_t ctcc[] = {3, 5, 11, 12};
 	if (mcc != 460) return -1;