diff --git a/figures/hw_iot_link.png b/figures/hw_iot_link.png new file mode 100755 index 0000000000000000000000000000000000000000..72082ca40b97d4437b58ff8a815c50b8817c8482 Binary files /dev/null and b/figures/hw_iot_link.png differ diff --git a/hwiotlink_example/BUILD.gn b/hwiotlink_example/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..ceb66ad41da29db866a66bcdd886209b0b2c66dc --- /dev/null +++ b/hwiotlink_example/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2021-2022 Talkweb 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 = [ + "hwiotlinktest.c", + # "wifi_connect.c", + ] + + include_dirs = [ + #"//foundation/communication/wifi_lite/interfaces/wifiservice", + #"//device/board/talkweb/niobeu4/sdk/drivers/wifi", + #"//device/soc/espressif/components/lwip/lwip/src/include/", + "//third_party/iotlink/oc/oc_mqtt/oc_mqtt_al", + "//third_party/iotlink/oc/oc_mqtt/oc_mqtt_profile_v5", + "//third_party/iotlink/inc", + "//third_party/iotlink/os/osal", + "//third_party/iotlink/os/ohos", + #"include", + "//third_party/hwcloud_iotlink/hwcloud_iotlink_config", + "//third_party/hwcloud_iotlink/queue", + "//third_party/hwcloud_iotlink/link_misc", + "//third_party/cJSON", + ] + deps = [ + "//third_party/iotlink:hwcloud_iotlink" + ] +} diff --git a/hwiotlink_example/README_zh.md b/hwiotlink_example/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..6608a9225f82fa2b4c18a53d9ae61237890d9071 --- /dev/null +++ b/hwiotlink_example/README_zh.md @@ -0,0 +1,487 @@ +# TWLink组件使用说明 + +# 简述 + +TWLink是模组统一连接拓维IoT平台的组件,该组件是一个全局统一的MQTTClient库,使用OpenHarmony SA机制作为原子化共性启动服务,整个系统中只存在一个,对上层应用提供统一的LPC通讯方式与拓维IoT平台进行交互,上层应用只要关注业务实现,不再关注与平台对接细节。 + +TWLink组件依deviceauth组件,twlink服务由deviceauth组件拉起。 + +# TWLink组件配置说明 + +niobeu4的TWLink组件可通过内核配置进行选配,操作如下: + +1. 切换到kernel/liteos_m/目录 + + ``` + cd kernel/liteos_m/ + ``` + +2. 输入make menuconfig 打开内核配置界面 + + ``` + make menuconfig + ``` + + 弹出配置界面,选择Platform下的select board niobeu4。 + + ![image-20220216150938794](figures/1.png) + +3. 选配上红色框内的组件,选配了该组件系统才会开启设备鉴权功能。 + + ![image-20220304170529872](figures/2.png) + +TWLink组件需要依赖设备鉴权组件来提供三元组信息,因此选择TWLink组件时,设备鉴权组件也会自动选配上。 + +## 组件接口说明 + +SetTWClientConfig + +功能:在应用层配置连接参数 + +``` +typedef struct +{ + const char Host[20]; // 服务器IP + const int Port; // 服务器连接端口 + const char UserName[32]; // 用户名 + const char PassWord[32]; // 连接密码 + const char ClientId[32]; // 连接客户端标示 + const char IoTProductKey[32]; //平台三元组--产品型号 + const char IoTDeviceName[32]; //平台三元组 -- 设备名称 + const char IoTDeviceSecret[32]; //平台三元组 设备连接秘钥 +} TWLinkParam; + +``` + +测例: + +``` +static void *MainTask(const char *arg) +{ + (void)arg; + WifiConnect("aaa", "talkweb1996"); + + TWLinkParam param = { + .Host = "116.63.137.223", + .Port = 1883, + .UserName = "", + .PassWord = "", + .ClientId = "talkweb_test", + .IoTDeviceName = "niobeu4", + .IoTDeviceSecret = "5348de753199dded", + .IoTProductKey = "L0rzgyzyy"}; + + SetTWClientConfig(¶m); +} +``` + +ConnectionedNotification + +功能:重新连接服务器回调接口 + +``` +/* + Description: + 重新连接服务器回调事件, 可能是客户端自己没有网络,也可能是服务器端关闭了 + + Parameter: + + Return Value: + NA +*/ +typedef void (*ConnectionedNotificationCallback)(); + +/* + Description: + 注册联网处理回调. + + Parameter: + ConnectionedNotificationCallback -- onConnectioned Server callback + + Return Value: +*/ +void ConnectionedNotification(ConnectionedNotificationCallback callback); + +``` + +测例: + +``` +static void OnConnectionedCallback() +{ + printf("[Application][TaskID:%p][OnConnectionedCallback]!\n", + osThreadGetId()); +} +// 注册联网回调 +ConnectionedNotification(OnConnectionedCallback); + +``` + +DisConnectionNotification + +功能:客户端断网或者服务器连接不上、服务器重启的时候触发 + +``` +/* + Description: + 离线回调事件, 可能是客户端自己没有网络,也可能是服务器端关闭了 + + Parameter: + + Return Value: + NA +*/ +typedef void (*DisConnectionNotificationCallback)(); + +/* + Description: + 注册离线处理回调. + + Parameter: + DisConnectionNotificationCallback -- onDisConnection Server callback + Return Value: +*/ +void DisConnectionNotification(DisConnectionNotificationCallback callback); +``` + +测例: + +``` +static void OnDisConnectionLineCallback() +{ + printf("[Application][TaskID:%p][OnDisConnectionLineCallback]!\n", + osThreadGetId()); +} +// 注册离线回调 +DisConnectionNotification(OnDisConnectionLineCallback); +``` + +SubscribeMQTTTopic + +功能:订阅主题 + +``` +/* + Description: + 订阅主题. + + Parameter: + sub_topic -- subscribe topic name of MQTT + MQTT_MESSAGE_QOS --mqtt qos + PMQTTMessageCallback -- message callback + + Return Value: + 0 -- Success + other -- Failure +*/ +int32 SubscribeMQTTTopicQOS(const char *sub_topic,MQTT_MESSAGE_QOS qos,PMQTTMessageCallback callback); +``` + +测例: + +``` +static void UserTopicCallback(char *ptopic, char *pdata) +{ + const char *rtopic = (const char *)ptopic; + const char *rdata = (const char *)pdata; + printf("[Application][TaskID:%p][UserTopicCallback][Topic:%s] : %s !\n", + osThreadGetId(), rtopic, pdata); +} + +SubscribeMQTTTopic("aaa",QOS2, UserTopicCallback); +``` + +UnSubscribeMQTTTopic + +功能:取消订阅主题 + +``` +/* + Description: + 取消订阅主题. + + Parameter: + topic -- unsubscribe topic name of MQTT + Return Value: + 0 -- Success + other -- Failure +*/ +int32 UnSubscribeMQTTTopic(const char *topic); +``` + +测例: + +``` +UnSubscribeMQTTTopic("aaa"); // 取消订阅主题aaa +``` + +PushMQTTMessage + +功能: 发送MQTT消息, + +``` +typedef enum +{ + QOS0 = 0, + QOS1 = 1, + QOS2 = 2, +} MQTT_MESSAGE_QOS; + +/* + Description: + 向某个主题发送信息. + + Parameter: + topic -- subscribe topic name of MQTT + MQTT_MESSAGE_QOS qos + topic -- MQTT message , The Message Max Size 2048 bytes + Return Value: + 0 -- Success + other -- Failure +*/ +int32 PushMQTTMessageQOS(char *topic, const char *message, MQTT_MESSAGE_QOS qos); +``` + +测例 : + +``` +PushMQTTMessage("aaa", "3333333"); +``` + +TwlinkIsConnected + +功能:读取twlink链接状态 + +## 测试 + +niobeu4的TWLink的测试可以通过内核核配置打开,操作如下: + +1. 切换到kernel/liteos_m/目录 + + ``` + cd kernel/liteos_m/ + ``` + +2. 输入make menuconfig 打开内核配置界面 + + ``` + make menuconfig + ``` + + 弹出配置界面,选择Platform下的select board niobeu4。 + + ![image-20220216150938794](figures/1.png) + +3. 选配application中的twlink example。 + + ![image-20220304164423511](figures/3.png) + +测例: + +``` +/* + * Copyright (c) 2021-2022 Talkweb 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 +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "mqtt_proxy.h" +#include "string.h" +#include "ohos_run.h" +#include "wifi_device.h" +#include "wifi.h" + +static uint32 pubCount = 0; +static uint32 subCount = 0; +// 自定义主题回调处理 +static void UserTopicCallback(char *ptopic, char *pdata) +{ + const char *rtopic = (const char *)ptopic; + const char *rdata = (const char *)pdata; + + subCount++; + printf("[Application]: %d, %s %s !\n", + strlen(rdata), rtopic, pdata); +} + + +static void OnConnectionedCallback() +{ + // 注册主题, 注意: 平台限制主题注册格式, + SubscribeMQTTTopicQOS("tlink/${productKey}/${deviceName}/event/propertyReport/post", QOS2,UserTopicCallback); + SubscribeMQTTTopicQOS("tlink/${productKey}/${deviceName}/command/setProperty/exec",QOS2, UserTopicCallback); + SubscribeMQTTTopicQOS("tlink/${productKey}/${deviceName}/ota/device/upgrade", QOS0,UserTopicCallback); + printf("OnConnectionedCallback test\n"); +} + +// 系统离线回调 +static void OnDisConnectionCallback() +{ + printf("OnDisConnectionCallback test\n"); +} + +static void *MainTask(const char *arg) +{ + (void)arg; + + DeviceAutoInit(); /*设备鉴权,获取三元组*/ + printf("twlink test!!!!\r\n"); + /*等待twlink连接云*/ + while(!TwlinkIsConnected()) + { + LOS_TaskDelay(100) ; + } + + ConnectionedNotification(OnConnectionedCallback); + // 注册离线回调 + DisConnectionNotification(OnDisConnectionCallback); + OnConnectionedCallback(); + + int step = 0; + int ret = -1, + ret1 = -1; + // 不让程序退出 + while (1) + { + LOS_TaskDelay(100); + ret = PushMQTTMessageQOS("tlink/${productKey}/${deviceName}/event/propertyReport/post","talkweb_twlinksdk test111>>>>>> !!!", QOS2); + if(ret == 0) + pubCount++; + ret1 = PushMQTTMessageQOS("tlink/${productKey}/${deviceName}/command/setProperty/exec","talkweb_twlinksdk test2222>>>>>> !!!", QOS2); + if(ret1 == 0 ) + pubCount++; + printf("subCount:%ld pubCount:%ld \r\n",subCount,pubCount); + } +} +static int testflag = 0; +static void MainEntry(void) +{ + osThreadAttr_t attr; + attr.name = "MainEntry"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = 4096 * 3; + attr.priority = osPriorityNormal; + + if (osThreadNew((osThreadFunc_t)MainTask, NULL, &attr) == NULL) + { + printf("[MainTask] Falied to create MainTask!\n"); + } + +} + +void twlink_example(void) +{ + //连接Wifi + WifiErrorCode error = EnableWifi(); + printf("EnableWifi errCode: %d\r\n", error); + if (error != WIFI_SUCCESS) { + return; + } + + error = Scan(); + printf("ScanWifi errCode: %d\r\n", error); + if (error != WIFI_SUCCESS) { + return; + } + OnWifiConnectDevice("HUAWEIP40","houpengfei8"); + printf("GetWifiConnectStatus: %d\r\n", GetWifiConnectStatus()); + + while(!GetWifiConnectStatus()) + { + LOS_TaskDelay(1000); + } + + MainEntry(); + +} +OHOS_APP_RUN(twlink_example); + +``` + +BUILD.gn + +``` +import("//kernel/liteos_m/liteos.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ + "twlinktest.c", + ] + + include_dirs = [ + "//device/board/talkweb/components/tlinksdk/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//device/soc/espressif/esp32/liteos_m/drivers/wifi", + ] +} +``` + +TWLink测试运行结果如下: + +设备鉴权成功: + +``` +device auth success !,ret is 0 +``` + +twlink + +``` +[TWMQTTInit]: MQTT_Init is 1073220968 +121.37.143.77 10003 +mqtt_connection_cb: Successfully connected +RegisterOfflineNotificationHandler +RegisterDisConnectionNotificationHandler +OnConnectionedCallback test +Subscribe result: 0 +Subscribe result: 0 +Subscribe result: 0 +subCount:0 pubCount:2 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:2 pubCount:4 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:4 pubCount:6 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:6 pubCount:8 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:8 pubCount:10 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:10 pubCount:12 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:12 pubCount:14 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:14 pubCount:16 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:16 pubCount:18 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +subCount:18 pubCount:20 +[Application]: 36, tlink/k0bvhXvUX/T13o0poxp/event/propertyReport/post talkweb_twlinksdk test111>>>>>> !!! ! +[Application]: 37, tlink/k0bvhXvUX/T13o0poxp/command/setProperty/exec talkweb_twlinksdk test2222>>>>>> !!! ! +``` + diff --git a/hwiotlink_example/deviceauth-zh.md b/hwiotlink_example/deviceauth-zh.md new file mode 100755 index 0000000000000000000000000000000000000000..baf4fe3bdc7ec8db947195c2c51b9c4529847204 --- /dev/null +++ b/hwiotlink_example/deviceauth-zh.md @@ -0,0 +1,151 @@ +# 设备鉴权模块使用说明 + +# 简述 + +设备鉴权组件实现设备与云平台的一型一密认证。 组件工作的前提条件是设备必须连上可用网络。当设备连接到网络之后,鉴权服务通过http动态从云平台获取设备三元组信息(ProductKey、DeviceName、DeviceSecret),存储三元组信息到设备flash,拉起Tlink服务。 + +# 设备鉴权模块使用说明 + +niobeu4的设备鉴权组件可通过内核配置进行选配,操作如下: + +1. 切换到kernel/liteos_m/目录 + + ``` + cd kernel/liteos_m/ + ``` + +2. 输入make menuconfig 打开内核配置界面 + + ``` + make menuconfig + ``` + + 弹出配置界面,选择Platform下的select board niobeu4。 + +![image-20220215170753727](figures/1.png) + +选配上红色框内的组件,选配了该组件系统才会开启设备鉴权功能。 + +设备鉴权组件获取三元组信息需要使用到设备的ProductKey和ProductSecret,可以在vendor\talkweb\niobeu4\hals\utils\token\hal_token.c中修改这两个参数: + +``` +/*productkey adn ProductSecret*/ +static char ProductSecret[] = {"ec76e4a427446224"}; +static char ProductKey[] = {"k0bvhXvUX"}; // ProductKey by OEM. +``` + +这两个参数由云平台提供。 + +![](figures/4.png) + +## API + +``` +/* + Description: + 启动DeviceAuth服务. + + Parameter: + + Return Value: +*/ +void DeviceAutoInit(); /*启动设备鉴权*/ +``` + +## 组件功能说明 + +设备鉴权组件实现以下功能: + +1. 从云平台动态获取三元组信息,获取到的元组信息存储在nvs里 +2. 设备鉴权成功拉起twlink服务。 + +## 测试结果 + +选配设备鉴权组件后,选配twlink的测试代码,通过http自动获取三元组,测试如下: + +``` +httpclient_conn() result:0, client:0x2001c86c +request header is POST /gateway/twiot-device-server/device/registerAndExtras HTTP/1.1 +User-Agent: OneOS-HTTP-Client/1.0 +Cache-Control: no-cache +Host: iot.devcloud.talkweb.com.cn + +Trying to write 219 bytes http header:POST /gateway/twiot-device-server/device/registerAndExtras HTTP/1.1 +User-Agent: OneOS-HTTP-Client/1.0 +Cache-Control: no-cache +Host: iot.devcloud.talkweb.com.cn +Content-Length: 149 +Content-Type: application/json + + +http tcp send wrapper buffer is POST /gateway/twiot-device-server/device/registerAndExtras HTTP/1.1 +User-Agent: OneOS-HTTP-Client/1.0 +Cache-Control: no-cache +Host: iot.devcloud.talkweb.com.cn +Content-Length: 149 +Content-Type: application/json + + +Written 219 bytes, socket = 10 +client_data->post_buf:{ + "productKey": "k0bvhXvUX", + "deviceName": "d234f86a137e", + "timestamp": 0, + "sign": "94b08aa21897d2f85d9605e33bb92682", + "signMethod": "hmacmd5" +} +Written 149 bytes +httpclient_send() result:0, client:0x2001c86c +select return 0 may disconnected +reclen:450, buf:HTTP/1.1 200 OK +Date: Thu, 17 Feb 2022 06:38:33 GMT +Content-Type: application/json;charset=UTF-8 +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +bodyLength: 199 +Server: elb + +e8 +{"code":{"code":"0","msg":"success","ok":true},"result":{"isPreRegister":"1","deviceSecret":"1ee8385ff16c419b","mqttIp":"121.37.143.77","productTanentId":"T0001","productKey":"k0bvhXvUX","deviceName":"U1yK0RKtR","mqttPort":"10003"}} +0 + + +Read header : Date: Thu, 17 Feb 2022 06:38:33 GMT +Read header : Content-Type: application/json;charset=UTF-8 +Read header : Transfer-Encoding: chunked +Read header : Connection: keep-alive +Read header : Vary: Accept-Encoding +Read header : bodyLength: 199 +Read header : Server: elb +in loop http_client_retrieve_content 644 len 243 ret 0 +Retrieving 232 bytes, len:239 +readLen 232, len:239 +memmove 232 239 0 +in loop http_client_retrieve_content 644 len 5 ret 0 +no more (last chunk) +httpclient_recv_data() result:0, client:0x2001c86c +No form data info found +httpclient_close() client:0x2001c86c +TWWriteLinkParam ready to write twlink.cfg +device auth success !,ret is 0 + +``` + +出现device auth success !,表示设备鉴权成功 + +获取三元组成功后,再次上电将直接使用上次保持的三元组信息,不再通过http获取。 + +``` +device auth success !,ret is 0 +[TWMQTTInit]: MQTT_Init is 536929676 +121.37.143.77 10003 +mqtt_connection_cb: Successfully connected +RegisterOfflineNotificationHandler +RegisterDisConnectionNotificationHandler +OnConnectionedCallback test +Subscribe result: 0 +Subscribe result: 0 +Subscribe result: 0 +``` + diff --git a/hwiotlink_example/figures/1.png b/hwiotlink_example/figures/1.png new file mode 100755 index 0000000000000000000000000000000000000000..d3f5554a4e8ad5ac210fc78df4675612a46d811b Binary files /dev/null and b/hwiotlink_example/figures/1.png differ diff --git a/hwiotlink_example/figures/2.png b/hwiotlink_example/figures/2.png new file mode 100755 index 0000000000000000000000000000000000000000..04591a556c5787a2253b7283884512e71d744d12 Binary files /dev/null and b/hwiotlink_example/figures/2.png differ diff --git a/hwiotlink_example/figures/3.png b/hwiotlink_example/figures/3.png new file mode 100755 index 0000000000000000000000000000000000000000..77c5b3512cc8c3ea0dbcf6265118b0ea988840e6 Binary files /dev/null and b/hwiotlink_example/figures/3.png differ diff --git a/hwiotlink_example/figures/4.png b/hwiotlink_example/figures/4.png new file mode 100755 index 0000000000000000000000000000000000000000..f5b932137fdc5b796b19ff3efea21f423816d076 Binary files /dev/null and b/hwiotlink_example/figures/4.png differ diff --git a/hwiotlink_example/hwiotlinktest.c b/hwiotlink_example/hwiotlinktest.c new file mode 100755 index 0000000000000000000000000000000000000000..76af7b526c45b549eb5112165ebd0f0222d47103 --- /dev/null +++ b/hwiotlink_example/hwiotlinktest.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2021-2022 Talkweb 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 +#include +#include +#include +#include "cmsis_os2.h" +#include "ohos_init.h" + +#include +#include +#include +#include +#include "ohos_run.h" +#include "app_ethernet.h" + + +#define CONFIG_APP_SERVERIP "121.36.42.100" +#define CONFIG_APP_DEVICEID "62294fb0c4e6a958e3560e16_12345678" // 替换为注册设备后生成的deviceid +#define CONFIG_APP_DEVICEPWD "12345678" // 替换为注册设备后生成的密钥 +#define CONFIG_APP_LIFETIME 60 // seconds +#define CONFIG_QUEUE_TIMEOUT (5 * 1000) +#define MSGQUEUE_COUNT 5 //16 +#define MSGQUEUE_SIZE 10 + +#ifdef DEMO_TLS +#define CONFIG_APP_SERVERPORT "8883" +#define CN_SECURITY_TYPE EN_DTLS_AL_SECURITY_TYPE_CERT +#else +#define CONFIG_APP_SERVERPORT "1883" +#define CN_SECURITY_TYPE EN_DTLS_AL_SECURITY_TYPE_NONE +#endif + +osMessageQueueId_t mid_MsgQueue; // message queue id +typedef enum { + en_msg_cmd = 0, + en_msg_report, + en_msg_conn, + en_msg_disconn, +} en_msg_type_t; + +typedef struct { + char* request_id; + char* payload; +} cmd_t; + +typedef struct { + int lum; + int temp; + int hum; +} report_t; + +typedef struct { + en_msg_type_t msg_type; + union { + cmd_t cmd; + report_t report; + } msg; +} app_msg_t; + +typedef struct { + osMessageQueueId_t app_msg; + int connected; + int led; + int motor; +} app_cb_t; +static app_cb_t g_app_cb; + +static void deal_report_msg(report_t* report) +{ + oc_mqtt_profile_service_t service; + oc_mqtt_profile_kv_t temperature; + oc_mqtt_profile_kv_t humidity; + oc_mqtt_profile_kv_t luminance; + oc_mqtt_profile_kv_t led; + oc_mqtt_profile_kv_t motor; + + if (g_app_cb.connected != 1) { + return; + } + + service.event_time = NULL; + service.service_id = "Agriculture"; + service.service_property = &temperature; + service.nxt = NULL; + + temperature.key = "Temperature"; + temperature.value = &report->temp; + temperature.type = EN_OC_MQTT_PROFILE_VALUE_INT; + temperature.nxt = &humidity; + + humidity.key = "Humidity"; + humidity.value = &report->hum; + humidity.type = EN_OC_MQTT_PROFILE_VALUE_INT; + humidity.nxt = &luminance; + + luminance.key = "Luminance"; + luminance.value = &report->lum; + luminance.type = EN_OC_MQTT_PROFILE_VALUE_INT; + luminance.nxt = &led; + + led.key = "LightStatus"; + led.value = g_app_cb.led ? "ON" : "OFF"; + led.type = EN_OC_MQTT_PROFILE_VALUE_STRING; + led.nxt = &motor; + + motor.key = "MotorStatus"; + motor.value = g_app_cb.motor ? "ON" : "OFF"; + motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING; + motor.nxt = NULL; + + oc_mqtt_profile_propertyreport(NULL, &service); + return; +} + +// use this function to push all the message to the buffer +static int msg_rcv_callback(oc_mqtt_profile_msgrcv_t* msg) +{ + int ret = 0; + char* buf; + int buf_len; + app_msg_t* app_msg; + + if ((msg == NULL) || (msg->request_id == NULL) || (msg->type != EN_OC_MQTT_PROFILE_MSG_TYPE_DOWN_COMMANDS)) { + return ret; + } + + buf_len = sizeof(app_msg_t) + strlen(msg->request_id) + 1 + msg->msg_len + 1; + buf = malloc(buf_len); + if (buf == NULL) { + printf("%s %d\r\n",__func__,__LINE__); + return ret; + } + app_msg = (app_msg_t*)buf; + buf += sizeof(app_msg_t); + + app_msg->msg_type = en_msg_cmd; + app_msg->msg.cmd.request_id = buf; + buf_len = strlen(msg->request_id); + buf += buf_len + 1; + memcpy_s(app_msg->msg.cmd.request_id, buf_len, msg->request_id, buf_len); + app_msg->msg.cmd.request_id[buf_len] = '\0'; + + buf_len = msg->msg_len; + app_msg->msg.cmd.payload = buf; + memcpy_s(app_msg->msg.cmd.payload, buf_len, msg->msg, buf_len); + app_msg->msg.cmd.payload[buf_len] = '\0'; + + printf("%s %d %d %s\r\n",__func__,app_msg->msg_type,msg->msg_len,app_msg->msg.cmd.payload); + ret = osMessageQueuePut(g_app_cb.app_msg, &app_msg, 0U, CONFIG_QUEUE_TIMEOUT); + if (ret != 0) { + printf("%s %d\r\n",__func__,__LINE__); + free(app_msg); + } + printf("%s %d\r\n",__func__,__LINE__); + return ret; +} + +static void oc_cmdresp(cmd_t* cmd, int cmdret) +{ + oc_mqtt_profile_cmdresp_t cmdresp; + ///< do the response + cmdresp.paras = NULL; + cmdresp.request_id = cmd->request_id; + cmdresp.ret_code = cmdret; + cmdresp.ret_name = NULL; + printf("%s %d\r\n",__func__,__LINE__); + (void)oc_mqtt_profile_cmdresp(NULL, &cmdresp); +} + +///< COMMAND DEAL +#include +static void deal_cmd_msg(cmd_t* cmd) +{ + cJSON* obj_root; + cJSON* obj_cmdname; + + int cmdret = 1; + obj_root = cJSON_Parse(cmd->payload); + if (obj_root == NULL) { + oc_cmdresp(cmd, cmdret); + } + obj_cmdname = cJSON_GetObjectItem(obj_root, "command_name"); + if (obj_cmdname == NULL) { + cJSON_Delete(obj_root); + } + oc_cmdresp(cmd, cmdret); + return; +} +static int MQTT_RUN_FLAG = 0; +static int CloudMainTaskEntry(void) +{ + app_msg_t* app_msg; + uint32_t ret; + + g_app_cb.app_msg = osMessageQueueNew(MSGQUEUE_COUNT, MSGQUEUE_SIZE, NULL); + if (g_app_cb.app_msg == NULL) { + printf("Create receive msg queue failed"); + } + oc_mqtt_profile_connect_t connect_para; + (void)memset_s(&connect_para, sizeof(connect_para), 0, sizeof(connect_para)); + + connect_para.boostrap = 0; + connect_para.device_id = CONFIG_APP_DEVICEID; + connect_para.device_passwd = CONFIG_APP_DEVICEPWD; + connect_para.server_addr = CONFIG_APP_SERVERIP; + connect_para.server_port = CONFIG_APP_SERVERPORT; + connect_para.life_time = CONFIG_APP_LIFETIME; + connect_para.rcvfunc = msg_rcv_callback; + connect_para.security.type = CN_SECURITY_TYPE; + + ret = oc_mqtt_profile_connect(&connect_para); + printf("ret = %u\n", ret); + if ((ret == (int)en_oc_mqtt_err_ok)) { + g_app_cb.connected = 1; + printf("oc_mqtt_profile_connect succed!\r\n"); + } else { + printf("oc_mqtt_profile_connect faild!\r\n"); + } + while (1) { + app_msg = NULL; + (void)osMessageQueueGet(g_app_cb.app_msg, (void**)&app_msg, NULL, 0xFFFFFFFF); + if (app_msg != NULL) { + switch (app_msg->msg_type) { + case en_msg_cmd: + deal_cmd_msg(&app_msg->msg.cmd); + break; + case en_msg_report: + deal_report_msg(&app_msg->msg.report); + break; + default: + break; + } + free(app_msg); + } + LOS_TaskDelay(100); + } + return 0; +} + +static int SensorTaskEntry(void) +{ + app_msg_t* app_msg; + while(!g_app_cb.connected){ + LOS_TaskDelay(100); + } + while (1) { + app_msg = malloc(sizeof(app_msg_t)); + // printf("SENSOR:lum:%.2f temp:%.2f hum:%.2f\r\n", 11.12, 11.14, 11.18); + if (app_msg != NULL) { + app_msg->msg_type = en_msg_report; + app_msg->msg.report.hum = 10;//(int)data.Humidity; + app_msg->msg.report.lum = 12;//(int)data.Lux; + app_msg->msg.report.temp = 18;//(int)data.Temperature; + if (osMessageQueuePut(g_app_cb.app_msg, &app_msg, 0U, CONFIG_QUEUE_TIMEOUT != 0)) { + free(app_msg); + } + } + LOS_TaskDelay(200); + } + return 0; +} + +static void IotMainTaskEntry(void) +{ + link_main_task_entry(); + (void) osal_task_create("CloudMainTaskEntry",CloudMainTaskEntry,NULL,0x1000,NULL,22); + (void) osal_task_create("SensorTaskEntry",SensorTaskEntry,NULL,0x1000,NULL,23); +} + +static int twlink_run_flag = 0; +static void eth_enable_state_callBack(EthLinkState state) +{ + /* ETH连接断开*/ + if(state == STATE_UPDATE_LINK_DOWN){ + printf("ETH LINK STATE: DisConnected!\r\n"); + } + /* ETH连接成功*/ + else if(state == STATE_UPDATE_LINK_UP){ + printf("ETH LINK STATE: Connected!\r\n"); + if(!twlink_run_flag){ + twlink_run_flag++; + IotMainTaskEntry(); + } + } +} + +void iotlink_example(void) +{ + ethernet_enable(eth_enable_state_callBack); //有线网络使能 +} +OHOS_APP_RUN(iotlink_example); diff --git a/hwiotlink_example/wifi_connect.c b/hwiotlink_example/wifi_connect.c new file mode 100755 index 0000000000000000000000000000000000000000..a127446033ef0a4c5e55ab35c3d748302f313dde --- /dev/null +++ b/hwiotlink_example/wifi_connect.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2021-2022 Talkweb 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 +#include +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "lwip/netif.h" +#include "lwip/netifapi.h" +#include "lwip/ip4_addr.h" +#include "wifi_device.h" + +#define DEF_TIMEOUT 15 +#define ONE_SECOND 1 + +#define SELECT_WLAN_PORT "wlan0" +#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_PSK + +static int g_staScanSuccess = 0; +static int g_ConnectSuccess = 0; +static int ssid_count = 0; + +WifiErrorCode error; +WifiEvent g_wifiEventHandler = {0}; + +int sock_fd; +int addr_length; + +#define STD_TIMEZONE_OFFSET +8 +const int timeZone = 8; + + +static void WiFiInit(void); +static void WaitSacnResult(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; + error = RegisterWifiEvent(&g_wifiEventHandler); + if (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(200); + printf("<--System Init-->\r\n"); + + //wifi init + WiFiInit(); + + if (EnableWifi() != WIFI_SUCCESS) + { + printf("EnableWifi failed, error = %d\n", error); + return -1; + } + + //check wifi + if (IsWifiActive() == 0) + { + printf("Wifi station is not actived.\n"); + return -1; + } + + //malloc mem,store wifiscaninfo + 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; + //start scan + Scan(); + WaitSacnResult(); + //get scan result + error = GetScanInfoList(info, &size); + } while (g_staScanSuccess != 1); + + strcpy(select_ap_config.ssid, ssid); + strcpy(select_ap_config.preSharedKey, psk); + 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"); + } + } + osDelay(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 + { + printf("connect error,please check password,state:%d,tyr connect again\r\n",state); + esp_wifi_connect(); + } + return; +} + +static void WaitSacnResult(void) +{ + int scanTimeout = DEF_TIMEOUT; + while (scanTimeout > 0) + { + sleep(ONE_SECOND); + scanTimeout--; + if (g_staScanSuccess == 1) + { + printf("WaitSacnResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout)); + break; + } + } + if (scanTimeout <= 0) + { + printf("WaitSacnResult:timeout!\n"); + } +} \ No newline at end of file