NBIOT 移動M5310A模塊 AT+MIPLCREATE註冊碼自動生成

模組註冊碼

移動M5310A模塊固件中封裝的SDK會自動獲取模組當前的IMEI和IMSI用於ONENET平臺登錄,在ONENET平臺需要使用當前設備的 IMEI 和 IMSI 進行設備註冊。模組設備實體創建需要的配置數據,稱爲設備註冊碼。雖然有專門的軟件生成註冊碼,但是不同平臺接入或者接入方式有更改時,則需要重新生產註冊碼並更新程序,本文將生成註冊碼移植到程序中,只提供相應的接口修改。
注意:本流程使用的模組版本爲CMVER:2.1.1.1809071028.

註冊碼詳細信息

原始配置信息在config.xml文件中:

<?xml version="1.0" encoding="utf-8"?>
<config>
 	<item>
		 <version>1.0</version> //配置文件版本號
		 <cfgcnt>3</cfgcnt> //配置個數
 	</item>
 	<item id="1"></item>
 	<item id="2">
 		<data name="Mtu">1024</data> //最大傳輸單元大小
 		<data name="Linktype">1</data> //連接類型。默認配置爲1
 		<data name="Bandtype">1</data> //網絡類型,默認應設置爲 1
 		<data name="APN"></data> //缺省,保持默認爲空
 		<data name="Username"></data> //APN 用戶名,保持默認爲空
 		<data name="Password"></data> //APN 密碼,保持認爲空
 		<data name="Bootstrap">1</data> //接入方式,對接重慶平臺默認應配置爲 1,其他平臺配置爲 0
 		<data name="Host">nbiotbt.heclouds.com:5683</data> //平臺地址
 		<data name="Userdata">AuthCode:12458789;</data> /*其他配置信息,以“key:value;”的組合形式構成,
 		如支持認證的 OneNET 接入方式配置爲 AuthCode,value 爲具體的 AuthCode 根據需求自行填寫。如未設置
		AuthCode 無需填寫*/
 	</item>
 	<item id="3">
 		<data name="LogEnabled">0</data> //調試開關,0 表示關閉調試模式,1 表示打開調試模式
 		<data name="LogExtOutput">0</data> //擴展信息開關,默認應設置爲 1
 		<data name="LogOutputType">0</data> //日誌輸出模式,默認應設置爲 3
 		<data name="LogOutputLevel">0</data> //日誌輸出調試級別,默認應設置爲 1
 		<data name="LogBufferSize">0</data> //日誌緩存長度,無效值
 		<data name="Userdata"></data> //如無需 OneNET 設備認證,該選項應缺省爲空,否則應配置 AuthCode
 	</item>
	</config>

模組側設備創建使用 AT+MIPLCREATE 指令,其指令格式爲:

AT+MIPLCREATE=<totalsize>,<config>,<index>,<currentsize>,<flag>
//totalsize : 	指示<config>部分總數據長度,按照 ASCII 計數
//config : 		具體的設備配置數據,滿足配置結構體規範
//index : 		配置數據分片參數
//currentsize : 當前指令所包含的配置文件長度
//flag : 		配置數據流結束符

源碼


/**@brief 配置ID**/
typedef enum enum_cfgid {
	cis_cfgid_init = 0x01,
	cis_cfgid_net = 0x02,
	cis_cfgid_sys = 0x03
}cfgid_t;

/**@brief 頭信息結構體**/
typedef struct {
	uint8_t head;	// version << 4 | cfgcnt
	uint16_t config_len;
}head_node_t;

/**@brief 初始信息結構體**/
typedef struct {
	uint8_t cfgid;
	uint16_t node_len;
}init_node_t;

/**@brief 網絡信息結構體**/
typedef struct {
	uint8_t cfgid;
	uint16_t node_len;
	uint16_t mtu_len;
	uint8_t link_band; // ((linktype << 4) & 0xF0 | bandtype & 0x0F)
	uint16_t apn_len;
	uint8_t* apn;
	uint16_t uname_len;
	uint8_t* uname;
	uint16_t pwd_len;
	uint8_t* pwd;
	uint16_t hostlen_bootstrap; //(dataHost.length)|(bootstrap<<12)
	char* host_data;
	uint16_t user_data_len;
	uint8_t* user_data;
}net_node_t;

