foreword
Recently, I was debugging the mesh function of ESP8266. After staring at the code and debugging information for a few days, I finally found that mesh is very simple to use (unfortunately, I don’t know anything about its working principle). Personally, I feel that other package sending programs are basically They all follow this process, so I decided to record the process of this mesh's json package function for future reference.
Program source code
void ICACHE_FLASH_ATTR mesh_json_bcast_test()
{
char buf[32];
uint8_t src[6];
uint8_t dst[6];
struct mesh_header_format *header = NULL;
/** 获取mac地址 */
if (!wifi_get_macaddr(STATION_IF, src))
{
MESH_PARSER_PRINT("bcast get sta mac fail\n");
return;
}
os_memset(buf, 0, sizeof(buf));
os_sprintf(buf, "%s", "{\"bcast\":\"");
os_sprintf(buf + os_strlen(buf), MACSTR, MAC2STR(src));
os_sprintf(buf + os_strlen(buf), "%s", "\"}\r\n");
os_memset(dst, 0, sizeof(dst));
/** 创建一个数据包 */
header = (struct mesh_header_format *)espconn_mesh_create_packet(
dst,
src,
false,
true,
M_PROTO_JSON,
os_strlen(buf),
false,
0,
false,
0,
false,
0,
0);
/** 进行数据包地址正确性检查 */
if (!header)
{
MESH_PARSER_PRINT("bcast create packet fail\n");
return;
}
/** 设置用户数据 */
if (!espconn_mesh_set_usr_data(header, buf, os_strlen(buf)))
{
MESH_DEMO_PRINT("bcast set user data fail\n");
MESH_DEMO_FREE(header);
return;
}
/** 发送数据 */
if (espconn_mesh_sent(&g_ser_conn, (uint8_t *)header, header->len))
{
MESH_DEMO_PRINT("bcast mesh is busy\n");
espconn_mesh_connect(&g_ser_conn);
MESH_DEMO_FREE(header);
return;
}
MESH_DEMO_FREE(header);
}
Process introduction
- First get the mac address of the module through wifi_get_macaddr .
- Configure the contents of the user data packet (buf).
- Initialize the target mac address (if the MAC address is zero, it is regarded as sending data packets to all devices in the network).
- Create a packet (pointed to by the pointer header) by calling the espconn_mesh_create_packet function.
- Add the contents of the user data packet to the data packet to be sent by calling the espconn_mesh_set_usr_data function.
- Send data by calling the espconn_mesh_sent function (the user needs to manually release the memory of this data packet after the data is sent).
It can be seen from the above flow chart that the json package first needs to create and configure the data package, then set the user data of the data package, and finally send the data through the package sending program.
Related API introduction
一、wifi_get_macaddr
Function |
Query MAC address |
- |
function prototype |
bool wifi_get_macaddr (uint8 if_index, uint8 * macaddr) |
- |
parameter |
if_index |
The current configuration of the obtained soft-ap |
parameter enumeration |
STATION_IF |
0x00 |
- |
SOFTAP_IF |
0x01 |
parameter |
* macaddr |
The obtained mac address |
return value |
true |
Obtain the mac address successfully |
- |
false |
Failed to get mac address |
二、espconn_mesh_create_packet
Function |
Create mesh packets |
- |
function prototype |
void * espconn_mesh_create_packet ( uint8_t* dst_addr, uint8_t* src_addr, bool p2p, bool piggyback_cr, enum mesh_usr_proto_type proto, uint16_t data_len, bool option, uint16_t ot_len, bool frag, enum mesh_option_type frag_type, bool mf, uint16_t frag_idx, uint16_t frag_id ) |
- |
parameter |
*dst_addr |
Receiver's mac address (if it is zero, it means that the receiver is all devices in the network) |
parameter |
*src_addr |
sender's mac address |
parameter |
p2p |
Whether it is a node-to-node packet (bool type) |
parameter |
piggyback_cr |
piggyback stream request (bool type) |
parameter |
proto |
The current configuration of the obtained soft-ap |
parameter enumeration |
M_PROTO_NONE |
User Data for Network Management Pack |
- |
M_PROTO_HTTP |
User data style is HTTP style |
- |
M_PROTO_JSON |
User data style is JSON style |
- |
M_PROTO_MQTT |
User data style is MQTT style |
- |
M_PROTO_BIN |
User data style is binary style |
parameter |
data_len |
length of user data |
parameter |
option |
Operation option enable (bool type) |
parameter |
от_лен |
Operation option data length |
parameter |
frag |
fragmentation enable flag (bool type) |
parameter |
frag_type |
fragmentation type |
parameter enumeration |
M_O_CONGEST_REQ |
blocking request |
- |
M_O_CONGEST_RESP |
Respond to blocking requests |
- |
M_O_ROUTER_SPREAD |
Router information extension options |
- |
M_O_ROUTE_ADD |
Node join options |
- |
M_O_ROUTE_DEL |
Node rollout options |
- |
M_O_TOPO_REQ |
Topology Request Options |
- |
M_O_TOPO_RESP |
Topology Response Options |
- |
M_O_MCAST_GRP |
Multicast of group lists |
- |
M_O_MESH_FRAG |
mesh management fragment options |
- |
M_O_USR_FRAG |
user data fragment |
- |
M_O_USR_OPTION |
User options |
parameter |
mf |
更多的fragmentation |
参数 |
frag_idx |
fragmentation首 |
参数 |
frag_id |
fragmentation id |
返回值 |
void * |
返回一个由系统创建的数据包的地址(该地址空间需要用户手动释放) |
三、 espconn_mesh_set_usr_data
功能 |
设置mesh发送包的用户数据 |
- |
函数原型 |
bool espconn_mesh_set_usr_data ( struct mesh_header_format* head, uint8_t* usr_data, uint16_t data_len ) |
- |
参数 |
*head |
发送包的地址 |
参数 |
*usr_data |
用户数据缓存区 |
参数 |
data_len |
数据长度 |
返回值 |
true |
设置成功 |
- |
false |
设置失败 |
四、 espconn_mesh_sent
功能 |
mesh发送数据包 |
- |
函数原型 |
int8_t espconn_mesh_sent ( struct espconn* usr_esp, uint8* pdata, uint16 len ) |
- |
参数 |
*usr_esp |
网络连接结构体 |
参数 |
*pdata |
数据包的地址 |
参数 |
len |
数据包的长度 |
返回值 |
ESPCONN_OK(0) |
发送成功 |
- |
ESPCONN_MEM(-1) |
内存不足 |
- |
ESPCONN_MAXNUM(-7) |
发送数据缓存区已满 |
- |
ESPCONN_ARG(-12) |
非法参数 |
- |
ESPCONN_IF(-14) |
发送UDP数据失败 |
参考资料
[1]. ESP8266 Mesh 用户手册
[2]. ESP8266 ESP-MESH API 参考
[3]. ESP8266Non-OS SDK API参考