support aliyun sdk on TencentOS tiny

sample: examples\aliyun_iotkit_csdk_mqtt
project: board\TencentOS_tiny_EVB_MX_Plus\KEIL\aliyun_iotkit_csdk_mqtt
This commit is contained in:
dcxajichu
2019-10-31 16:36:28 +08:00
parent 30ea36a7ab
commit 8c24d921b0
692 changed files with 199829 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
# README.md: alcs
## Contents
```shell
.
├── alcs_adapter.c
├── alcs_adapter.h
├── alcs_api.c
├── alcs_api.h
├── alcs_api_internal.h
├── alcs_client.c
├── alcs_coap.c
├── alcs_coap.h
├── alcs_localsetup.c
├── alcs_localsetup.h
├── alcs_mqtt.c
├── alcs_mqtt.h
├── alcs_server.c
├── aos.mk
├── CMakeLists.txt
├── Config.in
├── iot.mk
├── iotx_alcs_config.h
├── iotx_alcs.h
└── README.md
```
## Introduction
Implementation of ICA local communication service.
### Features
### Dependencies
- **hal**. osal and hal to shield different os and hardware
- **infra**. Authentication, net and so on tool set.
- **coap local**. for local communication
- **mqtt**. get token form cloud over mqtt
## API
none
## Reference
none

View File

@@ -0,0 +1,910 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stddef.h>
#include <string.h>
#include "alcs_internal.h"
#include "alcs_api.h"
#include "alcs_coap.h"
#include "alcs_mqtt.h"
#include "CoAPInternal.h"
#include "CoAPExport.h"
#include "CoAPServer.h"
#include "alcs_adapter.h"
#include "alcs_mqtt.h"
#include "alcs_localsetup.h"
#include "CoAPPlatform.h"
static iotx_alcs_adapter_t g_alcs_adapter;
static void alcs_heartbeat(void *handle);
static iotx_alcs_adapter_t *__iotx_alcs_get_ctx(void)
{
return &g_alcs_adapter;
}
static char *iotx_alcs_topic_parse_pk(char *topic, uint16_t *length)
{
char *pos = NULL;
uint8_t slash_count = 0;
uint16_t idx = 0;
uint16_t topic_len = 0;
if (topic == NULL || length == NULL) {
COAP_ERR("Invalid Parameter");
return NULL;
}
topic_len = strlen(topic);
while (idx < topic_len) {
if (topic[idx] == '/') {
slash_count++;
if (slash_count == 2) {
pos = topic + idx + 1;
}
if (slash_count == 3) {
*length = topic + idx - pos;
}
}
idx++;
}
return pos;
}
static char *iotx_alcs_topic_parse_dn(char *topic, uint16_t *length)
{
char *pos = NULL;
uint8_t slash_count = 0;
uint16_t idx = 0;
uint16_t topic_len = 0;
if (topic == NULL || length == NULL) {
COAP_ERR("Invalid Parameter");
return NULL;
}
topic_len = strlen(topic);
while (idx < topic_len) {
if (topic[idx] == '/') {
slash_count++;
if (slash_count == 3) {
pos = topic + idx + 1;
}
if (slash_count == 4) {
*length = topic + idx - pos;
}
}
idx++;
}
return pos;
}
static int _iotx_alcs_send_list_search_and_remove(iotx_alcs_adapter_t *adapter, CoAPMessage *message,
iotx_alcs_send_msg_t **send_msg)
{
iotx_alcs_send_msg_t *node = NULL;
iotx_alcs_send_msg_t *next = NULL;
list_for_each_entry_safe(node, next, &adapter->alcs_send_list, linked_list, iotx_alcs_send_msg_t) {
if (message->header.tokenlen == node->token_len &&
memcmp(message->token, node->token, node->token_len) == 0) {
*send_msg = node;
list_del(&node->linked_list);
return SUCCESS_RETURN;
}
}
return FAIL_RETURN;
}
void iotx_alcs_coap_adapter_send_msg_handle(CoAPContext *context,
CoAPReqResult result,
void *userdata,
NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)userdata;
iotx_alcs_event_msg_t event;
memset(&event, 0, sizeof(iotx_alcs_event_msg_t));
switch (result) {
case COAP_REQUEST_SUCCESS: {
iotx_alcs_transfer_msg_t transfer_msg;
iotx_alcs_send_msg_t *send_msg = NULL;
memset(&transfer_msg, 0, sizeof(iotx_alcs_transfer_msg_t));
transfer_msg.ip = (char *)remote->addr;
transfer_msg.port = remote->port;
HAL_MutexLock(adapter->mutex);
res = _iotx_alcs_send_list_search_and_remove(adapter, message, &send_msg);
HAL_MutexUnlock(adapter->mutex);
if (res < SUCCESS_RETURN) {
return;
}
transfer_msg.uri = send_msg->uri;
transfer_msg.token_len = send_msg->token_len;
transfer_msg.token = send_msg->token;
transfer_msg.payload_len = message->payloadlen;
transfer_msg.payload = message->payload;
event.event_type = IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_SUCCESS;
event.msg = &transfer_msg;
adapter->alcs_event_handle->h_fp(adapter->alcs_event_handle->pcontext, (void *)adapter, &event);
ALCS_free(send_msg->token);
ALCS_free(send_msg->uri);
ALCS_free(send_msg);
}
break;
case COAP_RECV_RESP_TIMEOUT: {
iotx_alcs_transfer_msg_t transfer_msg;
iotx_alcs_send_msg_t *send_msg = NULL;
memset(&transfer_msg, 0, sizeof(iotx_alcs_transfer_msg_t));
transfer_msg.ip = (char *)remote->addr;
transfer_msg.port = remote->port;
HAL_MutexLock(adapter->mutex);
res = _iotx_alcs_send_list_search_and_remove(adapter, message, &send_msg);
HAL_MutexUnlock(adapter->mutex);
if (res < SUCCESS_RETURN) {
return;
}
transfer_msg.uri = send_msg->uri;
transfer_msg.token_len = send_msg->token_len;
transfer_msg.token = send_msg->token;
transfer_msg.payload_len = 0;
transfer_msg.payload = NULL;
event.event_type = IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_RESP_TIMEOUT;
event.msg = &transfer_msg;
adapter->alcs_event_handle->h_fp(adapter->alcs_event_handle->pcontext, (void *)adapter, &event);
ALCS_free(send_msg->token);
ALCS_free(send_msg->uri);
ALCS_free(send_msg);
}
break;
default:
COAP_WRN("Unknown Coap Request Result: %d", result);
break;
}
}
void iotx_alcs_coap_adapter_event_notifier(unsigned int event, NetworkAddr *remote, void *message)
{
COAP_INFO("ALCS Coap Event: %d, Remote Device Address: %s, Remote Device Port: %d",
event, remote->addr, remote->port);
}
int iotx_alcs_adapter_list_init(iotx_alcs_adapter_t *adapter)
{
/* initialze send list */
INIT_LIST_HEAD(&adapter->alcs_send_list);
INIT_LIST_HEAD(&adapter->alcs_subdev_list);
return SUCCESS_RETURN;
}
static void _iotx_alcs_adapter_send_list_destroy(iotx_alcs_adapter_t *adapter)
{
iotx_alcs_send_msg_t *node = NULL;
iotx_alcs_send_msg_t *next = NULL;
list_for_each_entry_safe(node, next, &adapter->alcs_send_list, linked_list, iotx_alcs_send_msg_t) {
list_del(&node->linked_list);
ALCS_free(node->token);
ALCS_free(node->uri);
ALCS_free(node);
}
}
static void _iotx_alcs_adapter_subdev_list_destroy(iotx_alcs_adapter_t *adapter)
{
iotx_alcs_subdev_item_t *node = NULL;
iotx_alcs_subdev_item_t *next = NULL;
list_for_each_entry_safe(node, next, &adapter->alcs_subdev_list, linked_list, iotx_alcs_subdev_item_t) {
list_del(&node->linked_list);
ALCS_free(node);
}
}
int iotx_alcs_adapter_deinit(void)
{
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
HAL_GetProductKey(product_key);
HAL_GetDeviceName(device_name);
HAL_MutexLock(adapter->mutex);
_iotx_alcs_adapter_send_list_destroy(adapter);
_iotx_alcs_adapter_subdev_list_destroy(adapter);
HAL_MutexUnlock(adapter->mutex);
if (adapter->alcs_event_handle) {
ALCS_free(adapter->alcs_event_handle);
}
HAL_MutexDestroy(adapter->mutex);
alcs_mqtt_deinit(adapter->coap_ctx, product_key, device_name);
/* if (adapter->coap_ctx) CoAPContext_free(adapter->coap_ctx); */
alcs_context_deinit();
alcs_deinit();
alcs_auth_deinit();
return SUCCESS_RETURN;
}
int iotx_alcs_adapter_init(iotx_alcs_adapter_t *adapter, iotx_alcs_param_t *param)
{
int res;
CoAPInitParam coap_param;
CoAPContext *coap_ctx = NULL;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
COAP_INFO("iotx_alcs_adapter_init");
memset(&coap_param, 0, sizeof(CoAPInitParam));
adapter->mutex = HAL_MutexCreate();
if (adapter->mutex == NULL) {
COAP_ERR("Mutex Init Failed");
return FAIL_RETURN;
}
coap_param.send_maxcount = param->send_maxcount;
coap_param.obs_maxcount = param->obs_maxcount;
coap_param.port = param->port;
coap_param.group = param->group;
coap_param.waittime = param->waittime;
coap_param.res_maxcount = param->res_maxcount;
coap_param.appdata = NULL;
coap_param.notifier = iotx_alcs_coap_adapter_event_notifier;
coap_ctx = alcs_context_init(&coap_param);
if (coap_ctx == NULL) {
COAP_ERR("Coap Context Init Failed");
HAL_MutexDestroy(adapter->mutex);
return FAIL_RETURN;
}
adapter->coap_ctx = coap_ctx;
res = HAL_GetProductKey(product_key);
if (res <= 0 || res > IOTX_PRODUCT_KEY_LEN + 1 - 1) {
iotx_alcs_adapter_deinit();
COAP_ERR("Get Product Key Failed");
return FAIL_RETURN;
}
res = HAL_GetDeviceName(device_name);
if (res <= 0 || res > IOTX_DEVICE_NAME_LEN + 1 - 1) {
iotx_alcs_adapter_deinit();
COAP_ERR("Get Device Name Failed");
return FAIL_RETURN;
}
alcs_init();
res = alcs_auth_init(coap_ctx, product_key, device_name, param->role);
if (res != COAP_SUCCESS) {
iotx_alcs_adapter_deinit();
COAP_ERR("ALCS Auth Init Failed");
return FAIL_RETURN;
}
adapter->role = param->role;
#ifdef ALCS_SERVER_ENABLED
{
extern void on_svr_auth_timer(CoAPContext *);
if (adapter->role & IOTX_ALCS_ROLE_SERVER) {
adapter->alcs_server_auth_timer_func = on_svr_auth_timer;
}
}
#endif
#ifdef ALCS_CLIENT_ENABLED
{
extern void on_client_auth_timer(CoAPContext *);
if (adapter->role & IOTX_ALCS_ROLE_CLIENT) {
adapter->alcs_client_auth_timer_func = on_client_auth_timer;
}
}
#endif
adapter->alcs_event_handle = (iotx_alcs_event_handle_t *)ALCS_ADAPTER_malloc(sizeof(iotx_alcs_event_handle_t));
if (adapter->alcs_event_handle == NULL) {
iotx_alcs_adapter_deinit();
COAP_ERR("ALCS Event Handle Init Failed");
return FAIL_RETURN;
}
memcpy(adapter->alcs_event_handle, param->handle_event, sizeof(iotx_alcs_event_handle_t));
if (iotx_alcs_adapter_list_init(adapter) != SUCCESS_RETURN) {
iotx_alcs_adapter_deinit();
COAP_ERR("ALCS Linked List Init Failed");
return FAIL_RETURN;
}
alcs_localsetup_init(adapter, coap_ctx, product_key, device_name);
return SUCCESS_RETURN;
}
static int _iotx_alcs_subdev_list_search(const char *pk, const char *dn, iotx_alcs_subdev_item_t **subdev_item)
{
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
iotx_alcs_subdev_item_t *node = NULL;
if (pk == NULL || dn == NULL) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
list_for_each_entry(node, &adapter->alcs_subdev_list, linked_list, iotx_alcs_subdev_item_t) {
if (strlen(node->product_key) == strlen(pk) &&
memcmp(node->product_key, pk, strlen(pk)) == 0 &&
strlen(node->device_name) == strlen(dn) &&
memcmp(node->device_name, dn, strlen(dn)) == 0) {
*subdev_item = node;
return SUCCESS_RETURN;
}
}
return FAIL_RETURN;
}
int iotx_alcs_subdev_remove(const char *pk, const char *dn)
{
int res = 0;
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
iotx_alcs_subdev_item_t *subdev_item = NULL;
if (pk == NULL || dn == NULL) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
HAL_MutexLock(adapter->mutex);
res = _iotx_alcs_subdev_list_search(pk, dn, &subdev_item);
if (res < SUCCESS_RETURN) {
COAP_ERR("No Matched Item");
HAL_MutexUnlock(adapter->mutex);
return FAIL_RETURN;
}
list_del(&subdev_item->linked_list);
HAL_MutexUnlock(adapter->mutex);
ALCS_free(subdev_item);
return SUCCESS_RETURN;
}
int iotx_alcs_subdev_update_stage(iotx_alcs_subdev_item_t *item)
{
int res = 0;
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
iotx_alcs_subdev_item_t *subdev_item = NULL;
if (item == NULL) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
HAL_MutexLock(adapter->mutex);
res = _iotx_alcs_subdev_list_search(item->product_key, item->device_name, &subdev_item);
if (res < SUCCESS_RETURN) {
COAP_WRN("No Matched Item");
HAL_MutexUnlock(adapter->mutex);
return FAIL_RETURN;
}
subdev_item->stage = item->stage;
HAL_MutexUnlock(adapter->mutex);
return SUCCESS_RETURN;
}
void iotx_alcs_subdev_stage_check(void)
{
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
iotx_alcs_subdev_item_t *node = NULL;
uint64_t time_now = HAL_UptimeMs();
HAL_MutexLock(adapter->mutex);
list_for_each_entry(node, &adapter->alcs_subdev_list, linked_list, iotx_alcs_subdev_item_t) {
if (node->stage == IOTX_ALCS_SUBDEV_DISCONNCET_CLOUD) {
if (((time_now > node->retry_ms) &&
(time_now - node->retry_ms >= IOTX_ALCS_SUBDEV_RETRY_INTERVAL_MS)) ||
((time_now <= node->retry_ms) &&
((0xFFFFFFFFFFFFFFFF - node->retry_ms) + time_now >= IOTX_ALCS_SUBDEV_RETRY_INTERVAL_MS))) {
/* Get Prefix And Secret From Cloud */
alcs_mqtt_subdev_prefix_get(node->product_key, node->device_name);
node->retry_ms = time_now;
}
}
}
HAL_MutexUnlock(adapter->mutex);
}
void *iotx_alcs_construct(iotx_alcs_param_t *params)
{
int res = 0;
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
COAP_INFO("iotx_alcs_construct enter");
if (params == NULL || params->group == NULL ||
strlen(params->group) == 0) {
return NULL;
}
memset(adapter, 0, sizeof(iotx_alcs_adapter_t));
res = iotx_alcs_adapter_init(adapter, params);
if (res != SUCCESS_RETURN) {
COAP_ERR("Adapter Init Failed");
return NULL;
}
return (void *)adapter;
}
int iotx_alcs_cloud_init(void *handle)
{
int res = 0;
iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
COAP_INFO("Start ALCS Cloud Init");
if (adapter->local_cloud_inited == 1) {
return SUCCESS_RETURN;
}
if (handle == NULL) {
return FAIL_RETURN;
}
res = HAL_GetProductKey(product_key);
if (res <= 0 || res > IOTX_PRODUCT_KEY_LEN + 1 - 1) {
iotx_alcs_adapter_deinit();
COAP_ERR("Get Product Key Failed");
return FAIL_RETURN;
}
res = HAL_GetDeviceName(device_name);
if (res <= 0 || res > IOTX_DEVICE_NAME_LEN + 1 - 1) {
iotx_alcs_adapter_deinit();
COAP_ERR("Get Device Name Failed");
return FAIL_RETURN;
}
if (alcs_mqtt_init(adapter->coap_ctx, product_key, device_name) != ALCS_MQTT_STATUS_SUCCESS) {
/*solve the prpblem of hard fault when mqtt connection fails once*/
COAP_ERR("ALCS MQTT Init Failed");
return FAIL_RETURN;
}
adapter->local_cloud_inited = 1;
return SUCCESS_RETURN;
}
int iotx_alcs_destroy(void **phandle)
{
if (phandle == NULL || *phandle == NULL) {
return NULL_VALUE_ERROR;
}
iotx_alcs_adapter_deinit();
return SUCCESS_RETURN;
}
static void alcs_heartbeat(void *handle)
{
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
if (adapter->role & IOTX_ALCS_ROLE_SERVER && adapter->alcs_server_auth_timer_func != NULL) {
adapter->alcs_server_auth_timer_func(adapter->coap_ctx);
}
if (adapter->role & IOTX_ALCS_ROLE_CLIENT && adapter->alcs_client_auth_timer_func != NULL) {
adapter->alcs_client_auth_timer_func(adapter->coap_ctx);
}
}
int iotx_alcs_yield(void *handle)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
if (adapter == NULL || adapter->coap_ctx == NULL) {
return NULL_VALUE_ERROR;
}
alcs_heartbeat(handle);
iotx_alcs_subdev_stage_check();
return res;
}
int iotx_alcs_send(void *handle, iotx_alcs_msg_t *msg)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
CoAPMessage coap_msg;
CoAPLenString coap_payload;
NetworkAddr network_addr;
AlcsDeviceKey devKey;
char productKey[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char deviceName[IOTX_DEVICE_NAME_LEN + 1] = {0};
char *uri_pk = NULL;
char *uri_dn = NULL;
uint16_t uri_pk_len = 0;
uint16_t uri_dn_len = 0;
iotx_alcs_send_msg_t *alcs_send_msg = NULL;
if (adapter == NULL || adapter->coap_ctx ||
msg == NULL || msg->payload == NULL ||
msg->ip == NULL || strlen(msg->ip) == 0 ||
msg->uri == NULL || strlen(msg->uri) == 0) {
return NULL_VALUE_ERROR;
}
if (strlen(msg->ip) > NETWORK_ADDR_LEN) {
COAP_ERR("Invalid Ip Address Length");
return FAIL_RETURN;
}
memset(&coap_msg, 0, sizeof(CoAPMessage));
memset(&coap_payload, 0, sizeof(CoAPLenString));
coap_payload.len = msg->payload_len;
coap_payload.data = msg->payload;
alcs_msg_init(adapter->coap_ctx, &coap_msg, msg->msg_code, msg->msg_type, 0, &coap_payload, (void *)adapter);
res = alcs_msg_setAddr(&coap_msg, msg->uri, NULL);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Message Set URI Failed");
return FAIL_RETURN;
}
memset(&network_addr, 0, sizeof(NetworkAddr));
memcpy(network_addr.addr, msg->ip, strlen(msg->ip));
network_addr.port = msg->port;
memset(&devKey, 0, sizeof(AlcsDeviceKey));
memcpy(&devKey.addr, &network_addr, sizeof(NetworkAddr));
uri_pk = iotx_alcs_topic_parse_pk(msg->uri, &uri_pk_len);
uri_dn = iotx_alcs_topic_parse_dn(msg->uri, &uri_dn_len);
if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
memcpy(productKey, uri_pk, uri_pk_len);
memcpy(deviceName, uri_dn, uri_dn_len);
devKey.pk = productKey;
devKey.dn = deviceName;
res = alcs_sendmsg_secure(adapter->coap_ctx, &devKey, &coap_msg, 2, iotx_alcs_coap_adapter_send_msg_handle);
alcs_msg_deinit(&coap_msg);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Message Send Message Failed");
return FAIL_RETURN;
}
alcs_send_msg = (iotx_alcs_send_msg_t *)ALCS_ADAPTER_malloc(sizeof(iotx_alcs_send_msg_t));
if (alcs_send_msg == NULL) {
COAP_WRN("Not Enough Memory");
return FAIL_RETURN;
}
memset(alcs_send_msg, 0, sizeof(iotx_alcs_send_msg_t));
alcs_send_msg->token = (uint8_t *)ALCS_ADAPTER_malloc(coap_msg.header.tokenlen + 1);
if (alcs_send_msg->token == NULL) {
ALCS_free(alcs_send_msg);
COAP_WRN("Not Enough Memory");
return FAIL_RETURN;
}
alcs_send_msg->token_len = coap_msg.header.tokenlen;
memset(alcs_send_msg->token, 0, alcs_send_msg->token_len + 1);
memcpy(alcs_send_msg->token, coap_msg.token, alcs_send_msg->token_len);
alcs_send_msg->uri = (char *)ALCS_ADAPTER_malloc(strlen(msg->uri) + 1);
if (alcs_send_msg->uri == NULL) {
ALCS_free(alcs_send_msg->token);
ALCS_free(alcs_send_msg);
COAP_WRN("ALCS Message Buffer Failed");
return FAIL_RETURN;
}
memset(alcs_send_msg->uri, 0, strlen(msg->uri) + 1);
memcpy(alcs_send_msg->uri, msg->uri, strlen(msg->uri));
INIT_LIST_HEAD(&alcs_send_msg->linked_list);
HAL_MutexLock(adapter->mutex);
list_add_tail(&alcs_send_msg->linked_list, &adapter->alcs_send_list);
HAL_MutexUnlock(adapter->mutex);
return SUCCESS_RETURN;
}
int iotx_alcs_send_Response(void *handle, iotx_alcs_msg_t *msg, uint8_t token_len, uint8_t *token)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
CoAPMessage coap_msg;
CoAPLenString coap_payload;
CoAPLenString token_payload;
NetworkAddr network_addr;
AlcsDeviceKey devKey;
char productKey[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char deviceName[IOTX_DEVICE_NAME_LEN + 1] = {0};
char *uri_pk = NULL;
char *uri_dn = NULL;
uint16_t uri_pk_len = 0;
uint16_t uri_dn_len = 0;
if (adapter == NULL || adapter->coap_ctx == NULL ||
msg == NULL || msg->payload == NULL ||
msg->ip == NULL || strlen(msg->ip) == 0 ||
msg->uri == NULL || strlen(msg->uri) == 0) {
return NULL_VALUE_ERROR;
}
if (token_len == 0 || token == NULL) {
return FAIL_RETURN;
}
if (strlen(msg->ip) > NETWORK_ADDR_LEN) {
COAP_ERR("Invalid Ip Address Length");
return FAIL_RETURN;
}
memset(&coap_msg, 0, sizeof(CoAPMessage));
memset(&coap_payload, 0, sizeof(CoAPLenString));
memset(&token_payload, 0, sizeof(CoAPLenString));
coap_payload.len = msg->payload_len;
coap_payload.data = msg->payload;
alcs_msg_init(adapter->coap_ctx, &coap_msg, msg->msg_code, msg->msg_type, 0, &coap_payload, (void *)adapter);
res = alcs_msg_setAddr(&coap_msg, msg->uri, NULL);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Message Set URI Failed");
return FAIL_RETURN;
}
memset(&network_addr, 0, sizeof(NetworkAddr));
memcpy(network_addr.addr, msg->ip, strlen(msg->ip));
network_addr.port = msg->port;
token_payload.len = token_len;
token_payload.data = token;
memset(&devKey, 0, sizeof(AlcsDeviceKey));
memcpy(&devKey.addr, &network_addr, sizeof(NetworkAddr));
uri_pk = iotx_alcs_topic_parse_pk(msg->uri, &uri_pk_len);
uri_dn = iotx_alcs_topic_parse_dn(msg->uri, &uri_dn_len);
if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
memcpy(productKey, uri_pk, uri_pk_len);
memcpy(deviceName, uri_dn, uri_dn_len);
devKey.pk = productKey;
devKey.dn = deviceName;
if (alcs_resource_need_auth(adapter->coap_ctx, msg->uri)) {
res = alcs_sendrsp_secure(adapter->coap_ctx, &devKey, &coap_msg, 0, 0, &token_payload);
} else {
res = alcs_sendrsp(adapter->coap_ctx, &network_addr, &coap_msg, 0, 0, &token_payload);
}
alcs_msg_deinit(&coap_msg);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Message Send Message Failed");
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int iotx_alcs_register_resource(void *handle, iotx_alcs_res_t *resource)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
char productKey[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char deviceName[IOTX_DEVICE_NAME_LEN + 1] = {0};
char *uri_pk = NULL;
char *uri_dn = NULL;
uint16_t uri_pk_len = 0;
uint16_t uri_dn_len = 0;
int needAuth = 0;
if (adapter == NULL || adapter->coap_ctx == NULL ||
resource->uri == NULL || strlen(resource->uri) == 0) {
return NULL_VALUE_ERROR;
}
uri_pk = iotx_alcs_topic_parse_pk(resource->uri, &uri_pk_len);
uri_dn = iotx_alcs_topic_parse_dn(resource->uri, &uri_dn_len);
if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
memcpy(productKey, uri_pk, uri_pk_len);
memcpy(deviceName, uri_dn, uri_dn_len);
COAP_INFO("alcs register resource, uri:%s", resource->uri);
needAuth = resource->need_auth; /* strcmp (resource->uri, "/dev/core/service/dev"); */
res = alcs_resource_register(adapter->coap_ctx,
productKey,
deviceName,
resource->uri,
resource->msg_perm,
resource->msg_ct,
resource->maxage,
needAuth,
(void (*)(CoAPContext * context, const char *paths, NetworkAddr * remote,
CoAPMessage * message))resource->callback);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Register Resource Failed, Code: %d", res);
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int iotx_alcs_observe_notify(void *handle, const char *uri, uint32_t payload_len, uint8_t *payload)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
CoAPLenString coap_payload;
coap_payload.len = (int32_t)payload_len;
coap_payload.data = payload;
res = alcs_observe_notify(adapter->coap_ctx, uri, &coap_payload);
if (res != COAP_SUCCESS) {
COAP_ERR("ALCS Observe Notify Failed, Code: %d", res);
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int iotx_alcs_unregister_resource(void *handle, char *uri)
{
return SUCCESS_RETURN;
}
int iotx_alcs_add_sub_device(void *handle, const char *pk, const char *dn)
{
int res = 0;
iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
iotx_alcs_subdev_item_t *subdev_item = NULL;
char prefix[ALCS_MQTT_PREFIX_MAX_LEN] = {0};
char secret[ALCS_MQTT_SECRET_MAX_LEN] = {0};
if (handle == NULL || pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Argument");
return FAIL_RETURN;
}
if (adapter->coap_ctx != NULL) {
alcs_auth_subdev_init(adapter->coap_ctx, pk, dn);
}
/* Search Subdev In Linked List */
HAL_MutexLock(adapter->mutex);
res = _iotx_alcs_subdev_list_search(pk, dn, &subdev_item);
if (res == SUCCESS_RETURN) {
COAP_INFO("This Product Key And Device Name Have Been Added");
HAL_MutexUnlock(adapter->mutex);
return SUCCESS_RETURN;
}
HAL_MutexUnlock(adapter->mutex);
/* Insert New Subdev Into Linked List */
subdev_item = (iotx_alcs_subdev_item_t *)ALCS_ADAPTER_malloc(sizeof(iotx_alcs_subdev_item_t));
if (subdev_item == NULL) {
COAP_ERR("No Enough Memory");
return FAIL_RETURN;
}
memset(subdev_item, 0, sizeof(iotx_alcs_subdev_item_t));
/* Set Product Key And Device Name */
memcpy(subdev_item->product_key, pk, strlen(pk));
memcpy(subdev_item->device_name, dn, strlen(dn));
subdev_item->stage = IOTX_ALCS_SUBDEV_DISCONNCET_CLOUD;
subdev_item->retry_ms = HAL_UptimeMs();
INIT_LIST_HEAD(&subdev_item->linked_list);
HAL_MutexLock(adapter->mutex);
list_add_tail(&subdev_item->linked_list, &adapter->alcs_subdev_list);
HAL_MutexUnlock(adapter->mutex);
alcs_localsetup_add_sub_device(adapter, subdev_item->product_key, subdev_item->device_name);
/* Get Prefix And Secret From KV */
res = alcs_mqtt_prefix_secret_load(pk, strlen(pk), dn, strlen(dn), prefix, secret);
if (res == SUCCESS_RETURN) {
memcpy(subdev_item->prefix, prefix, strlen(prefix));
memcpy(subdev_item->secret, secret, strlen(secret));
alcs_mqtt_add_srv_key(prefix, secret);
}
/* Get Prefix And Secret From Cloud */
alcs_mqtt_subdev_prefix_get(pk, dn);
return SUCCESS_RETURN;
}
int iotx_alcs_remove_sub_device(void *handle, const char *pk, const char *dn)
{
int res = 0;
if (handle == NULL || pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return FAIL_RETURN;
}
res = iotx_alcs_subdev_remove(pk, dn);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Remove Subdev Item From KV */
alcs_mqtt_prefix_secret_del(pk, strlen(pk), dn, strlen(dn));
return SUCCESS_RETURN;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef __ALCS_ADAPTER_H__
#define __ALCS_ADAPTER_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include "alcs_internal.h"
#include "mqtt_api.h"
#include "CoAPExport.h"
#include "alcs_mqtt.h"
#include "iotx_alcs.h"
typedef struct iotx_alcs_send_msg_st {
uint8_t token_len;
uint8_t *token;
char *uri;
struct list_head linked_list;
} iotx_alcs_send_msg_t, *iotx_alcs_send_msg_pt;
typedef enum {
IOTX_ALCS_SUBDEV_DISCONNCET_CLOUD,
IOTX_ALCS_SUBDEV_CONNECT_CLOUD
} iotx_alcs_subdev_stage_t;
#define IOTX_ALCS_SUBDEV_RETRY_INTERVAL_MS (10000)
typedef struct iotx_alcs_subdev_item_st {
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
char prefix[ALCS_MQTT_PREFIX_MAX_LEN];
char secret[ALCS_MQTT_SECRET_MAX_LEN];
uint8_t stage;
uint64_t retry_ms;
struct list_head linked_list;
} iotx_alcs_subdev_item_t, *iotx_alcs_subdev_item_pt;
typedef void (*iotx_alcs_auth_timer_fnuc_t)(CoAPContext *);
typedef struct iotx_alcs_adapter_st {
void *mutex;
int local_cloud_inited;
CoAPContext *coap_ctx;
uint8_t role;
iotx_alcs_auth_timer_fnuc_t alcs_client_auth_timer_func;
iotx_alcs_auth_timer_fnuc_t alcs_server_auth_timer_func;
iotx_alcs_event_handle_t *alcs_event_handle;
struct list_head alcs_send_list;
struct list_head alcs_subdev_list;
char local_ip[NETWORK_ADDR_LEN];
uint16_t local_port;
} iotx_alcs_adapter_t, *iotx_alcs_adapter_pt;
int iotx_alcs_subdev_insert(iotx_alcs_subdev_item_t *item);
int iotx_alcs_subdev_remove(const char *pk, const char *dn);
int iotx_alcs_subdev_search(const char *pk, const char *dn, iotx_alcs_subdev_item_t **item);
int iotx_alcs_subdev_update_stage(iotx_alcs_subdev_item_t *item);
void iotx_alcs_send_list_handle(void *list_node, va_list *params);
int iotx_alcs_adapter_list_init(iotx_alcs_adapter_t *adapter);
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,725 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdlib.h>
#include <time.h>
#include "alcs_internal.h"
#include "alcs_api.h"
#include "alcs_coap.h"
#include "alcs_api_internal.h"
#include "CoAPPlatform.h"
#include "CoAPObserve.h"
LIST_HEAD(secure_resource_cb_head);
static bool is_inited = 0;
#ifdef SUPPORT_MULTI_DEVICES
LIST_HEAD(device_list);
device_auth_list *get_device(CoAPContext *context)
{
device_auth_list *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, &device_list, lst, device_auth_list) {
if (node->context == context) {
return node;
}
}
return NULL;
}
auth_list *get_list(CoAPContext *context)
{
device_auth_list *dev_lst = get_device(context);
return dev_lst ? &dev_lst->lst_auth : NULL;
}
#ifdef ALCS_CLIENT_ENABLED
struct list_head *get_ctl_session_list(CoAPContext *context)
{
device_auth_list *dev_lst = get_device(context);
if (!dev_lst || !(dev_lst->role & ROLE_CLIENT)) {
return NULL;
}
return &dev_lst->lst_ctl_sessions;
}
#endif
#ifdef ALCS_SERVER_ENABLED
struct list_head *get_svr_session_list(CoAPContext *context)
{
device_auth_list *dev_lst = get_device(context);
return dev_lst && (dev_lst->role & ROLE_SERVER) ? &dev_lst->lst_svr_sessions : NULL;
}
#endif
#else
device_auth_list _device;
#endif
void remove_session(CoAPContext *ctx, session_item *session)
{
COAP_INFO("remove_session");
if (session) {
CoapObsServerAll_delete(ctx, &session->addr);
list_del(&session->lst);
coap_free(session);
}
}
session_item *get_session_by_checksum(struct list_head *sessions, NetworkAddr *addr, char ck[PK_DN_CHECKSUM_LEN])
{
session_item *node = NULL, *next = NULL;
if (!sessions || !ck) {
return NULL;
}
list_for_each_entry_safe(node, next, sessions, lst, session_item) {
if (is_networkadd_same(addr, &node->addr)
&& strncmp(node->pk_dn, ck, PK_DN_CHECKSUM_LEN) == 0) {
COAP_DEBUG("find node, sessionid:%d", node->sessionId);
return node;
}
}
return NULL;
}
static session_item *get_session(struct list_head *sessions, AlcsDeviceKey *devKey)
{
char ck[PK_DN_CHECKSUM_LEN] = {0};
char path[100] = {0};
if (!sessions || !devKey || !devKey->pk || !devKey->dn) {
return NULL;
}
HAL_Snprintf(path, sizeof(path), "%s%s", devKey->pk, devKey->dn);
CoAPPathMD5_sum(path, strlen(path), ck, PK_DN_CHECKSUM_LEN);
return get_session_by_checksum(sessions, &devKey->addr, ck);
}
#ifdef ALCS_CLIENT_ENABLED
session_item *get_ctl_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
{
struct list_head *sessions = get_ctl_session_list(ctx);
COAP_DEBUG("get_ctl_session");
return get_session(sessions, devKey);
}
#endif
#ifdef ALCS_SERVER_ENABLED
session_item *get_svr_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
{
struct list_head *sessions = get_svr_session_list(ctx);
return get_session(sessions, devKey);
}
#endif
static session_item *get_auth_session(CoAPContext *ctx, AlcsDeviceKey *devKey)
{
#ifdef ALCS_CLIENT_ENABLED
session_item *node = get_ctl_session(ctx, devKey);
if (node && node->sessionId) {
return node;
}
#endif
#ifdef ALCS_SERVER_ENABLED
session_item *node1 = get_svr_session(ctx, devKey);
if (node1 && node1->sessionId) {
return node1;
}
#endif
return NULL;
}
static session_item *get_auth_session_by_checksum(CoAPContext *ctx, NetworkAddr *addr, char ck[])
{
#ifdef ALCS_CLIENT_ENABLED
struct list_head *sessions = get_ctl_session_list(ctx);
session_item *node = get_session_by_checksum(sessions, addr, ck);
if (node && node->sessionId) {
return node;
}
#endif
#ifdef ALCS_SERVER_ENABLED
struct list_head *sessions1 = get_svr_session_list(ctx);
session_item *node1 = get_session_by_checksum(sessions1, addr, ck);
if (node1 && node1->sessionId) {
return node1;
}
#endif
return NULL;
}
void gen_random_key(unsigned char random[], int len)
{
int i = 0, flag = 0;
memset(random, 0x00, len);
srand((unsigned)time(NULL));
for (i = 0; i < len - 1; i++) {
flag = rand() % 3;
switch (flag) {
case 0:
random[i] = 'A' + rand() % 26;
break;
case 1:
random[i] = 'a' + rand() % 26;
break;
case 2:
random[i] = '0' + rand() % 10;
break;
default:
random[i] = 'x';
break;
}
}
}
#ifdef ALCS_SERVER_ENABLED
extern void alcs_rec_auth_select(CoAPContext *context, const char *paths, NetworkAddr *remote, CoAPMessage *request);
extern void alcs_rec_auth(CoAPContext *context, const char *paths, NetworkAddr *remote, CoAPMessage *request);
extern void alcs_rec_heart_beat(CoAPContext *context, const char *paths, NetworkAddr *remote, CoAPMessage *request);
#endif
int alcs_auth_init(CoAPContext *ctx, const char *productKey, const char *deviceName, char role)
{
device_auth_list *dev;
#ifdef ALCS_SERVER_ENABLED
char path[256];
#endif
if (is_inited) {
return 0;
}
is_inited = 1;
/* auth_list* lst_auth; */
#ifdef SUPPORT_MULTI_DEVICES
INIT_LIST_HEAD(&device_list);
dev = coap_malloc(sizeof(device_auth_list));
list_add_tail(&dev->lst, &device_list);
#else
dev = &_device;
#endif
dev->context = ctx;
dev->seq = 1;
dev->role = role;
memset(&dev->lst_auth, 0, sizeof(auth_list));
/* strcpy (dev->deviceName, deviceName); */
/* strcpy (dev->productKey, productKey); */
INIT_LIST_HEAD(&dev->lst);
INIT_LIST_HEAD(&secure_resource_cb_head);
if (role & ROLE_SERVER) {
#ifdef ALCS_SERVER_ENABLED
INIT_LIST_HEAD(&dev->lst_svr_sessions);
INIT_LIST_HEAD(&dev->lst_auth.lst_svr);
HAL_Snprintf(path, sizeof(path), "/dev/%s/%s/core/service/auth", productKey, deviceName);
alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET, COAP_CT_APP_JSON, 60, 0, alcs_rec_auth);
strcat(path, "/select");
alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET, COAP_CT_APP_JSON, 60, 0, alcs_rec_auth_select);
alcs_resource_register(ctx, productKey, deviceName, "/dev/core/service/heartBeat", COAP_PERM_GET, COAP_CT_APP_JSON, 60,
0, alcs_rec_heart_beat);
#endif
}
if (role & ROLE_CLIENT) {
#ifdef ALCS_CLIENT_ENABLED
INIT_LIST_HEAD(&dev->lst_ctl_sessions);
INIT_LIST_HEAD(&dev->lst_auth.lst_ctl);
#endif
}
INIT_LIST_HEAD(&dev->lst_auth.lst_ctl_group);
INIT_LIST_HEAD(&dev->lst_auth.lst_svr_group);
dev->lst_auth.list_mutex = HAL_MutexCreate();
return COAP_SUCCESS;
}
void alcs_auth_subdev_init(CoAPContext *ctx, const char *productKey, const char *deviceName)
{
char path[256];
HAL_Snprintf(path, sizeof(path), "/dev/%s/%s/core/service/auth", productKey, deviceName);
alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET, COAP_CT_APP_JSON, 60, 0, alcs_rec_auth);
strcat(path, "/select");
alcs_resource_register(ctx, productKey, deviceName, path, COAP_PERM_GET, COAP_CT_APP_JSON, 60, 0, alcs_rec_auth_select);
}
void alcs_auth_deinit(void)
{
#ifdef SUPPORT_MULTI_DEVICES
device_auth_list *node = NULL, *next = NULL;
#endif
if (is_inited == 0) {
return;
}
is_inited = 0;
alcs_resource_cb_deinit();
alcs_auth_list_deinit();
#ifdef SUPPORT_MULTI_DEVICES
list_for_each_entry_safe(node, next, &device_list, lst, device_auth_list) {
if (node->lst_auth.list_mutex) {
HAL_MutexDestroy(node->lst_auth.list_mutex);
node->lst_auth.list_mutex = NULL;
}
}
#else
if (_device.lst_auth.list_mutex) {
HAL_MutexDestroy(_device.lst_auth.list_mutex);
_device.lst_auth.list_mutex = NULL;
}
#endif
}
bool is_networkadd_same(NetworkAddr *addr1, NetworkAddr *addr2)
{
if (!addr1 || !addr2) {
return 0;
}
COAP_DEBUG("compare addr1:%s,addr2:%s", addr1->addr, addr2->addr);
return addr1->port == addr2->port && !strcmp((const char *)addr1->addr, (const char *)addr2->addr);
}
int alcs_encrypt(const char *src, int len, const char *key, void *out)
{
char *iv = "a1b1c1d1e1f1g1h1";
int len1 = len & 0xfffffff0;
int len2 = len1 + 16;
int pad = len2 - len;
int ret = 0;
if (len1) {
p_HAL_Aes128_t aes_e_h = HAL_Aes128_Init((uint8_t *)key, (uint8_t *)iv, HAL_AES_ENCRYPTION);
ret = HAL_Aes128_Cbc_Encrypt(aes_e_h, src, len1 >> 4, out);
HAL_Aes128_Destroy(aes_e_h);
}
if (!ret && pad) {
char buf[16];
p_HAL_Aes128_t aes_e_h = NULL;
memcpy(buf, src + len1, len - len1);
memset(buf + len - len1, pad, pad);
aes_e_h = HAL_Aes128_Init((uint8_t *)key, (uint8_t *)iv, HAL_AES_ENCRYPTION);
ret = HAL_Aes128_Cbc_Encrypt(aes_e_h, buf, 1, (uint8_t *)out + len1);
HAL_Aes128_Destroy(aes_e_h);
}
COAP_DEBUG("to encrypt src:%s, len:%d", src, len2);
return ret == 0 ? len2 : 0;
}
int alcs_decrypt(const char *src, int len, const char *key, void *out)
{
char *iv = "a1b1c1d1e1f1g1h1";
p_HAL_Aes128_t aes_d_h;
int n = len >> 4;
char *out_c = NULL;
int offset = 0;
int ret = 0;
char pad = 0;
COAP_DEBUG("to decrypt len:%d", len);
do {
if (n > 1) {
aes_d_h = HAL_Aes128_Init((uint8_t *)key, (uint8_t *)iv, HAL_AES_DECRYPTION);
if (!aes_d_h) {
COAP_ERR("fail to decrypt init");
break;
}
ret = HAL_Aes128_Cbc_Decrypt(aes_d_h, src, n - 1, out);
HAL_Aes128_Destroy(aes_d_h);
if (ret != 0) {
COAP_ERR("fail to decrypt");
break;
}
}
out_c = (char *)out;
offset = n > 0 ? ((n - 1) << 4) : 0;
out_c[offset] = 0;
aes_d_h = HAL_Aes128_Init((uint8_t *)key, (uint8_t *)iv, HAL_AES_DECRYPTION);
if (!aes_d_h) {
COAP_ERR("fail to decrypt init");
break;
}
ret = HAL_Aes128_Cbc_Decrypt(aes_d_h, src + offset, 1, out_c + offset);
HAL_Aes128_Destroy(aes_d_h);
if (ret != 0) {
COAP_ERR("fail to decrypt remain data");
break;
}
pad = out_c[len - 1];
out_c[len - pad] = 0;
COAP_DEBUG("decrypt data:%s, len:%d", out_c, len - pad);
return len - pad;
} while (0);
return 0;
}
bool alcs_is_auth(CoAPContext *ctx, AlcsDeviceKey *devKey)
{
return get_auth_session(ctx, devKey) != NULL;
}
/*---------------------------------------------------------*/
typedef struct {
void *orig_user_data;
char pk_dn[PK_DN_CHECKSUM_LEN];
CoAPSendMsgHandler orig_handler;
} secure_send_item;
static int do_secure_send(CoAPContext *ctx, NetworkAddr *addr, CoAPMessage *message, const char *key, char *buf)
{
int ret = COAP_SUCCESS;
void *payload_old = message->payload;
int len_old = message->payloadlen;
COAP_DEBUG("do_secure_send");
message->payload = (unsigned char *)buf;
message->payloadlen = alcs_encrypt((const char *)payload_old, len_old, key, message->payload);
ret = CoAPMessage_send(ctx, addr, message);
message->payload = payload_old;
message->payloadlen = len_old;
return ret;
}
void secure_sendmsg_handler(CoAPContext *context, CoAPReqResult result, void *userdata, NetworkAddr *remote,
CoAPMessage *message);
int internal_secure_send(CoAPContext *ctx, session_item *session, NetworkAddr *addr, CoAPMessage *message, char observe,
CoAPSendMsgHandler handler)
{
int encryptlen = 0;
COAP_DEBUG("internal_secure_send");
if (!ctx || !session || !addr || !message) {
COAP_ERR("parameter is null");
return COAP_ERROR_INVALID_PARAM;
}
if (handler) {
secure_send_item *item = (secure_send_item *)coap_malloc(sizeof(secure_send_item));
item->orig_user_data = message->user;
item->orig_handler = handler;
memcpy(item->pk_dn, session->pk_dn, PK_DN_CHECKSUM_LEN);
message->handler = secure_sendmsg_handler;
message->user = item;
}
if (observe == 0) {
CoAPUintOption_add(message, COAP_OPTION_OBSERVE, observe);
}
CoAPUintOption_add(message, COAP_OPTION_CONTENT_FORMAT, COAP_CT_APP_OCTET_STREAM);
CoAPUintOption_add(message, COAP_OPTION_SESSIONID, session->sessionId);
COAP_DEBUG("secure_send sessionId:%d", session->sessionId);
encryptlen = (message->payloadlen & 0xfffffff0) + 16;
if (encryptlen > 64) {
char *buf = (char *)coap_malloc(encryptlen);
int rt = do_secure_send(ctx, addr, message, session->sessionKey, buf);
coap_free(buf);
return rt;
} else {
char buf[64];
return do_secure_send(ctx, addr, message, session->sessionKey, buf);
}
}
static void call_cb(CoAPContext *context, NetworkAddr *remote, CoAPMessage *message, const char *key, char *buf,
secure_send_item *send_item)
{
if (send_item->orig_handler) {
int len = alcs_decrypt((const char *)message->payload, message->payloadlen, key, buf);
CoAPMessage tmpMsg;
memcpy(&tmpMsg, message, sizeof(CoAPMessage));
tmpMsg.payload = (unsigned char *)buf;
tmpMsg.payloadlen = len;
send_item->orig_handler(context, COAP_REQUEST_SUCCESS, send_item->orig_user_data, remote, &tmpMsg);
}
}
void secure_sendmsg_handler(CoAPContext *context, CoAPReqResult result, void *userdata, NetworkAddr *remote,
CoAPMessage *message)
{
secure_send_item *send_item = (secure_send_item *)userdata;
session_item *session = NULL;
unsigned int obsVal;
if (!context || !userdata || !remote) {
return;
}
if (result == COAP_RECV_RESP_TIMEOUT) {
if (send_item->orig_handler) {
send_item->orig_handler(context, COAP_RECV_RESP_TIMEOUT, send_item->orig_user_data, remote, NULL);
}
COAP_INFO("secure_sendmsg_handler timeout");
} else {
unsigned int sessionId = 0;
CoAPUintOption_get(message, COAP_OPTION_SESSIONID, &sessionId);
COAP_DEBUG("secure_sendmsg_handler, sessionID:%d", (int)sessionId);
session = get_auth_session_by_checksum(context, remote, send_item->pk_dn);
if (!session || session->sessionId != sessionId) {
COAP_ERR("secure_sendmsg_handler, need auth, from:%s", remote->addr);
/* todo */
} else {
session->heart_time = HAL_UptimeMs();
if (message->payloadlen < 128) {
char buf[128];
call_cb(context, remote, message, session->sessionKey, buf, send_item);
} else {
char *buf = (char *)coap_malloc(message->payloadlen);
if (buf) {
call_cb(context, remote, message, session->sessionKey, buf, send_item);
coap_free(buf);
}
}
}
}
if (CoAPUintOption_get(message, COAP_OPTION_OBSERVE, &obsVal) != COAP_SUCCESS) {
coap_free(send_item);
}
}
int alcs_sendmsg_secure(CoAPContext *ctx, AlcsDeviceKey *devKey, CoAPMessage *message, char observe,
CoAPSendMsgHandler handler)
{
session_item *session = NULL;
if (!ctx || !devKey || !message) {
return COAP_ERROR_INVALID_PARAM;
}
session = get_auth_session(ctx, devKey);
if (!session) {
COAP_DEBUG("alcs_sendmsg_secure, session not found");
return ALCS_ERR_AUTH_UNAUTH;
}
return internal_secure_send(ctx, session, &devKey->addr, message, observe, handler);
}
int alcs_sendrsp_secure(CoAPContext *ctx, AlcsDeviceKey *devKey, CoAPMessage *message, char observe,
unsigned short msgid, CoAPLenString *token)
{
session_item *session = NULL;
COAP_DEBUG("alcs_sendrsp_secure");
if (!ctx || !devKey || !message) {
return COAP_ERROR_INVALID_PARAM;
}
if (msgid == 0) {
message->header.msgid = CoAPMessageId_gen(ctx);
} else {
message->header.msgid = msgid;
}
if (token) {
message->header.tokenlen = token->len;
memcpy(&message->token, token->data, token->len);
}
session = get_auth_session(ctx, devKey);
if (!session) {
COAP_DEBUG("alcs_sendrsp_secure, session not found");
return ALCS_ERR_AUTH_UNAUTH;
}
return internal_secure_send(ctx, session, &devKey->addr, message, observe, NULL);
}
bool req_payload_parser(const char *payload, int len, char **seq, int *seqlen, char **data, int *datalen)
{
if (!payload || !len || !seq || !seqlen || !datalen || !data) {
return 0;
}
*seq = json_get_value_by_name((char *)payload, len, "id", seqlen, NULL);
*data = json_get_value_by_name((char *)payload, len, "params", datalen, NULL);
return *data && datalen;
}
void on_auth_timer(void *param)
{
CoAPContext *ctx = NULL;
if (!is_inited) {
return;
}
ctx = (CoAPContext *) param;
#ifdef ALCS_CLIENT_ENABLED
{
extern void on_client_auth_timer(CoAPContext *);
on_client_auth_timer(ctx);
}
#endif
#ifdef ALCS_SERVER_ENABLED
{
extern void on_svr_auth_timer(CoAPContext *);
on_svr_auth_timer(ctx);
}
#endif
}
int alcs_add_ctl_group(CoAPContext *context, const char *groupid, const char *accesskey, const char *accesstoken)
{
ctl_group_item *item = NULL;
auth_list *lst = get_list(context);
if (!lst || lst->ctl_group_count >= KEY_MAXCOUNT) {
return COAP_ERROR_INVALID_LENGTH;
}
item = (ctl_group_item *) coap_malloc(sizeof(ctl_group_item));
if (!item) {
return COAP_ERROR_MALLOC;
}
memset(item, 0, sizeof(ctl_group_item));
do {
item->id = (char *) coap_malloc(strlen(groupid) + 1);
if (!item->id) {
break;
}
item->accessKey = (char *) coap_malloc(strlen(accesskey) + 1);
if (!item->accessKey) {
break;
}
item->accessToken = (char *) coap_malloc(strlen(accesstoken) + 1);
if (!item->accessToken) {
break;
}
strcpy(item->accessKey, accesskey);
strcpy(item->accessToken, accesstoken);
strcpy(item->id, groupid);
HAL_MutexLock(lst->list_mutex);
list_add_tail(&item->lst, &lst->lst_ctl_group);
++lst->ctl_group_count;
HAL_MutexUnlock(lst->list_mutex);
return 0;
} while (0);
if (item->id) {
coap_free(item->id);
}
if (item->accessKey) {
coap_free(item->accessKey);
}
if (item->accessToken) {
coap_free(item->accessToken);
}
coap_free(item);
return COAP_ERROR_MALLOC;
}
int alcs_remove_ctl_group(CoAPContext *context, const char *groupid)
{
return 0;
}
int alcs_add_svr_group(CoAPContext *context, const char *groupid, const char *keyprefix, const char *secret)
{
svr_group_item *item = NULL;
auth_list *lst = get_list(context);
if (!lst || lst->svr_group_count >= KEY_MAXCOUNT) {
return COAP_ERROR_INVALID_LENGTH;
}
item = (svr_group_item *) coap_malloc(sizeof(svr_group_item));
if (!item) {
return COAP_ERROR_MALLOC;
}
memset(item, 0, sizeof(svr_group_item));
do {
item->id = (char *) coap_malloc(strlen(groupid) + 1);
if (!item->id) {
break;
}
item->keyInfo.secret = (char *) coap_malloc(strlen(secret) + 1);
if (!item->keyInfo.secret) {
break;
}
strncpy(item->keyInfo.keyprefix, keyprefix, sizeof(item->keyInfo.keyprefix) - 1);
strcpy(item->keyInfo.secret, secret);
strcpy(item->id, groupid);
HAL_MutexLock(lst->list_mutex);
list_add_tail(&item->lst, &lst->lst_svr_group);
++lst->svr_group_count;
HAL_MutexUnlock(lst->list_mutex);
return 0;
} while (0);
if (item->id) {
coap_free(item->id);
}
if (item->keyInfo.secret) {
coap_free(item->keyInfo.secret);
}
coap_free(item);
return COAP_ERROR_MALLOC;
}
int alcs_remove_svr_group(CoAPContext *context, const char *groupid)
{
return 0;
}
void alcs_utils_md5_hexstr(unsigned char input[16], unsigned char output[32])
{
unsigned char idx = 0;
unsigned char output_char = 0;
for (idx = 0; idx < 16; idx++) {
if (((input[idx] >> 4) & 0x0F) <= 0x09) {
output_char = ((input[idx] >> 4) & 0x0F) + '0';
} else if (((input[idx] >> 4) & 0x0F) >= 0x0A) {
output_char = ((input[idx] >> 4) & 0x0F) + 'a' - 0x0A;
}
output[2 * idx] = output_char;
if (((input[idx]) & 0x0F) <= 0x09) {
output_char = ((input[idx]) & 0x0F) + '0';
} else if (((input[idx]) & 0x0F) >= 0x0A) {
output_char = ((input[idx]) & 0x0F) + 'a' - 0x0A;
}
output[2 * idx + 1] = output_char;
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "alcs_coap.h"
#ifndef __ALCS_API_H__
#define __ALCS_API_H__
#define SESSIONID_LEN 8
#define SESSIONKEY_MAXLEN 30
#define ALCS_ERR_AUTH_BASE (COAP_ERROR_BASE | 100)
#define ALCS_ERR_AUTH_AUTHING (ALCS_ERR_AUTH_BASE | 1)
#define ALCS_ERR_AUTH_NOCTLKEY (ALCS_ERR_AUTH_BASE | 2)
#define ALCS_ERR_AUTH_UNAUTH (ALCS_ERR_AUTH_BASE | 3)
#define ALCS_ERR_ENCRYPT_FAILED (ALCS_ERR_AUTH_BASE | 5)
typedef enum {
ALCS_AUTH_OK = 200,
ALCS_AUTH_REVOCATE = 501,
ALCS_AUTH_UNMATCHPREFIX,
ALCS_AUTH_INVALIDPARAM,
ALCS_AUTH_AUTHLISTEMPTY,
ALCS_AUTH_VERNOTSUPPORT,
ALCS_AUTH_ILLEGALSIGN,
ALCS_HEART_FAILAUTH,
} Auth_Result_Code;
#include "iotx_alcs_config.h"
typedef struct {
int code;
char *msg;/* MUST call coap_free to free memory */
} ResponseMsg;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
typedef struct
{
ResponseMsg msg;
char sessionId [SESSIONID_LEN];
char sessionKey[SESSIONKEY_MAXLEN];
NetworkAddr addr;
} AuthResult;
*/
typedef void (*AuthHandler)(CoAPContext *context, NetworkAddr *addr, void *user_data, ResponseMsg *result);
typedef struct {
char *productKey;
char *deviceName;
char *accessKey;
char *accessToken;
void *user_data;
AuthHandler handler;
} AuthParam;
typedef struct {
NetworkAddr addr;
char *pk;
char *dn;
} AlcsDeviceKey;
/* 初始化认证模块
* context 为当前设备生成的CoAPContext对象指针
* productKey当前设备的productKey可以为空
* deviceName 当前设备的deviceName可以为空
* role: 1 --client
* 2 --server
* 3 --client&server
*/
int alcs_auth_init(CoAPContext *context, const char *productKey, const char *deviceName, char role);
void alcs_auth_subdev_init(CoAPContext *ctx, const char *productKey, const char *deviceName);
void alcs_auth_deinit(void);
bool alcs_is_auth(CoAPContext *ctx, AlcsDeviceKey *devKey);
int alcs_sendmsg_secure(CoAPContext *ctx, AlcsDeviceKey *devKey, CoAPMessage *message, char observe,
CoAPSendMsgHandler handler);
int alcs_sendrsp_secure(CoAPContext *ctx, AlcsDeviceKey *devKey, CoAPMessage *message, char observe,
unsigned short msgid, CoAPLenString *token);
#ifdef ALCS_CLIENT_ENABLED
/* 身份认证-- 直接传入accesskey&accesstoken
* context 当前设备生成的CoAPContext对象指针
* addr 待连设备地址
* auth_param包含待连设备的信息和回调接口
*/
void alcs_auth_has_key(CoAPContext *ctx, NetworkAddr *addr, AuthParam *auth_param);
/* 身份认证--通过productkey&devicename在缓存的accesskey列表中查找合适accesskey
* 此函数需要和alcs_add_client_key 配合使用
* 若不知道准确的accessKey认证前client会和server协商合适的accessKey
*
* context 为当前设备生成的CoAPContext对象指针
* addr 待连设备地址
* productKey待连设备的productKey
* deviceName待连设备的deviceName
* handler 结果回调接口
*/
void alcs_auth_nego_key(CoAPContext *ctx, AlcsDeviceKey *devKey, AuthHandler handler);
/*
*
*
*/
int alcs_add_client_key(CoAPContext *context, const char *accesskey, const char *accesstoken, const char *productKey,
const char *deviceName);
int alcs_remove_client_key(CoAPContext *context, const char *key, char isfullkey);
/*
*
*
*/
bool alcs_device_online(CoAPContext *context, AlcsDeviceKey *devKey);
#endif
#ifdef ALCS_SERVER_ENABLED
typedef enum {
LOCALDEFAULT,
LOCALSETUP,
FROMCLOUDSVR
} ServerKeyPriority;
int alcs_add_svr_key(CoAPContext *context, const char *keyprefix, const char *secret, ServerKeyPriority priority);
int alcs_remove_svr_key(CoAPContext *context, const char *keyprefix);
/* 设置吊销列表*
* context 为当前设备生成的CoAPContext对象指针
* seqlist 吊销列表字符串,每个被吊销设备占用三字节
*/
int alcs_set_revocation(CoAPContext *context, const char *seqlist);
#endif
int alcs_add_ctl_group(CoAPContext *context, const char *groupid, const char *accesskey, const char *accesstoken);
int alcs_remove_ctl_group(CoAPContext *context, const char *groupid);
int alcs_add_svr_group(CoAPContext *context, const char *groupid, const char *keyprefix, const char *secret);
int alcs_remove_svr_group(CoAPContext *context, const char *groupid);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -0,0 +1,171 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef __ALCS_API_INTERNAL_H__
#define __ALCS_API_INTERNAL_H__
#include "CoAPExport.h"
#include "alcs_api.h"
#include "alcs_internal.h"
#define KEY_MAXCOUNT 10
#define RANDOMKEY_LEN 16
#define KEYSEQ_LEN 3
#define COAP_OPTION_SESSIONID 71
#ifdef ALCS_CLIENT_ENABLED
typedef struct {
char *accessKey;
char *accessToken;
char *deviceName;
char *productKey;
struct list_head lst;
} ctl_key_item;
#endif
#ifdef ALCS_SERVER_ENABLED
typedef struct {
char keyprefix[KEYPREFIX_LEN + 1];
char *secret;
ServerKeyPriority priority;
} svr_key_info;
typedef struct {
svr_key_info keyInfo;
struct list_head lst;
} svr_key_item;
typedef struct {
char *id;
char *revocation;
svr_key_info keyInfo;
struct list_head lst;
} svr_group_item;
#endif
typedef struct {
char *id;
char *accessKey;
char *accessToken;
struct list_head lst;
} ctl_group_item;
typedef struct {
void *list_mutex;
#ifdef ALCS_CLIENT_ENABLED
struct list_head lst_ctl;
unsigned char ctl_count;
#endif
#ifdef ALCS_SERVER_ENABLED
struct list_head lst_svr;
unsigned char svr_count;
char *revocation;
#endif
struct list_head lst_ctl_group;
int ctl_group_count;
struct list_head lst_svr_group;
int svr_group_count;
} auth_list;
#define PK_DN_CHECKSUM_LEN 6
typedef struct {
char randomKey[RANDOMKEY_LEN + 1];
int sessionId;
char sessionKey[32];
int authed_time;
int heart_time;
int interval;
NetworkAddr addr;
char pk_dn[PK_DN_CHECKSUM_LEN];
struct list_head lst;
} session_item;
#define ROLE_SERVER 2
#define ROLE_CLIENT 1
typedef struct {
CoAPContext *context;
int seq;
auth_list lst_auth;
#ifdef ALCS_SERVER_ENABLED
struct list_head lst_svr_sessions;
#endif
#ifdef ALCS_CLIENT_ENABLED
struct list_head lst_ctl_sessions;
#endif
char role;
struct list_head lst;
} device_auth_list;
#ifdef SUPPORT_MULTI_DEVICES
extern struct list_head device_list;
device_auth_list *get_device(CoAPContext *context);
auth_list *get_list(CoAPContext *context);
#ifdef ALCS_CLIENT_ENABLED
struct list_head *get_ctl_session_list(CoAPContext *context);
#endif
#ifdef ALCS_SERVER_ENABLED
struct list_head *get_svr_session_list(CoAPContext *context);
#endif
#else
extern device_auth_list _device;
#define get_device(v) (&_device)
#ifdef ALCS_SERVER_ENABLED
#define get_svr_session_list(v) (_device.role&ROLE_SERVER? &_device.lst_svr_sessions : NULL)
#endif
#ifdef ALCS_CLIENT_ENABLED
#define get_ctl_session_list(v) (_device.role&ROLE_CLIENT? &_device.lst_ctl_sessions : NULL)
#endif
#define get_list(v) (&_device.lst_auth)
#endif
void remove_session(CoAPContext *ctx, session_item *session);
#ifdef ALCS_CLIENT_ENABLED
session_item *get_ctl_session(CoAPContext *ctx, AlcsDeviceKey *key);
#endif
#ifdef ALCS_SERVER_ENABLED
session_item *get_svr_session(CoAPContext *ctx, AlcsDeviceKey *key);
session_item *get_session_by_checksum(struct list_head *sessions, NetworkAddr *addr, char ck[PK_DN_CHECKSUM_LEN]);
#define MAX_PATH_CHECKSUM_LEN (5)
typedef struct {
char path[MAX_PATH_CHECKSUM_LEN];
char pk_dn[PK_DN_CHECKSUM_LEN];
char *filter_path;
path_type_t path_type;
CoAPRecvMsgHandler cb;
struct list_head lst;
} secure_resource_cb_item;
extern struct list_head secure_resource_cb_head;
#endif
int alcs_encrypt(const char *src, int len, const char *key, void *out);
int alcs_decrypt(const char *src, int len, const char *key, void *out);
int observe_data_encrypt(CoAPContext *ctx, const char *paths, NetworkAddr *addr,
CoAPMessage *message, CoAPLenString *src, CoAPLenString *dest);
bool is_networkadd_same(NetworkAddr *addr1, NetworkAddr *addr2);
void gen_random_key(unsigned char random[], int len);
bool req_payload_parser(const char *payload, int len, char **seq, int *seqlen, char **data, int *datalen);
int internal_secure_send(CoAPContext *ctx, session_item *session, NetworkAddr *addr,
CoAPMessage *message, char observe, CoAPSendMsgHandler handler);
int alcs_resource_register_secure(CoAPContext *context, const char *pk, const char *dn, const char *path,
unsigned short permission,
unsigned int ctype, unsigned int maxage, CoAPRecvMsgHandler callback);
void alcs_resource_cb_deinit(void);
void alcs_auth_list_deinit(void);
void alcs_utils_md5_hexstr(unsigned char input[16], unsigned char output[32]);
#endif

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdint.h>
#include <stdlib.h>
#include "infra_types.h"
#include "infra_defs.h"
#include "alcs_base64.h"
static int8_t g_encodingTable[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
static int8_t g_decodingTable[256];
static int32_t g_modTable[] = { 0, 2, 1 };
static void build_decoding_table()
{
static int32_t signal = 0;
int32_t i = 0;
if (signal != 0) {
return;
}
for (i = 0; i < 64; i++) {
g_decodingTable[(uint8_t) g_encodingTable[i]] = i;
}
signal = 1;
return;
}
int utils_base64encode(const uint8_t *data, uint32_t inputLength, uint32_t outputLenMax,
uint8_t *encodedData, uint32_t *outputLength)
{
uint32_t i = 0;
uint32_t j = 0;
if (NULL == encodedData) {
return FAIL_RETURN;
}
*outputLength = 4 * ((inputLength + 2) / 3);
if (outputLenMax < *outputLength) {
return FAIL_RETURN;
}
for (i = 0, j = 0; i < inputLength;) {
uint32_t octet_a = i < inputLength ? (uint8_t) data[i++] : 0;
uint32_t octet_b = i < inputLength ? (uint8_t) data[i++] : 0;
uint32_t octet_c = i < inputLength ? (uint8_t) data[i++] : 0;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
encodedData[j++] = g_encodingTable[(triple >> 3 * 6) & 0x3F];
encodedData[j++] = g_encodingTable[(triple >> 2 * 6) & 0x3F];
encodedData[j++] = g_encodingTable[(triple >> 1 * 6) & 0x3F];
encodedData[j++] = g_encodingTable[(triple >> 0 * 6) & 0x3F];
}
for (i = 0; i < g_modTable[inputLength % 3]; i++) {
encodedData[*outputLength - 1 - i] = '=';
}
return SUCCESS_RETURN;
}
int utils_base64decode(const uint8_t *data, uint32_t inputLength, uint32_t outputLenMax,
uint8_t *decodedData, uint32_t *outputLength)
{
uint32_t i = 0;
uint32_t j = 0;
uint32_t sextet_a = 0;
uint32_t sextet_b = 0;
uint32_t sextet_c = 0;
uint32_t sextet_d = 0;
uint32_t triple = 0;
build_decoding_table();
if (inputLength % 4 != 0) {
return FAIL_RETURN;
}
*outputLength = inputLength / 4 * 3;
if (data[inputLength - 1] == '=') {
(*outputLength)--;
}
if (data[inputLength - 2] == '=') {
(*outputLength)--;
}
if (outputLenMax < *outputLength) {
return FAIL_RETURN;
}
for (i = 0, j = 0; i < inputLength;) {
sextet_a = data[i] == '=' ? 0 & i++ : g_decodingTable[data[i++]];
sextet_b = data[i] == '=' ? 0 & i++ : g_decodingTable[data[i++]];
sextet_c = data[i] == '=' ? 0 & i++ : g_decodingTable[data[i++]];
sextet_d = data[i] == '=' ? 0 & i++ : g_decodingTable[data[i++]];
triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
if (j < *outputLength) {
decodedData[j++] = (triple >> 2 * 8) & 0xFF;
}
if (j < *outputLength) {
decodedData[j++] = (triple >> 1 * 8) & 0xFF;
}
if (j < *outputLength) {
decodedData[j++] = (triple >> 0 * 8) & 0xFF;
}
}
return SUCCESS_RETURN;
}

View File

@@ -0,0 +1,10 @@
#ifndef _ALCS_BASE64_H_
#define _ALCS_BASE64_H_
#include "infra_types.h"
int utils_base64encode(const uint8_t *data, uint32_t inputLength, uint32_t outputLenMax,
uint8_t *encodedData, uint32_t *outputLength);
int utils_base64decode(const uint8_t *data, uint32_t inputLength, uint32_t outputLenMax,
uint8_t *decodedData, uint32_t *outputLength);
#endif

View File

@@ -0,0 +1,587 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "alcs_internal.h"
#include "alcs_api_internal.h"
#include "CoAPPlatform.h"
#include "CoAPResource.h"
#ifdef ALCS_CLIENT_ENABLED
static int default_heart_interval = 30000;
char match_key(const char *accesskey, const char *keyprefix)
{
if (strlen(keyprefix) == KEYPREFIX_LEN && strstr(accesskey, keyprefix) == accesskey) {
return 1;
}
return 0;
}
int do_auth(CoAPContext *ctx, NetworkAddr *addr, ctl_key_item *ctl_item, void *userdata, AuthHandler handler);
bool res_parse(const char *payload, int len, int *seq, ResponseMsg *res_msg, char **data, int *datalen)
{
if (!payload || !len || !seq || !res_msg || !data) {
return 0;
}
COAP_DEBUG("payload:%.*s", len, payload);
int tmplen;
char *tmp;
tmp = json_get_value_by_name((char *)payload, len, "id", &tmplen, NULL);
if (!tmp) {
return 0;
}
char back;
backup_json_str_last_char(tmp, tmplen, back);
*seq = atoi(tmp);
restore_json_str_last_char(tmp, tmplen, back);
tmp = json_get_value_by_name((char *)payload, len, "code", &tmplen, NULL);
if (!tmp) {
return 0;
}
backup_json_str_last_char(tmp, tmplen, back);
res_msg->code = atoi(tmp);
restore_json_str_last_char(tmp, tmplen, back);
tmp = json_get_value_by_name((char *)payload, len, "msg", &tmplen, NULL);
if (tmp && tmplen) {
res_msg->msg = (char *)coap_malloc(tmplen);
memcpy(res_msg->msg, tmp, tmplen);
} else {
res_msg->msg = NULL;
}
*data = json_get_value_by_name((char *)payload, len, "data", datalen, NULL);
return 1;
}
bool fillAccessKey(CoAPContext *ctx, char *buf)
{
auth_list *lst = get_list(ctx);
if (!lst) {
return 0;
}
HAL_MutexLock(lst->list_mutex);
if (list_empty(&lst->lst_ctl)) {
HAL_MutexUnlock(lst->list_mutex);
return 0;
}
strcpy(buf, ",\"accessKeys\":[");
ctl_key_item *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, &lst->lst_ctl, lst, ctl_key_item) {
char *format;
if (lst->ctl_group_count || !list_is_last(&node->lst, &lst->lst_ctl)) {
format = "\"%s\",";
} else {
format = "\"%s\"]";
}
sprintf(buf + strlen(buf), format, node->accessKey);
}
ctl_group_item *gnode = NULL, *gnext = NULL;
list_for_each_entry_safe(gnode, gnext, &lst->lst_ctl_group, lst, ctl_group_item) {
char *format;
if (!list_is_last(&gnode->lst, &lst->lst_ctl_group)) {
format = "\"%s\",";
} else {
format = "\"%s\"]";
}
sprintf(buf + strlen(buf), format, gnode->accessKey);
}
HAL_MutexUnlock(lst->list_mutex);
return 1;
}
#define payload_format "{\"version\":\"1.0\",\"method\":\"%s\",\"id\":%d,\"params\":{\"prodKey\":\"%s\", \"deviceName\":\"%s\"%s}}"
void nego_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata, NetworkAddr *remote, CoAPMessage *message)
{
COAP_INFO("nego_cb, message addr:%p, networkaddr:%p!", message, remote);
AuthParam *auth_param = (AuthParam *)userdata;
if (COAP_RECV_RESP_TIMEOUT == result) {
ResponseMsg msg = {-1, "response time!"};
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
coap_free(auth_param->productKey);
coap_free(auth_param->deviceName);
coap_free(auth_param);
} else {
COAP_DEBUG("recv response message");
int seq, datalen;
ResponseMsg msg;
char *data;
res_parse((const char *)message->payload, message->payloadlen, &seq, &msg, &data, &datalen);
do {
if (msg.code != 200) {
break;
}
int keylen;
char *accessKey = json_get_value_by_name(data, datalen, "accessKey", &keylen, NULL);
if (!accessKey || !keylen) {
break;
}
COAP_DEBUG("accesskey:%.*s", keylen, accessKey);
auth_list *lst = get_list(ctx);
ctl_key_item *node = NULL, *next = NULL;
char *accessTokenFound = NULL;
HAL_MutexLock(lst->list_mutex);
list_for_each_entry_safe(node, next, &lst->lst_ctl, lst, ctl_key_item) {
COAP_DEBUG("node:%s", node->accessKey);
if (strncmp(node->accessKey, accessKey, keylen) == 0) {
accessTokenFound = node->accessToken;
break;
}
}
if (!accessTokenFound) {
ctl_group_item *gnode = NULL, *gnext = NULL;
list_for_each_entry_safe(gnode, gnext, &lst->lst_ctl_group, lst, ctl_group_item) {
COAP_DEBUG("node:%s", gnode->accessKey);
if (strncmp(gnode->accessKey, accessKey, keylen) == 0) {
accessTokenFound = gnode->accessKey;
break;
}
}
}
HAL_MutexUnlock(lst->list_mutex);
if (accessTokenFound) {
ctl_key_item item;
item.deviceName = auth_param->deviceName;
item.productKey = auth_param->productKey;
item.accessKey = accessKey;
item.accessToken = accessTokenFound;
char back;
backup_json_str_last_char(accessKey, keylen, back);
do_auth(ctx, remote, &item, auth_param->user_data, auth_param->handler);
restore_json_str_last_char(accessKey, keylen, back);
coap_free(auth_param->productKey);
coap_free(auth_param->deviceName);
coap_free(auth_param);
return;
}
} while (0);
/* todo */
ResponseMsg tmp = {-1, ""};
auth_param->handler(ctx, remote, auth_param->user_data, &tmp);
coap_free(auth_param->productKey);
coap_free(auth_param->deviceName);
coap_free(auth_param);
}
}
static int CoAPServerPath_2_option(char *uri, CoAPMessage *message)
{
char *ptr = NULL;
char *pstr = NULL;
char path[COAP_MSG_MAX_PATH_LEN] = {0};
if (NULL == uri || NULL == message) {
COAP_ERR("Invalid paramter p_path %p, p_message %p", uri, message);
return COAP_ERROR_INVALID_PARAM;
}
if (256 < strlen(uri)) {
COAP_ERR("The uri length is too loog,len = %d", (int)strlen(uri));
return COAP_ERROR_INVALID_LENGTH;
}
COAP_DEBUG("The uri is %s", uri);
ptr = pstr = uri;
while ('\0' != *ptr) {
if ('/' == *ptr) {
if (ptr != pstr) {
memset(path, 0x00, sizeof(path));
strncpy(path, pstr, ptr - pstr);
COAP_DEBUG("path: %s,len=%d", path, (int)(ptr - pstr));
CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
(unsigned char *)path, (int)strlen(path));
}
pstr = ptr + 1;
}
if ('\0' == *(ptr + 1) && '\0' != *pstr) {
memset(path, 0x00, sizeof(path));
strncpy(path, pstr, sizeof(path) - 1);
COAP_DEBUG("path: %s,len=%d", path, (int)strlen(path));
CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
(unsigned char *)path, (int)strlen(path));
}
ptr ++;
}
return COAP_SUCCESS;
}
void auth_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata, NetworkAddr *remote, CoAPMessage *message)
{
AlcsDeviceKey devKey;
COAP_DEBUG("recv auth_cb response message");
AuthParam *auth_param = (AuthParam *)userdata;
memset(&devKey, 0x00, sizeof(AlcsDeviceKey));
memcpy(&devKey.addr, remote, sizeof(NetworkAddr));
devKey.pk = auth_param->productKey;
devKey.dn = auth_param->deviceName;
session_item *session = get_ctl_session(ctx, &devKey);
if (!session) {
COAP_INFO("receive unknown auth_cb response, pk:%s, dn:%s", devKey.pk, devKey.dn);
ResponseMsg msg = {-1, "no session found!"};
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
} else if (COAP_RECV_RESP_TIMEOUT == result) {
COAP_ERR("response time!");
ResponseMsg msg = {-1, "response time!"};
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
remove_session(ctx, session);
} else {
int seq, datalen;
ResponseMsg msg;
char *data;
res_parse((const char *)message->payload, message->payloadlen, &seq, &msg, &data, &datalen);
if (msg.code == 200) {
do {
int tmplen;
char *tmp;
tmp = json_get_value_by_name(data, datalen, "sessionId", &tmplen, NULL);
if (!tmp) {
msg.code = -1;
msg.msg = "sessionid = NULL!";
COAP_ERR("sessionid = NULL!");
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
break;
}
char back;
backup_json_str_last_char(tmp, tmplen, back);
session->sessionId = atoi(tmp);
restore_json_str_last_char(tmp, tmplen, back);
COAP_INFO("sessionId:%d", session->sessionId);
tmp = json_get_value_by_name(data, datalen, "randomKey", &tmplen, NULL);
if (!tmp) {
msg.code = -1;
msg.msg = "randomKey = NULL!";
COAP_ERR("randomKey = NULL!");
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
break;
}
char buf[32];
HAL_Snprintf(buf, sizeof(buf), "%s%.*s", session->randomKey, tmplen, tmp);
utils_hmac_sha1_hex(buf, strlen(buf), session->sessionKey, auth_param->accessToken, strlen(auth_param->accessToken));
session->authed_time = HAL_UptimeMs();
session->heart_time = session->authed_time;
session->interval = default_heart_interval;
COAP_INFO("sessionKey is created");
} while (0);
} else {
remove_session(ctx, session);
COAP_ERR("message code :%d", msg.code);
}
auth_param->handler(ctx, remote, auth_param->user_data, &msg);
}
coap_free(auth_param->productKey);
coap_free(auth_param->deviceName);
coap_free(auth_param->accessToken);
coap_free(auth_param);
}
#define auth_payload_format "{\"version\":\"1.0\",\"method\":\"core/service/auth\",\"id\":%d,\"params\":{\"prodKey\":\"%s\", \"deviceName\":\"%s\",\"encrypt\":\"payload\",\"randomKey\":\"%s\",\"sign\":\"%s\",\"accessKey\":\"%s\"}}"
int do_auth(CoAPContext *ctx, NetworkAddr *addr, ctl_key_item *ctl_item, void *user_data, AuthHandler handler)
{
int ret = COAP_SUCCESS;
AlcsDeviceKey devKey;
device_auth_list *dev = get_device(ctx);
if (!dev) {
return COAP_ERROR_INVALID_PARAM;
}
memset(&devKey, 0x00, sizeof(AlcsDeviceKey));
memcpy(&devKey.addr, addr, sizeof(NetworkAddr));
devKey.pk = ctl_item->productKey;
devKey.dn = ctl_item->deviceName;
session_item *session = get_ctl_session(ctx, &devKey);
if (session) {
if (session->sessionId) {
COAP_INFO("no need to reauth!");
ResponseMsg res = {COAP_SUCCESS, NULL};
handler(ctx, addr, user_data, &res);
return COAP_SUCCESS;
} else {
COAP_INFO("is authing, no need to reauth!");
return ALCS_ERR_AUTH_AUTHING;
}
}
/* create&save session item */
{
session = (session_item *)coap_malloc(sizeof(session_item));
memset(session, 0, sizeof(session_item));
char path[100] = {0};
strncpy(path, ctl_item->productKey, sizeof(path) - 1);
strncat(path, ctl_item->deviceName, sizeof(path) - strlen(path) - 1);
CoAPPathMD5_sum(path, strlen(path), session->pk_dn, PK_DN_CHECKSUM_LEN);
COAP_INFO("pk:%s, dn:%s, checksum:%s", devKey.pk, devKey.dn, session->pk_dn);
memcpy(&session->addr, addr, sizeof(NetworkAddr));
gen_random_key((unsigned char *)session->randomKey, RANDOMKEY_LEN);
struct list_head *ctl_head = get_ctl_session_list(ctx);
list_add_tail(&session->lst, ctl_head);
}
char sign[64] = {0};
int sign_len = sizeof(sign);
utils_hmac_sha1_base64(session->randomKey, RANDOMKEY_LEN, ctl_item->accessToken,
strlen(ctl_item->accessToken), sign, &sign_len);
COAP_INFO("calc randomKey:%s,token:%s,sign:%.*s", session->randomKey, ctl_item->accessToken, sign_len, sign);
char payloadbuf[512];
sprintf(payloadbuf, auth_payload_format, ++dev->seq, ctl_item->productKey, ctl_item->deviceName, session->randomKey,
sign, ctl_item->accessKey);
COAP_INFO("payload:%s", payloadbuf);
CoAPLenString payload;
payload.data = (unsigned char *)payloadbuf;
payload.len = strlen(payloadbuf);
CoAPMessage message;
alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET, COAP_MESSAGE_TYPE_CON, 0, &payload, NULL);
char path[120];
sprintf(path, "/dev/%s/%s/core/service/auth", ctl_item->productKey, ctl_item->deviceName);
CoAPServerPath_2_option(path, &message);
AuthParam *authParam = (AuthParam *) coap_malloc(sizeof(AuthParam));
authParam->handler = handler;
authParam->user_data = user_data;
authParam->productKey = (char *) coap_malloc(strlen(ctl_item->productKey) + 1);
strcpy(authParam->productKey, ctl_item->productKey);
authParam->deviceName = (char *) coap_malloc(strlen(ctl_item->deviceName) + 1);
strcpy(authParam->deviceName, ctl_item->deviceName);
authParam->accessToken = (char *) coap_malloc(strlen(ctl_item->accessToken) + 1);
strcpy(authParam->accessToken, ctl_item->accessToken);
message.user = authParam;
message.handler = auth_cb;
ret = CoAPMessage_send(ctx, addr, &message);
CoAPMessage_destory(&message);
return ret;
}
void alcs_auth_has_key(CoAPContext *ctx, NetworkAddr *addr, AuthParam *auth_param)
{
ctl_key_item item;
item.accessKey = auth_param->accessKey;
item.deviceName = auth_param->deviceName;
item.productKey = auth_param->productKey;
item.accessToken = auth_param->accessToken;/* (char*) coap_malloc (strlen(auth_param->accessToken) + 1); */
/* strcpy (item.accessToken, auth_param->accessToken); */
do_auth(ctx, addr, &item, auth_param->user_data, auth_param->handler);
}
void alcs_auth_nego_key(CoAPContext *ctx, AlcsDeviceKey *devKey, AuthHandler handler)
{
COAP_DEBUG("alcs_auth_nego_key");
device_auth_list *dev = get_device(ctx);
if (!dev) {
COAP_INFO("no device!");
return;
}
char accesskeys[1024] = {0};
if (!fillAccessKey(ctx, accesskeys)) {
COAP_INFO("no ctl key!");
return;
}
COAP_INFO("accesskeys:%s", accesskeys);
const char *method = "core/service/auth/select";
char payloadbuf[1024];
sprintf(payloadbuf, payload_format, method, ++dev->seq, devKey->pk, devKey->dn, accesskeys);
CoAPLenString payload;
payload.data = (unsigned char *)payloadbuf;
payload.len = strlen(payloadbuf);
CoAPMessage message;
alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET, COAP_MESSAGE_TYPE_CON, 0, &payload, NULL);
char path[120];
sprintf(path, "/dev/%s/%s/core/service/auth/select", devKey->pk, devKey->dn);
CoAPServerPath_2_option(path, &message);
AuthParam *authParam = (AuthParam *) coap_malloc(sizeof(AuthParam));
memset(authParam, 0, sizeof(AuthParam));
authParam->handler = handler;
authParam->productKey = (char *) coap_malloc(strlen(devKey->pk) + 1);
strcpy(authParam->productKey, devKey->pk);
authParam->deviceName = (char *) coap_malloc(strlen(devKey->dn) + 1);
strcpy(authParam->deviceName, devKey->dn);
message.user = authParam;
message.handler = nego_cb;
CoAPMessage_send(ctx, &devKey->addr, &message);
CoAPMessage_destory(&message);
}
int alcs_add_client_key(CoAPContext *ctx, const char *accesskey, const char *accesstoken, const char *productKey,
const char *deviceName)
{
auth_list *lst = get_list(ctx);
if (!lst || lst->ctl_count >= KEY_MAXCOUNT) {
return COAP_ERROR_INVALID_LENGTH;
}
ctl_key_item *item = (ctl_key_item *) coap_malloc(sizeof(ctl_key_item));
if (!item) {
return COAP_ERROR_MALLOC;
}
item->accessKey = (char *) coap_malloc(strlen(accesskey) + 1);
item->accessToken = (char *) coap_malloc(strlen(accesstoken) + 1);
if (!item->accessKey || !item->accessToken) {
coap_free(item);
return COAP_ERROR_MALLOC;
}
strcpy(item->accessKey, accesskey);
strcpy(item->accessToken, accesstoken);
if (deviceName) {
item->deviceName = (char *) coap_malloc(strlen(deviceName) + 1);
strcpy(item->deviceName, deviceName);
}
HAL_MutexLock(lst->list_mutex);
list_add_tail(&item->lst, &lst->lst_ctl);
++lst->ctl_count;
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
int alcs_remove_client_key(CoAPContext *ctx, const char *key, char isfullkey)
{
auth_list *lst = get_list(ctx);
if (!lst) {
return COAP_ERROR_NULL;
}
ctl_key_item *node = NULL, *next = NULL;
HAL_MutexLock(lst->list_mutex);
list_for_each_entry_safe(node, next, &lst->lst_ctl, lst, ctl_key_item) {
if (match_key(node->accessKey, key)) {
coap_free(node->accessKey);
coap_free(node->accessToken);
list_del(&node->lst);
coap_free(node);
break;
}
}
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
bool alcs_device_online(CoAPContext *ctx, AlcsDeviceKey *devKey)
{
session_item *session = get_ctl_session(ctx, devKey);
return session && session->sessionId ? 1 : 0;
}
void heart_beat_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata, NetworkAddr *remote, CoAPMessage *message)
{
COAP_DEBUG("heart_beat_cb, message addr:%p, networkaddr:%p!", message, remote);
struct list_head *ctl_head = get_ctl_session_list(ctx);
if (!ctl_head || list_empty(ctl_head)) {
return;
}
if (result == COAP_RECV_RESP_TIMEOUT) {
COAP_ERR("heart beat timeout");
session_item *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, ctl_head, lst, session_item) {
if (node->sessionId && is_networkadd_same(&node->addr, remote)) {
remove_session(ctx, node);
}
}
} else {
session_item *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, ctl_head, lst, session_item) {
if (node->sessionId && is_networkadd_same(&node->addr, remote)) {
unsigned int sessionId = 0;
CoAPUintOption_get(message, COAP_OPTION_SESSIONID, &sessionId);
if (node->sessionId != sessionId) {
COAP_INFO("receive stale heart beat response");
remove_session(ctx, node);
} else {
node->heart_time = HAL_UptimeMs();
}
}
}
}
}
void on_client_auth_timer(CoAPContext *ctx)
{
struct list_head *ctl_head = get_ctl_session_list(ctx);
if (!ctl_head || list_empty(ctl_head)) {
return;
}
COAP_DEBUG("on_client_auth_timer:%d", (int)HAL_UptimeMs());
device_auth_list *dev = get_device(ctx);
char payloadbuf[64];
sprintf(payloadbuf, "{\"id\":%d,\"version\":\"1.0\",\"params\":{\"delayTime\":%d}}", ++dev->seq, 5000);
CoAPLenString payload;
payload.data = (unsigned char *)payloadbuf;
payload.len = strlen(payloadbuf);
int tick = HAL_UptimeMs();
session_item *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, ctl_head, lst, session_item) {
if (!node->sessionId) {
continue;
}
if (node->heart_time + node->interval > tick) {
CoAPMessage message;
alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET, COAP_MESSAGE_TYPE_CON, 0, &payload, NULL);
CoAPServerPath_2_option("/dev/core/service/heartBeat", &message);
message.handler = heart_beat_cb;
CoAPMessage_send(ctx, &node->addr, &message);
COAP_DEBUG("send heartbeat to :%s", node->addr.addr);
CoAPMessage_destory(&message);
}
}
}
#endif

View File

@@ -0,0 +1,405 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <string.h>
#include "alcs_internal.h"
#include "alcs_coap.h"
#include "CoAPPlatform.h"
#include "CoAPResource.h"
#include "alcs_api_internal.h"
#include "CoAPServer.h"
#define MAX_PATH_CHECKSUM_LEN (5)
typedef struct {
char path[MAX_PATH_CHECKSUM_LEN];
CoAPRecvMsgHandler cb;
struct list_head lst;
} resource_cb_item;
LIST_HEAD(resource_cb_head);
static uint32_t tokenSeed = 0;
uint32_t getToken()
{
if (tokenSeed == 0) {
HAL_Srandom((uint32_t)HAL_UptimeMs());
tokenSeed = HAL_Random(0xffffffff);
} else {
++tokenSeed;
}
return tokenSeed;
}
void alcs_msg_init(CoAPContext *ctx, CoAPMessage *message, int code, unsigned char type,
int keep, CoAPLenString *payload, void *userdata)
{
uint32_t token = 0;
CoAPMessage_init(message);
message->header.code = code;
message->header.type = type;
message->user = userdata;
message->payload = payload->data;
message->payloadlen = payload->len;
message->keep = keep;
message->header.msgid = CoAPMessageId_gen(ctx);
message->header.tokenlen = 4;
token = getToken();
memcpy(&message->token, &token, 4);
}
void alcs_msg_deinit(CoAPMessage *message)
{
CoAPMessage_destory(message);
}
static int do_sendmsg(CoAPContext *context, NetworkAddr *addr, CoAPMessage *message, char observe, unsigned short msgid,
CoAPLenString *token)
{
int ret = COAP_SUCCESS;
if (!context || !addr || !message) {
return COAP_ERROR_NULL;
}
if (msgid == 0) {
message->header.msgid = CoAPMessageId_gen(context);
} else {
message->header.msgid = msgid;
}
if (observe == 0) {
CoAPUintOption_add(message, COAP_OPTION_OBSERVE, observe);
}
if (token) {
message->header.tokenlen = token->len;
memcpy(&message->token, token->data, token->len);
}
ret = CoAPMessage_send(context, addr, message);
CoAPMessage_destory(message);
return ret;
}
int alcs_sendmsg(CoAPContext *context, NetworkAddr *addr, CoAPMessage *message, char observe,
CoAPSendMsgHandler handler)
{
message->handler = handler;
return do_sendmsg(context, addr, message, observe, message->header.msgid, NULL);
}
int alcs_sendrsp(CoAPContext *context, NetworkAddr *addr, CoAPMessage *message, char observe, unsigned short msgid,
CoAPLenString *token)
{
return do_sendmsg(context, addr, message, observe, msgid, token);
}
/* observe */
int alcs_observe_notify(CoAPContext *context, const char *path, CoAPLenString *payload)
{
int needAuth = 0;
#ifdef USE_ALCS_SECURE
needAuth = alcs_resource_need_auth(context, path);
#endif
COAP_DEBUG("payload:%s", payload->data);
/* HEXDUMP_DEBUG(payload->data, payload->len); */
return CoAPObsServer_notify(context, path, payload->data, payload->len,
needAuth ? &observe_data_encrypt : NULL);
}
static void send_err_rsp(CoAPContext *ctx, NetworkAddr *addr, int code, CoAPMessage *fromMsg)
{
CoAPMessage sendMsg;
CoAPLenString payload = {0};
CoAPLenString token = {fromMsg->header.tokenlen, fromMsg->token};
alcs_msg_init(ctx, &sendMsg, code, COAP_MESSAGE_TYPE_ACK, 0, &payload, NULL);
alcs_sendrsp(ctx, addr, &sendMsg, 1, fromMsg->header.msgid, &token);
}
static void recv_msg_handler(CoAPContext *context, const char *path, NetworkAddr *remote, CoAPMessage *message)
{
unsigned int obsVal;
resource_cb_item *node = NULL, *next = NULL;
char path_calc[MAX_PATH_CHECKSUM_LEN] = {0};
CoAPPathMD5_sum(path, strlen(path), path_calc, MAX_PATH_CHECKSUM_LEN);
list_for_each_entry_safe(node, next, &resource_cb_head, lst, resource_cb_item) {
if (0 == memcmp(path_calc, node->path, MAX_PATH_CHECKSUM_LEN)) {
if (CoAPUintOption_get(message, COAP_OPTION_OBSERVE, &obsVal) == COAP_SUCCESS) {
if (obsVal == 0) {
CoAPObsServer_add(context, path, remote, message);
}
}
COAP_INFO("recv_msg_handler call callback");
node->cb(context, path, remote, message);
return;
}
}
COAP_ERR("receive unknown request, path:%s", path);
send_err_rsp(context, remote, COAP_MSG_CODE_401_UNAUTHORIZED, message);
}
/* resource */
int alcs_resource_register(CoAPContext *context, const char *pk, const char *dn, const char *path,
unsigned short permission,
unsigned int ctype, unsigned int maxage, char needAuth, CoAPRecvMsgHandler callback)
{
COAP_DEBUG("alcs_resource_register, ctx:%p", context);
COAP_DEBUG("ALCS Resource Register: %s", path);
if (!needAuth) {
resource_cb_item *item = (resource_cb_item *)coap_malloc(sizeof(resource_cb_item));
CoAPPathMD5_sum(path, strlen(path), item->path, MAX_PATH_CHECKSUM_LEN);
item->cb = callback;
list_add_tail(&item->lst, &resource_cb_head);
return CoAPResource_register(context, path, permission, ctype, maxage, &recv_msg_handler);
} else {
#ifdef USE_ALCS_SECURE
return alcs_resource_register_secure(context, pk, dn, path, permission, ctype, maxage, callback);
#else
return -1;
#endif
}
}
int alcs_resource_need_auth(CoAPContext *context, const char *path)
{
resource_cb_item *node = NULL, *next = NULL;
char path_calc[MAX_PATH_CHECKSUM_LEN] = {0};
CoAPPathMD5_sum(path, strlen(path), path_calc, MAX_PATH_CHECKSUM_LEN);
list_for_each_entry_safe(node, next, &resource_cb_head, lst, resource_cb_item) {
if (memcmp(path_calc, node->path, MAX_PATH_CHECKSUM_LEN) == 0) {
return 0;
}
}
return 1;
}
typedef struct {
CoAPContext *ctx;
char loop;
bool inited;
struct list_head lst;
} ALCSContext;
#ifdef SUPPORT_MULTI_DEVICES
LIST_HEAD(context_head);
ALCSContext *get_context(CoAPContext *ctx)
{
ALCSContext *node = NULL, *next = NULL;
list_for_each_entry_safe(node, next, &context_head, lst, ALCSContext) {
if (node->ctx == ctx) {
return node;
}
}
return NULL;
}
CoAPContext *alcs_context_create(CoAPInitParam *param)
{
ALCSContext *alcs_ctx = (ALCSContext *) coap_malloc(sizeof(ALCSContext));
alcs_ctx->ctx = CoAPContext_create(param);
COAP_INFO("CoAPContext_create return :%p", alcs_ctx->ctx);
alcs_ctx->loop = 0;
alcs_ctx->inited = 0;
list_add_tail(&alcs_ctx->lst, &context_head);
return alcs_ctx->ctx;
}
void alcs_context_free(CoAPContext *ctx)
{
ALCSContext *alcs_ctx = get_context(ctx);
if (alcs_ctx) {
CoAPContext_free(alcs_ctx->ctx);
coap_free(alcs_ctx);
}
}
#else
ALCSContext *g_alcs_ctx = NULL;
ALCSContext *get_context(CoAPContext *ctx)
{
return g_alcs_ctx;
}
CoAPContext *alcs_context_init(CoAPInitParam *param)
{
if (g_alcs_ctx) {
return g_alcs_ctx->ctx;
}
g_alcs_ctx = (ALCSContext *)coap_malloc(sizeof(ALCSContext));
if (g_alcs_ctx) {
g_alcs_ctx->loop = 0;
g_alcs_ctx->inited = 0;
g_alcs_ctx->ctx = CoAPServer_init();
COAP_INFO("CoAPServer_init return :%p", g_alcs_ctx->ctx);
if (!g_alcs_ctx->ctx) {
coap_free(g_alcs_ctx);
g_alcs_ctx = NULL;
return NULL;
}
return g_alcs_ctx->ctx;
} else {
return NULL;
}
}
void alcs_context_deinit()
{
if (g_alcs_ctx) {
if (g_alcs_ctx->ctx) {
CoAPServer_deinit(g_alcs_ctx->ctx);
}
coap_free(g_alcs_ctx);
g_alcs_ctx = NULL;
}
}
CoAPContext *alcs_get_context()
{
return g_alcs_ctx ? g_alcs_ctx->ctx : NULL;
}
#endif
extern void on_auth_timer(void *arg);
void *thread_routine(void *arg)
{
ALCSContext *ctx = (ALCSContext *)arg;
ctx->loop = 1;
COAP_INFO("thread_routine");
while (ctx->loop) {
CoAPMessage_cycle(ctx->ctx);
#ifdef USE_ALCS_SECURE
on_auth_timer(ctx->ctx);
#endif
}
return NULL;
}
void alcs_start_loop(CoAPContext *ctx, int newThread)
{
#ifdef SUPPORT_MULTI_DEVICES
void *handle = NULL;
ALCSContext *alcs_ctx = get_context(ctx);
if (alcs_ctx && !alcs_ctx->loop) {
int stack_used = 0;
if (!newThread || 0 != HAL_ThreadCreate(&handle, thread_routine, alcs_ctx, NULL, &stack_used)) {
thread_routine(alcs_ctx);
}
}
#else
#ifdef USE_ALCS_SECURE
CoAPServer_add_timer(on_auth_timer);
#endif
CoAPServer_loop(ctx);
#endif
}
void alcs_stop_loop(CoAPContext *ctx)
{
#ifdef SUPPORT_MULTI_DEVICES
ALCSContext *alcs_ctx = get_context(ctx);
if (alcs_ctx) {
alcs_ctx->loop = 0;
}
#else
CoAPServer_deinit(ctx);
#endif
}
void alcs_init()
{
#ifdef SUPPORT_MULTI_DEVICES
INIT_LIST_HEAD(&context_head);
#endif
INIT_LIST_HEAD(&resource_cb_head);
}
void alcs_deinit()
{
resource_cb_item *del_item = NULL;
list_for_each_entry(del_item, &resource_cb_head, lst, resource_cb_item) {
list_del(&del_item->lst);
coap_free(del_item);
del_item = list_entry(&resource_cb_head, resource_cb_item, lst);
}
}
static int path_2_option(const char *uri, CoAPMessage *message)
{
const char *ptr = NULL;
const char *pstr = NULL;
char path[COAP_MSG_MAX_PATH_LEN] = {0};
if (256 < strlen(uri)) {
COAP_ERR("The uri length is too loog,len = %d", (int)strlen(uri));
return COAP_ERROR_INVALID_LENGTH;
}
COAP_DEBUG("The uri is %s", uri);
ptr = pstr = uri;
while ('\0' != *ptr) {
if ('/' == *ptr) {
if (ptr != pstr) {
memset(path, 0x00, sizeof(path));
strncpy(path, pstr, ptr - pstr);
COAP_DEBUG("path: %s,len=%d", path, (int)(ptr - pstr));
CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
(unsigned char *)path, (int)strlen(path));
}
pstr = ptr + 1;
}
if ('\0' == *(ptr + 1) && '\0' != *pstr) {
memset(path, 0x00, sizeof(path));
strncpy(path, pstr, sizeof(path) - 1);
COAP_DEBUG("path: %s,len=%d", path, (int)strlen(path));
CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
(unsigned char *)path, (int)strlen(path));
}
ptr ++;
}
return COAP_SUCCESS;
}
int alcs_msg_setAddr(CoAPMessage *message, const char *path, const char *query)
{
int rt = 0;
if (NULL == path || NULL == message) {
COAP_ERR("Invalid paramter p_path %p, p_message %p", path, message);
return COAP_ERROR_INVALID_PARAM;
}
if (255 < strlen(path)) {
COAP_ERR("The uri length is too loog,len = %d", (int)strlen(path));
return COAP_ERROR_INVALID_LENGTH;
}
rt = path_2_option(path, message);
if (query) {
CoAPStrOption_add(message, COAP_OPTION_URI_QUERY, (unsigned char *)query, strlen(query));
}
return rt;
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "CoAPExport.h"
#ifndef __COAP_ALCS_H__
#define __COAP_ALCS_H__
#define OPTSESESSION 62
#define ALCSPORT 5683
#define ALCSPORT_SECURE 5684
#define MULTICAST_ADDRESS "224.0.1.187"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef bool
#define bool char
#endif
typedef struct {
NetworkAddr addr;
char *path;
char *query;
} ResourceAddr;
/* 会自动生成msgid & token */
void alcs_msg_init(CoAPContext *ctx, CoAPMessage *message, int code, unsigned char type, int keep,
CoAPLenString *payload, void *userdata);
void alcs_msg_deinit(CoAPMessage *message);
int alcs_msg_setAddr(CoAPMessage *message, const char *path, const char *query);
/* observe: 0 register */
/* observer:1 deregister */
/* observer:other 没意义 */
int alcs_sendmsg(CoAPContext *ctx, NetworkAddr *addr, CoAPMessage *message, char observe, CoAPSendMsgHandler handler);
/* msgid & token从接收到CoAPMessage获取, 若发送的是事件通知msgid设置为0 */
/* observe: 0 accept register */
/* observe: other: 没意义 */
int alcs_sendrsp(CoAPContext *ctx, NetworkAddr *addr, CoAPMessage *message, char observe, unsigned short msgid,
CoAPLenString *token);
void alcs_start_loop(CoAPContext *ctx, int newThread);
void alcs_stop_loop(CoAPContext *ctx);
/* 服务端接口
*
*/
/* observe */
int alcs_observe_notify(CoAPContext *context, const char *path, CoAPLenString *payload);
/* resource */
int alcs_resource_register(CoAPContext *context, const char *pk, const char *dn, const char *path,
unsigned short permission,
unsigned int ctype, unsigned int maxage, char needAuth, CoAPRecvMsgHandler callback);
int alcs_resource_need_auth(CoAPContext *context, const char *path);
/* init */
void alcs_init();
void alcs_deinit();
#ifdef SUPPORT_MULTI_DEVICES
CoAPContext *alcs_context_create(CoAPInitParam *param);
void alcs_context_free(CoAPContext *ctx);
#else
CoAPContext *alcs_context_init(CoAPInitParam *param);
void alcs_context_deinit();
CoAPContext *alcs_get_context();
#endif
/* option */
extern int CoAPUintOption_add(CoAPMessage *message, unsigned short optnum, unsigned int data);
extern int CoAPUintOption_get(CoAPMessage *message, unsigned short optnum, unsigned int *data);
extern int CoAPStrOption_add(CoAPMessage *message, unsigned short optnum,
unsigned char *data, unsigned short datalen);
extern int CoAPMessage_cancel(CoAPContext *context, CoAPMessage *message);
uint32_t getToken();
/* */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -0,0 +1,24 @@
#ifndef _ALCS_INTERNAL_H_
#define _ALCS_INTERNAL_H_
#include "infra_config.h"
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_md5.h"
#include "infra_sha1.h"
#include "infra_json_parser.h"
#include "alcs_base64.h"
#include "dm_wrapper.h"
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#define ALCS_malloc(size) LITE_malloc(size, MEM_MAGIC, "alcs")
#define ALCS_ADAPTER_malloc(size) LITE_malloc(size, MEM_MAGIC, "alcs_adapter")
#define ALCS_free(ptr) LITE_free(ptr)
#else
#define ALCS_malloc(size) HAL_Malloc(size)
#define ALCS_ADAPTER_malloc(size) HAL_Malloc(size)
#define ALCS_free(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
#endif
#endif

View File

@@ -0,0 +1,306 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include "alcs_internal.h"
#include "alcs_api_internal.h"
#include "CoAPExport.h"
#include "alcs_api.h"
#include "alcs_mqtt.h"
#include "alcs_adapter.h"
#include "CoAPPlatform.h"
#include "CoAPExport.h"
#include "iotx_alcs.h"
char *DEFAULT_AC = "Xtau@iot";
char *DEFAULT_AS = "Yx3DdsyetbSezlvc";
void *g_adapter_handle = NULL;
void *g_coap_handle = NULL;
typedef enum {
ALCS_LOCALSETUP_SUCCESS,
ALCS_LOCALSETUP_ERROR
} localsetup_status;
static localsetup_status __alcs_localsetup_kv_set(const char *key, const void *val, int len, int sync)
{
if (HAL_Kv_Set(key, val, len, sync) != 0) {
return ALCS_LOCALSETUP_ERROR;
}
COAP_INFO("ALCS KV Set, Key: %s, Val: %s, Len: %d", key, (char *)val, len);
return ALCS_LOCALSETUP_SUCCESS;
}
static localsetup_status __alcs_localsetup_kv_get(const char *key, void *buffer, int *buffer_len)
{
int rc = -1;
if ((rc = HAL_Kv_Get(key, buffer, buffer_len)) != 0) {
COAP_WRN("HAL_Kv_Get('%s') = %d (!= 0), return %d", key, rc, ALCS_LOCALSETUP_ERROR);
return ALCS_LOCALSETUP_ERROR;
}
COAP_INFO("ALCS KV Get, Key: %s", key);
return ALCS_LOCALSETUP_SUCCESS;
}
static localsetup_status __alcs_localsetup_kv_del(const char *key)
{
if (HAL_Kv_Del(key) != 0) {
return ALCS_LOCALSETUP_ERROR;
}
COAP_INFO("ALCS KV Del, Key: %s", key);
return ALCS_LOCALSETUP_SUCCESS;
}
static localsetup_status __fill_key(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len, char key_md5_hexstr[33])
{
uint8_t key_md5[16] = {0};
char key_source[IOTX_PRODUCT_KEY_LEN + 1 + IOTX_DEVICE_NAME_LEN + 1 + 3];
if (pk == NULL || pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return ALCS_LOCALSETUP_ERROR;
}
/* Calculate Key */
HAL_Snprintf(key_source, sizeof(key_source), "%.*s%.*s.l", pk_len, pk, dn_len, dn);
utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
return ALCS_LOCALSETUP_SUCCESS;
}
static localsetup_status __alcs_localsetup_ac_as_save(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len,
const char *prefix, uint16_t prefix_len,
const char *secret, uint16_t secret_len)
{
char key_md5_hexstr[33] = {0};
char *value = NULL;
int rt;
if (prefix == NULL || secret == NULL) {
COAP_ERR("Invalid Parameter");
return ALCS_LOCALSETUP_ERROR;
}
rt = __fill_key(pk, pk_len, dn, dn_len, key_md5_hexstr);
if (rt != ALCS_LOCALSETUP_SUCCESS) {
return rt;
}
/* Calculate Value */
value = ALCS_ADAPTER_malloc(prefix_len + secret_len + 3);
if (value == NULL) {
COAP_ERR("No Enough Memory");
return ALCS_LOCALSETUP_ERROR;
}
memset(value, 0, prefix_len + secret_len + 3);
value[0] = prefix_len;
value[1] = secret_len;
HAL_Snprintf(&value[2], prefix_len + secret_len + 1, "%.*s%.*s", prefix_len, prefix, secret_len, secret);
if (ALCS_LOCALSETUP_SUCCESS != __alcs_localsetup_kv_set(key_md5_hexstr, value, prefix_len + secret_len + 3, 1)) {
COAP_WRN("ALCS KV Set Prefix And Secret Fail");
ALCS_free(value);
return ALCS_LOCALSETUP_ERROR;
}
ALCS_free(value);
return ALCS_LOCALSETUP_SUCCESS;
}
localsetup_status alcs_localsetup_ac_as_load(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len,
char *prefix, int prefix_len, char *secret, int secret_len)
{
char key_md5_hexstr[33] = {0};
char value[128] = {0};
int value_len = sizeof(value);
int rt;
if (prefix == NULL || secret == NULL) {
COAP_ERR("Invalid Parameter");
return ALCS_LOCALSETUP_ERROR;
}
rt = __fill_key(pk, pk_len, dn, dn_len, key_md5_hexstr);
if (rt != ALCS_LOCALSETUP_SUCCESS) {
return rt;
}
/* Get Value */
if (ALCS_LOCALSETUP_SUCCESS != __alcs_localsetup_kv_get(key_md5_hexstr, value, &value_len)) {
COAP_WRN("ALCS KV Get local Prefix And Secret Fail");
return ALCS_LOCALSETUP_ERROR;
}
if (value[0] >= prefix_len || value[1] >= secret_len) {
COAP_ERR("insuffient buffer!");
return ALCS_LOCALSETUP_ERROR;
}
memset(prefix, 0, prefix_len);
memcpy(prefix, &value[2], value[0]);
memset(secret, 0, secret_len);
memcpy(secret, &value[2 + value[0]], value[1]);
return ALCS_LOCALSETUP_SUCCESS;
}
static localsetup_status __alcs_localsetup_ac_as_del(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len)
{
char key_md5_hexstr[33] = {0};
int rt;
rt = __fill_key(pk, pk_len, dn, dn_len, key_md5_hexstr);
if (rt != ALCS_LOCALSETUP_SUCCESS) {
return rt;
}
if (ALCS_LOCALSETUP_SUCCESS != __alcs_localsetup_kv_del(key_md5_hexstr)) {
COAP_ERR("ALCS KV Get local Prefix And Secret Fail");
return ALCS_LOCALSETUP_ERROR;
}
return ALCS_LOCALSETUP_SUCCESS;
}
static void alcs_service_cb_setup(CoAPContext *context, const char *paths, NetworkAddr *remote, CoAPMessage *message)
{
char payload[128];
char *id = NULL, *p;
int idlen = 0, len, aclen, aslen, pklen, dnlen;
char *ac = NULL, *as = NULL, *pk = NULL, *dn = dn;
bool success = 0;
char *err_msg = NULL;
char configValueBack, acBack, asBack;
char *str_pos, *entry;
int entry_len, type;
iotx_alcs_msg_t rsp_msg;
COAP_DEBUG("alcs_service_cb_setup, path:%s", paths);
do {
if (!remote || !message) {
COAP_DEBUG("alcs_service_cb_setup, param is NULL!");
err_msg = "invalid package";
break;
}
id = json_get_value_by_name((char *)message->payload, message->payloadlen, "id", &idlen, (int *)NULL);
p = json_get_value_by_name((char *)message->payload, message->payloadlen, "params", &len, (int *)NULL);
if (!p || !len) {
err_msg = "params is not found";
break;
}
p = json_get_value_by_name(p, len, "configValue", &len, (int *)NULL);
if (!p || !len) {
err_msg = "configValue is not found";
break;
}
backup_json_str_last_char(p, len, configValueBack);
json_array_for_each_entry(p, len, str_pos, entry, entry_len, type) {
COAP_DEBUG("entry:%.*s", entry_len, entry);
ac = json_get_value_by_name(entry, entry_len, "authCode", &aclen, (int *)NULL);
as = json_get_value_by_name(entry, entry_len, "authSecret", &aslen, (int *)NULL);
pk = json_get_value_by_name(entry, entry_len, "productKey", &pklen, (int *)NULL);
dn = json_get_value_by_name(entry, entry_len, "deviceName", &dnlen, (int *)NULL);
break;
} /* end json_array_for_each_entry */
restore_json_str_last_char(p, len, configValueBack);
if (!ac || !aclen || !as || !aslen || !pk || !pklen || !dn || !dnlen) {
err_msg = "authinfo is not found";
break;
}
/* save */
backup_json_str_last_char(ac, aclen, acBack);
backup_json_str_last_char(as, aslen, asBack);
__alcs_localsetup_ac_as_del(pk, pklen, dn, dnlen);
__alcs_localsetup_ac_as_save(pk, pklen, dn, dnlen, ac, aclen, as, aslen);
alcs_add_svr_key(g_coap_handle, ac, as, LOCALSETUP);
restore_json_str_last_char(ac, aclen, acBack);
restore_json_str_last_char(as, aslen, asBack)
success = 1;
} while (0);
if (success) {
HAL_Snprintf(payload, sizeof(payload), "{\"id\":\"%.*s\",\"code\":200}", idlen, id ? id : "");
} else {
HAL_Snprintf(payload, sizeof(payload), "{\"id\":\"%.*s\",\"code\":400,\"msg\":\"%s\"}", idlen, id ? id : "", err_msg);
COAP_ERR("alcs_service_cb_setup, %s", err_msg);
}
memset(&rsp_msg, 0, sizeof(iotx_alcs_msg_t));
rsp_msg.msg_code = ITOX_ALCS_COAP_MSG_CODE_205_CONTENT;
rsp_msg.msg_type = IOTX_ALCS_MESSAGE_TYPE_CON;
rsp_msg.payload = (unsigned char *)payload;
rsp_msg.payload_len = strlen(payload);
rsp_msg.ip = (char *)(remote ? remote->addr : NULL);
rsp_msg.port = remote ? remote->port : 5683;
rsp_msg.uri = (char *)paths;
if (message) {
iotx_alcs_send_Response(g_adapter_handle, &rsp_msg, message->header.tokenlen, message->token);
}
}
static void alcs_localsetup_register_resource(void *adapter_handle, char *pk, char *dn)
{
iotx_alcs_res_t alcs_res;
char uri [IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN + 24];
if (adapter_handle == NULL || pk == NULL || strlen(pk) > IOTX_PRODUCT_KEY_LEN ||
dn == NULL || strlen(dn) > IOTX_DEVICE_NAME_LEN) {
return;
}
HAL_Snprintf(uri, sizeof(uri), "/dev/%s/%s/core/service/setup", pk, dn);
memset(&alcs_res, 0, sizeof(iotx_alcs_res_t));
alcs_res.uri = uri;
alcs_res.msg_ct = IOTX_ALCS_MESSAGE_CT_APP_JSON;
alcs_res.msg_perm = IOTX_ALCS_MESSAGE_PERM_GET | IOTX_ALCS_MESSAGE_PERM_PUT;
alcs_res.maxage = 60;
alcs_res.need_auth = 1;
alcs_res.callback = alcs_service_cb_setup;
iotx_alcs_register_resource(adapter_handle, &alcs_res);
}
void alcs_localsetup_init(void *adapter_handle, void *coap_handler, char *pk, char *dn)
{
char prefix [10];
char secret [64];
g_adapter_handle = adapter_handle;
g_coap_handle = coap_handler;
alcs_localsetup_register_resource(adapter_handle, pk, dn);
if (alcs_localsetup_ac_as_load(pk, strlen(pk), dn, strlen(dn), prefix, sizeof(prefix), secret,
sizeof(secret)) != ALCS_LOCALSETUP_SUCCESS) {
alcs_add_svr_key(g_coap_handle, DEFAULT_AC, DEFAULT_AS, LOCALDEFAULT);
} else {
alcs_add_svr_key(g_coap_handle, prefix, secret, LOCALSETUP);
}
}
void alcs_localsetup_add_sub_device(void *adapter_handle, char *pk, char *dn)
{
alcs_localsetup_register_resource(adapter_handle, pk, dn);
}

View File

@@ -0,0 +1,14 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _ALCS_LOCALSETUP_H_
#define _ALCS_LOCALSETUP_H_
void alcs_localsetup_init(void *adapter_handle, void* coap_handler, char *product_key,char *device_name);
void alcs_localsetup_add_sub_device (void *adapter_handle,char *product_key,char *device_name);
void alcs_localsetup_deinit(void *handle);
#endif

View File

@@ -0,0 +1,618 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include "alcs_internal.h"
#include "alcs_api_internal.h"
#include "CoAPExport.h"
#include "alcs_api.h"
#include "alcs_adapter.h"
#include "alcs_mqtt.h"
#include "alcs_adapter.h"
#include "CoAPPlatform.h"
static alcs_mqtt_ctx_t g_alcs_mqtt_ctx;
static alcs_mqtt_ctx_t *__alcs_mqtt_get_ctx(void)
{
return &g_alcs_mqtt_ctx;
}
static alcs_mqtt_status_e __alcs_mqtt_publish(char *topic, int qos, void *data, int len)
{
return (IOT_MQTT_Publish_Simple(NULL, topic, qos, data, len) < 0) ? ALCS_MQTT_STATUS_ERROR : ALCS_MQTT_STATUS_SUCCESS;
}
static alcs_mqtt_status_e __alcs_mqtt_send_response(char *topic, int id, int code, char *data)
{
char *msg_pub = NULL;
uint16_t msg_len = 0;
alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
if (data == NULL || strlen(data) == 0) {
data = "{}";
}
msg_len = strlen(ALCS_MQTT_THING_LAN_PREFIX_RESPONSE_FMT) + 20 + strlen(data) + 1;
if ((msg_pub = ALCS_ADAPTER_malloc(msg_len)) == NULL) {
return ALCS_MQTT_STATUS_ERROR;
}
HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_LAN_PREFIX_RESPONSE_FMT, id, code, data);
status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
ALCS_free(msg_pub);
return status;
}
static alcs_mqtt_status_e __alcs_mqtt_kv_set(const char *key, const void *val, int len, int sync)
{
if (HAL_Kv_Set(key, val, len, sync) != 0) {
return ALCS_MQTT_STATUS_ERROR;
}
COAP_INFO("ALCS KV Set, Key: %s, Val: %s, Len: %d", key, (char *)val, len);
return ALCS_MQTT_STATUS_SUCCESS;
}
static alcs_mqtt_status_e __alcs_mqtt_kv_get(const char *key, void *buffer, int *buffer_len)
{
if (HAL_Kv_Get(key, buffer, buffer_len) != 0) {
return ALCS_MQTT_STATUS_ERROR;
}
COAP_INFO("ALCS KV Get, Key: %s", key);
return ALCS_MQTT_STATUS_SUCCESS;
}
static alcs_mqtt_status_e __alcs_mqtt_kv_del(const char *key)
{
if (HAL_Kv_Del(key) != 0) {
return ALCS_MQTT_STATUS_ERROR;
}
COAP_INFO("ALCS KV Del, Key: %s", key);
return ALCS_MQTT_STATUS_SUCCESS;
}
alcs_mqtt_status_e __alcs_mqtt_prefix_secret_save(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len,
const char *prefix, uint16_t prefix_len,
const char *secret, uint16_t secret_len)
{
char *key_source = NULL;
uint8_t key_md5[16] = {0};
char key_md5_hexstr[33] = {0};
char *value = NULL;
if (pk == NULL || pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || dn_len >= IOTX_DEVICE_NAME_LEN + 1 ||
prefix == NULL || secret == NULL) {
COAP_ERR("Invalid Parameter");
return ALCS_MQTT_STATUS_ERROR;
}
/* Calculate Key */
key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
if (key_source == NULL) {
COAP_ERR("No Enough Memory");
return ALCS_MQTT_STATUS_ERROR;
}
memset(key_source, 0, pk_len + dn_len + 1);
HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk, dn_len, dn);
utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
/* Calculate Value */
value = ALCS_ADAPTER_malloc(prefix_len + secret_len + 3);
if (value == NULL) {
COAP_ERR("No Enough Memory");
ALCS_free(key_source);
return ALCS_MQTT_STATUS_ERROR;
}
memset(value, 0, prefix_len + secret_len + 3);
value[0] = prefix_len;
value[1] = secret_len;
HAL_Snprintf(&value[2], prefix_len + secret_len + 1, "%.*s%.*s", prefix_len, prefix, secret_len, secret);
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_set(key_md5_hexstr, value, prefix_len + secret_len + 3, 1)) {
COAP_ERR("ALCS KV Set Prefix And Secret Fail");
ALCS_free(key_source);
ALCS_free(value);
return ALCS_MQTT_STATUS_ERROR;
}
ALCS_free(key_source);
ALCS_free(value);
return ALCS_MQTT_STATUS_SUCCESS;
}
alcs_mqtt_status_e alcs_mqtt_prefix_secret_load(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len,
char *prefix, char *secret)
{
char *key_source = NULL;
uint8_t key_md5[16] = {0};
char key_md5_hexstr[33] = {0};
char value[128] = {0};
int value_len = sizeof(value);
if (pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1 ||
prefix == NULL || secret == NULL) {
COAP_ERR("Invalid Parameter");
return ALCS_MQTT_STATUS_ERROR;
}
/* Calculate Key */
key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
if (key_source == NULL) {
COAP_ERR("No Enough Memory");
return ALCS_MQTT_STATUS_ERROR;
}
memset(key_source, 0, pk_len + dn_len + 1);
HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk, dn_len, dn);
utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
/* Get Value */
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_get(key_md5_hexstr, value, &value_len)) {
COAP_ERR("ALCS KV Get Prefix And Secret Fail");
ALCS_free(key_source);
return ALCS_MQTT_STATUS_ERROR;
}
memcpy(prefix, &value[2], value[0]);
memcpy(secret, &value[2 + value[0]], value[1]);
ALCS_free(key_source);
return ALCS_MQTT_STATUS_SUCCESS;
}
alcs_mqtt_status_e alcs_mqtt_prefix_secret_del(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len)
{
char *key_source = NULL;
uint8_t key_md5[16] = {0};
char key_md5_hexstr[33] = {0};
if (pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 ||
dn == NULL || strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
COAP_ERR("Invalid Parameter");
return ALCS_MQTT_STATUS_ERROR;
}
/* Calculate Key */
key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
if (key_source == NULL) {
COAP_ERR("No Enough Memory");
return ALCS_MQTT_STATUS_ERROR;
}
memset(key_source, 0, pk_len + dn_len + 1);
HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk, dn_len, dn);
utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_del(key_md5_hexstr)) {
COAP_ERR("ALCS KV Get Prefix And Secret Fail");
ALCS_free(key_source);
return ALCS_MQTT_STATUS_ERROR;
}
ALCS_free(key_source);
return ALCS_MQTT_STATUS_SUCCESS;
}
static void __alcs_mqtt_subscribe_callback(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
char topic_compare[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
char reqid[16] = {0};
char *topic;
int topic_len;
void *payload;
int payload_len;
alcs_mqtt_ctx_t *alcs_mqtt_ctx = NULL;
iotx_mqtt_topic_info_pt ptopic_info = NULL;
if (msg == NULL) {
return;
}
alcs_mqtt_ctx = (alcs_mqtt_ctx_t *)pcontext;
ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
switch (msg->event_type) {
case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
return;
case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
return;
case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
return;
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
topic = (char *)ptopic_info->ptopic;
topic_len = ptopic_info->topic_len;
payload = (char *)ptopic_info->payload;
payload_len = ptopic_info->payload_len;
break;
default:
return;
}
if (topic == NULL || payload == NULL || topic_len == 0 || payload_len == 0) {
return;
}
memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic_compare, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT,
alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
COAP_INFO("Receivce Message, Topic: %.*s\n", topic_len, topic);
if ((strlen(topic_compare) == topic_len) && (strncmp(topic_compare, topic, topic_len) == 0)) {
int data_len = 0, prefix_len = 0, secret_len = 0, productKey_len = 0, deviceName_len = 0;
char *data = NULL, *prefix = NULL, *secret = NULL, *productKey = NULL, *deviceName = NULL;
data = json_get_value_by_name((char *)payload, payload_len, "data", &data_len, NULL);
if (NULL != data && 0 != data_len) {
char back1, back2;
prefix = json_get_value_by_name(data, data_len, ALCS_MQTT_JSON_KEY_PREFIX, &prefix_len, NULL);
secret = json_get_value_by_name(data, data_len, ALCS_MQTT_JSON_KEY_SECRET, &secret_len, NULL);
productKey = json_get_value_by_name(data, data_len, ALCS_MQTT_JSON_KEY_PRODUCT_KEY, &productKey_len, NULL);
deviceName = json_get_value_by_name(data, data_len, ALCS_MQTT_JSON_KEY_DEVICE_NAME, &deviceName_len, NULL);
COAP_INFO("Get Reply, Product Key: %.*s, Device Name: %.*s\n", productKey_len, productKey, deviceName_len, deviceName);
if (NULL != alcs_mqtt_ctx->coap_ctx && prefix && secret) {
back1 = prefix[prefix_len];
prefix[prefix_len] = 0;
back2 = secret[secret_len];
secret[secret_len] = 0;
alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret, FROMCLOUDSVR);
prefix[prefix_len] = back1;
secret[secret_len] = back2;
if (productKey && deviceName) {
if (__alcs_mqtt_prefix_secret_save(productKey, productKey_len, deviceName, deviceName_len, prefix, prefix_len, secret,
secret_len) == ALCS_MQTT_STATUS_SUCCESS) {
iotx_alcs_subdev_item_t subdev_item;
memset(&subdev_item, 0, sizeof(iotx_alcs_subdev_item_t));
memcpy(subdev_item.product_key, productKey, productKey_len);
memcpy(subdev_item.device_name, deviceName, deviceName_len);
subdev_item.stage = IOTX_ALCS_SUBDEV_CONNECT_CLOUD;
iotx_alcs_subdev_update_stage(&subdev_item);
}
} else {
iotx_alcs_subdev_remove(alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_PREFIX, prefix, prefix_len, 1)) {
COAP_ERR("ALCS KV Set Prefix Fail");
}
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_SECRET, secret, secret_len, 1)) {
COAP_ERR("ALCS KV Set Secret Fail");
}
}
}
} else {
if (ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_PREFIX, prefix, &prefix_len) &&
ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_SECRET, secret, &secret_len)) {
if (NULL != alcs_mqtt_ctx->coap_ctx && prefix_len && secret_len) {
alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret, FROMCLOUDSVR);
}
}
}
return;
}
memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic_compare, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT,
alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
if ((strlen(topic_compare) == topic_len) && (strncmp(topic_compare, topic, topic_len) == 0)) {
int param_len = 0, prefix_len = 0, id_len = 0;
char *param = NULL, *prefix = NULL, *id = NULL;
id = json_get_value_by_name((char *)payload, payload_len, "id", &id_len, NULL);
if (NULL != id && 0 != id_len) {
strncpy(reqid, id, sizeof(reqid) - 1);
}
param = json_get_value_by_name((char *)payload, payload_len, "params", &param_len, NULL);
if (NULL != param && 0 != param_len) {
char reply_topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
prefix = json_get_value_by_name(param, param_len, ALCS_MQTT_JSON_KEY_PREFIX, &prefix_len, NULL);
if (NULL != alcs_mqtt_ctx->coap_ctx && prefix)
if (0 != alcs_remove_svr_key(alcs_mqtt_ctx->coap_ctx, prefix)) {
}
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_del(ALCS_MQTT_JSON_KEY_PREFIX)) {
COAP_ERR("Remove the keyprefix from aos_kv fail");
;
}
HAL_Snprintf(reply_topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_REPLY_FMT,
alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
__alcs_mqtt_send_response(reply_topic, atoi(reqid), 200, NULL);
}
return;
}
memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic_compare, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT,
alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
if ((strlen(topic_compare) == topic_len) && (strncmp(topic_compare, topic, topic_len) == 0)) {
int param_len = 0, blacklist_len = 0, id_len = 0;
char *param = NULL, *blacklist = NULL, *id = NULL;
id = json_get_value_by_name((char *)payload, payload_len, "id", &id_len, NULL);
if (NULL != id && 0 != id_len) {
strncpy(reqid, id, sizeof(reqid) - 1);
}
param = json_get_value_by_name((char *)payload, payload_len, "params", &param_len, NULL);
if (NULL != param && 0 != param_len) {
char reply_topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
blacklist = json_get_value_by_name(param, param_len, ALCS_MQTT_JSON_KEY_BLACK, &blacklist_len, NULL);
if (NULL != alcs_mqtt_ctx->coap_ctx && blacklist) {
alcs_set_revocation(alcs_mqtt_ctx->coap_ctx, blacklist);
if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_BLACK, blacklist, blacklist_len, 1)) {
COAP_ERR("aos_kv_set set blacklist fail");
;
}
}
HAL_Snprintf(reply_topic, ALCS_MQTT_TOPIC_MAX_LEN,
ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_REPLY_FMT,
alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
__alcs_mqtt_send_response(reply_topic, atoi(reqid), 200, NULL);
} else {
if (ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_BLACK, blacklist, &blacklist_len)) {
if (NULL != alcs_mqtt_ctx->coap_ctx) {
alcs_set_revocation(alcs_mqtt_ctx->coap_ctx, blacklist);
}
}
}
return;
}
}
static alcs_mqtt_status_e __alcs_mqtt_subscribe(void *ctx, char *topic)
{
return (IOT_MQTT_Subscribe(NULL, topic, 0, __alcs_mqtt_subscribe_callback,
ctx) < 0) ? ALCS_MQTT_STATUS_ERROR : ALCS_MQTT_STATUS_SUCCESS;
}
#if 0
static alcs_mqtt_status_e __alcs_mqtt_unsubscribe(void *ctx, char *topic)
{
return (mqtt_unsubscribe(topic) != 0) ? ALCS_MQTT_STATUS_ERROR : ALCS_MQTT_STATUS_SUCCESS;
}
#endif
alcs_mqtt_status_e alcs_mqtt_init(void *handle, char *product_key, char *device_name)
{
char topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
if (handle == NULL || product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
return ALCS_MQTT_STATUS_ERROR;
}
memset(ctx, 0, sizeof(alcs_mqtt_ctx_t));
ctx->coap_ctx = (CoAPContext *)handle;
memcpy(ctx->product_key, product_key, strlen(product_key));
memcpy(ctx->device_name, device_name, strlen(device_name));
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
alcs_mqtt_prefixkey_update((void *)ctx->coap_ctx);
alcs_mqtt_blacklist_update((void *)ctx->coap_ctx);
alcs_prefixkey_get(ctx->product_key, ctx->device_name);
return status;
}
alcs_mqtt_status_e alcs_mqtt_deinit(void *handle, char *product_key, char *device_name)
{
#if 0
char topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
ARGUMENT_SANITY_CHECK(product_key && strlen(product_key), FAIL_RETURN);
ARGUMENT_SANITY_CHECK(device_name && strlen(device_name), FAIL_RETURN);
if (handle == NULL || product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN || ctx == NULL) {
return ALCS_MQTT_STATUS_ERROR;
}
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_unsubscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_unsubscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT,
ctx->product_key, ctx->device_name);
if (__alcs_mqtt_unsubscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
status = ALCS_MQTT_STATUS_ERROR;
}
return status;
#endif
return ALCS_MQTT_STATUS_SUCCESS;
}
void alcs_mqtt_add_srv_key(const char *prefix, const char *secret)
{
alcs_mqtt_ctx_t *alcs_mqtt_ctx = __alcs_mqtt_get_ctx();
alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret, FROMCLOUDSVR);
}
alcs_mqtt_status_e alcs_mqtt_blacklist_update(void *ctx)
{
CoAPContext *context = (CoAPContext *)ctx;
char blacklist[ALCS_MQTT_BLACK_MAX_LEN] = {0};
int blacklist_len = ALCS_MQTT_BLACK_MAX_LEN;
if (NULL == context) {
return -1;
}
if (ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_BLACK, blacklist, &blacklist_len)) {
COAP_INFO("The blacklist is %.*s", blacklist_len, blacklist);
if (blacklist_len) {
alcs_set_revocation(context, blacklist);
return ALCS_MQTT_STATUS_SUCCESS;
}
}
return ALCS_MQTT_STATUS_ERROR;
}
alcs_mqtt_status_e alcs_mqtt_prefixkey_update(void *ctx)
{
CoAPContext *context = (CoAPContext *)ctx;
char prefix[ALCS_MQTT_PREFIX_MAX_LEN] = {0};
char secret[ALCS_MQTT_SECRET_MAX_LEN] = {0};
int prefix_len = ALCS_MQTT_PREFIX_MAX_LEN, secret_len = ALCS_MQTT_SECRET_MAX_LEN;
if (NULL == context) {
return ALCS_MQTT_STATUS_ERROR;
}
COAP_INFO("start alcs_prefixkey_update\n");
if (ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_PREFIX, prefix, &prefix_len) &&
ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_SECRET, secret, &secret_len)) {
COAP_INFO("The prefix is %.*s, deviceSecret is %.*s", prefix_len, prefix, secret_len, secret);
if (prefix_len && secret_len) {
alcs_add_svr_key(context, prefix, secret, FROMCLOUDSVR);
return ALCS_MQTT_STATUS_SUCCESS;
}
}
return ALCS_MQTT_STATUS_ERROR;
}
alcs_mqtt_status_e alcs_prefixkey_get(const char *product_key, const char *device_name)
{
/* int ret = 0; */
char *msg_pub = NULL;
uint16_t msg_len = 0;
char topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
int id = ctx->send_id++;
if (product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
return ALCS_MQTT_STATUS_ERROR;
}
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_FMT,
product_key, device_name);
msg_len = strlen(ALCS_MQTT_THING_ALCS_REQUEST) + 10 + 1;
if ((msg_pub = ALCS_ADAPTER_malloc(msg_len)) == NULL) {
return ALCS_MQTT_STATUS_ERROR;
}
HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_ALCS_REQUEST, id);
COAP_INFO("ALCS Prefix Get, Topic: %s, Payload: %s", topic, msg_pub);
status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
ALCS_free(msg_pub);
return status;
}
alcs_mqtt_status_e alcs_mqtt_subdev_prefix_get(const char *product_key, const char *device_name)
{
/* int ret = 0; */
char *msg_pub = NULL;
uint16_t msg_len = 0;
char topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
int id = ctx->send_id++;
if (product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
return ALCS_MQTT_STATUS_ERROR;
}
COAP_INFO("Subdevice, PK: %s, DN: %s\n", product_key, device_name);
HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_FMT,
ctx->product_key, ctx->device_name);
msg_len = strlen(ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST) + 10 + strlen(product_key) + strlen(device_name) + 1;
if ((msg_pub = ALCS_ADAPTER_malloc(msg_len)) == NULL) {
return ALCS_MQTT_STATUS_ERROR;
}
HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST, id,
(int)strlen(product_key), product_key, (int)strlen(device_name), device_name);
COAP_ERR("ALCS Prefix Get, Topic: %s, Payload: %s", topic, msg_pub);
status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
ALCS_free(msg_pub);
return status;
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _ALCS_MQTT_H_
#define _ALCS_MQTT_H_
#include "alcs_internal.h"
typedef enum {
ALCS_MQTT_STATUS_SUCCESS,
ALCS_MQTT_STATUS_ERROR
} alcs_mqtt_status_e;
typedef struct {
CoAPContext *coap_ctx;
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN + 2];
uint32_t send_id;
} alcs_mqtt_ctx_t;
#define ALCS_MQTT_PREFIX "/sys/%s/%s"
#define ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT "/thing/lan/prefix/get_reply"
#define ALCS_MQTT_THING_LAN_PREFIX_GET_FMT "/thing/lan/prefix/get"
#define ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT "/thing/lan/prefix/update"
#define ALCS_MQTT_THING_LAN_PREFIX_UPDATE_REPLY_FMT "/thing/lan/prefix/update_reply"
#define ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT "/thing/lan/blacklist/update"
#define ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_REPLY_FMT "/thing/lan/blacklist/update_reply"
#define ALCS_MQTT_THING_ALCS_REQUEST "{\"id\":\"%d\",\"version\":\"1.0\",\"params\":\"{}\",\"method\":\"thing.lan.prefix.get\"}"
#define ALCS_MQTT_THING_LAN_PREFIX_RESPONSE_FMT "{\"id\": \"%d\", \"code\": %d, \"data\": %s}"
#define ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST "{\"id\":\"%d\",\"version\":\"1.0\",\"params\":{\"productKey\":\"%.*s\",\"deviceName\":\"%.*s\"},\"method\":\"thing.lan.prefix.get\"}"
#define ALCS_MQTT_TOPIC_MAX_LEN (128)
#define ALCS_MQTT_JSON_KEY_PRODUCT_KEY "productKey"
#define ALCS_MQTT_JSON_KEY_DEVICE_NAME "deviceName"
#define ALCS_MQTT_JSON_KEY_PREFIX "prefix"
#define ALCS_MQTT_JSON_KEY_SECRET "deviceSecret"
#define ALCS_MQTT_JSON_KEY_BLACK "blacklist"
#define ALCS_MQTT_PREFIX_MAX_LEN (40)
#define ALCS_MQTT_SECRET_MAX_LEN (40)
#define ALCS_MQTT_BLACK_MAX_LEN (100)
alcs_mqtt_status_e alcs_mqtt_init(void *handle, char *product_key, char *device_name);
alcs_mqtt_status_e alcs_mqtt_deinit(void *handle, char *product_key, char *device_name);
alcs_mqtt_status_e alcs_mqtt_blacklist_update(void *ctx);
alcs_mqtt_status_e alcs_mqtt_prefixkey_update(void *ctx);
void alcs_mqtt_add_srv_key(const char *prefix, const char *secret);
alcs_mqtt_status_e alcs_mqtt_prefix_secret_load(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len,
char *prefix, char *secret);
alcs_mqtt_status_e alcs_mqtt_prefix_secret_del(const char *pk, uint16_t pk_len,
const char *dn, uint16_t dn_len);
alcs_mqtt_status_e alcs_mqtt_subdev_prefix_get(const char *product_key, const char *device_name);
alcs_mqtt_status_e alcs_prefixkey_get(const char *product_key, const char *device_name);
#endif

View File

@@ -0,0 +1,703 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "alcs_internal.h"
#include "alcs_api_internal.h"
#include "CoAPPlatform.h"
#include "CoAPResource.h"
#ifdef LOG_REPORT_TO_CLOUD
#include "iotx_log_report.h"
#endif
#define RES_FORMAT "{\"id\":\"%.*s\",\"code\":%d,\"data\":{%s}}"
#ifdef ALCS_SERVER_ENABLED
int sessionid_seed = 0xff;
static int default_heart_expire = 120000;
void utils_hmac_sha1_base64(const char *msg, int msg_len, const char *key, int key_len, char *digest, int *digest_len)
{
char buf[20];
uint32_t outlen;
utils_hmac_sha1_hex(msg, msg_len, buf, key, key_len);
utils_base64encode((unsigned char *)buf, 20, *digest_len, (unsigned char *)digest, &outlen);
*digest_len = outlen;
}
void alcs_rec_auth_select(CoAPContext *ctx, const char *paths, NetworkAddr *from, CoAPMessage *resMsg)
{
int seqlen, datalen;
char *seq, *data;
char *targetKey = "";
int targetLen = 0;
auth_list *lst = NULL;
char *accesskeys;
int keylen;
char back;
char *str_pos, *entry;
int entry_len, type;
CoAPMessage msg;
char keybuf[32];
char payloadbuf[512];
CoAPLenString token = {resMsg->header.tokenlen, resMsg->token};
CoAPLenString payload;
/* int res_code = 200; */
COAP_DEBUG("receive data:%.*s", resMsg->payloadlen, resMsg->payload);
do {
if (!req_payload_parser((const char *)resMsg->payload, resMsg->payloadlen, &seq, &seqlen, &data, &datalen)) {
break;
}
lst = get_list(ctx);
accesskeys = json_get_value_by_name(data, datalen, "accessKeys", &keylen, NULL);
if (!accesskeys || !keylen) {
break;
}
COAP_DEBUG("accessKeys:%.*s", keylen, accesskeys);
backup_json_str_last_char(accesskeys, keylen, back);
json_array_for_each_entry(accesskeys, keylen, str_pos, entry, entry_len, type) {
svr_key_item *node = NULL, *next = NULL;
svr_group_item *gnode = NULL, *gnext = NULL;
COAP_DEBUG("entry:%.*s", entry_len, entry);
list_for_each_entry_safe(node, next, &lst->lst_svr, lst, svr_key_item) {
COAP_DEBUG("keyprefix:%s", node->keyInfo.keyprefix);
if (strstr(entry, node->keyInfo.keyprefix) == entry) {
COAP_DEBUG("target keyprefix:%s", entry);
targetKey = entry;
targetLen = entry_len;
break;
}
}
if (targetKey) {
break;
}
list_for_each_entry_safe(gnode, gnext, &lst->lst_svr_group, lst, svr_group_item) {
COAP_DEBUG("keyprefix:%s", gnode->keyInfo.keyprefix);
if (strstr(entry, gnode->keyInfo.keyprefix) == entry) {
COAP_DEBUG("target keyprefix:%s", entry);
targetKey = entry;
targetLen = entry_len;
break;
}
}
if (targetKey) {
break;
}
}
restore_json_str_last_char(accesskeys, keylen, back);
} while (0);
COAP_DEBUG("key:%s", targetKey);
HAL_Snprintf(keybuf, sizeof(keybuf), "\"accessKey\":\"%.*s\"", targetLen, targetKey);
HAL_Snprintf(payloadbuf, sizeof(payloadbuf), RES_FORMAT, seqlen, seq, targetKey ? 200 : COAP_MSG_CODE_401_UNAUTHORIZED,
keybuf);
payload.data = (unsigned char *)payloadbuf;
payload.len = strlen(payloadbuf);
alcs_msg_init(ctx, &msg, COAP_MSG_CODE_205_CONTENT, COAP_MESSAGE_TYPE_ACK, 0, &payload, NULL);
alcs_sendrsp(ctx, from, &msg, 1, resMsg->header.msgid, &token);
}
svr_key_info *is_legal_key(CoAPContext *ctx, const char *keyprefix, int prefixlen, const char *keyseq, int seqlen,
int *res_code)
{
auth_list *lst = get_list(ctx);
COAP_INFO("islegal prefix:%.*s, seq:%.*s", prefixlen, keyprefix, seqlen, keyseq);
if (lst) {
COAP_DEBUG("find devices");
HAL_MutexLock(lst->list_mutex);
if (lst->revocation) {
int len = strlen(lst->revocation);
int i;
for (i = 0; i < len; i += KEYSEQ_LEN) {
if (strncmp(keyseq, lst->revocation + i, seqlen) == 0) {
HAL_MutexUnlock(lst->list_mutex);
*res_code = ALCS_AUTH_REVOCATE;
COAP_INFO("accesskey is revocated");
return NULL;
}
}
}
if (list_empty(&lst->lst_svr)) {
COAP_INFO("ALCS_AUTH_AUTHLISTEMPTY:%d\r\n", ALCS_AUTH_AUTHLISTEMPTY);
*res_code = ALCS_AUTH_AUTHLISTEMPTY;
} else {
svr_key_item *node = NULL, *next = NULL;
svr_group_item *gnode = NULL, *gnext = NULL;
list_for_each_entry_safe(node, next, &lst->lst_svr, lst, svr_key_item) {
COAP_DEBUG("node prefix:%s", node->keyInfo.keyprefix);
if (strlen(node->keyInfo.keyprefix) == prefixlen && strncmp(keyprefix, node->keyInfo.keyprefix, prefixlen) == 0) {
*res_code = ALCS_AUTH_OK;
HAL_MutexUnlock(lst->list_mutex);
return &node->keyInfo;
}
}
list_for_each_entry_safe(gnode, gnext, &lst->lst_svr_group, lst, svr_group_item) {
COAP_DEBUG("node prefix:%s", gnode->keyInfo.keyprefix);
if (strlen(gnode->keyInfo.keyprefix) == prefixlen && strncmp(keyprefix, gnode->keyInfo.keyprefix, prefixlen) == 0) {
*res_code = ALCS_AUTH_OK;
HAL_MutexUnlock(lst->list_mutex);
return &gnode->keyInfo;
}
}
COAP_INFO("ALCS_AUTH_UNMATCHPREFIX:%d\r\n", ALCS_AUTH_UNMATCHPREFIX);
*res_code = ALCS_AUTH_UNMATCHPREFIX;
}
HAL_MutexUnlock(lst->list_mutex);
}
return NULL;
}
void alcs_rec_auth(CoAPContext *ctx, const char *paths, NetworkAddr *from, CoAPMessage *resMsg)
{
int seqlen, datalen;
char *seq, *data;
int res_code = 200;
char body[200] = {0};
char *accesskey, *randomkey, *sign;
int tmplen;
char *keyprefix;
char *keyseq;
char accessToken[64];
int tokenlen;
int randomkeylen;
char buf[40];
int calc_sign_len;
int pklen, dnlen;
char *pk;
char *dn;
char tmp1;
char tmp2;
svr_key_info *item;
AlcsDeviceKey devKey;
session_item *session;
CoAPMessage message;
char payloadbuf[512];
CoAPLenString payload;
CoAPLenString token;
COAP_INFO("receive data:%.*s, from:%s", resMsg->payloadlen, resMsg->payload, from->addr);
do {
if (!req_payload_parser((const char *)resMsg->payload, resMsg->payloadlen, &seq, &seqlen, &data, &datalen)) {
break;
}
accesskey = json_get_value_by_name(data, datalen, "accessKey", &tmplen, NULL);
COAP_INFO("accesskey:%.*s", tmplen, accesskey);
if (!accesskey || tmplen != KEYPREFIX_LEN + 1 + 1 + KEYSEQ_LEN) {
break;
}
keyprefix = accesskey;
keyseq = accesskey + KEYPREFIX_LEN + 1 + 1;
item = is_legal_key(ctx, keyprefix, KEYPREFIX_LEN, keyseq, KEYSEQ_LEN, &res_code);
if (!item) {
COAP_INFO("islegal return null");
break;
}
tokenlen = sizeof(accessToken);
utils_hmac_sha1_base64(accesskey, tmplen, item->secret, strlen(item->secret), accessToken, &tokenlen);
COAP_INFO("accessToken:%.*s", tokenlen, accessToken);
randomkey = json_get_value_by_name(data, datalen, "randomKey", &randomkeylen, NULL);
if (!randomkey || !randomkeylen) {
res_code = ALCS_AUTH_INVALIDPARAM;
break;
}
/*calc sign, save in buf*/
calc_sign_len = sizeof(buf);
utils_hmac_sha1_base64(randomkey, randomkeylen, accessToken, tokenlen, buf, &calc_sign_len);
COAP_INFO("calc randomKey:%.*s,token:%.*s,sign:%.*s", randomkeylen, randomkey, tokenlen,
accessToken, calc_sign_len, buf);
sign = json_get_value_by_name(data, datalen, "sign", &tmplen, NULL);
if (!sign || tmplen != calc_sign_len || strncmp(sign, buf, calc_sign_len)) {
res_code = ALCS_AUTH_ILLEGALSIGN;
break;
}
pk = json_get_value_by_name(data, datalen, "prodKey", &pklen, NULL);
dn = json_get_value_by_name(data, datalen, "deviceName", &dnlen, NULL);
if (!pk || !pklen || !dn || !dnlen) {
res_code = ALCS_AUTH_INVALIDPARAM;
break;
}
tmp1 = pk[pklen];
tmp2 = dn[dnlen];
pk[pklen] = 0;
dn[dnlen] = 0;
memset(&devKey, 0x00, sizeof(AlcsDeviceKey));
memcpy(&devKey.addr, from, sizeof(NetworkAddr));
devKey.pk = pk;
devKey.dn = dn;
session = get_svr_session(ctx, &devKey);
if (!session) {
char path[100] = {0};
struct list_head *svr_head;
session = (session_item *)coap_malloc(sizeof(session_item));
gen_random_key((unsigned char *)session->randomKey, RANDOMKEY_LEN);
session->sessionId = ++sessionid_seed;
strncpy(path, pk, sizeof(path));
strncat(path, dn, sizeof(path) - strlen(path) - 1);
CoAPPathMD5_sum(path, strlen(path), session->pk_dn, PK_DN_CHECKSUM_LEN);
memcpy(&session->addr, from, sizeof(NetworkAddr));
COAP_INFO("new session, addr:%s, port:%d", session->addr.addr, session->addr.port);
svr_head = get_svr_session_list(ctx);
list_add_tail(&session->lst, svr_head);
}
pk[pklen] = tmp1;
dn[dnlen] = tmp2;
HAL_Snprintf(buf, sizeof(buf), "%.*s%s", randomkeylen, randomkey, session->randomKey);
utils_hmac_sha1_hex(buf, strlen(buf), session->sessionKey, accessToken, tokenlen);
/*calc sign, save in buf*/
calc_sign_len = sizeof(buf);
utils_hmac_sha1_base64(session->randomKey, RANDOMKEY_LEN, accessToken, tokenlen, buf, &calc_sign_len);
HAL_Snprintf(body, sizeof(body), "\"sign\":\"%.*s\",\"randomKey\":\"%s\",\"sessionId\":%d,\"expire\":86400",
calc_sign_len, buf, session->randomKey, session->sessionId);
session->authed_time = HAL_UptimeMs();
session->heart_time = session->authed_time;
/* ??? */
/* result = 1; */
} while (0);
HAL_Snprintf(payloadbuf, sizeof(payloadbuf), RES_FORMAT, seqlen, seq, res_code, body);
payload.len = strlen(payloadbuf);
payload.data = (unsigned char *)payloadbuf;
alcs_msg_init(ctx, &message, COAP_MSG_CODE_205_CONTENT, COAP_MESSAGE_TYPE_ACK, 0, &payload, NULL);
token.len = resMsg->header.tokenlen;
token.data = resMsg->token;
alcs_sendrsp(ctx, from, &message, 1, resMsg->header.msgid, &token);
}
static int alcs_remove_low_priority_key(CoAPContext *ctx, ServerKeyPriority priority)
{
auth_list *lst = get_list(ctx);
svr_key_item *node = NULL, *next = NULL;
HAL_MutexLock(lst->list_mutex);
list_for_each_entry_safe(node, next, &lst->lst_svr, lst, svr_key_item) {
if (node->keyInfo.priority < priority) {
coap_free(node->keyInfo.secret);
list_del(&node->lst);
coap_free(node);
--lst->svr_count;
}
}
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
static int add_svr_key(CoAPContext *ctx, const char *keyprefix, const char *secret, bool isGroup,
ServerKeyPriority priority)
{
auth_list *lst = get_list(ctx);
svr_key_item *node = NULL, *next = NULL;
svr_key_item *item;
COAP_INFO("add_svr_key\n");
if (!lst || lst->svr_count >= KEY_MAXCOUNT || strlen(keyprefix) != KEYPREFIX_LEN) {
return COAP_ERROR_INVALID_LENGTH;
}
alcs_remove_low_priority_key(ctx, priority);
HAL_MutexLock(lst->list_mutex);
list_for_each_entry_safe(node, next, &lst->lst_svr, lst, svr_key_item) {
if (node->keyInfo.priority > priority) {
/* find high priority key */
HAL_MutexUnlock(lst->list_mutex);
return COAP_ERROR_UNSUPPORTED;
}
}
item = (svr_key_item *) coap_malloc(sizeof(svr_key_item));
if (!item) {
HAL_MutexUnlock(lst->list_mutex);
return COAP_ERROR_MALLOC;
}
memset(item, 0, sizeof(svr_key_item));
item->keyInfo.secret = (char *) coap_malloc(strlen(secret) + 1);
if (!item->keyInfo.secret) {
HAL_MutexUnlock(lst->list_mutex);
coap_free(item);
return COAP_ERROR_MALLOC;
}
memset(item->keyInfo.secret, 0, strlen(secret) + 1);
strcpy(item->keyInfo.secret, secret);
memcpy(item->keyInfo.keyprefix, keyprefix, KEYPREFIX_LEN);
item->keyInfo.priority = priority;
list_add_tail(&item->lst, &lst->lst_svr);
++lst->svr_count;
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
int alcs_add_svr_key(CoAPContext *ctx, const char *keyprefix, const char *secret, ServerKeyPriority priority)
{
COAP_INFO("alcs_add_svr_key, priority=%d", priority);
return add_svr_key(ctx, keyprefix, secret, 0, priority);
}
int alcs_remove_svr_key(CoAPContext *ctx, const char *keyprefix)
{
auth_list *lst = get_list(ctx);
svr_key_item *node = NULL, *next = NULL;
HAL_MutexLock(lst->list_mutex);
list_for_each_entry_safe(node, next, &lst->lst_svr, lst, svr_key_item) {
if (strcmp(node->keyInfo.keyprefix, keyprefix) == 0) {
coap_free(node->keyInfo.secret);
list_del(&node->lst);
coap_free(node);
--lst->svr_count;
break;
}
}
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
int alcs_set_revocation(CoAPContext *ctx, const char *seqlist)
{
auth_list *lst = get_list(ctx);
int len;
HAL_MutexLock(lst->list_mutex);
len = seqlist ? strlen(seqlist) : 0;
if (lst->revocation) {
coap_free(lst->revocation);
lst->revocation = NULL;
}
if (len > 0) {
lst->revocation = (char *)coap_malloc(len + 1);
strcpy(lst->revocation, seqlist);
}
HAL_MutexUnlock(lst->list_mutex);
return COAP_SUCCESS;
}
/* ----------------------------------------- */
void send_err_rsp(CoAPContext *ctx, NetworkAddr *addr, int code, CoAPMessage *request)
{
CoAPMessage sendMsg;
CoAPLenString payload = {0};
CoAPLenString token;
alcs_msg_init(ctx, &sendMsg, code, COAP_MESSAGE_TYPE_ACK, 0, &payload, NULL);
token.len = request->header.tokenlen;
token.data = request->token;
alcs_sendrsp(ctx, addr, &sendMsg, 1, request->header.msgid, &token);
}
void call_cb(CoAPContext *context, const char *path, NetworkAddr *remote, CoAPMessage *message, const char *key,
char *buf, CoAPRecvMsgHandler cb)
{
CoAPMessage tmpMsg;
memcpy(&tmpMsg, message, sizeof(CoAPMessage));
if (key && buf) {
int len = alcs_decrypt((const char *)message->payload, message->payloadlen, key, buf);
tmpMsg.payload = (unsigned char *)buf;
tmpMsg.payloadlen = len;
#ifdef LOG_REPORT_TO_CLOUD
get_msgid(buf, 0);
#endif
} else {
tmpMsg.payload = NULL;
tmpMsg.payloadlen = 0;
}
cb(context, path, remote, &tmpMsg);
}
static secure_resource_cb_item *get_resource_by_path(const char *path)
{
secure_resource_cb_item *node, *next;
char path_calc[MAX_PATH_CHECKSUM_LEN] = {0};
CoAPPathMD5_sum(path, strlen(path), path_calc, MAX_PATH_CHECKSUM_LEN);
list_for_each_entry_safe(node, next, &secure_resource_cb_head, lst, secure_resource_cb_item) {
if (node->path_type == PATH_NORMAL) {
if (memcmp(node->path, path_calc, MAX_PATH_CHECKSUM_LEN) == 0) {
return node;
}
} else if (strlen(node->filter_path) > 0) {
if (CoAPResource_topicFilterMatch(node->filter_path, path) == 0) {
return node;
}
}
}
COAP_ERR("receive unknown request, path:%s", path);
return NULL;
}
void recv_msg_handler(CoAPContext *context, const char *path, NetworkAddr *remote, CoAPMessage *message)
{
secure_resource_cb_item *node = get_resource_by_path(path);
struct list_head *sessions;
session_item *session;
unsigned int obsVal;
unsigned int sessionId = 0;
CoAPUintOption_get(message, COAP_OPTION_SESSIONID, &sessionId);
COAP_DEBUG("recv_msg_handler, sessionID:%d", (int)sessionId);
if (!node) {
return;
}
sessions = get_svr_session_list(context);
session = get_session_by_checksum(sessions, remote, node->pk_dn);
if (!session || session->sessionId != sessionId) {
send_err_rsp(context, remote, COAP_MSG_CODE_401_UNAUTHORIZED, message);
COAP_ERR("need auth, path:%s, from:%s", path, remote->addr);
return;
}
if (CoAPUintOption_get(message, COAP_OPTION_OBSERVE, &obsVal) == COAP_SUCCESS) {
if (obsVal == 0) {
CoAPObsServer_add(context, path, remote, message);
}
}
if (message->payloadlen < 256) {
char buf[256];
call_cb(context, path, remote, message, session->sessionKey, buf, node->cb);
} else {
char *buf = (char *)coap_malloc(message->payloadlen);
if (buf) {
call_cb(context, path, remote, message, session->sessionKey, buf, node->cb);
coap_free(buf);
}
}
}
int alcs_resource_register_secure(CoAPContext *context, const char *pk, const char *dn, const char *path,
unsigned short permission,
unsigned int ctype, unsigned int maxage, CoAPRecvMsgHandler callback)
{
secure_resource_cb_item *node = NULL, *next_node = NULL;
char pk_dn[100] = {0};
int dup = 0;
secure_resource_cb_item *item;
COAP_INFO("alcs_resource_register_secure");
item = (secure_resource_cb_item *)coap_malloc(sizeof(secure_resource_cb_item));
if (item == NULL) {
return -1;
}
memset(item, 0, sizeof(secure_resource_cb_item));
item->cb = callback;
item->path_type = PATH_NORMAL;
if (strstr(path, "/#") != NULL) {
item->path_type = PATH_FILTER;
} else {
CoAPPathMD5_sum(path, strlen(path), item->path, MAX_PATH_CHECKSUM_LEN);
}
list_for_each_entry_safe(node, next_node, &secure_resource_cb_head, lst, secure_resource_cb_item) {
if (item->path_type == PATH_NORMAL && node->path_type == PATH_NORMAL) {
if (memcmp(node->path, item->path, MAX_PATH_CHECKSUM_LEN) == 0) {
dup = 1;
}
} else if (item->path_type == PATH_FILTER && node->path_type == PATH_FILTER) {
if (strncmp(node->filter_path, path, strlen(path)) == 0) {
dup = 1;
}
}
}
if (dup == 0) {
if (item->path_type == PATH_FILTER) {
item->filter_path = coap_malloc(strlen(path) + 1);
if (item->filter_path == NULL) {
coap_free(item);
return -1;
}
memset(item->filter_path, 0, strlen(path) + 1);
strncpy(item->filter_path, path, strlen(path));
}
strncpy(pk_dn, pk, sizeof(pk_dn) - 1);
strncat(pk_dn, dn, sizeof(pk_dn) - strlen(pk_dn) - 1);
CoAPPathMD5_sum(pk_dn, strlen(pk_dn), item->pk_dn, PK_DN_CHECKSUM_LEN);
list_add_tail(&item->lst, &secure_resource_cb_head);
} else {
coap_free(item);
}
return CoAPResource_register(context, path, permission, ctype, maxage, &recv_msg_handler);
}
void alcs_resource_cb_deinit(void)
{
secure_resource_cb_item *del_item = NULL;
list_for_each_entry(del_item, &secure_resource_cb_head, lst, secure_resource_cb_item) {
list_del(&del_item->lst);
if (del_item->path_type == PATH_FILTER) {
coap_free(del_item->filter_path);
}
coap_free(del_item);
del_item = list_entry(&secure_resource_cb_head, secure_resource_cb_item, lst);
}
}
void alcs_auth_list_deinit(void)
{
auth_list *auth_list_ctx = get_list(ctx);
svr_key_item *del_item = NULL, *next_item = NULL;
list_for_each_entry_safe(del_item, next_item, &auth_list_ctx->lst_svr, lst, svr_key_item) {
list_del(&del_item->lst);
if (del_item->keyInfo.secret) {
coap_free(del_item->keyInfo.secret);
}
coap_free(del_item);
}
}
void alcs_rec_heart_beat(CoAPContext *ctx, const char *path, NetworkAddr *remote, CoAPMessage *request)
{
struct list_head *ctl_head = get_svr_session_list(ctx);
session_item *session = NULL;
session_item *node = NULL, *next = NULL;
int seqlen, datalen;
char *seq, *data;
CoAPMessage msg;
char databuf[32];
char payloadbuf[128];
CoAPLenString payload;
COAP_DEBUG("alcs_rec_heart_beat");
if (!ctl_head || list_empty(ctl_head)) {
return;
}
list_for_each_entry_safe(node, next, ctl_head, lst, session_item) {
if (node->sessionId && is_networkadd_same(&node->addr, remote)) {
node->heart_time = HAL_UptimeMs();
session = node;
}
}
if (!session) {
COAP_INFO("receive stale heart beat");
}
if (!req_payload_parser((const char *)request->payload, request->payloadlen, &seq, &seqlen, &data, &datalen)) {
/* do nothing */
}
if (session) {
HAL_Snprintf(databuf, sizeof(databuf), "\"delayTime\":%d", default_heart_expire / 1000);
HAL_Snprintf(payloadbuf, sizeof(payloadbuf), RES_FORMAT, seqlen, seq, 200, databuf);
} else {
HAL_Snprintf(payloadbuf, sizeof(payloadbuf), RES_FORMAT, seqlen, seq, ALCS_HEART_FAILAUTH, "");
}
payload.data = (unsigned char *)payloadbuf;
payload.len = strlen(payloadbuf);
alcs_msg_init(ctx, &msg, COAP_MSG_CODE_205_CONTENT, COAP_MESSAGE_TYPE_CON, 0, &payload, NULL);
if (session) {
msg.header.msgid = request->header.msgid;
msg.header.tokenlen = request->header.tokenlen;
memcpy(&msg.token, request->token, request->header.tokenlen);
internal_secure_send(ctx, session, remote, &msg, 1, NULL);
} else {
CoAPLenString token = {request->header.tokenlen, request->token};
alcs_sendrsp(ctx, remote, &msg, 1, request->header.msgid, &token);
}
alcs_msg_deinit(&msg);
}
int observe_data_encrypt(CoAPContext *ctx, const char *path, NetworkAddr *from, CoAPMessage *message,
CoAPLenString *src, CoAPLenString *dest)
{
secure_resource_cb_item *node = get_resource_by_path(path);
struct list_head *sessions;
session_item *session;
COAP_DEBUG("observe_data_encrypt, src:%.*s", src->len, src->data);
if (!node) {
return COAP_ERROR_NOT_FOUND;
}
sessions = get_svr_session_list(ctx);
session = get_session_by_checksum(sessions, from, node->pk_dn);
if (session) {
dest->len = (src->len & 0xfffffff0) + 16;
dest->data = (unsigned char *)coap_malloc(dest->len);
alcs_encrypt((const char *)src->data, src->len, session->sessionKey, dest->data);
CoAPUintOption_add(message, COAP_OPTION_SESSIONID, session->sessionId);
return COAP_SUCCESS;
}
return COAP_ERROR_NOT_FOUND;
}
void on_svr_auth_timer(CoAPContext *ctx)
{
struct list_head *head = get_svr_session_list(ctx);
int tick;
session_item *node = NULL, *next = NULL;
if (!head || list_empty(head)) {
return;
}
/* COAP_INFO ("on_svr_auth_timer:%d", (int)HAL_UptimeMs()); */
/* device_auth_list* dev = get_device (ctx); */
tick = HAL_UptimeMs();
list_for_each_entry_safe(node, next, head, lst, session_item) {
if (node->sessionId && node->heart_time + default_heart_expire < tick) {
COAP_ERR("heart beat timeout");
remove_session(ctx, node);
}
}
}
#endif

View File

@@ -0,0 +1,277 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOT_EXPORT_ALCS_BACKUP_H_
#define _IOT_EXPORT_ALCS_BACKUP_H_
#define IOTX_ALCS_ROLE_CLIENT (0x01)
#define IOTX_ALCS_ROLE_SERVER (0x02)
#define ALCS_MSG_MAX_TOKEN_LEN (8)
typedef enum {
/*iotx_alcs_send Message Result And Receive Message*/
IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_SUCCESS,
IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_RESP_TIMEOUT,
IOTX_ALCS_EVENT_MSG_RECV_MESSAGE,
/*Its data type is @iotx_alcs_transfer_msg_t and see detail at the declare of this type.*/
} iotx_alcs_event_type_t;
typedef struct iotx_alcs_event_msg_st {
/* Specify the event type */
iotx_alcs_event_type_t event_type;
void *msg;
} iotx_alcs_event_msg_t, *iotx_alcs_event_msg_pt;
typedef struct iotx_alcs_transfer_msg_st {
char *ip;
uint16_t port;
char *uri;
uint8_t token_len;
uint8_t *token;
uint16_t payload_len;
uint8_t *payload;
} iotx_alcs_transfer_msg_t, *iotx_alcs_transfer_msg_pt;
typedef void (*iotx_alcs_event_handle_func_fpt)(void *pcontext, void *phandle, iotx_alcs_event_msg_t *msg);
typedef struct {
iotx_alcs_event_handle_func_fpt h_fp;
void *pcontext;
} iotx_alcs_event_handle_t;
typedef struct iotx_alcs_param_st {
uint8_t role; /*can be client, server or both*/
uint8_t send_maxcount; /*list maximal count*/
uint8_t obs_maxcount; /*observe maximal count*/
uint16_t port; /* Local port */
char *group; /* Multicast address */
uint32_t waittime;
uint8_t res_maxcount;
iotx_alcs_event_handle_t *handle_event;
} iotx_alcs_param_t, *iotx_alcs_param_pt;
#define ITOX_ALCS_COAP_MSG_CODE_DEF(N) (((N)/100 << 5) | (N)%100)
/*CoAP Message codes*/
typedef enum {
/* CoAP Empty Message */
ITOX_ALCS_COAP_MSG_CODE_EMPTY_MESSAGE = ITOX_ALCS_COAP_MSG_CODE_DEF(0), /* Mapping to CoAP code 0.00 */
/* CoAP Method Codes */
ITOX_ALCS_COAP_MSG_CODE_GET = ITOX_ALCS_COAP_MSG_CODE_DEF(1), /* CoAP Get method */
ITOX_ALCS_COAP_MSG_CODE_POST = ITOX_ALCS_COAP_MSG_CODE_DEF(2), /* CoAP Post method */
ITOX_ALCS_COAP_MSG_CODE_PUT = ITOX_ALCS_COAP_MSG_CODE_DEF(3), /* CoAP Put method */
ITOX_ALCS_COAP_MSG_CODE_DELETE = ITOX_ALCS_COAP_MSG_CODE_DEF(4), /* CoAP Delete method */
/* CoAP Success Response Codes */
ITOX_ALCS_COAP_MSG_CODE_201_CREATED = ITOX_ALCS_COAP_MSG_CODE_DEF(201), /* Mapping to CoAP code 2.01, Hex:0x41, Created */
ITOX_ALCS_COAP_MSG_CODE_202_DELETED = ITOX_ALCS_COAP_MSG_CODE_DEF(202), /* Mapping to CoAP code 2.02, Hex:0x42, Deleted*/
ITOX_ALCS_COAP_MSG_CODE_203_VALID = ITOX_ALCS_COAP_MSG_CODE_DEF(203), /* Mapping to CoAP code 2.03, Hex:0x43, Valid*/
ITOX_ALCS_COAP_MSG_CODE_204_CHANGED = ITOX_ALCS_COAP_MSG_CODE_DEF(204), /* Mapping to CoAP code 2.04, Hex:0x44, Changed*/
ITOX_ALCS_COAP_MSG_CODE_205_CONTENT = ITOX_ALCS_COAP_MSG_CODE_DEF(205), /* Mapping to CoAP code 2.05, Hex:0x45, Content*/
ITOX_ALCS_COAP_MSG_CODE_231_CONTINUE = ITOX_ALCS_COAP_MSG_CODE_DEF(231), /* Mapping to CoAP code 2.31, Hex:0x5F, Continue*/
/* CoAP Client Error Response Codes */
ITOX_ALCS_COAP_MSG_CODE_400_BAD_REQUEST = ITOX_ALCS_COAP_MSG_CODE_DEF(400), /* Mapping to CoAP code 4.00, Hex:0x80, Bad Request */
ITOX_ALCS_COAP_MSG_CODE_401_UNAUTHORIZED = ITOX_ALCS_COAP_MSG_CODE_DEF(401), /* Mapping to CoAP code 4.01, Hex:0x81, Unauthorized */
ITOX_ALCS_COAP_MSG_CODE_402_BAD_OPTION = ITOX_ALCS_COAP_MSG_CODE_DEF(402), /* Mapping to CoAP code 4.02, Hex:0x82, Bad Option */
ITOX_ALCS_COAP_MSG_CODE_403_FORBIDDEN = ITOX_ALCS_COAP_MSG_CODE_DEF(403), /* Mapping to CoAP code 4.03, Hex:0x83, Forbidden */
ITOX_ALCS_COAP_MSG_CODE_404_NOT_FOUND = ITOX_ALCS_COAP_MSG_CODE_DEF(404), /* Mapping to CoAP code 4.04, Hex:0x84, Not Found */
ITOX_ALCS_COAP_MSG_CODE_405_METHOD_NOT_ALLOWED = ITOX_ALCS_COAP_MSG_CODE_DEF(405), /* Mapping to CoAP code 4.05, Hex:0x85, Method Not Allowed */
ITOX_ALCS_COAP_MSG_CODE_406_NOT_ACCEPTABLE = ITOX_ALCS_COAP_MSG_CODE_DEF(406), /* Mapping to CoAP code 4.06, Hex:0x86, Not Acceptable */
ITOX_ALCS_COAP_MSG_CODE_408_REQUEST_ENTITY_INCOMPLETE = ITOX_ALCS_COAP_MSG_CODE_DEF(408), /* Mapping to CoAP code 4.08, Hex:0x88, Request Entity Incomplete */
ITOX_ALCS_COAP_MSG_CODE_412_PRECONDITION_FAILED = ITOX_ALCS_COAP_MSG_CODE_DEF(412), /* Mapping to CoAP code 4.12, Hex:0x8C, Precondition Failed */
ITOX_ALCS_COAP_MSG_CODE_413_REQUEST_ENTITY_TOO_LARGE = ITOX_ALCS_COAP_MSG_CODE_DEF(413), /* Mapping to CoAP code 4.13, Hex:0x8D, Request Entity Too Large */
ITOX_ALCS_COAP_MSG_CODE_415_UNSUPPORTED_CONTENT_FORMAT = ITOX_ALCS_COAP_MSG_CODE_DEF(415), /* Mapping to CoAP code 4.15, Hex:0x8F, Unsupported Content-Format */
/* CoAP Server Error Response Codes */
ITOX_ALCS_COAP_MSG_CODE_500_INTERNAL_SERVER_ERROR = ITOX_ALCS_COAP_MSG_CODE_DEF(500), /* Mapping to CoAP code 5.00, Hex:0xA0, Internal Server Error */
ITOX_ALCS_COAP_MSG_CODE_501_NOT_IMPLEMENTED = ITOX_ALCS_COAP_MSG_CODE_DEF(501), /* Mapping to CoAP code 5.01, Hex:0xA1, Not Implemented */
ITOX_ALCS_COAP_MSG_CODE_502_BAD_GATEWAY = ITOX_ALCS_COAP_MSG_CODE_DEF(502), /* Mapping to CoAP code 5.02, Hex:0xA2, Bad Gateway */
ITOX_ALCS_COAP_MSG_CODE_503_SERVICE_UNAVAILABLE = ITOX_ALCS_COAP_MSG_CODE_DEF(503), /* Mapping to CoAP code 5.03, Hex:0xA3, Service Unavailable */
ITOX_ALCS_COAP_MSG_CODE_504_GATEWAY_TIMEOUT = ITOX_ALCS_COAP_MSG_CODE_DEF(504), /* Mapping to CoAP code 5.04, Hex:0xA4, Gateway Timeout */
ITOX_ALCS_COAP_MSG_CODE_505_PROXYING_NOT_SUPPORTED = ITOX_ALCS_COAP_MSG_CODE_DEF(505) /* Mapping to CoAP code 5.05, Hex:0xA5, Proxying Not Supported */
} iotx_alcs_message_code_t;
typedef enum {
IOTX_ALCS_MESSAGE_TYPE_CON = 0,
IOTX_ALCS_MESSAGE_TYPE_NON = 1,
IOTX_ALCS_MESSAGE_TYPE_ACK = 2,
IOTX_ALCS_MESSAGE_TYPE_RST = 3
} iotx_alcs_message_type_t;
typedef enum {
IOTX_ALCS_MESSAGE_PERM_NONE = 0x0000,
IOTX_ALCS_MESSAGE_PERM_GET = 0x0001,
IOTX_ALCS_MESSAGE_PERM_POST = 0x0002,
IOTX_ALCS_MESSAGE_PERM_PUT = 0x0004,
IOTX_ALCS_MESSAGE_PERM_DEL = 0x0008,
IOTX_ALCS_MESSAGE_PERM_OBSERVE = 0x0100
} iotx_alcs_message_perm_t;
typedef enum {
IOTX_ALCS_MESSAGE_CT_TEXT_PLAIN = 0, /* text/plain (UTF-8) */
IOTX_ALCS_MESSAGE_CT_APP_LINK_FORMAT = 40, /* application/link-format */
IOTX_ALCS_MESSAGE_CT_APP_XML = 41, /* application/xml */
IOTX_ALCS_MESSAGE_CT_APP_OCTET_STREAM = 42, /* application/octet-stream */
IOTX_ALCS_MESSAGE_CT_APP_RDF_XML = 43, /* application/rdf+xml */
IOTX_ALCS_MESSAGE_CT_APP_EXI = 47, /* application/exi */
IOTX_ALCS_MESSAGE_CT_APP_JSON = 50, /* application/json */
IOTX_ALCS_MESSAGE_CT_APP_CBOR = 60 /* application/cbor */
} iotx_alcs_message_content_type_t;
typedef struct iotx_alcs_msg_st {
uint16_t group_id; /*multicast group id, used as unicast when 0*/
char *ip; /*dotted decimal notation, max len 16*/
uint16_t port;
iotx_alcs_message_code_t msg_code;
iotx_alcs_message_type_t msg_type;
char *uri;
uint32_t payload_len;
uint8_t *payload;
} iotx_alcs_msg_t, *iotx_alcs_msg_pt;
typedef struct iotx_alcs_res_st {
char *uri;
int32_t need_auth;
iotx_alcs_message_perm_t msg_perm;
iotx_alcs_message_content_type_t msg_ct;
uint32_t maxage; /*0~60*/
CoAPRecvMsgHandler callback;
} iotx_alcs_res_t, *iotx_alcs_res_pt;
/**
* @brief Construct the ALCS handle
* This function initialize the data structures, initialize ALCS information.
*
* @param [in] params: specify the ALCS initialize parameter.
*
* @retval NULL : Construct failed.
* @retval NOT_NULL : The handle of ALCS.
* @see None.
*/
void *iotx_alcs_construct(iotx_alcs_param_t *params);
/**
* @brief Init Cloud Part
* This function initialize the cloud part.
*
* @param [in] params: specify the ALCS initialize parameter.
*
* @retval NULL : Construct failed.
* @retval NOT_NULL : The handle of ALCS.
* @see None.
*/
int iotx_alcs_cloud_init(void *handle);
/**
* @brief Deconstruct the ALCS handle
* This function distroy ALCS handle and release the related resource.
*
* @param [in] phandle: pointer of handle, specify the MQTT client.
*
* @retval 0 : Deconstruct success.
* @retval -1 : Deconstruct failed.
* @see None.
*/
int iotx_alcs_destroy(void **phandle);
/**
* @brief Handle ALCS message from specific udp port
*
* @param [in] handle: specify the ALCS handle.
*
* @return status.
* @see None.
*/
int iotx_alcs_yield(void *handle);
/**
* @brief Send Message To Secific Deivce
*
* @param [in] handle: specify the ALCS handle.
*
* @return status.
* @see None.
*/
int iotx_alcs_send(void *handle, iotx_alcs_msg_t *msg);
/**
* @brief Send Response Message To Secific Deivce
*
* @param [in] handle: specify the ALCS handle.
*
* @return status.
* @see None.
*/
int iotx_alcs_send_Response(void *handle, iotx_alcs_msg_t *msg, uint8_t token_len, uint8_t *token);
/**
* @brief Register Resource
*
* @param [in] handle: specify the ALCS handle.
* @param [in] handle: the resource need to be registered.
*
* @return status.
* @see None.
*/
int iotx_alcs_register_resource(void *handle, iotx_alcs_res_t *resource);
/**
* @brief ALCS Observe Notify
*
* @param [in] handle: specify the ALCS handle.
* @param [in] uri: the resource need to notify.
*
* @return status.
* @see None.
*/
int iotx_alcs_observe_notify(void *handle, const char *uri, uint32_t payload_len, uint8_t *payload);
/**
* @brief Unregister Resource
*
* @param [in] handle: specify the ALCS handle.
* @param [in] handle: the resource need to be registered.
*
* @return status.
* @see None.
*/
int iotx_alcs_unregister_resource(void *handle, char *uri);
/**
* @brief Add sub device
*
* @param [in] handle: specify the ALCS handle.
* @param [in] pk: the productkey of device.
* @param [in] dn: the deviceName of device.
*
* @return status.
* @see None.
*/
int iotx_alcs_add_sub_device(void *handle, const char *pk, const char *dn);
/**
* @brief remove sub device
*
* @param [in] handle: specify the ALCS handle.
* @param [in] pk: the productkey of device.
* @param [in] dn: the deviceName of device.
*
* @return status.
* @see None.
*/
int iotx_alcs_remove_sub_device(void *handle, const char *pk, const char *dn);
#endif

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef __IOTX_ALCS_CONFIG_H__
#define __IOTX_ALCS_CONFIG_H__
#if 0
#ifndef ALCS_CLIENT_ENABLED
#define ALCS_CLIENT_ENABLED (1)
#endif
#endif
#ifndef ALCS_SERVER_ENABLED
#define ALCS_SERVER_ENABLED (1)
#endif
#ifndef USE_ALCS_SECURE
#define USE_ALCS_SECURE (1)
#endif
#ifndef KEYPREFIX_LEN
#define KEYPREFIX_LEN (8)
#endif
#ifndef GROUPID_LEN
#define GROUPID_LEN (8)
#endif
#endif /* #ifndef __IOTX_ALCS_CONFIG_H__ */

View File

@@ -0,0 +1,741 @@
#include "iotx_dm_internal.h"
#ifdef DEV_BIND_ENABLED
#include "dev_bind_api.h"
#endif
#ifdef LOG_REPORT_TO_CLOUD
#include "iotx_log_report.h"
#endif
static dm_client_uri_map_t g_dm_client_uri_map[] = {
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
{DM_URI_THING_EVENT_POST_REPLY_WILDCARD, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_event_post_reply },
#ifdef DEVICE_MODEL_SHADOW
{DM_URI_THING_PROPERTY_DESIRED_DELETE_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_property_desired_delete_reply},
{DM_URI_THING_PROPERTY_DESIRED_GET_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_property_desired_get_reply },
{DM_URI_THING_SERVICE_PROPERTY_GET, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_service_property_get },
#endif
{DM_URI_THING_SERVICE_PROPERTY_SET, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_service_property_set },
{DM_URI_THING_SERVICE_REQUEST_WILDCARD, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_service_request },
{DM_URI_THING_DEVICEINFO_UPDATE_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_deviceinfo_update_reply },
{DM_URI_THING_DEVICEINFO_DELETE_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_deviceinfo_delete_reply },
{DM_URI_THING_DYNAMICTSL_GET_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_dynamictsl_get_reply },
{DM_URI_RRPC_REQUEST_WILDCARD, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_rrpc_request_wildcard },
{DM_URI_NTP_RESPONSE, DM_URI_EXT_NTP_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_ntp_response },
{NULL, DM_URI_EXT_ERROR_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_ext_error },
#endif
{DM_URI_THING_MODEL_DOWN_RAW, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_model_down_raw },
{DM_URI_THING_MODEL_UP_RAW_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_ALL, (void *)dm_client_thing_model_up_raw_reply },
#ifdef DEVICE_MODEL_GATEWAY
{DM_URI_THING_TOPO_ADD_NOTIFY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_topo_add_notify },
{DM_URI_THING_GATEWAY_PERMIT, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_gateway_permit },
{DM_URI_THING_SUB_REGISTER_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_sub_register_reply },
{DM_URI_THING_SUB_UNREGISTER_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_sub_unregister_reply },
{DM_URI_THING_TOPO_ADD_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_topo_add_reply },
{DM_URI_THING_TOPO_DELETE_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_topo_delete_reply },
{DM_URI_THING_TOPO_GET_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_topo_get_reply },
{DM_URI_THING_LIST_FOUND_REPLY, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_list_found_reply },
{DM_URI_COMBINE_LOGIN_REPLY, DM_URI_EXT_SESSION_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_combine_login_reply },
{DM_URI_COMBINE_LOGOUT_REPLY, DM_URI_EXT_SESSION_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_combine_logout_reply },
{DM_URI_THING_DISABLE, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_disable },
{DM_URI_THING_ENABLE, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_enable },
{DM_URI_THING_DELETE, DM_URI_SYS_PREFIX, IOTX_DM_DEVICE_GATEWAY, (void *)dm_client_thing_delete },
#endif
};
static int _dm_client_subscribe_filter(char *uri, char *uri_name, char product_key[IOTX_PRODUCT_KEY_LEN + 1],
char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int res = 0;
#endif
if (uri_name == NULL) {
return SUCCESS_RETURN;
}
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
if (strlen(uri_name) == strlen(DM_URI_THING_EVENT_POST_REPLY_WILDCARD) &&
memcmp(uri_name, DM_URI_THING_EVENT_POST_REPLY_WILDCARD, strlen(uri_name)) == 0) {
int event_post_reply_opt = 0;
res = dm_opt_get(DM_OPT_DOWNSTREAM_EVENT_POST_REPLY, &event_post_reply_opt);
if (res == SUCCESS_RETURN && event_post_reply_opt == 0) {
dm_client_unsubscribe(uri);
return FAIL_RETURN;
}
}
#endif
return SUCCESS_RETURN;
}
int dm_client_subscribe_all(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1],
int dev_type)
{
int res = 0, index = 0, fail_count = 0;
int number = sizeof(g_dm_client_uri_map) / sizeof(dm_client_uri_map_t);
char *uri = NULL;
uint8_t local_sub = 0;
#ifdef SUB_PERSISTENCE_ENABLED
char device_key[IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN + 4] = {0};
#endif
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
index = 1;
for (fail_count = 0; fail_count < IOTX_DM_CLIENT_SUB_RETRY_MAX_COUNTS; fail_count++) {
res = dm_utils_service_name((char *)g_dm_client_uri_map[0].uri_prefix, (char *)g_dm_client_uri_map[0].uri_name,
product_key, device_name, &uri);
if (res < SUCCESS_RETURN) {
continue;
}
res = _dm_client_subscribe_filter(uri, (char *)g_dm_client_uri_map[0].uri_name, product_key, device_name);
if (res < SUCCESS_RETURN) {
DM_free(uri);
continue;
}
res = dm_client_subscribe(uri, (iotx_cm_data_handle_cb)g_dm_client_uri_map[0].callback, 0);
if (res < SUCCESS_RETURN) {
DM_free(uri);
continue;
}
DM_free(uri);
break;
}
#else
index = 0;
#endif
fail_count = 0;
#ifdef SUB_PERSISTENCE_ENABLED
{
int len = 1;
HAL_Snprintf(device_key, IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN, "qub_%s%s", product_key, device_name);
HAL_Kv_Get(device_key, &local_sub, &len);
}
#endif
for (; index < number; index++) {
if ((g_dm_client_uri_map[index].dev_type & dev_type) == 0) {
continue;
}
dm_log_info("index: %d", index);
if (fail_count >= IOTX_DM_CLIENT_SUB_RETRY_MAX_COUNTS) {
fail_count = 0;
continue;
}
res = dm_utils_service_name((char *)g_dm_client_uri_map[index].uri_prefix, (char *)g_dm_client_uri_map[index].uri_name,
product_key, device_name, &uri);
if (res < SUCCESS_RETURN) {
index--;
continue;
}
res = _dm_client_subscribe_filter(uri, (char *)g_dm_client_uri_map[index].uri_name, product_key, device_name);
if (res < SUCCESS_RETURN) {
DM_free(uri);
continue;
}
res = dm_client_subscribe(uri, (iotx_cm_data_handle_cb)g_dm_client_uri_map[index].callback, &local_sub);
if (res < SUCCESS_RETURN) {
index--;
fail_count++;
DM_free(uri);
continue;
}
fail_count = 0;
DM_free(uri);
}
#ifdef SUB_PERSISTENCE_ENABLED
local_sub = 1;
HAL_Kv_Set(device_key, &local_sub, 1, 1);
#endif
return SUCCESS_RETURN;
}
static void _dm_client_event_cloud_connected_handle(void)
{
#ifdef DEV_BIND_ENABLED
static int awss_reported = 0;
if(awss_reported == 0) {
awss_reported = 1;
awss_report_cloud();
}
#endif
dm_log_info("IOTX_CM_EVENT_CLOUD_CONNECTED");
dm_msg_cloud_connected();
}
static void _dm_client_event_cloud_disconnect_handle(void)
{
dm_log_info("IOTX_CM_EVENT_CLOUD_DISCONNECT");
dm_msg_cloud_disconnect();
}
void dm_client_event_handle(int fd, iotx_cm_event_msg_t *event, void *context)
{
switch (event->type) {
case IOTX_CM_EVENT_CLOUD_CONNECTED: {
_dm_client_event_cloud_connected_handle();
}
break;
case IOTX_CM_EVENT_CLOUD_CONNECT_FAILED: {
}
break;
case IOTX_CM_EVENT_CLOUD_DISCONNECT: {
_dm_client_event_cloud_disconnect_handle();
}
break;
default:
break;
}
}
void dm_client_thing_model_down_raw(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_model_down_raw(&source);
}
void dm_client_thing_model_up_raw_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_model_up_raw_reply(&source);
}
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
void dm_client_thing_service_property_set(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
int prop_set_reply_opt = 0;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_SERVICE_PROPERTY_SET_REPLY;
res = dm_msg_proc_thing_service_property_set(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
prop_set_reply_opt = 0;
res = dm_opt_get(DM_OPT_UPSTREAM_PROPERTY_SET_REPLY, &prop_set_reply_opt);
if (res == SUCCESS_RETURN) {
if (prop_set_reply_opt) {
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
#ifdef LOG_REPORT_TO_CLOUD
if (SUCCESS_RETURN == check_target_msg(request.id.value, request.id.value_length)) {
send_permance_info(request.id.value, request.id.value_length, "2", 1);
}
#endif
}
}
}
#ifdef DEVICE_MODEL_SHADOW
void dm_client_thing_service_property_get(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
unsigned char *data = NULL;
int data_len = 0;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_SERVICE_PROPERTY_GET_REPLY;
res = dm_msg_proc_thing_service_property_get(&source, &dest, &request, &response, &data, &data_len);
if (res < SUCCESS_RETURN) {
return;
}
}
#endif
void dm_client_thing_service_request(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_service_request(&source);
}
void dm_client_thing_event_post_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_event_post_reply(&source);
}
#ifdef DEVICE_MODEL_SHADOW
void dm_client_thing_property_desired_get_reply(int fd, const char *topic, const char *payload,
unsigned int payload_len, void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_property_desired_get_reply(&source);
}
void dm_client_thing_property_desired_delete_reply(int fd, const char *topic, const char *payload,
unsigned int payload_len, void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_property_desired_delete_reply(&source);
}
#endif
void dm_client_thing_deviceinfo_update_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_deviceinfo_update_reply(&source);
}
void dm_client_thing_deviceinfo_delete_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_deviceinfo_delete_reply(&source);
}
void dm_client_thing_dynamictsl_get_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_dynamictsl_get_reply(&source);
}
void dm_client_rrpc_request_wildcard(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_rrpc_request(&source);
}
void dm_client_ntp_response(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_disp_ntp_response(&source);
}
void dm_client_ext_error(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_disp_ext_error_response(&source);
}
#endif
#ifdef DEVICE_MODEL_GATEWAY
int dm_client_subdev_unsubscribe(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
int res = 0, index = 0;
int number = sizeof(g_dm_client_uri_map) / sizeof(dm_client_uri_map_t);
char *uri = NULL;
for (index = 0; index < number; index++) {
if ((g_dm_client_uri_map[index].dev_type & IOTX_DM_DEVICE_SUBDEV) == 0) {
continue;
}
res = dm_utils_service_name((char *)g_dm_client_uri_map[index].uri_prefix, (char *)g_dm_client_uri_map[index].uri_name,
product_key, device_name, &uri);
if (res < SUCCESS_RETURN) {
index--;
continue;
}
dm_client_unsubscribe(uri);
DM_free(uri);
}
return SUCCESS_RETURN;
}
void dm_client_thing_topo_add_notify(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_TOPO_ADD_NOTIFY_REPLY;
res = dm_msg_proc_thing_topo_add_notify(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
}
void dm_client_thing_disable(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_DISABLE_REPLY;
res = dm_msg_proc_thing_disable(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
}
void dm_client_thing_enable(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_ENABLE_REPLY;
res = dm_msg_proc_thing_enable(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
}
void dm_client_thing_delete(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_DELETE_REPLY;
res = dm_msg_proc_thing_delete(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
}
void dm_client_thing_gateway_permit(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dest.uri_name = DM_URI_THING_GATEWAY_PERMIT_REPLY;
res = dm_msg_proc_thing_gateway_permit(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
return;
}
dm_msg_response(DM_MSG_DEST_CLOUD, &request, &response, "{}", strlen("{}"), NULL);
}
void dm_client_thing_sub_register_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_sub_register_reply(&source);
}
void dm_client_thing_sub_unregister_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_sub_unregister_reply(&source);
}
void dm_client_thing_topo_add_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_topo_add_reply(&source);
}
void dm_client_thing_topo_delete_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_topo_delete_reply(&source);
}
void dm_client_thing_topo_get_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_topo_get_reply(&source);
}
void dm_client_thing_list_found_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_thing_list_found_reply(&source);
}
void dm_client_combine_login_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_combine_login_reply(&source);
}
void dm_client_combine_logout_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context)
{
dm_msg_source_t source;
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = topic;
source.payload = (unsigned char *)payload;
source.payload_len = payload_len;
source.context = NULL;
dm_msg_proc_combine_logout_reply(&source);
}
#endif

View File

@@ -0,0 +1,75 @@
#ifndef _DM_CLIENT_H_
#define _DM_CLIENT_H_
typedef struct {
const char *uri_name;
const char *uri_prefix;
int dev_type;
void *callback;
} dm_client_uri_map_t;
void dm_client_event_handle(int fd, iotx_cm_event_msg_t *event, void *context);
int dm_client_subscribe_all(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1], int dev_type);
void dm_client_thing_model_down_raw(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_model_up_raw_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
void dm_client_thing_property_desired_get_reply(int fd, const char *topic, const char *payload,
unsigned int payload_len, void *context);
void dm_client_thing_property_desired_delete_reply(int fd, const char *topic, const char *payload,
unsigned int payload_len, void *context);
void dm_client_thing_service_property_set(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_service_property_get(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_service_property_post(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_event_property_post_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_deviceinfo_update_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_deviceinfo_delete_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_dynamictsl_get_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_service_request(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_event_post_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_rrpc_request_wildcard(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_ntp_response(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context);
void dm_client_ext_error(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context);
#endif
#ifdef DEVICE_MODEL_GATEWAY
int dm_client_subdev_unsubscribe(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1]);
void dm_client_thing_topo_add_notify(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_disable(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context);
void dm_client_thing_enable(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context);
void dm_client_thing_delete(int fd, const char *topic, const char *payload, unsigned int payload_len, void *context);
void dm_client_thing_gateway_permit(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_sub_register_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_sub_unregister_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_topo_add_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_topo_delete_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_topo_get_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_thing_list_found_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_combine_login_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
void dm_client_combine_logout_reply(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
#endif
#endif

View File

@@ -0,0 +1,145 @@
#include "iotx_dm_internal.h"
static dm_client_ctx_t g_dm_client_ctx = {0};
static dm_client_ctx_t *dm_client_get_ctx(void)
{
return &g_dm_client_ctx;
}
int dm_client_open(void)
{
int res = 0;
dm_client_ctx_t *ctx = dm_client_get_ctx();
iotx_cm_init_param_t cm_param;
memset(ctx, 0, sizeof(dm_client_ctx_t));
memset(&cm_param, 0, sizeof(iotx_cm_init_param_t));
cm_param.request_timeout_ms = IOTX_DM_CLIENT_REQUEST_TIMEOUT_MS;
cm_param.keepalive_interval_ms = IOTX_DM_CLIENT_KEEPALIVE_INTERVAL_MS;
cm_param.write_buf_size = CONFIG_MQTT_TX_MAXLEN;
cm_param.read_buf_size = CONFIG_MQTT_RX_MAXLEN;
#if defined(COAP_COMM_ENABLED) && !defined(MQTT_COMM_ENABLED)
cm_param.protocol_type = IOTX_CM_PROTOCOL_TYPE_COAP;
#else
cm_param.protocol_type = IOTX_CM_PROTOCOL_TYPE_MQTT;
#endif
cm_param.handle_event = dm_client_event_handle;
res = iotx_cm_open(&cm_param);
if (res < SUCCESS_RETURN) {
return res;
}
ctx->fd = res;
dm_log_info("CM Fd: %d", ctx->fd);
return SUCCESS_RETURN;
}
int dm_client_connect(int timeout_ms)
{
int res = 0;
dm_client_ctx_t *ctx = dm_client_get_ctx();
res = iotx_cm_connect(ctx->fd, timeout_ms);
if (res < SUCCESS_RETURN) {
return res;
}
return SUCCESS_RETURN;
}
int dm_client_close(void)
{
dm_client_ctx_t *ctx = dm_client_get_ctx();
return iotx_cm_close(ctx->fd);
}
int dm_client_subscribe(char *uri, iotx_cm_data_handle_cb callback, void *context)
{
int res = 0;
uint8_t local_sub = 0;
dm_client_ctx_t *ctx = dm_client_get_ctx();
iotx_cm_ext_params_t sub_params;
memset(&sub_params, 0, sizeof(iotx_cm_ext_params_t));
if (context != NULL) {
local_sub = *((uint8_t *)context);
}
if (local_sub == 1) {
sub_params.ack_type = IOTX_CM_MESSAGE_SUB_LOCAL;
sub_params.sync_mode = IOTX_CM_ASYNC;
} else {
sub_params.ack_type = IOTX_CM_MESSAGE_NO_ACK;
sub_params.sync_mode = IOTX_CM_SYNC;
}
sub_params.sync_timeout = IOTX_DM_CLIENT_SUB_TIMEOUT_MS;
sub_params.ack_cb = NULL;
res = iotx_cm_sub(ctx->fd, &sub_params, (const char *)uri, callback, NULL);
dm_log_info("Subscribe Result: %d", res);
if (res < SUCCESS_RETURN) {
return res;
}
return SUCCESS_RETURN;
}
int dm_client_unsubscribe(char *uri)
{
int res = 0;
dm_client_ctx_t *ctx = dm_client_get_ctx();
res = iotx_cm_unsub(ctx->fd, uri);
dm_log_info("Unsubscribe Result: %d", res);
return res;
}
int dm_client_publish(char *uri, unsigned char *payload, int payload_len, iotx_cm_data_handle_cb callback)
{
int res = 0;
char *pub_uri = NULL;
dm_client_ctx_t *ctx = dm_client_get_ctx();
iotx_cm_ext_params_t pub_param;
memset(&pub_param, 0, sizeof(iotx_cm_ext_params_t));
pub_param.ack_type = IOTX_CM_MESSAGE_NO_ACK;
pub_param.sync_mode = IOTX_CM_ASYNC;
pub_param.sync_timeout = 0;
pub_param.ack_cb = NULL;
#if defined(COAP_COMM_ENABLED) && !defined(MQTT_COMM_ENABLED)
pub_param.ack_cb = callback;
res = dm_utils_uri_add_prefix("/topic", uri, &pub_uri);
if (res < SUCCESS_RETURN) {
return FAIL_RETURN;
}
#else
pub_uri = uri;
#endif
res = iotx_cm_pub(ctx->fd, &pub_param, (const char *)pub_uri, (const char *)payload, (unsigned int)payload_len);
dm_log_info("Publish Result: %d", res);
#if defined(COAP_COMM_ENABLED) && !defined(MQTT_COMM_ENABLED)
DM_free(pub_uri);
#endif
return res;
}
int dm_client_yield(unsigned int timeout)
{
dm_client_ctx_t *ctx = dm_client_get_ctx();
return iotx_cm_yield(ctx->fd, timeout);
}

View File

@@ -0,0 +1,18 @@
#ifndef _DM_CLIENT_ADAPTER_H_
#define _DM_CLIENT_ADAPTER_H_
typedef struct {
int fd;
iotx_conn_info_t *conn_info;
void *callback;
} dm_client_ctx_t;
int dm_client_open(void);
int dm_client_connect(int timeout_ms);
int dm_client_close(void);
int dm_client_subscribe(char *uri, iotx_cm_data_handle_cb callback, void *context);
int dm_client_unsubscribe(char *uri);
int dm_client_publish(char *uri, unsigned char *payload, int payload_len, iotx_cm_data_handle_cb callback);
int dm_client_yield(unsigned int timeout);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _LINKKIT_GATEWAY_LEGACY_H_
#define _LINKKIT_GATEWAY_LEGACY_H_
#include "infra_list.h"
#include "linkkit_gateway_export.h"
#define LINKKIT_GATEWAY_LEGACY_KEY_ID "id"
#define LINKKIT_GATEWAY_LEGACY_KEY_CODE "code"
#define LINKKIT_GATEWAY_LEGACY_KEY_DEVID "devid"
#define LINKKIT_GATEWAY_LEGACY_KEY_SERVICEID "serviceid"
#define LINKKIT_GATEWAY_LEGACY_KEY_PROPERTYID "propertyid"
#define LINKKIT_GATEWAY_LEGACY_KEY_EVENTID "eventid"
#define LINKKIT_GATEWAY_LEGACY_KEY_PAYLOAD "payload"
#define LINKKIT_GATEWAY_LEGACY_KEY_PRODUCT_KEY "productKey"
#define LINKKIT_GATEWAY_LEGACY_KEY_TIME "time"
#define LINKKIT_GATEWAY_LEGACY_KEY_VERSION "version"
#define LINKKIT_GATEWAY_LEGACY_SYNC_DEFAULT_TIMEOUT_MS (10000)
typedef struct {
int devid;
linkkit_cbs_t *callback;
void *callback_ctx;
struct list_head linked_list;
} linkkit_gateway_dev_callback_node_t;
typedef void (*linkkit_gateway_upstream_async_callback)(int retval, void *ctx);
typedef struct {
int msgid;
void *semaphore;
int code;
struct list_head linked_list;
} linkkit_gateway_upstream_sync_callback_node_t;
typedef struct {
int msgid;
int timeout_ms;
uint64_t timestamp_ms;
linkkit_gateway_upstream_async_callback callback;
void *callback_ctx;
struct list_head linked_list;
} linkkit_gateway_upstream_async_callback_node_t;
typedef struct {
void *mutex;
void *upstream_mutex;
int is_inited;
int is_started;
linkkit_params_t init_params;
void *dispatch_thread;
handle_service_fota_callback_fp_t fota_callback;
struct list_head dev_callback_list;
struct list_head upstream_sync_callback_list;
struct list_head upstream_async_callback_list;
} linkkit_gateway_legacy_ctx_t;
#endif

View File

@@ -0,0 +1,185 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#ifdef DEPRECATED_LINKKIT
#include "infra_json_parser.h"
#include "mqtt_api.h"
#include "impl_ntp.h"
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#define IMPL_NTP_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "impl.ntp")
#define IMPL_NTP_FREE(ptr) LITE_free(ptr)
#else
#define IMPL_NTP_MALLOC(size) HAL_Malloc(size)
#define IMPL_NTP_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
#endif
typedef void (*ntp_reply_cb_t)(const char *);
static ntp_reply_cb_t g_ntp_reply_cb = NULL;
static char g_ntp_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
static void linkkit_ntp_time_reply(void *pcontext, void *pclient, void *mesg)
{
#define DEV_TX_TIME "deviceSendTime"
#define SERVER_RX_TIME "serverRecvTime"
#define SERVER_TX_TIME "serverSendTime"
int len = 0;
char *elem = NULL;
char server_rx_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
char server_tx_time[NTP_TIME_STR_MAX_LEN + 1] = {0};
uint32_t payload_len;
char *payload;
uint32_t tx = 0;
uint32_t rx = 0;
uint32_t diff = 0;
iotx_mqtt_event_msg_pt msg = (iotx_mqtt_event_msg_pt)mesg;
iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
switch (msg->event_type) {
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
payload_len = ptopic_info->payload_len;
payload = (char *)ptopic_info->payload;
break;
default:
goto NTP_FAIL;
}
if (payload == NULL || payload_len == 0) {
goto NTP_FAIL;
}
memset(g_ntp_time, 0, sizeof(g_ntp_time));
log_debug("[ntp]", "ntp reply len:%u, payload:%s\r\n", payload_len, payload);
/*
* get deviceSendTime, serverRecvTime, serverSendTime
*/
elem = json_get_value_by_name(payload, payload_len, SERVER_TX_TIME, &len, NULL);
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
goto NTP_FAIL;
}
memcpy(server_tx_time, elem, len);
elem = json_get_value_by_name(payload, payload_len, SERVER_RX_TIME, &len, NULL);
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
goto NTP_FAIL;
}
memcpy(server_rx_time, elem, len);
elem = json_get_value_by_name(payload, payload_len, DEV_TX_TIME, &len, NULL);
if (elem == NULL || len <= 0 || len > NTP_TIME_STR_MAX_LEN) {
goto NTP_FAIL;
}
/*
* atoi fails to convert string to integer
* so we convert manully
*/
while (len -- > 0) {
tx *= 10;
tx += elem[0] - '0';
elem ++;
}
rx = HAL_UptimeMs();
diff = (rx - tx) >> 1;
if (diff >= 1000000) {
goto NTP_FAIL;
}
len = strlen(server_tx_time);
elem = &server_tx_time[len > 9 ? len - 9 : 0];
tx = atoi(elem);
tx += diff;
if (tx > 999999999) {
tx = 999999999;
}
if (len > 9) {
sprintf(elem, "%09u", (unsigned int)tx);
} else {
sprintf(elem, "%u", (unsigned int)tx);
}
strncpy(g_ntp_time, (const char *)server_tx_time, sizeof(g_ntp_time) - 1);
NTP_FAIL:
if (g_ntp_reply_cb != NULL) {
g_ntp_reply_cb(g_ntp_time);
}
return;
}
int linkkit_ntp_time_request(void (*ntp_reply)(const char *ntp_offset_time_ms))
{
int ret = -1;
int final_len = 0;
int packet_len = 64;
int topic_len = 128;
char *packet = NULL;
char *topic = NULL;
do {
char pk[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char dn[IOTX_DEVICE_NAME_LEN + 1] = {0};
HAL_GetProductKey(pk);
HAL_GetDeviceName(dn);
topic = (char *)IMPL_NTP_MALLOC(topic_len + 1);
if (topic == NULL) {
goto NTP_REQ_ERR;
}
memset(topic, 0, topic_len + 1);
HAL_Snprintf(topic, topic_len, TOPIC_NTP_REPLY, pk, dn);
ret = IOT_MQTT_Subscribe_Sync(NULL, topic, IOTX_MQTT_QOS0,
(iotx_mqtt_event_handle_func_fpt)linkkit_ntp_time_reply, NULL, 1000);
if (ret < 0) {
goto NTP_REQ_ERR;
}
memset(topic, 0, topic_len + 1);
HAL_Snprintf(topic, topic_len, TOPIC_NTP, pk, dn);
} while (0);
packet = (char *)IMPL_NTP_MALLOC(packet_len + 1);
if (packet == NULL) {
ret = -1;
goto NTP_REQ_ERR;
}
memset(packet, 0, packet_len + 1);
g_ntp_reply_cb = ntp_reply;
final_len = HAL_Snprintf(packet, packet_len, "{\"deviceSendTime\":\"%u\"}", (unsigned int)(HAL_UptimeMs()));
log_debug("[ntp]", "report ntp:%s\r\n", packet);
ret = IOT_MQTT_Publish_Simple(NULL, topic, IOTX_MQTT_QOS0, packet, final_len);
NTP_REQ_ERR:
if (topic) {
IMPL_NTP_FREE(topic);
}
if (packet) {
IMPL_NTP_FREE(packet);
}
return ret;
}
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef NTP_H
#define NTP_H
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#define TOPIC_NTP "/ext/ntp/%s/%s/request"
#define TOPIC_NTP_REPLY "/ext/ntp/%s/%s/response"
#define NTP_TIME_STR_MAX_LEN (20)
int linkkit_ntp_time_request(void (*)(const char *ntp_offset_time_ms));
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _LINKKIT_SOLO_LEGACY_H_
#define _LINKKIT_SOLO_LEGACY_H_
#include "linkkit_export.h"
#define LINKKIT_SOLO_LEGACY_KEY_ID "id"
#define LINKKIT_SOLO_LEGACY_KEY_CODE "code"
#define LINKKIT_SOLO_LEGACY_KEY_DEVID "devid"
#define LINKKIT_SOLO_LEGACY_KEY_SERVICEID "serviceid"
#define LINKKIT_SOLO_LEGACY_KEY_PROPERTYID "propertyid"
#define LINKKIT_SOLO_LEGACY_KEY_EVENTID "eventid"
#define LINKKIT_SOLO_LEGACY_KEY_PAYLOAD "payload"
#define LINKKIT_SOLO_LEGACY_KEY_CONFIG_ID "configId"
#define LINKKIT_SOLO_LEGACY_KEY_CONFIG_SIZE "configSize"
#define LINKKIT_SOLO_LEGACY_KEY_GET_TYPE "getType"
#define LINKKIT_SOLO_LEGACY_KEY_SIGN "sign"
#define LINKKIT_SOLO_LEGACY_KEY_SIGN_METHOD "signMethod"
#define LINKKIT_SOLO_LEGACY_KEY_URL "url"
#define LINKKIT_SOLO_LEGACY_KEY_VERSION "version"
typedef struct {
int msgid;
handle_post_cb_fp_t callback;
struct list_head linked_list;
} linkkit_solo_upstream_callback_node_t;
typedef struct {
void *mutex;
void *upstream_mutex;
int is_started;
int is_leaved;
linkkit_ops_t *user_callback;
void *user_context;
handle_service_cota_callback_fp_t cota_callback;
handle_service_fota_callback_fp_t fota_callback;
struct list_head callback_list;
} linkkit_solo_legacy_ctx_t;
#endif

View File

@@ -0,0 +1,183 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOT_EXPORT_LINKKIT_H_
#define _IOT_EXPORT_LINKKIT_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "dm_wrapper.h"
typedef enum {
IOTX_LINKKIT_DEV_TYPE_MASTER,
IOTX_LINKKIT_DEV_TYPE_SLAVE,
IOTX_LINKKIT_DEV_TYPE_MAX
} iotx_linkkit_dev_type_t;
typedef struct {
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char product_secret[IOTX_PRODUCT_SECRET_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
char device_secret[IOTX_DEVICE_SECRET_LEN + 1];
} iotx_linkkit_dev_meta_info_t;
typedef enum {
/* post property value to cloud */
ITM_MSG_POST_PROPERTY,
/* post device info update message to cloud */
ITM_MSG_DEVICEINFO_UPDATE,
/* post device info delete message to cloud */
ITM_MSG_DEVICEINFO_DELETE,
/* post raw data to cloud */
ITM_MSG_POST_RAW_DATA,
/* only for slave device, send login request to cloud */
ITM_MSG_LOGIN,
/* only for slave device, send logout request to cloud */
ITM_MSG_LOGOUT,
/* only for slave device, send delete topo request to cloud */
ITM_MSG_DELETE_TOPO,
/* query ntp time from cloud */
ITM_MSG_QUERY_TIMESTAMP,
/* only for master device, query topo list */
ITM_MSG_QUERY_TOPOLIST,
/* only for master device, qurey firmware ota data */
ITM_MSG_QUERY_FOTA_DATA,
/* only for master device, qurey config ota data */
ITM_MSG_QUERY_COTA_DATA,
/* only for master device, request config ota data from cloud */
ITM_MSG_REQUEST_COTA,
/* only for master device, request fota image from cloud */
ITM_MSG_REQUEST_FOTA_IMAGE,
/* report subdev's firmware version */
ITM_MSG_REPORT_SUBDEV_FIRMWARE_VERSION,
/* get a device's desired property */
ITM_MSG_PROPERTY_DESIRED_GET,
/* delete a device's desired property */
ITM_MSG_PROPERTY_DESIRED_DELETE,
IOTX_LINKKIT_MSG_MAX
} iotx_linkkit_msg_type_t;
/**
* @brief create a new device
*
* @param dev_type. type of device which will be created. see iotx_linkkit_dev_type_t
* @param meta_info. The product key, product secret, device name and device secret of new device.
*
* @return success: device id (>=0), fail: -1.
*
*/
int IOT_Linkkit_Open(iotx_linkkit_dev_type_t dev_type, iotx_linkkit_dev_meta_info_t *meta_info);
/**
* @brief start device network connection.
* for master device, start to connect aliyun server.
* for slave device, send message to cloud for register new device and add topo with master device
*
* @param devid. device identifier.
*
* @return success: device id (>=0), fail: -1.
*
*/
int IOT_Linkkit_Connect(int devid);
/**
* @brief try to receive message from cloud and dispatch these message to user event callback
*
* @param timeout_ms. timeout for waiting new message arrived
*
* @return void.
*
*/
void IOT_Linkkit_Yield(int timeout_ms);
/**
* @brief close device network connection and release resources.
* for master device, disconnect with aliyun server and release all local resources.
* for slave device, send message to cloud for delete topo with master device and unregister itself, then release device's resources.
*
* @param devid. device identifier.
*
* @return success: 0, fail: -1.
*
*/
int IOT_Linkkit_Close(int devid);
/**
* @brief Report message to cloud
*
* @param devid. device identifier.
* @param msg_type. message type. see iotx_linkkit_msg_type_t, as follows:
* ITM_MSG_POST_PROPERTY
* ITM_MSG_DEVICEINFO_UPDATE
* ITM_MSG_DEVICEINFO_DELETE
* ITM_MSG_POST_RAW_DATA
* ITM_MSG_LOGIN
* ITM_MSG_LOGOUT
*
* @param payload. message payload.
* @param payload_len. message payload length.
*
* @return success: 0 or message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_Report(int devid, iotx_linkkit_msg_type_t msg_type, unsigned char *payload,
int payload_len);
/**
* @brief post message to cloud
*
* @param devid. device identifier.
* @param msg_type. message type. see iotx_linkkit_msg_type_t, as follows:
* ITM_MSG_QUERY_TIMESTAMP
* ITM_MSG_QUERY_TOPOLIST
* ITM_MSG_QUERY_FOTA_DATA
* ITM_MSG_QUERY_COTA_DATA
* ITM_MSG_REQUEST_COTA
* ITM_MSG_REQUEST_FOTA_IMAGE
*
* @param payload. message payload.
* @param payload_len. message payload length.
*
* @return success: 0 or message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_Query(int devid, iotx_linkkit_msg_type_t msg_type, unsigned char *payload,
int payload_len);
/**
* @brief post event to cloud
*
* @param devid. device identifier.
* @param eventid. tsl event id.
* @param eventid_len. length of tsl event id.
* @param payload. event payload.
* @param payload_len. event payload length.
*
* @return success: message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_TriggerEvent(int devid, char *eventid, int eventid_len, char *payload, int payload_len);
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,370 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef LINKKIT_EXPORT_H
#define LINKKIT_EXPORT_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdint.h>
typedef void (*handle_post_cb_fp_t)(const void *thing_id, int respons_id, int code, const char *response_message,
void *ctx);
typedef void (*handle_subdev_cb_fp_t)(const void *thing_id, int code, const char *response_message, int success,
void *ctx);
typedef struct _linkkit_ops {
#ifdef LOCAL_CONN_ENABLE
int (*on_connect)(void *ctx, int cloud); /* true: cloud connection; false: local connection */
int (*on_disconnect)(void *ctx, int cloud); /* true: cloud connection; false: local connection */
#else
int (*on_connect)(void *ctx); /* true: cloud connection; false: local connection */
int (*on_disconnect)(void *ctx); /* true: cloud connection; false: local connection */
#endif
int (*raw_data_arrived)(const void *thing_id, const void *data, int len, void *ctx);
int (*thing_create)(const void *thing_id, void *ctx);
int (*thing_enable)(const void *thing_id, void *ctx);
int (*thing_disable)(const void *thing_id, void *ctx);
int (*thing_call_service)(const void *thing_id, const char *service, int request_id, void *ctx);
int (*thing_prop_changed)(const void *thing_id, const char *property, void *ctx);
int (*linkit_data_arrived)(const void *thing_id, const void *data, int len, void *ctx);
} linkkit_ops_t;
typedef enum _linkkit_loglevel {
linkkit_loglevel_emerg = 0,
linkkit_loglevel_crit,
linkkit_loglevel_error,
linkkit_loglevel_warning,
linkkit_loglevel_info,
linkkit_loglevel_debug,
} linkkit_loglevel_t;
/* domain type */
/* please sync with dm_cloud_domain_type_t */
typedef enum {
/* shanghai */
linkkit_cloud_domain_shanghai,
/* singapore */
linkkit_cloud_domain_singapore,
/* japan */
linkkit_cloud_domain_japan,
/* america */
linkkit_cloud_domain_america,
/* germany */
linkkit_cloud_domain_germany,
linkkit_cloud_domain_max,
} linkkit_cloud_domain_type_t;
/* device info related operation */
typedef enum {
linkkit_extended_info_operate_update,
linkkit_extended_info_operate_delete,
linkkit_deviceinfo_operate_max,
} linkkit_extended_info_operate_t;
/**
* @brief dispatch message of queue for further process.
*
* @return void*
*/
void *linkkit_dispatch(void);
typedef enum {
linkkit_opt_property_post_reply, /* data type: int */
linkkit_opt_event_post_reply, /* data type: int */
linkkit_opt_property_set_reply /* data type: int */
} linkkit_opt_t;
/**
* @brief get leave signal.
*
*
* @return int,0 no leave signal, 1 get a leave signal
*/
int being_deprecated linkkit_is_try_leave();
/**
* @brief start linkkit routines, and install callback funstions(async type for cloud connecting).
*
* @param opt, specify the option need to be set.
* @param data, specify the option value.
*
* @return int, 0 when success, -1 when fail.
*/
int being_deprecated linkkit_set_opt(linkkit_opt_t opt, void *data);
/**
* @brief start linkkit routines, and install callback funstions(async type for cloud connecting).
*
* @param max_buffered_msg, specify max buffered message size.
* @param ops, callback function struct to be installed.
* @param get_tsl_from_cloud, config if device need to get tsl from cloud(!0) or local(0), if local selected, must invoke linkkit_set_tsl to tell tsl to dm after start complete.
* @param log_level, config log level.
* @param user_context, user context pointer.
* @param domain_type, specify the could server domain.
*
* @return int, 0 when success, -1 when fail.
*/
int being_deprecated linkkit_start(int max_buffered_msg, int get_tsl_from_cloud,
linkkit_loglevel_t log_level,
linkkit_ops_t *ops,
linkkit_cloud_domain_type_t domain_type, void *user_context);
/**
* @brief stop linkkit routines.
*
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_end(void);
/**
* @brief install user tsl.
*
* @param tsl, tsl string that contains json description for thing object.
* @param tsl_len, tsl string length.
*
* @return pointer to thing object, NULL when fails.
*/
void *linkkit_set_tsl(const char *tsl, int tsl_len);
/* patterns: */
/* method:
* set_property_/event_output_/service_output_value:
* method_set, thing_id, identifier, value */
typedef enum {
linkkit_method_set_property_value = 0,
linkkit_method_set_event_output_value,
linkkit_method_set_service_output_value,
linkkit_method_set_number,
} linkkit_method_set_t;
/**
* @brief set value to property, event output, service output items.
* if identifier is struct type or service output type or event output type, use '.' as delimeter like "identifier1.ientifier2"
* to point to specific item.
* value and value_str could not be NULL at the same time;
* if value and value_str both as not NULL, value shall be used and value_str will be ignored.
* if value is NULL, value_str not NULL, value_str will be used.
* in brief, value will be used if not NULL, value_str will be used only if value is NULL.
*
* @param method_set, specify set value type.
* @param thing_id, pointer to thing object, specify which thing to set.
* @param identifier, property, event output, service output identifier.
* @param value. The value to be set, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char*, enum: int*, date: char*, bool: int*
*
* @param value_str, value to set in string format if value is null.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_set_value(linkkit_method_set_t method_set, const void *thing_id,
const char *identifier,
const void *value, const char *value_str);
typedef enum {
linkkit_method_get_property_value = 0,
linkkit_method_get_event_output_value,
linkkit_method_get_service_input_value,
linkkit_method_get_service_output_value,
linkkit_method_get_number,
} linkkit_method_get_t;
/**
* @brief get value from property, event output, service input/output items.
* if identifier is struct type or service input/output type or event output type, use '.' as delimeter like "identifier1.ientifier2"
* to point to specific item.
* value and value_str could not be NULL at the same time;
* if value and value_str both as not NULL, value shall be used and value_str will be ignored.
* if value is NULL, value_str not NULL, value_str will be used.
* in brief, value will be used if not NULL, value_str will be used only if value is NULL.
* @param method_get, specify get value type.
* @param thing_id, pointer to thing object, specify which thing to get.
* @param identifier, property, event output, service input/output identifier.
* @param value. The variable to store value, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char**, enum: int*, date: char**, bool: int*
*
* @param value_str, value to get in string format. If success, memory of *value_str will be allocated,
* user should free the memory.
*
* @warning if data type is text or date, *value well be end with '\0'.
* the memory allocated to *value must be free by user.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_get_value(linkkit_method_get_t method_get, const void *thing_id,
const char *identifier,
void *value, char **value_str);
/**
* @brief answer to a service when a service requested by cloud.
*
* @param thing_id, pointer to thing object.
* @param service_identifier, service identifier to answer, user should get this identifier from handle_dm_callback_fp_t type callback
* report that "dm_callback_type_service_requested" happened, use this function to generate response to the service sender.
* @param response_id, id value in response payload. its value is from "dm_callback_type_service_requested" type callback function.
* use the same id as the request to send response as the same communication session.
* @param code, code value in response payload. for example, 200 when service successfully executed, 400 when not successfully executed.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_answer_service(const void *thing_id, const char *service_identifier,
int response_id, int code);
/**
* @brief answer a down raw service when a raw service requested by cloud, or invoke a up raw service to cloud.
*
* @param thing_id, pointer to thing object.
* @param is_up_raw, specify up raw(not 0) or down raw reply(0).
* @param raw_data, raw data that sent to cloud.
* @param raw_data_length, raw data length that sent to cloud.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_invoke_raw_service(const void *thing_id, int is_up_raw, void *raw_data,
int raw_data_length);
/**
* @brief trigger extended info update procedure.
*
* @param thing_id, pointer to thing object.
* @param params, json type string that user to send to cloud.
* @param linkkit_extended_info_operation, specify update type or delete type.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_trigger_extended_info_operate(const void *thing_id, const char *params,
linkkit_extended_info_operate_t linkkit_extended_info_operation);
/**
* @brief trigger a event to post to cloud.
*
* @param thing_id, pointer to thing object.
* @param event_identifier, event identifier to trigger.
* @param cb, callback function of event post.
*
* @return >=0 when success, -1 when fail.
*/
int being_deprecated linkkit_trigger_event(const void *thing_id, const char *event_identifier,
handle_post_cb_fp_t cb);
/**
* @brief post property to cloud.
*
* @param thing_id, pointer to thing object.
* @param property_identifier, used when trigger event with method "event.property.post", if set, post specified property, if NULL, post all.
* @param cb, callback function of property post.
*
* @return >=0 when success, -1 when fail.
*/
int being_deprecated linkkit_post_property(const void *thing_id, const char *property_identifier,
handle_post_cb_fp_t cb);
/**
* @brief this function used to yield when want to receive or send data.
* if multi-thread enabled, user should NOT call this function.
*
* @param timeout_ms, timeout value in ms.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_yield(int timeout_ms);
typedef enum {
service_cota_callback_type_new_version_detected = 10,
service_cota_callback_type_number,
} service_cota_callback_type_t;
typedef void (*handle_service_cota_callback_fp_t)(service_cota_callback_type_t callback_type, const char *configid,
uint32_t configsize,
const char *gettype,
const char *sign,
const char *signmethod,
const char *cota_url);
/**
* @brief this function used to register callback for config ota.
*
* @param callback_fp, user callback which register to cota.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_cota_init(handle_service_cota_callback_fp_t callback_fp);
/**
* @brief this function used to execute cota process.
*
* @param data_buf, data buf that used to do ota. ota service will use this buffer to download bin.
* @param data_buf_length, data buf length that used to do ota.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_invoke_cota_service(void *data_buf, int data_buf_length);
/**
* @brief this function used to trigger cota process.
*
* @param config_scope, remote config scope, should be "product".
* @param get_type, remote config file type, should be "file".
* @param attribute_Keys, reserved.
* @param option, reserved.
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_invoke_cota_get_config(const char *config_scope, const char *get_type,
const char *attribute_Keys, void *option);
typedef enum {
service_fota_callback_type_new_version_detected = 10,
service_fota_callback_type_number,
} service_fota_callback_type_t;
typedef void (*handle_service_fota_callback_fp_t)(service_fota_callback_type_t callback_type, const char *version);
/**
* @brief this function used to register callback for firmware ota.
*
* @param callback_fp, user callback which register to fota.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_fota_init(handle_service_fota_callback_fp_t callback_fp);
/**
* @brief this function used to execute fota process.
*
* @param data_buf, data buf that used to do ota. ota service will use this buffer to download bin.
* @param data_buf_length, data buf length that used to do ota.
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_invoke_fota_service(void *data_buf, int data_buf_length);
/**
* @brief this function used to get NTP time from cloud.
*
* @param ntp_reply_cb, user callback which register to ntp request.
* when cloud returns ntp reply, sdk would trigger the callback function
*
* @return 0 when success, -1 when fail.
*/
int being_deprecated linkkit_ntp_time_request(void (*ntp_reply_cb)(const char *ntp_offset_time_ms));
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LINKKIT_EXPORT_H */

View File

@@ -0,0 +1,434 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef LINKKIT_GATEWAY_EXPORT_H
#define LINKKIT_GATEWAY_EXPORT_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if defined (__CC_ARM)
#define ssize_t int
#elif defined (__ICCARM__)
#define ssize_t int
#endif
/***************************Gateway Interface***************************/
enum {
LINKKIT_EVENT_CLOUD_DISCONNECTED = 0, /* cloud disconnected */
LINKKIT_EVENT_CLOUD_CONNECTED = 1, /* cloud connected */
LINKKIT_EVENT_SUBDEV_DELETED = 2, /* subdev deleted */
LINKKIT_EVENT_SUBDEV_PERMITED = 3, /* subdev permit join */
LINKKIT_EVENT_SUBDEV_SETUP = 4, /* subdev install */
};
/*
* option | default | minimum | maximum
*--------------------------------|---------|---------|---------
* LINKKIT_OPT_MAX_MSG_SIZE | 20480 | 512 | 51200
* LINKKIT_OPT_MAX_MSG_QUEUE_SIZE | 16 | 2 | 32
* LINKKIT_OPT_THREAD_POOL_SIZE | 4 | 1 | 16
* LINKKIT_OPT_THREAD_STACK_SIZE | 8192 | 1024 | 8388608
* LINKKIT_OPT_LOG_LEVEL | 3 | 0 | 5
*/
enum {
LINKKIT_OPT_MAX_MSG_SIZE = 1,
LINKKIT_OPT_MAX_MSG_QUEUE_SIZE = 2,
LINKKIT_OPT_THREAD_POOL_SIZE = 3,
LINKKIT_OPT_THREAD_STACK_SIZE = 4,
LINKKIT_OPT_PROPERTY_POST_REPLY = 5, /* data type: int */
LINKKIT_OPT_EVENT_POST_REPLY = 6, /* data type: int */
LINKKIT_OPT_PROPERTY_SET_REPLY = 7 /* data type: int */
};
typedef struct {
int event_type; /* see LINKKIT_EVENT_XXX for more details */
union {
struct {
char *productKey;
char *deviceName;
} subdev_deleted;
struct {
char *productKey;
int timeoutSec;
} subdev_permited;
struct {
char *subdevList; /* json format:[{"productKey":"","deviceName":""},...] */
} subdev_install;
} event_data;
} linkkit_event_t;
typedef struct linkkit_params_s {
int maxMsgSize; /* max message size */
int maxMsgQueueSize; /* max message queue size */
int threadPoolSize; /* number threads in pool */
int threadStackSize; /* default thread stack size */
int (*event_cb)(linkkit_event_t *ev, void *ctx);
/* user private data */
void *ctx;
} linkkit_params_t;
/**
* @brief get default initialize parameters
*
* @return linkkit default parameters.
*/
linkkit_params_t *linkkit_gateway_get_default_params(void);
/**
* @brief set option in paremeters
*
* @param params, linkkit initialize parameters, return from linkkit_gateway_get_default_params().
* @param option, see LINKKIT_OPT_XXX for more detail.
* @param value, value of option.
* @param value_len, value length.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_setopt(linkkit_params_t *params, int option, void *value, int value_len);
/**
* @brief set event callback
*
* @param params, linkkit initialize parameters, return from linkkit_gateway_get_default_params().
* @param event_cb, event callback.
* @param ctx, user private data.
*
* @return 0 when success, < 0 when fail.
*/
int linkkit_gateway_set_event_callback(linkkit_params_t *params, int (*event_cb)(linkkit_event_t *ev,
void *ctx),
void *ctx);
/**
* @brief linkkit initialization.
*
* @param initParams, linkkit initialize parameters, see linkkit_params_t for more detail.
*
* @return 0 when success, < 0 when fail.
*/
int linkkit_gateway_init(linkkit_params_t *initParams);
/**
* @brief linkkit deinitialization.
*
* @return 0 when success, < 0 when fail.
*/
int linkkit_gateway_exit(void);
typedef struct {
int (*register_complete)(void *ctx);
/**
* @brief get property callback.
*
* @param in, properties to be get, in JSON array format, terminated by NULL.
* @param out, output buffer fill by user, in json format, terminated by NULL.
* @param out_len, out buffer length.
* @param ctx, user private data passed by linkkit_gateway_start() or linkkit_gateway_subdev_create()
*
* @return 0 when success, -1 when fail.
*/
int (*get_property)(char *in, char *out, int out_len, void *ctx);
/**
* @brief set property callback.
*
* @param in, properties to be set, in JSON object format, terminated by NULL.
* @param ctx, user private data passed by linkkit_gateway_start() or linkkit_gateway_subdev_create()
*
* @return 0 when success, -1 when fail.
*/
int (*set_property)(char *in, void *ctx);
/**
* @brief call service callback.
*
* @param identifier, service identifier, available services define in TSL file.
* @param in, service input data, in JSON object format, terminated by NULL.
* @param out, service output, this buffer will be filled by user, in json format, terminated by NULL.
* @param out_len, out buffer length.
* @param ctx, user private data passed by linkkit_gateway_start() or linkkit_gateway_subdev_create().
*
* @return 0 when success, -1 when fail.
*/
int (*call_service)(char *identifier, char *in, char *out, int out_len, void *ctx);
/**
* @brief raw data from cloud.
*
* @param in, input data from cloud.
* @param in_len, input data length.
* @param out, output data to cloud, allocated by linkkit fill by user, no need to be free.
* @param out_len, out buffer length.
* @param ctx, user private data passed by linkkit_gateway_start() or linkkit_gateway_subdev_create().
*
* @return output data size. < 0 when fail.
*/
int (*down_rawdata)(const void *in, int in_len, void *out, int out_len, void *ctx);
/**
* @brief return data from cloud when calling linkkit_gateway_post_rawdata().
*
* @param data, return raw data from cloud.
* @param len, data length.
* @param ctx, user private data passed by linkkit_gateway_start() or linkkit_gateway_subdev_create().
*
* @return 0 when success, -1 when fail.
*/
int (*post_rawdata_reply)(const void *data, int len, void *ctx);
} linkkit_cbs_t;
/**
* @brief start linkkit gateway routines and install callback funstions.
*
* @param cbs, callback function struct to be installed.
* @param ctx, user context pointer.
*
* @return device id, 0 > when success, < 0 when fail.
*/
int linkkit_gateway_start(linkkit_cbs_t *cbs, void *ctx);
/**
* @brief stop linkkit gateway.
* @param devid, device id return from linkkit_gateway_start().
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_stop(int devid);
/**
* @brief register subdev to gateway.
* @param productKey, subdev's product key.
* @param deviceName, subdev's device name.
* @param deviceSecret, subdev's device secret.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_subdev_register(char *productKey, char *deviceName, char *deviceSecret);
/**
* @brief deregister subdev from gateway.
* @param productKey, subdev's product key.
* @param deviceName, subdev's device name.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_subdev_unregister(char *productKey, char *deviceName);
/**
* @brief create subdev and install callback funstions.
*
* @param productKey, subdev's product key.
* @param deviceName, subdev's device name.
* @param cbs, callback function struct to be installed.
* @param ctx, user context pointer.
*
* @return device id, 0 > when success, < 0 when fail.
*/
int linkkit_gateway_subdev_create(char *productKey, char *deviceName, linkkit_cbs_t *cbs, void *ctx);
/**
* @brief destroy subdev by device id.
* @param devid, device id return from linkkit_gateway_subdev_create().
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_subdev_destroy(int devid);
/**
* @brief make subdev accessible from cloud.
* @param devid, device id return from linkkit_gateway_subdev_create().
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_subdev_login(int devid);
/**
* @brief make subdev inaccessible on cloud.
* @param devid, device id return from linkkit_gateway_subdev_create().
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_subdev_logout(int devid);
enum {
LINKKIT_STATE_ENABLED = 0, /* device is enabled by cloud */
LINKKIT_STATE_DISABLED, /* device is disabled by cloud */
LINKKIT_STATE_REMOVED, /* device is deleted by cloud */
};
typedef struct {
char *productKey; /* device's product key */
char *deviceName; /* device's device name */
int devtype; /* Device Type: 0 - gateway, 1 - subdev */
int login; /* Login State: 0 - logout, 1 - login */
int state; /* Device State: see LINKKIT_STATE_xxx */
int online; /* 0 - offline, 1 - online */
} linkkit_devinfo_t;
/**
* @brief get device infomation specific by devid.
*
* @param devinfo, device information, see linkkit_devinfo_t for more detail.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_get_devinfo(int devid, linkkit_devinfo_t *devinfo);
/**
* @brief post event to cloud.
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param identifier, event identifier, see tsl file for more detail.
* @param event, event data, in JSON format.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_trigger_event_json_sync(int devid, char *identifier, char *event, int timeout_ms);
/**
* @brief post event to cloud asynchronously.
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param identifier, event identifier, see tsl file for more detail.
* @param event, event data, in JSON format.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
* @param func, callback function when success(retval > 0), timeout(retval = 0) or failed(retval < 0).
* @param ctx, user data passed to 'func'.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_trigger_event_json(int devid, char *identifier, char *event, int timeout_ms,
void (*func)(int retval, void *ctx), void *ctx);
/**
* @brief post property to cloud.
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param property, property data, in JSON format.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_post_property_json_sync(int devid, char *property, int timeout_ms);
/**
* @brief post property to cloud asynchronously.
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param property, property data, in JSON format.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
* @param func, callback function when success(retval > 0), timeout(retval = 0) or failed(retval < 0).
* @param ctx, user data passed to 'func'.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_post_property_json(int devid, char *property, int timeout_ms,
void (*func)(int retval, void *ctx),
void *ctx);
/**
* @brief post raw data to cloud.
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param data, raw data buffer pointer.
* @param len, raw data length.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_post_rawdata(int devid, void *data, int len);
typedef enum {
LINKKIT_OTA_EVENT_NEW_VERSION_DETECTED = 1,
} linkkit_ota_event_t;
typedef enum {
service_fota_callback_type_new_version_detected = 10,
service_fota_callback_type_number,
} service_fota_callback_type_t;
typedef void (*handle_service_fota_callback_fp_t)(service_fota_callback_type_t callback_type, const char *version);
/**
* @brief this function used to register callback for firmware ota.
*
* @param callback_fp, user callback which register to fota. (NULL for unregister)
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_fota_init(handle_service_fota_callback_fp_t callback_fp);
/**
* @brief this function used to execute fota process.
*
* @param data_buf, data buf that used to do ota. ota service will use this buffer to download bin.
* @param data_buf_length, data buf length that used to do ota.
*
* @return 0 when success, -1 when fail.
*/
int linkkit_gateway_invoke_fota_service(void *data_buf, int data_buf_length);
typedef struct {
char *attrKey; /* the key of extend info. */
char *attrValue; /* the value of extend info. */
} linkkit_extinfo_t;
/**
* @brief post group of extend info to cloud
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param extinfos, group of extend info to be post.
* @param nb_extinfos, number of extend infos in extinfos.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
*
* @return 0 when success, < 0 when fail.
*/
int linkkit_gateway_post_extinfos(int devid, linkkit_extinfo_t *extinfos, int nb_extinfos,
int timeout_ms);
/**
* @brief delete extend info specific by key
*
* @param devid, device id return from linkkit_gateway_start() or linkkit_gateway_subdev_create().
* @param extinfos, group of extend info to be deleted, attrValue in linkkit_extinfo_t will be ignore.
* @param nb_extinfos, number of extend infos in extinfos.
* @param timeout_ms, transmission timeout, in milliseconds. when timeout_ms is 0, wait no response.
*
* @return 0 when success, < 0 when fail.
*/
int linkkit_gateway_delete_extinfos(int devid, linkkit_extinfo_t *extinfos, int nb_extinfos,
int timeout_ms);
/**
* @brief get number devices currently in gateway
*
* @return number devinfos.
*/
int linkkit_gateway_get_num_devices(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LINKKIT_GATEWAY_EXPORT_H */

View File

@@ -0,0 +1,184 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOT_EXPORT_LINKKIT_H_
#define _IOT_EXPORT_LINKKIT_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "infra_types.h"
#include "infra_defs.h"
typedef enum {
IOTX_LINKKIT_DEV_TYPE_MASTER,
IOTX_LINKKIT_DEV_TYPE_SLAVE,
IOTX_LINKKIT_DEV_TYPE_MAX
} iotx_linkkit_dev_type_t;
typedef struct {
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char product_secret[IOTX_PRODUCT_SECRET_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
char device_secret[IOTX_DEVICE_SECRET_LEN + 1];
} iotx_linkkit_dev_meta_info_t;
typedef enum {
/* post property value to cloud */
ITM_MSG_POST_PROPERTY,
/* post device info update message to cloud */
ITM_MSG_DEVICEINFO_UPDATE,
/* post device info delete message to cloud */
ITM_MSG_DEVICEINFO_DELETE,
/* post raw data to cloud */
ITM_MSG_POST_RAW_DATA,
/* only for slave device, send login request to cloud */
ITM_MSG_LOGIN,
/* only for slave device, send logout request to cloud */
ITM_MSG_LOGOUT,
/* only for slave device, send delete topo request to cloud */
ITM_MSG_DELETE_TOPO,
/* query ntp time from cloud */
ITM_MSG_QUERY_TIMESTAMP,
/* only for master device, query topo list */
ITM_MSG_QUERY_TOPOLIST,
/* only for master device, qurey firmware ota data */
ITM_MSG_QUERY_FOTA_DATA,
/* only for master device, qurey config ota data */
ITM_MSG_QUERY_COTA_DATA,
/* only for master device, request config ota data from cloud */
ITM_MSG_REQUEST_COTA,
/* only for master device, request fota image from cloud */
ITM_MSG_REQUEST_FOTA_IMAGE,
/* report subdev's firmware version */
ITM_MSG_REPORT_SUBDEV_FIRMWARE_VERSION,
/* get a device's desired property */
ITM_MSG_PROPERTY_DESIRED_GET,
/* delete a device's desired property */
ITM_MSG_PROPERTY_DESIRED_DELETE,
IOTX_LINKKIT_MSG_MAX
} iotx_linkkit_msg_type_t;
/**
* @brief create a new device
*
* @param dev_type. type of device which will be created. see iotx_linkkit_dev_type_t
* @param meta_info. The product key, product secret, device name and device secret of new device.
*
* @return success: device id (>=0), fail: -1.
*
*/
int IOT_Linkkit_Open(iotx_linkkit_dev_type_t dev_type, iotx_linkkit_dev_meta_info_t *meta_info);
/**
* @brief start device network connection.
* for master device, start to connect aliyun server.
* for slave device, send message to cloud for register new device and add topo with master device
*
* @param devid. device identifier.
*
* @return success: device id (>=0), fail: -1.
*
*/
int IOT_Linkkit_Connect(int devid);
/**
* @brief try to receive message from cloud and dispatch these message to user event callback
*
* @param timeout_ms. timeout for waiting new message arrived
*
* @return void.
*
*/
void IOT_Linkkit_Yield(int timeout_ms);
/**
* @brief close device network connection and release resources.
* for master device, disconnect with aliyun server and release all local resources.
* for slave device, send message to cloud for delete topo with master device and unregister itself, then release device's resources.
*
* @param devid. device identifier.
*
* @return success: 0, fail: -1.
*
*/
int IOT_Linkkit_Close(int devid);
/**
* @brief Report message to cloud
*
* @param devid. device identifier.
* @param msg_type. message type. see iotx_linkkit_msg_type_t, as follows:
* ITM_MSG_POST_PROPERTY
* ITM_MSG_DEVICEINFO_UPDATE
* ITM_MSG_DEVICEINFO_DELETE
* ITM_MSG_POST_RAW_DATA
* ITM_MSG_LOGIN
* ITM_MSG_LOGOUT
*
* @param payload. message payload.
* @param payload_len. message payload length.
*
* @return success: 0 or message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_Report(int devid, iotx_linkkit_msg_type_t msg_type, unsigned char *payload,
int payload_len);
/**
* @brief post message to cloud
*
* @param devid. device identifier.
* @param msg_type. message type. see iotx_linkkit_msg_type_t, as follows:
* ITM_MSG_QUERY_TIMESTAMP
* ITM_MSG_QUERY_TOPOLIST
* ITM_MSG_QUERY_FOTA_DATA
* ITM_MSG_QUERY_COTA_DATA
* ITM_MSG_REQUEST_COTA
* ITM_MSG_REQUEST_FOTA_IMAGE
*
* @param payload. message payload.
* @param payload_len. message payload length.
*
* @return success: 0 or message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_Query(int devid, iotx_linkkit_msg_type_t msg_type, unsigned char *payload,
int payload_len);
/**
* @brief post event to cloud
*
* @param devid. device identifier.
* @param eventid. tsl event id.
* @param eventid_len. length of tsl event id.
* @param payload. event payload.
* @param payload_len. event payload length.
*
* @return success: message id (>=1), fail: -1.
*
*/
int IOT_Linkkit_TriggerEvent(int devid, char *eventid, int eventid_len, char *payload, int payload_len);
#if defined(__cplusplus)
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,236 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#define DM_COTA_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "dm.cota")
#define DM_COTA_FREE(ptr) LITE_free(ptr)
#else
#define DM_COTA_MALLOC(size) HAL_Malloc(size)
#define DM_COTA_FREE(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
#endif
static dm_cota_ctx_t g_dm_cota_ctx;
static dm_cota_ctx_t *_dm_cota_get_ctx(void)
{
return &g_dm_cota_ctx;
}
int dm_cota_init(void)
{
dm_cota_ctx_t *ctx = _dm_cota_get_ctx();
memset(ctx, 0, sizeof(dm_cota_ctx_t));
return SUCCESS_RETURN;
}
int dm_cota_deinit(void)
{
dm_cota_ctx_t *ctx = _dm_cota_get_ctx();
memset(ctx, 0, sizeof(dm_cota_ctx_t));
return SUCCESS_RETURN;
}
static int _dm_cota_send_new_config_to_user(void *ota_handle)
{
int res = 0, message_len = 0;
char *message = NULL;
uint32_t config_size = 0;
char *config_id = NULL, *sign = NULL, *sign_method = NULL, *url = NULL, *get_type = NULL;
const char *cota_new_config_fmt =
"{\"configId\":\"%s\",\"configSize\":%d,\"getType\":\"%s\",\"sign\":\"%s\",\"signMethod\":\"%s\",\"url\":\"%s\"}";
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_CONFIG_ID, (void *)&config_id, 1);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_CONFIG_SIZE, &config_size, 4);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_SIGN, (void *)&sign, 1);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_SIGN_METHOD, (void *)&sign_method, 1);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_URL, (void *)&url, 1);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_COTA_GETTYPE, (void *)&get_type, 1);
if (config_id == NULL || sign == NULL || sign_method == NULL || url == NULL || get_type == NULL) {
res = FAIL_RETURN;
goto ERROR;
}
message_len = strlen(cota_new_config_fmt) + strlen(config_id) + DM_UTILS_UINT32_STRLEN + strlen(get_type) +
strlen(sign) + strlen(sign_method) + strlen(url) + 1;
message = DM_malloc(message_len);
if (message == NULL) {
res = DM_MEMORY_NOT_ENOUGH;
goto ERROR;
}
memset(message, 0, message_len);
HAL_Snprintf(message, message_len, cota_new_config_fmt, config_id, config_size, get_type, sign, sign_method, url);
dm_log_info("Send To User: %s", message);
res = _dm_msg_send_to_user(IOTX_DM_EVENT_COTA_NEW_CONFIG, message);
if (res != SUCCESS_RETURN) {
if (message) {
DM_free(message);
}
res = FAIL_RETURN;
goto ERROR;
}
res = SUCCESS_RETURN;
ERROR:
if (config_id) {
DM_COTA_FREE(config_id);
}
if (sign) {
DM_COTA_FREE(sign);
}
if (sign_method) {
DM_COTA_FREE(sign_method);
}
if (url) {
DM_COTA_FREE(url);
}
if (get_type) {
DM_COTA_FREE(get_type);
}
return res;
}
int dm_cota_perform_sync(_OU_ char *output, _IN_ int output_len)
{
int res = 0, file_download = 0;
uint32_t file_size = 0, file_downloaded = 0;
uint64_t percent_pre = 0, percent_now = 0;
unsigned long long report_pre = 0, report_now = 0;
dm_cota_ctx_t *ctx = _dm_cota_get_ctx();
void *ota_handle = NULL;
uint32_t ota_type = IOT_OTAT_NONE;
if (output == NULL || output_len <= 0) {
return DM_INVALID_PARAMETER;
}
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (ota_handle == NULL) {
return FAIL_RETURN;
}
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_OTA_TYPE, &ota_type, 4);
if (ota_type != IOT_OTAT_COTA) {
return FAIL_RETURN;
}
/* reset the size_fetched in ota_handle to be 0 */
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_RESET_FETCHED_SIZE, ota_handle, 4);
/* Prepare Write Data To Storage */
HAL_Firmware_Persistence_Start();
while (1) {
file_download = IOT_OTA_FetchYield(ota_handle, output, output_len, 1);
if (file_download < 0) {
IOT_OTA_ReportProgress(ota_handle, IOT_OTAP_FETCH_FAILED, NULL);
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return FAIL_RETURN;
}
/* Write Config File Into Stroage */
HAL_Firmware_Persistence_Write(output, file_download);
/* Get OTA information */
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_FETCHED_SIZE, &file_downloaded, 4);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_FILE_SIZE, &file_size, 4);
/* Calculate Download Percent And Update Report Timestamp*/
percent_now = (file_downloaded * 100) / file_size;
report_now = HAL_UptimeMs();
/* Report Download Process To Cloud */
if (report_now < report_pre) {
report_pre = report_now;
}
if ((((percent_now - percent_pre) > 5) &&
((report_now - report_pre) > 50)) || (percent_now >= IOT_OTAP_FETCH_PERCENTAGE_MAX)) {
IOT_OTA_ReportProgress(ota_handle, percent_now, NULL);
percent_pre = percent_now;
report_pre = report_now;
}
/* Check If OTA Finished */
if (IOT_OTA_IsFetchFinish(ota_handle)) {
uint32_t file_isvalid = 0;
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_CHECK_CONFIG, &file_isvalid, 4);
if (file_isvalid == 0) {
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return FAIL_RETURN;
} else {
break;
}
}
}
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return SUCCESS_RETURN;
}
int dm_cota_get_config(const char *config_scope, const char *get_type, const char *attribute_keys)
{
int res = 0;
void *ota_handle = NULL;
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return iotx_ota_get_config(ota_handle, config_scope, get_type, attribute_keys);
}
int dm_cota_status_check(void)
{
int res = 0;
dm_cota_ctx_t *ctx = _dm_cota_get_ctx();
void *ota_handle = NULL;
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (IOT_OTA_IsFetching(ota_handle)) {
uint32_t ota_type = IOT_OTAT_NONE;
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_OTA_TYPE, &ota_type, 4);
if (ota_type == IOT_OTAT_COTA) {
/* Send New Config Information To User */
if (ctx->is_report_new_config == 0) {
dm_log_debug("Cota Status Check");
res = _dm_cota_send_new_config_to_user(ota_handle);
if (res == SUCCESS_RETURN) {
ctx->is_report_new_config = 1;
}
}
}
}
return SUCCESS_RETURN;
}
#endif

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_COTA_H_
#define _DM_COTA_H_
typedef struct {
int is_report_new_config;
} dm_cota_ctx_t;
int dm_cota_init(void);
int dm_cota_deinit(void);
int dm_cota_perform_sync(_OU_ char *output, _IN_ int output_len);
int dm_cota_get_config(const char *config_scope, const char *get_type, const char *attribute_keys);
int dm_cota_status_check(void);
#endif

View File

@@ -0,0 +1,218 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
static dm_fota_ctx_t g_dm_fota_ctx;
static dm_fota_ctx_t *_dm_fota_get_ctx(void)
{
return &g_dm_fota_ctx;
}
int dm_fota_init(void)
{
dm_fota_ctx_t *ctx = _dm_fota_get_ctx();
memset(ctx, 0, sizeof(dm_fota_ctx_t));
return SUCCESS_RETURN;
}
int dm_fota_deinit(void)
{
dm_fota_ctx_t *ctx = _dm_fota_get_ctx();
memset(ctx, 0, sizeof(dm_fota_ctx_t));
return SUCCESS_RETURN;
}
static int _dm_fota_send_new_config_to_user(void *ota_handle)
{
int res = 0, message_len = 0;
char *message = NULL;
char version[128] = {0};
const char *fota_new_config_fmt = "{\"version\":\"%s\"}";
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_VERSION, version, 128);
message_len = strlen(fota_new_config_fmt) + strlen(version) + 1;
message = DM_malloc(message_len);
if (message == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(message, 0, message_len);
HAL_Snprintf(message, message_len, fota_new_config_fmt, version);
dm_log_info("Send To User: %s", message);
res = _dm_msg_send_to_user(IOTX_DM_EVENT_FOTA_NEW_FIRMWARE, message);
if (res != SUCCESS_RETURN) {
if (message) {
DM_free(message);
}
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int dm_fota_perform_sync(_OU_ char *output, _IN_ int output_len)
{
int res = 0, file_download = 0;
uint32_t file_size = 0, file_downloaded = 0;
uint64_t percent_pre = 0, percent_now = 0;
unsigned long long report_pre = 0, report_now = 0;
dm_fota_ctx_t *ctx = _dm_fota_get_ctx();
void *ota_handle = NULL;
uint32_t ota_type = IOT_OTAT_NONE;
int ret = 0;
if (output == NULL || output_len <= 0) {
return DM_INVALID_PARAMETER;
}
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (ota_handle == NULL) {
return FAIL_RETURN;
}
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_OTA_TYPE, &ota_type, 4);
if (ota_type != IOT_OTAT_FOTA) {
return FAIL_RETURN;
}
/* reset the size_fetched in ota_handle to be 0 */
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_RESET_FETCHED_SIZE, ota_handle, 4);
/* Prepare Write Data To Storage */
HAL_Firmware_Persistence_Start();
while (1) {
file_download = IOT_OTA_FetchYield(ota_handle, output, output_len, 1);
if (file_download < 0) {
IOT_OTA_ReportProgress(ota_handle, IOT_OTAP_FETCH_FAILED, NULL);
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return FAIL_RETURN;
}
/* Write Config File Into Stroage */
ret = HAL_Firmware_Persistence_Write(output, file_download);
if (-1 == ret) {
IOT_OTA_ReportProgress(ota_handle, IOT_OTAP_BURN_FAILED, NULL);
dm_log_err("Fota write firmware failed");
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return FAIL_RETURN;
}
/* Get OTA information */
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_FETCHED_SIZE, &file_downloaded, 4);
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_FILE_SIZE, &file_size, 4);
/* Calculate Download Percent And Update Report Timestamp*/
percent_now = (file_downloaded * 100) / file_size;
report_now = HAL_UptimeMs();
/* Report Download Process To Cloud */
if (report_now < report_pre) {
report_pre = report_now;
}
if ((((percent_now - percent_pre) > 5) &&
((report_now - report_pre) > 50)) || (percent_now >= IOT_OTAP_FETCH_PERCENTAGE_MAX)) {
IOT_OTA_ReportProgress(ota_handle, percent_now, NULL);
percent_pre = percent_now;
report_pre = report_now;
}
/* Check If OTA Finished */
if (IOT_OTA_IsFetchFinish(ota_handle)) {
uint32_t file_isvalid = 0;
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_CHECK_FIRMWARE, &file_isvalid, 4);
if (file_isvalid == 0) {
HAL_Firmware_Persistence_Stop();
IOT_OTA_ReportProgress(ota_handle, IOT_OTAP_CHECK_FALIED, NULL);
ctx->is_report_new_config = 0;
return FAIL_RETURN;
} else {
break;
}
}
}
HAL_Firmware_Persistence_Stop();
ctx->is_report_new_config = 0;
return SUCCESS_RETURN;
}
int dm_fota_status_check(void)
{
int res = 0;
dm_fota_ctx_t *ctx = _dm_fota_get_ctx();
void *ota_handle = NULL;
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (IOT_OTA_IsFetching(ota_handle)) {
uint32_t ota_type = IOT_OTAT_NONE;
IOT_OTA_Ioctl(ota_handle, IOT_OTAG_OTA_TYPE, &ota_type, 4);
if (ota_type == IOT_OTAT_FOTA) {
/* Send New Config Information To User */
if (ctx->is_report_new_config == 0) {
dm_log_debug("Fota Status Check");
res = _dm_fota_send_new_config_to_user(ota_handle);
if (res == SUCCESS_RETURN) {
ctx->is_report_new_config = 1;
}
}
}
}
return SUCCESS_RETURN;
}
int dm_fota_request_image(const char *version, int buffer_len)
{
int res = 0;
void *ota_handle = NULL;
char *version_str = NULL;
if (NULL == version || buffer_len <= 0) {
dm_log_info("invalid input");
return FAIL_RETURN;
}
/* Get Ota Handle */
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
version_str = DM_malloc(buffer_len + 1);
if (NULL == version_str) {
dm_log_info("failed to malloc");
return FAIL_RETURN;
}
memset(version_str, 0, buffer_len + 1);
memcpy(version_str, version, buffer_len);
res = iotx_req_image(ota_handle, version_str);
DM_free(version_str);
return res;
}
#endif

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_FOTA_H_
#define _DM_FOTA_H_
typedef struct {
int is_report_new_config;
} dm_fota_ctx_t;
int dm_fota_init(void);
int dm_fota_deinit(void);
int dm_fota_perform_sync(_OU_ char *output, _IN_ int output_len);
int dm_fota_status_check(void);
int dm_fota_request_image(_IN_ const char *version, _IN_ int buffer_len);
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOT_DM_API_H_
#define _IOT_DM_API_H_
typedef struct {
void *mutex;
void *cloud_connectivity;
void *local_connectivity;
iotx_dm_event_callback event_callback;
} dm_api_ctx_t;
#if defined(DEPRECATED_LINKKIT)
typedef struct {
void *mutex;
int devid;
lite_cjson_item_t *lite;
} dm_api_property_t;
#endif
#endif

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
dm_ipc_t g_dm_ipc;
static dm_ipc_t *_dm_ipc_get_ctx(void)
{
return &g_dm_ipc;
}
static void _dm_ipc_lock(void)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
if (ctx->mutex) {
HAL_MutexLock(ctx->mutex);
}
}
static void _dm_ipc_unlock(void)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
if (ctx->mutex) {
HAL_MutexUnlock(ctx->mutex);
}
}
int dm_ipc_init(int max_size)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
memset(ctx, 0, sizeof(dm_ipc_t));
/* Create Mutex */
ctx->mutex = HAL_MutexCreate();
if (ctx->mutex == NULL) {
return DM_INVALID_PARAMETER;
}
/* Init List */
ctx->msg_list.max_size = max_size;
INIT_LIST_HEAD(&ctx->msg_list.message_list);
return SUCCESS_RETURN;
}
void dm_ipc_deinit(void)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
dm_ipc_msg_node_t *del_node = NULL;
dm_ipc_msg_node_t *next_node = NULL;
dm_ipc_msg_t *del_msg = NULL;
if (ctx->mutex) {
HAL_MutexDestroy(ctx->mutex);
}
list_for_each_entry_safe(del_node, next_node, &ctx->msg_list.message_list, linked_list, dm_ipc_msg_node_t) {
/* Free Message */
del_msg = (dm_ipc_msg_t *)del_node->data;
if (del_msg->data) {
DM_free(del_msg->data);
}
DM_free(del_msg);
del_msg = NULL;
/* Free Node */
list_del(&del_node->linked_list);
DM_free(del_node);
}
}
int dm_ipc_msg_insert(void *data)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
dm_ipc_msg_node_t *node = NULL;
if (data == NULL) {
return DM_INVALID_PARAMETER;
}
_dm_ipc_lock();
dm_log_debug("dm msg list size: %d, max size: %d", ctx->msg_list.size, ctx->msg_list.max_size);
if (ctx->msg_list.size >= ctx->msg_list.max_size) {
dm_log_warning("dm ipc list full");
_dm_ipc_unlock();
return FAIL_RETURN;
}
node = DM_malloc(sizeof(dm_ipc_msg_node_t));
if (node == NULL) {
_dm_ipc_unlock();
return DM_MEMORY_NOT_ENOUGH;
}
memset(node, 0, sizeof(dm_ipc_msg_node_t));
node->data = data;
INIT_LIST_HEAD(&node->linked_list);
ctx->msg_list.size++;
list_add_tail(&node->linked_list, &ctx->msg_list.message_list);
_dm_ipc_unlock();
return SUCCESS_RETURN;
}
int dm_ipc_msg_next(void **data)
{
dm_ipc_t *ctx = _dm_ipc_get_ctx();
dm_ipc_msg_node_t *node = NULL;
if (data == NULL || *data != NULL) {
return DM_INVALID_PARAMETER;
}
_dm_ipc_lock();
if (list_empty(&ctx->msg_list.message_list)) {
_dm_ipc_unlock();
return FAIL_RETURN;
}
node = list_first_entry(&ctx->msg_list.message_list, dm_ipc_msg_node_t, linked_list);
list_del(&node->linked_list);
ctx->msg_list.size--;
*data = node->data;
DM_free(node);
_dm_ipc_unlock();
return SUCCESS_RETURN;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_IPC_H_
#define _DM_IPC_H_
#include "iotx_dm_internal.h"
typedef struct {
iotx_dm_event_types_t type;
char *data;
} dm_ipc_msg_t;
typedef struct {
void *data;
struct list_head linked_list;
} dm_ipc_msg_node_t;
typedef struct {
int max_size;
int size;
struct list_head message_list;
} dm_ipc_msg_list_t;
typedef struct {
void *mutex;
dm_ipc_msg_list_t msg_list;
} dm_ipc_t;
int dm_ipc_init(int max_size);
void dm_ipc_deinit(void);
int dm_ipc_msg_insert(void *data);
int dm_ipc_msg_next(void **data);
#endif

View File

@@ -0,0 +1,277 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#ifdef LOG_REPORT_TO_CLOUD
#include "dev_model_api.h"
const char THING_LOG_POST_PARAMS_HEAD[] =
"\"%.*s %s %ld ";
const char THING_LOG_POST_PARAMS_BODY[] =
"%s %ld ";
const char THING_LOG_POST_PARAMS_END[] =
"%s %ld\",";
char *g_log_poll = NULL;
static char *current_log_pos = NULL;
int remove_log_poll()
{
if (NULL != g_log_poll) {
HAL_Free(g_log_poll);
g_log_poll = NULL;
current_log_pos = NULL;
}
return 0;
}
unsigned int push_log(const char *input_log, int input_log_size)
{
if (NULL == current_log_pos || NULL == input_log || input_log_size <= 0) {
dm_log_debug("invalid params");
return (unsigned int)-1;
}
memcpy(current_log_pos, input_log, input_log_size);
current_log_pos += input_log_size;
return (current_log_pos - g_log_poll);
}
unsigned int add_tail()
{
const char *tail = "]}";
current_log_pos -= 1;
return push_log(tail, strlen(tail));
}
void add_log_header()
{
const char *subprefix = "{\"template\": \"traceContext logContent\",\"contents\":[";
int sublen = strlen(subprefix);
push_log(subprefix, sublen);
}
int reset_log_poll()
{
if (NULL == g_log_poll) {
dm_log_err("log buffer is NULL");
return -1;
}
memset(g_log_poll, 0, LOG_POLL_SIZE);
current_log_pos = g_log_poll;
add_log_header();
return 0;
}
int create_log_poll()
{
int ret;
remove_log_poll();
g_log_poll = HAL_Malloc(LOG_POLL_SIZE);
ret = reset_log_poll();
return ret;
}
static int switch_status = 0; /* 0 for switch off; 1 for switch on */
static unsigned int sample_interval = 5;
static unsigned int sample_count = 1000;
#define MSG_ID_LEN (64)
char msg_array[MSG_ID_LEN] = {0};
int check_target_msg(const char *input, int len)
{
/* do not upload log when swith is off */
if (0 == switch_status) {
return -1;
}
if (NULL == input || len <= 0) {
dm_log_err("invalid params");
return -1;
}
return strncmp(input, msg_array, len);
}
static unsigned int msg_num = 0;
/* return 0 for success; -1 for failure */
int set_target_msg(const char *input, int len)
{
if (0 == switch_status) {
return -1;
}
if ((msg_num % sample_interval == 0) && (msg_num < sample_count)) {
if (NULL == input || len <= 0) {
dm_log_err("invalid params");
return -1;
}
strncpy(msg_array, input, len);
return 0;
}
return -1;
}
void parse_msg_id(_IN_ char *payload, _IN_ int payload_len, _OU_ dm_msg_request_payload_t *request)
{
lite_cjson_t lite;
if (payload == NULL || payload_len <= 0 || request == NULL) {
return;
}
dm_utils_json_parse(payload, payload_len, cJSON_Object, &lite);
dm_utils_json_object_item(&lite, DM_MSG_KEY_ID, strlen(DM_MSG_KEY_ID), cJSON_String, &request->id);
}
int stop_sample()
{
if (current_log_pos > g_log_poll) {
dm_mgr_upstream_thing_log_post(0, NULL, 0, 1);
}
switch_status = 0;
dm_log_info("stop sample");
return remove_log_poll();
}
void parse_switch_info(_IN_ char *payload, _IN_ int payload_len)
{
lite_cjson_t lite, lite_sample_count, lite_sample_interval, lite_sample_target;
const char *c1 = "Count";
const char *c2 = "Interval";
const char *c3 = "ProfileTarget";
char *sample_target;
int sample_target_len;
const char *target = "propSet";
int ret = -1;
if (payload == NULL || payload_len <= 0) {
return;
}
dm_utils_json_parse(payload, payload_len, cJSON_Object, &lite);
ret = lite_cjson_object_item(&lite, c1, strlen(c1), &lite_sample_count);
if (ret < SUCCESS_RETURN) {
return;
}
ret = lite_cjson_object_item(&lite, c2, strlen(c2), &lite_sample_interval);
if (ret < SUCCESS_RETURN) {
return;
}
ret = lite_cjson_object_item(&lite, c3, strlen(c3), &lite_sample_target);
if (ret < SUCCESS_RETURN) {
return;
}
sample_count = lite_sample_count.value_int;
sample_interval = lite_sample_interval.value_int;
sample_target = lite_sample_target.value;
sample_target_len = lite_sample_target.value_length;
dm_log_info("switch count is %d, interval is %d, target is %.*s\n", sample_count, sample_interval,
sample_target_len, sample_target);
/* if the target is not property set, return */
if (0 != strncmp(sample_target, target, sample_target_len)) {
dm_log_info("target is not propSet, return\n");
return;
}
if (sample_interval <= 0) {
dm_log_err("invalid sample interval\n");
return;
}
msg_num = 0;
/* when it switch off, force upload the remaining log */
if (0 == sample_count) {
ret = stop_sample();
} else {
switch_status = 1;
ret = create_log_poll();
}
dm_log_info("log switch run status is %d\n", ret);
}
REPORT_STATE g_report_status = READY;
void send_permance_info(char *input, int input_len, char *comments, int report_format)
{
#define LOCAL_POST_LEN (150)
char data[LOCAL_POST_LEN] = {0};
const char *format = NULL;
if (0 == switch_status) {
return;
}
switch (report_format) {
case 0:
if (NULL == input || input_len <= 0) {
dm_log_err("invalid params");
return;
}
format = THING_LOG_POST_PARAMS_HEAD;
HAL_Snprintf(data, sizeof(data), format, input_len, input,
comments, (long)HAL_UptimeMs());
break;
case 1:
format = THING_LOG_POST_PARAMS_BODY;
HAL_Snprintf(data, sizeof(data), format,
comments, (long)HAL_UptimeMs());
break;
case 2:
format = THING_LOG_POST_PARAMS_END;
HAL_Snprintf(data, sizeof(data), format,
comments, (long)HAL_UptimeMs());
g_report_status = DONE;
break;
default:
return;
}
iotx_dm_log_post(0, data, strlen((const char *)data));
if (2 == report_format) {
g_report_status = READY;
}
}
void get_msgid(char *payload, int is_cloud)
{
const char *interest = "\"method\":\"thing.service.property.set";
char *found;
dm_msg_request_payload_t request;
if (0 == switch_status || NULL == payload) {
return;
}
found = strstr(payload, interest);
if (NULL == found) {
return;
}
found = strstr(payload, "{");
if (NULL == found) {
return;
}
msg_num++;
parse_msg_id(found, strlen(found), &request);
if (RUNNING == g_report_status) {
dm_log_info("current working on a sample, return");
return;
}
if (sample_count <= msg_num) {
stop_sample();
return;
}
/* if it does not meet the sample conditions, do NOT take sample */
if (SUCCESS_RETURN != set_target_msg(request.id.value, request.id.value_length)) {
return;
}
g_report_status = RUNNING;
if (1 == is_cloud) {
send_permance_info(request.id.value, request.id.value_length, "1_cloud", 0);
} else if (0 == is_cloud) {
send_permance_info(request.id.value, request.id.value_length, "1_alcs", 0);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_MANAGER_H_
#define _DM_MANAGER_H_
#include "iotx_dm_internal.h"
typedef struct {
int devid;
int dev_type;
#if defined(DEPRECATED_LINKKIT)
dm_shw_t *dev_shadow;
iotx_dm_tsl_source_t tsl_source;
#endif
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
char device_secret[IOTX_DEVICE_SECRET_LEN + 1];
iotx_dm_dev_avail_t status;
iotx_dm_dev_status_t dev_status;
struct list_head linked_list;
} dm_mgr_dev_node_t;
typedef struct {
void *mutex;
int global_devid;
struct list_head dev_list;
} dm_mgr_ctx;
int dm_mgr_init(void);
int dm_mgr_deinit(void);
int dm_mgr_device_query(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1], _OU_ int *devid);
int dm_mgr_device_create(_IN_ int dev_type, _IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1], _IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1], _OU_ int *devid);
int dm_mgr_device_destroy(_IN_ int devid);
int dm_mgr_device_number(void);
int dm_mgr_get_devid_by_index(_IN_ int index, _OU_ int *devid);
int dm_mgr_get_next_devid(_IN_ int devid, _OU_ int *devid_next);
int dm_mgr_search_device_by_devid(_IN_ int devid, _OU_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_OU_ char device_name[IOTX_DEVICE_NAME_LEN + 1], _OU_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1]);
int dm_mgr_search_device_by_pkdn(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ int *devid);
int dm_mgr_search_device_node_by_devid(_IN_ int devid, _OU_ void **node);
int dm_mgr_get_dev_type(_IN_ int devid, _OU_ int *dev_type);
int dm_mgr_set_dev_enable(_IN_ int devid);
int dm_mgr_set_dev_disable(_IN_ int devid);
int dm_mgr_get_dev_avail(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ iotx_dm_dev_avail_t *status);
int dm_mgr_set_dev_status(_IN_ int devid, _IN_ iotx_dm_dev_status_t status);
int dm_mgr_get_dev_status(_IN_ int devid, _OU_ iotx_dm_dev_status_t *status);
int dm_mgr_set_device_secret(_IN_ int devid, _IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1]);
int dm_mgr_dev_initialized(int devid);
int dm_mgr_upstream_thing_property_desired_get(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_property_desired_delete(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#ifdef DEVICE_MODEL_GATEWAY
int dm_mgr_upstream_thing_sub_register(_IN_ int devid);
int dm_mgr_upstream_thing_sub_unregister(_IN_ int devid);
int dm_mgr_upstream_thing_topo_add(_IN_ int devid);
int dm_mgr_upstream_thing_topo_delete(_IN_ int devid);
int dm_mgr_upstream_thing_topo_get(void);
int dm_mgr_upstream_thing_list_found(_IN_ int devid);
int dm_mgr_upstream_combine_login(_IN_ int devid);
int dm_mgr_upstream_combine_logout(_IN_ int devid);
#endif
int dm_mgr_upstream_thing_model_up_raw(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int dm_mgr_upstream_thing_property_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#ifdef LOG_REPORT_TO_CLOUD
int dm_mgr_upstream_thing_log_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len, int force_update);
#endif
int dm_mgr_upstream_thing_event_post(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
_IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_deviceinfo_update(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_deviceinfo_delete(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_dsltemplate_get(_IN_ int devid);
int dm_mgr_upstream_thing_dynamictsl_get(_IN_ int devid);
int dm_mgr_upstream_ntp_request(void);
int dm_mgr_upstream_thing_service_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len,
_IN_ iotx_dm_error_code_t code,
_IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len, void *ctx);
int dm_mgr_upstream_thing_property_get_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len,
_IN_ iotx_dm_error_code_t code,
_IN_ char *payload, _IN_ int payload_len, _IN_ void *ctx);
int dm_mgr_upstream_rrpc_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len, _IN_ iotx_dm_error_code_t code,
_IN_ char *rrpcid, _IN_ int rrpcid_len, _IN_ char *payload, _IN_ int payload_len);
#ifdef DEVICE_MODEL_SUBDEV_OTA
int dm_mgr_upstream_thing_firmware_version_update(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#endif
#endif
#ifdef DEPRECATED_LINKKIT
int dm_mgr_deprecated_set_tsl_source(_IN_ int devid, _IN_ iotx_dm_tsl_source_t tsl_source);
int dm_mgr_deprecated_get_tsl_source(_IN_ int devid, _IN_ iotx_dm_tsl_source_t *tsl_source);
int dm_mgr_deprecated_search_devid_by_device_node(_IN_ void *node, _OU_ int *devid);
int dm_mgr_deprecated_set_tsl(int devid, iotx_dm_tsl_type_t tsl_type, const char *tsl, int tsl_len);
int dm_mgr_deprecated_get_property_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
int dm_mgr_deprecated_get_service_input_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
int dm_mgr_deprecated_get_service_output_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
int dm_mgr_deprecated_get_event_output_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
int dm_mgr_deprecated_get_data_type(_IN_ void *property, _OU_ dm_shw_data_type_e *type);
int dm_mgr_deprecated_get_property_number(_IN_ int devid, _OU_ int *number);
int dm_mgr_deprecated_get_service_number(_IN_ int devid, _OU_ int *number);
int dm_mgr_deprecated_get_event_number(_IN_ int devid, _OU_ int *number);
int dm_mgr_deprecated_get_property_by_index(_IN_ int devid, _IN_ int index, _OU_ void **property);
int dm_mgr_deprecated_get_service_by_index(_IN_ int devid, _IN_ int index, _OU_ void **service);
int dm_mgr_deprecated_get_event_by_index(_IN_ int devid, _IN_ int index, _OU_ void **event);
int dm_mgr_deprecated_get_service_by_identifier(_IN_ int devid, _IN_ char *identifier, _OU_ void **service);
int dm_mgr_deprecated_get_event_by_identifier(_IN_ int devid, _IN_ char *identifier, _OU_ void **event);
int dm_mgr_deprecated_get_property_identifier(_IN_ void *property, _OU_ char **identifier);
int dm_mgr_deprecated_get_service_method(_IN_ void *service, _OU_ char **method);
int dm_mgr_deprecated_get_event_method(_IN_ void *event, _OU_ char **method);
int dm_mgr_deprecated_set_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int dm_mgr_deprecated_get_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int dm_mgr_deprecated_set_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int dm_mgr_deprecated_get_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int dm_mgr_deprecated_set_service_input_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int dm_mgr_deprecated_get_service_input_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int dm_mgr_deprecated_set_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int dm_mgr_deprecated_get_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int dm_mgr_deprecated_assemble_property(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
int dm_mgr_deprecated_assemble_event_output(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
int dm_mgr_deprecated_assemble_service_output(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
int dm_mgr_deprecated_upstream_thing_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
_IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_MESSAGE_H_
#define _DM_MESSAGE_H_
#include "iotx_dm_internal.h"
#define DM_MSG_KEY_ID "id"
#define DM_MSG_KEY_VERSION "version"
#define DM_MSG_KEY_METHOD "method"
#define DM_MSG_KEY_PARAMS "params"
#define DM_MSG_KEY_CODE "code"
#define DM_MSG_KEY_DATA "data"
#define DM_MSG_KEY_MESSAGE "message"
#define DM_MSG_VERSION "1.0"
#define DM_MSG_KEY_PRODUCT_KEY "productKey"
#define DM_MSG_KEY_DEVICE_NAME "deviceName"
#define DM_MSG_KEY_DEVICE_SECRET "deviceSecret"
#define DM_MSG_KEY_TIME "time"
#define DM_MSG_SIGN_METHOD_SHA256 "Sha256"
#define DM_MSG_SIGN_METHOD_HMACMD5 "hmacMd5"
#define DM_MSG_SIGN_METHOD_HMACSHA1 "hmacSha1"
#define DM_MSG_SIGN_METHOD_HMACSHA256 "hmacSha256"
typedef enum {
DM_MSG_DEST_CLOUD = 0x01,
DM_MSG_DEST_LOCAL = 0x02,
DM_MSG_DEST_ALL = 0x03
} dm_msg_dest_type_t;
typedef struct {
const char *uri;
unsigned char *payload;
unsigned int payload_len;
void *context;
} dm_msg_source_t;
typedef struct {
const char *uri_name;
} dm_msg_dest_t;
typedef struct {
lite_cjson_t id;
lite_cjson_t version;
lite_cjson_t method;
lite_cjson_t params;
} dm_msg_request_payload_t;
typedef struct {
lite_cjson_t id;
lite_cjson_t code;
lite_cjson_t data;
lite_cjson_t message;
} dm_msg_response_payload_t;
typedef struct {
int msgid;
int devid;
const char *service_prefix;
const char *service_name;
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
char *params;
int params_len;
char *method;
iotx_cm_data_handle_cb callback;
} dm_msg_request_t;
typedef struct {
const char *service_prefix;
const char *service_name;
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
iotx_dm_error_code_t code;
} dm_msg_response_t;
typedef struct {
int id;
} dm_msg_ctx_t;
int dm_msg_init(void);
int dm_msg_deinit(void);
int _dm_msg_send_to_user(iotx_dm_event_types_t type, char *message);
int dm_msg_send_msg_timeout_to_user(int msg_id, int devid, iotx_dm_event_types_t type);
int dm_msg_uri_parse_pkdn(_IN_ char *uri, _IN_ int uri_len, _IN_ int start_deli, _IN_ int end_deli,
_OU_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _OU_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_request_parse(_IN_ char *payload, _IN_ int payload_len, _OU_ dm_msg_request_payload_t *request);
int dm_msg_response_parse(_IN_ char *payload, _IN_ int payload_len, _OU_ dm_msg_response_payload_t *response);
int dm_msg_request(dm_msg_dest_type_t type, _IN_ dm_msg_request_t *request);
int dm_msg_response(dm_msg_dest_type_t type, _IN_ dm_msg_request_payload_t *request, _IN_ dm_msg_response_t *response,
_IN_ char *data, _IN_ int data_len, _IN_ void *user_data);
int dm_msg_thing_model_down_raw(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_IN_ char *payload, _IN_ int payload_len);
int dm_msg_thing_model_up_raw_reply(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1], char *payload, int payload_len);
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int dm_msg_property_set(int devid, dm_msg_request_payload_t *request);
#ifndef DEPRECATED_LINKKIT
int dm_msg_property_get(_IN_ int devid, _IN_ dm_msg_request_payload_t *request, _IN_ void *ctx);
#else
int dm_msg_property_get(_IN_ int devid, _IN_ dm_msg_request_payload_t *request, _IN_ char **payload,
_IN_ int *payload_len);
#endif
int dm_msg_thing_service_request(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
char *identifier, int identifier_len, dm_msg_request_payload_t *request, _IN_ void *ctx);
int dm_msg_rrpc_request(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
char *messageid, int messageid_len, dm_msg_request_payload_t *request);
int dm_msg_thing_event_property_post_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_event_post_reply(_IN_ char *identifier, _IN_ int identifier_len,
_IN_ dm_msg_response_payload_t *response);
int dm_msg_thing_deviceinfo_update_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_property_desired_get_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_property_desired_delete_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_deviceinfo_delete_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_dsltemplate_get_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_dynamictsl_get_reply(dm_msg_response_payload_t *response);
int dm_msg_ntp_response(char *payload, int payload_len);
int dm_msg_ext_error_reply(dm_msg_response_payload_t *response);
#endif
#ifdef DEVICE_MODEL_GATEWAY
int dm_msg_topo_add_notify(_IN_ char *payload, _IN_ int payload_len);
int dm_msg_thing_disable(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_thing_enable(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_thing_delete(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_thing_gateway_permit(_IN_ char *payload, _IN_ int payload_len);
int dm_msg_thing_sub_register_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_sub_unregister_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_topo_add_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_topo_delete_reply(dm_msg_response_payload_t *response);
int dm_msg_topo_get_reply(dm_msg_response_payload_t *response);
int dm_msg_thing_list_found_reply(dm_msg_response_payload_t *response);
int dm_msg_combine_login_reply(dm_msg_response_payload_t *response);
int dm_msg_combine_logout_reply(dm_msg_response_payload_t *response);
#endif
#ifdef ALCS_ENABLED
int dm_msg_dev_core_service_dev(char **payload, int *payload_len);
#endif
int dm_msg_cloud_connected(void);
int dm_msg_cloud_disconnect(void);
int dm_msg_cloud_reconnect(void);
#if 0
int dm_msg_found_device(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_remove_device(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_msg_unregister_result(_IN_ char *uri, _IN_ int result);
int dm_msg_send_result(_IN_ char *uri, _IN_ int result);
int dm_msg_add_service_result(_IN_ char *uri, _IN_ int result);
int dm_msg_remove_service_result(_IN_ char *uri, _IN_ int result);
#endif
int dm_msg_register_result(_IN_ char *uri, _IN_ int result);
#ifdef DEVICE_MODEL_GATEWAY
int dm_msg_thing_sub_register(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ dm_msg_request_t *request);
int dm_msg_thing_sub_unregister(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ dm_msg_request_t *request);
int dm_msg_thing_topo_add(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1], _OU_ dm_msg_request_t *request);
int dm_msg_thing_topo_delete(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ dm_msg_request_t *request);
int dm_msg_thing_topo_get(_OU_ dm_msg_request_t *request);
int dm_msg_thing_list_found(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ dm_msg_request_t *request);
int dm_msg_combine_login(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1], _OU_ dm_msg_request_t *request);
int dm_msg_combine_logout(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ dm_msg_request_t *request);
#endif
#endif

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#if !defined(DM_MESSAGE_CACHE_DISABLED)
dm_msg_cache_ctx_t g_dm_msg_cache_ctx;
dm_msg_cache_ctx_t *_dm_msg_cache_get_ctx(void)
{
return &g_dm_msg_cache_ctx;
}
static void _dm_msg_cache_mutex_lock(void)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
if (ctx->mutex) {
HAL_MutexLock(ctx->mutex);
}
}
static void _dm_msg_cache_mutex_unlock(void)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
if (ctx->mutex) {
HAL_MutexUnlock(ctx->mutex);
}
}
int dm_msg_cache_init(void)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
memset(ctx, 0, sizeof(dm_msg_cache_ctx_t));
/* Create Mutex */
ctx->mutex = HAL_MutexCreate();
if (ctx->mutex == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
/* Init Message Cache List */
INIT_LIST_HEAD(&ctx->dmc_list);
return SUCCESS_RETURN;
}
int dm_msg_cache_deinit(void)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
dm_msg_cache_node_t *node = NULL;
dm_msg_cache_node_t *next = NULL;
_dm_msg_cache_mutex_lock();
list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list, dm_msg_cache_node_t) {
list_del(&node->linked_list);
if (node->data) {
DM_free(node->data);
}
DM_free(node);
_dm_msg_cache_mutex_unlock();
}
_dm_msg_cache_mutex_unlock();
if (ctx->mutex) {
HAL_MutexDestroy(ctx->mutex);
}
return SUCCESS_RETURN;
}
int dm_msg_cache_insert(int msgid, int devid, iotx_dm_event_types_t type, char *data)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
dm_msg_cache_node_t *node = NULL;
dm_log_debug("dmc list size: %d", ctx->dmc_list_size);
if (ctx->dmc_list_size >= CONFIG_MSGCACHE_QUEUE_MAXLEN) {
return FAIL_RETURN;
}
node = DM_malloc(sizeof(dm_msg_cache_node_t));
if (node == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(node, 0, sizeof(dm_msg_cache_node_t));
node->msgid = msgid;
node->devid = devid;
node->response_type = type;
node->data = data;
node->ctime = HAL_UptimeMs();
INIT_LIST_HEAD(&node->linked_list);
_dm_msg_cache_mutex_lock();
list_add_tail(&node->linked_list, &ctx->dmc_list);
ctx->dmc_list_size++;
_dm_msg_cache_mutex_unlock();
return SUCCESS_RETURN;
}
int dm_msg_cache_search(_IN_ int msgid, _OU_ dm_msg_cache_node_t **node)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
dm_msg_cache_node_t *search_node = NULL;
if (msgid <= 0 || node == NULL || *node != NULL) {
return DM_INVALID_PARAMETER;
}
_dm_msg_cache_mutex_lock();
list_for_each_entry(search_node, &ctx->dmc_list, linked_list, dm_msg_cache_node_t) {
if (search_node->msgid == msgid) {
*node = search_node;
_dm_msg_cache_mutex_unlock();
return SUCCESS_RETURN;
}
}
_dm_msg_cache_mutex_unlock();
return FAIL_RETURN;
}
int dm_msg_cache_remove(int msgid)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
dm_msg_cache_node_t *node = NULL;
dm_msg_cache_node_t *next = NULL;
_dm_msg_cache_mutex_lock();
list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list, dm_msg_cache_node_t) {
if (node->msgid == msgid) {
list_del(&node->linked_list);
if (node->data) {
DM_free(node->data);
}
ctx->dmc_list_size--;
DM_free(node);
dm_log_debug("Remove Message ID: %d", msgid);
_dm_msg_cache_mutex_unlock();
return SUCCESS_RETURN;
}
}
_dm_msg_cache_mutex_unlock();
return FAIL_RETURN;
}
void dm_msg_cache_tick(void)
{
dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
dm_msg_cache_node_t *node = NULL;
dm_msg_cache_node_t *next = NULL;
uint64_t current_time = HAL_UptimeMs();
_dm_msg_cache_mutex_lock();
list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list, dm_msg_cache_node_t) {
if (current_time < node->ctime) {
node->ctime = current_time;
}
if (current_time - node->ctime >= DM_MSG_CACHE_TIMEOUT_MS_DEFAULT) {
dm_log_debug("Message ID Timeout: %d", node->msgid);
/* Send Timeout Message To User */
dm_msg_send_msg_timeout_to_user(node->msgid, node->devid, node->response_type);
list_del(&node->linked_list);
if (node->data) {
DM_free(node->data);
}
DM_free(node);
ctx->dmc_list_size--;
}
}
_dm_msg_cache_mutex_unlock();
}
#endif

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#if !defined(DM_MESSAGE_CACHE_DISABLED)
#ifndef _DM_MESSAGE_CACHE_H_
#define _DM_MESSAGE_CACHE_H_
#include "iotx_dm_internal.h"
#define DM_MSG_CACHE_TIMEOUT_MS_DEFAULT (10000)
typedef struct {
int msgid;
int devid;
iotx_dm_event_types_t response_type;
char *data;
uint64_t ctime;
struct list_head linked_list;
} dm_msg_cache_node_t;
typedef struct {
void *mutex;
int dmc_list_size;
struct list_head dmc_list;
} dm_msg_cache_ctx_t;
int dm_msg_cache_init(void);
int dm_msg_cache_deinit(void);
int dm_msg_cache_insert(int msg_id, int devid, iotx_dm_event_types_t type, char *data);
int dm_msg_cache_search(_IN_ int msg_id, _OU_ dm_msg_cache_node_t **node);
int dm_msg_cache_remove(int msg_id);
void dm_msg_cache_tick(void);
#endif
#endif

View File

@@ -0,0 +1,974 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/";
const char DM_URI_EXT_SESSION_PREFIX[] DM_READ_ONLY = "/ext/session/%s/%s/";
const char DM_URI_EXT_NTP_PREFIX[] DM_READ_ONLY = "/ext/ntp/%s/%s/";
const char DM_URI_EXT_ERROR_PREFIX[] DM_READ_ONLY = "/ext/error/%s/%s";
const char DM_URI_REPLY_SUFFIX[] DM_READ_ONLY = "_reply";
const char DM_URI_OTA_DEVICE_INFORM[] DM_READ_ONLY = "/ota/device/inform/%s/%s";
/* From Cloud To Local Request And Response*/
const char DM_URI_THING_MODEL_DOWN_RAW[] DM_READ_ONLY = "thing/model/down_raw";
const char DM_URI_THING_MODEL_DOWN_RAW_REPLY[] DM_READ_ONLY = "thing/model/down_raw_reply";
/* From Local To Cloud Request And Response*/
const char DM_URI_THING_MODEL_UP_RAW[] DM_READ_ONLY = "thing/model/up_raw";
const char DM_URI_THING_MODEL_UP_RAW_REPLY[] DM_READ_ONLY = "thing/model/up_raw_reply";
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
const char DM_URI_RRPC_REQUEST_WILDCARD[] DM_READ_ONLY = "rrpc/request/+";
/* From Cloud To Local Request And Response*/
const char DM_URI_THING_SERVICE_PROPERTY_SET[] DM_READ_ONLY = "thing/service/property/set";
const char DM_URI_THING_SERVICE_PROPERTY_SET_REPLY[] DM_READ_ONLY = "thing/service/property/set_reply";
const char DM_URI_THING_SERVICE_PROPERTY_GET[] DM_READ_ONLY = "thing/service/property/get";
const char DM_URI_THING_SERVICE_PROPERTY_GET_REPLY[] DM_READ_ONLY = "thing/service/property/get_reply";
const char DM_URI_THING_SERVICE_REQUEST_WILDCARD[] DM_READ_ONLY = "thing/service/+";
const char DM_URI_THING_SERVICE_REQUEST_WILDCARD2[] DM_READ_ONLY = "thing/service/#";
const char DM_URI_THING_SERVICE_REQUEST[] DM_READ_ONLY = "thing/service/%s";
const char DM_URI_THING_SERVICE_RESPONSE[] DM_READ_ONLY = "thing/service/%.*s_reply";
#ifdef DEVICE_MODEL_SHADOW
const char DM_URI_THING_PROPERTY_DESIRED_GET[] DM_READ_ONLY = "thing/property/desired/get";
const char DM_URI_THING_PROPERTY_DESIRED_DELETE[] DM_READ_ONLY = "thing/property/desired/delete";
const char DM_URI_THING_PROPERTY_DESIRED_GET_REPLY[] DM_READ_ONLY = "thing/property/desired/get_reply";
const char DM_URI_THING_PROPERTY_DESIRED_DELETE_REPLY[] DM_READ_ONLY = "thing/property/desired/delete_reply";
#endif
/* From Local To Cloud Request And Response*/
#ifdef LOG_REPORT_TO_CLOUD
const char DM_URI_THING_LOG_POST[] DM_READ_ONLY = "thing/log/post";
#endif
const char DM_URI_THING_EVENT_PROPERTY_POST[] DM_READ_ONLY = "thing/event/property/post";
const char DM_URI_THING_EVENT_PROPERTY_POST_REPLY[] DM_READ_ONLY = "thing/event/property/post_reply";
const char DM_URI_THING_EVENT_POST[] DM_READ_ONLY = "thing/event/%.*s/post";
const char DM_URI_THING_EVENT_POST_REPLY[] DM_READ_ONLY = "thing/event/%s/post_reply";
const char DM_URI_THING_EVENT_POST_REPLY_WILDCARD[] DM_READ_ONLY = "thing/event/+/post_reply";
const char DM_URI_THING_DEVICEINFO_UPDATE[] DM_READ_ONLY = "thing/deviceinfo/update";
const char DM_URI_THING_DEVICEINFO_UPDATE_REPLY[] DM_READ_ONLY = "thing/deviceinfo/update_reply";
const char DM_URI_THING_DEVICEINFO_DELETE[] DM_READ_ONLY = "thing/deviceinfo/delete";
const char DM_URI_THING_DEVICEINFO_DELETE_REPLY[] DM_READ_ONLY = "thing/deviceinfo/delete_reply";
const char DM_URI_THING_DSLTEMPLATE_GET[] DM_READ_ONLY = "thing/dsltemplate/get";
const char DM_URI_THING_DSLTEMPLATE_GET_REPLY[] DM_READ_ONLY = "thing/dsltemplate/get_reply";
const char DM_URI_THING_DYNAMICTSL_GET[] DM_READ_ONLY = "thing/dynamicTsl/get";
const char DM_URI_THING_DYNAMICTSL_GET_REPLY[] DM_READ_ONLY = "thing/dynamicTsl/get_reply";
const char DM_URI_NTP_REQUEST[] DM_READ_ONLY = "request";
const char DM_URI_NTP_RESPONSE[] DM_READ_ONLY = "response";
#endif
const char DM_URI_DEV_CORE_SERVICE_DEV[] DM_READ_ONLY = "/dev/core/service/dev";
#ifdef DEVICE_MODEL_GATEWAY
/* From Cloud To Local Request And Response*/
const char DM_URI_THING_TOPO_ADD_NOTIFY[] DM_READ_ONLY = "thing/topo/add/notify";
const char DM_URI_THING_TOPO_ADD_NOTIFY_REPLY[] DM_READ_ONLY = "thing/topo/add/notify_reply";
const char DM_URI_THING_DELETE[] DM_READ_ONLY = "thing/delete";
const char DM_URI_THING_DELETE_REPLY[] DM_READ_ONLY = "thing/delete_reply";
const char DM_URI_THING_DISABLE[] DM_READ_ONLY = "thing/disable";
const char DM_URI_THING_DISABLE_REPLY[] DM_READ_ONLY = "thing/disable_reply";
const char DM_URI_THING_ENABLE[] DM_READ_ONLY = "thing/enable";
const char DM_URI_THING_ENABLE_REPLY[] DM_READ_ONLY = "thing/enable_reply";
const char DM_URI_THING_GATEWAY_PERMIT[] DM_READ_ONLY = "thing/gateway/permit";
const char DM_URI_THING_GATEWAY_PERMIT_REPLY[] DM_READ_ONLY = "thing/gateway/permit_reply";
/* From Local To Cloud Request And Response*/
const char DM_URI_THING_SUB_REGISTER[] DM_READ_ONLY = "thing/sub/register";
const char DM_URI_THING_SUB_REGISTER_REPLY[] DM_READ_ONLY = "thing/sub/register_reply";
const char DM_URI_THING_SUB_UNREGISTER[] DM_READ_ONLY = "thing/sub/unregister";
const char DM_URI_THING_SUB_UNREGISTER_REPLY[] DM_READ_ONLY = "thing/sub/unregister_reply";
const char DM_URI_THING_TOPO_ADD[] DM_READ_ONLY = "thing/topo/add";
const char DM_URI_THING_TOPO_ADD_REPLY[] DM_READ_ONLY = "thing/topo/add_reply";
const char DM_URI_THING_TOPO_DELETE[] DM_READ_ONLY = "thing/topo/delete";
const char DM_URI_THING_TOPO_DELETE_REPLY[] DM_READ_ONLY = "thing/topo/delete_reply";
const char DM_URI_THING_TOPO_GET[] DM_READ_ONLY = "thing/topo/get";
const char DM_URI_THING_TOPO_GET_REPLY[] DM_READ_ONLY = "thing/topo/get_reply";
const char DM_URI_THING_LIST_FOUND[] DM_READ_ONLY = "thing/list/found";
const char DM_URI_THING_LIST_FOUND_REPLY[] DM_READ_ONLY = "thing/list/found_reply";
const char DM_URI_COMBINE_LOGIN[] DM_READ_ONLY = "combine/login";
const char DM_URI_COMBINE_LOGIN_REPLY[] DM_READ_ONLY = "combine/login_reply";
const char DM_URI_COMBINE_LOGOUT[] DM_READ_ONLY = "combine/logout";
const char DM_URI_COMBINE_LOGOUT_REPLY[] DM_READ_ONLY = "combine/logout_reply";
#endif
int dm_msg_proc_thing_model_down_raw(_IN_ dm_msg_source_t *source)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
/* Parse Product Key And Device Name */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return dm_msg_thing_model_down_raw(product_key, device_name, (char *)source->payload, source->payload_len);
}
int dm_msg_proc_thing_model_up_raw_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_MODEL_UP_RAW_REPLY);
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
res = dm_msg_thing_model_up_raw_reply(product_key, device_name, (char *)source->payload, source->payload_len);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int dm_msg_proc_thing_service_property_set(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0, devid = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_SERVICE_PROPERTY_SET);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_mgr_search_device_by_pkdn(product_key, device_name, &devid);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Operation */
res = dm_msg_property_set(devid, request);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_service_property_get(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response,
_OU_ unsigned char **data, int *data_len)
{
int res = 0, devid = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_SERVICE_PROPERTY_GET);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_mgr_search_device_by_pkdn(product_key, device_name, &devid);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Operation */
#ifndef DEPRECATED_LINKKIT
res = dm_msg_property_get(devid, request, source->context);
#else
res = dm_msg_property_get(devid, request, (char **)data, data_len);
#endif
#ifdef DEPRECATED_LINKKIT
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
if (res != SUCCESS_RETURN) {
*data = DM_malloc(strlen("{}") + 1);
if (*data == NULL) {
return FAIL_RETURN;
}
memset(*data, 0, strlen("{}") + 1);
memcpy(*data, "{}", strlen("{}"));
*data_len = strlen((char *)*data);
}
#endif
if (res != SUCCESS_RETURN) {
dm_log_err("DM Property Get Failed");
}
return res;
}
int dm_msg_proc_thing_service_property_post(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_EVENT_PROPERTY_POST);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_service_request(_IN_ dm_msg_source_t *source)
{
int res = 0, serviceid_pos = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_msg_request_payload_t request;
memset(&request, 0, sizeof(dm_msg_request_payload_t));
res = dm_utils_memtok((char *)source->uri, strlen(source->uri), DM_URI_SERVICE_DELIMITER, 6, &serviceid_pos);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
dm_log_info("Service Identifier: %.*s", (int)(strlen(source->uri) - serviceid_pos - 1),
source->uri + serviceid_pos + 1);
/* Parse Product Key And Device Name */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Request */
res = dm_msg_request_parse((char *)source->payload, source->payload_len, &request);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
return dm_msg_thing_service_request(product_key, device_name, (char *)source->uri + serviceid_pos + 1,
strlen(source->uri) - serviceid_pos - 1, &request, source->context);
}
int dm_msg_proc_thing_event_post_reply(_IN_ dm_msg_source_t *source)
{
int res = 0, eventid_start_pos = 0, eventid_end_pos = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
res = dm_utils_memtok((char *)source->uri, strlen(source->uri), DM_URI_SERVICE_DELIMITER, 6 + DM_URI_OFFSET,
&eventid_start_pos);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_utils_memtok((char *)source->uri, strlen(source->uri), DM_URI_SERVICE_DELIMITER, 7 + DM_URI_OFFSET,
&eventid_end_pos);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
dm_log_info("Event Id: %.*s", eventid_end_pos - eventid_start_pos - 1, source->uri + eventid_start_pos + 1);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
if ((strlen("property") == eventid_end_pos - eventid_start_pos - 1) &&
(memcmp("property", source->uri + eventid_start_pos + 1, eventid_end_pos - eventid_start_pos - 1) == 0)) {
dm_msg_thing_event_property_post_reply(&response);
} else {
dm_msg_thing_event_post_reply((char *)source->uri + eventid_start_pos + 1, eventid_end_pos - eventid_start_pos - 1,
&response);
}
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
#ifdef DEVICE_MODEL_SHADOW
int dm_msg_proc_thing_property_desired_get_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_PROPERTY_DESIRED_GET_REPLY);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
res = dm_msg_thing_property_desired_get_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_property_desired_delete_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_PROPERTY_DESIRED_DELETE_REPLY);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
res = dm_msg_thing_property_desired_delete_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
#endif
int dm_msg_proc_thing_deviceinfo_update_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_DEVICEINFO_UPDATE_REPLY);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_deviceinfo_update_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_deviceinfo_delete_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_DEVICEINFO_DELETE_REPLY);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_deviceinfo_delete_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_dynamictsl_get_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_DYNAMICTSL_GET_REPLY);
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_dynamictsl_get_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_rrpc_request(_IN_ dm_msg_source_t *source)
{
int res = 0, rrpcid_pos = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_msg_request_payload_t request;
memset(&request, 0, sizeof(dm_msg_request_payload_t));
res = dm_utils_memtok((char *)source->uri, strlen(source->uri), DM_URI_SERVICE_DELIMITER, 6, &rrpcid_pos);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
dm_log_info("Rrpc Id: %.*s", (int)(strlen(source->uri) - rrpcid_pos - 1), source->uri + rrpcid_pos + 1);
/* Parse Product Key And Device Name */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Request */
res = dm_msg_request_parse((char *)source->payload, source->payload_len, &request);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
return dm_msg_rrpc_request(product_key, device_name, (char *)source->uri + rrpcid_pos + 1,
strlen(source->uri) - rrpcid_pos - 1, &request);
}
int dm_disp_ntp_response(_IN_ dm_msg_source_t *source)
{
dm_log_info(DM_URI_NTP_RESPONSE);
/* Operation */
return dm_msg_ntp_response((char *)source->payload, source->payload_len);
}
int dm_disp_ext_error_response(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
/* char int_id[DM_UTILS_UINT32_STRLEN] = {0}; */
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
return dm_msg_ext_error_reply(&response);
}
#endif
#ifdef DEVICE_MODEL_GATEWAY
int dm_msg_proc_thing_topo_add_notify(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_TOPO_ADD_NOTIFY);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Operation */
res = dm_msg_topo_add_notify(request->params.value, request->params.value_length);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_disable(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_DISABLE);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res != SUCCESS_RETURN) {
return res;
}
/* Operation */
res = dm_msg_thing_disable(product_key, device_name);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_enable(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_DISABLE);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res != SUCCESS_RETURN) {
return res;
}
/* Operation */
res = dm_msg_thing_enable(product_key, device_name);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_delete(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_DELETE);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res != SUCCESS_RETURN) {
return res;
}
/* Operation */
res = dm_msg_thing_delete(product_key, device_name);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_gateway_permit(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response)
{
int res = 0;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
dm_log_info(DM_URI_THING_DELETE);
/* Request */
res = dm_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + DM_URI_OFFSET, 4 + DM_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res != SUCCESS_RETURN) {
return res;
}
/* Operation */
res = dm_msg_thing_gateway_permit(request->params.value, request->params.value_length);
/* Response */
response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_sub_register_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_SUB_REGISTER_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_sub_register_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_sub_unregister_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_SUB_UNREGISTER_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_sub_unregister_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_topo_add_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_ADD_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_topo_add_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_topo_delete_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_DELETE_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_topo_delete_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_topo_get_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_GET_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_topo_get_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_thing_list_found_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_GET_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_thing_list_found_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_combine_login_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_GET_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_combine_login_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
int dm_msg_proc_combine_logout_reply(_IN_ dm_msg_source_t *source)
{
int res = 0;
dm_msg_response_payload_t response;
#if !defined(DM_MESSAGE_CACHE_DISABLED)
char int_id[DM_UTILS_UINT32_STRLEN] = {0};
#endif
dm_log_info(DM_URI_THING_TOPO_GET_REPLY);
memset(&response, 0, sizeof(dm_msg_response_payload_t));
/* Response */
res = dm_msg_response_parse((char *)source->payload, source->payload_len, &response);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Operation */
dm_msg_combine_logout_reply(&response);
/* Remove Message From Cache */
#if !defined(DM_MESSAGE_CACHE_DISABLED)
memcpy(int_id, response.id.value, response.id.value_length);
dm_msg_cache_remove(atoi(int_id));
#endif
return SUCCESS_RETURN;
}
#endif
#ifdef ALCS_ENABLED
int dm_msg_proc_thing_dev_core_service_dev(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response,
_OU_ unsigned char **data, int *data_len)
{
int res = 0;
dm_log_info(DM_URI_DEV_CORE_SERVICE_DEV);
/* Request */
res = dm_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Operation */
res = dm_msg_dev_core_service_dev((char **)data, data_len);
if (res < SUCCESS_RETURN) {
return res;
}
/* Response */
response->service_prefix = NULL;
response->service_name = dest->uri_name;
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
return SUCCESS_RETURN;
}
#endif

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_MSG_PROCESS_H_
#define _DM_MSG_PROCESS_H_
#define DM_URI_SERVICE_DELIMITER '/'
extern const char DM_URI_SYS_PREFIX[] DM_READ_ONLY;
extern const char DM_URI_EXT_SESSION_PREFIX[] DM_READ_ONLY;
extern const char DM_URI_EXT_NTP_PREFIX[] DM_READ_ONLY;
extern const char DM_URI_EXT_ERROR_PREFIX[] DM_READ_ONLY;
extern const char DM_URI_REPLY_SUFFIX[] DM_READ_ONLY;
extern const char DM_URI_OTA_DEVICE_INFORM[] DM_READ_ONLY;
extern const char DM_URI_THING_PROPERTY_DESIRED_GET[] DM_READ_ONLY;
extern const char DM_URI_THING_PROPERTY_DESIRED_DELETE[] DM_READ_ONLY;
extern const char DM_URI_THING_PROPERTY_DESIRED_GET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_PROPERTY_DESIRED_DELETE_REPLY[] DM_READ_ONLY;
/* From Cloud To Local Request And Response*/
extern const char DM_URI_THING_MODEL_DOWN_RAW[] DM_READ_ONLY;
extern const char DM_URI_THING_MODEL_DOWN_RAW_REPLY[] DM_READ_ONLY;
/* From Local To Cloud Request And Response*/
extern const char DM_URI_THING_MODEL_UP_RAW[] DM_READ_ONLY;
extern const char DM_URI_THING_MODEL_UP_RAW_REPLY[] DM_READ_ONLY;
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
extern const char DM_URI_RRPC_REQUEST_WILDCARD[] DM_READ_ONLY;
/* From Cloud To Local Request And Response*/
extern const char DM_URI_THING_SERVICE_PROPERTY_SET[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_PROPERTY_SET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_PROPERTY_GET[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_PROPERTY_GET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_REQUEST_WILDCARD[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_REQUEST_WILDCARD2[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_REQUEST[] DM_READ_ONLY;
extern const char DM_URI_THING_SERVICE_RESPONSE[] DM_READ_ONLY;
/* From Local To Cloud Request And Response*/
extern const char DM_URI_THING_EVENT_PROPERTY_POST[] DM_READ_ONLY;
extern const char DM_URI_THING_EVENT_PROPERTY_POST_REPLY[] DM_READ_ONLY;
#ifdef LOG_REPORT_TO_CLOUD
extern const char DM_URI_THING_LOG_POST[] DM_READ_ONLY;
#endif
extern const char DM_URI_THING_EVENT_POST[] DM_READ_ONLY;
extern const char DM_URI_THING_EVENT_POST_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_EVENT_POST_REPLY_WILDCARD[] DM_READ_ONLY;
extern const char DM_URI_THING_DEVICEINFO_UPDATE[] DM_READ_ONLY;
extern const char DM_URI_THING_DEVICEINFO_UPDATE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_DEVICEINFO_DELETE[] DM_READ_ONLY;
extern const char DM_URI_THING_DEVICEINFO_DELETE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_DSLTEMPLATE_GET[] DM_READ_ONLY;
extern const char DM_URI_THING_DSLTEMPLATE_GET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_DYNAMICTSL_GET[] DM_READ_ONLY;
extern const char DM_URI_THING_DYNAMICTSL_GET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_NTP_REQUEST[] DM_READ_ONLY;
extern const char DM_URI_NTP_RESPONSE[] DM_READ_ONLY;
#endif
extern const char DM_URI_DEV_CORE_SERVICE_DEV[] DM_READ_ONLY;
#ifdef DEVICE_MODEL_GATEWAY
/* From Cloud To Local Request And Response*/
extern const char DM_URI_THING_TOPO_ADD_NOTIFY[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_ADD_NOTIFY_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_DISABLE[] DM_READ_ONLY;
extern const char DM_URI_THING_DISABLE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_ENABLE[] DM_READ_ONLY;
extern const char DM_URI_THING_ENABLE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_DELETE[] DM_READ_ONLY;
extern const char DM_URI_THING_DELETE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_GATEWAY_PERMIT[] DM_READ_ONLY;
extern const char DM_URI_THING_GATEWAY_PERMIT_REPLY[] DM_READ_ONLY;
/* From Local To Cloud Request And Response*/
extern const char DM_URI_THING_SUB_REGISTER[] DM_READ_ONLY;
extern const char DM_URI_THING_SUB_REGISTER_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_SUB_UNREGISTER[] DM_READ_ONLY;
extern const char DM_URI_THING_SUB_UNREGISTER_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_ADD[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_ADD_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_DELETE[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_DELETE_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_GET[] DM_READ_ONLY;
extern const char DM_URI_THING_TOPO_GET_REPLY[] DM_READ_ONLY;
extern const char DM_URI_THING_LIST_FOUND[] DM_READ_ONLY;
extern const char DM_URI_THING_LIST_FOUND_REPLY[] DM_READ_ONLY;
extern const char DM_URI_COMBINE_LOGIN[] DM_READ_ONLY;
extern const char DM_URI_COMBINE_LOGIN_REPLY[] DM_READ_ONLY;
extern const char DM_URI_COMBINE_LOGOUT[] DM_READ_ONLY;
extern const char DM_URI_COMBINE_LOGOUT_REPLY[] DM_READ_ONLY;
#endif
int dm_disp_uri_prefix_split(_IN_ const char *prefix, _IN_ char *uri, _IN_ int uri_len, _OU_ int *start, _OU_ int *end);
int dm_disp_uri_pkdn_split(_IN_ char *uri, _IN_ int uri_len, _OU_ int *start, _OU_ int *end);
int dm_disp_uri_service_specific_split(_IN_ char *uri, _IN_ int uri_len, _OU_ int *start, _OU_ int *end);
int dm_disp_uri_rrpc_request_split(_IN_ char *uri, _IN_ int uri_len, _OU_ int *start, _OU_ int *end);
int dm_disp_uri_event_specific_split(_IN_ char *uri, _IN_ int uri_len, _OU_ int *start, _OU_ int *end);
int dm_msg_proc_thing_model_down_raw(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_model_up_raw_reply(_IN_ dm_msg_source_t *source);
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int dm_msg_proc_thing_service_property_set(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_service_property_get(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response,
_OU_ unsigned char **data, int *data_len);
int dm_msg_proc_thing_property_desired_get_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_property_desired_delete_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_service_property_post(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_service_request(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_event_post_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_deviceinfo_update_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_deviceinfo_delete_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_dynamictsl_get_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_rrpc_request(_IN_ dm_msg_source_t *source);
int dm_disp_ntp_response(_IN_ dm_msg_source_t *source);
int dm_disp_ext_error_response(_IN_ dm_msg_source_t *source);
#endif
#ifdef DEVICE_MODEL_GATEWAY
int dm_msg_proc_thing_topo_add_notify(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_disable(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_enable(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_delete(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_gateway_permit(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response);
int dm_msg_proc_thing_sub_register_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_sub_unregister_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_topo_add_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_topo_delete_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_topo_get_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_thing_list_found_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_combine_login_reply(_IN_ dm_msg_source_t *source);
int dm_msg_proc_combine_logout_reply(_IN_ dm_msg_source_t *source);
#endif
#ifdef ALCS_ENABLED
int dm_msg_proc_thing_dev_core_service_dev(_IN_ dm_msg_source_t *source, _IN_ dm_msg_dest_t *dest,
_OU_ dm_msg_request_payload_t *request, _OU_ dm_msg_response_t *response,
_OU_ unsigned char **data, int *data_len);
#endif
#endif

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
static dm_opt_ctx g_dm_opt = {
0, 0, 1, 1, 1
};
int dm_opt_set(dm_opt_t opt, void *data)
{
int res = SUCCESS_RETURN;
if (data == NULL) {
return FAIL_RETURN;
}
switch (opt) {
case DM_OPT_DOWNSTREAM_PROPERTY_POST_REPLY: {
int opt = *(int *)(data);
g_dm_opt.prop_post_reply_opt = opt;
}
break;
case DM_OPT_DOWNSTREAM_EVENT_POST_REPLY: {
int opt = *(int *)(data);
g_dm_opt.event_post_reply_opt = opt;
}
break;
case DM_OPT_UPSTREAM_PROPERTY_SET_REPLY: {
int opt = *(int *)(data);
g_dm_opt.prop_set_reply_opt = opt;
}
break;
#ifdef DEVICE_MODEL_SHADOW
case DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_GET_REPLY: {
int opt = *(int *)(data);
g_dm_opt.prop_desired_get_reply_opt = opt;
}
break;
case DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_DELETE_REPLY: {
int opt = *(int *)(data);
g_dm_opt.prop_desired_delete_reply_opt = opt;
}
break;
#endif
default: {
res = FAIL_RETURN;
}
break;
}
return res;
}
int dm_opt_get(dm_opt_t opt, void *data)
{
int res = SUCCESS_RETURN;
if (data == NULL) {
return FAIL_RETURN;
}
switch (opt) {
case DM_OPT_DOWNSTREAM_PROPERTY_POST_REPLY: {
*(int *)(data) = g_dm_opt.prop_post_reply_opt;
}
break;
case DM_OPT_DOWNSTREAM_EVENT_POST_REPLY: {
*(int *)(data) = g_dm_opt.event_post_reply_opt;
}
break;
case DM_OPT_UPSTREAM_PROPERTY_SET_REPLY: {
*(int *)(data) = g_dm_opt.prop_set_reply_opt;
}
break;
#ifdef DEVICE_MODEL_SHADOW
case DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_DELETE_REPLY: {
*(int *)(data) = g_dm_opt.prop_desired_delete_reply_opt;
}
break;
case DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_GET_REPLY: {
*(int *)(data) = g_dm_opt.prop_desired_get_reply_opt;
}
break;
#endif
default: {
res = FAIL_RETURN;
}
break;
}
return res;
}
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
#ifndef _DM_OPT_H
#define _DM_OPT_H
typedef enum {
DM_OPT_DOWNSTREAM_PROPERTY_POST_REPLY,
DM_OPT_DOWNSTREAM_EVENT_POST_REPLY,
DM_OPT_UPSTREAM_PROPERTY_SET_REPLY,
DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_DELETE_REPLY,
DM_OPT_DOWNSTREAM_EVENT_PROPERTY_DESIRED_GET_REPLY
} dm_opt_t;
typedef struct {
int prop_post_reply_opt;
int event_post_reply_opt;
int prop_set_reply_opt;
int prop_desired_get_reply_opt;
int prop_desired_delete_reply_opt;
} dm_opt_ctx;
int dm_opt_set(dm_opt_t opt, void *data);
int dm_opt_get(dm_opt_t opt, void *data);
#endif
#endif

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
static dm_ota_ctx_t g_dm_ota_ctx;
static dm_ota_ctx_t *_dm_ota_get_ctx(void)
{
return &g_dm_ota_ctx;
}
int dm_ota_init(void)
{
dm_ota_ctx_t *ctx = _dm_ota_get_ctx();
memset(ctx, 0, sizeof(dm_ota_ctx_t));
HAL_GetProductKey(ctx->product_key);
HAL_GetDeviceName(ctx->device_name);
return SUCCESS_RETURN;
}
int dm_ota_sub(void)
{
dm_ota_ctx_t *ctx = _dm_ota_get_ctx();
void *handle = NULL;
/* Init OTA Handle */
handle = IOT_OTA_Init(ctx->product_key, ctx->device_name, NULL);
if (handle == NULL) {
return FAIL_RETURN;
}
ctx->ota_handle = handle;
return SUCCESS_RETURN;
}
int dm_ota_deinit(void)
{
dm_ota_ctx_t *ctx = _dm_ota_get_ctx();
if (ctx->ota_handle) {
IOT_OTA_Deinit(ctx->ota_handle);
ctx->ota_handle = NULL;
}
return SUCCESS_RETURN;
}
#ifdef DEVICE_MODEL_GATEWAY
#ifdef DEVICE_MODEL_SUBDEV_OTA
int dm_ota_switch_device(int devid)
{
char pk[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char dn[IOTX_DEVICE_NAME_LEN + 1] = {0};
char ds[IOTX_DEVICE_SECRET_LEN + 1] = {0};
int ret = dm_mgr_search_device_by_devid(devid, pk, dn, ds);
void *ota_handle = NULL;
int res = -1;
dm_ota_ctx_t *ctx = NULL;
if (SUCCESS_RETURN != ret) {
dm_log_err("could not find device by id, ret is %d", ret);
return FAIL_RETURN;
}
dm_log_info("do subdevice ota, pk, dn is %s, %s", pk, dn);
ota_handle = NULL;
res = dm_ota_get_ota_handle(&ota_handle);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* if currently a device is doing OTA, do not interrupt */
if (IOT_OTA_IsFetching(ota_handle)) {
dm_log_info("OTA is processing, can not switch to another device");
return FAIL_RETURN;
}
dm_ota_deinit();
ctx = _dm_ota_get_ctx();
memset(ctx, 0, sizeof(dm_ota_ctx_t));
memcpy(ctx->product_key, pk, strlen(pk) + 1);
memcpy(ctx->device_name, dn, strlen(dn) + 1);
ret = dm_ota_sub();
if (ret < 0) {
dm_log_err("dm_ota_sub ret is %d, %s, %s\n", ret, pk, dn);
}
return ret;
}
#endif
#endif
int dm_ota_get_ota_handle(void **handle)
{
dm_ota_ctx_t *ctx = _dm_ota_get_ctx();
if (handle == NULL || *handle != NULL) {
return FAIL_RETURN;
}
if (ctx->ota_handle == NULL) {
return FAIL_RETURN;
}
*handle = ctx->ota_handle;
return SUCCESS_RETURN;
}
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_OTA_H_
#define _DM_OTA_H_
typedef struct {
void *ota_handle;
char product_key[IOTX_PRODUCT_KEY_LEN + 1];
char device_name[IOTX_DEVICE_NAME_LEN + 1];
} dm_ota_ctx_t;
int dm_ota_init(void);
int dm_ota_sub(void);
int dm_ota_deinit(void);
int dm_ota_get_ota_handle(void **handle);
#ifdef DEVICE_MODEL_GATEWAY
#ifdef DEVICE_MODEL_SUBDEV_OTA
int dm_ota_switch_device(int devid);
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,533 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#if defined(DEPRECATED_LINKKIT)
#ifndef _DM_SHADOW_H_
#define _DM_SHADOW_H_
#include "iotx_dm_internal.h"
#define DM_SHW_KEY_SCHEMA "schema"
#define DM_SHW_KEY_LINK "link"
#define DM_SHW_KEY_PROFILE "profile"
#define DM_SHW_KEY_PROPERTIES "properties"
#define DM_SHW_KEY_EVENTS "events"
#define DM_SHW_KEY_SERVICES "services"
#define DM_SHW_KEY_PROFILE_PK "productKey"
#define DM_SHW_KEY_PROFILE_DN "deviceName"
#define DM_SHW_KEY_IDENTIFIER "identifier"
#define DM_SHW_KEY_NAME "name"
#define DM_SHW_KEY_DESC "desc"
#define DM_SHW_KEY_ACCESS_MODE "accessMode"
#define DM_SHW_KEY_REQUIRED "required"
#define DM_SHW_KEY_METHOD "method"
#define DM_SHW_KEY_CALLTYPE "callType"
#define DM_SHW_KEY_OUTPUTDATA "outputData"
#define DM_SHW_KEY_INPUTDATA "inputData"
#define DM_SHW_KEY_DATATYPE "dataType"
#define DM_SHW_KEY_TYPE "type"
#define DM_SHW_KEY_SPECS "specs"
#define DM_SHW_KEY_UNIT "unit"
#define DM_SHW_KEY_UNITNAME "unitName"
#define DM_SHW_KEY_MIN "min"
#define DM_SHW_KEY_MAX "max"
#define DM_SHW_KEY_LENGTH "length"
#define DM_SHW_KEY_SIZE "size"
#define DM_SHW_KEY_ITEM "item"
/* Special Service And Event */
#define DM_SHW_SPECIAL_SERVICE_SET_IDENTIFIER "set"
#define DM_SHW_SPECIAL_SERVICE_SET_METHOD "thing.service.property.set"
#define DM_SHW_SPECIAL_SERVICE_GET_IDENTIFIER "get"
#define DM_SHW_SPECIAL_SERVICE_GET_METHOD "thing.service.property.get"
#define DM_SHW_SPECIAL_EVENT_POST_IDENTIFIER "post"
#define DM_SHW_SPECIAL_EVENT_POST_METHOD "thing.event.property.post"
#define DM_SHW_KEY_DELIMITER '.'
typedef enum {
DM_SHW_DATA_TYPE_NONE, /* none */
DM_SHW_DATA_TYPE_INT, /* int */
DM_SHW_DATA_TYPE_FLOAT, /* float */
DM_SHW_DATA_TYPE_DOUBLE, /* double */
DM_SHW_DATA_TYPE_TEXT, /* string */
DM_SHW_DATA_TYPE_ENUM, /* int */
DM_SHW_DATA_TYPE_DATE, /* string */
DM_SHW_DATA_TYPE_BOOL, /* bool,0 or 1 */
DM_SHW_DATA_TYPE_ARRAY, /* support int, float, double, text */
DM_SHW_DATA_TYPE_STRUCT, /* support above 8 data types */
} dm_shw_data_type_e;
typedef enum {
DM_SHW_DATA_TARGET_SERVICE_INPUT_DATA,
DM_SHW_DATA_TARGET_SERVICE_OUTPUT_DATA
} dm_shw_data_target_e;
typedef struct {
dm_shw_data_type_e type;
int size;
void *value;
} dm_shw_data_value_complex_t;
typedef struct {
dm_shw_data_type_e type;
union {
int value_int;
float value_float;
double value_double;
void *value; /* string or complex type accroding to data type */
};
} dm_shw_data_value_t;
typedef struct {
dm_shw_data_type_e type;
int specs_number; /* used when type is enum and struct */
void *specs; /* nerver be used by struct */
} dm_shw_data_type_t;
typedef struct {
char *identifier;
dm_shw_data_value_t data_value;
} dm_shw_data_t;
typedef struct {
char *identifier;
int input_data_number; /* input_data Number */
dm_shw_data_t *input_datas; /* input_data array, type is dm_shw_data_t */
int output_data_number; /* ouput_data Number */
dm_shw_data_t *output_datas; /* output_data array, type is dm_shw_data_t */
} dm_shw_event_t;
typedef struct {
char *identifier; /* synchronized or asynchronized */
int input_data_number; /* input_data_number */
dm_shw_data_t *input_datas; /* input_data array, type is dm_shw_data_t */
int output_data_number; /* ouput_data Number */
dm_shw_data_t *output_datas; /* output_data array, type is dm_shw_data_t */
} dm_shw_service_t;
typedef struct {
int property_number;
dm_shw_data_t *properties; /* property array, type is dm_shw_data_t */
int event_number;
dm_shw_event_t *events; /* event array, type is dm_shw_event_t */
int service_number;
dm_shw_service_t *services; /* service array, type is dm_shw_service_t */
} dm_shw_t;
/**
* @brief Create TSL struct from TSL string.
* This function used to parse TSL string into TSL struct.
*
* @param tsl. The TSL string in JSON format.
* @param tsl_len. The length of tsl
* @param shadow. The pointer of TSL Struct pointer, will be malloc memory.
* This memory should be free by dm_shw_destroy.
*
* @return success or fail.
*
*/
int dm_shw_create(_IN_ iotx_dm_tsl_type_t type, _IN_ const char *tsl, _IN_ int tsl_len, _OU_ dm_shw_t **shadow);
/**
* @brief Get property from TSL struct.
* This function used to get property from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: property_id
* array type: property_id(array)[index]
* struct type: property_id(struct).property_id or property_id(struct).property_id[index]
*
* @param key_len. The length of key.
* @param property. The property in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_property_data(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
int dm_shw_get_service_input_output_data(_IN_ dm_shw_data_target_e type, _IN_ dm_shw_t *shadow, _IN_ char *key,
_IN_ int key_len, _OU_ void **data);
/**
* @brief Get event output data from TSL struct.
* This function used to get event output data from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: property_id
* array type: property_id(array)[index]
* struct type: property_id(struct).property_id or property_id(struct).property_id[index]
*
* @param key_len. The length of key.
* @param property. The property in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_event_output_data(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
/**
* @brief Get property type from TSL struct.
* This function used to get property type from TSL struct.
*
* @param property. The handle of property.
* @param type. The data type of property
*
*
* @return success or fail.
*
*/
int dm_shw_get_data_type(_IN_ void *data, _OU_ dm_shw_data_type_e *type);
/**
* @brief Get event from TSL struct.
* This function used to get property from TSL struct.
*
* @param service. The handle of event.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: event_id
*
* @param key_len. The length of key.
* @param property. The event in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_event(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **event);
/**
* @brief Get service from TSL struct.
* This function used to get property from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: service_id
*
* @param key_len. The length of key.
* @param property. The service in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_service(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **service);
/**
* @brief Get property number from TSL struct.
* This function used to get property number from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param number. The property number in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_property_number(_IN_ dm_shw_t *shadow, _OU_ int *number);
/**
* @brief Get service number from TSL struct.
* This function used to get property number from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param number. The service number in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_service_number(_IN_ dm_shw_t *shadow, _OU_ int *number);
/**
* @brief Get event number from TSL struct.
* This function used to get property number from TSL struct.
*
* @param shadow. The pointer of TSL Struct.
* @param number. The event number in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_event_number(_IN_ dm_shw_t *shadow, _OU_ int *number);
/**
* @brief Get property reference from TSL struct by index.
* This function used to get property reference from TSL struct by index.
*
* @param shadow. The pointer of TSL Struct.
* @param index. The index of property
* @param property. The property reference in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_property_by_index(_IN_ dm_shw_t *shadow, _IN_ int index, _OU_ void **property);
/**
* @brief Get service reference from TSL struct by index.
* This function used to get service reference from TSL struct by index.
*
* @param shadow. The pointer of TSL Struct.
* @param index. The index of service
* @param service. The service reference in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_service_by_index(_IN_ dm_shw_t *shadow, _IN_ int index, _OU_ void **service);
/**
* @brief Get event reference from TSL struct by index.
* This function used to get event reference from TSL struct by index.
*
* @param shadow. The pointer of TSL Struct.
* @param index. The index of event
* @param event. The event reference in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_event_by_index(_IN_ dm_shw_t *shadow, _IN_ int index, _OU_ void **event);
/**
* @brief Get service reference from TSL struct by identifier.
* This function used to get service reference from TSL struct by identifier.
*
* @param shadow. The pointer of TSL Struct.
* @param identifier. The identifier of event
* @param service. The service reference in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_service_by_identifier(_IN_ dm_shw_t *shadow, _IN_ char *identifier, _OU_ void **service);
/**
* @brief Get event reference from TSL struct by identifier.
* This function used to get event reference from TSL struct by identifier.
*
* @param shadow. The pointer of TSL Struct.
* @param identifier. The identifier of event
* @param event. The event reference in TSL Struct.
*
* @return success or fail.
*
*/
int dm_shw_get_event_by_identifier(_IN_ dm_shw_t *shadow, _IN_ char *identifier, _OU_ void **event);
/**
* @brief Get property identifier from TSL struct by service handle.
* This function used to get property identifier from TSL struct by service handle.
*
* @param service. The handle of property.
* @param method. The reference to property identifier in TSL Struct
*
* @return success or fail.
*
*/
int dm_shw_get_property_identifier(_IN_ void *property, _OU_ char **identifier);
/**
* @brief Get service method from TSL struct by service handle.
* This function used to get service method from TSL struct by service handle.
*
* @param service. The handle of service.
* @param method. Generate method from service identifier
*
* @return success or fail.
*
*/
int dm_shw_get_service_method(_IN_ void *service, _OU_ char **method);
/**
* @brief Get event method from TSL struct by event handle.
* This function used to get event method from TSL struct by event handle.
*
* @param service. The handle of event.
* @param method. Generate method from event identifier
*
* @return success or fail.
*
*/
int dm_shw_get_event_method(_IN_ void *event, _OU_ char **method);
/**
* @brief Set Property Value Into TSL Struct.
* This function used to set property value into TSL Struct.
*
* @param tsl. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: property_id
* array type: property_id(array)[index]
* struct type: property_id(struct).property_id or property_id(struct).property_id[index]
*
* @param key_len. The length of key
* @param value. The value to be set, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char*, enum: int*, date: char*, bool: int*
* attention! value can be NULL to clear property value
* @param value_len. The length of value, only be used when type is text or data
*
* @return success or fail.
*
*/
int dm_shw_set_property_value(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
/**
* @brief Get Property Value From TSL Struct.
* This function used to get property value from TSL Struct.
*
* @param tsl. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: property_id
* array type: property_id(array)[index]
* struct type: property_id(struct).property_id or property_id(struct).property_id[index]
*
* @param key_len. The length of key
* @param value. The variable to store value, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char**, enum: int*, date: char**, bool: int*
* attention! value can not be NULL
*
* @warning if data type is text or date, *value well be end with '\0'.
* the memory allocated to *value must be free by user.
*
* @return success or fail.
*
*/
int dm_shw_get_property_value(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void *value);
/**
* @brief Set event output value into TSL struct.
* This function used to set event output value into TSL struct.
*
* @param tsl. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: event_id.event_data_id
* array type: event_id.event_data_id(array)[index]
* struct type: event_id.event_data_id(struct).property_id
* or event_id.event_data_id(struct).property_id[index]
*
* @param key_len. The length of key
* @param value. The value to be set, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char*, enum: int*, date: char*, bool: int*
* attention! value can be NULL to clear property value
* @param value_len. The length of value, only be used when type is text or data
*
* @return success or fail.
*
*/
int dm_shw_set_event_output_value(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
/**
* @brief Get event output value from TSL struct.
* This function used to get event output value from TSL struct.
*
* @param tsl. The pointer of TSL Struct.
* @param key. The property compound string, format decided by data type of property as follows:
* int,float,double,text,enum,date,bool type: event_id.event_data_id
* array type: event_id.event_data_id(array)[index]
* struct type: event_id.event_data_id(struct).property_id
* or event_id.event_data_id(struct).property_id[index]
*
* @param key_len. The length of key
* @param value. The variable to store value, data type decided by data type of property as follows:
* int: int*, float: float*, double: double*,
* text: char**, enum: int*, date: char**, bool: int*
* attention! value can not be NULL
*
* @warning if data type is text or date, *value well be end with '\0'.
* the memory allocated to *value must be free by user.
*
* @return success or fail.
*
*/
int dm_shw_get_event_output_value(_IN_ dm_shw_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int dm_shw_set_service_input_output_value(_IN_ dm_shw_data_target_e type, _IN_ dm_shw_t *shadow, _IN_ char *key,
_IN_ int key_len, _IN_ void *value, _IN_ int value_len);
int dm_shw_get_service_input_output_value(_IN_ dm_shw_data_target_e type, _IN_ dm_shw_t *shadow, _IN_ char *key,
_IN_ int key_len, _IN_ void *value);
/**
* @brief Get property payload from TSL struct.
* This function used to get property payload from TSL struct.
*
* @param shadow. The pointer of TSL Struct
* @param identifier. The Property Identifier
* @param identifier_len. The Property Identifier Length
* @param lite. The pointer to json array where to store property value
*
* @warning The payload malloc by this function and need to be free manully.
*
* @return success or fail.
*
*/
int dm_shw_assemble_property(_IN_ dm_shw_t *shadow, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
/**
* @brief Get event output payload from TSL struct.
* This function used to get event output payload from TSL struct.
*
* @param shadow. The pointer of TSL Struct
* @param identifier. The Event Identifier
* @param identifier_len. The Event Identifier Length
* @param lite. The pointer to json array where to store event output value
*
* @warning The payload malloc by this function and need to be free manully.
*
* @return success or fail.
*
*/
int dm_shw_assemble_event_output(_IN_ dm_shw_t *shadow, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
/**
* @brief Get service output payload from TSL struct.
* This function used to get service output payload from TSL struct.
*
* @param shadow. The pointer of TSL Struct
* @param identifier. The Service Identifier
* @param identifier_len. The Service Identifier Length
* @param lite. The pointer to json array where to store service output value
*
* @warning The payload malloc by this function and need to be free manully.
*
* @return success or fail.
*
*/
int dm_shw_assemble_service_output(_IN_ dm_shw_t *shadow, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite);
/**
* @brief Free TSL struct.
* This function used to free TSL struct.
*
* @param shadow. The pointer of TSL Struct.
*
* @return success or fail.
*
*/
void dm_shw_destroy(_IN_ dm_shw_t **shadow);
#if 0
/**
* @brief Print detailed information of TSL struct.
* This function used to print detailed information of TSL struct.
*
* @param shadow. The pointer of TSL Struct.
*
* @return success or fail.
*
*/
void dm_shw_print(_IN_ dm_shw_t *shadow);
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#if defined(DEPRECATED_LINKKIT)
#ifndef _DM_TSL_ALINK_H_
#define _DM_TSL_ALINK_H_
/**
* @brief Create TSL struct from TSL string.
* This function used to parse TSL string into TSL struct.
*
* @param tsl. The TSL string in JSON format.
* @param tsl_len. The length of tsl
* @param shadow. The pointer of TSL Struct pointer, will be malloc memory.
* This memory should be free by dm_shw_destroy.
*
* @return success or fail.
*
*/
int dm_tsl_alink_create(_IN_ const char *tsl, _IN_ int tsl_len, _OU_ dm_shw_t **shadow);
#endif
#endif

View File

@@ -0,0 +1,428 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "iotx_dm_internal.h"
int dm_utils_copy_direct(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len)
{
if (input == NULL || output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
*output = HAL_Malloc(output_len);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, output_len);
memcpy(*output, input, input_len);
return SUCCESS_RETURN;
}
int dm_utils_copy(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len)
{
if (input == NULL || output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
*output = DM_malloc(output_len);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, output_len);
memcpy(*output, input, input_len);
return SUCCESS_RETURN;
}
int dm_utils_strarr_index(_IN_ char *input, _IN_ int input_len,
_OU_ int *partial_input_len, _OU_ int *array_input_len, _OU_ int *array_index)
{
int index = 0;
int deep = 0;
char *bracket_pre = NULL;
char *bracket_suf = NULL;
char array_index_str[10] = {0};
if (input == NULL || input_len <= 1 || array_index == NULL) {
return DM_INVALID_PARAMETER;
}
for (index = 0; index < input_len; index++) {
switch (input[index]) {
case '[': {
if (deep != 0) {
return FAIL_RETURN;
}
deep++;
if (!bracket_pre) {
bracket_pre = (char *)&input[index];
}
}
break;
case ']': {
if (deep != 1) {
return FAIL_RETURN;
}
deep--;
if (input[index - 1] == '[') {
return FAIL_RETURN;
}
if (!bracket_suf) {
bracket_suf = (char *)&input[index];
}
}
break;
default:
break;
}
}
if (bracket_pre && bracket_suf && ((bracket_suf - input + 1) == input_len)) {
if (partial_input_len) {
*partial_input_len = bracket_pre - input;
}
if (array_input_len) {
*array_input_len = bracket_suf - input + 1;
}
/* Get Index */
memcpy(array_index_str, bracket_pre + 1, bracket_suf - bracket_pre - 1);
*array_index = atoi(array_index_str);
return SUCCESS_RETURN;
}
return FAIL_RETURN;
}
int dm_utils_itoa_direct(_IN_ int input, _OU_ char **output)
{
int res = 0;
char temp_output[10 + 1] = {0};
if (output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
res = HAL_Snprintf(temp_output, 10, "%d", input);
if (res < 0) {
return FAIL_RETURN;
}
*output = HAL_Malloc(strlen(temp_output) + 1);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, strlen(temp_output) + 1);
memcpy(*output, temp_output, strlen(temp_output));
return SUCCESS_RETURN;
}
int dm_utils_itoa(_IN_ int input, _OU_ char **output)
{
int res = 0;
char temp_output[10 + 1] = {0};
if (output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
res = HAL_Snprintf(temp_output, 10, "%d", input);
if (res < 0) {
return FAIL_RETURN;
}
*output = DM_malloc(strlen(temp_output) + 1);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, strlen(temp_output) + 1);
memcpy(*output, temp_output, strlen(temp_output));
return SUCCESS_RETURN;
}
int dm_utils_ftoa_direct(_IN_ double input, _OU_ char **output)
{
int res = 0;
char temp_output[30 + 1] = {0};
if (output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
res = HAL_Snprintf(temp_output, 30, "%f", input);
if (res < 0) {
return FAIL_RETURN;
}
*output = HAL_Malloc(strlen(temp_output) + 1);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, strlen(temp_output) + 1);
memcpy(*output, temp_output, strlen(temp_output));
return SUCCESS_RETURN;
}
int dm_utils_ftoa(_IN_ double input, _OU_ char **output)
{
int res = 0;
char temp_output[30 + 1] = {0};
if (output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
res = HAL_Snprintf(temp_output, 30, "%f", input);
if (res < 0) {
return FAIL_RETURN;
}
*output = DM_malloc(strlen(temp_output) + 1);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, strlen(temp_output) + 1);
memcpy(*output, temp_output, strlen(temp_output));
return SUCCESS_RETURN;
}
int dm_utils_hex_to_str(_IN_ unsigned char *input, _IN_ int input_len, _OU_ char **output)
{
int index = 0, output_len = 0;
unsigned char iter_char = 0;
if (input == NULL || input_len <= 0 || output == NULL || *output != NULL) {
return DM_INVALID_PARAMETER;
}
output_len = input_len * 2;
*output = DM_malloc(output_len + 1);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, output_len + 1);
for (index = 0; index < input_len; index++) {
iter_char = (input[index] >> 4) & 0x0F;
if (iter_char <= 0x09) {
iter_char += '0';
} else if (iter_char >= 0x0A && iter_char <= 0x0F) {
iter_char += 'A' - 0x0A;
}
(*output)[index * 2] = iter_char;
iter_char = (input[index]) & 0x0F;
if (iter_char <= 0x09) {
iter_char += '0';
} else if (iter_char >= 0x0A && iter_char <= 0x0F) {
iter_char += 'A' - 0x0A;
}
(*output)[index * 2 + 1] = iter_char;
}
return SUCCESS_RETURN;
}
int dm_utils_str_to_hex(_IN_ char *input, _IN_ int input_len, _OU_ unsigned char **output, _OU_ int *output_len)
{
int index = 0;
char iter_char = 0;
if (input == NULL || input_len <= 0 || input_len % 2 != 0 ||
output == NULL || *output != NULL || output_len == NULL) {
return DM_INVALID_PARAMETER;
}
*output_len = input_len / 2;
*output = DM_malloc(*output_len);
if (*output == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*output, 0, *output_len);
for (index = 0; index < input_len; index += 2) {
if (input[index] >= '0' && input[index] <= '9') {
iter_char = input[index] - '0';
} else if (input[index] >= 'A' && input[index] <= 'F') {
iter_char = input[index] - 'A' + 0x0A;
}
(*output)[index / 2] |= (iter_char << 4) & 0xF0;
if (input[index + 1] >= '0' && input[index + 1] <= '9') {
iter_char = input[index + 1] - '0';
} else if (input[index + 1] >= 'A' && input[index + 1] <= 'F') {
iter_char = input[index + 1] - 'A' + 0x0A;
}
(*output)[index / 2] |= (iter_char) & 0x0F;
}
return SUCCESS_RETURN;
}
int dm_utils_memtok(_IN_ char *input, _IN_ int input_len, _IN_ char delimiter, _IN_ int index, _OU_ int *offset)
{
int item_index = 0;
int count = 0;
if (input == NULL || input_len <= 0 || offset == NULL) {
return DM_INVALID_PARAMETER;
}
for (item_index = 0; item_index < input_len; item_index++) {
if (input[item_index] == delimiter && (item_index + 1) < input_len) {
count++;
if (count == index) {
*offset = item_index;
return SUCCESS_RETURN;
}
}
}
return FAIL_RETURN;
}
int dm_utils_replace_char(_IN_ char *input, _IN_ int input_len, _IN_ char src, _IN_ char dest)
{
int index = 0;
if (input == NULL || input_len <= 0) {
return DM_INVALID_PARAMETER;
}
for (index = 0; index < input_len; index++) {
if (input[index] == src) {
input[index] = dest;
}
}
return SUCCESS_RETURN;
}
int dm_utils_service_name(_IN_ const char *prefix, _IN_ const char *name, _IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1], _OU_ char **service_name)
{
int prefix_len = (prefix == NULL) ? (0) : (strlen(prefix));
int name_len = (name == NULL) ? (0) : (strlen(name));
int service_name_len = 0;
if ((prefix == NULL && name == NULL) || product_key == NULL || device_name == NULL ||
service_name == NULL || *service_name != NULL) {
return DM_INVALID_PARAMETER;
}
service_name_len = prefix_len + name_len + strlen(product_key) + strlen(device_name) + 1;
*service_name = DM_malloc(service_name_len);
if (*service_name == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*service_name, 0, service_name_len);
if (prefix != NULL) {
HAL_Snprintf(*service_name, service_name_len, prefix, product_key, device_name);
}
if (name != NULL) {
memcpy(*service_name + strlen(*service_name), name, name_len);
}
return SUCCESS_RETURN;
}
int dm_utils_uri_add_prefix(_IN_ const char *prefix, _IN_ char *uri, _OU_ char **new_uri)
{
int new_uri_len = 0;
if (prefix == NULL || uri == NULL || new_uri == NULL || *new_uri != NULL) {
return DM_INVALID_PARAMETER;
}
new_uri_len = strlen(prefix) + strlen(uri) + 1;
*new_uri = DM_malloc(new_uri_len);
if (*new_uri == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(*new_uri, 0, new_uri_len);
memcpy(*new_uri, prefix, strlen(prefix));
memcpy(*new_uri + strlen(*new_uri), uri, strlen(uri));
return SUCCESS_RETURN;
}
int dm_utils_json_parse(_IN_ const char *payload, _IN_ int payload_len, _IN_ int type, _OU_ lite_cjson_t *lite)
{
int res = 0;
if (payload == NULL || payload_len <= 0 || type < 0 || lite == NULL) {
return DM_INVALID_PARAMETER;
}
memset(lite, 0, sizeof(lite_cjson_t));
res = lite_cjson_parse(payload, payload_len, lite);
if (res != SUCCESS_RETURN) {
memset(lite, 0, sizeof(lite_cjson_t));
return FAIL_RETURN;
}
if (type != cJSON_Invalid && lite->type != type) {
memset(lite, 0, sizeof(lite_cjson_t));
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int dm_utils_json_object_item(_IN_ lite_cjson_t *lite, _IN_ const char *key, _IN_ int key_len, _IN_ int type,
_OU_ lite_cjson_t *lite_item)
{
int res = 0;
if (lite == NULL || lite->type != cJSON_Object || key == NULL || key_len <= 0 || type < 0 || lite_item == NULL) {
return DM_INVALID_PARAMETER;
}
if (lite->type != cJSON_Object) {
dm_log_err("lite->type != cJSON_Object, %d", lite->type);
}
memset(lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(lite, key, key_len, lite_item);
if (res != SUCCESS_RETURN) {
/* dm_log_err(DM_UTILS_LOG_JSON_PARSE_FAILED, lite->value_length, lite->value); */
memset(lite_item, 0, sizeof(lite_cjson_t));
return FAIL_RETURN;
}
if (type != cJSON_Invalid && lite_item->type != type) {
memset(lite_item, 0, sizeof(lite_cjson_t));
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
void *dm_utils_malloc(unsigned int size)
{
#ifdef INFRA_MEM_STATS
return LITE_malloc(size, MEM_MAGIC, "lite_cjson");
#else
return HAL_Malloc(size);
#endif
}
void dm_utils_free(void *ptr)
{
#ifdef INFRA_MEM_STATS
LITE_free(ptr);
#else
HAL_Free((void *)ptr);
#endif
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _DM_UTILS_H_
#define _DM_UTILS_H_
#define DM_UTILS_UINT16_STRLEN (5)
#define DM_UTILS_UINT32_STRLEN (10)
#define DM_UTILS_UINT64_STRLEN (20)
int dm_utils_copy_direct(void *input, int input_len, void **output, int output_len);
int dm_utils_copy(void *input, int input_len, void **output, int output_len);
/**
* @brief search array index in a string.
* This function used to search array index in a string.
*
* @param input. The string to be searched
* @param input_len. The length of input
* @param partial_input_len. The length of input except [xx]
* @param array_input_len. The length of input include [xx]
* @param array_index. The array index in [xx]
*
* @warning input must be type of "xxxxx[xx]"
* @return success or fail.
*
*/
int dm_utils_strarr_index(char *input, int input_len,
int *partial_input_len, int *array_input_len, int *array_index);
int dm_utils_itoa_direct(int input, char **output);
int dm_utils_itoa(int input, char **output);
int dm_utils_ftoa_direct(double input, char **output);
int dm_utils_ftoa(double input, char **output);
int dm_utils_hex_to_str(unsigned char *input, int input_len, char **output);
int dm_utils_str_to_hex(char *input, int input_len, unsigned char **output, int *output_len);
int dm_utils_memtok(char *input, int input_len, char delimiter, int index, int *offset);
int dm_utils_replace_char(char *input, int input_len, char src, char dest);
int dm_utils_service_name(const char *prefix, const char *name, char product_key[IOTX_PRODUCT_KEY_LEN + 1],
char device_name[IOTX_DEVICE_NAME_LEN + 1], char **service_name);
int dm_utils_uri_add_prefix(const char *prefix, char *uri, char **new_uri);
int dm_utils_json_parse(const char *payload, int payload_len, int type, lite_cjson_t *lite);
int dm_utils_json_object_item(lite_cjson_t *lite, const char *key, int key_len, int type,
lite_cjson_t *lite_item);
void *dm_utils_malloc(unsigned int size);
void dm_utils_free(void *ptr);
#endif

View File

@@ -0,0 +1,82 @@
#ifndef _DM_WRAPPER_H_
#define _DM_WRAPPER_H_
#include "infra_compat.h"
#include "wrappers_defs.h"
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]);
int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1]);
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1]);
int HAL_SetDeviceName(char *device_name);
int HAL_SetDeviceSecret(char *device_secret);
int HAL_SetProductKey(char *product_key);
int HAL_SetProductSecret(char *product_secret);
void *HAL_MutexCreate(void);
void HAL_MutexDestroy(void *mutex);
void HAL_MutexLock(void *mutex);
void HAL_MutexUnlock(void *mutex);
void *HAL_Malloc(uint32_t size);
void HAL_Free(void *ptr);
uint64_t HAL_UptimeMs(void);
void HAL_SleepMs(uint32_t ms);
void HAL_Srandom(uint32_t seed);
uint32_t HAL_Random(uint32_t region);
void HAL_Printf(const char *fmt, ...);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
#ifdef INFRA_LOG
#include <stdarg.h>
int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap);
#endif
int HAL_ThreadCreate(
void **thread_handle,
void *(*work_routine)(void *),
void *arg,
hal_os_thread_param_t *hal_os_thread_param,
int *stack_used);
void HAL_ThreadDelete(void *thread_handle);
void *HAL_SemaphoreCreate(void);
void HAL_SemaphoreDestroy(void *sem);
void HAL_SemaphorePost(void *sem);
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms);
int HAL_Kv_Set(const char *key, const void *val, int len, int sync);
int HAL_Kv_Get(const char *key, void *val, int *buffer_len);
int HAL_Kv_Del(const char *key);
#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
void HAL_Firmware_Persistence_Start(void);
int HAL_Firmware_Persistence_Write(char *buffer, uint32_t length);
int HAL_Firmware_Persistence_Stop(void);
#endif
#ifdef DEPRECATED_LINKKIT
int HAL_SetProductKey(char *product_key);
int HAL_SetProductSecret(char *product_secret);
int HAL_SetDeviceName(char *device_name);
int HAL_SetDeviceSecret(char *device_secret);
#endif
#ifdef ALCS_ENABLED
p_HAL_Aes128_t HAL_Aes128_Init(
const uint8_t *key,
const uint8_t *iv,
AES_DIR_t dir);
int HAL_Aes128_Cbc_Encrypt(
p_HAL_Aes128_t aes,
const void *src,
size_t blockNum,
void *dst);
int HAL_Aes128_Destroy(p_HAL_Aes128_t aes);
int HAL_Aes128_Cbc_Decrypt(
p_HAL_Aes128_t aes,
const void *src,
size_t blockNum,
void *dst);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 5
#define CJSON_VERSION_PATCH 3
#include <stdint.h>
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,254 @@
/*
* please modify this string follow as product's TSL.
*/
static const char TSL_STRING[] =
"{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/"
"schema.json\",\"profile\":{\"productKey\":\"a1X2bEnP82z\"},\"services\":[{"
"\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":"
"true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":"
"\"WIFI_Band\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{"
"\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_"
"BSSID\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},"
"\"name\":\"热点BSSID\"},{\"identifier\":\"WIFI_Channel\",\"dataType\":{"
"\"specs\":{\"min\":\"1\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":"
"\"127\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信噪比\"},{"
"\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_"
"Name\"},{\"identifier\":\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Rx_Rate_Name\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":"
"\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},"
"{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{"
"\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":"
"\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":"
"\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":"
"\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0."
"01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":"
"\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":"
"{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"亮度\"}],"
"\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"WorkMode\","
"\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":"
"\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":"
"\"工作模式\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{"
"\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{"
"\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"ColorTemperature\","
"\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2000\",\"unitName\":"
"\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"冷暖色温\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":"
"{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\"}"
",{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-"
"100\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"Propertypoint_Name\"}],\"identifier\":\"get\",\"inputData\":["
"\"LightSwitch\",\"WIFI_Band\",\"WiFI_RSSI\",\"WIFI_AP_BSSID\",\"WIFI_"
"Channel\",\"WiFI_SNR\",\"WIFI_Tx_Rate\",\"WIFI_Rx_Rate\",\"RGBColor\","
"\"HSVColor\",\"HSLColor\",\"WorkMode\",\"NightLightSwitch\",\"Brightness\","
"\"ColorTemperature\",\"PropertyCharacter\",\"Propertypoint\"],\"method\":"
"\"thing.service.property.get\",\"name\":\"get\",\"required\":true,"
"\"callType\":\"async\",\"desc\":\"属性获取\"}],\"properties\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_Band\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"频段\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WiFI_RSSI\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"-"
"1\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信号强度\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WIFI_Channel\","
"\"dataType\":{\"specs\":{\"min\":\"1\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信道\",\"accessMode\":\"rw\","
"\"required\":true},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\",\"accessMode\":\"rw\",\"required\":"
"true},{\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Tx_Rate_Name\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\","
"\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":"
"{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":"
"\"RGB调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"明度\"}],"
"\"type\":\"struct\"},\"name\":\"HSV调色\",\"accessMode\":\"rw\","
"\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":"
"\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},"
"\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":"
"\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"明暗度\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":"
"\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":"
"\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\","
"\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\",\"step\":\"0.01\"}"
",\"type\":\"double\"},\"name\":\"Propertypoint_Name\",\"accessMode\":\"rw\","
"\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":"
"\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{"
"\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{"
"\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],"
"\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":"
"\"故障上报\",\"type\":\"error\",\"required\":true}]}";

View File

@@ -0,0 +1,254 @@
/*
* please modify this string follow as product's TSL.
*/
static const char TSL_STRING[] =
"{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/"
"schema.json\",\"profile\":{\"productKey\":\"a1X2bEnP82z\"},\"services\":[{"
"\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":"
"true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":"
"\"WIFI_Band\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{"
"\"specs\":{\"min\":\"-127\",\"unitName\":\"\",\"max\":\"-1\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_"
"BSSID\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},"
"\"name\":\"热点BSSID\"},{\"identifier\":\"WIFI_Channel\",\"dataType\":{"
"\"specs\":{\"min\":\"1\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"\",\"max\":"
"\"127\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信噪比\"},{"
"\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_"
"Name\"},{\"identifier\":\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Rx_Rate_Name\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":"
"\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},"
"{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{"
"\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":"
"\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":"
"\"\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":"
"\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0."
"01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":"
"\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":"
"{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"亮度\"}],"
"\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"WorkMode\","
"\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":"
"\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":"
"\"工作模式\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{"
"\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{"
"\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"ColorTemperature\","
"\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2000\",\"unitName\":"
"\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"冷暖色温\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":"
"{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\"}"
",{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-"
"100\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"Propertypoint_Name\"}],\"identifier\":\"get\",\"inputData\":["
"\"LightSwitch\",\"WIFI_Band\",\"WiFI_RSSI\",\"WIFI_AP_BSSID\",\"WIFI_"
"Channel\",\"WiFI_SNR\",\"WIFI_Tx_Rate\",\"WIFI_Rx_Rate\",\"RGBColor\","
"\"HSVColor\",\"HSLColor\",\"WorkMode\",\"NightLightSwitch\",\"Brightness\","
"\"ColorTemperature\",\"PropertyCharacter\",\"Propertypoint\"],\"method\":"
"\"thing.service.property.get\",\"name\":\"get\",\"required\":true,"
"\"callType\":\"async\",\"desc\":\"属性获取\"}],\"properties\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_Band\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"频段\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WiFI_RSSI\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"\",\"max\":\"-"
"1\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信号强度\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WIFI_Channel\","
"\"dataType\":{\"specs\":{\"min\":\"1\",\"unitName\":\"\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信道\",\"accessMode\":\"rw\","
"\"required\":true},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\",\"accessMode\":\"rw\",\"required\":"
"true},{\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Tx_Rate_Name\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\","
"\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":"
"{\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":"
"\"RGB调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"明度\"}],"
"\"type\":\"struct\"},\"name\":\"HSV调色\",\"accessMode\":\"rw\","
"\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":"
"\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},"
"\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":"
"\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"明暗度\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":"
"\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":"
"\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\","
"\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\",\"step\":\"0.01\"}"
",\"type\":\"double\"},\"name\":\"Propertypoint_Name\",\"accessMode\":\"rw\","
"\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":"
"\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{"
"\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{"
"\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],"
"\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":"
"\"故障上报\",\"type\":\"error\",\"required\":true}]}";

View File

@@ -0,0 +1,517 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "infra_config.h"
#ifdef DEPRECATED_LINKKIT
#include "gateway.c"
#else
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "cJSON.h"
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_compat.h"
#include "infra_log.h"
#include "infra_compat.h"
#include "infra_log.h"
#include "dev_model_api.h"
#include "dm_wrapper.h"
#ifdef LINKKIT_GATEWAY_TEST_CMD
#include "simulate_subdev/testcmd.h"
#endif
#if defined(OTA_ENABLED) && defined(BUILD_AOS)
#include "ota_service.h"
#endif
char PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char PRODUCT_SECRET[IOTX_PRODUCT_SECRET_LEN + 1] = {0};
char DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
char DEVICE_SECRET[IOTX_DEVICE_SECRET_LEN + 1] = {0};
#define USER_EXAMPLE_YIELD_TIMEOUT_MS (200)
void HAL_Printf(const char *fmt, ...);
#define EXAMPLE_TRACE(...) \
do { \
HAL_Printf("\033[1;32;40m%s.%d: ", __func__, __LINE__); \
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\033[0m\r\n"); \
} while (0)
#define EXAMPLE_SUBDEV_ADD_NUM 3
#define EXAMPLE_SUBDEV_MAX_NUM 20
const iotx_linkkit_dev_meta_info_t subdevArr[EXAMPLE_SUBDEV_MAX_NUM] = {
{
"a13Npv1vjZ4",
"PKbZL7baK8pBso94",
"example_sub1",
"eglNFNJiRuR0yncB9RP05sSTY4FrUIoe"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_02",
"jFsErM3uA7UfbS6J0hm0QaEXsQbmO6Pa"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_03",
"MjWMvCLBcuZyqUswryBbgypN8uOgJGVD"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_04",
"DXbcbpxepIyYm3BiS0ICdBou4uWPfP6L"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_05",
"VKuVZfcz3umcoR3WhOp4cu1p2dyTQGq1"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_06",
"QTobiz1BdGW5XNgLGIgNSylH0btVvvGS"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_07",
"IX7ol50rRS2uP8V74jt0DKfmYn8iC6h1"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_08",
"sbFxx62evXVoVgJ5gL2oCLcz1pX9d6K2"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_09",
"S0CpOl54GZxEO7Gz5DWQa5YxgUMfT4xA"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_10",
"MowJJjiNIkTdUcX5fCNUDu39Yz02KADL"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_11",
"BrJNdAihVznMWTpdRfe8HIiI95ubSYdN"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_12",
"Yd3ZHK8D6cAKKRQb9rUevCfwPf7atoQ4"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_13",
"d3HKvu2eBR5ytcgDaBEt0gpvJZlu9W0g"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_14",
"qAJYUpQ1tGmAINQBzMiZwwbyjY6YXDGc"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_15",
"GxgVknnAmUmwjjdHJf9dbEBDoqyDaUfp"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_16",
"9d17Sv05j1XeTYOs80UBpBU1OYTTJ58X"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_17",
"FTUm4HAfhZ5wH2u0pPn7PWcCLGDrgEfn"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_18",
"mF7a2ptc3PRi7jWLE92t0GElhGdPnAe3"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_19",
"Vrh8HuNvu3jtTEwSzulAjTqgOseAsVgz"
},
{
"a1YRfb9bepk",
"PKbZL7baK8pBso94",
"test_20",
"8Wxrxnjch6SW0s2HR5JkIBtgjt3BOUo7"
}
};
typedef struct {
int auto_add_subdev;
int master_devid;
int cloud_connected;
int master_initialized;
int subdev_index;
int permit_join;
void *g_user_dispatch_thread;
int g_user_dispatch_thread_running;
} user_example_ctx_t;
static user_example_ctx_t g_user_example_ctx;
void *example_malloc(size_t size)
{
return HAL_Malloc(size);
}
void example_free(void *ptr)
{
HAL_Free(ptr);
}
static user_example_ctx_t *user_example_get_ctx(void)
{
return &g_user_example_ctx;
}
static int user_connected_event_handler(void)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Cloud Connected");
user_example_ctx->cloud_connected = 1;
return 0;
}
static int user_disconnected_event_handler(void)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Cloud Disconnected");
user_example_ctx->cloud_connected = 0;
return 0;
}
static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);
res = IOT_Linkkit_Report(devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)request, request_len);
EXAMPLE_TRACE("Post Property Message ID: %d", res);
return 0;
}
static int user_report_reply_event_handler(const int devid, const int msgid, const int code, const char *reply,
const int reply_len)
{
const char *reply_value = (reply == NULL) ? ("NULL") : (reply);
const int reply_value_len = (reply_len == 0) ? (strlen("NULL")) : (reply_len);
EXAMPLE_TRACE("Message Post Reply Received, Devid: %d, Message ID: %d, Code: %d, Reply: %.*s", devid, msgid, code,
reply_value_len,
reply_value);
return 0;
}
static int user_timestamp_reply_event_handler(const char *timestamp)
{
EXAMPLE_TRACE("Current Timestamp: %s", timestamp);
return 0;
}
static int user_initialized(const int devid)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Device Initialized, Devid: %d", devid);
if (user_example_ctx->master_devid == devid) {
user_example_ctx->master_initialized = 1;
user_example_ctx->subdev_index++;
}
return 0;
}
static uint64_t user_update_sec(void)
{
static uint64_t time_start_ms = 0;
if (time_start_ms == 0) {
time_start_ms = HAL_UptimeMs();
}
return (HAL_UptimeMs() - time_start_ms) / 1000;
}
void user_post_property(void)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *property_payload = "{\"Counter\":1}";
res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)property_payload, strlen(property_payload));
EXAMPLE_TRACE("Post Property Message ID: %d", res);
}
void user_deviceinfo_update(void)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *device_info_update = "[{\"attrKey\":\"abc\",\"attrValue\":\"hello,world\"}]";
res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_DEVICEINFO_UPDATE,
(unsigned char *)device_info_update, strlen(device_info_update));
EXAMPLE_TRACE("Device Info Update Message ID: %d", res);
}
void user_deviceinfo_delete(void)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *device_info_delete = "[{\"attrKey\":\"abc\"}]";
res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_DEVICEINFO_DELETE,
(unsigned char *)device_info_delete, strlen(device_info_delete));
EXAMPLE_TRACE("Device Info Delete Message ID: %d", res);
}
static int user_master_dev_available(void)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
if (user_example_ctx->cloud_connected && user_example_ctx->master_initialized) {
return 1;
}
return 0;
}
static int example_add_subdev(iotx_linkkit_dev_meta_info_t *meta_info)
{
int res = 0, devid = -1;
devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_SLAVE, meta_info);
if (devid == FAIL_RETURN) {
EXAMPLE_TRACE("subdev open Failed\n");
return FAIL_RETURN;
}
EXAMPLE_TRACE("subdev open susseed, devid = %d\n", devid);
res = IOT_Linkkit_Connect(devid);
if (res == FAIL_RETURN) {
EXAMPLE_TRACE("subdev connect Failed\n");
return res;
}
EXAMPLE_TRACE("subdev connect success: devid = %d\n", devid);
res = IOT_Linkkit_Report(devid, ITM_MSG_LOGIN, NULL, 0);
if (res == FAIL_RETURN) {
EXAMPLE_TRACE("subdev login Failed\n");
return res;
}
EXAMPLE_TRACE("subdev login success: devid = %d\n", devid);
return res;
}
int user_permit_join_event_handler(const char *product_key, const int time)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Product Key: %s, Time: %d", product_key, time);
user_example_ctx->permit_join = 1;
return 0;
}
void *user_dispatch_yield(void *args)
{
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
while (user_example_ctx->g_user_dispatch_thread_running) {
IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS);
}
return NULL;
}
static int max_running_seconds = 0;
int main(int argc, char **argv)
{
int res = 0;
uint64_t time_prev_sec = 0, time_now_sec = 0, time_begin_sec = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
iotx_linkkit_dev_meta_info_t master_meta_info;
int domain_type = 0;
int dynamic_register = 0;
int post_event_reply = 0;
memset(user_example_ctx, 0, sizeof(user_example_ctx_t));
#if defined(__UBUNTU_SDK_DEMO__)
if (argc > 1) {
int tmp = atoi(argv[1]);
if (tmp >= 60) {
max_running_seconds = tmp;
EXAMPLE_TRACE("set [max_running_seconds] = %d seconds\n", max_running_seconds);
}
}
if (argc > 2) {
if (strlen("auto") == strlen(argv[2]) &&
memcmp("auto", argv[2], strlen(argv[2])) == 0) {
user_example_ctx->auto_add_subdev = 1;
}
}
#endif
HAL_GetProductKey(PRODUCT_KEY);
HAL_GetProductSecret(PRODUCT_SECRET);
HAL_GetDeviceName(DEVICE_NAME);
HAL_GetDeviceSecret(DEVICE_SECRET);
user_example_ctx->subdev_index = -1;
IOT_SetLogLevel(IOT_LOG_DEBUG);
/* Register Callback */
IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler);
IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler);
IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);
IOT_RegisterCallback(ITE_PERMIT_JOIN, user_permit_join_event_handler);
memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));
memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY));
memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));
memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME));
memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));
/* Create Master Device Resources */
user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
if (user_example_ctx->master_devid < 0) {
EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n");
return -1;
}
/* Choose Login Server */
domain_type = IOTX_CLOUD_REGION_SHANGHAI;
IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);
/* Choose Login Method */
dynamic_register = 0;
IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);
/* Choose Whether You Need Post Property/Event Reply */
post_event_reply = 0;
IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_event_reply);
/* Start Connect Aliyun Server */
do {
res = IOT_Linkkit_Connect(user_example_ctx->master_devid);
if (res < 0) {
EXAMPLE_TRACE("IOT_Linkkit_Connect failed, retry after 5s...\n");
HAL_SleepMs(5000);
}
} while (res < 0);
user_example_ctx->g_user_dispatch_thread_running = 1;
res = HAL_ThreadCreate(&user_example_ctx->g_user_dispatch_thread, user_dispatch_yield, NULL, NULL, NULL);
if (res < 0) {
EXAMPLE_TRACE("HAL_ThreadCreate Failed\n");
IOT_Linkkit_Close(user_example_ctx->master_devid);
return -1;
}
time_begin_sec = user_update_sec();
while (1) {
HAL_SleepMs(200);
time_now_sec = user_update_sec();
if (time_prev_sec == time_now_sec) {
continue;
}
if (max_running_seconds && (time_now_sec - time_begin_sec > max_running_seconds)) {
EXAMPLE_TRACE("Example Run for Over %d Seconds, Break Loop!\n", max_running_seconds);
break;
}
/* Add subdev */
if (user_example_ctx->master_initialized && user_example_ctx->subdev_index >= 0 &&
(user_example_ctx->auto_add_subdev == 1 || user_example_ctx->permit_join != 0)) {
if (user_example_ctx->subdev_index < EXAMPLE_SUBDEV_ADD_NUM) {
/* Add next subdev */
if (example_add_subdev((iotx_linkkit_dev_meta_info_t *)&subdevArr[user_example_ctx->subdev_index]) == SUCCESS_RETURN) {
EXAMPLE_TRACE("subdev %s add succeed", subdevArr[user_example_ctx->subdev_index].device_name);
} else {
EXAMPLE_TRACE("subdev %s add failed", subdevArr[user_example_ctx->subdev_index].device_name);
}
user_example_ctx->subdev_index++;
user_example_ctx->permit_join = 0;
}
}
/* Post Proprety Example */
if (time_now_sec % 11 == 0 && user_master_dev_available()) {
/* user_post_property(); */
}
/* Device Info Update Example */
if (time_now_sec % 23 == 0 && user_master_dev_available()) {
/* user_deviceinfo_update(); */
}
/* Device Info Delete Example */
if (time_now_sec % 29 == 0 && user_master_dev_available()) {
/* user_deviceinfo_delete(); */
}
time_prev_sec = time_now_sec;
}
user_example_ctx->g_user_dispatch_thread_running = 0;
IOT_Linkkit_Close(user_example_ctx->master_devid);
HAL_ThreadDelete(user_example_ctx->g_user_dispatch_thread);
IOT_DumpMemoryStats(IOT_LOG_DEBUG);
IOT_SetLogLevel(IOT_LOG_NONE);
return 0;
}
#endif

View File

@@ -0,0 +1,362 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include "infra_config.h"
void HAL_Printf(const char *fmt, ...);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
#ifdef DEPRECATED_LINKKIT
#include "solo.c"
#else
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_compat.h"
#include "infra_compat.h"
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#endif
#include "dev_model_api.h"
#include "dm_wrapper.h"
#include "cJSON.h"
#ifdef ATM_ENABLED
#include "at_api.h"
#endif
#define EXAMPLE_TRACE(...) \
do { \
HAL_Printf("\033[1;32;40m%s.%d: ", __func__, __LINE__); \
HAL_Printf(__VA_ARGS__); \
HAL_Printf("\033[0m\r\n"); \
} while (0)
#define EXAMPLE_MASTER_DEVID (0)
#define EXAMPLE_YIELD_TIMEOUT_MS (200)
typedef struct {
int master_devid;
int cloud_connected;
int master_initialized;
} user_example_ctx_t;
/**
* These PRODUCT_KEY|PRODUCT_SECRET|DEVICE_NAME|DEVICE_SECRET are listed for demo only
*
* When you created your own devices on iot.console.com, you SHOULD replace them with what you got from console
*
*/
char PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char PRODUCT_SECRET[IOTX_PRODUCT_SECRET_LEN + 1] = {0};
char DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
char DEVICE_SECRET[IOTX_DEVICE_SECRET_LEN + 1] = {0};
static user_example_ctx_t g_user_example_ctx;
/** cloud connected event callback */
static int user_connected_event_handler(void)
{
EXAMPLE_TRACE("Cloud Connected");
g_user_example_ctx.cloud_connected = 1;
return 0;
}
/** cloud disconnected event callback */
static int user_disconnected_event_handler(void)
{
EXAMPLE_TRACE("Cloud Disconnected");
g_user_example_ctx.cloud_connected = 0;
return 0;
}
/* device initialized event callback */
static int user_initialized(const int devid)
{
EXAMPLE_TRACE("Device Initialized");
g_user_example_ctx.master_initialized = 1;
return 0;
}
/** recv property post response message from cloud **/
static int user_report_reply_event_handler(const int devid, const int msgid, const int code, const char *reply,
const int reply_len)
{
EXAMPLE_TRACE("Message Post Reply Received, Message ID: %d, Code: %d, Reply: %.*s", msgid, code,
reply_len,
(reply == NULL)? ("NULL") : (reply));
return 0;
}
/** recv event post response message from cloud **/
static int user_trigger_event_reply_event_handler(const int devid, const int msgid, const int code, const char *eventid,
const int eventid_len, const char *message, const int message_len)
{
EXAMPLE_TRACE("Trigger Event Reply Received, Message ID: %d, Code: %d, EventID: %.*s, Message: %.*s",
msgid, code,
eventid_len,
eventid, message_len, message);
return 0;
}
/** recv property setting message from cloud **/
static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
int res = 0;
EXAMPLE_TRACE("Property Set Received, Request: %s", request);
res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY,
(unsigned char *)request, request_len);
EXAMPLE_TRACE("Post Property Message ID: %d", res);
return 0;
}
static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len,
const char *request, const int request_len,
char **response, int *response_len)
{
int add_result = 0;
cJSON *root = NULL, *item_number_a = NULL, *item_number_b = NULL;
const char *response_fmt = "{\"Result\": %d}";
EXAMPLE_TRACE("Service Request Received, Service ID: %.*s, Payload: %s", serviceid_len, serviceid, request);
/* Parse Root */
root = cJSON_Parse(request);
if (root == NULL || !cJSON_IsObject(root)) {
EXAMPLE_TRACE("JSON Parse Error");
return -1;
}
if (strlen("Operation_Service") == serviceid_len && memcmp("Operation_Service", serviceid, serviceid_len) == 0) {
/* Parse NumberA */
item_number_a = cJSON_GetObjectItem(root, "NumberA");
if (item_number_a == NULL || !cJSON_IsNumber(item_number_a)) {
cJSON_Delete(root);
return -1;
}
EXAMPLE_TRACE("NumberA = %d", item_number_a->valueint);
/* Parse NumberB */
item_number_b = cJSON_GetObjectItem(root, "NumberB");
if (item_number_b == NULL || !cJSON_IsNumber(item_number_b)) {
cJSON_Delete(root);
return -1;
}
EXAMPLE_TRACE("NumberB = %d", item_number_b->valueint);
add_result = item_number_a->valueint + item_number_b->valueint;
/* Send Service Response To Cloud */
*response_len = strlen(response_fmt) + 10 + 1;
*response = (char *)HAL_Malloc(*response_len);
if (*response == NULL) {
EXAMPLE_TRACE("Memory Not Enough");
return -1;
}
memset(*response, 0, *response_len);
HAL_Snprintf(*response, *response_len, response_fmt, add_result);
*response_len = strlen(*response);
}
cJSON_Delete(root);
return 0;
}
static int user_timestamp_reply_event_handler(const char *timestamp)
{
EXAMPLE_TRACE("Current Timestamp: %s", timestamp);
return 0;
}
/** fota event handler **/
static int user_fota_event_handler(int type, const char *version)
{
char buffer[128] = {0};
int buffer_length = 128;
/* 0 - new firmware exist, query the new firmware */
if (type == 0) {
EXAMPLE_TRACE("New Firmware Version: %s", version);
IOT_Linkkit_Query(EXAMPLE_MASTER_DEVID, ITM_MSG_QUERY_FOTA_DATA, (unsigned char *)buffer, buffer_length);
}
return 0;
}
/* cota event handler */
static int user_cota_event_handler(int type, const char *config_id, int config_size, const char *get_type,
const char *sign, const char *sign_method, const char *url)
{
char buffer[128] = {0};
int buffer_length = 128;
/* type = 0, new config exist, query the new config */
if (type == 0) {
EXAMPLE_TRACE("New Config ID: %s", config_id);
EXAMPLE_TRACE("New Config Size: %d", config_size);
EXAMPLE_TRACE("New Config Type: %s", get_type);
EXAMPLE_TRACE("New Config Sign: %s", sign);
EXAMPLE_TRACE("New Config Sign Method: %s", sign_method);
EXAMPLE_TRACE("New Config URL: %s", url);
IOT_Linkkit_Query(EXAMPLE_MASTER_DEVID, ITM_MSG_QUERY_COTA_DATA, (unsigned char *)buffer, buffer_length);
}
return 0;
}
void user_post_property(void)
{
static int cnt = 0;
int res = 0;
char property_payload[30] = {0};
HAL_Snprintf(property_payload, sizeof(property_payload), "{\"Counter\": %d}", cnt++);
res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY,
(unsigned char *)property_payload, strlen(property_payload));
EXAMPLE_TRACE("Post Property Message ID: %d", res);
}
void user_post_event(void)
{
int res = 0;
char *event_id = "HardwareError";
char *event_payload = "{\"ErrorCode\": 0}";
res = IOT_Linkkit_TriggerEvent(EXAMPLE_MASTER_DEVID, event_id, strlen(event_id),
event_payload, strlen(event_payload));
EXAMPLE_TRACE("Post Event Message ID: %d", res);
}
void user_deviceinfo_update(void)
{
int res = 0;
char *device_info_update = "[{\"attrKey\":\"abc\",\"attrValue\":\"hello,world\"}]";
res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_DEVICEINFO_UPDATE,
(unsigned char *)device_info_update, strlen(device_info_update));
EXAMPLE_TRACE("Device Info Update Message ID: %d", res);
}
void user_deviceinfo_delete(void)
{
int res = 0;
char *device_info_delete = "[{\"attrKey\":\"abc\"}]";
res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_DEVICEINFO_DELETE,
(unsigned char *)device_info_delete, strlen(device_info_delete));
EXAMPLE_TRACE("Device Info Delete Message ID: %d", res);
}
int main(int argc, char **argv)
{
int res = 0;
int cnt = 0;
iotx_linkkit_dev_meta_info_t master_meta_info;
int domain_type = 0, dynamic_register = 0, post_reply_need = 0;
#ifdef ATM_ENABLED
if (IOT_ATM_Init() < 0) {
EXAMPLE_TRACE("IOT ATM init failed!\n");
return -1;
}
#endif
memset(&g_user_example_ctx, 0, sizeof(user_example_ctx_t));
HAL_GetProductKey(PRODUCT_KEY);
HAL_GetProductSecret(PRODUCT_SECRET);
HAL_GetDeviceName(DEVICE_NAME);
HAL_GetDeviceSecret(DEVICE_SECRET);
memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));
memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY));
memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));
memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME));
memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));
IOT_SetLogLevel(IOT_LOG_DEBUG);
/* Register Callback */
IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);
IOT_RegisterCallback(ITE_SERVICE_REQUEST, user_service_request_event_handler);
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler);
IOT_RegisterCallback(ITE_TRIGGER_EVENT_REPLY, user_trigger_event_reply_event_handler);
IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler);
IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);
IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler);
IOT_RegisterCallback(ITE_COTA, user_cota_event_handler);
domain_type = IOTX_CLOUD_REGION_SHANGHAI;
IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);
/* Choose Login Method */
dynamic_register = 0;
IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);
/* post reply doesn't need */
post_reply_need = 1;
IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_reply_need);
/* Create Master Device Resources */
g_user_example_ctx.master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
if (g_user_example_ctx.master_devid < 0) {
EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n");
return -1;
}
/* Start Connect Aliyun Server */
do {
res = IOT_Linkkit_Connect(g_user_example_ctx.master_devid);
if (res < 0) {
EXAMPLE_TRACE("IOT_Linkkit_Connect failed, retry after 5s...\n");
HAL_SleepMs(5000);
}
} while (res < 0);
while (1) {
IOT_Linkkit_Yield(EXAMPLE_YIELD_TIMEOUT_MS);
/* Post Proprety Example */
if ((cnt % 2) == 0) {
user_post_property();
}
/* Post Event Example */
if ((cnt % 10) == 0) {
user_post_event();
}
if (++cnt > 3600) {
break;
}
HAL_SleepMs(1000);
}
IOT_Linkkit_Close(g_user_example_ctx.master_devid);
IOT_DumpMemoryStats(IOT_LOG_DEBUG);
IOT_SetLogLevel(IOT_LOG_NONE);
return 0;
}
#endif

View File

@@ -0,0 +1,201 @@
{
"schema":"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json",
"profile":{
"productKey":"a1pkcDf0Xv0"
},
"services":[
{
"outputData":[
],
"identifier":"set",
"inputData":[
{
"identifier":"PowerSwitch",
"dataType":{
"specs":{
"0":"关闭",
"1":"开启"
},
"type":"bool"
},
"name":"电源开关"
}
],
"method":"thing.service.property.set",
"name":"set",
"required":true,
"callType":"async",
"desc":"属性设置"
},
{
"outputData":[
{
"identifier":"PowerSwitch",
"dataType":{
"specs":{
"0":"关闭",
"1":"开启"
},
"type":"bool"
},
"name":"电源开关"
},
{
"identifier":"Counter",
"dataType":{
"specs":{
"min":"0",
"max":"99999",
"step":"1"
},
"type":"int"
},
"name":"计数器演示"
}
],
"identifier":"get",
"inputData":[
"PowerSwitch",
"Counter"
],
"method":"thing.service.property.get",
"name":"get",
"required":true,
"callType":"async",
"desc":"属性获取"
},
{
"outputData":[
{
"identifier":"Result",
"dataType":{
"specs":{
"min":"1",
"max":"10000000",
"step":"1"
},
"type":"int"
},
"name":"计算结果"
}
],
"identifier":"Operation_Service",
"inputData":[
{
"identifier":"NumberA",
"dataType":{
"specs":{
"min":"0",
"max":"1000000",
"step":"1"
},
"type":"int"
},
"name":"数值A"
},
{
"identifier":"NumberB",
"dataType":{
"specs":{
"min":"1",
"max":"1000000",
"step":"1"
},
"type":"int"
},
"name":"数值B"
}
],
"method":"thing.service.Operation_Service",
"name":"数值计算服务演示",
"required":false,
"callType":"sync"
}
],
"properties":[
{
"identifier":"PowerSwitch",
"dataType":{
"specs":{
"0":"关闭",
"1":"开启"
},
"type":"bool"
},
"name":"电源开关",
"accessMode":"rw",
"required":false
},
{
"identifier":"Counter",
"dataType":{
"specs":{
"min":"0",
"max":"99999",
"step":"1"
},
"type":"int"
},
"name":"计数器演示",
"accessMode":"r",
"required":true
}
],
"events":[
{
"outputData":[
{
"identifier":"PowerSwitch",
"dataType":{
"specs":{
"0":"关闭",
"1":"开启"
},
"type":"bool"
},
"name":"电源开关"
},
{
"identifier":"Counter",
"dataType":{
"specs":{
"min":"0",
"max":"99999",
"step":"1"
},
"type":"int"
},
"name":"计数器演示"
}
],
"identifier":"post",
"method":"thing.event.property.post",
"name":"post",
"type":"info",
"required":true,
"desc":"属性上报"
},
{
"outputData":[
{
"identifier":"ErrorCode",
"dataType":{
"specs":{
"0":"故障类型0",
"1":"故障类型1",
"2":"故障类型2"
},
"type":"enum"
},
"name":"故障编号"
}
],
"identifier":"HardwareError",
"method":"thing.event.HardwareError.post",
"name":"故障事件演示",
"type":"error",
"required":false
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
LIBA_TARGET := libiot_alink.a
HDR_REFS += src/infra
HDR_REFS += src/mqtt
HDR_REFS += src/dev_sign
DEPENDS += wrappers
LDFLAGS += -liot_sdk -liot_hal -liot_tls
LIB_SRCS_PATTERN := *.c server/*.c client/*.c deprecated/*.c
LIB_SRCS_EXCLUDE := examples/linkkit_example_solo.c examples/cJSON.c
SRCS_linkkit-example-solo := examples/linkkit_example_solo.c examples/cJSON.c
LIB_SRCS_EXCLUDE += examples/linkkit_example_gateway.c examples/cJSON.c
SRCS_linkkit-example-gateway := examples/linkkit_example_gateway.c examples/cJSON.c
$(call Append_Conditional, LIB_SRCS_PATTERN, alcs/*.c, ALCS_ENABLED)
ifneq (,$(filter -DDEPRECATED_LINKKIT,$(CFLAGS)))
$(call Append_Conditional, TARGET, linkkit-example-solo, DEVICE_MODEL_ENABLED, BUILD_AOS NO_EXECUTABLES DEVICE_MODEL_GATEWAY)
$(call Append_Conditional, TARGET, linkkit-example-gateway, DEVICE_MODEL_ENABLED DEVICE_MODEL_GATEWAY, BUILD_AOS NO_EXECUTABLES)
else
$(call Append_Conditional, TARGET, linkkit-example-solo, DEVICE_MODEL_ENABLED, BUILD_AOS NO_EXECUTABLES)
$(call Append_Conditional, TARGET, linkkit-example-gateway, DEVICE_MODEL_GATEWAY, BUILD_AOS NO_EXECUTABLES)
endif

View File

@@ -0,0 +1,310 @@
#include "iotx_cm_internal.h"
#if defined(MQTT_COMM_ENABLED) || defined(MAL_ENABLED)
#include "iotx_cm_mqtt.h"
#endif
#ifdef COAP_COMM_ENABLED
#include "iotx_cm_coap.h"
#endif
static void *fd_lock = NULL;
static iotx_cm_connection_t *_cm_fd[CM_MAX_FD_NUM] = {NULL};
static int _get_fd(iotx_cm_connection_t *handle);
static int _recycle_fd(int fd);
static int inline _fd_is_valid(int fd);
static int inited_conn_num = 0;
#ifdef DEVICE_MODEL_GATEWAY
static void *_iotx_cm_yield_thread_func(void *params);
static void *yield_thread = NULL;
static int yield_task_leave = 1;
#endif
const char ERR_INVALID_PARAMS[] = "invalid parameter";
int iotx_cm_open(iotx_cm_init_param_t *params)
{
int fd;
iotx_cm_connection_t *connection = NULL;
switch (params->protocol_type) {
case IOTX_CM_PROTOCOL_TYPE_MQTT:
#if defined(MQTT_COMM_ENABLED) || defined(MAL_ENABLED)
connection = iotx_cm_open_mqtt(params);
#endif
break;
case IOTX_CM_PROTOCOL_TYPE_COAP:
#ifdef COAP_COMM_ENABLED
connection = iotx_cm_open_coap(params);
#endif
break;
default:
break;
}
if (connection == NULL) {
cm_err("cm opon failed");
return -1;
}
fd = _get_fd(connection);
if (fd < 0) {
cm_err("get fd failed");
connection->close_func();
return -1;
}
connection->fd = fd;
return fd;
}
int iotx_cm_connect(int fd, uint32_t timeout)
{
iotx_cm_connect_fp connect_func;
int ret;
if (_fd_is_valid(fd) == -1) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
HAL_MutexLock(fd_lock);
connect_func = _cm_fd[fd]->connect_func;
HAL_MutexUnlock(fd_lock);
iotx_event_post(IOTX_CONN_CLOUD);
ret = connect_func(timeout);
if (ret == 0) {
inited_conn_num++;
if (inited_conn_num == 1) {
#ifdef DEVICE_MODEL_GATEWAY
int stack_used;
hal_os_thread_param_t task_parms = {0};
task_parms.stack_size = 6144;
task_parms.name = "cm_yield";
ret = HAL_ThreadCreate(&yield_thread, _iotx_cm_yield_thread_func, NULL,
&task_parms, &stack_used);
if (ret < 0) {
inited_conn_num--;
}
#endif
}
iotx_event_post(IOTX_CONN_CLOUD_SUC);
} else {
iotx_event_post(IOTX_CONN_CLOUD_FAIL);
}
return ret;
}
static int _iotx_cm_yield(int fd, unsigned int timeout)
{
iotx_cm_yield_fp yield_func;
if (fd_lock == NULL) {
return NULL_VALUE_ERROR;
}
if (fd == -1) {
int i;
for (i = 0; i < CM_MAX_FD_NUM; i++) {
yield_func = NULL;
HAL_MutexLock(fd_lock);
if (_cm_fd[i] != NULL) {
yield_func = _cm_fd[i]->yield_func;
}
HAL_MutexUnlock(fd_lock);
if (yield_func != NULL) {
yield_func(timeout);
}
}
return 0;
}
if (_fd_is_valid(fd) == -1) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
HAL_MutexLock(fd_lock);
yield_func = _cm_fd[fd]->yield_func;
HAL_MutexUnlock(fd_lock);
return yield_func(timeout);
}
#ifdef DEVICE_MODEL_GATEWAY
static void *_iotx_cm_yield_thread_func(void *params)
{
yield_task_leave = 0;
while (inited_conn_num > 0) {
_iotx_cm_yield(-1, CM_DEFAULT_YIELD_TIMEOUT);
}
yield_task_leave = 1;
return NULL;
}
#endif
int iotx_cm_yield(int fd, unsigned int timeout)
{
#ifdef DEVICE_MODEL_GATEWAY
return 0;
#else
return _iotx_cm_yield(fd, timeout);
#endif
}
int iotx_cm_sub(int fd, iotx_cm_ext_params_t *ext, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext)
{
iotx_cm_sub_fp sub_func;
if (_fd_is_valid(fd) == -1) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
HAL_MutexLock(fd_lock);
sub_func = _cm_fd[fd]->sub_func;
HAL_MutexUnlock(fd_lock);
return sub_func(ext, topic, topic_handle_func, pcontext);
}
int iotx_cm_unsub(int fd, const char *topic)
{
iotx_cm_unsub_fp unsub_func;
if (_fd_is_valid(fd) == -1) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
HAL_MutexLock(fd_lock);
unsub_func = _cm_fd[fd]->unsub_func;
HAL_MutexUnlock(fd_lock);
return unsub_func(topic);
}
int iotx_cm_pub(int fd, iotx_cm_ext_params_t *ext, const char *topic, const char *payload, unsigned int payload_len)
{
iotx_cm_pub_fp pub_func;
if (_fd_is_valid(fd) == -1) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
HAL_MutexLock(fd_lock);
pub_func = _cm_fd[fd]->pub_func;
HAL_MutexUnlock(fd_lock);
return pub_func(ext, topic, payload, payload_len);
}
int iotx_cm_close(int fd)
{
iotx_cm_close_fp close_func;
if (_fd_is_valid(fd) != 0) {
cm_err(ERR_INVALID_PARAMS);
return -1;
}
if (inited_conn_num > 0) {
inited_conn_num--;
}
if (inited_conn_num == 0) {
#ifdef DEVICE_MODEL_GATEWAY
while (!yield_task_leave) {
HAL_SleepMs(10);
}
if (yield_thread != NULL) {
HAL_ThreadDelete(yield_thread);
}
#endif
}
HAL_MutexLock(fd_lock);
close_func = _cm_fd[fd]->close_func;
HAL_MutexUnlock(fd_lock);
if (close_func() != 0) {
return -1;
}
if (_recycle_fd(fd) != 0) {
return -1;
}
if (inited_conn_num == 0) {
if (fd_lock != NULL) {
HAL_MutexDestroy(fd_lock);
fd_lock = NULL;
}
}
return 0;
}
static int inline _fd_is_valid(int fd)
{
int ret;
if (fd_lock == NULL) {
return NULL_VALUE_ERROR;
}
HAL_MutexLock(fd_lock);
ret = (fd >= 0 && fd < CM_MAX_FD_NUM && _cm_fd[fd] != NULL) ? 0 : -1;
HAL_MutexUnlock(fd_lock);
return ret;
}
static int _recycle_fd(int fd)
{
if (fd_lock == NULL) {
fd_lock = HAL_MutexCreate();
if (fd_lock == NULL) {
return -1;
}
}
if (fd < 0 || fd > CM_MAX_FD_NUM - 1) {
return -1;
}
HAL_MutexLock(fd_lock);
_cm_fd[fd] = NULL;
HAL_MutexUnlock(fd_lock);
return 0;
}
static int _get_fd(iotx_cm_connection_t *handle)
{
int i;
if (handle == NULL) {
return NULL_VALUE_ERROR;
}
if (fd_lock == NULL) {
fd_lock = HAL_MutexCreate();
if (fd_lock == NULL) {
return -1;
}
}
HAL_MutexLock(fd_lock);
for (i = 0; i < CM_MAX_FD_NUM; i++) {
if (_cm_fd[i] == NULL) {
_cm_fd[i] = handle;
HAL_MutexUnlock(fd_lock);
return i;
}
}
HAL_MutexUnlock(fd_lock);
cm_err("cm fd reached the limit");
return -1;
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_CM_H_
#define _IOTX_CM_H_
#include "infra_types.h"
#define CM_MAX_FD_NUM 3
#define CM_DEFAULT_YIELD_TIMEOUT 200
/* message confirmation type */
typedef enum {
/* non ACK */
/* MQTT: QoS is 0 */
/* CoAP: NON */
/* default */
IOTX_CM_MESSAGE_NO_ACK,
/* need ACK */
/* MQTT: QoS is 1 */
/* CoAP: CON */
IOTX_CM_MESSAGE_NEED_ACK,
/* non ACK */
/* MQTT: QoS is 3 */
/* CoAP: NONE*/
IOTX_CM_MESSAGE_SUB_LOCAL,
/* Maximum number of ack type */
IOTX_CM_MESSAGE_ACK_MAX
} iotx_cm_ack_types_t;
/* message confirmation type */
typedef enum {
/* non ACK */
/* MQTT: QoS is 0 */
/* CoAP: NON */
/* default */
IOTX_CM_ASYNC,
/* need ACK */
/* MQTT: QoS is 1 */
/* CoAP: CON */
IOTX_CM_SYNC,
/* Maximum number of ack type */
IOTX_CM_SYNC_MAX
} iotx_cm_sync_mode_types_t;
/* protocol type */
typedef enum IOTX_CM_PROTOCOL_TYPES {
/* MQTT */
IOTX_CM_PROTOCOL_TYPE_MQTT = 1,
/* COAP */
IOTX_CM_PROTOCOL_TYPE_COAP = 2,
/* HTTP */
IOTX_CM_PROTOCOL_TYPE_HTTP = 3,
/* HTTP2 */
IOTX_CM_PROTOCOL_TYPE_HTTP2 = 4,
/* Maximum number of protocol type */
IOTX_CM_PROTOCOL_TYPE_MAX
} iotx_cm_protocol_types_t;
/* event type */
typedef enum IOTX_CM_EVENT_TYPES {
/* cloud connected */
IOTX_CM_EVENT_CLOUD_CONNECTED = 0,
/* cloud: disconnect */
/* event_msg is null */
IOTX_CM_EVENT_CLOUD_CONNECT_FAILED,
/* cloud: disconnect */
/* event_msg is null */
IOTX_CM_EVENT_CLOUD_DISCONNECT,
/* event_msg is iotx_cm_event_result_pt */
IOTX_CM_EVENT_SUBCRIBE_SUCCESS,
IOTX_CM_EVENT_SUBCRIBE_FAILED,
IOTX_CM_EVENT_UNSUB_SUCCESS,
IOTX_CM_EVENT_UNSUB_FAILED,
IOTX_CM_EVENT_PUBLISH_SUCCESS,
IOTX_CM_EVENT_PUBLISH_FAILED,
/* Maximum number of event */
IOTX_CM_EVENT_MAX
} iotx_cm_event_types_t;
/* The structure of cloud Connection event struct */
typedef struct {
iotx_cm_event_types_t type;
void *msg;
} iotx_cm_event_msg_t;
typedef struct {
char *topic;
uint8_t *payload;
uint32_t payload_len;
} event_msg_data_t;
#ifdef DEVICE_MODEL_ALINK2
typedef void (*iotx_cm_data_handle_cb)(int fd, const char *topic, uint32_t topic_len, const char *payload, unsigned int payload_len, void *context);
#else
typedef void (*iotx_cm_data_handle_cb)(int fd, const char *topic, const char *payload, unsigned int payload_len,
void *context);
#endif
typedef void (*iotx_cm_event_handle_cb)(int fd, iotx_cm_event_msg_t *event, void *context);
/* IoTx initializa parameters */
typedef struct {
uint32_t request_timeout_ms;
uint32_t keepalive_interval_ms;
uint32_t write_buf_size;
uint32_t read_buf_size;
iotx_cm_protocol_types_t protocol_type;
iotx_cm_event_handle_cb handle_event; /* Specify MQTT event handle */
void *context;
#ifdef DEVICE_MODEL_ALINK2
iotx_dev_meta_info_t *dev_info;
iotx_mqtt_region_types_t region;
#endif
} iotx_cm_init_param_t;
typedef struct {
iotx_cm_ack_types_t ack_type;
iotx_cm_sync_mode_types_t sync_mode;
uint32_t sync_timeout;
iotx_cm_data_handle_cb ack_cb;
void *cb_context;
} iotx_cm_ext_params_t;
int iotx_cm_open(iotx_cm_init_param_t *params);
int iotx_cm_connect(int fd, uint32_t timeout);
int iotx_cm_yield(int fd, unsigned int timeout);
int iotx_cm_sub(int fd, iotx_cm_ext_params_t *ext, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext);
int iotx_cm_unsub(int fd, const char *topic);
int iotx_cm_pub(int fd, iotx_cm_ext_params_t *ext, const char *topic, const char *payload, unsigned int payload_len);
int iotx_cm_close(int fd);
#endif /* _LINKKIT_CM_H_ */

View File

@@ -0,0 +1,408 @@
#include "iotx_cm_internal.h"
#ifdef COAP_COMM_ENABLED
#include "iotx_cm.h"
#include "iotx_cm_coap.h"
#include "infra_timer.h"
#ifdef COAP_DTLS_SUPPORT /* DTLS */
#ifdef ON_DAILY
#define IOTX_COAP_SERVER_URI "coaps://11.239.164.238:5684"
#else
#ifdef ON_PRE
#define IOTX_COAP_SERVER_URI "coaps://pre.coap.cn-shanghai.link.aliyuncs.com:5684"
#else /* online */
#define IOTX_COAP_SERVER_URI "coaps://%s.coap.cn-shanghai.link.aliyuncs.com:5684"
#endif
#endif
#else
#ifdef COAP_PSK_SUPPORT /* PSK */
#ifdef ON_DAILY
#define IOTX_COAP_SERVER_URI "coap-psk://10.101.83.159:5682"
#else
#ifdef ON_PRE
#define IOTX_COAP_SERVER_URI "coap-psk://pre.coap.cn-shanghai.link.aliyuncs.com:5682"
#else /* online */
#define IOTX_COAP_SERVER_URI "coap-psk://%s.coap.cn-shanghai.link.aliyuncs.com:5682"
#endif
#endif
#else /* UDP */
#ifdef ON_DAILY
#define IOTX_COAP_SERVER_URI ""
#else
#ifdef ON_PRE
#define IOTX_COAP_SERVER_URI "coap://pre.iot-as-coap.cn-shanghai.aliyuncs.com:5683"
#else /* online */
#define IOTX_COAP_SERVER_URI "coap://%s.coap.cn-shanghai.link.aliyuncs.com:5683"
#endif
#endif
#endif
#endif
extern uint32_t IOT_CoAP_GetCurToken(iotx_coap_context_t *p_context);
int IOT_CoAP_GetMessageToken(void *p_message, unsigned int *token);
static struct list_head g_coap_response_list = LIST_HEAD_INIT(g_coap_response_list);
static iotx_cm_connection_t *_coap_conncection = NULL;
static int iotx_set_devinfo(iotx_device_info_t *p_devinfo);
static int _coap_connect(uint32_t timeout);
static int _coap_publish(iotx_cm_ext_params_t *params, const char *topic, const char *payload,
unsigned int payload_len);
static int _coap_sub(iotx_cm_ext_params_t *params, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext);
static iotx_msg_type_t _get_coap_qos(iotx_cm_ack_types_t ack_type);
static int _coap_unsub(const char *topic);
static int _coap_close();
static void _set_common_handlers();
iotx_cm_connection_t *iotx_cm_open_coap(iotx_cm_init_param_t *params)
{
iotx_coap_config_t *coap_config = NULL;
iotx_device_info_t *deviceinfo = NULL;
if (_coap_conncection != NULL) {
cm_warning("mqtt connection is opened already,return it");
return _coap_conncection;
}
_coap_conncection = (iotx_cm_connection_t *)cm_malloc(sizeof(iotx_cm_connection_t));
if (_coap_conncection == NULL) {
cm_err("_coap_conncection malloc failed!");
goto failed;
}
_coap_conncection->list_lock = HAL_MutexCreate();
if (_coap_conncection->list_lock == NULL) {
cm_err("list_lock create failed!");
goto failed;
}
coap_config = (iotx_coap_config_t *)cm_malloc(sizeof(iotx_coap_config_t));
if (coap_config == NULL) {
cm_err("coap_config malloc failed!");
goto failed;
}
memset(coap_config, 0, sizeof(iotx_coap_config_t));
deviceinfo = (iotx_device_info_t *)cm_malloc(sizeof(iotx_device_info_t));
if (deviceinfo == NULL) {
cm_err("deviceinfo malloc failed!");
goto failed;
}
_coap_conncection->open_params = coap_config;
memset(deviceinfo, 0, sizeof(iotx_device_info_t));
iotx_set_devinfo(deviceinfo);
coap_config->wait_time_ms = params->request_timeout_ms;
coap_config->p_devinfo = deviceinfo;
/* coap_config->p_url = IOTX_COAP_SERVER_URI; */
_coap_conncection->event_handler = params->handle_event;
_set_common_handlers();
return _coap_conncection;
failed:
if (_coap_conncection != NULL) {
if (_coap_conncection->list_lock != NULL) {
HAL_MutexDestroy(_coap_conncection->list_lock);
}
cm_free(_coap_conncection);
_coap_conncection = NULL;
}
if (coap_config != NULL) {
cm_free(coap_config);
}
if (deviceinfo != NULL) {
cm_free(deviceinfo);
}
return NULL;
}
static int iotx_set_devinfo(iotx_device_info_t *p_devinfo)
{
if (NULL == p_devinfo) {
return IOTX_ERR_INVALID_PARAM;
}
memset(p_devinfo, 0x00, sizeof(iotx_device_info_t));
/**< get device info*/
HAL_GetProductKey(p_devinfo->product_key);
HAL_GetDeviceName(p_devinfo->device_name);
HAL_GetDeviceSecret(p_devinfo->device_secret);
HAL_Snprintf(p_devinfo->device_id, IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN + 2, "%s.%s", p_devinfo->product_key, p_devinfo->device_name);
p_devinfo->device_id[IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN + 1] = '\0';
/**< end*/
cm_info("*****The Product Key : %s *****\r\n", p_devinfo->product_key);
cm_info("*****The Device Name : %s *****\r\n", p_devinfo->device_name);
cm_info("*****The Device Secret: %s *****\r\n", p_devinfo->device_secret);
cm_info("*****The Device ID : %s *****\r\n", p_devinfo->device_id);
return IOTX_SUCCESS;
}
static int _coap_connect(uint32_t timeout)
{
int ret;
char url[100] = {0};
iotx_time_t timer;
iotx_coap_config_t *config = NULL;
iotx_coap_context_t *p_ctx = NULL;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
if (_coap_conncection == NULL) {
return NULL_VALUE_ERROR;
}
HAL_GetProductKey(product_key);
config = _coap_conncection->open_params;
if (config == NULL) {
return NULL_VALUE_ERROR;
}
HAL_Snprintf(url, 100, IOTX_COAP_SERVER_URI, product_key);
config->p_url = url;
iotx_time_init(&timer);
utils_time_countdown_ms(&timer, timeout);
do {
if (p_ctx == NULL) {
p_ctx = IOT_CoAP_Init(config);
if (NULL == p_ctx) {
continue;
}
}
ret = IOT_CoAP_DeviceNameAuth(p_ctx);
if (ret == 0) {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_CLOUD_CONNECTED;
event.msg = NULL;
_coap_conncection->context = p_ctx;
if (_coap_conncection->event_handler) {
_coap_conncection->event_handler(_coap_conncection->fd, &event, (void *)_coap_conncection);
}
return 0;
}
} while (!utils_time_is_expired(&timer));
{
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_CLOUD_CONNECT_FAILED;
event.msg = NULL;
if (_coap_conncection->event_handler) {
_coap_conncection->event_handler(_coap_conncection->fd, &event, (void *)_coap_conncection);
}
}
cm_err("mqtt connect failed");
return -1;
}
static void _coap_response_default(void *p_arg, void *p_message)
{
int ret;
int len = 0;
unsigned char *p_payload = NULL;
unsigned int token;
iotx_coap_resp_code_t resp_code;
coap_response_node_t *node = NULL;
coap_response_node_t *next = NULL;
if (_coap_conncection == NULL || p_message == NULL) {
cm_err("paras err");
return;
}
ret = IOT_CoAP_GetMessageCode(p_message, &resp_code);
if (ret < 0) {
cm_err("get msg code err");
return;
}
cm_info("resp_code = %d", resp_code);
ret = IOT_CoAP_GetMessagePayload(p_message, &p_payload, &len);
if (ret < 0) {
cm_err("get msg payload err");
return;
}
ret = IOT_CoAP_GetMessageToken(p_message, &token);
if (ret < 0) {
cm_err("get msg token err");
return;
}
HAL_MutexLock(_coap_conncection->list_lock);
list_for_each_entry_safe(node, next, &g_coap_response_list, linked_list, coap_response_node_t) {
if (node->token_num == token) {
iotx_cm_data_handle_cb recieve_cb = node->responce_cb;
void *context = node->context;
unsigned int topic_len = strlen(node->topic) + 1;
char *topic = cm_malloc(topic_len);
if (topic == NULL) {
cm_err("topic malloc failed");
continue;
}
memset(topic, 0, topic_len);
strncpy(topic, node->topic, topic_len);
list_del(&node->linked_list);
cm_free(node->topic);
cm_free(node);
HAL_MutexUnlock(_coap_conncection->list_lock); /* do not lock while callback */
recieve_cb(_coap_conncection->fd, topic, (const char *)p_payload, len, context);
/* recieve_cb(_coap_conncection->fd, &msg, context); */
cm_free(topic);
HAL_MutexLock(_coap_conncection->list_lock);
}
}
HAL_MutexUnlock(_coap_conncection->list_lock);
}
static int _coap_publish(iotx_cm_ext_params_t *ext, const char *topic, const char *payload, unsigned int payload_len)
{
iotx_msg_type_t qos = 0;
iotx_message_t message;
uint32_t token;
int topic_len;
int ret;
if (_coap_conncection == NULL) {
return NULL_VALUE_ERROR;
}
if (ext != NULL) {
qos = _get_coap_qos(ext->ack_type);
}
memset(&message, 0, sizeof(iotx_message_t));
message.p_payload = (unsigned char *)payload;
message.payload_len = payload_len;
message.resp_callback = _coap_response_default;
message.msg_type = qos;
message.content_type = IOTX_CONTENT_TYPE_JSON;
token = IOT_CoAP_GetCurToken((iotx_coap_context_t *)_coap_conncection->context);
ret = IOT_CoAP_SendMessage((iotx_coap_context_t *)_coap_conncection->context, (char *)topic, &message);
if (ret < 0) {
return -1;
}
if (ext != NULL && ext->ack_cb != NULL) {
coap_response_node_t *node;
node = (coap_response_node_t *)cm_malloc(sizeof(coap_response_node_t));
if (node == NULL) {
return -1;
}
memset(node, 0, sizeof(coap_response_node_t));
topic_len = strlen(topic) + 1;
node->topic = (char *)cm_malloc(topic_len);
if (node->topic == NULL) {
cm_free(node);
return -1;
}
memset(node->topic, 0, topic_len);
strncpy(node->topic, topic, topic_len);
node->user_data = _coap_conncection;
node->responce_cb = ext->ack_cb;
node->context = ext->cb_context;
node->token_num = token;
HAL_MutexLock(_coap_conncection->list_lock);
list_add_tail(&node->linked_list, &g_coap_response_list);
HAL_MutexUnlock(_coap_conncection->list_lock);
}
return 0;
}
static int _coap_yield(uint32_t timeout)
{
if (_coap_conncection == NULL) {
return NULL_VALUE_ERROR;
}
return IOT_CoAP_Yield((iotx_coap_context_t *)_coap_conncection->context);
}
static int _coap_sub(iotx_cm_ext_params_t *ext, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext)
{
return 0;
}
static int _coap_unsub(const char *topic)
{
return 0;
}
static int _coap_close()
{
coap_response_node_t *node = NULL;
coap_response_node_t *next = NULL;
iotx_coap_config_t *coap_config = NULL;
if (_coap_conncection == NULL) {
return NULL_VALUE_ERROR;
}
coap_config = (iotx_coap_config_t *)_coap_conncection->open_params;
HAL_MutexLock(_coap_conncection->list_lock);
list_for_each_entry_safe(node, next, &g_coap_response_list, linked_list, coap_response_node_t) {
cm_free(node->topic);
list_del(&node->linked_list);
cm_free(node);
}
HAL_MutexUnlock(_coap_conncection->list_lock);
if (_coap_conncection->list_lock != NULL) {
HAL_MutexDestroy(_coap_conncection->list_lock);
}
cm_free(coap_config->p_devinfo);
cm_free(coap_config);
IOT_CoAP_Deinit(&_coap_conncection->context);
cm_free(_coap_conncection);
_coap_conncection = NULL;
return 0;
}
static iotx_msg_type_t _get_coap_qos(iotx_cm_ack_types_t ack_type)
{
switch (ack_type) {
case IOTX_CM_MESSAGE_NO_ACK:
return IOTX_MESSAGE_NON;
case IOTX_CM_MESSAGE_NEED_ACK:
return IOTX_MESSAGE_CON;
default:
return IOTX_MESSAGE_CON;
}
}
static void _set_common_handlers()
{
if (_coap_conncection != NULL) {
_coap_conncection->connect_func = _coap_connect;
_coap_conncection->sub_func = _coap_sub;
_coap_conncection->unsub_func = _coap_unsub;
_coap_conncection->pub_func = _coap_publish;
_coap_conncection->yield_func = _coap_yield;
_coap_conncection->close_func = _coap_close;
}
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_CM_COAP_H_
#define _IOTX_CM_COAP_H_
#include "iotx_cm.h"
#include "iotx_cm_internal.h"
#include "coap_api.h"
typedef struct {
uint32_t token_num;
void *user_data;
char *topic;
iotx_cm_data_handle_cb responce_cb;
void *context;
dlist_t linked_list;
} coap_response_node_t;
iotx_cm_connection_t *iotx_cm_open_coap(iotx_cm_init_param_t *params);
#endif /* _LINKKIT_CM_H_ */

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_CM_INTERNAL_H_
#define _IOTX_CM_INTERNAL_H_
#include <string.h>
#include "infra_config.h"
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_list.h"
#include "infra_compat.h"
#include "infra_timer.h"
#include "dm_wrapper.h"
#include "mqtt_api.h"
#include "iotx_cm.h"
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#define cm_malloc(size) LITE_malloc(size, MEM_MAGIC, "cm")
#define cm_free(ptr) LITE_free(ptr)
#else
#define cm_malloc(size) HAL_Malloc(size)
#define cm_free(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
#endif
#ifdef INFRA_LOG
#include "infra_log.h"
#define cm_debug(...) log_debug("CM", __VA_ARGS__)
#define cm_info(...) log_info("CM", __VA_ARGS__)
#define cm_warning(...) log_warning("CM", __VA_ARGS__)
#define cm_err(...) log_err("CM", __VA_ARGS__)
#else
#define cm_debug(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
#define cm_info(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
#define cm_warning(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
#define cm_err(...) do{HAL_Printf(__VA_ARGS__);HAL_Printf("\r\n");}while(0)
#endif
typedef int (*iotx_cm_connect_fp)(uint32_t timeout);
typedef int (*iotx_cm_yield_fp)(unsigned int timeout);
typedef int (*iotx_cm_sub_fp)(iotx_cm_ext_params_t *params, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext);
typedef int (*iotx_cm_unsub_fp)(const char *topic);
typedef int (*iotx_cm_pub_fp)(iotx_cm_ext_params_t *params, const char *topic, const char *payload,
unsigned int payload_len);
typedef int (*iotx_cm_close_fp)();
typedef struct iotx_connection_st {
int fd;
void *open_params;
void *context;
void *list_lock;
iotx_cm_protocol_types_t protocol_type;
iotx_cm_connect_fp connect_func;
iotx_cm_sub_fp sub_func;
iotx_cm_unsub_fp unsub_func;
iotx_cm_pub_fp pub_func;
iotx_cm_yield_fp yield_func;
iotx_cm_close_fp close_func;
iotx_cm_event_handle_cb event_handler;
void *cb_data;
} iotx_cm_connection_t;
#include "iotx_cm_mqtt.h"
extern const char ERR_INVALID_PARAMS[];
#endif /* _LINKKIT_CM_H_ */

View File

@@ -0,0 +1,411 @@
#include "iotx_cm_internal.h"
#if defined(MQTT_COMM_ENABLED) || defined(MAL_ENABLED)
static iotx_cm_connection_t *_mqtt_conncection = NULL;
static void iotx_cloud_conn_mqtt_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg);
static int _mqtt_connect(uint32_t timeout);
static int _mqtt_publish(iotx_cm_ext_params_t *params, const char *topic, const char *payload,
unsigned int payload_len);
static int _mqtt_sub(iotx_cm_ext_params_t *params, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext);
static iotx_mqtt_qos_t _get_mqtt_qos(iotx_cm_ack_types_t ack_type);
static int _mqtt_unsub(const char *topic);
static int _mqtt_close();
static void _set_common_handlers();
iotx_cm_connection_t *iotx_cm_open_mqtt(iotx_cm_init_param_t *params)
{
iotx_mqtt_param_t *mqtt_param = NULL;
if (_mqtt_conncection != NULL) {
cm_warning("mqtt connection is opened already,return it");
return _mqtt_conncection;
}
_mqtt_conncection = (iotx_cm_connection_t *)cm_malloc(sizeof(iotx_cm_connection_t));
if (_mqtt_conncection == NULL) {
cm_err("_mqtt_conncection malloc failed!");
goto failed;
}
memset(_mqtt_conncection, 0, sizeof(iotx_cm_connection_t));
mqtt_param = (iotx_mqtt_param_t *)cm_malloc(sizeof(iotx_mqtt_param_t));
if (mqtt_param == NULL) {
cm_err("mqtt_param malloc failed!");
goto failed;
}
memset(mqtt_param, 0, sizeof(iotx_mqtt_param_t));
_mqtt_conncection->open_params = mqtt_param;
mqtt_param->request_timeout_ms = params->request_timeout_ms;
mqtt_param->clean_session = 0;
mqtt_param->keepalive_interval_ms = params->keepalive_interval_ms;
mqtt_param->read_buf_size = params->read_buf_size;
mqtt_param->write_buf_size = params->write_buf_size;
mqtt_param->handle_event.h_fp = iotx_cloud_conn_mqtt_event_handle;
mqtt_param->handle_event.pcontext = NULL;
_mqtt_conncection->event_handler = params->handle_event;
_mqtt_conncection->cb_data = params->context;
_set_common_handlers();
return _mqtt_conncection;
failed:
if (_mqtt_conncection != NULL) {
cm_free(_mqtt_conncection);
_mqtt_conncection = NULL;
}
if (mqtt_param != NULL) {
cm_free(mqtt_param);
}
return NULL;
}
static void iotx_cloud_conn_mqtt_event_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
uintptr_t packet_id = (uintptr_t)msg->msg;
if (_mqtt_conncection == NULL) {
return;
}
switch (msg->event_type) {
case IOTX_MQTT_EVENT_DISCONNECT: {
iotx_cm_event_msg_t event;
cm_info("disconnected,fd = %d", _mqtt_conncection->fd);
event.type = IOTX_CM_EVENT_CLOUD_DISCONNECT;
event.msg = NULL;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_RECONNECT: {
iotx_cm_event_msg_t event;
cm_info("connected,fd = %d", _mqtt_conncection->fd);
event.type = IOTX_CM_EVENT_CLOUD_CONNECTED;
event.msg = NULL;
/* cm_info(cm_log_info_MQTT_reconnect); */
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_SUBCRIBE_SUCCESS;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_SUBCRIBE_FAILED;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_UNSUB_SUCCESS;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK:
case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_UNSUB_FAILED;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_PUBLISH_SUCCESS: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_PUBLISH_SUCCESS;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_PUBLISH_NACK:
case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT: {
iotx_cm_event_msg_t event;
event.type = IOTX_CM_EVENT_PUBLISH_FAILED;
event.msg = (void *)packet_id;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, _mqtt_conncection->cb_data);
}
}
break;
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED: {
iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg;
iotx_cm_data_handle_cb topic_handle_func = (iotx_cm_data_handle_cb)pcontext;
#ifndef DEVICE_MODEL_ALINK2
char *topic = NULL;
#endif
if (topic_handle_func == NULL) {
cm_warning("bypass %d bytes on [%.*s]", topic_info->payload_len, topic_info->topic_len, topic_info->ptopic);
return;
}
#ifdef DEVICE_MODEL_ALINK2
topic_handle_func(_mqtt_conncection->fd, topic_info->ptopic, topic_info->topic_len, topic_info->payload,
topic_info->payload_len, NULL);
#else
topic = cm_malloc(topic_info->topic_len + 1);
if (topic == NULL) {
cm_err("topic malloc failed");
return;
}
memset(topic, 0, topic_info->topic_len + 1);
memcpy(topic, topic_info->ptopic, topic_info->topic_len);
topic_handle_func(_mqtt_conncection->fd, topic, topic_info->payload, topic_info->payload_len, NULL);
cm_free(topic);
#endif
}
break;
case IOTX_MQTT_EVENT_BUFFER_OVERFLOW:
cm_warning("buffer overflow", msg->msg);
break;
default:
cm_warning("msg type unkown, type = %d", msg->event_type);
break;
}
}
extern sdk_impl_ctx_t g_sdk_impl_ctx;
static int _mqtt_connect(uint32_t timeout)
{
void *pclient;
iotx_time_t timer;
iotx_mqtt_param_t *mqtt_param = NULL;
iotx_conn_info_pt pconn_info = NULL;
iotx_cm_event_msg_t event;
char product_key[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char device_name[IOTX_DEVICE_NAME_LEN + 1] = {0};
char device_secret[IOTX_DEVICE_SECRET_LEN + 1] = {0};
if (_mqtt_conncection == NULL) {
return NULL_VALUE_ERROR;
}
mqtt_param = _mqtt_conncection->open_params;
HAL_GetProductKey(product_key);
HAL_GetDeviceName(device_name);
HAL_GetDeviceSecret(device_secret);
if (strlen(product_key) == 0 || strlen(device_name) == 0) {
return FAIL_RETURN;
}
iotx_time_init(&timer);
utils_time_countdown_ms(&timer, timeout);
/* Device AUTH */
do {
if (0 == IOT_SetupConnInfo(product_key, device_name, device_secret, (void **)&pconn_info)) {
mqtt_param->port = pconn_info->port;
mqtt_param->host = pconn_info->host_name;
mqtt_param->client_id = pconn_info->client_id;
mqtt_param->username = pconn_info->username;
mqtt_param->password = pconn_info->password;
mqtt_param->pub_key = pconn_info->pub_key;
break;
}
cm_err("IOT_SetupConnInfo failed");
HAL_SleepMs(500);
} while (!utils_time_is_expired(&timer));
if (g_sdk_impl_ctx.mqtt_customzie_info[0] != '\0') {
((iotx_mqtt_param_t *)_mqtt_conncection->open_params)->customize_info = g_sdk_impl_ctx.mqtt_customzie_info;
}
do {
pclient = IOT_MQTT_Construct((iotx_mqtt_param_t *)_mqtt_conncection->open_params);
if (pclient != NULL) {
iotx_cm_event_msg_t event;
_mqtt_conncection->context = pclient;
event.type = IOTX_CM_EVENT_CLOUD_CONNECTED;
event.msg = NULL;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, (void *)_mqtt_conncection);
}
return 0;
}
HAL_SleepMs(500);
} while (!utils_time_is_expired(&timer));
event.type = IOTX_CM_EVENT_CLOUD_CONNECT_FAILED;
event.msg = NULL;
if (_mqtt_conncection->event_handler) {
_mqtt_conncection->event_handler(_mqtt_conncection->fd, &event, (void *)_mqtt_conncection);
}
cm_err("mqtt connect failed");
return -1;
}
static int _mqtt_publish(iotx_cm_ext_params_t *ext, const char *topic, const char *payload, unsigned int payload_len)
{
int qos = 0;
if (_mqtt_conncection == NULL) {
return NULL_VALUE_ERROR;
}
if (ext != NULL) {
qos = (int)_get_mqtt_qos(ext->ack_type);
}
return IOT_MQTT_Publish_Simple(_mqtt_conncection->context, topic, qos, (void *)payload, payload_len);
}
static int _mqtt_yield(uint32_t timeout)
{
if (_mqtt_conncection == NULL) {
return NULL_VALUE_ERROR;
}
return IOT_MQTT_Yield(_mqtt_conncection->context, timeout);
}
static int _mqtt_sub(iotx_cm_ext_params_t *ext, const char *topic,
iotx_cm_data_handle_cb topic_handle_func, void *pcontext)
{
int sync = 0;
int qos = 0;
int timeout = 0;
int ret;
if (_mqtt_conncection == NULL || topic == NULL || topic_handle_func == NULL) {
return NULL_VALUE_ERROR;
}
if (ext != NULL) {
if (ext->sync_mode == IOTX_CM_ASYNC) {
sync = 0;
} else {
sync = 1;
timeout = ext->sync_timeout;
}
qos = (int)_get_mqtt_qos(ext->ack_type);
}
if (sync != 0) {
ret = IOT_MQTT_Subscribe_Sync(_mqtt_conncection->context,
topic,
qos,
iotx_cloud_conn_mqtt_event_handle,
(void *)topic_handle_func,
timeout);
} else {
ret = IOT_MQTT_Subscribe(_mqtt_conncection->context,
topic,
qos,
iotx_cloud_conn_mqtt_event_handle,
(void *)topic_handle_func);
}
return ret;
}
static int _mqtt_unsub(const char *topic)
{
int ret;
if (_mqtt_conncection == NULL) {
return NULL_VALUE_ERROR;
}
ret = IOT_MQTT_Unsubscribe(_mqtt_conncection->context, topic);
if (ret < 0) {
return -1;
}
return ret;
}
static int _mqtt_close()
{
if (_mqtt_conncection == NULL) {
return NULL_VALUE_ERROR;
}
cm_free(_mqtt_conncection->open_params);
IOT_MQTT_Destroy(&_mqtt_conncection->context);
cm_free(_mqtt_conncection);
_mqtt_conncection = NULL;
return 0;
}
static iotx_mqtt_qos_t _get_mqtt_qos(iotx_cm_ack_types_t ack_type)
{
switch (ack_type) {
case IOTX_CM_MESSAGE_NO_ACK:
return IOTX_MQTT_QOS0;
case IOTX_CM_MESSAGE_NEED_ACK:
return IOTX_MQTT_QOS1;
case IOTX_CM_MESSAGE_SUB_LOCAL:
return IOTX_MQTT_QOS3_SUB_LOCAL;
default:
return IOTX_MQTT_QOS0;
}
}
static void _set_common_handlers()
{
if (_mqtt_conncection != NULL) {
_mqtt_conncection->connect_func = _mqtt_connect;
_mqtt_conncection->sub_func = _mqtt_sub;
_mqtt_conncection->unsub_func = _mqtt_unsub;
_mqtt_conncection->pub_func = _mqtt_publish;
_mqtt_conncection->yield_func = (iotx_cm_yield_fp)_mqtt_yield;
_mqtt_conncection->close_func = _mqtt_close;
}
}
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_CM_MQTT_H_
#define _IOTX_CM_MQTT_H_
#include "iotx_cm.h"
#include "iotx_cm_internal.h"
typedef struct {
uintptr_t packet_id;
char * topic;
void * user_data;
iotx_mqtt_event_handle_func_fpt sub_state_cb;
iotx_cm_data_handle_cb sub_recieve_cb;
dlist_t linked_list;
} mqtt_sub_node_t;
iotx_cm_connection_t *iotx_cm_open_mqtt(iotx_cm_init_param_t *params);
#endif /* _LINKKIT_CM_H_ */

View File

@@ -0,0 +1,289 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOT_EXPORT_DM_H_
#define _IOT_EXPORT_DM_H_
#ifndef _IN_
#define _IN_
#endif
#ifndef _OU_
#define _OU_
#endif
#ifdef DEVICE_MODEL_GATEWAY
#define IOTX_DM_DEVICE_TYPE IOTX_DM_DEVICE_GATEWAY
#else
#define IOTX_DM_DEVICE_TYPE IOTX_DM_DEVICE_SINGLE
#endif
#define IOTX_DM_LOCAL_NODE_DEVID (0)
#define IOTX_DM_DEVICE_SINGLE (0x01)
#define IOTX_DM_DEVICE_SUBDEV (0x02)
#define IOTX_DM_DEVICE_GATEWAY (0x04)
#define IOTX_DM_DEVICE_MAIN (IOTX_DM_DEVICE_SINGLE|IOTX_DM_DEVICE_GATEWAY)
#define IOTX_DM_DEVICE_ALL (IOTX_DM_DEVICE_SINGLE|IOTX_DM_DEVICE_SUBDEV|IOTX_DM_DEVICE_GATEWAY)
/* Service Type 0~7bit: type, 8~15bit: extended*/
#define IOTX_DM_SERVICE_CLOUD (0x0001)
#define IOTX_DM_SERVICE_LOCAL (0x0002)
#define IOTX_DM_SERVICE_LOCAL_NO_AUTH (0x0000)
#define IOTX_DM_SERVICE_LOCAL_AUTH (0x0100)
#define IOTX_DM_LOCAL_AUTH (IOTX_DM_SERVICE_LOCAL|IOTX_DM_SERVICE_LOCAL_AUTH)
#define IOTX_DM_LOCAL_NO_AUTH (IOTX_DM_SERVICE_LOCAL|IOTX_DM_SERVICE_LOCAL_NO_AUTH)
#define IOTX_DM_SERVICE_ALL (IOTX_DM_SERVICE_CLOUD|IOTX_DM_LOCAL_AUTH)
typedef enum {
IOTX_DM_ERR_CODE_SUCCESS = 200,
IOTX_DM_ERR_CODE_REQUEST_ERROR = 400,
IOTX_DM_ERR_CODE_REQUEST_PARAMS_ERROR = 460,
IOTX_DM_ERR_CODE_REQUEST_TOO_MANY = 429,
IOTX_DM_ERR_CODE_NO_ACTIVE_SESSION = 520,
IOTX_DM_ERR_CODE_TIMEOUT = 100000
} iotx_dm_error_code_t;
typedef enum {
IOTX_DM_EVENT_CLOUD_CONNECTED = 0,
IOTX_DM_EVENT_CLOUD_DISCONNECT,
IOTX_DM_EVENT_CLOUD_RECONNECT,
IOTX_DM_EVENT_LOCAL_CONNECTED,
IOTX_DM_EVENT_LOCAL_DISCONNECT,
IOTX_DM_EVENT_LOCAL_RECONNECT,
IOTX_DM_EVENT_FOUND_DEVICE,
IOTX_DM_EVENT_REMOVE_DEVICE,
IOTX_DM_EVENT_REGISTER_RESULT,
IOTX_DM_EVENT_UNREGISTER_RESULT,
IOTX_DM_EVENT_INITIALIZED,
IOTX_DM_EVENT_SEND_RESULT,
IOTX_DM_EVENT_ADD_SERVICE_RESULT,
IOTX_DM_EVENT_REMOVE_SERVICE_RESULT,
IOTX_DM_EVENT_NEW_DATA_RECEIVED,
IOTX_DM_EVENT_PROPERTY_SET,
IOTX_DM_EVENT_PROPERTY_GET,
IOTX_DM_EVENT_PROPERTY_DESIRED_GET_REPLY,
IOTX_DM_EVENT_PROPERTY_DESIRED_DELETE_REPLY,
IOTX_DM_EVENT_TOPO_ADD_NOTIFY,
IOTX_DM_EVENT_THING_SERVICE_REQUEST,
IOTX_DM_EVENT_THING_DISABLE,
IOTX_DM_EVENT_THING_ENABLE,
IOTX_DM_EVENT_THING_DELETE,
IOTX_DM_EVENT_MODEL_DOWN_RAW,
IOTX_DM_EVENT_GATEWAY_PERMIT,
IOTX_DM_EVENT_SUBDEV_REGISTER_REPLY,
IOTX_DM_EVENT_SUBDEV_UNREGISTER_REPLY,
IOTX_DM_EVENT_TOPO_ADD_REPLY,
IOTX_DM_EVENT_TOPO_DELETE_REPLY,
IOTX_DM_EVENT_TOPO_GET_REPLY,
IOTX_DM_EVENT_TOPO_ADD_NOTIFY_REPLY,
IOTX_DM_EVENT_EVENT_PROPERTY_POST_REPLY,
IOTX_DM_EVENT_EVENT_SPECIFIC_POST_REPLY,
IOTX_DM_EVENT_DEVICEINFO_UPDATE_REPLY,
IOTX_DM_EVENT_DEVICEINFO_DELETE_REPLY,
IOTX_DM_EVENT_DSLTEMPLATE_GET_REPLY,
IOTX_DM_EVENT_COMBINE_LOGIN_REPLY,
IOTX_DM_EVENT_COMBINE_LOGOUT_REPLY,
IOTX_DM_EVENT_MODEL_UP_RAW_REPLY,
IOTX_DM_EVENT_LEGACY_THING_CREATED,
IOTX_DM_EVENT_COTA_NEW_CONFIG,
IOTX_DM_EVENT_FOTA_NEW_FIRMWARE,
IOTX_DM_EVENT_NTP_RESPONSE,
IOTX_DM_EVENT_RRPC_REQUEST,
IOTX_DM_EVENT_MAX
} iotx_dm_event_types_t;
typedef void (*iotx_dm_event_callback)(iotx_dm_event_types_t type, char *payload);
typedef enum {
IOTX_DM_DEVICE_SECRET_PRODUCT,
IOTX_DM_DEVICE_SECRET_DEVICE,
IOTX_DM_DEVICE_SECRET_TYPES_MAX
} iotx_dm_device_secret_types_t;
typedef enum {
IOTX_DM_CLOUD_DOMAIN_SHANGHAI,
IOTX_DM_CLOUD_DOMAIN_SINGAPORE,
IOTX_DM_CLOUD_DOMAIN_JAPAN,
IOTX_DM_CLOUD_DOMAIN_AMERICA,
IOTX_DM_CLOUD_DOMAIN_GERMANY,
IOTX_DM_CLOUD_DOMAIN_MAX
} iotx_dm_cloud_domain_types_t;
typedef enum {
IOTX_DM_MESSAGE_NO_AUTH,
IOTX_DM_MESSAGE_AUTH,
IOTX_DM_MESSAGE_AUTH_MAX
} iotx_dm_message_auth_types_t;
typedef enum {
IOTX_DM_TSL_SOURCE_LOCAL,
IOTX_DM_TSL_SOURCE_CLOUD
} iotx_dm_tsl_source_t;
typedef enum {
IOTX_DM_TSL_TYPE_ALINK,
IOTX_DM_TSL_TYPE_TLV
} iotx_dm_tsl_type_t;
typedef struct {
iotx_dm_device_secret_types_t secret_type;
iotx_dm_cloud_domain_types_t domain_type;
iotx_dm_event_callback event_callback;
} iotx_dm_init_params_t;
typedef enum {
IOTX_DM_DEV_AVAIL_ENABLE,
IOTX_DM_DEV_AVAIL_DISABLE
} iotx_dm_dev_avail_t;
typedef enum {
IOTX_DM_DEV_STATUS_UNAUTHORIZED, /* Subdev Created */
IOTX_DM_DEV_STATUS_AUTHORIZED, /* Receive Topo Add Notify */
IOTX_DM_DEV_STATUS_REGISTERED, /* Receive Subdev Registered */
IOTX_DM_DEV_STATUS_ATTACHED, /* Receive Subdev Topo Add Reply */
IOTX_DM_DEV_STATUS_LOGINED, /* Receive Subdev Login Reply */
IOTX_DM_DEV_STATUS_ONLINE /* After All Topic Subscribed */
} iotx_dm_dev_status_t;
typedef enum {
DM_TSL_SERVICE_GET_FAILED = -13,
DM_TSL_SERVICE_SET_FAILED = -12,
DM_TSL_EVENT_GET_FAILED = -11,
DM_TSL_EVENT_SET_FAILED = -10,
DM_TSL_PROPERTY_GET_FAILED = -9,
DM_TSL_PROPERTY_SET_FAILED = -8,
DM_TSL_EVENT_NOT_EXIST = -7,
DM_TSL_PROPERTY_NOT_EXIST = -6,
DM_TSL_SERVICE_NOT_EXIST = -5,
DM_JSON_PARSE_FAILED = -4,
DM_MEMORY_NOT_ENOUGH = -3,
DM_INVALID_PARAMETER = -2
} dm_error_code_t;
#define IOTX_DM_POST_PROPERTY_ALL (NULL)
int iotx_dm_open(void);
int iotx_dm_connect(_IN_ iotx_dm_init_params_t *init_params);
int iotx_dm_subscribe(_IN_ int devid);
int iotx_dm_close(void);
int iotx_dm_yield(int timeout_ms);
void iotx_dm_dispatch(void);
int iotx_dm_post_rawdata(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
int iotx_dm_set_opt(int opt, void *data);
int iotx_dm_get_opt(int opt, void *data);
#ifdef LOG_REPORT_TO_CLOUD
int iotx_dm_log_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
#endif
int iotx_dm_post_property(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_property_desired_get(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_property_desired_delete(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_post_event(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload,
_IN_ int payload_len);
int iotx_dm_send_service_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len, _IN_ iotx_dm_error_code_t code,
_IN_ char *identifier,
_IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len, void *ctx);
int iotx_dm_send_property_get_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len,
_IN_ iotx_dm_error_code_t code,
_IN_ char *payload, _IN_ int payload_len, _IN_ void *ctx);
int iotx_dm_send_rrpc_response(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len, _IN_ iotx_dm_error_code_t code,
_IN_ char *rrpcid, _IN_ int rrpcid_len, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_deviceinfo_update(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_deviceinfo_delete(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len);
int iotx_dm_qurey_ntp(void);
int iotx_dm_send_aos_active(int devid);
#endif
int iotx_dm_cota_perform_sync(_OU_ char *buffer, _IN_ int buffer_len);
int iotx_dm_cota_get_config(_IN_ const char *config_scope, const char *get_type, const char *attribute_keys);
int iotx_dm_fota_perform_sync(_OU_ char *buffer, _IN_ int buffer_len);
int iotx_dm_fota_request_image(_IN_ const char *version, _IN_ int buffer_len);
#ifdef DEVICE_MODEL_GATEWAY
int iotx_dm_query_topo_list(void);
int iotx_dm_subdev_query(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_OU_ int *devid);
int iotx_dm_subdev_create(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1], _IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1],
_IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1], _OU_ int *devid);
int iotx_dm_subdev_destroy(_IN_ int devid);
int iotx_dm_subdev_number(void);
int iotx_dm_subdev_register(_IN_ int devid);
int iotx_dm_subdev_unregister(_IN_ int devid);
int iotx_dm_subdev_topo_add(_IN_ int devid);
int iotx_dm_subdev_topo_del(_IN_ int devid);
int iotx_dm_subdev_login(_IN_ int devid);
int iotx_dm_subdev_logout(_IN_ int devid);
int iotx_dm_get_device_type(_IN_ int devid, _OU_ int *type);
int iotx_dm_get_device_avail_status(_IN_ int devid, _OU_ iotx_dm_dev_avail_t *status);
int iotx_dm_get_device_status(_IN_ int devid, _OU_ iotx_dm_dev_status_t *status);
#ifdef DEVICE_MODEL_SUBDEV_OTA
int iotx_dm_send_firmware_version(int devid, const char *firmware_version);
int iotx_dm_ota_switch_device(_IN_ int devid);
#endif
#endif
#ifdef DEPRECATED_LINKKIT
int iotx_dm_deprecated_subdev_register(_IN_ int devid, _IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1]);
int iotx_dm_deprecated_set_tsl(_IN_ int devid, _IN_ iotx_dm_tsl_source_t source, _IN_ const char *tsl,
_IN_ int tsl_len);
int iotx_dm_deprecated_set_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int iotx_dm_deprecated_get_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int iotx_dm_deprecated_set_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int iotx_dm_deprecated_get_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int iotx_dm_deprecated_get_service_input_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int iotx_dm_deprecated_set_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
int iotx_dm_deprecated_get_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int iotx_dm_deprecated_post_property_start(_IN_ int devid, _OU_ void **handle);
int iotx_dm_deprecated_post_property_add(_IN_ void *handle, _IN_ char *identifier, _IN_ int identifier_len);
int iotx_dm_deprecated_post_property_end(_IN_ void **handle);
int iotx_dm_deprecated_post_event(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len);
int iotx_dm_deprecated_send_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
_IN_ char *identifier,
_IN_ int identifier_len);
int iotx_dm_deprecated_legacy_set_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ char *value_str);
int iotx_dm_deprecated_legacy_get_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ char **value_str);
int iotx_dm_deprecated_legacy_set_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ char *value_str);
int iotx_dm_deprecated_legacy_get_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ char **value_str);
int iotx_dm_deprecated_legacy_get_service_input_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len,
_IN_ void *value,
_IN_ char **value_str);
int iotx_dm_deprecated_legacy_set_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len,
_IN_ void *value,
_IN_ char *value_str);
int iotx_dm_deprecated_legacy_get_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len,
_IN_ void *value,
_IN_ char **value_str);
int iotx_dm_deprecated_legacy_get_pkdn_by_devid(_IN_ int devid, _OU_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_OU_ char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int iotx_dm_deprecated_legacy_get_devid_by_pkdn(_IN_ char product_key[IOTX_PRODUCT_KEY_LEN + 1],
_IN_ char device_name[IOTX_DEVICE_NAME_LEN + 1], _OU_ int *devid);
int iotx_dm_deprecated_legacy_get_thingid_by_devid(_IN_ int devid, _OU_ void **thing_id);
int iotx_dm_deprecated_legacy_get_devid_by_thingid(_IN_ void *thing_id, _OU_ int *devid);
int iotx_dm_deprecated_legacy_get_pkdn_ptr_by_devid(_IN_ int devid, _OU_ char **product_key, _OU_ char **device_name);
int iotx_dm_deprecated_legacy_send_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
_IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len);
#ifdef DEVICE_MODEL_GATEWAY
int iotx_dm_deprecated_subdev_register(_IN_ int devid, _IN_ char device_secret[IOTX_DEVICE_SECRET_LEN + 1]);
#endif
#endif
#endif

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_DM_CONFIG_H_
#define _IOTX_DM_CONFIG_H_
#define IOTX_DM_CLIENT_CONNECT_TIMEOUT_MS (10000)
#define IOTX_DM_CLIENT_SUB_RETRY_MAX_COUNTS (3)
#define IOTX_DM_CLIENT_SUB_TIMEOUT_MS (5000)
#define IOTX_DM_CLIENT_REQUEST_TIMEOUT_MS (2000)
#define IOTX_DM_CLIENT_KEEPALIVE_INTERVAL_MS (30000)
#ifndef CONFIG_MQTT_TX_MAXLEN
#define CONFIG_MQTT_TX_MAXLEN (1024)
#endif
#ifndef CONFIG_MQTT_RX_MAXLEN
#define CONFIG_MQTT_RX_MAXLEN (1024)
#endif
#ifndef CONFIG_DISPATCH_QUEUE_MAXLEN
#define CONFIG_DISPATCH_QUEUE_MAXLEN (50)
#endif
#ifndef CONFIG_DISPATCH_PACKET_MAXCOUNT
#define CONFIG_DISPATCH_PACKET_MAXCOUNT (0)
#endif
#ifndef CONFIG_MSGCACHE_QUEUE_MAXLEN
#define CONFIG_MSGCACHE_QUEUE_MAXLEN (50)
#endif
#endif

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef _IOTX_DM_INTERNAL_H_
#define _IOTX_DM_INTERNAL_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "infra_config.h"
#include "infra_types.h"
#include "infra_defs.h"
#include "infra_list.h"
#include "infra_cjson.h"
#include "infra_report.h"
#include "infra_string.h"
#if defined(DEVICE_MODEL_GATEWAY)
#include "infra_sha1.h"
#endif
#ifndef _IN_
#define _IN_
#endif
#ifndef _OU_
#define _OU_
#endif
#ifndef DM_READ_ONLY
#define DM_READ_ONLY
#endif
#include <stdlib.h>
#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
#include "iotx_ota.h"
#include "ota_api.h"
#endif
/* CM Header File */
#include "iotx_cm.h"
/* ALCS Header File */
#ifdef ALCS_ENABLED
#include "CoAPExport.h"
#include "iotx_alcs.h"
#include "dm_server_adapter.h"
#include "dm_server.h"
#endif
/* DM Header File */
#include "dm_wrapper.h"
#include "iotx_dm_config.h"
#include "iotx_dm.h"
#include "dm_utils.h"
#include "dm_shadow.h"
#include "dm_tsl_alink.h"
#include "dm_message_cache.h"
#include "dm_opt.h"
#include "dm_ota.h"
#include "dm_cota.h"
#include "dm_fota.h"
#include "dm_ipc.h"
#include "dm_message.h"
#include "dm_msg_process.h"
#include "dm_manager.h"
#include "dm_client_adapter.h"
#include "dm_client.h"
#include "dm_intf.h"
#ifdef INFRA_MEM_STATS
#include "infra_mem_stats.h"
#define DM_malloc(size) LITE_malloc(size, MEM_MAGIC, "dm")
#define DM_free(ptr) LITE_free(ptr)
#else
#define DM_malloc(size) HAL_Malloc(size)
#define DM_free(ptr) {HAL_Free((void *)ptr);ptr = NULL;}
#endif
#if defined(COAP_COMM_ENABLED) && !defined(MQTT_COMM_ENABLED)
#define DM_URI_OFFSET 1
#else
#define DM_URI_OFFSET 0
#endif
#ifdef INFRA_LOG
#include "infra_log.h"
#define dm_log_emerg(...) log_emerg("DM", __VA_ARGS__)
#define dm_log_crit(...) log_crit("DM", __VA_ARGS__)
#define dm_log_err(...) log_err("DM", __VA_ARGS__)
#define dm_log_warning(...) log_warning("DM", __VA_ARGS__)
#define dm_log_info(...) log_info("DM", __VA_ARGS__)
#define dm_log_debug(...) log_debug("DM", __VA_ARGS__)
#else
#define dm_log_emerg(...)
#define dm_log_crit(...)
#define dm_log_err(...)
#define dm_log_warning(...)
#define dm_log_info(...)
#define dm_log_debug(...)
#define HEXDUMP_INFO(...)
#define HEXDUMP_DEBUG(...)
#endif
#ifdef LOG_REPORT_TO_CLOUD
#define LOG_POLL_SIZE (CONFIG_MQTT_TX_MAXLEN - 174)
#define REPORT_LEN (LOG_POLL_SIZE - 110)
#define OVERFLOW_LEN (LOG_POLL_SIZE - 10)
typedef enum {
READY,
RUNNING,
DONE
} REPORT_STATE;
unsigned int add_tail();
int reset_log_poll();
int remove_log_poll();
unsigned int push_log(const char *perform_data, int perform_data_size);
#endif
#endif

View File

@@ -0,0 +1,3 @@
void get_msgid(char *payload, int is_cloud);
int check_target_msg(const char *input, int len);
void send_permance_info(char *input, int input_len, char *comments, int report_format);

View File

@@ -0,0 +1,284 @@
#include "iotx_dm_internal.h"
#ifdef ALCS_ENABLED
#ifdef LOG_REPORT_TO_CLOUD
#include "iotx_log_report.h"
#endif
static int _dm_server_malloc_context(_IN_ NetworkAddr *remote, _IN_ CoAPMessage *message,
_OU_ dm_server_alcs_context_t **context)
{
dm_server_alcs_context_t *alcs_context = NULL;
alcs_context = DM_malloc(sizeof(dm_server_alcs_context_t));
if (alcs_context == NULL) {
return FAIL_RETURN;
}
memset(alcs_context, 0, sizeof(dm_server_alcs_context_t));
alcs_context->ip = DM_malloc(strlen((char *)remote->addr) + 1);
if (alcs_context->ip == NULL) {
DM_free(alcs_context);
return FAIL_RETURN;
}
memset(alcs_context->ip, 0, strlen((char *)remote->addr) + 1);
memcpy(alcs_context->ip, (char *)remote->addr, strlen((char *)remote->addr) + 1);
alcs_context->port = remote->port;
dm_log_info("alcs_context->ip: %s", alcs_context->ip);
dm_log_info("alcs_context->port: %d", alcs_context->port);
alcs_context->token = DM_malloc(message->header.tokenlen);
if (alcs_context->token == NULL) {
DM_free(alcs_context->ip);
DM_free(alcs_context);
return FAIL_RETURN;
}
memset(alcs_context->token, 0, message->header.tokenlen);
memcpy(alcs_context->token, message->token, message->header.tokenlen);
alcs_context->token_len = message->header.tokenlen;
*context = alcs_context;
return SUCCESS_RETURN;
}
void dm_server_free_context(_IN_ void *ctx)
{
dm_server_alcs_context_t *context = (dm_server_alcs_context_t *)ctx;
DM_free(context->ip);
DM_free(context->token);
DM_free(context);
}
static dm_server_uri_map_t g_dm_server_uri_map[] = {
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
{DM_URI_THING_SERVICE_PROPERTY_SET, DM_URI_SYS_PREFIX, IOTX_DM_LOCAL_AUTH, dm_server_thing_service_property_set },
{DM_URI_THING_SERVICE_PROPERTY_GET, DM_URI_SYS_PREFIX, IOTX_DM_LOCAL_AUTH, dm_server_thing_service_property_get },
{DM_URI_THING_EVENT_PROPERTY_POST, DM_URI_SYS_PREFIX, IOTX_DM_LOCAL_AUTH, dm_server_thing_service_property_post },
{DM_URI_THING_SERVICE_REQUEST_WILDCARD2, DM_URI_SYS_PREFIX, IOTX_DM_LOCAL_AUTH, dm_server_thing_service_request },
#endif
{DM_URI_DEV_CORE_SERVICE_DEV, NULL, IOTX_DM_LOCAL_NO_AUTH, dm_server_thing_dev_core_service_dev },
};
int dm_server_subscribe_all(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
int res = 0, index = 0, auth = 0;
int number = sizeof(g_dm_server_uri_map) / sizeof(dm_server_uri_map_t);
char *uri = NULL;
for (index = 0; index < number; index++) {
res = dm_utils_service_name((char *)g_dm_server_uri_map[index].uri_prefix, (char *)g_dm_server_uri_map[index].uri_name,
product_key, device_name, &uri);
if (res < SUCCESS_RETURN) {
index--;
continue;
}
auth = (g_dm_server_uri_map[index].auth_type & IOTX_DM_SERVICE_LOCAL_AUTH) ? (IOTX_DM_MESSAGE_AUTH) :
(IOTX_DM_MESSAGE_NO_AUTH);
res = dm_server_subscribe(uri, (void *)g_dm_server_uri_map[index].callback, auth);
if (res < SUCCESS_RETURN) {
index--;
DM_free(uri);
continue;
}
DM_free(uri);
}
return SUCCESS_RETURN;
}
void dm_server_alcs_event_handler(void *pcontext, void *phandle, iotx_alcs_event_msg_t *msg)
{
}
#if !defined(DEVICE_MODEL_RAWDATA_SOLO)
void dm_server_thing_service_property_set(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
dm_server_alcs_context_t *alcs_context = NULL;
res = _dm_server_malloc_context(remote, message, &alcs_context);
if (res != SUCCESS_RETURN) {
return;
}
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = paths;
source.payload = (unsigned char *)message->payload;
source.payload_len = message->payloadlen;
source.context = alcs_context;
dest.uri_name = DM_URI_THING_SERVICE_PROPERTY_SET;
res = dm_msg_proc_thing_service_property_set(&source, &dest, &request, &response);
if (res < SUCCESS_RETURN) {
dm_server_free_context(alcs_context);
return;
}
#ifdef LOG_REPORT_TO_CLOUD
{
extern void send_permance_info(char *input, int input_len, char *comments, int report_format);
if (SUCCESS_RETURN == check_target_msg(request.id.value, request.id.value_length)) {
send_permance_info(request.id.value, request.id.value_length, "2", 1);
}
}
#endif
dm_msg_response(DM_MSG_DEST_LOCAL, &request, &response, "{}", strlen("{}"), (void *)alcs_context);
dm_server_free_context(alcs_context);
}
void dm_server_thing_service_request(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
dm_msg_source_t source;
dm_server_alcs_context_t *alcs_context = NULL;
res = _dm_server_malloc_context(remote, message, &alcs_context);
if (res != SUCCESS_RETURN) {
return;
}
memset(&source, 0, sizeof(dm_msg_source_t));
source.uri = paths;
source.payload = (unsigned char *)message->payload;
source.payload_len = message->payloadlen;
source.context = alcs_context;
if (dm_msg_proc_thing_service_request(&source) < 0) {
dm_server_free_context(alcs_context);
}
}
void dm_server_thing_service_property_get(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
dm_server_alcs_context_t *alcs_context = NULL;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
unsigned char *data = NULL;
int data_len = 0;
res = _dm_server_malloc_context(remote, message, &alcs_context);
if (res != SUCCESS_RETURN) {
return;
}
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = paths;
source.payload = (unsigned char *)message->payload;
source.payload_len = message->payloadlen;
source.context = alcs_context;
dest.uri_name = DM_URI_THING_SERVICE_PROPERTY_GET;
dm_msg_proc_thing_service_property_get(&source, &dest, &request, &response, &data, &data_len);
#ifdef DEPRECATED_LINKKIT
dm_msg_response(DM_MSG_DEST_LOCAL, &request, &response, (char *)data, data_len, alcs_context);
DM_free(data);
dm_server_free_context(alcs_context);
#endif
}
void dm_server_thing_service_property_post(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
dm_server_alcs_context_t *alcs_context = NULL;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
res = _dm_server_malloc_context(remote, message, &alcs_context);
if (res != SUCCESS_RETURN) {
return;
}
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = paths;
source.payload = (unsigned char *)message->payload;
source.payload_len = message->payloadlen;
source.context = alcs_context;
dest.uri_name = DM_URI_THING_EVENT_PROPERTY_POST;
dm_msg_proc_thing_service_property_post(&source, &dest, &request, &response);
dm_msg_response(DM_MSG_DEST_LOCAL, &request, &response, "{}", strlen("{}"), alcs_context);
dm_server_free_context(alcs_context);
}
#endif
void dm_server_thing_dev_core_service_dev(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message)
{
int res = 0;
dm_server_alcs_context_t *alcs_context = NULL;
dm_msg_source_t source;
dm_msg_dest_t dest;
dm_msg_request_payload_t request;
dm_msg_response_t response;
unsigned char *data = NULL;
int data_len = 0;
res = _dm_server_malloc_context(remote, message, &alcs_context);
if (res != SUCCESS_RETURN) {
return;
}
memset(&source, 0, sizeof(dm_msg_source_t));
memset(&dest, 0, sizeof(dm_msg_dest_t));
memset(&request, 0, sizeof(dm_msg_request_payload_t));
memset(&response, 0, sizeof(dm_msg_response_t));
source.uri = paths;
source.payload = (unsigned char *)message->payload;
source.payload_len = message->payloadlen;
source.context = alcs_context;
dest.uri_name = DM_URI_DEV_CORE_SERVICE_DEV;
res = dm_msg_proc_thing_dev_core_service_dev(&source, &dest, &request, &response, &data, &data_len);
if (res < SUCCESS_RETURN) {
dm_server_free_context(alcs_context);
return;
}
dm_msg_response(DM_MSG_DEST_LOCAL, &request, &response, (char *)data, data_len, alcs_context);
if (response.code == IOTX_DM_ERR_CODE_SUCCESS) {
DM_free(data);
}
dm_server_free_context(alcs_context);
}
#endif

View File

@@ -0,0 +1,29 @@
#ifndef _DM_SERVER_H_
#define _DM_SERVER_H_
#ifdef ALCS_ENABLED
typedef struct {
const char *uri_name;
const char *uri_prefix;
int auth_type;
CoAPRecvMsgHandler callback;
} dm_server_uri_map_t;
#define DM_SERVER_ALCS_NO_AUTH (0)
#define DM_SERVER_ALCS_AUTH (1)
void dm_server_alcs_event_handler(void *pcontext, void *phandle, iotx_alcs_event_msg_t *msg);
int dm_server_subscribe_all(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1]);
void dm_server_thing_service_property_set(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message);
void dm_server_thing_service_property_get(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message);
void dm_server_thing_service_property_post(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message);
void dm_server_thing_dev_core_service_dev(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message);
void dm_server_thing_service_request(CoAPContext *context, const char *paths, NetworkAddr *remote,
CoAPMessage *message);
#endif
#endif

View File

@@ -0,0 +1,140 @@
#include "iotx_dm_internal.h"
#ifdef ALCS_ENABLED
static dm_server_ctx_t g_dm_server_ctx = {0};
static dm_server_ctx_t *dm_server_get_ctx(void)
{
return &g_dm_server_ctx;
}
int dm_server_open(void)
{
dm_server_ctx_t *ctx = dm_server_get_ctx();
iotx_alcs_param_t alcs_param;
iotx_alcs_event_handle_t event_handle;
memset(&alcs_param, 0x0, sizeof(iotx_alcs_param_t));
memset(&event_handle, 0x0, sizeof(iotx_alcs_event_handle_t));
alcs_param.group = (char *)DM_SERVER_ALCS_ADDR;
alcs_param.port = DM_SERVER_ALCS_PORT;
alcs_param.send_maxcount = DM_SERVER_ALCS_SEND_MAXCOUNT;
alcs_param.waittime = DM_SERVER_ALCS_WAITTIME;
alcs_param.obs_maxcount = DM_SERVER_ALCS_OBS_MAXCOUNT;
alcs_param.res_maxcount = DM_SERVER_ALCS_RES_MAXCOUNT;
alcs_param.role = IOTX_ALCS_ROLE_CLIENT | IOTX_ALCS_ROLE_SERVER;
event_handle.h_fp = dm_server_alcs_event_handler;
event_handle.pcontext = NULL;
alcs_param.handle_event = &event_handle;
ctx->conn_handle = iotx_alcs_construct(&alcs_param);
if (ctx->conn_handle == NULL) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int dm_server_connect(void)
{
dm_server_ctx_t *ctx = dm_server_get_ctx();
return iotx_alcs_cloud_init(ctx->conn_handle);
}
int dm_server_close(void)
{
dm_server_ctx_t *ctx = dm_server_get_ctx();
return iotx_alcs_destroy(&ctx->conn_handle);
}
int dm_server_send(char *uri, unsigned char *payload, int payload_len, void *context)
{
int res = 0;
dm_server_ctx_t *ctx = dm_server_get_ctx();
iotx_alcs_msg_t alcs_msg;
dm_server_alcs_context_t *alcs_context = (dm_server_alcs_context_t *)context;
memset(&alcs_msg, 0, sizeof(iotx_alcs_msg_t));
alcs_msg.group_id = 0;
alcs_msg.ip = alcs_context ? alcs_context->ip : NULL;
alcs_msg.port = alcs_context ? alcs_context->port : 0;
alcs_msg.msg_code = (alcs_context && alcs_context->token_len
&& alcs_context->token) ? ITOX_ALCS_COAP_MSG_CODE_205_CONTENT : ITOX_ALCS_COAP_MSG_CODE_GET;
alcs_msg.msg_type = IOTX_ALCS_MESSAGE_TYPE_CON;
alcs_msg.uri = uri;
alcs_msg.payload = payload;
alcs_msg.payload_len = payload_len;
if (alcs_context == NULL) {
res = iotx_alcs_observe_notify(ctx->conn_handle, alcs_msg.uri, alcs_msg.payload_len, alcs_msg.payload);
dm_log_info("Send Observe Notify Result %d", res);
} else if (alcs_context->ip && alcs_context->port && NULL == alcs_context->token) {
res = iotx_alcs_send(ctx->conn_handle, &alcs_msg);
dm_log_info("Send Result %d", res);
} else if (alcs_context->ip && alcs_context->port && alcs_context->token_len && alcs_context->token) {
res = iotx_alcs_send_Response(ctx->conn_handle, &alcs_msg, (uint8_t)alcs_context->token_len,
(uint8_t *)alcs_context->token);
dm_log_info("Send Response Result %d", res);
}
return res;
}
int dm_server_subscribe(char *uri, CoAPRecvMsgHandler callback, int auth_type)
{
int res = 0;
dm_server_ctx_t *ctx = dm_server_get_ctx();
iotx_alcs_res_t alcs_res;
memset(&alcs_res, 0, sizeof(iotx_alcs_res_t));
alcs_res.uri = uri;
alcs_res.msg_ct = IOTX_ALCS_MESSAGE_CT_APP_JSON;
alcs_res.msg_perm = IOTX_ALCS_MESSAGE_PERM_GET;
alcs_res.maxage = 60;
alcs_res.need_auth = auth_type;
alcs_res.callback = callback;
res = iotx_alcs_register_resource(ctx->conn_handle, &alcs_res);
dm_log_info("Register Resource Result: %d", res);
return res;
}
int dm_server_add_device(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
int res = 0;
dm_server_ctx_t *ctx = dm_server_get_ctx();
res = iotx_alcs_add_sub_device(ctx->conn_handle, (const char *)product_key, (const char *)device_name);
dm_log_info("Add Device Result: %d, Product Key: %s, Device Name: %s", res, product_key, device_name);
return res;
}
int dm_server_del_device(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1])
{
int res = 0;
dm_server_ctx_t *ctx = dm_server_get_ctx();
res = iotx_alcs_remove_sub_device(ctx->conn_handle, (const char *)product_key, (const char *)device_name);
dm_log_info("Del Device Result: %d, Product Key: %s, Device Name: %s", res, product_key, device_name);
return res;
}
int dm_server_yield(void)
{
dm_server_ctx_t *ctx = dm_server_get_ctx();
return iotx_alcs_yield(ctx->conn_handle);
}
#endif

View File

@@ -0,0 +1,34 @@
#ifndef _DM_SERVER_ADAPTER_H_
#define _DM_SERVER_ADAPTER_H_
#ifdef ALCS_ENABLED
#define DM_SERVER_ALCS_ADDR "224.0.1.187"
#define DM_SERVER_ALCS_PORT (5863)
#define DM_SERVER_ALCS_SEND_MAXCOUNT (16)
#define DM_SERVER_ALCS_WAITTIME (200)
#define DM_SERVER_ALCS_OBS_MAXCOUNT (16)
#define DM_SERVER_ALCS_RES_MAXCOUNT (255)
typedef struct {
void *conn_handle;
} dm_server_ctx_t;
typedef struct {
char *ip;
uint16_t port;
char *token;
int token_len;
} dm_server_alcs_context_t;
int dm_server_open(void);
int dm_server_connect(void);
int dm_server_close(void);
int dm_server_send(char *uri, unsigned char *payload, int payload_len, void *context);
int dm_server_subscribe(char *uri, CoAPRecvMsgHandler callback, int auth_type);
int dm_server_add_device(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_server_del_device(char product_key[IOTX_PRODUCT_KEY_LEN + 1], char device_name[IOTX_DEVICE_NAME_LEN + 1]);
int dm_server_yield(void);
#endif
#endif