/**@brief 系統調試信息結構體**/
typedef struct {
	uint8_t cfgid;
	uint16_t node_len;
	uint8_t log_cfg; //LogEnabled << 7 | LogExtOutput << 6 | LogOutputType << 4 | LogOutputLevel
	uint16_t log_buf_size;
	uint16_t user_data_len;
	uint8_t* user_data;
}sys_node_t;

/**@brief MIPL配置結構體**/
typedef struct {
	head_node_t	head_node;	/* 頭信息 */
	init_node_t	init_node;	/* 初始信息 */
	net_node_t	net_node;	/* 入網信息 */
	sys_node_t	sys_node;	/* 系統調試信息 */
}mipl_config_t;

/*******************************************************************************
 * 函數名稱:config_put_u16
 * 功能描述:16位數據轉爲字符串格式
 * 輸入參數:p 		- 字符串指針
 *		   val 	- 傳入需要轉換的數值  	
 * 返 回 值 : none.
 ******************************************************************************/
static void config_put_u16(uint8_t* p, uint16_t val)
{
	uint8_t data[2] = { 0 };

	data[0] = (val >> 8) & 0xff;
	data[1] = (val) & 0xff;
	memcpy(p, data, 2);
}

/*******************************************************************************
 * 函數名稱:m5310a_HexToAsc
 * 功能描述:將一個字節數據轉換爲16進制字符串
 * 輸入參數:uc 		- 待轉換數據
 *		   val 	- 轉換後的字符串
 * 返 回 值 : none.
 ******************************************************************************/
static void m5310a_HexToAsc(uint8_t uc, unsigned char* str)
{
	*str++ = g_strlib_digits[(uc >> 4) & 0x0f];
	*str++ = g_strlib_digits[uc & 0x0f];
	*str = 0;
}

/*******************************************************************************
 * 函數名稱:mipconfig_legal
 * 功能描述:MIPL配置參數檢驗合格性
 * 輸入參數:config		- 傳入配置信息數據指針
 * 返 回 值 : 0:成功,-1:失敗.
 ******************************************************************************/
static int mipconfig_legal(mipl_config_t* config)
{
	if (config->net_node.mtu_len <= 256) {
		config->net_node.mtu_len = 256;
		M5310A_dbg( "WARNING:not found mtu.use default %d\n", config->net_node.mtu_len);
	}
	else if (config->net_node.mtu_len > 1280) {
		config->net_node.mtu_len = 1280;
		M5310A_dbg("WARNING:invalid mtu.use default %d\n", config->net_node.mtu_len);
	}

	if (0 == (config->net_node.hostlen_bootstrap & 0x0fff) || NULL == config->net_node.host_data) {
		M5310A_dbg("ERROR:invalid or not found host info.\n");
		return - 1;
	}

	if (config->net_node.apn_len > 0) {
		if (config->net_node.apn == NULL) {
			M5310A_dbg("ERROR:invalid or not found APN info.\n");
			return -1;
		}
	}

	if (config->net_node.uname_len > 0) {
		if (config->net_node.uname == NULL) {
			M5310A_dbg("ERROR:invalid or not found Username info.\n");
			return -1;
		}
	}

	if (config->net_node.pwd_len > 0) {
		if (config->net_node.pwd == NULL) {
			M5310A_dbg("ERROR:invalid or not found Password info.\n");
			return -1;
		}
	}

	if (config->net_node.user_data_len > 0) {
		if (config->net_node.user_data == NULL) {
			M5310A_dbg("ERROR:invalid or not found Userdata info.\n");
			return -1;
		}
	}

	if (config->sys_node.user_data_len > 0) {
		if (config->sys_node.user_data == NULL) {
			M5310A_dbg("ERROR:invalid or not found Log_Userdata info.\n");
			return -1;
		}
	}

	return 0;
}

/*******************************************************************************
 * 函數名稱:head_node_parse
 * 功能描述:頭信息解析
 * 輸入參數:head_node		- 傳入頭信息數據指針
 *		   buffer		- 解析處理後存儲緩衝區指針
 * 返 回 值 : 返回數據長度.
 ******************************************************************************/
