跟着许思维老师的脚步,在许大神的影响之下才诞生了这个 demo。这玩意,说简单也不简单,说复杂吧也不复杂。
01
demo 源码如何使用
这里我已经把整个 demo 源码作为附件上传了,大家把文件解压后放在源码目录中:applications/sample/wifi-iot/app 文件夹下。
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"iothardware:wifi_demo",
]
}
这里我还是先按照老规矩说一下总体的大概思路:
PC 和 Hi3861 开发板之间使用无线连接到同一个局域网中。
Hi3861 作为客户端,PC 作为服务端建立 TCP 连接。
Hi3861 作为客户端接受到 PC 端发送的相应指令来进行相应的控制三色灯板的操作。
说完了大概思路,就可以说操作需要注意的一个点了:在把 Hi3861 烧好之后进行测试的时候,需要先开启服务端(这里我是直接拿 linux 下的 netcat,小伙伴完全可以换成自己熟悉的,都可以),然后在 reset 一下 Hi3861 开发板。
02
讲解代码
下面开始按照大概思路来分成三块讲解代码:
①PC 和 Hi3861 开发板之间使用无线连接到同一个局域网中
首先定义了 wifi 需要的两个监听事件 OnWifiConnectionChanged 和 OnWifiScanStateChanged:
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
if (!info) return;
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
PrintLinkedInfo(info);
if (state == WIFI_STATE_AVALIABLE) {
g_connected = 1;
} else {
g_connected = 0;
}
}
static void OnWifiScanStateChanged(int state, int size)
{
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}
static void PrintLinkedInfo(WifiLinkedInfo* info)
{
if (!info) return;
static char macAddress[32] = {0};
unsigned char* mac = info->bssid;
snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n",
macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid);
}
(void)arg;
WifiErrorCode errCode;
WifiEvent eventListener = {
.OnWifiConnectionChanged = OnWifiConnectionChanged,
.OnWifiScanStateChanged = OnWifiScanStateChanged
};
WifiDeviceConfig apConfig = {0};
int netId = -1;
osDelay(10);
errCode = RegisterWifiEvent(&eventListener);
printf("RegisterWifiEvent: %d\r\n", errCode);
strcpy(apConfig.ssid, "helloworld");
strcpy(apConfig.preSharedKey, "12345678");
apConfig.securityType = WIFI_SEC_TYPE_PSK;
errCode = EnableWifi();
printf("EnableWifi: %d\r\n", errCode);
osDelay(10);
errCode = AddDeviceConfig(&apConfig, &netId);
printf("AddDeviceConfig: %d\r\n", errCode);
g_connected = 0;
errCode = ConnectTo(netId);
printf("ConnectTo(%d): %d\r\n", netId, errCode);
while (!g_connected) {
osDelay(10);
}
printf("g_connected: %d\r\n", g_connected);
osDelay(50);
struct netif* iface = netifapi_netif_find("wlan0");
if (iface) {
err_t ret = netifapi_dhcp_start(iface);
printf("netifapi_dhcp_start: %d\r\n", ret);
osDelay(200); // wait DHCP server give me IP
ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL);
printf("netifapi_netif_common: %d\r\n", ret);
}
②Hi3861 作为客户端,PC 作为服务端建立 TCP 连接
ssize_t retval = 0;
int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
unsigned short port=5678;
struct sockaddr_in serverAddr = {0};
serverAddr.sin_family = AF_INET; // AF_INET表示IPv4协议
serverAddr.sin_port = htons(port); // 端口号,从主机字节序转为网络字节序
if (inet_pton(AF_INET, PARAM_SERVER_ADDR, &serverAddr.sin_addr) <= 0) { // 将主机IP地址从“点分十进制”字符串 转化为 标准格式(32位整数)
printf("inet_pton failed!\r\n");
goto do_cleanup;
调用 connect 函数进行连接,这里确保连接之后,才可以:
if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
printf("connect failed!\r\n");
goto do_cleanup;
}
printf("connect to server %s success!\r\n", PARAM_SERVER_ADDR);
调用 recv 接口接收从 PC 服务端发来的消息:
retval = recv(sockfd, &response, sizeof(response), 0);
if (retval <= 0) {
printf("send response from server failed or done, %ld!\r\n", retval);
goto do_cleanup;
}
response[retval] = '\0';
printf("recv response{%s} %ld from server done!\r\n", response, retval);
③Hi3861 作为客户端接受到 PC 端发送的相应指令来进行相应的控制三色灯板的操作
GpioInit();
IoSetFunc(RED_LED_PIN_NAME,RED_LED_PIN_FUNCTION);
IoSetFunc(GREEN_LED_PIN_NAME,GREEN_LED_PIN_FUNCTION);
IoSetFunc(RELLOW_LED_PIN_NAME,RELLOW_LED_PIN_FUNCTION);
GpioSetDir(RED_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT);
GpioSetDir(GREEN_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT);
GpioSetDir(RELLOW_LED_PIN_NAME,WIFI_IOT_GPIO_DIR_OUT);
if(strncmp(RED_ON,response,5) == 0){
printf("red on----------------");
GpioSetOutputVal(RED_LED_PIN_NAME,LED_BRIGHT);
}
else if(strncmp(RED_OFF,response,6) == 0){
printf("red off--------------");
GpioSetOutputVal(RED_LED_PIN_NAME,LED_DARK);
}else if(strncmp(GREEN_ON,response,7) == 0){
printf("red on----------------");
GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_BRIGHT);
}
else if(strncmp(GREEN_OFF,response,8) == 0){
printf("red off--------------");
GpioSetOutputVal(GREEN_LED_PIN_NAME,LED_DARK);
}else
if(strncmp(RELLOW_ON,response,8) == 0){
printf("red on----------------");
GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_BRIGHT);
}
else if(strncmp(RELLOW_OFF,response,9) == 0){
printf("red off--------------");
GpioSetOutputVal(RELLOW_LED_PIN_NAME,LED_DARK);
}else
{
printf("error index");
}
上述所有源码见附件,有什么问题欢迎留言交流。
PS:分享一个调试中困扰了我好长时间的一个问题,就是在调试过程中 Hi3861 的无线很不稳定,连接上一会儿就会掉,然后又连接,我一度以为是代码的问题,苦苦探求,之后才发现问题的根源是我公司的同时使用的 wifi 太多了,把无线信道都占了,导致我使用的只支持 2.4G 的小破路由器根本不稳定,给大家分享这个坑,遇到的话直接跳过去,别重蹈我的覆辙了......

专注开源技术,共建鸿蒙生态

点“阅读原文”了解更多




