星闪 SLE 网关透传测试
通过两块开发板实现 星闪 (SparkLink) 低功耗接入技术(Sparklink Low Energy, SLE)数据传输测试。
传输过程如上图所示,其中一块开发板做为 Server 服务端,另外一块开发板做为 Client 客户端,具体过程如下
(1)A 开发板通过串口接收数据,然后通过 SLE 传输给 B 开发板;
(2)B 开发板将接收到的数据通过 UDP 协议发送到 UDP 服务端;
(3)B 开发板接收 UDP 服务端发来的数据,然后通过 SLE 传输给 A 开发板,A开发板通过串口打印接收到的数据。
注意 B 开发板和 UDP 服务器需要处于同一个局域网
服务端配置
核心代码
static void ssaps_server_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para,
errcode_t status)
{
osal_printk("%s ssaps write request callback cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
SLE_GATEWAY_SERVER_LOG, server_id, conn_id, write_cb_para->handle, status);
if ((write_cb_para->length > 0) && write_cb_para->value) {
osal_printk("\n sle uart recived data : %s\r\n", write_cb_para->value);
uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)write_cb_para->value, write_cb_para->length, 0);
}
}
static void sle_uart_server_read_int_handler(const void *buffer, uint16_t length, bool error)
{
unused(error);
if (sle_uart_client_is_connected()) {
sle_uart_server_send_report_by_handle(buffer, length);
} else {
osal_printk("%s sle client is not connected! \r\n", SLE_GATEWAY_SERVER_LOG);
}
}
static void *sle_uart_server_task(const char *arg)
{
unused(arg);
uint8_t rx_buf[SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE] = {0};
uint32_t rx_length = SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE;
uint8_t sle_connect_state[] = "sle_dis_connect";
sle_uart_server_create_msgqueue();
sle_uart_server_register_msg(sle_uart_server_write_msgqueue);
sle_uart_server_init(ssaps_server_read_request_cbk, ssaps_server_write_request_cbk);
uart_init_config();
uapi_uart_unregister_rx_callback(CONFIG_SLE_GATEWAY_BUS);
errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_GATEWAY_BUS,
UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
1, sle_uart_server_read_int_handler);
if (ret != ERRCODE_SUCC) {
osal_printk("%s Register uart callback fail.[%x]\r\n", SLE_GATEWAY_SERVER_LOG, ret);
return NULL;
}
while (1) {
sle_uart_server_rx_buf_init(rx_buf, &rx_length);
sle_uart_server_receive_msgqueue(rx_buf, &rx_length);
if (strncmp((const char *)rx_buf, (const char *)sle_connect_state, sizeof(sle_connect_state)) == 0) {
ret = sle_start_announce(SLE_ADV_HANDLE_DEFAULT);
if (ret != ERRCODE_SLE_SUCCESS) {
osal_printk("%s sle_connect_state_changed_cbk,sle_start_announce fail :%02x\r\n",
SLE_GATEWAY_SERVER_LOG, ret);
}
}
osal_msleep(SLE_GATEWAY_TASK_DURATION_MS);
}
sle_uart_server_delete_msgqueue();
return NULL;
}
重编译
工程后 程序加载
至开发板并重置 RST
开发板即可。
客户端配置
核心代码
修改代码中的 WIFi 用户名、密码和 IP 地址信息
struct sockaddr_in g_send_addr;
socklen_t g_addr_length = sizeof(g_send_addr);
#define CONFIG_WIFI_SSID "test"
#define CONFIG_WIFI_PWD "0987654321"
#define CONFIG_SERVER_IP "192.168.1.175"
#define CONFIG_SERVER_PORT 8888
电脑 IP 地址查询方法:打开 Windows PowerShell,输入 ipconfig
回车即可。
客户端关键代码
void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
errcode_t status)
{
unused(client_id);
unused(conn_id);
unused(status);
osal_printk("\n sle uart recived data : %s\r\n", data->data);
uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)(data->data), data->data_len, 0);
sendto(g_sock_fd, (uint8_t *)(data->data), data->data_len, 0, (struct sockaddr *)&g_send_addr, g_addr_length);
}
void sle_uart_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
errcode_t status)
{
unused(client_id);
unused(conn_id);
unused(status);
osal_printk("\n sle uart recived data : %s\r\n", data->data);
uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)(data->data), data->data_len, 0);
}
static void sle_uart_client_read_int_handler(const void *buffer, uint16_t length, bool error)
{
unused(error);
ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
sle_uart_send_param->data_len = length;
sle_uart_send_param->data = (uint8_t *)buffer;
ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
}
static void *sle_uart_client_task(const char *arg)
{
unused(arg);
char recvBuf[512];
uart_init_config();
wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);
printf("create socket start!\r\n");
if ((g_sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
printf("create socket failed!\r\n");
return 0;
}
g_send_addr.sin_family = AF_INET;
g_send_addr.sin_port = htons(CONFIG_SERVER_PORT);
g_send_addr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP);
g_addr_length = sizeof(g_send_addr);
printf("create socket end!\r\n");
uapi_uart_unregister_rx_callback(CONFIG_SLE_GATEWAY_BUS);
errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_GATEWAY_BUS,
UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
1, sle_uart_client_read_int_handler);
sle_uart_client_init(sle_uart_notification_cb, sle_uart_indication_cb);
if (ret != ERRCODE_SUCC) {
osal_printk("Register uart callback fail.");
return NULL;
}
while (1) {
bzero(recvBuf, sizeof(recvBuf));
recvfrom(g_sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&g_send_addr, &g_addr_length);
ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
sle_uart_send_param->data_len = strlen(recvBuf);
sle_uart_send_param->data = (uint8_t *)recvBuf;
ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
}
return NULL;
}
重编译
工程后 程序加载
至开发板并重置 RST
开发板即可。
网关透传测试
准备工作
**下载并打开软件 Socket 调试工具,依次点击 **UDP Server
- 创建
- 输入 本地端口
号 - 确定
即可,如下图所示
连接开发板至电脑,串口助手软件打开 Server 服务端对应的端口号,Client 客户端接电即可,如下图所示
测试流程
- **串口助手通过 Server 端开发板发送数据 **
222
,Client 端开发板 SLE 接收数据并通过 WiFi 转发至 UDP 服务端,此时调试工具显示接收到的数据;
- **UDP 服务端调试工具发送数据 **
111
通过 WiFi 路由器至 Client 客户端开发板,Client 开发板通过 SLE 将数据转发至 Server 端开发板并通过串口显示接收数据。
视频