目录
巴法云云平台官网
巴法云云平台搭建
- 进入巴法云平台登录注册
- 点击TCP设备云

- 在最右边输入框中输入主题名,主题命名并无强制性要求,也可以参考主题类型命名说明:

比如我们这里将主题命名为ledtest,点击新建主题

创建成功后可以看到下面出现了一个主题

TCP简介
TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议,传输层协议常用的有TCP和UDP,像常见的http协议或mqtt协议,都是在TCP上传输的,TCP用途广泛,一般可以联网的设备,都支持TCP协议传输。
订阅、发布简介
通俗的来讲,订阅、发布是两种不同的信号
 订阅:订阅某一个主题,订阅之后,就可以收到发往该主题的消息。
 发布:向某个主题发送消息。
 例如:当某个设备订阅了主题“X”,这时向主题“X”发送的任何消息,设备都可以收到,因为设备已经订阅上了该主题。
直接上干货!
代码示例
wifi_sta_connect.c
- /*
-  * Copyright (c) 2022 Hunan OpenValley Digital Industry Development Co., Ltd.
-  * Licensed under the Apache License, Version 2.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  *
-  *    http://www.apache.org/licenses/LICENSE-2.0
-  *
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include "securec.h"
- #include "cmsis_os2.h"
- #include "ohos_init.h"
- #include "wifi_device.h"
- #include "lwip/ip4_addr.h"
- #include "lwip/netif.h"
- #include "lwip/netifapi.h"
- #include "wifi_error_code.h"
-  
- #define DEF_TIMEOUT 15
- #define ONE_SECOND 1
- #define SELECT_WLAN_PORT "wlan0"
- #define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_OPEN
- #define STD_TIMEZONE_OFFSET (+8)
- #define OD_DELAY_100 100
- #define OD_DELAY_200 200
-  
- static int g_staScanSuccess = 0;
- static int g_ConnectSuccess = 0;
- static int ssid_count = 0;
- static WifiErrorCode wifi_error;
- static WifiEvent g_wifiEventHandler = {0};
- static int wifi_sta_init_state = 0;
- int sock_fd;
- int addr_length;
- const int timeZone = 8;
-  
- static void WiFiInit(void);
- static void WaitScanResult(void);
- static int WaitConnectResult(void);
- static void OnWifiScanStateChangedHandler(int state, int size);
- static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);
- static void OnHotspotStaJoinHandler(StationInfo *info);
- static void OnHotspotStateChangedHandler(int state);
- static void OnHotspotStaLeaveHandler(StationInfo *info);
-  
- void DisableWIFI(void)
- {
-     DisableWifi();
- }
-  
- static void OnHotspotStaJoinHandler(StationInfo *info)
- {
-     (void)info;
-     printf("STA join AP\n");
-     return;
- }
-  
- static void OnHotspotStaLeaveHandler(StationInfo *info)
- {
-     (void)info;
-     printf("HotspotStaLeave:info is null.\n");
-     return;
- }
-  
- static void OnHotspotStateChangedHandler(int state)
- {
-     printf("HotspotStateChanged:state is %d.\n", state);
-     return;
- }
-  
- static void WiFiInit(void)
- {
-     printf("<--Wifi Init-->\r\n");
-     g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler;
-     g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler;
-     g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
-     g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
-     g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
-     wifi_error = RegisterWifiEvent(&g_wifiEventHandler);
-     if (wifi_error != WIFI_SUCCESS)
-     {
-         printf("register wifi event fail!\r\n");
-     }
-     else
-     {
-         printf("register wifi event succeed!\r\n");
-     }
- }
-  
- static void OnWifiScanStateChangedHandler(int state, int size)
- {
-     (void)state;
-     if (size > 0)
-     {
-         ssid_count = size;
-         g_staScanSuccess = 1;
-     }
-     return;
- }
-  
- static int result;
- int WifiConnect(const char *ssid, const char *psk)
- {
-     WifiScanInfo *info = NULL;
-     unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
-     static struct netif *g_lwip_netif = NULL;
-     WifiDeviceConfig select_ap_config = {0};
-     osDelay(OD_DELAY_200);
-     printf("<--System Init-->\r\n");
-     WiFiInit();
-     if (EnableWifi() != WIFI_SUCCESS)
-     {
-         printf("EnableWifi failed, wifi_error = %d\n", wifi_error);
-         return -1;
-     }
-     if (IsWifiActive() == 0)
-     {
-         printf("Wifi station is not actived.\n");
-         return -1;
-     }
-     info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
-     if (info == NULL)
-     {
-         printf("faild to create wifiscanInfo.\n");
-         return -1;
-     }
-     do
-     {
-         ssid_count = 0;
-         g_staScanSuccess = 0;
-         Scan();
-         WaitScanResult();
-         wifi_error = GetScanInfoList(info, &size);
-     } while (g_staScanSuccess != 1);
-     strcpy_s(select_ap_config.ssid, sizeof(select_ap_config.ssid), ssid);
-     printf("[%s][%s] \r\n", select_ap_config.ssid, select_ap_config.preSharedKey);
-     select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
-     if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
-     {
-         if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
-         {
-             printf("WiFi connect succeed!\r\n");
-             wifi_sta_init_state = 1;
-         }
-     }
-     osDelay(OD_DELAY_100);
-     return 0;
- }
-  
- static int WaitConnectResult(void)
- {
-     int ConnectTimeout = DEF_TIMEOUT;
-     while (ConnectTimeout > 0)
-     {
-         sleep(1);
-         ConnectTimeout--;
-         if (g_ConnectSuccess == 1)
-         {
-             printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout));
-             break;
-         }
-     }
-     if (ConnectTimeout <= 0)
-     {
-         printf("WaitConnectResult:timeout!\n");
-         return 0;
-     }
-     return 1;
- }
-  
- static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
- {
-     (void)info;
-     if (state > 0)
-     {
-         g_ConnectSuccess = 1;
-         printf("callback function for wifi connect\r\n");
-     }
-     else
-     {
-         g_ConnectSuccess = 0;
-         printf("connect wifi_error, please check password, state:%d, try connect again\r\n", state);
-         esp_wifi_connect();
-     }
-     return;
- }
-  
- static void WaitScanResult(void)
- {
-     int scanTimeout = DEF_TIMEOUT;
-     while (scanTimeout > 0)
-     {
-         sleep(ONE_SECOND);
-         scanTimeout--;
-         if (g_staScanSuccess == 1)
-         {
-             printf("WaitScanResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout));
-             break;
-         }
-     }
-     if (scanTimeout <= 0)
-     {
-         printf("WaitScanResult:timeout!\n");
-     }
- }
wifi_sta_example.c
- /*
-  * Copyright (c) 2022 Hunan OpenValley Digital Industry Development Co., Ltd.
-  * Licensed under the Apache License, Version 2.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  *
-  *    http://www.apache.org/licenses/LICENSE-2.0
-  *
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
- #include <stdio.h>
- #include "securec.h"
- #include "cmsis_os2.h"
- #include "ohos_run.h"
- #include "lwip/sockets.h"
- #include "lwip/ip_addr.h"
- #include "wifi_device.h"
-  
- #include <string.h>
-  
- #define OPEN_WIFI_NAME "test"
- // #define SERVER_IP	"192.168.31.67"
- #define SERVER_IP "119.91.109.180"
- #define SERVER_PORT 8344
- #define OD_DELAY_1000 1000
- #define OD_DELAY_100 100
- #define RECV_LEN 511
- #define STACK_SIZE 4096
- #define PRIORITY 25
-  
- osThreadId_t wifi_test_id = NULL;
-  
- void wifi_test(void)
- {
-   int sock = -1;
-   struct sockaddr_in client_addr;
-   char recv_data[512] = {0};
-   int recv_data_len;
-   WifiConnect(OPEN_WIFI_NAME);
-   printf("start wifi_test test\r\n");
-   while (1)
-   {
-     sock = socket(AF_INET, SOCK_STREAM, 0);
-     if (sock < 0)
-     {
-       printf("Socket error\n");
-       osDelay(OD_DELAY_100);
-       continue;
-     }
-     memset_s(&(client_addr), sizeof(client_addr), 0, sizeof(client_addr));
-     client_addr.sin_family = AF_INET;
-     client_addr.sin_port = htons(SERVER_PORT);
-     client_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
-     printf("try connect to server " SERVER_IP " :%d \n", SERVER_PORT);
-     if (connect(sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1)
-     {
-       closesocket(sock);
-       osDelay(OD_DELAY_1000);
-       continue;
-     }
-     printf("Connect to tcp server successful!\n");
-     write(sock, "cmd=1&uid=4e2a189d769e4511bd5885742aa3edcb&topic=ledtest\r\n", strlen("cmd=1&uid=4e2a189d769e4511bd5885742aa3edcb&topic=ledtest\r\n"));
-     while (1)
-     {
-       recv_data_len = recv(sock, recv_data, RECV_LEN, 0);
-       if (recv_data_len <= 0)
-       {
-         break;
-       }
-       else
-       {
-         recv_data[recv_data_len] = '\0';
-         printf("recv: %s\n", recv_data);
-       }
-     }
-   }
- }
-  
- static void wifi_test_example(void)
- {
-   osThreadAttr_t attr;
-   attr.name = "wifi_test";
-   attr.attr_bits = 0U;
-   attr.cb_mem = NULL;
-   attr.cb_size = 0U;
-   attr.stack_mem = NULL;
-   attr.stack_size = STACK_SIZE;
-   attr.priority = PRIORITY;
-   wifi_test_id = osThreadNew((osThreadFunc_t)wifi_test, NULL, &attr);
-   if (wifi_test_id == NULL)
-   {
-     printf("Failed to create wifi_test thread!\n");
-   }
- }
-  
- OHOS_APP_RUN(wifi_test_example);
BUILD.gn
- # Copyright (c) 2022 Hunan OpenValley Digital Industry Development Co., Ltd.
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- #     http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import("//kernel/liteos_m/liteos.gni")
-  
- module_name = get_path_info(rebase_path("."), "name")
- kernel_module(module_name) {
-     sources = [
-         "wifi_sta_example.c",
-         "wifi_sta_connect.c"
-     ]
-     include_dirs = [
-         "//foundation/communication/wifi_lite/interfaces/wifiservice",
-         "//device/board/esp/esp32/liteos_m/hals/driver/wifi_lite"
-     ]
- }
移植步骤
移植本代码中有几个部分需要注意:

- 所连接的热点必须是开放的2.4G热点(没有密码)
修改连接热点名方法:将wifi_sta_example.c中OPEN_WIFI_NAME的宏定义修改为热点名即可
- 参考巴法云平台接入文档 - TCP协议中 接口地址应是:

但经笔者测试,直接填入"bemfa.com"无法连接上该服务器,推测是无法进行DNS解析,所以我们直接连接IP地址,可以通过cmd打开windows终端 - ping bemfa.com查看域名对应的IP地址

- 巴法云提供的TCP服务器是基于订阅/发布(简化版MQTT)的服务,我们可以通过向服务器发送命令的方式对主题进行订阅与发布。
巴法云TCP客户端接入详解
命令字段说明
cmd:消息类型
- cmd=1 时为订阅消息,当设备发送一次此消息类型,之后就可以收到发往该主题的消息
-  
- cmd=2 时为发布消息,向订阅该主题的设备发送消息
-  
- cmd=3 是订阅消息,和cmd=1相同,并且会拉取一次已发送过的消息
-  
- cmd=7 是获取时间,获取当前北京时间
-  
- cmd=9 为遗嘱消息,拉取一次已经发送的消息
uid:用户私钥
可在控制台获取topic:用户主题
可以在控制台创建主题,格式为英文或数字,相当于设备标识msg: 为消息体
用户想要发送到某个主题的数据符号说明
- \r\n: 为回车换符,每条指令后都需要有回车换行。
- &: 为连接符,各字段间用'&'隔离。
心跳说明
- 发送任意数据 为心跳消息,包括上述指令也算是心跳,但要以回车换行结尾。
- 心跳消息是告诉服务器设备还在线,建议60秒发送一次,超过65秒未发送心跳会掉线。
订阅主题
订阅主题,单次最多订阅八个主题
cmd=1&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=xxx1,xxx2,xxx3,xxx4\r\n正常返回:
cmd=1&res=1发布
cmd=2&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=light002&msg=off\r\n正常返回:
cmd=2&res=1订阅主题,并获取一条历史消息
cmd=3&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=light002\r\n正常返回:
cmd=3&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=light002&msg=on获取一次时间
cmd=7&uid=xxxxxxxxxxxxxxxxxxxxxxx&type=1\r\n正常返回:
2021-06-11 16:39:27- type=1 获取当前日期和时间,例如:2021-06-11 17:20:54
-  
- type=2 获取当前时间,例如:17:20:54
-  
- type=3 获取当前时间戳,例如:1623403325
获取一次已发消息
cmd=9&uid=7d54f85af42976ee3c2693e6xxxxxxxx&topic=light002\r\n正常返回:
cmd=9&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=light002&msg=on发送心跳
ping\r\n正常返回:
cmd=0&res=1发送任意数据,并以\r\n结尾,都为心跳消息,包括上述发布、订阅指令也都算是心跳。 心跳消息是告诉服务器设备还在线,建议60秒发送一次,超过65秒未发送心跳会掉线。
set 指令
推送消息时:主题名后加/set推送消息,表示向所有订阅这个主题的设备们推送消息,假如推送者自己也订阅了这个主题,消息不会被推送给它自己,以防止自己推送的消息被自己接收。 例如向主题 light002推送数据,可为 light002/set 。
示例:
cmd=2&uid=4d9ec352e0376f2110a0c601a2857225&topic=light002/set&msg=onup 指令
推送消息时:主题名后加/up推送消息,表示只更新云端数据,不进行任何推送。 例如向主题 light002推送数据,可为light002/up。
示例:
cmd=2&uid=4d9ec352e0376f2110a0c601a2857225&topic=light002/up&msg=onapp 指令
订阅时:主题名后加/app订阅主题,不会占用设备在线状态,即不会显示设备在线,可用于app、小程序等订阅时使用。
示例:
cmd=1&uid=4d9ec352e0376f2110a0c601a2857225&topic=light002/app编译并烧录

在源码根目录下使用hb工具对写好的代码进行编译

选择mini级系统
同理 产品选择esp公司下的esp32

选择完毕后在源码根目录下执行hb build -f 进行编译

编译完成后会有如下界面,并且编译后的代码固件位于:out\esp32\esp32

使用烧录软件进行烧录:

点击start,等待烧录完成
实验现象

按下ESP32开发板上的EN键,即可观察到实验现象:

可以看到我们已经成功连接上TCP服务器,我们打开云平台查看是否有客户端对主题ledtest进行了订阅

我们尝试在云平台进行手动发布信息:hello openharmony!

在串口助手上成功打印出了该信息

后续大家自行将手动发布信息改成使用命令的方式进行发布即可!订阅相同主题的设备都可以收到发布的信息!
 本项目代码已上传至gitee:ESP32_Oh: ESP32移植Openharmony
 
                                    
评论记录:
回复评论: