void ICACHE_FLASH_ATTR mesh_device_set_root(struct mesh_device_mac_type *root) { if (!g_mesh_device_init) mesh_device_list_init(); /* * the first time to set root */ if (g_node_list.scale == 0) { MESH_DEMO_PRINT("new root:" MACSTR "\n", MAC2STR((uint8_t *)root)); MESH_DEV_MEMCPY(&g_node_list.root, root, sizeof(*root)); g_node_list.scale = 1; return; } /* * root device is the same to the current node, * we don't need to modify anything */ if (!MESH_DEV_MEMCMP(&g_node_list.root, root, sizeof(*root))) return; /* * switch root device, so the mac address list is stale * we need to free the stale the mac list */ MESH_DEMO_PRINT("switch root:" MACSTR "to root:" MACSTR "\n", MAC2STR((uint8_t *)&g_node_list.root), MAC2STR((uint8_t *)root)); mesh_device_list_release(); MESH_DEV_MEMCPY(&g_node_list.root, root, sizeof(*root)); g_node_list.scale = 1; }
bool ICACHE_FLASH_ATTR mesh_device_del(struct mesh_device_mac_type *nodes, uint16_t count) { uint16_t idx = 0, i = 0; uint16_t sub_count = g_node_list.scale - 1; if (!nodes || count == 0) return true; if (!g_mesh_device_init) mesh_device_list_init(); if (g_node_list.scale == 0) return false; while (idx < count) { /* * node is not in list, do nothing */ if (!mesh_search_device(nodes + idx)) { idx ++; continue; } /* * root will be delete, so current mac list is stale */ if (!MESH_DEV_MEMCMP(nodes + idx, &g_node_list.root, sizeof(*nodes))) { mesh_device_list_release(); return true; } /* * delete node from mac list */ for (i = 0; i < sub_count; i ++) { if (!MESH_DEV_MEMCMP(nodes + idx, &g_node_list.list[i], sizeof(*nodes))) { if (sub_count - i > 1) MESH_DEV_MEMCPY(&g_node_list.list[i], &g_node_list.list[i + 1], (sub_count - i - 1) * sizeof(*nodes)); sub_count --; g_node_list.scale --; i --; MESH_DEV_MEMSET(&g_node_list.list[g_node_list.scale], 0, sizeof(*nodes)); break; } } idx ++; } return true; }
bool ICACHE_FLASH_ATTR mesh_device_add(struct mesh_device_mac_type *nodes, uint16_t count) { #define MESH_DEV_STEP (10) uint16_t idx = 0; uint16_t rest = g_node_list.size + 1 - g_node_list.scale; if (!g_mesh_device_init) mesh_device_list_init(); if (g_node_list.size == 0) rest = 0; if (rest < count) { /* * current list is limited * we need to re-allocate buffer for mac list */ uint16_t size = g_node_list.size + rest + MESH_DEV_STEP; uint8_t *buf = (uint8_t *)MESH_DEV_ZALLOC(size * sizeof(*nodes)); if (!buf) { MESH_DEMO_PRINT("mesh add alloc buf fail\n"); return false; } /* * move the current list to new buffer */ if (g_node_list.list && g_node_list.scale > 1) MESH_DEV_MEMCPY(buf, g_node_list.list, (g_node_list.scale - 1) * sizeof(*nodes)); if (g_node_list.list) MESH_DEV_FREE(g_node_list.list); g_node_list.list = (struct mesh_device_mac_type *)buf; g_node_list.size = size; } while (idx < count) { if (!mesh_search_device(nodes + idx)) { // not in list, add it into list MESH_DEV_MEMCPY(g_node_list.list + g_node_list.scale - 1, nodes + idx, sizeof(*nodes)); g_node_list.scale ++; } idx ++; } return true; }
void ICACHE_FLASH_ATTR mesh_enable_cb(int8_t res) { MESH_DEMO_PRINT("mesh_enable_cb\n"); if (res == MESH_OP_FAILURE) { MESH_DEMO_PRINT("enable mesh fail, re-enable\n"); espconn_mesh_enable(mesh_enable_cb, MESH_ONLINE); return; } if (espconn_mesh_get_usr_context() && espconn_mesh_is_root() && res == MESH_LOCAL_SUC) goto TEST_SCENARIO; /* * try to estable user virtual connect * user can to use the virtual connect to sent packet to any node, server or mobile. * if you want to sent packet to one node in mesh, please build p2p packet * if you want to sent packet to server/mobile, please build normal packet (uincast packet) * if you want to sent bcast/mcast packet, please build bcast/mcast packet */ MESH_DEMO_MEMSET(&g_ser_conn, 0 ,sizeof(g_ser_conn)); MESH_DEMO_MEMSET(&ser_tcp, 0, sizeof(ser_tcp)); MESH_DEMO_MEMCPY(ser_tcp.remote_ip, server_ip, sizeof(server_ip)); ser_tcp.remote_port = server_port; ser_tcp.local_port = espconn_port(); g_ser_conn.proto.tcp = &ser_tcp; if (espconn_regist_connectcb(&g_ser_conn, esp_mesh_demo_con_cb)) { MESH_DEMO_PRINT("regist con_cb err\n"); espconn_mesh_disable(NULL); return; } if (espconn_regist_recvcb(&g_ser_conn, esp_recv_entrance)) { MESH_DEMO_PRINT("regist recv_cb err\n"); espconn_mesh_disable(NULL); return; } /* * regist the other callback * sent_cb, reconnect_cb, disconnect_cb * if you donn't need the above cb, you donn't need to register them. */ if (espconn_mesh_connect(&g_ser_conn)) { MESH_DEMO_PRINT("connect err\n"); if (espconn_mesh_is_root()) espconn_mesh_enable(mesh_enable_cb, MESH_LOCAL); else espconn_mesh_enable(mesh_enable_cb, MESH_ONLINE); return; } TEST_SCENARIO: mesh_device_list_init(); mesh_topo_test_init(); mesh_json_mcast_test_init(); mesh_json_bcast_test_init(); mesh_json_p2p_test_init(); }