merge new qcloud sdk
1. qcloud has a great revolution, the protocol has been changed to implement data template, so the old TencentCloud_SDK developed by us will not work fine now(mqtt still works, but data template will not works fine for recently created product/devices). 2. I merge the official qlcoud sdk(include both the iot-hub and iot-explorer sdk) into the componet/conectivity to support new protocol of data template 3. iot-hub sdk, supply the fundamental iot protocol(like mqtt coap, etc.) iot-explorer sdk, supply the high level service like data template based on mqtt 4. To know how it works, see qcloud_iot_explorer_sdk_data_template、qcloud_iot_hub_sdk_mqtt example(keil project in board\TencentOS_tiny_EVB_MX_Plus\KEIL\qcloud_iot_explorer_sdk_data_template and board\TencentOS_tiny_EVB_MX_Plus\KEIL\qcloud_iot_hub_sdk_mqtt)
This commit is contained in:
101
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/CMakeLists.txt
vendored
Normal file
101
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
set(INC_DIR ${PROJECT_SOURCE_DIR}/output/${BUILD_TYPE}/include)
|
||||
set(LINK_DIR ${PROJECT_SOURCE_DIR}/output/${BUILD_TYPE}/lib/)
|
||||
include_directories(${INC_DIR})
|
||||
link_directories(${LINK_DIR})
|
||||
|
||||
if(FEATURE_AUTH_WITH_NOTLS)
|
||||
set(link_lib
|
||||
iot_sdk
|
||||
iot_platform
|
||||
)
|
||||
else()
|
||||
set(link_lib
|
||||
iot_sdk
|
||||
iot_platform
|
||||
mbedtls
|
||||
mbedx509
|
||||
mbedcrypto
|
||||
)
|
||||
endif()
|
||||
|
||||
if (PLATFORM STREQUAL "linux" AND COMPILE_TOOLS STREQUAL "gcc")
|
||||
set(lib -Wl,--start-group ${link_lib} -Wl,--end-group)
|
||||
elseif (PLATFORM STREQUAL "windows" AND COMPILE_TOOLS STREQUAL "MSVC")
|
||||
set(lib ${link_lib})
|
||||
endif()
|
||||
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/output/${BUILD_TYPE}/bin)
|
||||
|
||||
# MQTT
|
||||
if(${FEATURE_MQTT_COMM_ENABLED} STREQUAL "ON")
|
||||
file(GLOB src_mqtt_sample ${PROJECT_SOURCE_DIR}/samples/mqtt/mqtt_sample.c)
|
||||
add_executable(mqtt_sample ${src_mqtt_sample})
|
||||
target_link_libraries(mqtt_sample ${lib})
|
||||
|
||||
file(GLOB src_door_mqtt_sample ${PROJECT_SOURCE_DIR}/samples/scenarized/door_mqtt_sample.c)
|
||||
add_executable(door_mqtt_sample ${src_door_mqtt_sample})
|
||||
target_link_libraries(door_mqtt_sample ${lib})
|
||||
endif()
|
||||
|
||||
if (PLATFORM STREQUAL "linux" AND COMPILE_TOOLS STREQUAL "gcc")
|
||||
file(GLOB src_multi_thread_mqtt_sample ${PROJECT_SOURCE_DIR}/samples/mqtt/multi_thread_mqtt_sample.c)
|
||||
add_executable(multi_thread_mqtt_sample ${src_multi_thread_mqtt_sample})
|
||||
target_link_libraries(multi_thread_mqtt_sample ${lib})
|
||||
endif()
|
||||
|
||||
|
||||
# DYN_REG
|
||||
if(${FEATURE_DEV_DYN_REG_ENABLED} STREQUAL "ON")
|
||||
file(GLOB src_dynreg_dev_sample ${PROJECT_SOURCE_DIR}/samples/dynreg_dev/dynreg_dev_sample.c)
|
||||
add_executable(dynreg_dev_sample ${src_dynreg_dev_sample})
|
||||
target_link_libraries(dynreg_dev_sample ${lib})
|
||||
endif()
|
||||
|
||||
# OTA MQTT
|
||||
if(${FEATURE_OTA_COMM_ENABLED} STREQUAL "ON" AND ${FEATURE_OTA_SIGNAL_CHANNEL} STREQUAL "MQTT")
|
||||
file(GLOB src_ota_mqtt_sample ${PROJECT_SOURCE_DIR}/samples/ota/ota_mqtt_sample.c)
|
||||
add_executable(ota_mqtt_sample ${src_ota_mqtt_sample})
|
||||
target_link_libraries(ota_mqtt_sample ${lib})
|
||||
endif()
|
||||
|
||||
# SHADOW
|
||||
if(${FEATURE_MQTT_DEVICE_SHADOW} STREQUAL "ON")
|
||||
file(GLOB src_shadow_sample ${PROJECT_SOURCE_DIR}/samples/shadow/shadow_sample.c)
|
||||
add_executable(shadow_sample ${src_shadow_sample})
|
||||
target_link_libraries(shadow_sample ${lib})
|
||||
|
||||
file(GLOB src_aircond_shadow_sample ${PROJECT_SOURCE_DIR}/samples/scenarized/aircond_shadow_sample.c)
|
||||
file(GLOB src_aircond_shadow_sample_v2 ${PROJECT_SOURCE_DIR}/samples/scenarized/aircond_shadow_sample_v2.c)
|
||||
add_executable(aircond_shadow_sample ${src_aircond_shadow_sample})
|
||||
add_executable(aircond_shadow_sample_v2 ${src_aircond_shadow_sample_v2})
|
||||
target_link_libraries(aircond_shadow_sample ${lib})
|
||||
target_link_libraries(aircond_shadow_sample_v2 ${lib})
|
||||
endif()
|
||||
|
||||
|
||||
# GATEWAY
|
||||
if(${FEATURE_GATEWAY_ENABLED} STREQUAL "ON")
|
||||
file(GLOB src_gateway_sample ${PROJECT_SOURCE_DIR}/samples/gateway/gateway_sample.c)
|
||||
add_executable(gateway_sample ${src_gateway_sample})
|
||||
target_link_libraries(gateway_sample ${lib})
|
||||
endif()
|
||||
|
||||
# COAP
|
||||
if(${FEATURE_COAP_COMM_ENABLED} STREQUAL "ON")
|
||||
file(GLOB src_coap_sample ${PROJECT_SOURCE_DIR}/samples/coap/coap_sample.c)
|
||||
add_executable(coap_sample ${src_coap_sample})
|
||||
target_link_libraries(coap_sample ${lib})
|
||||
|
||||
file(GLOB src_door_coap_sample ${PROJECT_SOURCE_DIR}/samples/scenarized/door_coap_sample.c)
|
||||
add_executable(door_coap_sample ${src_door_coap_sample})
|
||||
target_link_libraries(door_coap_sample ${lib})
|
||||
endif()
|
||||
|
||||
|
||||
if(${FEATURE_OTA_COMM_ENABLED} STREQUAL "ON" AND ${FEATURE_OTA_SIGNAL_CHANNEL} STREQUAL "COAP")
|
||||
file(GLOB src_ota_coap_sample ${PROJECT_SOURCE_DIR}/samples/ota/ota_coap_sample.c)
|
||||
add_executable(ota_coap_sample ${src_ota_coap_sample})
|
||||
target_link_libraries(ota_coap_sample ${lib})
|
||||
endif()
|
144
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/Makefile
vendored
Normal file
144
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/Makefile
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
# Basic Settings
|
||||
SHELL := /bin/bash
|
||||
TOP_DIR ?= $(CURDIR)/../
|
||||
SUBDIRS := directory-not-exist-actually
|
||||
|
||||
# Settings of input directory
|
||||
SCRIPT_DIR := $(TOP_DIR)/tools/build_scripts
|
||||
|
||||
include $(TOP_DIR)/make.settings
|
||||
include $(SCRIPT_DIR)/parse_make_settings.mk
|
||||
|
||||
# Makefile echo
|
||||
ifeq ($(DEBUG_MAKEFILE),n)
|
||||
Q := @
|
||||
TOP_Q := @
|
||||
else
|
||||
Q :=
|
||||
TOP_Q :=
|
||||
endif
|
||||
|
||||
# Settings of output directory
|
||||
SAMPLE_DIR := $(CURDIR)
|
||||
FINAL_DIR := $(CURDIR)/../output/$(BUILD_TYPE)
|
||||
|
||||
IOT_LIB_DIR = $(FINAL_DIR)/lib
|
||||
IOT_INC_CFLAGS = -I$(FINAL_DIR)/include -I$(FINAL_DIR)/include/exports
|
||||
|
||||
LDFLAGS := -Wl,--start-group $(IOT_LIB_DIR)/libiot_sdk.a
|
||||
ifeq ($(FEATURE_AUTH_WITH_NOTLS),n)
|
||||
LDFLAGS += $(IOT_LIB_DIR)/libmbedtls.a $(IOT_LIB_DIR)/libmbedx509.a $(IOT_LIB_DIR)/libmbedcrypto.a
|
||||
endif
|
||||
LDFLAGS += $(IOT_LIB_DIR)/libiot_platform.a -Wl,--end-group
|
||||
|
||||
|
||||
CFLAGS += -Wall -Wno-error=sign-compare -Wno-error=format -Os -pthread -DFORCE_SSL_VERIFY
|
||||
CFLAGS += ${IOT_INC_CFLAGS}
|
||||
|
||||
ifeq ($(FEATURE_AUTH_MODE),CERT)
|
||||
CFLAGS += -DAUTH_MODE_CERT
|
||||
endif
|
||||
|
||||
.PHONY: mqtt_sample ota_mqtt_sample ota_coap_sample shadow_sample coap_sample gateway_sample multi_thread_mqtt_sample dynreg_dev_sample
|
||||
|
||||
all: mqtt_sample ota_mqtt_sample ota_coap_sample shadow_sample coap_sample gateway_sample multi_thread_mqtt_sample dynreg_dev_sample
|
||||
|
||||
ifneq (,$(filter -DMQTT_COMM_ENABLED,$(CFLAGS)))
|
||||
mqtt_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/mqtt/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/scenarized/door_$@.c $(LDFLAGS) -o door_$@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv door_$@ $(FINAL_DIR)/bin && \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
|
||||
ifneq (,$(filter -DMULTITHREAD_TEST_ENABLED,$(CFLAGS)))
|
||||
multi_thread_mqtt_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/mqtt/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DDEV_DYN_REG_ENABLED,$(CFLAGS)))
|
||||
dynreg_dev_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/dynreg_dev/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DOTA_COMM_ENABLED,$(CFLAGS)))
|
||||
ifneq (,$(filter -DOTA_MQTT_CHANNEL,$(CFLAGS)))
|
||||
ota_mqtt_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/ota/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DMQTT_DEVICE_SHADOW,$(CFLAGS)))
|
||||
shadow_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/shadow/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/scenarized/aircond_$@.c $(LDFLAGS) -o aircond_$@
|
||||
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/scenarized/aircond_$@_v2.c $(LDFLAGS) -o aircond_$@_v2
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin && \
|
||||
mv aircond_$@ $(FINAL_DIR)/bin && \
|
||||
mv aircond_$@_v2 $(FINAL_DIR)/bin
|
||||
endif
|
||||
|
||||
|
||||
ifneq (,$(filter -DGATEWAY_ENABLED,$(CFLAGS)))
|
||||
gateway_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/gateway/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter -DCOAP_COMM_ENABLED,$(CFLAGS)))
|
||||
coap_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/coap/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/scenarized/door_$@.c $(LDFLAGS) -o door_$@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
|
||||
$(TOP_Q) \
|
||||
mv door_$@ $(FINAL_DIR)/bin
|
||||
|
||||
ifneq (,$(filter -DOTA_COMM_ENABLED,$(CFLAGS)))
|
||||
ifneq (,$(filter -DOTA_COAP_CHANNEL,$(CFLAGS)))
|
||||
ota_coap_sample:
|
||||
$(TOP_Q) \
|
||||
$(PLATFORM_CC) $(CFLAGS) $(SAMPLE_DIR)/ota/$@.c $(LDFLAGS) -o $@
|
||||
|
||||
$(TOP_Q) \
|
||||
mv $@ $(FINAL_DIR)/bin
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf $(FINAL_DIR)/bin/*
|
||||
|
199
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/coap/coap_sample.c
vendored
Normal file
199
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/coap/coap_sample.c
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
void response_message_callback(void* coap_message, void* userContext)
|
||||
{
|
||||
int ret_code = IOT_COAP_GetMessageCode(coap_message);
|
||||
switch (ret_code) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
{
|
||||
char* payload = NULL;
|
||||
int payload_len = 0;
|
||||
int ret = -1;
|
||||
ret = IOT_COAP_GetMessagePayload(coap_message, &payload, &payload_len);
|
||||
if (ret == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("message received response, content: %s", payload);
|
||||
}
|
||||
else {
|
||||
Log_e("message received response, content error.");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void event_handler(void *pcontext, CoAPEventMessage *message)
|
||||
{
|
||||
switch (message->event_type) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
Log_i("message received response, content: %s", IOT_COAP_GetMessageId(message->message));
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
default:
|
||||
Log_e("unrecogonized event type: %d", message->event_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(CoAPInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
initParams->max_retry_count = 3;
|
||||
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
CoAPInitParams init_params = DEFAULT_COAPINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *coap_client = IOT_COAP_Construct(&init_params);
|
||||
if (coap_client == NULL) {
|
||||
Log_e("COAP Client construct failed.");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
do {
|
||||
SendMsgParams send_params = DEFAULT_SENDMSG_PARAMS;
|
||||
send_params.pay_load = "{\"name\":\"hello world\"}";
|
||||
send_params.pay_load_len = strlen("{\"name\":\"hello world\"}");
|
||||
send_params.resp_callback = response_message_callback;
|
||||
|
||||
char topicName[128] = "";
|
||||
sprintf(topicName, "%s/%s/data", sg_devInfo.product_id, sg_devInfo.device_name);
|
||||
Log_i("topic name is %s", topicName);
|
||||
|
||||
rc = IOT_COAP_SendMessage(coap_client, topicName, &send_params);
|
||||
if (rc < 0) {
|
||||
Log_e("client publish topic failed :%d.", rc);
|
||||
}
|
||||
else {
|
||||
Log_d("client topic has been sent, msg_id: %d", rc);
|
||||
}
|
||||
|
||||
if (!(argc >= 2 && !strcmp("loop", argv[1]))) {
|
||||
HAL_SleepMs(1000);
|
||||
}
|
||||
|
||||
rc = IOT_COAP_Yield(coap_client, 200);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS){
|
||||
Log_e("exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (argc >= 2)
|
||||
HAL_SleepMs(1000);
|
||||
|
||||
} while (argc >= 2 && !strcmp("loop", argv[1]));
|
||||
|
||||
IOT_COAP_Destroy(&coap_client);
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
108
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/dynreg_dev/dynreg_dev_sample.c
vendored
Normal file
108
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/dynreg_dev/dynreg_dev_sample.c
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
/* NULL cert file */
|
||||
#define QCLOUD_IOT_NULL_CERT_FILENAME "YOUR_DEVICE_NAME_cert.crt"
|
||||
/* NULL key file */
|
||||
#define QCLOUD_IOT_NULL_KEY_FILENAME "YOUR_DEVICE_NAME_private.key"
|
||||
#else
|
||||
/* NULL device secret */
|
||||
#define QCLOUD_IOT_NULL_DEVICE_SECRET "YOUR_IOT_PSK"
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
while ((c = utils_getopt(argc, argv, "c:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file for DeviceInfo>] \n"
|
||||
, argv[0]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
int ret;
|
||||
DeviceInfo sDevInfo;
|
||||
bool infoNullFlag = false;
|
||||
|
||||
memset((char *)&sDevInfo, 0, sizeof(DeviceInfo));
|
||||
|
||||
ret = HAL_GetDevInfo(&sDevInfo);
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
/* just demo the cert/key files are empty */
|
||||
if(!strcmp(sDevInfo.dev_cert_file_name, QCLOUD_IOT_NULL_CERT_FILENAME)
|
||||
||!strcmp(sDevInfo.dev_key_file_name, QCLOUD_IOT_NULL_KEY_FILENAME)){
|
||||
Log_d("dev Cert not exist!");
|
||||
infoNullFlag = true;
|
||||
}else{
|
||||
Log_d("dev Cert exist");
|
||||
}
|
||||
#else
|
||||
/* just demo the PSK is empty */
|
||||
if(!strcmp(sDevInfo.device_secret, QCLOUD_IOT_NULL_DEVICE_SECRET)){
|
||||
Log_d("dev psk not exist!");
|
||||
infoNullFlag = true;
|
||||
}else{
|
||||
Log_d("dev psk exist");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* device cert/key files or PSK is empty, do dynamic register to fetch */
|
||||
if(infoNullFlag){
|
||||
if(QCLOUD_RET_SUCCESS == IOT_DynReg_Device(&sDevInfo)){
|
||||
ret = HAL_SetDevInfo(&sDevInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
Log_e("devices info save fail");
|
||||
}else{
|
||||
#ifdef AUTH_MODE_CERT
|
||||
Log_d("dynamic register success, productID: %s, devName: %s, CertFile: %s, KeyFile: %s", \
|
||||
sDevInfo.product_id, sDevInfo.device_name, sDevInfo.dev_cert_file_name, sDevInfo.dev_key_file_name);
|
||||
#else
|
||||
Log_d("dynamic register success,productID: %s, devName: %s, device_secret: %s", \
|
||||
sDevInfo.product_id, sDevInfo.device_name, sDevInfo.device_secret);
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
Log_e("%s dynamic register fail", sDevInfo.device_name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
278
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/gateway/gateway_sample.c
vendored
Normal file
278
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/gateway/gateway_sample.c
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC (128)
|
||||
#define MAX_SIZE_OF_DATA (128)
|
||||
|
||||
static int sg_sub_packet_id = -1;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
void _event_handler(void *client, void *context, MQTTEventMsg *msg)
|
||||
{
|
||||
MQTTMessage* mqtt_messge = (MQTTMessage*)msg->msg;
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_RECVEIVED:
|
||||
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
mqtt_messge->topic_len,
|
||||
mqtt_messge->ptopic,
|
||||
mqtt_messge->payload_len,
|
||||
mqtt_messge->payload);
|
||||
break;
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_SUCCESS:
|
||||
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
|
||||
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_NACK:
|
||||
Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _message_handler(void *client, MQTTMessage *message, void *user_data)
|
||||
{
|
||||
if (message == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log_i("Receive Message With topicName:%.*s, payload:%.*s",
|
||||
(int) message->topic_len, message->ptopic, (int) message->payload_len, (char *) message->payload);
|
||||
}
|
||||
|
||||
static int sg_loop_count = 1;
|
||||
static int parse_arguments(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
while ((c = utils_getopt(argc, argv, "c:l:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
sg_loop_count = atoi(utils_optarg);
|
||||
if (sg_loop_count > 10000)
|
||||
sg_loop_count = 10000;
|
||||
else if (sg_loop_count < 0)
|
||||
sg_loop_count = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file for DeviceInfo>] \n"
|
||||
" [-l <loop count>] \n"
|
||||
, argv[0]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = QCLOUD_ERR_FAILURE;
|
||||
void* client = NULL;
|
||||
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
// parse arguments for device info file and loop test;
|
||||
rc = parse_arguments(argc, argv);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("parse arguments error, rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
GatewayDeviceInfo GWdevInfo;
|
||||
rc = HAL_GetGwDevInfo((void *)&GWdevInfo);
|
||||
if(QCLOUD_RET_SUCCESS != rc){
|
||||
Log_e("Get gateway dev info err,rc:%d",rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
GatewayInitParam init_params = DEFAULT_GATEWAY_INIT_PARAMS;
|
||||
init_params.init_param.product_id = GWdevInfo.gw_info.product_id;
|
||||
init_params.init_param.device_name = GWdevInfo.gw_info.device_name;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, GWdevInfo.gw_info.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, GWdevInfo.gw_info.dev_key_file_name);
|
||||
|
||||
init_params.init_param.cert_file = sg_cert_file;
|
||||
init_params.init_param.key_file = sg_key_file;
|
||||
#else
|
||||
init_params.init_param.device_secret = GWdevInfo.gw_info.device_secret;
|
||||
#endif
|
||||
|
||||
init_params.init_param.command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
init_params.init_param.auto_connect_enable = 1;
|
||||
init_params.init_param.event_handle.h_fp = _event_handler;
|
||||
client = IOT_Gateway_Construct(&init_params);
|
||||
if (client == NULL) {
|
||||
Log_e("client constructed failed.");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
// make sub-device online
|
||||
GatewayParam param = DEFAULT_GATEWAY_PARAMS;;
|
||||
param.product_id = GWdevInfo.gw_info.product_id;
|
||||
param.device_name = GWdevInfo.gw_info.device_name;
|
||||
|
||||
DeviceInfo *subDevInfo;
|
||||
subDevInfo = GWdevInfo.sub_dev_info;
|
||||
|
||||
param.subdev_product_id = subDevInfo->product_id;
|
||||
param.subdev_device_name = subDevInfo->device_name;
|
||||
|
||||
rc = IOT_Gateway_Subdev_Online(client, ¶m);
|
||||
if(rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("IOT_Gateway_Subdev_Online fail.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
// subscribe sub-device topic
|
||||
char topic_filter[MAX_SIZE_OF_TOPIC+1] = {0};
|
||||
SubscribeParams sub_param = DEFAULT_SUB_PARAMS;
|
||||
int size = HAL_Snprintf(topic_filter, MAX_SIZE_OF_TOPIC+1, "%s/%s/data", subDevInfo->product_id, subDevInfo->device_name);
|
||||
if (size < 0 || size > MAX_SIZE_OF_TOPIC)
|
||||
{
|
||||
Log_e("buf size < topic length!");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sub_param.on_message_handler = _message_handler;
|
||||
rc = IOT_Gateway_Subscribe(client, topic_filter, &sub_param);
|
||||
if(rc < 0) {
|
||||
Log_e("IOT_Gateway_Subscribe fail.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = IOT_Gateway_Yield(client, 200);
|
||||
|
||||
// publish msg to sub-device topic
|
||||
char topic_name[MAX_SIZE_OF_TOPIC+1] = {0};
|
||||
PublishParams pub_param = DEFAULT_PUB_PARAMS;
|
||||
size = HAL_Snprintf(topic_name, MAX_SIZE_OF_TOPIC+1, "%s/%s/data", subDevInfo->product_id, subDevInfo->device_name);
|
||||
if (size < 0 || size > MAX_SIZE_OF_TOPIC)
|
||||
{
|
||||
Log_e("buf size < topic length!");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
pub_param.qos = QOS1;
|
||||
pub_param.payload = "{\"data\":\"test gateway\"}";
|
||||
pub_param.payload_len = sizeof("{\"data\":\"test gateway\"}");
|
||||
|
||||
do {
|
||||
if(sg_sub_packet_id > 0) {
|
||||
rc = IOT_Gateway_Publish(client, topic_name, &pub_param);
|
||||
if(rc < 0) {
|
||||
Log_e("IOT_Gateway_Publish fail.");
|
||||
}
|
||||
}
|
||||
rc = IOT_Gateway_Yield(client, 200);
|
||||
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED){
|
||||
Log_e("exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_SleepMs(1000);
|
||||
|
||||
} while (--sg_loop_count > 0);
|
||||
|
||||
// make sub-device offline
|
||||
rc = IOT_Gateway_Subdev_Offline(client, ¶m);
|
||||
if(rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("IOT_Gateway_Subdev_Offline fail.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = IOT_Gateway_Destroy(client);
|
||||
|
||||
return rc;
|
||||
}
|
359
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/mqtt/mqtt_sample.c
vendored
Normal file
359
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/mqtt/mqtt_sample.c
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
static int sg_count = 0;
|
||||
static int sg_sub_packet_id = -1;
|
||||
|
||||
|
||||
// user's log print callback
|
||||
static bool log_handler(const char* message)
|
||||
{
|
||||
// return true if print success
|
||||
return false;
|
||||
}
|
||||
|
||||
// MQTT event callback
|
||||
static void _mqtt_event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
MQTTMessage* mqtt_messge = (MQTTMessage*)msg->msg;
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_RECVEIVED:
|
||||
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
mqtt_messge->topic_len,
|
||||
mqtt_messge->ptopic,
|
||||
mqtt_messge->payload_len,
|
||||
mqtt_messge->payload);
|
||||
break;
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
sg_sub_packet_id = packet_id;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_SUCCESS:
|
||||
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
|
||||
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_NACK:
|
||||
Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(MQTTInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
sprintf(sg_cert_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s\\%s\\%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
#else
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
#endif
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = _mqtt_event_handler;
|
||||
initParams->event_handle.context = NULL;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC_CONTENT 100
|
||||
// publish MQTT msg
|
||||
static int _publish_test_msg(void *client, char *topic_keyword, QoS qos)
|
||||
{
|
||||
char topicName[128] = {0};
|
||||
sprintf(topicName,"%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, topic_keyword);
|
||||
|
||||
PublishParams pub_params = DEFAULT_PUB_PARAMS;
|
||||
pub_params.qos = qos;
|
||||
|
||||
char topic_content[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
|
||||
int size = HAL_Snprintf(topic_content, sizeof(topic_content), "{\"action\": \"publish_test\", \"count\": \"%d\"}", sg_count++);
|
||||
if (size < 0 || size > sizeof(topic_content) - 1) {
|
||||
Log_e("payload content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_content));
|
||||
return -3;
|
||||
}
|
||||
|
||||
pub_params.payload = topic_content;
|
||||
pub_params.payload_len = strlen(topic_content);
|
||||
|
||||
return IOT_MQTT_Publish(client, topicName, &pub_params);
|
||||
}
|
||||
|
||||
// callback when MQTT msg arrives
|
||||
static void on_message_callback(void *pClient, MQTTMessage *message, void *userData)
|
||||
{
|
||||
if (message == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log_i("Receive Message With topicName:%.*s, payload:%.*s",
|
||||
(int) message->topic_len, message->ptopic, (int) message->payload_len, (char *) message->payload);
|
||||
}
|
||||
|
||||
// subscrib MQTT topic
|
||||
static int _subscribe_topic(void *client, char *topic_keyword, QoS qos)
|
||||
{
|
||||
static char topic_name[128] = {0};
|
||||
int size = HAL_Snprintf(topic_name, sizeof(topic_name), "%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, topic_keyword);
|
||||
|
||||
if (size < 0 || size > sizeof(topic_name) - 1) {
|
||||
Log_e("topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_name));
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.qos = qos;
|
||||
sub_params.on_message_handler = on_message_callback;
|
||||
return IOT_MQTT_Subscribe(client, topic_name, &sub_params);
|
||||
}
|
||||
|
||||
#ifdef LOG_UPLOAD
|
||||
// init log upload module
|
||||
static int _init_log_upload(void)
|
||||
{
|
||||
LogUploadInitParams log_init_params;
|
||||
memset(&log_init_params, 0, sizeof(LogUploadInitParams));
|
||||
|
||||
log_init_params.product_id = sg_devInfo.product_id;
|
||||
log_init_params.device_name = sg_devInfo.device_name;
|
||||
#ifdef AUTH_MODE_CERT
|
||||
log_init_params.sign_key = sg_cert_file;
|
||||
#else
|
||||
log_init_params.sign_key = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(WIN32)
|
||||
log_init_params.read_func = HAL_Log_Read;
|
||||
log_init_params.save_func = HAL_Log_Save;
|
||||
log_init_params.del_func = HAL_Log_Del;
|
||||
log_init_params.get_size_func = HAL_Log_Get_Size;
|
||||
#endif
|
||||
|
||||
return IOT_Log_Init_Uploader(&log_init_params);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool sg_loop_test = false;
|
||||
static int parse_arguments(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
while ((c = utils_getopt(argc, argv, "c:l")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
sg_loop_test = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file for DeviceInfo>] \n"
|
||||
" [-l ] loop test or not\n"
|
||||
, argv[0]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
IOT_Log_Set_MessageHandler(log_handler);
|
||||
|
||||
// parse arguments for device info file and loop test;
|
||||
rc = parse_arguments(argc, argv);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("parse arguments error, rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
//init connection
|
||||
MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params error, rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef LOG_UPLOAD
|
||||
// _init_log_upload should be done after _setup_connect_init_params and before IOT_MQTT_Construct
|
||||
rc = _init_log_upload();
|
||||
if (rc != QCLOUD_RET_SUCCESS)
|
||||
Log_e("init log upload error, rc = %d", rc);
|
||||
#endif
|
||||
|
||||
// create MQTT client and connect with server
|
||||
void *client = IOT_MQTT_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
rc = IOT_MQTT_GetErrCode();
|
||||
Log_e("MQTT Construct failed, rc = %d", rc);
|
||||
IOT_Log_Upload(true);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef SYSTEM_COMM
|
||||
long time = 0;
|
||||
// get system timestamp from server
|
||||
rc = IOT_Get_SysTime(client, &time);
|
||||
if (QCLOUD_RET_SUCCESS == rc){
|
||||
Log_i("system time is %ld", time);
|
||||
} else {
|
||||
Log_e("get system time failed!");
|
||||
}
|
||||
#endif
|
||||
|
||||
//subscribe normal topics here
|
||||
rc = _subscribe_topic(client, "data", QOS0);
|
||||
if (rc < 0) {
|
||||
Log_e("Client Subscribe Topic Failed: %d", rc);
|
||||
IOT_Log_Upload(true);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// wait for subscription result
|
||||
IOT_MQTT_Yield(client, 500);
|
||||
|
||||
do {
|
||||
|
||||
if (sg_sub_packet_id > 0) {
|
||||
rc = _publish_test_msg(client, "data", QOS1);
|
||||
if (rc < 0) {
|
||||
Log_e("client publish topic failed :%d.", rc);
|
||||
}
|
||||
}
|
||||
|
||||
rc = IOT_MQTT_Yield(client, 500);
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
} else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED){
|
||||
Log_e("exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sg_loop_test)
|
||||
HAL_SleepMs(1000);
|
||||
|
||||
} while (sg_loop_test);
|
||||
|
||||
rc = IOT_MQTT_Destroy(&client);
|
||||
|
||||
IOT_Log_Upload(true);
|
||||
|
||||
return rc;
|
||||
}
|
518
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/mqtt/multi_thread_mqtt_sample.c
vendored
Normal file
518
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/mqtt/multi_thread_mqtt_sample.c
vendored
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
/*
|
||||
* Notes for using SDK in multi-thread programing
|
||||
* 1. IOT_MQTT_Yield, IOT_MQTT_Construct and IOT_MQTT_Destroy are NOT thread-safe, only calling them in the same thread
|
||||
* 2. IOT_MQTT_Publish, IOT_MQTT_Subscribe and IOT_MQTT_Unsubscribe are thread-safe, and be executed in multi-threads simultaneously
|
||||
* 3. IOT_MQTT_Yield is the only entry to read from socket and should not be hand up for long
|
||||
*/
|
||||
|
||||
#if defined(__linux__)
|
||||
/*
|
||||
* This sample test MQTT multithread performance in Linux pthread runtime. Please note the data format is not JSON
|
||||
*/
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC_CONTENT 100
|
||||
#define MAX_PUB_THREAD_COUNT 5
|
||||
#define PUBLISH_COUNT 10
|
||||
#define THREAD_SLEEP_INTERVAL_USEC 1000000
|
||||
#define CONNECT_MAX_ATTEMPT_COUNT 3
|
||||
#define RX_RECEIVE_PERCENTAGE 99.0f
|
||||
|
||||
static bool sg_terminate_yield_thread;
|
||||
static bool sg_terminate_subUnsub_thread;
|
||||
|
||||
static unsigned int sg_countArray[MAX_PUB_THREAD_COUNT][PUBLISH_COUNT]; // record the times when msg from subscribed topic is received
|
||||
static unsigned int sg_rxMsgBufferTooBigCounter; // record the times when msg is oversize
|
||||
static unsigned int sg_rxUnexpectedNumberCounter; // record the times when unexpected msg is received
|
||||
static unsigned int sg_rePublishCount; // record the times of re-publish
|
||||
static unsigned int sg_wrongYieldCount; // record the times of Yield failure
|
||||
static unsigned int sg_threadStatus[MAX_PUB_THREAD_COUNT]; // record the status of all the threads
|
||||
static char sg_integeration_test_topic[MAX_SIZE_OF_TOPIC_CONTENT]; // topic for sub/pub
|
||||
|
||||
|
||||
typedef struct ThreadData {
|
||||
int threadId;
|
||||
void *client;
|
||||
} ThreadData;
|
||||
|
||||
|
||||
void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg) {
|
||||
MQTTMessage* mqtt_messge = (MQTTMessage*)msg->msg;
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_RECVEIVED:
|
||||
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
mqtt_messge->topic_len,
|
||||
mqtt_messge->ptopic,
|
||||
mqtt_messge->payload_len,
|
||||
mqtt_messge->payload);
|
||||
break;
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_SUCCESS:
|
||||
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_TIMEOUT:
|
||||
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBCRIBE_NACK:
|
||||
Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(MQTTInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
memset(sg_integeration_test_topic, 0, MAX_SIZE_OF_TOPIC_CONTENT);
|
||||
sprintf(sg_integeration_test_topic, "%s/%s/data", sg_devInfo.product_id, sg_devInfo.device_name);
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* self-defined format, not JSON
|
||||
*/
|
||||
static void _mqtt_message_handler(void *pClient, MQTTMessage *message, void *userData)
|
||||
{
|
||||
if (message == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(MAX_SIZE_OF_TOPIC_CONTENT >= message->payload_len) {
|
||||
/* parsing payload */
|
||||
char tempBuf[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
unsigned int tempRow = 0, tempCol = 0;
|
||||
char *temp = NULL;
|
||||
|
||||
HAL_Snprintf(tempBuf, message->payload_len + 1, "%s", (char *)message->payload);
|
||||
Log_d("Message received : %s", tempBuf);
|
||||
temp = strtok(tempBuf, " ,:");
|
||||
if(NULL == temp) {
|
||||
return;
|
||||
}
|
||||
temp = strtok(NULL, " ,:");
|
||||
if(NULL == temp) {
|
||||
return;
|
||||
}
|
||||
tempRow = atoi(temp);
|
||||
temp = strtok(NULL, " ,:");
|
||||
if(NULL == temp) {
|
||||
return;
|
||||
}
|
||||
temp = strtok(NULL, " ,:");
|
||||
if(NULL == temp) {
|
||||
return;
|
||||
}
|
||||
tempCol = atoi(temp);
|
||||
|
||||
if(((tempRow - 1) < MAX_PUB_THREAD_COUNT) && (tempCol < PUBLISH_COUNT)) {
|
||||
sg_countArray[tempRow - 1][tempCol]++;
|
||||
} else {
|
||||
Log_e(" Unexpected Thread : %d, Message : %d ", tempRow, tempCol);
|
||||
sg_rxUnexpectedNumberCounter++;
|
||||
}
|
||||
} else {
|
||||
sg_rxMsgBufferTooBigCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* yield test thread runner
|
||||
*/
|
||||
static void *_mqtt_yield_thread_runner(void *ptr) {
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
void *pClient = ptr;
|
||||
|
||||
while(false == sg_terminate_yield_thread) {
|
||||
|
||||
rc = IOT_MQTT_Yield(pClient, 200);
|
||||
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
usleep(THREAD_SLEEP_INTERVAL_USEC);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED){
|
||||
Log_e("Yield thread exit with error: %d", rc);
|
||||
break;
|
||||
}
|
||||
usleep(THREAD_SLEEP_INTERVAL_USEC);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribe/unsubscribe test thread runner
|
||||
* subscribed and unsubscribe
|
||||
*/
|
||||
static void *_mqtt_sub_unsub_thread_runner(void *ptr) {
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
void *pClient = ptr;
|
||||
char testTopic[128];
|
||||
HAL_Snprintf(testTopic, 128, "%s/%s/control", sg_devInfo.product_id, sg_devInfo.device_name);
|
||||
|
||||
while(QCLOUD_RET_SUCCESS == rc && false == sg_terminate_subUnsub_thread) {
|
||||
do {
|
||||
usleep(THREAD_SLEEP_INTERVAL_USEC);
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.qos = QOS1;
|
||||
sub_params.on_message_handler = _mqtt_message_handler;
|
||||
rc = IOT_MQTT_Subscribe(pClient, testTopic, &sub_params);
|
||||
|
||||
} while(QCLOUD_ERR_MQTT_NO_CONN == rc || QCLOUD_ERR_MQTT_REQUEST_TIMEOUT == rc);
|
||||
|
||||
if(rc < 0) {
|
||||
Log_e("Subscribe failed. Ret : %d ", rc);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
do {
|
||||
usleep(THREAD_SLEEP_INTERVAL_USEC);
|
||||
rc = IOT_MQTT_Unsubscribe(pClient, testTopic);
|
||||
} while(QCLOUD_ERR_MQTT_NO_CONN == rc|| QCLOUD_ERR_MQTT_REQUEST_TIMEOUT == rc);
|
||||
|
||||
if(rc < 0) {
|
||||
Log_e("Unsubscribe failed. Returned : %d ", rc);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* do subscribe in the thread
|
||||
*/
|
||||
static int _mqtt_subscribe_to_test_topic(void *pClient)
|
||||
{
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.on_message_handler = _mqtt_message_handler;
|
||||
sub_params.qos = QOS1;
|
||||
return IOT_MQTT_Subscribe(pClient, sg_integeration_test_topic, &sub_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* do publish in the thread
|
||||
* loop for PUBLISH_COUNT times
|
||||
* If publish failed in 1st time, do it again
|
||||
*/
|
||||
static void *_mqtt_publish_thread_runner(void *ptr) {
|
||||
int itr = 0;
|
||||
char topic_content[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
|
||||
PublishParams params;
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
ThreadData *threadData = (ThreadData *) ptr;
|
||||
void *pClient = threadData->client;
|
||||
int threadId = threadData->threadId;
|
||||
|
||||
int sleep_us = THREAD_SLEEP_INTERVAL_USEC;
|
||||
for(itr = 0; itr < PUBLISH_COUNT; itr++) {
|
||||
int size = HAL_Snprintf(topic_content, sizeof(topic_content), "Thread : %d, Msg : %d", threadId, itr);
|
||||
if (size < 0 || size > sizeof(topic_content) - 1) {
|
||||
Log_e("payload content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_content));
|
||||
return 0;
|
||||
}
|
||||
|
||||
params.payload = (void *) topic_content;
|
||||
params.payload_len = strlen(topic_content);
|
||||
params.qos = QOS1;
|
||||
Log_d("Msg being published: %s", topic_content);
|
||||
|
||||
do {
|
||||
rc = IOT_MQTT_Publish(pClient, sg_integeration_test_topic, ¶ms);
|
||||
usleep(sleep_us);
|
||||
} while(QCLOUD_ERR_MQTT_NO_CONN == rc || QCLOUD_ERR_MQTT_REQUEST_TIMEOUT == rc);
|
||||
|
||||
// 1st publish failed, re-publish and update sg_rePublishCount
|
||||
if(rc < 0) {
|
||||
Log_e("Failed attempt 1 Publishing Thread : %d, Msg : %d, cs : %d ", threadId, itr, rc);
|
||||
do {
|
||||
rc = IOT_MQTT_Publish(pClient, sg_integeration_test_topic, ¶ms);
|
||||
usleep(sleep_us);
|
||||
} while(QCLOUD_ERR_MQTT_NO_CONN == rc);
|
||||
sg_rePublishCount++;
|
||||
if(rc < 0) {
|
||||
Log_e("Failed attempt 2 Publishing Thread : %d, Msg : %d, cs : %d Second Attempt ", threadId, itr, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
sg_threadStatus[threadId - 1] = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* thread safety test
|
||||
*/
|
||||
static int _mqtt_multi_thread_test(void* client)
|
||||
{
|
||||
pthread_t publish_thread[MAX_PUB_THREAD_COUNT]; // for all publish thread
|
||||
pthread_t yield_thread; // yield thread
|
||||
pthread_t sub_unsub_thread; // sub/unsub thread
|
||||
int threadId[MAX_PUB_THREAD_COUNT]; // thread id
|
||||
int pubThreadReturn[MAX_PUB_THREAD_COUNT]; // to save return value when creating pub threads
|
||||
float percentOfRxMsg = 0.0; // record the success percentage of every pub send and recv
|
||||
int finishedThreadCount = 0; // record the number of finished publish threads
|
||||
int rxMsgCount = 0; // record the times of successfull subscribe
|
||||
ThreadData threadData[MAX_PUB_THREAD_COUNT]; // thread data to wrap client threadId for publish thread
|
||||
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
int test_result = 0;
|
||||
int i = 0 , j = 0;
|
||||
|
||||
// init the global variables
|
||||
sg_terminate_yield_thread = false;
|
||||
sg_rxMsgBufferTooBigCounter = 0;
|
||||
sg_rxUnexpectedNumberCounter = 0;
|
||||
sg_rePublishCount = 0;
|
||||
sg_wrongYieldCount = 0;
|
||||
|
||||
if (client == NULL) {
|
||||
Log_e("MQTT client is invalid!");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
/* Firstly create the thread for IOT_MQTT_Yield() so we can read and handle MQTT packet */
|
||||
rc = pthread_create(&yield_thread, NULL, _mqtt_yield_thread_runner, client);
|
||||
if (rc < 0) {
|
||||
Log_e("Create Yield thread failed. err: %d - %s", rc, strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* create a thread to test subscribe and unsubscribe another topic */
|
||||
rc = pthread_create(&sub_unsub_thread, NULL, _mqtt_sub_unsub_thread_runner, client);
|
||||
if (rc < 0) {
|
||||
Log_e("Create Sub_unsub thread failed. err: %d - %s", rc, strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* subscribe the same test topic as publish threads */
|
||||
rc = _mqtt_subscribe_to_test_topic(client);
|
||||
if (rc < 0) {
|
||||
Log_e("Client subscribe failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* setup the thread info for pub-threads */
|
||||
for(j = 0; j < MAX_PUB_THREAD_COUNT; j++) {
|
||||
threadId[j] = j + 1; // self defined thread ID: 1 - MAX_PUB_THREAD_COUNT
|
||||
sg_threadStatus[j] = 0; // thread status flag
|
||||
for(i = 0; i < PUBLISH_COUNT; i++) {
|
||||
sg_countArray[j][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* create multi threads to test IOT_MQTT_Publish() */
|
||||
for(i = 0; i < MAX_PUB_THREAD_COUNT; i++) {
|
||||
threadData[i].client = client;
|
||||
threadData[i].threadId = threadId[i];
|
||||
pubThreadReturn[i] = pthread_create(&publish_thread[i], NULL, _mqtt_publish_thread_runner,
|
||||
&threadData[i]);
|
||||
|
||||
if (pubThreadReturn[i] < 0) {
|
||||
Log_e("Create publish thread(ID: %d) failed. err: %d - %s",
|
||||
threadId[i], pubThreadReturn[i], strerror(pubThreadReturn[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for all pub-threads to finish their jobs */
|
||||
do {
|
||||
finishedThreadCount = 0;
|
||||
for(i = 0; i < MAX_PUB_THREAD_COUNT; i++) {
|
||||
finishedThreadCount += sg_threadStatus[i];
|
||||
}
|
||||
Log_i(">>>>>>>>Finished thread count : %d", finishedThreadCount);
|
||||
sleep(1);
|
||||
} while(finishedThreadCount < MAX_PUB_THREAD_COUNT);
|
||||
|
||||
Log_i("Publishing is finished");
|
||||
|
||||
sg_terminate_yield_thread = true;
|
||||
sg_terminate_subUnsub_thread = true;
|
||||
|
||||
/* Allow time for yield_thread and sub_sunsub thread to exit */
|
||||
|
||||
/* Not using pthread_join because all threads should have terminated gracefully at this point. If they haven't,
|
||||
* which should not be possible, something below will fail. */
|
||||
sleep(1);
|
||||
|
||||
/* Calculating Test Results */
|
||||
for(i = 0; i < PUBLISH_COUNT; i++) {
|
||||
for(j = 0; j < MAX_PUB_THREAD_COUNT; j++) {
|
||||
if(sg_countArray[j][i] > 0) {
|
||||
rxMsgCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
percentOfRxMsg = (float) rxMsgCount * 100 / (PUBLISH_COUNT * MAX_PUB_THREAD_COUNT);
|
||||
|
||||
printf("\n\nMQTT Multi-thread Test Result : \n");
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
if(RX_RECEIVE_PERCENTAGE <= percentOfRxMsg &&
|
||||
0 == sg_rxMsgBufferTooBigCounter &&
|
||||
0 == sg_rxUnexpectedNumberCounter &&
|
||||
0 == sg_wrongYieldCount)
|
||||
{
|
||||
// test success
|
||||
printf("Success! PercentOfRxMsg: %f %%\n", percentOfRxMsg);
|
||||
printf("Published Messages: %d , Received Messages: %d \n", PUBLISH_COUNT * MAX_PUB_THREAD_COUNT, rxMsgCount);
|
||||
printf("QoS 1 re publish count %u\n", sg_rePublishCount);
|
||||
printf("Yield count without error during callback %u\n", sg_wrongYieldCount);
|
||||
test_result = 0;
|
||||
} else {
|
||||
// test fail
|
||||
printf("\nFailure! PercentOfRxMsg: %f %%\n", percentOfRxMsg);
|
||||
printf("Published Messages: %d , Received Messages: %d \n", PUBLISH_COUNT * MAX_PUB_THREAD_COUNT, rxMsgCount);
|
||||
printf("\"Received message was too big than anything sent\" count: %u\n", sg_rxMsgBufferTooBigCounter);
|
||||
printf("\"The number received is out of the range\" count: %u\n", sg_rxUnexpectedNumberCounter);
|
||||
printf("Yield count without error during callback %u\n", sg_wrongYieldCount);
|
||||
test_result = -1;
|
||||
}
|
||||
printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
|
||||
|
||||
return test_result;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int rc;
|
||||
|
||||
//Init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
//Avoid broken pipe crash
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
//Init connection
|
||||
MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
//MQTT client connect
|
||||
void * client = IOT_MQTT_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
//Start rock & roll
|
||||
rc = _mqtt_multi_thread_test(client);
|
||||
if(0 != rc) {
|
||||
Log_e("MQTT multi-thread test FAILED! RC: %d", rc);
|
||||
} else {
|
||||
Log_i("MQTT multi-thread test SUCCESS");
|
||||
}
|
||||
|
||||
//Finish and destroy
|
||||
rc = IOT_MQTT_Destroy(&client);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
288
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/ota/ota_coap_sample.c
vendored
Normal file
288
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/ota/ota_coap_sample.c
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
#define OTA_BUF_LEN (5000)
|
||||
|
||||
static bool sg_pub_ack = false;
|
||||
static int sg_packet_id = 0;
|
||||
|
||||
void response_message_callback(void* coap_message, void* userContext)
|
||||
{
|
||||
int ret_code = IOT_COAP_GetMessageCode(coap_message);
|
||||
switch (ret_code) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
{
|
||||
char* payload = NULL;
|
||||
int payload_len = 0;
|
||||
int ret = -1;
|
||||
ret = IOT_COAP_GetMessagePayload(coap_message, &payload, &payload_len);
|
||||
if (ret == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("message received response, content: %s", payload);
|
||||
}
|
||||
else {
|
||||
Log_e("message received response, content error.");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", IOT_COAP_GetMessageId(coap_message));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void event_handler(void *pcontext, CoAPEventMessage *message)
|
||||
{
|
||||
switch (message->event_type) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
if(sg_packet_id == (unsigned)(uintptr_t)message->message){
|
||||
sg_pub_ack = true;
|
||||
}
|
||||
Log_i("message received ACK, msgid: %d", sg_packet_id);
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT:
|
||||
Log_i("message received response, content: %s", IOT_COAP_GetMessageId(message->message));
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT:
|
||||
Log_i("message received ACK but receive response timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
default:
|
||||
Log_e("unrecogonized event type: %d", message->event_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(CoAPInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
int rc;
|
||||
|
||||
CoAPInitParams init_params = DEFAULT_COAPINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_COAP_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
void *h_ota = IOT_OTA_Init(sg_devInfo.product_id, sg_devInfo.device_name, client);
|
||||
if (NULL == h_ota) {
|
||||
Log_e("initialize OTA failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
if (0 > IOT_OTA_ReportVersion(h_ota, "1.0.0")) {
|
||||
Log_e("report OTA version failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
HAL_SleepMs(2000);
|
||||
|
||||
int ota_over = 0;
|
||||
bool upgrade_fetch_success = true;
|
||||
FILE *fp;
|
||||
char buf_ota[OTA_BUF_LEN];
|
||||
if (NULL == (fp = fopen("ota.bin", "wb+"))) {
|
||||
Log_e("open file failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
do {
|
||||
uint32_t firmware_valid;
|
||||
Log_i("wait for ota upgrade command...");
|
||||
|
||||
IOT_COAP_Yield(client, 200);
|
||||
|
||||
if (IOT_OTA_IsFetching(h_ota)) {
|
||||
char version[128], md5sum[33];
|
||||
uint32_t len, size_downloaded, size_file;
|
||||
do {
|
||||
len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
|
||||
if (len > 0) {
|
||||
if (1 != fwrite(buf_ota, len, 1, fp)) {
|
||||
Log_e("write data to file failed");
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
} else if (len < 0) {
|
||||
Log_e("download fail rc=%d", len);
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* get OTA information */
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
|
||||
|
||||
IOT_COAP_Yield(client, 100);
|
||||
} while (!IOT_OTA_IsFetchFinish(h_ota));
|
||||
|
||||
/* Must check MD5 match or not */
|
||||
if (upgrade_fetch_success) {
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
|
||||
if (0 == firmware_valid) {
|
||||
Log_e("The firmware is invalid");
|
||||
upgrade_fetch_success = false;
|
||||
} else {
|
||||
Log_e("The firmware is valid");
|
||||
upgrade_fetch_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
ota_over = 1;
|
||||
}
|
||||
|
||||
HAL_SleepMs(2000);
|
||||
|
||||
} while(!ota_over);
|
||||
|
||||
|
||||
if (upgrade_fetch_success)
|
||||
{
|
||||
/* begin execute OTA files, should report upgrade begin */
|
||||
// sg_packet_id = IOT_OTA_ReportUpgradeBegin(h_ota);
|
||||
// if (0 > sg_packet_id) {
|
||||
// Log_e("report OTA begin failed error:%d", sg_packet_id);
|
||||
// return QCLOUD_ERR_FAILURE;
|
||||
// }
|
||||
|
||||
// while (!sg_pub_ack) {
|
||||
// HAL_SleepMs(1000);
|
||||
// IOT_COAP_Yield(client, 200);
|
||||
// }
|
||||
// sg_pub_ack = false;
|
||||
|
||||
/* if upgrade success */
|
||||
/* after execute OTA files, should report upgrade result */
|
||||
// sg_packet_id = IOT_OTA_ReportUpgradeSuccess(h_ota, "1.0.1");
|
||||
// if (0 > sg_packet_id) {
|
||||
// Log_e("report OTA result failed error:%d", sg_packet_id);
|
||||
// return QCLOUD_ERR_FAILURE;
|
||||
// }
|
||||
|
||||
// while (!sg_pub_ack) {
|
||||
// HAL_SleepMs(1000);
|
||||
// IOT_COAP_Yield(client, 200);
|
||||
// }
|
||||
// sg_pub_ack = false;
|
||||
|
||||
/* if upgrade fail */
|
||||
// sg_packet_id = IOT_OTA_ReportUpgradeFail(h_ota, "1.0.1");
|
||||
// if (0 > sg_packet_id) {
|
||||
// Log_e("report OTA result failed error:%d", sg_packet_id);
|
||||
// return QCLOUD_ERR_FAILURE;
|
||||
// }
|
||||
// while (!sg_pub_ack) {
|
||||
// HAL_SleepMs(1000);
|
||||
// IOT_COAP_Yield(client, 200);
|
||||
// }
|
||||
// sg_pub_ack = false;
|
||||
}
|
||||
|
||||
IOT_OTA_Destroy(h_ota);
|
||||
|
||||
IOT_COAP_Destroy(&client);
|
||||
|
||||
return 0;
|
||||
}
|
509
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/ota/ota_mqtt_sample.c
vendored
Normal file
509
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/ota/ota_mqtt_sample.c
vendored
Normal file
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
#include "lite-utils.h"
|
||||
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
#define OTA_BUF_LEN (5000)
|
||||
|
||||
static bool sg_pub_ack = false;
|
||||
static int sg_packet_id = 0;
|
||||
|
||||
static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
if (sg_packet_id == packet_id)
|
||||
sg_pub_ack = true;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* demo of firmware info management in device side for resuming download from break point */
|
||||
#define VERSION_FILE_PATH "./local_fw_info.json"
|
||||
#define KEY_VER "version"
|
||||
#define KEY_MD5 "md5"
|
||||
#define KEY_SIZE "downloadSize"
|
||||
#define KEY_STATE "state"
|
||||
#define KEY_PREVER "running_version"
|
||||
static char * get_local_fw_version(char **ver, char **md5, char **size)
|
||||
{
|
||||
#define INFO_FILE_MAX_LEN 256
|
||||
|
||||
FILE *fp;
|
||||
int len;
|
||||
int rlen;
|
||||
char *preVer;
|
||||
char *reportVer = NULL;
|
||||
|
||||
fp = fopen(VERSION_FILE_PATH, "r");
|
||||
if(NULL == fp) {
|
||||
Log_e("open file %s failed", VERSION_FILE_PATH);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
len = ftell(fp);
|
||||
if(len > INFO_FILE_MAX_LEN){
|
||||
Log_e("%s is too big, pls check", VERSION_FILE_PATH);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
char *JsonDoc = (char *)HAL_Malloc(len + 10);
|
||||
if(NULL == JsonDoc){
|
||||
Log_e("malloc buffer for json file read fail");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
rlen = fread(JsonDoc, 1, len, fp);
|
||||
|
||||
if(len != rlen){
|
||||
Log_e("read data len (%d) less than needed (%d), %s", rlen, len, JsonDoc);
|
||||
}
|
||||
|
||||
*ver = LITE_json_value_of(KEY_VER, JsonDoc);
|
||||
*md5 = LITE_json_value_of(KEY_MD5, JsonDoc);
|
||||
*size = LITE_json_value_of(KEY_SIZE, JsonDoc);
|
||||
preVer = LITE_json_value_of(KEY_PREVER, JsonDoc);
|
||||
|
||||
if((NULL != *ver) && (NULL != preVer) && (0 == strcmp(*ver, preVer))){
|
||||
reportVer = *ver;
|
||||
HAL_Free(preVer);
|
||||
}else{
|
||||
reportVer = preVer;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if(NULL != fp){
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return reportVer;
|
||||
#undef INFO_FILE_MAX_LEN
|
||||
}
|
||||
|
||||
/* update local firmware info for resuming download from break point */
|
||||
static int update_local_fw_info(const char *version, const char *preVer, const char *md5, uint32_t downloadedSize)
|
||||
{
|
||||
#define INFO_FILE_MAX_LEN 256
|
||||
|
||||
FILE *fp;
|
||||
int wlen;
|
||||
int ret = QCLOUD_RET_SUCCESS;
|
||||
char dataBuff[INFO_FILE_MAX_LEN];
|
||||
|
||||
memset(dataBuff, 0, INFO_FILE_MAX_LEN);
|
||||
HAL_Snprintf(dataBuff, INFO_FILE_MAX_LEN, "{\"%s\":\"%s\", \"%s\":\"%s\",\"%s\":%d,\"%s\":\"%s\"}",\
|
||||
KEY_VER, version, KEY_MD5, md5, KEY_SIZE, downloadedSize, \
|
||||
KEY_PREVER, (NULL == preVer)?"1.0.0": preVer);
|
||||
|
||||
fp = fopen(VERSION_FILE_PATH, "w");
|
||||
if(NULL == fp) {
|
||||
Log_e("open file %s failed", VERSION_FILE_PATH);
|
||||
ret = QCLOUD_ERR_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
wlen = fwrite(dataBuff, 1, strlen(dataBuff), fp);
|
||||
if(wlen != strlen(dataBuff)){
|
||||
Log_e("save version to file err");
|
||||
ret = QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if(NULL != fp){
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#undef INFO_FILE_MAX_LEN
|
||||
}
|
||||
|
||||
/* get local firmware offset for resuming download from break point */
|
||||
static int getFwOffset(void *h_ota, char *local_ver, char *local_md5, char *local_size, uint32_t *offset, uint32_t *size_file)
|
||||
{
|
||||
char version[128], md5sum[33];
|
||||
uint32_t local_len;
|
||||
int Ret;
|
||||
|
||||
Ret = IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
|
||||
Ret |= IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
|
||||
Ret |= IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, size_file, 4);
|
||||
|
||||
local_len = (NULL == local_size)?0:atoi(local_size);
|
||||
|
||||
|
||||
if((NULL == local_ver)||(NULL == local_md5)||(NULL == local_size)){
|
||||
*offset = 0;
|
||||
}
|
||||
else if((0 != strcmp(local_ver, version))||(0 != strcmp(local_md5, md5sum))||(local_len > *size_file)){
|
||||
*offset = 0;
|
||||
}else {
|
||||
*offset = local_len;
|
||||
}
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* calculate left MD5 for resuming download from break point */
|
||||
static int cal_exist_fw_md5(void *h_ota, FILE *fp, size_t size){
|
||||
#define BUFF_LEN 1024
|
||||
|
||||
char buff[BUFF_LEN];
|
||||
size_t rlen;
|
||||
int Ret = QCLOUD_RET_SUCCESS;
|
||||
|
||||
while((size > 0) && (!feof(fp))){
|
||||
rlen = (size > BUFF_LEN)?BUFF_LEN:size;
|
||||
if(rlen != fread(buff, 1, rlen, fp)){
|
||||
Log_e("read data len not expected");
|
||||
Ret = QCLOUD_ERR_FAILURE;
|
||||
break;
|
||||
}
|
||||
IOT_OTA_UpdateClientMd5(h_ota, buff, rlen);
|
||||
size -= rlen;
|
||||
}
|
||||
return Ret;
|
||||
#undef BUFF_LEN
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(MQTTInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
int rc;
|
||||
uint32_t firmware_valid;
|
||||
char version[128], md5sum[33];
|
||||
uint32_t size_downloaded, size_file;
|
||||
int len;
|
||||
int ota_over = 0;
|
||||
bool upgrade_fetch_success = true;
|
||||
char buf_ota[OTA_BUF_LEN];
|
||||
FILE *fp = NULL;
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_MQTT_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
void *h_ota = IOT_OTA_Init(sg_devInfo.product_id, sg_devInfo.device_name, client);
|
||||
if (NULL == h_ota) {
|
||||
Log_e("initialize OTA failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
IOT_MQTT_Yield(client, 1000); //make sure subscribe success
|
||||
|
||||
char *local_ver = NULL, *local_md5 = NULL, *local_size = NULL, *reportVer = NULL;
|
||||
reportVer = get_local_fw_version(&local_ver, &local_md5, &local_size);
|
||||
Log_d("local_ver:%s local_md5:%s, local_size:%s", local_ver, local_md5, local_size);
|
||||
|
||||
/* Must report version first */
|
||||
if (0 > IOT_OTA_ReportVersion(h_ota, (NULL == reportVer)?"1.0.0": reportVer)) {
|
||||
Log_e("report OTA version failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
do {
|
||||
Log_i("wait for ota upgrade command...");
|
||||
|
||||
IOT_MQTT_Yield(client, 200);
|
||||
|
||||
if (IOT_OTA_IsFetching(h_ota)) {
|
||||
|
||||
/*check pre-download finished or not*/
|
||||
/*if version & MD5 is the same,then pre-download not finished,get breakpoint continue download.otherwise the version is new*/
|
||||
rc = getFwOffset(h_ota, local_ver, local_md5, local_size, &offset, &size_file);
|
||||
if(QCLOUD_RET_SUCCESS != rc){
|
||||
Log_e("get fw offset err,rc:%d",rc);
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/*cal file md5*/
|
||||
//Log_d("Get offset:%d(%x)", offset, offset);
|
||||
if(offset > 0){
|
||||
if (NULL == (fp = fopen("ota.bin", "ab+"))) {
|
||||
Log_e("open file failed");
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(QCLOUD_RET_SUCCESS != cal_exist_fw_md5(h_ota, fp, offset)){
|
||||
Log_e("cal exist fw md5 failed");
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
if (NULL == (fp = fopen("ota.bin", "wb+"))) {
|
||||
Log_e("open file failed");
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*set offset and start http connect*/
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
rc = IOT_OTA_StartDownload(h_ota, offset, size_file);
|
||||
if(QCLOUD_RET_SUCCESS != rc){
|
||||
Log_e("OTA download start err,rc:%d",rc);
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
|
||||
if (len > 0) {
|
||||
if (1 != fwrite(buf_ota, len, 1, fp)) {
|
||||
Log_e("write data to file failed");
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
} else if (len < 0) {
|
||||
Log_e("download fail rc=%d", len);
|
||||
upgrade_fetch_success = false;
|
||||
break;
|
||||
}
|
||||
fflush(fp);
|
||||
|
||||
/* get OTA information and update local info */
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
|
||||
rc = update_local_fw_info(version, reportVer, md5sum, size_downloaded);
|
||||
if(QCLOUD_RET_SUCCESS != rc){
|
||||
Log_e("update local fw info err,rc:%d", rc);
|
||||
}
|
||||
|
||||
IOT_MQTT_Yield(client, 100);
|
||||
|
||||
} while (!IOT_OTA_IsFetchFinish(h_ota));
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
/* Must check MD5 match or not */
|
||||
if (upgrade_fetch_success) {
|
||||
IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
|
||||
if (0 == firmware_valid) {
|
||||
Log_e("The firmware is invalid");
|
||||
upgrade_fetch_success = false;
|
||||
rc = update_local_fw_info(NULL, reportVer, NULL, 0);
|
||||
if(QCLOUD_RET_SUCCESS != rc){
|
||||
Log_e("update local fw info err,rc:%d", rc);
|
||||
}
|
||||
} else {
|
||||
Log_i("The firmware is valid");
|
||||
upgrade_fetch_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
ota_over = 1;
|
||||
}
|
||||
|
||||
HAL_SleepMs(2000);
|
||||
} while(!ota_over);
|
||||
|
||||
|
||||
if (upgrade_fetch_success)
|
||||
{
|
||||
/* begin execute OTA files, should report upgrade begin */
|
||||
sg_packet_id = IOT_OTA_ReportUpgradeBegin(h_ota);
|
||||
if (0 > sg_packet_id) {
|
||||
Log_e("report OTA begin failed error:%d", sg_packet_id);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
while (!sg_pub_ack) {
|
||||
HAL_SleepMs(1000);
|
||||
IOT_MQTT_Yield(client, 200);
|
||||
}
|
||||
sg_pub_ack = false;
|
||||
|
||||
//* add your own upgrade logic here*//
|
||||
//* fw_upgrade.....
|
||||
|
||||
if(QCLOUD_RET_SUCCESS == rc){
|
||||
/* if upgrade success */
|
||||
/* after execute OTA files, should report upgrade result */
|
||||
sg_packet_id = IOT_OTA_ReportUpgradeSuccess(h_ota, NULL);
|
||||
if (0 > sg_packet_id) {
|
||||
Log_e("report OTA result failed error:%d", sg_packet_id);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
while (!sg_pub_ack) {
|
||||
HAL_SleepMs(1000);
|
||||
IOT_MQTT_Yield(client, 200);
|
||||
}
|
||||
rc = update_local_fw_info(version, version, md5sum, size_downloaded); // just for example, add your own logic
|
||||
sg_pub_ack = false;
|
||||
|
||||
}else{
|
||||
/* if upgrade fail */
|
||||
sg_packet_id = IOT_OTA_ReportUpgradeFail(h_ota, NULL);
|
||||
if (0 > sg_packet_id) {
|
||||
Log_e("report OTA result failed error:%d", sg_packet_id);
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
while (!sg_pub_ack) {
|
||||
HAL_SleepMs(1000);
|
||||
IOT_MQTT_Yield(client, 200);
|
||||
}
|
||||
rc = update_local_fw_info(NULL, reportVer, NULL, 0); // just for example, add your own logic
|
||||
sg_pub_ack = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if(NULL != fp){
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
if(NULL != local_ver){
|
||||
reportVer = (reportVer == local_ver)?NULL: reportVer;
|
||||
HAL_Free(local_ver);
|
||||
local_ver = NULL;
|
||||
}
|
||||
|
||||
if(NULL != local_md5){
|
||||
HAL_Free(local_md5);
|
||||
local_md5 = NULL;
|
||||
}
|
||||
|
||||
if(NULL != local_size){
|
||||
HAL_Free(local_size);
|
||||
local_size = NULL;
|
||||
}
|
||||
|
||||
if(NULL != reportVer){
|
||||
HAL_Free(reportVer);
|
||||
reportVer = NULL;
|
||||
}
|
||||
|
||||
IOT_OTA_Destroy(h_ota);
|
||||
|
||||
IOT_MQTT_Destroy(&client);
|
||||
|
||||
return 0;
|
||||
}
|
300
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/aircond_shadow_sample.c
vendored
Normal file
300
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/aircond_shadow_sample.c
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
#include "lite-utils.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200
|
||||
|
||||
#define ROOM_TEMPERATURE 32.0f
|
||||
static float sg_desire_temperature = 20.0f;
|
||||
static float sg_report_temperature = ROOM_TEMPERATURE;
|
||||
|
||||
static float sg_energy_consumption = 0.0f;
|
||||
static bool sg_airconditioner_openned = false;
|
||||
|
||||
static MQTTEventType sg_subscribe_event_result = MQTT_EVENT_UNDEF;
|
||||
|
||||
#define MAX_RECV_LEN (512 + 1)
|
||||
|
||||
|
||||
// compare float value
|
||||
bool _is_value_equal(float left, float right)
|
||||
{
|
||||
if((left<right+0.01) && (left>right-0.01))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// simulate room temperature change
|
||||
static void _simulate_room_temperature(float *roomTemperature) {
|
||||
float delta_change = 0;
|
||||
|
||||
if (!sg_airconditioner_openned) {
|
||||
if(!_is_value_equal(*roomTemperature, ROOM_TEMPERATURE)) {
|
||||
delta_change = (*roomTemperature)>ROOM_TEMPERATURE ? -0.5: 0.5;
|
||||
}
|
||||
} else {
|
||||
sg_energy_consumption += 1;
|
||||
if (!_is_value_equal(*roomTemperature, sg_desire_temperature)) {
|
||||
delta_change = (*roomTemperature)>sg_desire_temperature ? -1.0: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
*roomTemperature += delta_change;
|
||||
}
|
||||
|
||||
// MQTT event callback
|
||||
static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// callback when MQTT msg arrives
|
||||
static void on_message_callback(void *pClient, MQTTMessage *message, void *userData)
|
||||
{
|
||||
if (message == NULL)
|
||||
return;
|
||||
|
||||
const char *topicName = message->ptopic;
|
||||
size_t topicNameLen = message->topic_len;
|
||||
|
||||
if (topicName == NULL || topicNameLen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log_i("Receive Message With topicName:%.*s, payload:%.*s",
|
||||
(int) topicNameLen, topicName, (int) message->payload_len, (char *) message->payload);
|
||||
|
||||
|
||||
static char cloud_rcv_buf[MAX_RECV_LEN + 1];
|
||||
size_t len = (message->payload_len > MAX_RECV_LEN)?MAX_RECV_LEN:(message->payload_len);
|
||||
|
||||
if(message->payload_len > MAX_RECV_LEN){
|
||||
Log_e("paload len exceed buffer size");
|
||||
}
|
||||
|
||||
memcpy(cloud_rcv_buf, message->payload, len);
|
||||
cloud_rcv_buf[len] = '\0'; // jsmn_parse relies on a string
|
||||
|
||||
char* value = LITE_json_value_of("action", cloud_rcv_buf);
|
||||
if (value != NULL) {
|
||||
if(strcmp(value, "come_home") == 0)
|
||||
{
|
||||
sg_airconditioner_openned = true;
|
||||
}
|
||||
else if(strcmp(value, "leave_home") == 0)
|
||||
{
|
||||
sg_airconditioner_openned = false;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_Free(value);
|
||||
}
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(ShadowInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// subscrib MQTT topic
|
||||
static int _register_subscribe_topics(void *client)
|
||||
{
|
||||
static char topic_name[128] = {0};
|
||||
int size = HAL_Snprintf(topic_name, sizeof(topic_name), "%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, "control");
|
||||
if (size < 0 || size > sizeof(topic_name) - 1)
|
||||
{
|
||||
Log_e("topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_name));
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.on_message_handler = on_message_callback;
|
||||
return IOT_Shadow_Subscribe(client, topic_name, &sub_params);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
while ((c = utils_getopt(argc, argv, "c:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file for DeviceInfo>] \n"
|
||||
, argv[0]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rc;
|
||||
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
//init connection
|
||||
ShadowInitParams init_params = DEFAULT_SHAWDOW_INIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_Shadow_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
//register subscribe topics here
|
||||
rc = _register_subscribe_topics(client);
|
||||
if (rc < 0) {
|
||||
Log_e("Client Subscribe Topic Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
while (IOT_Shadow_IsConnected(client) || rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT || rc == QCLOUD_RET_MQTT_RECONNECTED) {
|
||||
|
||||
rc = IOT_Shadow_Yield(client, 200);
|
||||
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("Exit loop caused of errCode: %d", rc);
|
||||
}
|
||||
|
||||
if (sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_SUCCESS &&
|
||||
sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_TIMEOUT &&
|
||||
sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_NACK)
|
||||
{
|
||||
Log_i("Wait for subscribe result. sg_subscribe_event_result = %d", sg_subscribe_event_result);
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
_simulate_room_temperature(&sg_report_temperature);
|
||||
Log_i("airConditioner state: %s", sg_airconditioner_openned ? "open" : "close");
|
||||
Log_i("currentTemperature: %f, energyConsumption: %f", sg_report_temperature, sg_energy_consumption);
|
||||
|
||||
HAL_SleepMs(1000);
|
||||
}
|
||||
|
||||
rc = IOT_Shadow_Destroy(client);
|
||||
|
||||
return rc;
|
||||
}
|
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
#include "lite-utils.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200
|
||||
#define ROOM_TEMPERATURE 32.0f
|
||||
#define MAX_RECV_LEN (512 + 1)
|
||||
|
||||
|
||||
static float sg_desire_temperature = 20.0f;
|
||||
static float sg_report_temperature = ROOM_TEMPERATURE;
|
||||
|
||||
static float sg_energy_consumption = 0.0f;
|
||||
static bool sg_airconditioner_openned = false;
|
||||
|
||||
static DeviceProperty sg_energy_consumption_prop;
|
||||
static DeviceProperty sg_temperature_desire_prop;
|
||||
|
||||
static bool sg_message_arrived_on_delta = false;
|
||||
|
||||
static MQTTEventType sg_subscribe_event_result = MQTT_EVENT_UNDEF;
|
||||
static bool sg_finish_shadow_get = false;
|
||||
|
||||
char sg_document_buffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
|
||||
size_t sg_document_buffersize = sizeof(sg_document_buffer) / sizeof(sg_document_buffer[0]);
|
||||
|
||||
|
||||
static int _register_config_shadow_property(void *client);
|
||||
static int _register_subscribe_topics(void *client);
|
||||
|
||||
|
||||
// compare float value
|
||||
bool _is_value_equal(float left, float right)
|
||||
{
|
||||
if((left<right+0.01) && (left>right-0.01))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// simulate room temperature change
|
||||
static void _simulate_room_temperature(float *roomTemperature)
|
||||
{
|
||||
float delta_change = 0;
|
||||
|
||||
if (!sg_airconditioner_openned) {
|
||||
if(!_is_value_equal(*roomTemperature, ROOM_TEMPERATURE)) {
|
||||
delta_change = (*roomTemperature) > ROOM_TEMPERATURE ? -0.5: 0.5;
|
||||
}
|
||||
} else {
|
||||
sg_energy_consumption += 1;
|
||||
if (!_is_value_equal(*roomTemperature, sg_desire_temperature)) {
|
||||
delta_change = (*roomTemperature) > sg_desire_temperature ? -1.0: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
*roomTemperature += delta_change;
|
||||
}
|
||||
|
||||
// callback for request response arrives
|
||||
static void on_request_handler(void *pClient, Method method, RequestAck status, const char *jsonDoc, void *userData)
|
||||
{
|
||||
|
||||
char *shadow_status = NULL;
|
||||
char *shadow_method = NULL;
|
||||
|
||||
if (status == ACK_TIMEOUT) {
|
||||
shadow_status = "ACK_TIMEOUT";
|
||||
} else if (status == ACK_ACCEPTED) {
|
||||
shadow_status = "ACK_ACCEPTED";
|
||||
} else if (status == ACK_REJECTED) {
|
||||
shadow_status = "ACK_REJECTED";
|
||||
}
|
||||
|
||||
if (method == GET) {
|
||||
shadow_method = "GET";
|
||||
} else if (method == UPDATE) {
|
||||
shadow_method = "UPDATE";
|
||||
}
|
||||
|
||||
Log_i("Method=%s|Ack=%s", shadow_method, shadow_status);
|
||||
Log_i("received jsonString=%s", jsonDoc);
|
||||
|
||||
if (status == ACK_ACCEPTED && method == UPDATE) {
|
||||
if (sg_message_arrived_on_delta)
|
||||
sg_message_arrived_on_delta = false;
|
||||
Log_i("Update Shadow Success");
|
||||
} else if (status == ACK_ACCEPTED && method == GET) {
|
||||
Log_i("Get Shadow Document Success");
|
||||
sg_finish_shadow_get = true;
|
||||
} else if (status == ACK_TIMEOUT && method == UPDATE) {
|
||||
Log_e("Update Shadow Fail!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// callback when MQTT msg arrives
|
||||
static void on_message_callback(void *pClient, MQTTMessage *message, void *userData)
|
||||
{
|
||||
if (message == NULL)
|
||||
return;
|
||||
|
||||
const char *topicName = message->ptopic;
|
||||
uint16_t topicNameLen = message->topic_len;
|
||||
|
||||
if (topicName == NULL || topicNameLen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log_i("Receive Message With topicName:%.*s, payload:%.*s",
|
||||
(int) topicNameLen, topicName, (int) message->payload_len, (char *) message->payload);
|
||||
|
||||
static char cloud_rcv_buf[MAX_RECV_LEN + 1];
|
||||
size_t len = (message->payload_len > MAX_RECV_LEN)?MAX_RECV_LEN:(message->payload_len);
|
||||
|
||||
if(message->payload_len > MAX_RECV_LEN){
|
||||
Log_e("paload len exceed buffer size");
|
||||
}
|
||||
memcpy(cloud_rcv_buf, message->payload, len);
|
||||
cloud_rcv_buf[len] = '\0'; // jsmn_parse relies on a string
|
||||
|
||||
char* value = LITE_json_value_of("action", cloud_rcv_buf);
|
||||
if (value != NULL) {
|
||||
if(strcmp(value, "come_home") == 0)
|
||||
{
|
||||
sg_airconditioner_openned = true;
|
||||
}
|
||||
else if(strcmp(value, "leave_home") == 0)
|
||||
{
|
||||
sg_airconditioner_openned = false;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_Free(value);
|
||||
}
|
||||
|
||||
// callback for delta msg
|
||||
static void on_temperature_actuate_callback(void *pClient, const char *jsonResponse, uint32_t responseLen, DeviceProperty *context)
|
||||
{
|
||||
Log_i("actuate callback jsonString=%s|dataLen=%u", jsonResponse, responseLen);
|
||||
|
||||
if (context != NULL) {
|
||||
Log_i("modify desire temperature to: %f", *(float *) context->data);
|
||||
sg_message_arrived_on_delta = true;
|
||||
}
|
||||
}
|
||||
|
||||
// MQTT event callback
|
||||
static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
sg_subscribe_event_result = msg->event_type;
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// report energy consumption
|
||||
static int _do_report_energy_consumption(void *client)
|
||||
{
|
||||
int rc = IOT_Shadow_JSON_ConstructReport(client, sg_document_buffer, sg_document_buffersize, 1, &sg_energy_consumption_prop);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("shadow construct report failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Log_i("Update Shadow: %s", sg_document_buffer);
|
||||
rc = IOT_Shadow_Update(client, sg_document_buffer, sg_document_buffersize, on_request_handler, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_i("Update Shadow Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _do_report_temperature_desire(void *client)
|
||||
{
|
||||
/*
|
||||
* report desire as null if recv delta or desire msg, otherwise server will keep desire record
|
||||
*/
|
||||
|
||||
int rc;
|
||||
rc = IOT_Shadow_JSON_ConstructReportAndDesireAllNull(client, sg_document_buffer, sg_document_buffersize, 1, &sg_temperature_desire_prop);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("shadow construct report failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Log_i("update desire temperature: %s", sg_document_buffer);
|
||||
rc = IOT_Shadow_Update(client, sg_document_buffer, sg_document_buffersize, on_request_handler, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_i("Update Shadow Failed: %d", rc);
|
||||
return rc;
|
||||
} else {
|
||||
Log_i("Update Shadow Success");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(ShadowInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// setup shadow properties
|
||||
static void _setup_shadow_data()
|
||||
{
|
||||
//s_temperatureReportProp: device ---> shadow <---> app
|
||||
sg_energy_consumption_prop.key = "energyConsumption";
|
||||
sg_energy_consumption_prop.data = &sg_energy_consumption;
|
||||
sg_energy_consumption_prop.type = JFLOAT;
|
||||
//s_temperatureDesireProp: app ---> shadow ---> device
|
||||
sg_temperature_desire_prop.key = "temperatureDesire";
|
||||
sg_temperature_desire_prop.data = &sg_desire_temperature;
|
||||
sg_temperature_desire_prop.type = JFLOAT;
|
||||
}
|
||||
|
||||
// register properties
|
||||
static int _register_config_shadow_property(void *client)
|
||||
{
|
||||
return IOT_Shadow_Register_Property(client, &sg_temperature_desire_prop, on_temperature_actuate_callback);
|
||||
}
|
||||
|
||||
// subscrib MQTT topic
|
||||
static int _register_subscribe_topics(void *client)
|
||||
{
|
||||
static char topic_name[128] = {0};
|
||||
|
||||
int size = HAL_Snprintf(topic_name, sizeof(topic_name), "%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, "control");
|
||||
if (size < 0 || size > sizeof(topic_name) - 1)
|
||||
{
|
||||
Log_e("topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_name));
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
SubscribeParams sub_params = DEFAULT_SUB_PARAMS;
|
||||
sub_params.qos = QOS1;
|
||||
sub_params.on_message_handler = on_message_callback;
|
||||
return IOT_Shadow_Subscribe(client, topic_name, &sub_params);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
while ((c = utils_getopt(argc, argv, "c:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file for DeviceInfo>] \n"
|
||||
, argv[0]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc;
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
//init connection
|
||||
ShadowInitParams init_params = DEFAULT_SHAWDOW_INIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_Shadow_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
//init shadow data
|
||||
_setup_shadow_data();
|
||||
|
||||
//register config shadow propertys here
|
||||
rc = _register_config_shadow_property(client);
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
Log_i("Cloud Device Register Delta Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Register Delta Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
//pull shadow document and update local shadow version
|
||||
IOT_Shadow_Get(client, on_request_handler, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
while(sg_finish_shadow_get == false)
|
||||
{
|
||||
Log_i("Wait for Shadow Get Result");
|
||||
IOT_Shadow_Yield(client, 200);
|
||||
HAL_SleepMs(1000);
|
||||
}
|
||||
|
||||
//register subscribe topics here
|
||||
rc = _register_subscribe_topics(client);
|
||||
if (rc < 0) {
|
||||
Log_e("Client Subscribe Topic Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
while (IOT_Shadow_IsConnected(client) || rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT || rc == QCLOUD_RET_MQTT_RECONNECTED) {
|
||||
|
||||
rc = IOT_Shadow_Yield(client, 200);
|
||||
|
||||
if (rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("Exit loop caused of errCode: %d", rc);
|
||||
}
|
||||
|
||||
if (sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_SUCCESS &&
|
||||
sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_TIMEOUT &&
|
||||
sg_subscribe_event_result != MQTT_EVENT_SUBCRIBE_NACK)
|
||||
{
|
||||
Log_i("Wait for subscribe result, sg_subscribe_event_result = %d", sg_subscribe_event_result);
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
_simulate_room_temperature(&sg_report_temperature);
|
||||
Log_i("airConditioner state: %s", sg_airconditioner_openned ? "open" : "close");
|
||||
Log_i("currentTemperature: %f, energyConsumption: %f", sg_report_temperature, sg_energy_consumption);
|
||||
|
||||
if (sg_message_arrived_on_delta)
|
||||
_do_report_temperature_desire(client);
|
||||
|
||||
if (sg_message_arrived_on_delta == false)
|
||||
_do_report_energy_consumption(client);
|
||||
|
||||
HAL_SleepMs(3000);
|
||||
}
|
||||
|
||||
rc = IOT_Shadow_Destroy(client);
|
||||
|
||||
return rc;
|
||||
}
|
203
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/door_coap_sample.c
vendored
Normal file
203
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/door_coap_sample.c
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC_CONTENT 100
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
#define PROGRAM_NAME "door_coap_sample"
|
||||
void printUsage()
|
||||
{
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file of DeviceInfo>] \n"
|
||||
" [-t <target device name>]\n"
|
||||
" [-a <action: come_home or leave_home>]\n",
|
||||
PROGRAM_NAME);
|
||||
}
|
||||
|
||||
|
||||
void event_handler(void *pcontext, CoAPEventMessage *message)
|
||||
{
|
||||
switch (message->event_type) {
|
||||
case COAP_EVENT_RECEIVE_ACK:
|
||||
Log_i("message received ACK, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_RECEIVE_RESPCONTENT: /* not supported currently */
|
||||
break;
|
||||
case COAP_EVENT_UNAUTHORIZED:
|
||||
Log_i("coap client auth token expired or invalid, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_FORBIDDEN:
|
||||
Log_i("coap URI is invalid for this device, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_INTERNAL_SERVER_ERROR:
|
||||
Log_i("coap server internal error, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_ACK_TIMEOUT:
|
||||
Log_i("message receive ACK timeout, msgid: %d", (unsigned)(uintptr_t)message->message);
|
||||
break;
|
||||
case COAP_EVENT_SEPRESP_TIMEOUT: /* not supported currently */
|
||||
break;
|
||||
default:
|
||||
Log_e("unrecogonized event type: %d", message->event_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(CoAPInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
initParams->max_retry_count = 3;
|
||||
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
char action[16] = {0};
|
||||
char target_device_name[MAX_SIZE_OF_DEVICE_NAME+1] = {0};
|
||||
|
||||
while ((c = utils_getopt(argc, argv, "c:t:a:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
strncpy(target_device_name, utils_optarg, MAX_SIZE_OF_DEVICE_NAME);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
strncpy(action, utils_optarg, sizeof(action)-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
printUsage();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = QCLOUD_RET_SUCCESS;
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
CoAPInitParams init_params = DEFAULT_COAPINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *coap_client = IOT_COAP_Construct(&init_params);
|
||||
if (coap_client == NULL) {
|
||||
Log_e("COAP Client construct failed.");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
else {
|
||||
Log_e("%p", coap_client);
|
||||
}
|
||||
|
||||
|
||||
if(strcmp(action, "come_home") == 0 || strcmp(action, "leave_home") == 0)
|
||||
{
|
||||
char topic_content[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
SendMsgParams send_params = DEFAULT_SENDMSG_PARAMS;
|
||||
|
||||
int size = HAL_Snprintf(topic_content, sizeof(topic_content), "{\"action\": \"%s\", \"targetDevice\": \"%s\"}", action, target_device_name);
|
||||
if (size < 0 || size > sizeof(topic_content) - 1)
|
||||
{
|
||||
Log_e("payload content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_content));
|
||||
return -3;
|
||||
}
|
||||
|
||||
send_params.pay_load = topic_content;
|
||||
send_params.pay_load_len = strlen(topic_content);
|
||||
|
||||
char topicName[128] = "";
|
||||
sprintf(topicName, "%s/%s/event", sg_devInfo.product_id, sg_devInfo.device_name);
|
||||
Log_i("topic name is %s", topicName);
|
||||
|
||||
rc = IOT_COAP_SendMessage(coap_client, topicName, &send_params);
|
||||
if (rc < 0) {
|
||||
Log_e("client publish topic failed :%d.", rc);
|
||||
}
|
||||
else {
|
||||
Log_d("client topic has been sent, msg_id: %d", rc);
|
||||
}
|
||||
|
||||
rc = IOT_COAP_Yield(coap_client, 200);
|
||||
|
||||
if (rc != QCLOUD_RET_SUCCESS){
|
||||
Log_e("exit with error: %d", rc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printUsage();
|
||||
return -2;
|
||||
}
|
||||
|
||||
IOT_COAP_Destroy(&coap_client);
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
246
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/door_mqtt_sample.c
vendored
Normal file
246
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/scenarized/door_mqtt_sample.c
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_getopt.h"
|
||||
#include "qcloud_iot_export.h"
|
||||
#include "qcloud_iot_import.h"
|
||||
|
||||
#define MAX_SIZE_OF_TOPIC_CONTENT 100
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
|
||||
static bool sg_has_rev_ack = false;
|
||||
|
||||
|
||||
#define PROGRAM_NAME "door_mqtt_sample"
|
||||
void printUsage()
|
||||
{
|
||||
HAL_Printf("usage: %s [options]\n"
|
||||
" [-c <config file of DeviceInfo>] \n"
|
||||
" [-t <target device name>]\n"
|
||||
" [-a <action: come_home or leave_home>]\n",
|
||||
PROGRAM_NAME);
|
||||
}
|
||||
|
||||
|
||||
static void event_handler(void *pclient, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
sg_has_rev_ack = true;
|
||||
|
||||
switch(msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup MQTT construct parameters
|
||||
static int _setup_connect_init_params(MQTTInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
initParams->auto_connect_enable = 1;
|
||||
initParams->event_handle.h_fp = event_handler;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// publish MQTT msg
|
||||
static int _publish_msg(void *client, char* action, char* targetDeviceName)
|
||||
{
|
||||
if(NULL == action || NULL == targetDeviceName)
|
||||
return -1;
|
||||
|
||||
char topic_name[128] = {0};
|
||||
sprintf(topic_name,"%s/%s/%s", sg_devInfo.product_id, sg_devInfo.device_name, "event");
|
||||
|
||||
PublishParams pub_params = DEFAULT_PUB_PARAMS;
|
||||
pub_params.qos = QOS1;
|
||||
|
||||
char topic_content[MAX_SIZE_OF_TOPIC_CONTENT + 1] = {0};
|
||||
if(strcmp(action, "come_home") == 0 || strcmp(action, "leave_home") == 0)
|
||||
{
|
||||
int size = HAL_Snprintf(topic_content, sizeof(topic_content), "{\"action\": \"%s\", \"targetDevice\": \"%s\"}", action, targetDeviceName);
|
||||
if (size < 0 || size > sizeof(topic_content) - 1)
|
||||
{
|
||||
Log_e("payload content length not enough! content size:%d buf size:%d", size, (int)sizeof(topic_content));
|
||||
return -3;
|
||||
}
|
||||
|
||||
pub_params.payload = topic_content;
|
||||
pub_params.payload_len = strlen(topic_content);
|
||||
}
|
||||
else
|
||||
{
|
||||
printUsage();
|
||||
return -2;
|
||||
}
|
||||
|
||||
int rc = IOT_MQTT_Publish(client, topic_name, &pub_params);
|
||||
if (rc < 0) {
|
||||
Log_e("Client publish Topic:%s Failed :%d with content: %s", topic_name, rc, (char*)pub_params.payload);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
char action[16] = {0};
|
||||
char target_device_name[MAX_SIZE_OF_DEVICE_NAME+1] = {0};
|
||||
|
||||
while ((c = utils_getopt(argc, argv, "c:t:a:")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
if (HAL_SetDevInfoFile(utils_optarg))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
strncpy(target_device_name, utils_optarg, MAX_SIZE_OF_DEVICE_NAME);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
strncpy(action, utils_optarg, sizeof(action)-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
printUsage();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//init log level
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
int rc;
|
||||
|
||||
//init connection
|
||||
MQTTInitParams init_params = DEFAULT_MQTTINIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *client = IOT_MQTT_Construct(&init_params);
|
||||
if (client != NULL) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("Cloud Device Construct Failed");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
//publish msg
|
||||
rc = _publish_msg(client, action, target_device_name);
|
||||
if (rc < 0) {
|
||||
Log_e("Demo publish fail rc=%d", rc);
|
||||
}
|
||||
|
||||
while (IOT_MQTT_IsConnected(client) ||
|
||||
rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT ||
|
||||
rc == QCLOUD_RET_MQTT_RECONNECTED )
|
||||
{
|
||||
if (false != sg_has_rev_ack) break;
|
||||
Log_i("Wait for publish ack");
|
||||
rc = IOT_MQTT_Yield(client, 200);
|
||||
HAL_SleepMs(1000);
|
||||
}
|
||||
|
||||
rc = IOT_MQTT_Destroy(&client);
|
||||
|
||||
return rc;
|
||||
}
|
171
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/shadow/shadow_sample.c
vendored
Normal file
171
components/connectivity/qcloud-iot-hub-sdk-3.1.2/3rdparty/samples/shadow/shadow_sample.c
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "qcloud_iot_export.h"
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
static char sg_cert_file[PATH_MAX + 1]; // full path of device cert file
|
||||
static char sg_key_file[PATH_MAX + 1]; // full path of device key file
|
||||
#endif
|
||||
|
||||
|
||||
static DeviceInfo sg_devInfo;
|
||||
|
||||
static char sg_shadow_update_buffer[200];
|
||||
size_t sg_shadow_update_buffersize = sizeof(sg_shadow_update_buffer) / sizeof(sg_shadow_update_buffer[0]);
|
||||
|
||||
static DeviceProperty sg_shadow_property;
|
||||
static int sg_current_update_count = 0;
|
||||
static bool sg_delta_arrived = false;
|
||||
|
||||
void OnDeltaCallback(void *pClient, const char *pJsonValueBuffer, uint32_t valueLength, DeviceProperty *pProperty) {
|
||||
int rc = IOT_Shadow_JSON_ConstructDesireAllNull(pClient, sg_shadow_update_buffer, sg_shadow_update_buffersize);
|
||||
|
||||
if (rc == QCLOUD_RET_SUCCESS) {
|
||||
sg_delta_arrived = true;
|
||||
}
|
||||
else {
|
||||
Log_e("construct desire failed, err: %d", rc);
|
||||
}
|
||||
}
|
||||
|
||||
void OnShadowUpdateCallback(void *pClient, Method method, RequestAck requestAck, const char *pJsonDocument, void *pUserdata) {
|
||||
Log_i("recv shadow update response, response ack: %d", requestAck);
|
||||
}
|
||||
|
||||
static int _setup_connect_init_params(ShadowInitParams* initParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = HAL_GetDevInfo((void *)&sg_devInfo);
|
||||
if(QCLOUD_RET_SUCCESS != ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
initParams->device_name = sg_devInfo.device_name;
|
||||
initParams->product_id = sg_devInfo.product_id;
|
||||
|
||||
#ifdef AUTH_MODE_CERT
|
||||
char certs_dir[PATH_MAX + 1] = "certs";
|
||||
char current_path[PATH_MAX + 1];
|
||||
char *cwd = getcwd(current_path, sizeof(current_path));
|
||||
if (cwd == NULL)
|
||||
{
|
||||
Log_e("getcwd return NULL");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
sprintf(sg_cert_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_cert_file_name);
|
||||
sprintf(sg_key_file, "%s/%s/%s", current_path, certs_dir, sg_devInfo.dev_key_file_name);
|
||||
|
||||
initParams->cert_file = sg_cert_file;
|
||||
initParams->key_file = sg_key_file;
|
||||
#else
|
||||
initParams->device_secret = sg_devInfo.device_secret;
|
||||
#endif
|
||||
|
||||
initParams->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
initParams->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
initParams->auto_connect_enable = 1;
|
||||
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int demo_device_shadow()
|
||||
{
|
||||
int rc = QCLOUD_ERR_FAILURE;
|
||||
|
||||
void* shadow_client = NULL;
|
||||
|
||||
//init connection
|
||||
ShadowInitParams init_params = DEFAULT_SHAWDOW_INIT_PARAMS;
|
||||
rc = _setup_connect_init_params(&init_params);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("init params err,rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
shadow_client = IOT_Shadow_Construct(&init_params);
|
||||
if (shadow_client == NULL) {
|
||||
Log_e("shadow client constructed failed.");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
// register delta property
|
||||
sg_shadow_property.key = "updateCount";
|
||||
sg_shadow_property.data = &sg_current_update_count;
|
||||
sg_shadow_property.type = JINT32;
|
||||
rc = IOT_Shadow_Register_Property(shadow_client, &sg_shadow_property, OnDeltaCallback);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
rc = IOT_Shadow_Destroy(shadow_client);
|
||||
Log_e("register device shadow property failed, err: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// do get and sync operation before update
|
||||
rc = IOT_Shadow_Get_Sync(shadow_client, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
if (rc != QCLOUD_RET_SUCCESS) {
|
||||
Log_e("get device shadow failed, err: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
while (IOT_Shadow_IsConnected(shadow_client) || QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT == rc ||
|
||||
QCLOUD_RET_MQTT_RECONNECTED == rc || QCLOUD_RET_SUCCESS == rc) {
|
||||
|
||||
rc = IOT_Shadow_Yield(shadow_client, 200);
|
||||
|
||||
if (QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT == rc) {
|
||||
HAL_SleepMs(1000);
|
||||
continue;
|
||||
}
|
||||
else if (rc != QCLOUD_RET_SUCCESS && rc != QCLOUD_RET_MQTT_RECONNECTED) {
|
||||
Log_e("exit with error: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (sg_delta_arrived) {
|
||||
rc = IOT_Shadow_Update_Sync(shadow_client, sg_shadow_update_buffer, sg_shadow_update_buffersize, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
sg_delta_arrived = false;
|
||||
if (rc == QCLOUD_RET_SUCCESS)
|
||||
Log_i("shadow update success");
|
||||
}
|
||||
|
||||
IOT_Shadow_JSON_ConstructReport(shadow_client, sg_shadow_update_buffer, sg_shadow_update_buffersize, 1, &sg_shadow_property);
|
||||
rc = IOT_Shadow_Update(shadow_client, sg_shadow_update_buffer, sg_shadow_update_buffersize, OnShadowUpdateCallback, NULL, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
|
||||
sg_current_update_count++;
|
||||
|
||||
// sleep for some time in seconds
|
||||
HAL_SleepMs(1000);
|
||||
}
|
||||
|
||||
Log_e("loop exit with error: %d", rc);
|
||||
|
||||
rc = IOT_Shadow_Destroy(shadow_client);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
IOT_Log_Set_Level(eLOG_DEBUG);
|
||||
|
||||
demo_device_shadow();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user