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 | cfgcntuint16_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 | LogOutputLeveluint16_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;
}
NBIOT 移动M5310A模块 AT+MIPLCREATE注册码自动生成相关推荐
- Driller、Exploit自动生成引擎 Rex
来自 UCSB 的团队 Shellphish,为参加 DARPA 举办的 CGC 竞赛,设计并实现了 CRS(Cyber Reasoning System)Mechaphish.该系统包含自动化漏洞挖 ...
- TP自动生成模块目录
TP自动生成模块目录 例如我想在项目中增加一个AdminI模块 只需要在入口文件index.php中添加: define('BIND_MODULE','Admin'); 再访问127.0.0.1项目就 ...
- boost::python模块显示重载和自动转换问题的示例
boost::python模块显示重载和自动转换问题的示例 实现功能 C++实现代码 实现功能 boost::python模块显示重载和自动转换问题的示例 C++实现代码 #include <b ...
- 第三百二十六节,web爬虫,scrapy模块,解决重复ur——自动递归url
第三百二十六节,web爬虫,scrapy模块,解决重复url--自动递归url 一般抓取过的url不重复抓取,那么就需要记录url,判断当前URL如果在记录里说明已经抓取过了,如果不存在说明没抓取过 ...
- python利用什么写模板_利用python自动生成verilog模块例化模板
一.前言 初入职场,一直忙着熟悉工作,就没什么时间更新博客.今天受"利奇马"的影响,只好宅在家中,写写技术文章.芯片设计规模日益庞大,编写脚本成了芯片开发人员必要的软技能.模块端口 ...
- python使用selenium模块实现火车票的自动购买
python使用selenium模块实现火车票的自动购买 python使用selenium模块实现火车票的自动购买 实现功能描述 直接撸代码 总结 实现功能描述 程序运行后会打开一个浏览器界面定义其尺 ...
- 华为为LG Uplus提供10万个NB-IoT芯片和模块
OFweek 光通讯网讯:据悉,韩国移动运营商LG Uplus已经于华为就窄带物联网(NB-IoT)服务达成了合作协议.华为计划向那些加入NB-IoT业务平台的中小企业提供大约10万个NB-IoT芯片 ...
- AI助力90.4%双11前端模块自动生成
简介:与大家分享,我们是如何看待人工智能在前端领域的未来发展方向,如何推进智能化能力在智能生成代码平台 imgcook 上的应用落地和迭代升级助力今年双 11 会场 90.4% 新模块的代码智能生成, ...
- PHPCMS v9类新华网新闻头条模块自动生成头条图片
在原1.0基础上进行了升级 主要的升级功能就是增加了自动生成头条功能,用户可以在后台模块配置中自定义头条图片的大小.背景颜色.文字颜色.文体.边距然后自动生成头条图片. 并可以在每次添加时都可以自定义 ...
最新文章
- python代码命令行tab补齐_Python在命令行下Tab键自动补全脚本
- github建立静态网站,域名解析和跳转
- 一台服务器最多能创建多少个 TCP 连接?
- 剑指offer之41-45题解
- 封装log4cp p
- 无线数传在桥梁检测中传感器信号的采集应用
- 这位博士跑赢“地震波”:提前 10 秒预警宜宾地震!
- mysql 单数据库设置编码,mysql数据库编码设置
- MySQL的两个存储引擎--MyISAM和InnoDB
- LED的本质和发光原理是什么,彩色的LED灯是怎么做出来的
- Django学习笔记之Ajax入门
- 松下电视切换html,松下等离子电视如何用HDMI连接电脑?
- 应广单片机长按开关机_单键实现单片机开关机设计案例
- Python 爬虫抓取网站汇率并将结果保存到文件
- 信息系统项目管理师(2022年)—— 重点内容:知识产权与标准规范(22)
- BZOJ 1050: [HAOI2006]旅行comf
- python 等腰三角形的性质_Blender 脚本之 Operator 初探
- 联想G40-70m黑苹果安装实录
- C/C++输入未知组数据的方法,多行输入介绍
- 开心一笑,,,哈哈哈