static int head_node_parse(head_node_t * head_node, uint8_t * buffer)
{
	uint8_t* buf = buffer;
	uint8_t* start = buf;

	*buf++ = head_node->head;
	buf += sizeof(uint16_t);

	return buf - start;
}

/*******************************************************************************
 * 函數名稱:init_node_parse
 * 功能描述:初始信息解析
 * 輸入參數:init_node		- 傳入初始信息數據指針
 *		   buffer		- 解析處理後存儲緩衝區指針
 * 返 回 值 : 返回數據長度.
 ******************************************************************************/
static int init_node_parse(init_node_t * init_node, uint8_t * buffer)
{
	uint8_t* buf = buffer;
	uint8_t* start = buf;
	uint16_t offset = 0;

	*buf++ = init_node->cfgid;
	buf += sizeof(uint16_t);
	offset = buf - start;
	config_put_u16(start + 1, offset);
	
	return offset;
}

/*******************************************************************************
 * 函數名稱:net_node_parse
 * 功能描述:網絡信息解析
 * 輸入參數:net_node		- 傳入網絡信息數據指針
 *		   buffer		- 解析處理後存儲緩衝區指針
 * 返 回 值 : 返回數據長度.
 ******************************************************************************/
static int net_node_parse(net_node_t * net_node, uint8_t * buffer)
{
	uint8_t* buf = (uint8_t *)buffer;
	uint8_t* start = (uint8_t *)buf;
	uint16_t offset = 0;

	*buf++ = net_node->cfgid;
	buf += sizeof(uint16_t);

	config_put_u16(buf, net_node->mtu_len);
	buf += sizeof(uint16_t);

	*buf++ = net_node->link_band;

	config_put_u16(buf, net_node->apn_len);
	buf += sizeof(uint16_t);
	if (net_node->apn_len > 0) {
		memcpy(buf, net_node->apn, net_node->apn_len);
		buf += net_node->apn_len;
	}

	config_put_u16(buf, net_node->user_data_len);
	buf += sizeof(uint16_t);
	if (net_node->user_data_len > 0) {
		memcpy(buf, net_node->user_data, net_node->user_data_len);
		buf += net_node->user_data_len;
	}

	config_put_u16(buf, net_node->pwd_len);
	buf += sizeof(uint16_t);
	if (net_node->pwd_len > 0) {
		memcpy(buf, net_node->pwd, net_node->pwd_len);
		buf += net_node->pwd_len;
	}

	config_put_u16(buf, net_node->hostlen_bootstrap);
	buf += sizeof(uint16_t);
	if ((net_node->hostlen_bootstrap & 0x0fff) > 0) {
		memcpy(buf, (uint8_t *)net_node->host_data, net_node->hostlen_bootstrap & 0x0fff);
		buf += (net_node->hostlen_bootstrap & 0x0fff);
	}

	config_put_u16(buf, net_node->user_data_len);
	buf += sizeof(uint16_t);
	if (net_node->user_data_len > 0) {
		memcpy(buf, net_node->user_data, net_node->user_data_len);
		buf += net_node->user_data_len;
	}

	offset = buf - start;
	config_put_u16(start + 1, offset);

	return offset;
}

/*******************************************************************************
 * 函數名稱:sys_node_parse
 * 功能描述:系統調試信息解析
 * 輸入參數:sys_node		- 傳入系統調試信息數據指針
 *		   buffer		- 解析處理後存儲緩衝區指針
 * 返 回 值 : 返回數據長度.
 ******************************************************************************/
static int sys_node_parse(sys_node_t * sys_node, uint8_t * buffer)
{
	uint8_t* buf = (uint8_t*)buffer;
	uint8_t* start = (uint8_t*)buf;
	uint16_t offset = 0;

	*buf++ = (sys_node->cfgid & 0xff);
	buf += sizeof(uint16_t);

	*buf++ = sys_node->log_cfg;
	config_put_u16(buf, sys_node->log_buf_size);
	buf += sizeof(uint16_t);

	config_put_u16(buf, sys_node->user_data_len);
	buf += sizeof(uint16_t);
	if (sys_node->user_data_len > 0) {
		memcpy(buf, sys_node->user_data, sys_node->user_data_len);
		buf += sys_node->user_data_len;
	}

	offset = buf - start;
	config_put_u16(start + 1, offset);
	
	return offset;
}

