小熊派鸿蒙社区
直播中

jf_07365693

1年用户 78经验值
擅长:嵌入式技术 控制/MCU
私信 关注
[经验]

【BearPi-Pico H3863星闪开发板体验连载】星闪 SLE 网关透传测试

星闪 SLE 网关透传测试

通过两块开发板实现 星闪 (SparkLink) 低功耗接入技术(Sparklink Low Energy, SLE)数据传输测试。

SLE_Gateway.png

传输过程如上图所示,其中一块开发板做为 Server 服务端,另外一块开发板做为 Client 客户端,具体过程如下

(1)A 开发板通过串口接收数据,然后通过 SLE 传输给 B 开发板;

(2)B 开发板将接收到的数据通过 UDP 协议发送到 UDP 服务端;

(3)B 开发板接收 UDP 服务端发来的数据,然后通过 SLE 传输给 A 开发板,A开发板通过串口打印接收到的数据。

注意 B 开发板和 UDP 服务器需要处于同一个局域网

服务端配置

SLE_GateWay_Server_Config.png

核心代码

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. */
    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 开发板即可。

客户端配置

SLE_GateWay_Client_Config.png

核心代码

修改代码中的 WIFi 用户名、密码和 IP 地址信息

// 服务器的地址信息
struct sockaddr_in g_send_addr;
socklen_t g_addr_length = sizeof(g_send_addr);
​
#define CONFIG_WIFI_SSID            "test"           // 要连接的WiFi 热点账号
#define CONFIG_WIFI_PWD             "0987654321"     // 要连接的WiFi 热点密码
#define CONFIG_SERVER_IP            "192.168.1.175"  // 要连接的服务器IP
#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. */
    uart_init_config();
​
    /*  Wifi connect */
    wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);
​
    /* create socket */
    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);
        // printf("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);
        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 - 创建 - 输入 本地端口 号 - 确定 即可,如下图所示

TCP-UDP_Socket_Tool.png

连接开发板至电脑,串口助手软件打开 Server 服务端对应的端口号,Client 客户端接电即可,如下图所示

SLE_Gateway_test_TwoBoard.jpg

测试流程

  1. **串口助手通过 Server 端开发板发送数据 **222,Client 端开发板 SLE 接收数据并通过 WiFi 转发至 UDP 服务端,此时调试工具显示接收到的数据;
  2. **UDP 服务端调试工具发送数据 **111 通过 WiFi 路由器至 Client 客户端开发板,Client 开发板通过 SLE 将数据转发至 Server 端开发板并通过串口显示接收数据。

SLE_GateWay_test.png

视频

VID_20241004_SLE_Gateway

更多回帖

发帖
×
20
完善资料,
赚取积分