char cmd_buf[256];
short Nb_IPAddr[4]; //添加平臺地址
short Nb_Port; //端口號
short NB_BootStarp; //接入方式
/*******************************************************************************
 * 函數名稱:miplconfig_generate
 * 功能描述:入網MIPL信息配置發送,應用層只改bootstarp 以及 host ,
 *		   其他爲默認,如有其他需要可自行修改 
 * 輸入參數:None.
 * 返 回 值 : SUCCESS : 成功,ERROR : 失敗.
 ******************************************************************************/
BOOL miplconfig_generate(void)
{
	int init_len = 0;
	int net_len = 0;
	int sys_len = 0;
	int config_len = 0;
	int head_len = 0;
	int i = 0, count = 0;
	uint8_t* pConfig = (uint8_t*)cmd_buf + 50; // 預留50字節
	uint8_t* pbuf = (uint8_t*)cmd_buf + 50;
	uint8_t *pSend = (uint8_t *)cmd_buf;
	char host_addr[30] = {0};
	int host_len = 0;
	mipl_config_t mipl_config;

	if (pbuf == NULL) return ERROR;

	sprintf(host_addr, "%d.%d.%d.%d:%d", Nb_IPAddr[0], Nb_IPAddr[1], 
		Nb_IPAddr[2], Nb_IPAddr[3], Nb_Port);
	host_len = strlen(host_addr);
	
	mipl_config.head_node.head = (1 << 4) | 3;
	mipl_config.init_node.cfgid = 0xf0 | cis_cfgid_init; /* 配置ID */

	mipl_config.net_node.cfgid = 0xf0 | cis_cfgid_net; /* 配置ID */
	mipl_config.net_node.mtu_len = 1024;
	mipl_config.net_node.link_band = ((1 << 4) & 0xF0) | (1 & 0x0F);
	mipl_config.net_node.apn_len = 0;
	mipl_config.net_node.apn = NULL;
	mipl_config.net_node.uname_len = 0;
	mipl_config.net_node.uname = NULL;
	mipl_config.net_node.pwd_len = 0;
	mipl_config.net_node.pwd = NULL;
	mipl_config.net_node.hostlen_bootstrap = ((NB_BootStarp << 12) | host_len);
	mipl_config.net_node.host_data = host_addr;
	mipl_config.net_node.user_data_len = 1; 
	mipl_config.net_node.user_data = "1";

	mipl_config.sys_node.cfgid = 0xf0 | cis_cfgid_sys; /* 配置ID */
	mipl_config.sys_node.log_cfg = 0;
	mipl_config.sys_node.log_buf_size = 0;
	mipl_config.sys_node.user_data_len = 0;
	mipl_config.sys_node.user_data = NULL;

	if (0 != mipconfig_legal(&mipl_config)) return ERROR;
	memset(cmd_buf, 0, sizeof(cmd_buf));

	head_len = head_node_parse(&mipl_config.head_node, pbuf);
	pbuf += head_len;

	init_len = init_node_parse(&mipl_config.init_node, pbuf);
	pbuf += init_len;

	net_len = net_node_parse(&mipl_config.net_node, pbuf);
	pbuf += net_len;

	sys_len = sys_node_parse(&mipl_config.sys_node, pbuf);
	pbuf += sys_len;
	
	config_len = head_len + init_len + net_len + sys_len;
	
	config_put_u16(pConfig + 1, config_len);

	sprintf((char *)pSend, "AT+MIPLCREATE=%d,", config_len);
	count = strlen((char *)pSend);
	for (i = 0; i < config_len; i++) {
		m5310a_HexToAsc(pConfig[i], &pSend[i * 2+count]);
	}
	sprintf((char *)&pSend[i*2 + count], ",0,%d,0", config_len);
	printf("pSend:%s\r\n", pSend);
	return SUCCESS;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章