rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,196 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR__H
#define __DEVMGR__H
#include <stdint.h>
#include <unistd.h>
#include "aos/aos.h"
#include "service.h"
#include "devmgr_common.h"
#include "alink_export_internal.h"
//#define __DEVMGR_UT__ 1
#ifdef __DEVMGR_UT__
#include "devmgr_ut.h"
#endif
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
#define STR_SIGN_LEN (16)
#define STR_DEVID_LEN (17)
#define STR_TOKEN_LEN (6)
#define STR_UUID_LEN (32)
#define ETHER_ADDR_BYTES (6)
// add by wukong 2017-4-17
#define STR_MODEL_LEN (80 + 1)
#ifndef STR_NAME_LEN
#define STR_NAME_LEN (32 + 1)
#endif
// add by wukong end 2017-4-17
#define MODULE_NAME_DEVMGR "devmgr"
/*
*
*/
typedef enum {
DEV_TYPE_GATEWAY = 0,
DEV_TYPE_WIFI = 1,
DEV_TYPE_ZIGBEE = 2,
DEV_TYPE_BLE = 3,
DEV_TYPE_WIFI_SUB = 4,
DEV_TYPE_MAX
}
devtype_t;
/*
*
*/
typedef enum {
LINK_STATE_OFFLINE = 0,
LINK_STATE_ONLINE = 1,
} link_state_t;
/*
*
*/
typedef enum {
NETWORK_EVENT_UP = 0,
NETWORK_EVENT_DOWN = 1,
LINK_EVENT_ONLINE = 2,
LINK_EVENT_OFFLINE = 3,
LINK_EVENT_LEAVE = 4
} network_event_t;
/*
*
*/
typedef enum {
DEVICE_STATE_INITIAL = 0,
DEVICE_STATE_AUTHORISED = 1,
DEVICE_STATE_REGISTERED = 2,
DEVICE_STATE_LOGINED = 3,
DEVICE_STATE_LOGOUTED = 4
} device_state_t;
// add by wukong 2017-4-17 for router sub devices
typedef struct router_base_s {
char name[STR_NAME_LEN]; // hostname, for example, my iphone's hostname is "wujy"
char ostype[STR_NAME_LEN]; // router's sub device type, e.g "Android"
char category[STR_NAME_LEN]; // e.g "unknown"
char manufacturer[STR_NAME_LEN]; // e.g "HUAWEI","HTC", "unknown"
char model[STR_MODEL_LEN]; // e.g "PANDORABOX_NETWORKING_ROUTER_NEWIFI_PB1", "alink", "unknown"
} router_base_t;
// add by wukong end 2017-4-17
typedef struct dev_base_s {
uint8_t dev_type;
uint32_t model_id;
union {
char ether_mac[ETHER_ADDR_BYTES];
char ieee_addr[IEEE_ADDR_BYTES];
} u;
char rand[SUBDEV_RAND_BYTES];
char sign[STR_SIGN_LEN + 1];
char dev_id[STR_DEVID_LEN + 1];
char uuid[STR_UUID_LEN + 1];
char token[STR_TOKEN_LEN + 1];
uint16_t crc;
} dev_base_t;
typedef struct dev_info_s {
dlist_t list_node;
dlist_t attr_head;
dev_base_t dev_base;
// add by wukong 2017-4-17
router_base_t router_base;
// add by wukong end 2017-4-17
uint8_t device_idx; //0xff为无效值
uint8_t cloud_state;
uint8_t link_state;
void *dev_mutex;
uint8_t ref_cnt;
} dev_info_t;
typedef int32_t (*zigbee_remove_device_cb_t)(uint8_t ieee_addr[IEEE_ADDR_BYTES]);
int devmgr_get_dev_type(const char *devid_or_uuid, uint8_t *dev_type);
dev_info_t *devmgr_get_devinfo(const char *devid_or_uuid_or_mac);
#ifdef GATEWAY_SDK
//dev_info_t *devmgr_get_devinfo(const char *devid_or_uuid);
dev_info_t *devmgr_get_unknown_devinfo(const char *devid_or_uuid);
dev_info_t *devmgr_get_devinfo_by_ieeeaddr(unsigned char
ieee_addr[IEEE_ADDR_BYTES]);
int devmgr_sync_device_profile(uint8_t dev_type, unsigned int model_id);
int devmgr_authorise_device(char *devid);
/*获取全部设备model_id,提供给文件下载管理模块使用*/
int devmgr_get_all_device_modelid(uint32_t model_id[], int *num);
/*释放devinfo对象引用计数*/
void devmgr_put_devinfo_ref(dev_info_t *devinfo);
int devmgr_update_device_online_status(const char *devid, link_state_t state);
int devmgr_update_zigbee_device_online_status(uint8_t
ieee_addr[IEEE_ADDR_BYTES], uint8_t online);
int devmgr_relogin_device(const char *devid);
int devmgr_join_zigbee_device(unsigned char ieee_addr[IEEE_ADDR_BYTES],
uint32_t model_id, const char rand[SUBDEV_RAND_BYTES], const char *sign);
int devmgr_leave_zigbee_device(unsigned char ieee_addr[IEEE_ADDR_BYTES]);
void __dump_devinfo(dev_info_t *devinfo);
int devmgr_delete_device_by_devinfo(dev_info_t *devinfo);
void __dump_device_list();
//lmns依赖接口
//device -> gw,wifi设备上下线接口
//payload:{"uuid":"","mac":"","modelId":"","model":"","name":""}
int devmgr_update_wifi_device_online_status(const char *devid, uint8_t online,
const char *payload);
//app -> gw,扫码添加和删除设备
int devmgr_delete_device(const char *devid);
//payload:{"mac":"","ieeeAddr":"","modelId":"","dev_type":""}
int devmgr_add_device(const char *devid, const char *payload);
void devmgr_free_unknown_devlist(void);
//主动从设备端获取设备静态信息
int devmgr_zbnet_get_devinfo(unsigned char ieee_addr[IEEE_ADDR_BYTES]);
void devmgr_reset_all_device(void);
#endif
// add by wukong 2017-4-17
int get_mac_by_uuid(const char *uuid, char *mac);
int get_uuid_by_mac(const char *mac, char *uuid);
// add by wukong end 2017-17
int devmgr_init();
void devmgr_exit();
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,21 @@
NAME := devmgr
$(NAME)_TYPE := framework
GLOBAL_INCLUDES += .
$(NAME)_SOURCES := devmgr_alink.c devmgr_common.c devmgr.c devmgr_cache.c devmgr_router.c
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration
$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized
$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable
$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration
$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized
$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable
$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing
endif
$(NAME)_CFLAGS += -DGATEWAY_SDK

View file

@ -0,0 +1,742 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>
#include "aos/aos.h"
#include "json_parser.h"
#include "msdp.h"
#include "devmgr.h"
#include "devmgr_alink.h"
#include "devmgr_cache.h"
#include "service_manager.h"
#include "connectivity_manager.h"
#include "digest_algorithm.h"
#include "alink_protocol.h"
#include "alink_export_internal.h"
#define MODULE_NAME MODULE_NAME_DEVMGR
#define DEVMGR_SERVICE_AUTHORISE_DEVICE_LIST "AuthoriseDeviceList"
#define DEVMGR_SERVICE_REMOVE_DEVICE "RemoveDevice"
#define DEVMGR_ATTRIBUTE_JOINED_DEVICE_LIST "JoinedDeviceList"
#define DEVMGR_SERVICE_PERMITJOIN_DEVICE "PermitJoin"
#define DEMGR_JOINED_DEVINFO_STRING_FMT "{\"sn\":\"%s\",\"shortModel\":\"%08x\"}"
#define DEVMGR_JSON_KEY_IEEE_ADDR "ieeeAddr"
#define DEVMGR_JSON_KEY_MAC "mac"
#define DEVMGR_JSON_KEY_SN "sn"
#define DEVMGR_JSON_KEY_SN_SET "snSet"
#define DEVMGR_JSON_KEY_DURATION "duration"
#define DEVMGR_JSON_KEY_MODEL_ID "modelId"
#define DEVMGR_JSON_KEY_SHORT_MODEL "shortModel"
#define DEVMGR_JSON_KEY_ENABLE "enable"
/* imported from other files to pass compile */
typedef int32_t (*zigbee_permit_join_cb_t)(uint8_t duration);
typedef struct {
bool enable;
uint8_t duration; //permitjoin持续时间
uint32_t short_model; //允许加入的设备shortModel0xffff表示不指定特定shortModel
uint32_t timestamp; //permitjoin起始时间戳
} permitjoin_t;
/*defined in devmgr.c*/
extern void *devlist_lock;
extern dlist_t dev_head;
extern dlist_t unknown_dev_head;
static permitjoin_t g_permitjoin_config;
static void *disablejoin_work = NULL;
void __work_func(void *work)
{
log_trace("disable device join");
g_permitjoin_config.enable = false;
devmgr_free_unknown_devlist();
}
const char *devmgr_get_device_signature(uint32_t short_model,
const char rand[SUBDEV_RAND_BYTES], char *sign_buff, uint32_t buff_size)
{
int i = 0;
char buff[128] = {0};
unsigned char md5_ret[16] = {0};
char secret[41] = {0};
char rand_hexstr[SUBDEV_RAND_BYTES * 2 + 1] = {0};
int ret = SERVICE_RESULT_ERR;
if (buff_size <= STR_SIGN_LEN) {
log_error("buffer size is too small");
return NULL;
}
memcpy(secret, "ISsi2JtDctJf0qW0HUjF7JtJjiiJLMbcZE8wxu4E", sizeof(secret));
int len = SUBDEV_RAND_BYTES;
memcpy(buff, rand, len);
len += snprintf(buff + len, sizeof(buff) - len, "%s", secret);
digest_md5(buff, len, md5_ret);
for (i = 0; i < STR_SIGN_LEN / 2; i++) {
sprintf(sign_buff + i * 2, "%02x", md5_ret[i]);
}
bytes_2_hexstr(rand, SUBDEV_RAND_BYTES, rand_hexstr, sizeof(rand_hexstr));
log_trace("rand hexstr:%s, secret:%s, sign:%s\n", rand_hexstr, secret,
sign_buff);
return sign_buff;
}
static int devmgr_listener(int type, void *data, int dlen, void *result,
int *rlen)
{
//log_trace("DEVMGR recv %s", sm_code2string(type));
if (type == SERVICE_EVENT) {
int st = *((int *)data);
log_trace("DEVMGR recv %s, %s", sm_code2string(type), sm_code2string(st));
if (st == SERVICE_STATE_READY) {
devmgr_network_event_cb(NETWORK_EVENT_UP);
} else if (st == SERVICE_STATE_STOP || st == SERVICE_STATE_INIT) {
devmgr_network_event_cb(NETWORK_EVENT_DOWN);
}
}
return EVENT_IGNORE;
}
int stdd_get_device_service(dev_info_t *devinfo, char *service_buff,
int buff_size)
{
return 0;
}
static int devmgr_register_remote_service(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_ERR;
uint8_t service[256] = {0};
if (NULL == devinfo) {
log_info("parameter invalid");
return SERVICE_RESULT_ERR;
}
ret = stdd_get_device_service(devinfo, service, sizeof(service));
if (SERVICE_RESULT_OK != ret ||
0 == json_get_array_size(service, strlen(service))) {
log_info("The device %s no service to register\r\n", devinfo->dev_base.uuid);
return SERVICE_RESULT_OK;
} else {
log_trace("The device %s service is %s\r\n", devinfo->dev_base.uuid, service);
return msdp_register_remote_service(devinfo->dev_base.uuid, service);
}
}
int devmgr_login_device(dev_info_t *devinfo)
{
int len, ret;
uint8_t tx_buff[128] = {0};
uint8_t digest[16] = {0};
uint8_t sign[33] = {0};
uint8_t rand_hexstr[SUBDEV_RAND_BYTES * 2 + 1] = {0};
alink_data_t data = {METHOD_DEVICE_LOGIN_SUB, tx_buff};
if (devinfo->dev_base.uuid[0] == '\0') {
return SERVICE_RESULT_ERR;
}
//"sign" : "hmacmd5(sub device's token, rand + sub device's uuid)"
memcpy(tx_buff, devinfo->dev_base.rand, sizeof(devinfo->dev_base.rand));
len = sizeof(devinfo->dev_base.rand);
len += snprintf(tx_buff + len, sizeof(tx_buff) - len, "%s",
devinfo->dev_base.uuid);
digest_hmac(DIGEST_TYPE_MD5, tx_buff, len, devinfo->dev_base.token,
strlen(devinfo->dev_base.token), digest);
bytes_2_hexstr(digest, sizeof(digest), sign, sizeof(sign));
tx_buff[0] = '\0';
bytes_2_hexstr(devinfo->dev_base.rand, sizeof(devinfo->dev_base.rand),
rand_hexstr, sizeof(rand_hexstr));
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_LOGIN_SUB_FMT, devinfo->dev_base.uuid, rand_hexstr, sign)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->put((void *)&data,
sizeof(data)); //accs_put
//ret = SERVICE_RESULT_OK;
return ret;
}
int devmgr_logout_device(dev_info_t *devinfo)
{
int ret;
char tx_buff[64] = {0};
alink_data_t data = {METHOD_DEVICE_LOGOUT_SUB, tx_buff};
if (devinfo->dev_base.uuid[0] == '\0') {
return SERVICE_RESULT_ERR;
}
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_LOGOUT_SUB_FMT, devinfo->dev_base.uuid)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->put((void *)&data,
sizeof(data)); //accs_put
// TODO: if need check the return code?
//ret = SERVICE_RESULT_OK;
return ret;
}
int devmgr_register_device(dev_info_t *devinfo)
{
int ret;
char tx_buff[512] = {0};
char features[128] = {0};
char result[128] = {0};
char sign_buff[STR_SIGN_LEN + 1] = {0};
char rand_hexstr[SUBDEV_RAND_BYTES * 2 + 1] = {0};
alink_data_t data = {METHOD_DEVICE_REGISTER_SUB, tx_buff};
if (sizeof(features) == snprintf(features, sizeof(features),
FEATURE_DEVICE_LOGIN_SUB_FMT, PROTOCL_ZIGBEE, "1")) {
return SERVICE_RESULT_ERR;
}
char *sign = devinfo->dev_base.sign;
if (strcmp(get_main_dev()->config->alinkserver,
default_online_server_with_port) != 0 &&
NULL != devmgr_get_device_signature(devinfo->dev_base.model_id,
devinfo->dev_base.rand, sign_buff, sizeof(sign_buff))) {
sign = sign_buff;
}
bytes_2_hexstr(devinfo->dev_base.rand, sizeof(devinfo->dev_base.rand),
rand_hexstr, sizeof(rand_hexstr));
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_REGISTER_SUB_FMT,
devinfo->dev_base.model_id, rand_hexstr, sign,
devinfo->dev_base.dev_id, "", "", "",
"", "", "", "", features)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->get((void *)&data, sizeof(data),
result, sizeof(result));//accs_put
if (SERVICE_RESULT_OK == ret) {
int len = 0;
char *json_str = json_get_value_by_name(result, strlen(result), "token", &len,
NULL);
if (NULL == json_str) {
log_error("get token fail, result data = %s", result);
return SERVICE_RESULT_ERR;
}
strncpy(devinfo->dev_base.token, json_str,
sizeof(devinfo->dev_base.token) > len ? len : sizeof(devinfo->dev_base.token));
json_str = json_get_value_by_name(result, strlen(result), JSON_KEY_UUID, &len,
NULL);
if (NULL == json_str) {
log_error("get uuid fail, result data = %s", result);
return SERVICE_RESULT_ERR;
}
strncpy(devinfo->dev_base.uuid, json_str,
sizeof(devinfo->dev_base.uuid) > len ? len : sizeof(devinfo->dev_base.uuid));
log_info("register device success, uuid:%s, token:%s", devinfo->dev_base.uuid,
devinfo->dev_base.token);
}
return ret;
}
int devmgr_unregister_device(dev_info_t *devinfo)
{
int len, ret;
uint8_t digest[16] = {0};
uint8_t sign[33] = {0};
uint8_t tx_buff[128] = {0};
uint8_t rand_hexstr[SUBDEV_RAND_BYTES * 2 + 1] = {0};
alink_data_t data = {METHOD_DEVICE_UNREGISTER_SUB, tx_buff};
log_info("unregister device, devid:%s", devinfo->dev_base.dev_id);
if (devinfo->dev_base.uuid[0] == '\0') {
return SERVICE_RESULT_ERR;
}
bytes_2_hexstr(devinfo->dev_base.rand, sizeof(devinfo->dev_base.rand),
rand_hexstr, sizeof(rand_hexstr));
//"sign" : "hmacmd5(sub device's token, rand + sub device's uuid)"
memcpy(tx_buff, devinfo->dev_base.rand, sizeof(devinfo->dev_base.rand));
len = sizeof(devinfo->dev_base.rand);
len += snprintf(tx_buff + len, sizeof(tx_buff) - len, "%s",
devinfo->dev_base.uuid);
digest_hmac(DIGEST_TYPE_MD5, tx_buff, len, devinfo->dev_base.token,
strlen(devinfo->dev_base.token), digest);
bytes_2_hexstr(digest, sizeof(digest), sign, sizeof(sign));
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_UNREGISTER_SUB_FMT, devinfo->dev_base.uuid, rand_hexstr, sign)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->put((void *)&data,
sizeof(data)); //accs_put
ret = SERVICE_RESULT_OK;
return ret;
}
static int devmgr_authorise_device_cb(char *devid, int str_len, int type)
{
int ret = SERVICE_RESULT_OK;
char devid_str[32] = {0};
strncpy(devid_str, devid, str_len);
ret = devmgr_authorise_device(devid_str);
RET_RETURN(ret, "authorise device fail, devid:%s", devid_str);
return ret;
}
//获取临时入网设备列表
static int devmgr_get_joined_devlist_attribute_cb(char *buf, unsigned int buf_len)
{
int ret = SERVICE_RESULT_OK;
dev_info_t *pos = NULL;
char ieeeAddr[STR_DEVID_LEN + 1] = {0};
int len = 0;
len += snprintf(buf, buf_len - len - 1, "[");
os_mutex_lock(devlist_lock);
dlist_for_each_entry(&unknown_dev_head, pos, dev_info_t, list_node) {
get_ieeeaddr_string_by_extaddr(pos->dev_base.u.ieee_addr, ieeeAddr,
sizeof(ieeeAddr));
len += snprintf(buf + len, buf_len - len - 1, DEMGR_JOINED_DEVINFO_STRING_FMT,
ieeeAddr, (unsigned int)pos->dev_base.model_id);
//buff太小
if (len == buf_len - 1) {
os_mutex_unlock(devlist_lock);
return SERVICE_BUFFER_INSUFFICENT;
}
}
os_mutex_unlock(devlist_lock);
buf[len] = ']';
buf[len + 1] = '\0';
return SERVICE_RESULT_OK;
}
static int devmgr_authorise_devlist_service_cb(char *args, char *buf,
unsigned int buf_len)
{
//args:{"ieeeAddrs":["", ...]}
int ret = SERVICE_RESULT_OK;
char *ieee_addrs = NULL;
int str_len = 0;
ieee_addrs = json_get_value_by_name(args, strlen(args), DEVMGR_JSON_KEY_SN_SET,
&str_len, NULL);
PTR_RETURN(ieee_addrs, ret, "get snSet fail, rpc args:%s", args);
//遍历json数组并执行处理函数
char back_chr = 0;
backup_json_str_last_char(ieee_addrs, str_len, back_chr);
char *str_pos, *entry;
int entry_len, type;
json_array_for_each_entry(ieee_addrs, str_pos, entry, entry_len, type) {
ret = devmgr_authorise_device_cb(entry, entry_len, type);
RET_LOG(ret, "authorise device fail, ieee_addrs:%s", ieee_addrs);
}
restore_json_str_last_char(ieee_addrs, str_len, back_chr);
devmgr_free_unknown_devlist();
return SERVICE_RESULT_OK;
}
static int devmgr_permitjoin_service_cb(char *args, char *buf,
unsigned int buf_len)
{
int str_len, ret = SERVICE_RESULT_ERR;
char buff[32] = {0};
char *str_pos = NULL;
//args:{"enable", "duration":"","shortModel":""}
//enable,获取使能状态
str_pos = json_get_value_by_name(args, strlen(args), DEVMGR_JSON_KEY_ENABLE,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get enable fail, args:%s", args);
g_permitjoin_config.enable = (*str_pos != '0') ? true : false;
//duration
str_pos = json_get_value_by_name(args, strlen(args), DEVMGR_JSON_KEY_DURATION,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get duration fail, args:%s", args);
strncpy(buff, str_pos, str_len);
g_permitjoin_config.duration = (uint8_t)atoi(buff);
if (g_permitjoin_config.duration < 1) {
g_permitjoin_config.enable = false;
}
memset(buff, 0, sizeof(buff));
#if 0/*2016.11.15开始modelId参数变更为shortModel*/
str_pos = json_get_value_by_name(args, strlen(args),
DEVMGR_JSON_KEY_SHORT_MODEL, &str_len, NULL);
PTR_RETURN(str_pos, ret, "get short model fail, args:%s", args);
strncpy(buff, str_pos, str_len);
#else/*获取shortModel失败再获取modelId过渡使用*/
str_pos = json_get_value_by_name(args, strlen(args), DEVMGR_JSON_KEY_MODEL_ID,
&str_len, NULL);
if (NULL == str_pos) {
str_pos = json_get_value_by_name(args, strlen(args),
DEVMGR_JSON_KEY_SHORT_MODEL, &str_len, NULL);
PTR_RETURN(str_pos, ret, "get short model fail, args:%s", args);
}
strncpy(buff, str_pos, str_len);
#endif
sscanf(buff, "%08x", (unsigned int *)&g_permitjoin_config.short_model);
//设置时间戳
g_permitjoin_config.timestamp = time(NULL);
if (alink_cb_func[_ALINK_ZIGBEE_PERMIT_JOIN]) {
ret = ((zigbee_permit_join_cb_t)alink_cb_func[_ALINK_ZIGBEE_PERMIT_JOIN])(
g_permitjoin_config.duration);
RET_RETURN(ret, "permit join fail");
} else {
log_error("permit_device callback is NULL");
}
//设置定时器
aos_cancel_work(disablejoin_work, __work_func, NULL);
if (g_permitjoin_config.enable == true &&
g_permitjoin_config.duration > 0) {
log_trace("delay disable device join, duration:%d",
g_permitjoin_config.duration);
disablejoin_work = aos_loop_schedule_work(g_permitjoin_config.duration * 1000,
__work_func, NULL, NULL, NULL);
}
return ret;
}
static int devmgr_remove_device_service_cb(char *args, char *buf,
unsigned int buf_len)
{
int str_len, ret = SERVICE_RESULT_ERR;
char ieee_addr[STR_DEVID_LEN + 1] = {0};
char *str_pos = NULL;
//args:{"ieeeAddr":""}
str_pos = json_get_value_by_name(args, strlen(args), DEVMGR_JSON_KEY_SN,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get sn fail, args:%s", args);
strncpy(ieee_addr, str_pos,
sizeof(ieee_addr) > str_len ? str_len : sizeof(ieee_addr) - 1);
ret = devmgr_delete_device(ieee_addr);
RET_RETURN(ret, CALL_FUCTION_FAILED, "devmgr_delete_device");
return ret;
}
static int devmgr_network_down_event_handler(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_OK;
switch (devinfo->cloud_state) {
case DEVICE_STATE_AUTHORISED:
case DEVICE_STATE_LOGOUTED:
//nothing todo
break;
case DEVICE_STATE_REGISTERED:
case DEVICE_STATE_LOGINED:
ret = devmgr_logout_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
break;
}
devinfo->cloud_state = DEVICE_STATE_LOGOUTED;
break;
default:
break;
}
return ret;
}
void devmgr_delay_disable_join(int duration)
{
//permit join nothing todi
if (g_permitjoin_config.enable == true) {
return;
}
log_trace("permit device join, duration:%d", duration);
g_permitjoin_config.short_model = DEVMGR_PERMITJOIN_ANY_MODEL;
g_permitjoin_config.enable = true;
aos_cancel_work(disablejoin_work, __work_func, NULL);
disablejoin_work = aos_loop_schedule_work(duration * 1000, __work_func, NULL, NULL,
NULL);
return;
}
int devmgr_network_leave_event_handler(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_OK;
switch (devinfo->cloud_state) {
case DEVICE_STATE_AUTHORISED:
//nothing todo
break;
case DEVICE_STATE_REGISTERED:
case DEVICE_STATE_LOGINED:
case DEVICE_STATE_LOGOUTED:
ret = devmgr_unregister_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
break;
}
devinfo->cloud_state = DEVICE_STATE_INITIAL;
break;
default:
break;
}
return ret;
}
int devmgr_network_up_event_handler(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_OK;
switch (devinfo->cloud_state) {
case DEVICE_STATE_AUTHORISED:
//发起设备注册,注册成功则更新设备信息和状态
ret = devmgr_register_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
break;
}
ret = devmgr_login_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
break;
}
devmgr_register_remote_service(devinfo);
devinfo->cloud_state = DEVICE_STATE_LOGINED;
break;
case DEVICE_STATE_REGISTERED:
case DEVICE_STATE_LOGOUTED:
if (LINK_STATE_ONLINE == devinfo->link_state) {
ret = devmgr_login_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
log_warn("login sub device fail, devid:%s,uuid:%s, ret: %d",
devinfo->dev_base.dev_id, devinfo->dev_base.uuid, ret);
/* ALINK_CODE_ERROR_SUBDEV_NO_RELATIONSHIP:
* sub device relation not exist, delete the device from the gateway
* ALINK_CODE_ERROR_SUBDEV_INVALID_UUID:
* gw or sub device's uuid is invalid, delete the device from the gateway
*/
if (ALINK_CODE_ERROR_SUBDEV_NO_RELATIONSHIP == ret
|| ALINK_CODE_ERROR_SUBDEV_INVALID_UUID == ret) {
devinfo->cloud_state = DEVICE_STATE_AUTHORISED; /*needn't do unregister*/
devmgr_delete_device_by_devinfo(devinfo);
ret = SERVICE_RESULT_OK;
}
break;
}
devmgr_register_remote_service(devinfo);
devinfo->cloud_state = DEVICE_STATE_LOGINED;
}
break;
case DEVICE_STATE_LOGINED:
default:
break;
}
return ret;
}
uint32_t devmgr_get_permitjoin_short_model()
{
//app端触发入网/按键触发入网再超时时间内置直接返回指定short_model
if (g_permitjoin_config.timestamp + g_permitjoin_config.duration > time(NULL)
|| g_permitjoin_config.duration == 0xff) {
return g_permitjoin_config.short_model;
}
//网关按键触发入网
return DEVMGR_PERMITJOIN_ANY_MODEL;
}
static int devmgr_update_status_cb(char *name, int name_len, char *value,
int value_len, int value_type, const char *devid)
{
int str_len, ret = SERVICE_RESULT_ERR;
char attr_name[MAX_ATTR_NAME_LEN] = {0};
char attr_value[128] = {0};
//忽略uuid,attrset参数
if (strcmp(name, JSON_KEY_ATTRSET) == 0 || strcmp(name, JSON_KEY_UUID)) {
return SERVICE_RESULT_OK;
}
strncpy(attr_name, name, sizeof(attr_name) - 1);
char *str_pos = json_get_value_by_name(value, value_len, JSON_KEY_VALUE,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get value fail, attr_value:%s", value);
strncpy(attr_value, str_pos,
sizeof(attr_value) > str_len ? str_len : sizeof(attr_value) - 1);
log_trace("attr_name:%s, attr_value:%s", attr_name, attr_value);
ret = devmgr_update_attr_cache(devid, attr_name, attr_value);
return ret;
}
/*通告局域网内设备状态变更*/
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["OnOff"],"OnOff":{"value":"1","when":"1404443369"}}
*/
int devmgr_annunciate_device_status(const char *devid, char *params)
{
int ret = SERVICE_RESULT_OK;
/* unknonw device */
dev_info_t *devinfo = devmgr_get_devinfo(devid);
PTR_RETURN(devinfo, ret, "get devinfo fail, devid:%s", devid);
devmgr_put_devinfo_ref(devinfo);
//遍历attr
char *pos, *key, *val;
int klen, vlen, vtype;
json_object_for_each_kv(params, pos, key, klen, val, vlen, vtype) {
ret = devmgr_update_status_cb(key, klen, val, vlen, vtype, devid);
RET_LOG(ret, "update device status fail, key:%s, value:%s", key, val);
}
return ret;
}
int devmgr_link_state_event_handler(dev_info_t *devinfo, link_state_t state)
{
int ret = SERVICE_RESULT_ERR;
devinfo->link_state = state;
if (LINK_STATE_ONLINE == state) {
ret = devmgr_network_up_event_handler(devinfo);
RET_LOG(ret, CALL_FUCTION_FAILED, "devmgr_network_up_event_handler");
} else if (LINK_STATE_OFFLINE == state) {
ret = devmgr_network_down_event_handler(devinfo);
RET_LOG(ret, CALL_FUCTION_FAILED, "devmgr_network_down_event_handler");
} else {
log_error("unknown link state, state:%d", state);
}
return ret;
}
int devmgr_network_event_cb(network_event_t event)
{
//遍历设备逐个注册、attatch
int ret = SERVICE_RESULT_OK;
dev_info_t *pos, *next = NULL;
os_mutex_lock(devlist_lock);
dlist_for_each_entry(&unknown_dev_head, pos, dev_info_t, list_node) {
switch (event) {
case NETWORK_EVENT_DOWN: //network disconnected
//ret = devmgr_network_down_event_handler(pos);
pos->cloud_state = DEVICE_STATE_LOGOUTED;
break;
case NETWORK_EVENT_UP: //network connected
ret = devmgr_network_up_event_handler(pos);
break;
default:
break;
}
}
os_mutex_unlock(devlist_lock);
return ret;
}
int devmgr_alink_init()
{
int ret = SERVICE_RESULT_OK;
memset(&g_permitjoin_config, 0, sizeof(g_permitjoin_config));
#if 0
//属性注册
ret = alink_register_attribute(DEVMGR_ATTRIBUTE_JOINED_DEVICE_LIST,
devmgr_get_joined_devlist_attribute_cb, NULL);
//服务注册
ret = alink_register_service(DEVMGR_SERVICE_AUTHORISE_DEVICE_LIST,
devmgr_authorise_devlist_service_cb);
ret = alink_register_service(DEVMGR_SERVICE_REMOVE_DEVICE,
devmgr_remove_device_service_cb);
ret = alink_register_service(DEVMGR_SERVICE_PERMITJOIN_DEVICE,
devmgr_permitjoin_service_cb);
#endif
sm_attach_service("accs", &devmgr_listener);
return ret;
}
void devmgr_alink_exit()
{
sm_detach_service("accs", &devmgr_listener);
aos_cancel_work(disablejoin_work, __work_func, NULL);
alink_unregister_service(DEVMGR_SERVICE_AUTHORISE_DEVICE_LIST);
alink_unregister_service(DEVMGR_SERVICE_REMOVE_DEVICE);
alink_unregister_service(DEVMGR_SERVICE_PERMITJOIN_DEVICE);
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR_ALINK__H__
#define __DEVMGR_ALINK__H__
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PROTOCL_ZIGBEE "zigbee"
#define PROTOCL_RF433 "rf433"
#define METHOD_DEVICE_REGISTER_SUB "device.registerSub"
#define METHOD_DEVICE_UNREGISTER_SUB "device.unregisterSub"
#define METHOD_DEVICE_LOGIN_SUB "device.loginSub"
#define METHOD_DEVICE_LOGOUT_SUB "device.logoutSub"
#define DEVMGR_PERMITJOIN_ANY_MODEL (0xffffffff)
/*按键触发入网开关,默认超时时间*/
#define DEVMGR_DEFAULT_PERMITJOIN_DURATION 240
//"sign":"hmacmd5(secret, rand+sn)"
#define PARAMS_DEVICE_REGISTER_SUB_FMT ("{\"shortModel\":\"%08x\",\"rand\":\"%s\",\"sign\":\"%s\","\
"\"sn\":\"%s\",\"model\":\"%s\",\"mac\":\"%s\",\"version\":\"%s\",\"name\":\"%s\","\
"\"barcode\":\"%s\",\"cid\":\"%s\",\"description\":\"%s\",\"features\":%s}")
#define PARAMS_DEVICE_UNREGISTER_SUB_FMT ("{\"uuid\":\"%s\",\"rand\":\"%s\",\"sign\":\"%s\"}")
//"sign" : "hmacmd5(sub device's token, rand + sub device's uuid)"
#define PARAMS_DEVICE_LOGIN_SUB_FMT ("{\"uuid\":\"%s\",\"rand\":\"%s\",\"sign\":\"%s\"}")
#define PARAMS_DEVICE_LOGOUT_SUB_FMT ("{\"uuid\":\"%s\"}")
#define FEATURE_DEVICE_LOGIN_SUB_FMT ("{\"linkCapability\":[{\"protocol\":\"%s\",\"profile\":\"%s\"}]}")
#define RESULT_DEVICE_REGISTER_SUB_FMT ("{\"uuid\":\"%s\",\"token\":\"%s\"}")
int devmgr_network_up_event_handler(dev_info_t *devinfo);
uint32_t devmgr_get_permitjoin_short_model();
/*通告局域网内设备状态变更*/
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["OnOff"],"OnOff":{"value":"1","when":"1404443369"}}
*/
const char *devmgr_get_device_signature(uint32_t short_model,
const char rand[SUBDEV_RAND_BYTES], char *sign_buff, uint32_t buff_size);
int devmgr_login_device(dev_info_t *devinfo);
int devmgr_logout_device(dev_info_t *devinfo);
int devmgr_register_device(dev_info_t *devinfo);
int devmgr_unregister_device(dev_info_t *devinfo);
int devmgr_annunciate_device_status(const char *devid, char *params);
int devmgr_link_state_event_handler(dev_info_t *devinfo, link_state_t state);
int devmgr_network_leave_event_handler(dev_info_t *devinfo);
int devmgr_network_event_cb(network_event_t event);
void devmgr_delay_disable_join(int duration);
int devmgr_alink_init();
void devmgr_alink_exit();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,277 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "aos/aos.h"
#include "os.h"
#include "devmgr.h"
#include "devmgr_cache.h"
#define MODULE_NAME MODULE_NAME_DEVMGR
typedef struct attr_cache_s {
dlist_t list_node;
char *attr_name;
char *attr_value;
} attr_cache_t;
static void *__cache_dup_string(const char *src)
{
char *dst;
int n ;
if (!src) {
return NULL;
}
n = strlen(src);
dst = (char *)os_malloc(n + 1);
if (!dst) {
return NULL;
}
memcpy(dst, src, n);
dst[n] = '\0';
return dst;
}
static void *__cache_new_buff(unsigned int buff_size)
{
void *buff = os_malloc(buff_size);
if (NULL != buff) {
memset(buff, 0, buff_size);
}
return buff;
}
static void __cache_free_buff(void *buff)
{
if (buff) {
os_free(buff);
}
}
static void *__cache_renew_buff(char *src, uint32_t new_size)
{
__cache_free_buff(src);
return __cache_new_buff(new_size);
}
static attr_cache_t *__new_attr_node(const char *attr_name,
const char *attr_value)
{
attr_cache_t *attr_node = __cache_new_buff(sizeof(attr_cache_t));
PTR_GOTO(attr_node, err, "pstrdup error");
memset(attr_node, 0, sizeof(attr_cache_t));
attr_node->attr_name = __cache_dup_string(attr_name);
PTR_GOTO(attr_node->attr_name, err, "pstrdup error");
attr_node->attr_value = __cache_dup_string(attr_value);
PTR_GOTO(attr_node->attr_value, err, "pstrdup error");
return attr_node;
err:
if (attr_node != NULL) {
if (attr_node->attr_name) {
__cache_free_buff(attr_node->attr_name);
}
if (attr_node->attr_value) {
__cache_free_buff(attr_node->attr_value);
}
__cache_free_buff((char *)attr_node);
}
return NULL;
}
static void __free_attr_node(attr_cache_t *cache)
{
if (cache != NULL) {
if (cache->attr_name) {
__cache_free_buff(cache->attr_name);
}
if (cache->attr_value) {
__cache_free_buff(cache->attr_value);
}
__cache_free_buff((char *)cache);
}
}
static int __get_attr_cache(dlist_t *attr_head, const char *attr_name,
char *attr_value_buff, int buff_size)
{
attr_cache_t *attr_node = NULL;
char *buff = NULL;
dlist_for_each_entry(attr_head, attr_node, attr_cache_t, list_node) {
if (strcmp(attr_node->attr_name, attr_name) == 0) {
if (buff_size <= strlen(attr_node->attr_value)) {
return SERVICE_BUFFER_INSUFFICENT;
}
strncpy(attr_value_buff, attr_node->attr_value, buff_size);
return SERVICE_RESULT_OK;
}
}
return SERVICE_RESULT_ERR;
}
static int __read_attr_cache(dlist_t *attr_head, const char *attr_name,
char **attr_value)
{
attr_cache_t *attr_node = NULL;
char *buff = NULL;
dlist_for_each_entry(attr_head, attr_node, attr_cache_t, list_node) {
if (strcmp(attr_node->attr_name, attr_name) == 0) {
buff = os_malloc(strlen(attr_node->attr_value) + 1);
PTR_RETURN(buff, SERVICE_RESULT_ERR, "pmalloc failed");
strncpy(buff, attr_node->attr_value, strlen(attr_node->attr_value) + 1);
*attr_value = buff;
return SERVICE_RESULT_OK;
}
}
return SERVICE_RESULT_ERR;
}
static int __update_attr_cache(dlist_t *attr_head, const char *attr_name,
const char *attr_value)
{
attr_cache_t *attr_node = NULL;
char *buff = NULL;
dlist_for_each_entry(attr_head, attr_node, attr_cache_t, list_node) {
if (strcmp(attr_node->attr_name, attr_name) == 0) {
attr_node->attr_value = __cache_renew_buff(attr_node->attr_value,
strlen(attr_value) + 1);
strncpy(attr_node->attr_value, attr_value, strlen(attr_value) + 1);
return SERVICE_RESULT_OK;
}
}
attr_node = __new_attr_node(attr_name, attr_value);
PTR_RETURN(attr_node, SERVICE_RESULT_ERR, CALL_FUCTION_FAILED,
"__new_attr_node")
dlist_add_tail(&attr_node->list_node, attr_head);
return SERVICE_RESULT_OK;
}
static void __free_attr_cache_list(dlist_t *cache_head)
{
attr_cache_t *cache;
dlist_t *next;
dlist_for_each_entry_safe(cache_head, next, cache, attr_cache_t, list_node) {
__free_attr_node(cache);
}
}
void __dump_attr_cache(dlist_t *attr_head)
{
os_printf("\tattr cache:\n");
attr_cache_t *cache;
dlist_for_each_entry(attr_head, cache, attr_cache_t, list_node) {
os_printf("\t\t%s: %s\n", cache->attr_name, cache->attr_value);
}
}
/*读取子设备属性缓存*/
int devmgr_get_attr_cache(const char *devid_or_uuid, const char *attr_name,
char *attr_value_buff, int buff_size)
{
int ret = SERVICE_RESULT_ERR;
dev_info_t *devinfo = devmgr_get_devinfo(devid_or_uuid);
PTR_RETURN(devinfo, SERVICE_RESULT_ERR, CALL_FUCTION_FAILED,
"devmgr_get_devinfo");
os_mutex_lock(devinfo->dev_mutex);
ret = __get_attr_cache(&devinfo->attr_head, attr_name, attr_value_buff,
buff_size);
os_mutex_unlock(devinfo->dev_mutex);
devmgr_put_devinfo_ref(devinfo);
return ret;
}
/*读取子设备属性缓存*/
int devmgr_read_attr_cache(const char *devid_or_uuid, const char *attr_name,
char **attr_value)
{
int ret = SERVICE_RESULT_ERR;
dev_info_t *devinfo = devmgr_get_devinfo(devid_or_uuid);
PTR_RETURN(devinfo, SERVICE_RESULT_ERR, CALL_FUCTION_FAILED,
"devmgr_get_devinfo");
os_mutex_lock(devinfo->dev_mutex);
ret = __read_attr_cache(&devinfo->attr_head, attr_name, attr_value);
os_mutex_unlock(devinfo->dev_mutex);
devmgr_put_devinfo_ref(devinfo);
return ret;
}
/*更新子设备属性缓存*/
int devmgr_update_attr_cache(const char *devid_or_uuid, const char *attr_name,
const char *attr_value)
{
int ret = SERVICE_RESULT_ERR;
dev_info_t *devinfo = devmgr_get_devinfo(devid_or_uuid);
PTR_RETURN(devinfo, ret, CALL_FUCTION_FAILED, "devmgr_get_devinfo")
os_mutex_lock(devinfo->dev_mutex);
ret = __update_attr_cache(&devinfo->attr_head, attr_name, attr_value);
os_mutex_unlock(devinfo->dev_mutex);
devmgr_put_devinfo_ref(devinfo);
return ret;
}
void devmgr_free_device_cache(dev_info_t *devinfo)
{
__free_attr_cache_list(&devinfo->attr_head);
}
int devmgr_cache_init()
{
return SERVICE_RESULT_OK;
}
void devmgr_cache_exit()
{
return;
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR_CACHE__H__
#define __DEVMGR_CACHE__H__
#include "devmgr.h"
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
void __dump_attr_cache(dlist_t *attr_head);
int devmgr_get_attr_cache(const char *devid_or_uuid, const char *attr_name,
char *attr_value_buff, int buff_size);
int devmgr_read_attr_cache(const char *devid_or_uuid, const char *attr_name,
char **attr_value);
int devmgr_update_attr_cache(const char *devid_or_uuid, const char *attr_name,
const char *attr_value);
void devmgr_free_device_cache(dev_info_t *devinfo);
int devmgr_cache_init();
void devmgr_cache_exit();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aos/errno.h>
#include "devmgr_common.h"
#include "service.h"
#define IEEE_ADDR_STRING_FMT "%02x%02x%02x%02x%02x%02x%02x%02x"
int bytes_2_hexstr(const uint8_t *buf, int buf_len, char *hexstr,
int hex_buf_len)
{
int len = 0;
int index = 0;
if (hex_buf_len <= buf_len * 2) {
return SERVICE_RESULT_ERR;
}
while (index < buf_len) {
len += snprintf(hexstr + len, hex_buf_len - len, "%02x", *(buf + index));
index++;
}
*(hexstr + len) = '\0';
return SERVICE_RESULT_OK;
}
int hexstr_2_bytes(const char *hexstr, uint8_t *buf, int *buf_len)
{
int len = 0;
int index = 0;
unsigned int arr = 0;
if (strlen(hexstr) / 2 > *buf_len + 1) {
return SERVICE_RESULT_ERR;
}
while (len < strlen(hexstr)) {
if (1 != sscanf(hexstr, "%02x", &arr )) {
return SERVICE_RESULT_ERR;
}
*(buf + index) = (uint8_t) * (&arr);
index++;
len += 2;
}
*buf_len = index;
return SERVICE_RESULT_OK;
}
int get_ieeeaddr_by_string(char *ieeeaddr_string,
uint8_t extaddr[IEEE_ADDR_BYTES])
{
int i;
unsigned int arr[8] = {0};
if (NULL == ieeeaddr_string) {
return SERVICE_RESULT_ERR;
}
if (IEEE_ADDR_BYTES != sscanf(ieeeaddr_string, IEEE_ADDR_STRING_FMT,
&arr[0], &arr[1], &arr[2], &arr[3],
&arr[4], &arr[5], &arr[6], &arr[7])) {
return SERVICE_RESULT_ERR;
}
for (i = 0; i < 8; i++) {
extaddr[i] = (uint8_t)arr[i];
}
return SERVICE_RESULT_OK;
}
char *get_ieeeaddr_string_by_extaddr(uint8_t extaddr[IEEE_ADDR_BYTES],
char *ieeeaddr_buf, int buf_len)
{
int len = 0;
len = snprintf(ieeeaddr_buf, buf_len, IEEE_ADDR_STRING_FMT, extaddr[0],
extaddr[1], extaddr[2],
extaddr[3], extaddr[4], extaddr[5], extaddr[6], extaddr[7]);
if (len == buf_len) {
return NULL;
}
return ieeeaddr_buf;
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR_COMMON_UT__
#define __DEVMGR_COMMON_UT__
#include <stdint.h>
#include <unistd.h>
#include "alink_export_zigbee.h"
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
int bytes_2_hexstr(const uint8_t *buf, int buf_len, char *hexstr,
int hex_buf_len);
int hexstr_2_bytes(const char *hexstr, uint8_t *buf, int *buf_len);
int get_ieeeaddr_by_string(char *ieeeaddr_string,
uint8_t extaddr[IEEE_ADDR_BYTES]);
char *get_ieeeaddr_string_by_extaddr(uint8_t extaddr[IEEE_ADDR_BYTES],
char *ieeeaddr_buf, int buf_len);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,281 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>
#include "devmgr.h"
#include "devmgr_router.h"
#include "aos/aos.h"
#include "json_parser.h"
#include "msdp.h"
#include "service_manager.h"
#include "connectivity_manager.h"
#include "digest_algorithm.h"
#include "config.h"
#define MODULE_NAME MODULE_NAME_DEVMGR
extern void *devlist_lock;
extern dlist_t dev_head;
static int router_register_device(dev_info_t *devinfo)
{
int ret;
char tx_buff[512] = {0};
char result[128] = {0};
alink_data_t data = {METHOD_DEVICE_REGISTER_SUB_WIFI, tx_buff};
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_REGISTER_SUB_WIFI_FMT,
devinfo->router_base.name,
devinfo->router_base.model,
devinfo->router_base.ostype,
devinfo->router_base.category,
devinfo->dev_base.u.ether_mac,
devinfo->router_base.manufacturer)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->get((void *)&data, sizeof(data),
result, sizeof(result));
if (SERVICE_RESULT_OK == ret) {
int len = 0;
char *json_str = json_get_value_by_name(result, strlen(result), JSON_KEY_UUID,
&len, NULL);
if (NULL == json_str) {
log_error("get uuid fail, result data = %s", result);
return SERVICE_RESULT_ERR;
}
strncpy(devinfo->dev_base.uuid, json_str,
sizeof(devinfo->dev_base.uuid) > len ? len : sizeof(devinfo->dev_base.uuid));
log_info("register device success, uuid:%s", devinfo->dev_base.uuid);
}
return ret;
}
static int router_login_device(dev_info_t *devinfo)
{
int ret;
char tx_buff[512] = {0};
char result[128] = {0};
alink_data_t data = {METHOD_DEVICE_ATTACH_SUB_WIFI, tx_buff};
if (devinfo->dev_base.uuid[0] == '\0') {
return SERVICE_RESULT_ERR;
}
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_ATTACH_SUB_WIFI_FMT,
config_get_main_uuid(),
devinfo->dev_base.uuid)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->get((void *)&data, sizeof(data),
result, sizeof(result));
if (SERVICE_RESULT_OK == ret) {
int len = 0;
char *json_str = json_get_value_by_name(result, strlen(result), JSON_KEY_CODE,
&len, NULL);
if (NULL == json_str) {
log_error("get rsp code fail, result data = %s", result);
return SERVICE_RESULT_ERR;
}
log_info("attach wifi device result, code:%s", json_str);
}
return ret;
}
static int router_logout_device(dev_info_t *devinfo)
{
int ret;
char tx_buff[512] = {0};
char result[128] = {0};
alink_data_t data = {METHOD_DEVICE_DETACH_SUB_WIFI, tx_buff};
if (devinfo->dev_base.uuid[0] == '\0') {
return SERVICE_RESULT_ERR;
}
if (sizeof(tx_buff) == snprintf(tx_buff, sizeof(tx_buff),
PARAMS_DEVICE_DETACH_SUB_WIFI_FMT,
config_get_main_uuid(),
devinfo->dev_base.uuid)) {
return SERVICE_RESULT_ERR;
}
log_debug("send:%s", tx_buff);
ret = ((service_t *)sm_get_service("accs"))->get((void *)&data, sizeof(data),
result, sizeof(result));
if (SERVICE_RESULT_OK == ret) {
int len = 0;
char *json_str = json_get_value_by_name(result, strlen(result), JSON_KEY_CODE,
&len, NULL);
if (NULL == json_str) {
log_error("get rsp code fail, result data = %s", result);
return SERVICE_RESULT_ERR;
}
log_info("deattach wifi device result, code:%s", json_str);
}
return ret;
}
int router_network_down_event_handler(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_OK;
switch (devinfo->cloud_state) {
case DEVICE_STATE_LOGOUTED:
//nothing todo
break;
case DEVICE_STATE_REGISTERED:
case DEVICE_STATE_LOGINED:
ret = router_logout_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
break;
}
devinfo->cloud_state = DEVICE_STATE_LOGOUTED;
break;
default:
break;
}
return ret;
}
int router_network_up_event_handler(dev_info_t *devinfo)
{
int ret = SERVICE_RESULT_OK;
switch (devinfo->cloud_state) {
case DEVICE_STATE_LOGOUTED:
case DEVICE_STATE_INITIAL:
ret = router_register_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
goto ERR;
}
devinfo->cloud_state = DEVICE_STATE_REGISTERED;
case DEVICE_STATE_REGISTERED:
ret = router_login_device(devinfo);
if (ret != SERVICE_RESULT_OK) {
goto ERR;
}
devinfo->cloud_state = DEVICE_STATE_LOGINED;
break;
default:
break;
}
ERR:
log_error("ret = %d.", ret);
return ret;
}
int router_link_state_event_handler(dev_info_t *devinfo, link_state_t state)
{
int ret = SERVICE_RESULT_ERR;
devinfo->link_state = state;
if (LINK_STATE_ONLINE == state) {
ret = router_network_up_event_handler(devinfo);
RET_LOG(ret, CALL_FUCTION_FAILED, "devmgr_network_up_event_handler");
} else if (LINK_STATE_OFFLINE == state) {
ret = router_network_down_event_handler(devinfo);
RET_LOG(ret, CALL_FUCTION_FAILED, "devmgr_network_down_event_handler");
} else {
log_error("unknown link state, state:%d", state);
}
return ret;
}
static int router_network_event_cb(network_event_t event)
{
//±éÀúÉ豸£¬Öð¸ö×¢²á¡¢attatch
int ret = SERVICE_RESULT_OK;
dev_info_t *pos;
dlist_t *next = NULL;
os_mutex_lock(devlist_lock);
dlist_for_each_entry_safe(&dev_head, next, pos, dev_info_t, list_node) {
if (pos->dev_base.dev_type != DEV_TYPE_WIFI) {
continue;
}
switch (event) {
case NETWORK_EVENT_DOWN: //network disconnected
ret = router_network_down_event_handler(pos);
break;
case NETWORK_EVENT_UP: //network connected
ret = router_network_up_event_handler(pos);
break;
default:
break;
}
}
os_mutex_unlock(devlist_lock);
return ret;
}
static int devmgr_listener(int type, void *data, int dlen, void *result,
int *rlen)
{
if (type == SERVICE_EVENT) {
int st = *((int *)data);
log_trace("DEVMGR recv %s, %s", sm_code2string(type), sm_code2string(st));
if (st == SERVICE_STATE_READY) {
router_network_event_cb(NETWORK_EVENT_UP);
} else if (st == SERVICE_STATE_STOP || st == SERVICE_STATE_INIT) {
router_network_event_cb(NETWORK_EVENT_DOWN);
}
}
return EVENT_IGNORE;
}
int devmgr_router_init()
{
log_trace("devmgr_router init success.");
sm_attach_service("accs", &devmgr_listener);
return 0;
}
void devmgr_router_exit()
{
sm_detach_service("accs", &devmgr_listener);
log_trace("devmgr_router exit.");
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR_ROUTER__H__
#define __DEVMGR_ROUTER__H__
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
#define METHOD_DEVICE_REGISTER_SUB_WIFI "registerSubDevice"
#define METHOD_DEVICE_UNREGISTER_SUB_WIFI "unregisterDevice"
#define METHOD_DEVICE_ATTACH_SUB_WIFI "attachSubDevice"
#define METHOD_DEVICE_DETACH_SUB_WIFI "detachSubDevice"
#define PARAMS_DEVICE_REGISTER_SUB_WIFI_FMT ("{\"name\":\"%s\","\
"\"model\":\"%s\","\
"\"type\":\"%s\","\
"\"category\":\"%s\","\
"\"sn\":\"\","\
"\"mac\":\"%s\","\
"\"manufacturer\":\"%s\","\
"\"version\":\"\"}")
#define PARAMS_DEVICE_ATTACH_SUB_WIFI_FMT "{\"uuid\":\"%s\", \"clients\":[\"%s\"]}"
#define PARAMS_DEVICE_DETACH_SUB_WIFI_FMT "{\"uuid\":\"%s\", \"clients\":[\"%s\"]}"
int router_network_up_event_handler(dev_info_t *devinfo);
int router_network_down_event_handler(dev_info_t *devinfo);
int router_link_state_event_handler(dev_info_t *devinfo, link_state_t state);
int devmgr_router_init();
void devmgr_router_exit();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,196 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aos/errno.h>
#include "devmgr.h"
#include "devmgr_alink.h"
#include "devmgr_cache.h"
dev_base_t dev_base1;
dev_base_t dev_base2;
void __dump_device_list();
void *alink_cb_func[ALINK_CB_MAX_NUM] = {NULL};
int alink_unregister_service(const char *name)
{
return 0;
}
int stdd_zbnet_remove_device_cb(uint8_t ieee_addr[8])
{
log_trace("remove device: %02x%02x%02x%02x%02x%02x%02x%02x",
ieee_addr[0], ieee_addr[1], ieee_addr[2], ieee_addr[3],
ieee_addr[4], ieee_addr[5], ieee_addr[6], ieee_addr[7]);
return 0;
}
int stdd_zigbee_permit_join(uint8_t duration)
{
return 0;
}
int stdd_zbnet_supervision_interval_cb(uint8_t ieee_addr[8], uint8_t interval)
{
return 0;
}
int get_device_profile_file(uint8_t dev_type, uint32_t model_id,
char file_name[], int max_name_length)
{
strcpy(file_name, "test_attr_profile.lua");
return 0;
}
int fmgr_get_attr_profile(char file_name[], int max_name_length)
{
sprintf(file_name, "test_device_profile.lua");
return 0;
}
int get_kv(const char *key, void *value_buf, int *buf_len)
{
int ret = 0;
if (strcmp(key, "device_01") == 0) {
memcpy(value_buf, &dev_base1, sizeof(dev_base1));
} else if (strcmp(key, "device_02") == 0) {
memcpy(value_buf, &dev_base2, sizeof(dev_base2));
} else {
ret = -1;
}
return ret;
}
int set_kv_in_flash(const char *key, const void *value_buf, int buf_len,
int flag)
{
return 0;
}
int remove_kv(const char *key)
{
return 0;
}
int alink_register_attribute(const char *name,
void *get_cb,
void *set_cb)
{
return 0;
}
int alink_register_service(const char *name, void *exec_cb)
{
return 0;
}
void stdd_forward_device_status(dev_info_t *devinfo,
const char *attr_name, const char *attr_value)
{
log_trace("forward device state, devid:%s, uuid:%s, attr_name:%s, attr_value:%s",
devinfo->dev_base.dev_id, devinfo->dev_base.uuid, attr_name, attr_value);
}
int32_t stdd_add_device_profile(uint32_t model_id, const char *profile_path)
{
log_trace("add device profile, profile_path:%s", profile_path);
return 0;
}
#define UUID_1 "123412412312312312312sdfsdgdgdew"
#define UUID_2 "5465465465465464865465asdfa12312"
void dev_list_init()
{
memset(&dev_base1, 0, sizeof(dev_base1));
memset(&dev_base2, 0, sizeof(dev_base2));
dev_base1.dev_type = DEV_TYPE_ZIGBEE;
dev_base1.model_id = 0x01010101;
memcpy(dev_base1.u.ieee_addr, "12345678", 8);
strncpy(dev_base1.rand, "rand_01", strlen("rand_01"));
strncpy(dev_base1.sign, "sign_01", strlen("sign_01"));
strcpy(dev_base1.uuid, UUID_1);
bytes_2_hexstr(dev_base1.u.ieee_addr, 8, dev_base1.dev_id,
sizeof(dev_base1.dev_id));
//log_trace("dev_base1.devid:%s", dev_base1.dev_id);
dev_base2.dev_type = DEV_TYPE_ZIGBEE;
dev_base2.model_id = 0x02020202;
memcpy(dev_base2.u.ieee_addr, "87654321", 8);
strncpy(dev_base2.rand, "rand_02", strlen("rand_02"));
strncpy(dev_base2.sign, "sign_02", strlen("sign_02"));
strcpy(dev_base2.uuid, UUID_2);
bytes_2_hexstr(dev_base2.u.ieee_addr, 8, dev_base2.dev_id,
sizeof(dev_base2.dev_id));
//log_trace("dev_base2.devid:%s", dev_base2.dev_id);
}
void dev_list_ut()
{
char ieee_addr[8];
//devmgr_delete_device(UUID_1);
//devmgr_delete_device(UUID_2);
memcpy(ieee_addr, "12345678", 8);
devmgr_leave_zigbee_device(ieee_addr);
__dump_device_list();
}
#define ATTR_NAME_1 "attr_1"
#define ATTR_NAME_2 "attr_2"
#define ATTR_VALUE_1 "value_1"
#define ATTR_VALUE_2 "value_2"
void dev_cache_ut()
{
int ret = SERVICE_RESULT_ERR;
ret = devmgr_update_attr_cache(UUID_1, ATTR_NAME_1, ATTR_VALUE_1);
RET_LOG(ret, "update attr cache fail, uuid:%s, attr_name:%s", UUID_1,
ATTR_NAME_1);
ret = devmgr_update_attr_cache(UUID_1, ATTR_NAME_2, ATTR_VALUE_2);
RET_LOG(ret, "update attr cache fail, uuid:%s, attr_name:%s", UUID_1,
ATTR_NAME_2);
ret = devmgr_update_attr_cache(UUID_2, ATTR_NAME_1, ATTR_VALUE_1);
RET_LOG(ret, "update attr cache fail, uuid:%s, attr_name:%s", UUID_1,
ATTR_NAME_1);
ret = devmgr_update_attr_cache(UUID_2, ATTR_NAME_2, ATTR_VALUE_2);
RET_LOG(ret, "update attr cache fail, uuid:%s, attr_name:%s", UUID_1,
ATTR_NAME_2);
char *attr_value = NULL;
ret = devmgr_read_attr_cache(UUID_1, ATTR_NAME_1, &attr_value);
RET_LOG(ret, "read attr cache fail, uuid:%s, attr_name:%s", UUID_1,
ATTR_NAME_1);
if (attr_value) {
log_trace("attr_name:%s, attr_value:%s", ATTR_NAME_1, attr_value);
}
}
int main(int argc, char *argv[])
{
int ret = SERVICE_RESULT_ERR;
dev_list_init();
ret = devmgr_init();
RET_RETURN(ret, "devmgr_init fail");
dev_cache_ut();
dev_list_ut();
return 0;
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __DEVMGR_UT__H__
#define __DEVMGR_UT__H__
#include <stdint.h>
#include <unistd.h>
#include "alink_export_zigbee.h"
#ifdef __cplusplus
extern "C" {
#endif
#define os_mutex_init() \
((void *)0x010101010)
#define os_mutex_lock(mutex)
#define os_mutex_unlock(mutex)
#define os_mutex_destroy(mutex) (mutex = NULL)
#define CALL_FUCTION_FAILED "Call function \"%s\" failed\n"
#define MAX_UUID_LEN 33
#define MAX_ATTR_NAME_LEN 80
#define MAX_SERVICE_NAME_LEN 80
#define MAX_ALINKGW_ATTR_HANDLER 64
#define MAX_ALINKGW_SERVICE_HANDLER 32
#define ALINKGW_MAX_VENDOR_CALLBACK_REMALLOC_COUNT 4 //回调函数返回buff不够的情况下最多尝试4次分配内存
#define JSON_KEY_UUID "uuid"
#define JSON_KEY_ATTRSET "attrSet"
#define JSON_KEY_SERVICE "service"
#define JSON_KEY_VALUE "value"
#define JSON_KEY_WHEN "when"
#define JSON_KEY_RESULT "result"
#define JSON_KEY_CODE "code"
#define JSON_KEY_ARGS "args"
#define JSON_KEY_SET "set"
#define JSON_KEY_EXTRA "extra"
#define log_print(fmt, args...) \
do { \
printf("[DEVMGR] %s:%4d %20s: " fmt "\n", __FILE__, __LINE__, __func__, ##args); \
} while(0)
#define log_fatal(FMT, args...) log_print(FMT, ##args)
#define log_error(FMT, args...) log_print(FMT, ##args)
#define log_info(FMT, args...) log_print(FMT, ##args)
#define log_dump(FMT, args...) log_print(FMT, ##args)
#define log_debug(FMT, args...) log_print(FMT, ##args)
#define log_trace(FMT, args...) log_print(FMT, ##args)
#define RET_FAILED(ret) (ret != SERVICE_RESULT_OK)
#define RET_GOTO(Ret,gotoTag,strError, args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
goto gotoTag; \
}\
}
#define RET_FALSE(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
return false; \
}\
}
#define RET_RETURN(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
return Ret; \
}\
}
#define RET_LOG(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_error(strError, ##args); \
}\
}
#define PTR_RETURN(Pointer,Ret,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return Ret; \
}\
}
#define PTR_FALSE(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return FALSE; \
}\
}
#define PTR_LOG(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_error(strError, ##args); \
}\
}
#define PTR_GOTO(Pointer, gotoTag, strError, args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
goto gotoTag; \
}\
}
#define POINTER_RETURN(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return Pointer; \
}\
}
enum SERVICE_CODE {
SERVICE_BUFFER_INSUFFICENT = -3,
SERVICE_CODE_UNKNOWN = -2,
SERVICE_RESULT_ERR = -1,
SERVICE_RESULT_OK = 0,
SERVICE_CODE_BEGIN = 0x0100,
SERVICE_EVENT,
SERVICE_DATA,
SERVICE_CONN_INIT,
SERVICE_CONN_READY,
SERVICE_CONN_CLOSE,
SERVICE_ATTACH,
SERVICE_DETACH,
SERVICE_STATE_INIT,
SERVICE_STATE_PREPARE,
SERVICE_STATE_READY,
SERVICE_STATE_BUSY,
SERVICE_STATE_STOP,
SERVICE_CODE_END = 0x01FF,
};
typedef struct alink_data {
char *method;
char *data;
} alink_data_t;
#define ALINK_CODE_ERROR_SIGN (3074)
extern void *alink_cb_func[ALINK_CB_MAX_NUM];
int alink_unregister_service(const char *name);
int get_device_profile_file(uint8_t dev_type, uint32_t model_id,
char file_name[], int max_name_length);
int fmgr_get_global_profile(char file_name[], int max_name_length);
int get_kv(const char *key, void *value_buf, *int buf_len);
int set_kv_in_flash(const char *key, const void *value_buf, int buf_len,
int flag);
int remove_kv(const char *key);
int alink_register_attribute(const char *name,
void *get_cb,
void *set_cb);
int alink_register_service(const char *name, void *exec_cb);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,9 @@
src = Split('''
devmgr_alink.c
devmgr_common.c
devmgr.c
devmgr_cache.c
devmgr_router.c
''')
component = aos_component('devmgr', src)

View file

@ -0,0 +1,13 @@
NAME := gateway
$(NAME)_TYPE := framework
GLOBAL_INCLUDES += ./
GLOBAL_CFLAGS += -DMESH_GATEWAY_SERVICE -DGATEWAY_SDK
$(NAME)_SOURCES += gateway_service.c
$(NAME)_COMPONENTS += cjson protocols.mesh protocol.alink gateway.devmgr gateway.msdp
GLOBAL_DEFINES += CONFIG_GATEWAY

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef GATEWAY_SERVICE_H
#define GATEWAY_SERVICE_H
#ifndef bool
#define bool unsigned char
#endif
int gateway_service_init(void);
void gateway_service_deinit(void);
int gateway_service_start(void);
void gateway_service_stop(void);
bool gateway_service_get_mesh_mqtt_state(void);
#endif

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __AOS_MQTT_SN_H__
#define __AOS_MQTT_SN_H__
#include <stdint.h>
#define MQTT_SN_PORT 1883
enum {
ADVERTISE = 0x0,
SEARCHGW,
GWINFO,
reserved1,
CONNECT,
CONNACK,
WILLTOPICREQ,
WILLTOPIC,
WILLMSGREQ,
WILLMSG,
REGISTER,
REGACK,
PUBLISH,
PUBACK,
PUBCOMP,
PUBREC,
PUBREL,
reserved2,
SUBSCRIBE,
SUBACK,
UNSUBSCRIBE,
UNSUBACK,
PINGREQ,
PINGRESP,
DISCONNECT,
reserved3,
WILLTOPICUPD,
WILLTOPICRESP,
WILLMSGUPD,
WILLMSGRESP,
ENCAP = 0xfe,
};
#define FLAG_DUP 0x80
#define FLAG_QoS 0x60
#define FLAG_RETAIN 0x10
#define FLAG_WILL 0x08
#define FLAG_CLEAN 0x04
#define FLAG_TOPIC 0x03
#define QoS_00 0x00
#define QoS_01 0x20
#define QoS_10 0x40
#define QoS_11 0x60
#define TOPIC_NORMAL 0x0
#define TOPIC_PRE 0x1
#define TOPIC_SHORT 0x2
#define TOPIC_RSV 0x3
typedef struct {
uint8_t Flags;
uint8_t TopicId[2];
uint8_t MsgId[2];
uint8_t payload[];
} __attribute__((packed)) pub_body_t;
typedef struct {
uint8_t Flags;
uint8_t MsgId[2];
union {
char TopicName[1];
uint8_t TopicId[2];
};
} __attribute__((packed)) sub_body_t;
typedef struct {
uint8_t Flags;
uint8_t ProtocolId;
uint8_t Duration[2];
char ClientId[];
} __attribute__((packed)) conn_body_t;
typedef struct {
uint8_t ReturnCode;
uint8_t payload[];
} __attribute__((packed)) conn_ack_t;
typedef struct {
uint8_t GwId;
uint8_t Duration[2];
uint8_t payload[];
} __attribute__((packed)) adv_body_t;
static inline int msn_parse_header(uint8_t *buf, int l, uint8_t **pbuf)
{
int len = *buf ++;
if (len == 1) {
len = *buf ++;
len <<= 8;
len += *buf ++;
} else {
len = (uint8_t)len - 1;
}
if (pbuf) {
*pbuf = buf;
}
if (l != len &&
l != len + 3) {
return -1;
}
return len;
}
static inline int msn_header_len(uint8_t msg_type)
{
switch (msg_type) {
case PUBLISH:
return sizeof(pub_body_t);
case CONNECT:
return sizeof(conn_body_t);
case CONNACK:
return sizeof(conn_ack_t);
case ADVERTISE:
return sizeof(adv_body_t);
}
return 0;
}
static inline void *msn_alloc(uint8_t msg_type, int payload_len, void **pbuf, int *plen)
{
int header_len = 2 + msn_header_len(msg_type);
int len;
uint8_t *buf;
len = header_len + payload_len;
buf = aos_malloc(len);
buf[0] = header_len + payload_len + 1;
buf[1] = msg_type;
*pbuf = buf;
*plen = len;
return buf + 2;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,199 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MSDP_H__
#define __MSDP_H__
/******************************************/
#include <stdint.h>
#include <unistd.h>
#include <stdarg.h>
#include "aos/aos.h"
#include "alink_export_internal.h"
#include "alink_protocol.h"
#include "json_parser.h"
//#define __MSDP_UT__ 1
#ifdef __MSDP_UT__
#include "msdp_ut.h"
#endif
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
/******************************************/
#define MODULE_NAME_MSDP "msdp"
#define MAX_PARAMS_LEN 3600
#define MAX_VENDOR_CB_REMALLOC_COUNT 5
#define MAX_UUID_LEN 33
#define MAX_ATTR_NAME_LEN 80
#define MAX_SERVICE_NAME_LEN 80
#define MAX_SERVICE_COUNT 32
#define JSON_KEY_UUID "uuid"
#define JSON_KEY_ATTRSET "attrSet"
#define JSON_KEY_SERVICE "service"
#define JSON_KEY_VALUE "value"
#define JSON_KEY_WHEN "when"
#define JSON_KEY_RESULT "result"
#define JSON_KEY_CODE "code"
#define JSON_KEY_ARGS "args"
#define JSON_KEY_SET "set"
#define JSON_KEY_EXTRA "extra"
#define JSON_KEY_DEVID "devId"
#define REQUEST_SERVICE_STRING_FMT "{\"uuid\":\"%s\",\"service\":\"%s\",\"args\":%s}"
#define RPC_RESULT_STRING_FMT "{\"uuid\":\"%s\",\"service\":\"%s\",\"code\":\"%d\",\"result\":[%s]}"
#define REGISTER_SERVICES_STRING_FMT "[{\"uuid\":\"%s\",\"service\":%s}]"
#define GET_DEVICE_ATTR_STRING_FMT "{\"uuid\":\"%s\",\"attrSet\":%s}"
#define SET_DEVICE_ATTR_STRING_FMT "{\"uuid\":\"%s\",\"attrSet\":%s,%s}"
#define ATTR_NAME_VALUE_STRING_FMT "\"%s\":{\"value\":\"%s\",\"when\":\"%s\"}"
#define ATTR_NAME_OBJECT_STRING_FMT "\"%s\":{\"value\":%s,\"when\":\"%s\"}"
#define POST_ATTR_OBJECT_STRING_FMT "{\"uuid\":\"%s\",\"%s\":{\"value\":%s,\"when\":\"%s\"}}"
#define POST_ATTR_VALUE_STRING_FMT "{\"uuid\":\"%s\",\"%s\":{\"value\":\"%s\",\"when\":\"%s\"}}"
#define METHOD_REGISTER_REMOTE_SERVICE "registerRemoteService"
#define METHOD_GET_DEVICE_STATUS "getDeviceStatus"
#define METHOD_SET_DEVICE_STATUS "setDeviceStatus"
#define METHOD_SET_DEVICE_STATUS_ARRAY "setDeviceStatusArray"
#define METHOD_POST_DEVICE_DATA "postDeviceData"
#define METHOD_POST_DEVICE_DATA_ARRAY "postDeviceDataArray"
#define METHOD_REQUEST_REMOTE_SERVICE "requestRemoteService"
#define METHOD_POST_REMOTE_SERVICE_RSP "postRemoteServieRsp"
/******************************************/
typedef int (*dev_option_cb)(char *params);
typedef int (*get_attr_cb)(char *value_buff, int buff_size);
typedef int (*set_attr_cb)(const char *attr_value);
typedef int (*get_subdev_attr_cb)(const char *mac, char *value_buff,
int buff_size);
typedef int (*set_subdev_attr_cb)(const char *mac, const char *value_buff);
typedef int (*get_dev_attr_cb)(const char *uuid, const char *attr_name,
char **attr_value);
typedef int (*set_dev_attr_cb)(const char *uuid, const char *attr_name,
const char *attr_value);
enum ALINK_COMMAND {
ACB_GET_DEVICE_STATUS = 0,
ACB_SET_DEVICE_STATUS = 1,
ACB_SET_DEVICE_STATUS_ARRAY = 2,
ACB_REQUEST_REMOTE_SERVICE = 3,
ACB_GET_DEVICE_STATUS_BY_RAWDATA = 4,
ACB_SET_DEVICE_STATUS_BY_RAWDATA = 5,
ACB_REQUEST_DEVICE_UPGRADE = 6,
ACB_REQUEST_DEVICE_UNUPGRADE = 7,
MAX_CALLBACK_NUM
};
typedef struct {
dlist_t list_node; //链表节点
char name[MAX_SERVICE_NAME_LEN]; //service方法名称
ALINK_SERVICE_EXECUTE_CB service_cb; //设置属性回调函数
} service_handler_t, *service_handler_ptr;
typedef struct {
dlist_t list_node; //当前属性handler链接节点
char name[MAX_ATTR_NAME_LEN]; //属性名称
void *get_cb; //获取属性回调函数
void *set_cb; //设置属性回调函数
} attr_hanler_t, *attr_hanler_ptr;
typedef struct {
uint8_t dev_type; //设备model
dlist_t list_node; //设备model链表节点(只对subdevice有意义)
dlist_t attr_head; //属性链表头
dlist_t srv_head; //服务链表头
void *mutex_lock; //service和attribute链表读写操作锁
dev_option_cb option_callback[MAX_CALLBACK_NUM];//alink method处理接口
} device_helper_t, *device_helper_ptr;
typedef struct post_node {
dlist_t list_node; /* post_list */
char *params;
} post_node_t;
/******************************************/
int msdp_add_asyncpost_task(char *params);
int msdp_get_all_attrname(const char *uuid, char *attrset, int buff_size);
int msdp_get_all_rpcname(uint8_t dev_type, char *name_array[], int array_size);
int msdp_register_attr_cb(uint8_t dev_type,
const char *name,
void *pf_get,
void *pf_set);
int msdp_register_service_cb(uint8_t dev_type,
const char *name,
void *pf_exec);
int msdp_register_remote_service(char *uuid, const char *service);
void msdp_unregister_service_cb(uint8_t dev_type, const char *name);
int msdp_register_device_helper(uint8_t dev_type,
dev_option_cb callback[MAX_CALLBACK_NUM]);
void msdp_unregister_device_helper(uint8_t dev_type);
int msdp_report_device_status(const char *uuid, const char *attr_name,
const char *attr_value);
int msdp_report_device_attrs(const char *uuid, const char *attrs[]);
int msdp_set_device_status(const char *uuid, const char *attr_name,
const char *attr_value);
int msdp_request_remote_service(const char *uuid, const char *service_name,
const char *args);
int msdp_dispatch_event(const char *uuid, const char *method, char *params);
void msdp_dump_helper();
attr_hanler_ptr msdp_get_attr_handler(const device_helper_ptr helper,
const char *name);
service_handler_ptr msdp_get_service_handler(const device_helper_ptr helper,
const char *name);
device_helper_ptr msdp_get_helper(const char *devid_or_uuid);
int lmns_post_device_data(const char *devid, char *payload);
int lmns_post_remote_service_rsp(const char *devid, char *payload);
int msdp_post_device_data_array(char *params);
int msdp_get_gw_attr(const char *gw_uuid, const char *attr_name,
char *attr_value_buff, int buff_size);
void *msdp_dup_string(const char *src);
void *msdp_dup_buff(const void *buff, unsigned buff_size);
void *msdp_new_buff(unsigned int buff_size);
void msdp_free_buff(void *buff);
int msdp_gw_init();
int msdp_zbnet_init();
int msdp_init();
void msdp_exit();
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,21 @@
NAME := msdp
$(NAME)_TYPE := framework
GLOBAL_INCLUDES += .
$(NAME)_SOURCES := msdp.c msdp_common.c msdp_zigbee.c msdp_gateway.c
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration
$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized
$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable
$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration
$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized
$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable
$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing
endif
$(NAME)_CFLAGS += -DGATEWAY_SDK

View file

@ -0,0 +1,359 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include "aos/aos.h"
#include "json_parser.h"
#include "service.h"
#include "msdp.h"
#define MODULE_NAME MODULE_NAME_MSDP
typedef int (*status_array_cb)(char *entry, int entry_len, int entry_type,
const char *method_name);
typedef int (*get_status_cb)(char *entry, int entry_len, int entry_type,
const char *params, dlist_t *head, void *exec_cb);
typedef int (*set_status_cb)(char *entry, int entry_len, int entry_type,
const char *params, void *exec_cb);
typedef struct st_attribute_info {
dlist_t list_node;
char *attr_name;
char *attr_value;
} attribute_info;
static const char *msdp_get_timestamp_string()
{
static char time_string[32] = {0};
snprintf(time_string, sizeof(time_string) - 1, "%d", (unsigned int)time(NULL));
return time_string;
}
static int msdp_set_attr_array_each_cb(char *params, int str_len,
const char *method_name)//va_list *ap)
{
int uuid_len, ret = SERVICE_RESULT_ERR;
char *str_pos;
char uuid[MAX_UUID_LEN] = {0};
str_pos = json_get_value_by_name(params, str_len, JSON_KEY_UUID, &uuid_len,
NULL);
PTR_RETURN(str_pos, SERVICE_RESULT_ERR, "get value fail, name:%s, params:%s",
JSON_KEY_UUID, params);
strncpy(uuid, str_pos, uuid_len);
char *params_buff = msdp_dup_buff(str_pos, str_len + 1);
PTR_RETURN(params_buff, ret, "pmalloc fail");
params_buff[str_len] = '\0';
log_trace("params = %s\n", params_buff);
/*method转换为setDeviceStatus*/
ret = msdp_dispatch_event(uuid, method_name, params_buff);
RET_LOG(ret, "msdp_dispatch_event, params:%s", params_buff);
msdp_free_buff(params_buff);
return ret;
}
static int msdp_status_array_handler(char *params, void *cb,
const char *method_name)
{
int ret = SERVICE_RESULT_OK;
//遍历设置设备状态数组
char *entry, *pos;
int entry_len, type;
json_array_for_each_entry(params, pos, entry, entry_len, type) {
ret = ((status_array_cb)cb)(entry, entry_len, type, method_name);
RET_LOG(ret, CALL_FUCTION_FAILED, "json_array_for_each_entry");
}
return ret;
}
int msdp_set_attr_each_cb(const char *attr_name, int name_len, int type,
char *params, set_dev_attr_cb exec_cb)//va_list *ap)
{
int str_len, ret = SERVICE_RESULT_ERR;
char *str_pos, *attr_value = NULL;
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&str_len, NULL);
PTR_RETURN(str_pos, SERVICE_RESULT_ERR, "get uuid fail, params:%s", params);
char uuid[MAX_UUID_LEN] = {0};
strncpy(uuid, str_pos, str_len);
char *name_str = msdp_dup_buff(attr_name, name_len + 1);
PTR_GOTO(name_str, out, CALL_FUCTION_FAILED, "msdp_dup_buff");
name_str[name_len] = '\0';
str_pos = json_get_value_by_name(params, strlen(params), name_str, &str_len, NULL);
PTR_GOTO(str_pos, out, "get %s value fail, params:%s", name_str, params);
int value_len = 0;
char *value_str = NULL;
char *value_pos = json_get_value_by_name(str_pos, str_len, JSON_KEY_VALUE,
&value_len, NULL);
if (NULL != value_pos) {
value_str = msdp_dup_buff(value_pos, value_len + 1);
} else {
value_len = str_len;
value_str = msdp_dup_buff(str_pos, value_len + 1);
}
value_str[value_len] = '\0';
log_trace("attr_name:%s, attr_value:%s", name_str, value_str);
ret = exec_cb(uuid, name_str, value_str);
RET_GOTO(ret, out, CALL_FUCTION_FAILED, "exec_cb");
log_trace("set attibute \"%s\" = \"%s\" success", name_str, value_str);
out:
if (name_str) {
msdp_free_buff(name_str);
}
if (value_str) {
msdp_free_buff(value_str);
}
return ret;
}
int msdp_get_attr_each_cb(const char *attr_name, int name_len, int type,
char *params,
dlist_t *head, get_dev_attr_cb exec_cb)// va_list *ap)
{
int str_len, ret = SERVICE_RESULT_ERR;
attribute_info *pnode = NULL;
char *str_pos, *buff = NULL;
char name_buff[MAX_UUID_LEN] = {0};
strncpy(name_buff, attr_name, name_len);
//log_trace("attr_name:%s, params:%s", name_buff, params);
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&str_len, NULL);
PTR_RETURN(str_pos, SERVICE_RESULT_ERR, "get uuid fail, params:%s", params);
char uuid[MAX_UUID_LEN] = {0};
strncpy(uuid, str_pos, str_len);
log_trace("uuid:%s, attrname:%s", uuid, name_buff);
ret = exec_cb(uuid, name_buff, &buff);
RET_RETURN(ret, CALL_FUCTION_FAILED, "exec_cb");
log_trace("get attibute \"%s\" handler output = %s", name_buff, buff);
if (head && buff) {
pnode = (attribute_info *)msdp_new_buff( sizeof(attribute_info));
PTR_GOTO(pnode, err, "malloc failed\n");
memset(pnode, 0, sizeof(attribute_info));
//attr name
pnode->attr_name = msdp_dup_buff(attr_name, name_len + 1);
PTR_GOTO(pnode->attr_name, err, "pbufdup failed");
pnode->attr_name[name_len] = '\0';
//attr value
pnode->attr_value = msdp_dup_string(buff);
PTR_GOTO(pnode->attr_value, err, "pstrdup failed");
dlist_add_tail(&pnode->list_node, head);
}
if (buff) {
msdp_free_buff(buff);
}
return SERVICE_RESULT_OK;
err:
if (pnode) {
if (pnode->attr_name) {
msdp_free_buff(pnode->attr_name);
}
if (pnode->attr_value) {
msdp_free_buff(pnode->attr_value);
}
msdp_free_buff((void *)pnode);
}
if (buff) {
msdp_free_buff(buff);
}
return SERVICE_RESULT_ERR;
}
/*
--> [{"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState"],"wlanSwitchState":{"value":"1","when":"1404443369"}}]
*/
int msdp_set_status_array(char *params)
{
int ret = SERVICE_RESULT_OK;
//遍历各设备,分别设置属性并返会新的属性值
ret = msdp_status_array_handler(params, msdp_set_attr_array_each_cb,
METHOD_SET_DEVICE_STATUS_ARRAY);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_status_array_handler");
return ret;
}
int msdp_set_device_status_handler(char *params, void *cb, void *exec_cb)
{
int ret = SERVICE_RESULT_OK;
char *str_pos, *attr_set = NULL;
char uuid[MAX_UUID_LEN] = {0};
int str_len = 0;
attr_set = json_get_value_by_name(params, strlen(params), JSON_KEY_ATTRSET,
&str_len, NULL);
PTR_RETURN(attr_set, SERVICE_RESULT_ERR, "get arrSet fail");
log_trace("attr_set = %s, len:%d", attr_set, str_len);
char *attr_set_dup = msdp_dup_buff(attr_set, str_len + 1);
attr_set_dup[str_len] = '\0';
char *entry, *pos;
int entry_len, type;
json_array_for_each_entry(attr_set_dup, pos, entry, entry_len, type) {
ret = ((set_status_cb)cb)(entry, entry_len, type, params, exec_cb);
RET_LOG(ret, CALL_FUCTION_FAILED, "json_array_for_each_entry");
}
msdp_free_buff(attr_set_dup);
return ret;
}
int msdp_get_device_status_handler(char *params, void *cb, void *exec_cb,
char **json_out)
{
int str_len = 0;
int ret = SERVICE_RESULT_OK;
int uuid_len = 0;
char *str_pos = NULL;
char *report_params = NULL;
attribute_info *pnode;
dlist_t *pnode_next = NULL;
AOS_DLIST_HEAD(head);
char uuid[MAX_UUID_LEN] = {0};
char *entry, *pos;
int entry_len, type;
char *attr_set_dup = NULL;
char *attr_set = json_get_value_by_name(params, strlen(params),
JSON_KEY_ATTRSET, &str_len, NULL);
PTR_RETURN(attr_set, SERVICE_RESULT_ERR, "get arrSet fail");
log_trace("attr_set = %s", attr_set);
/*无需同步返回结果*/
if (NULL == json_out) {
attr_set_dup = msdp_dup_buff(attr_set, str_len + 1);
attr_set_dup[str_len] = '\0';
json_array_for_each_entry(attr_set_dup, pos, entry, entry_len, type) {
ret = ((get_status_cb)cb)(entry, entry_len, type, params, NULL, exec_cb);
RET_LOG(ret, CALL_FUCTION_FAILED, "json_array_for_each_entry");
}
msdp_free_buff(attr_set_dup);
attr_set_dup = NULL;
return ret;
}
attr_set_dup = msdp_dup_buff(attr_set, str_len + 1);
attr_set_dup[str_len] = '\0';
json_array_for_each_entry(attr_set_dup, pos, entry, entry_len, type) {
ret = ((get_status_cb)cb)(entry, entry_len, type, params, &head, exec_cb);
RET_LOG(ret, "get device status fail, params:%s", params);
}
msdp_free_buff(attr_set_dup);
attr_set_dup = NULL;
if (dlist_empty(&head)) {
log_warn("attribute value list is empty, nothing todo");
//输出串为空也返回OK避免未注册get_callback的属性设置失败
ret = SERVICE_RESULT_OK;
//return SERVICE_RESULT_ERR;
goto out;
}
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&str_len, NULL);
PTR_RETURN(str_pos, SERVICE_RESULT_ERR, "get uuid fail");
strncpy(uuid, str_pos, str_len);
/*{"uuid":"%s"}*/
unsigned int params_length = strlen(uuid) + strlen(JSON_KEY_UUID) + 20;
dlist_for_each_entry(&head, pnode, attribute_info, list_node) {
/*计算单个属性字符串长度:"attr_name":{"value":%s,"when":""}*/
params_length += strlen(pnode->attr_name) + strlen(pnode->attr_value) + 30;
}
report_params = msdp_new_buff( params_length);
PTR_GOTO(report_params, out, "pmalloc fail");
memset(report_params, 0, params_length);
int len = snprintf(report_params, params_length, "{\"uuid\":\"%s\"", uuid);
dlist_for_each_entry_safe(&head, pnode_next, pnode, attribute_info, list_node) {
if (pnode->attr_value[0] != '{' && pnode->attr_value[0] != '[')
len += snprintf(report_params + len, params_length - len,
",\"%s\":{\"value\":\"%s\"}",
pnode->attr_name, pnode->attr_value);
else
len += snprintf(report_params + len, params_length - len,
",\"%s\":{\"value\":%s}",
pnode->attr_name, pnode->attr_value);
if (len == params_length) {
goto out;
log_error("memory overflow");
}
/*移除节点*/
dlist_del(&pnode->list_node);
msdp_free_buff(pnode->attr_name);
msdp_free_buff(pnode->attr_value);
msdp_free_buff((void *)pnode);
}
report_params[len++] = '}';
//#ifdef CONFIG_METHOD_POSTDEVICEDATAARRAY
memmove(report_params + 1, report_params, len);
report_params[0] = '[';
report_params[len + 1] = ']';
//#endif
if (json_out) {
*json_out = report_params;
report_params = NULL;
}
ret = SERVICE_RESULT_OK;
log_trace("json_out = %s", json_out ? *json_out : "NULL");
out:
dlist_for_each_entry_safe(&head, pnode_next, pnode, attribute_info, list_node) {
dlist_del(&pnode->list_node);
msdp_free_buff(pnode->attr_name);
msdp_free_buff(pnode->attr_value);
msdp_free_buff((void *)pnode);
}
if (report_params) {
msdp_free_buff(report_params);
}
return ret;
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MSDP_COMMON_H__
#define __MSDP_COMMON_H__
#include <stdint.h>
#include <unistd.h>
#include <stdarg.h>
#include "msdp.h"
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
int msdp_set_attr_each_cb(const char *attr_name, int name_len, int type,
va_list *ap);
int msdp_get_attr_each_cb(const char *attr_name, int name_len, int type,
va_list *ap);
int msdp_set_status_array(char *params);
int msdp_set_device_status_handler(char *params, void *cb, void *exec_cb);
int msdp_get_device_status_handler(char *params, void *cb, void *exec_cb,
char **json_out);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,386 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "aos/aos.h"
#include "msdp_common.h"
#include "json_parser.h"
#include "service.h"
#include "devmgr.h"
#include "msdp.h"
#define MODULE_NAME MODULE_NAME_MSDP
static int __get_attribute(const char *uuid, const char *attr_name,
char **ppbuf)
{
int ret = SERVICE_RESULT_ERR;
attr_hanler_ptr attr_handler = NULL;
int buff_size, count = 0;
log_trace("uuid = %s, attr_name = %s", uuid, attr_name);
*ppbuf = NULL;
buff_size = MAX_PARAMS_LEN / (1 << MAX_VENDOR_CB_REMALLOC_COUNT);
device_helper_ptr helper = NULL;
helper = msdp_get_helper(uuid);
PTR_RETURN(helper, ret, "no exist model helper, uuid = %s", uuid)
os_mutex_lock((helper->mutex_lock));
attr_handler = msdp_get_attr_handler(helper, attr_name);
if (attr_handler) {
log_debug("exist attribute(%s) handler", attr_name);
void *get_cb = NULL;
get_cb = attr_handler->get_cb;
PTR_GOTO(get_cb, unlock_out, "attribute %s's get_cb is NULL", attr_name);
while (count < MAX_VENDOR_CB_REMALLOC_COUNT) {
buff_size = MAX_PARAMS_LEN / (1 << (MAX_VENDOR_CB_REMALLOC_COUNT - count));
*ppbuf = msdp_new_buff( buff_size);
PTR_GOTO(*ppbuf, unlock_out, "malloc failed");
memset(*ppbuf, 0, buff_size);
if (helper->dev_type == DEV_TYPE_GATEWAY) {
ret = ((get_attr_cb)attr_handler->get_cb)(*ppbuf, buff_size);
} else {
// modify by wukong 2017-4-17
char mac[ETHER_ADDR_BYTES] = {0};
get_mac_by_uuid(uuid, mac);
//modify by wukong end 2017-4-17
ret = ((get_subdev_attr_cb)attr_handler->get_cb)(mac, *ppbuf, buff_size);
}
if (ret != SERVICE_BUFFER_INSUFFICENT) {
break;
}
log_error("buff too short,buff_size = %d, remalloc", buff_size);
msdp_free_buff(*ppbuf);
*ppbuf = NULL;
count++;
}
//检查attribute调用返回值
RET_GOTO(ret, unlock_out, "get attibute \"%s\" handler faild", attr_name);
if (NULL == *ppbuf) { // || strlen(*ppbuf) == 0)
log_error("get attibute \"%s\" handler error, output_len == 0", attr_name);
ret = SERVICE_RESULT_ERR;
goto unlock_out;
}
log_debug("get attibute \"%s\" handler output = %s", attr_name, *ppbuf);
} else {
log_error("unsupport attribute \"%s\"", attr_name);
}
os_mutex_unlock((helper->mutex_lock));
return ret;
unlock_out:
os_mutex_unlock((helper->mutex_lock));
if (*ppbuf) {
msdp_free_buff(*ppbuf);
*ppbuf = NULL;
}
return ret;
}
static int __set_attribute(const char *uuid, const char *attr_name,
char *attr_value)
{
int ret = SERVICE_RESULT_ERR;
const char *mac = NULL;
attr_hanler_ptr attr_handler = NULL;
log_trace("uuid = %s, attr_name = %s, attr_value = %s", uuid, attr_name,
attr_value);
device_helper_ptr helper = NULL;
helper = msdp_get_helper(uuid);
PTR_RETURN(helper, ret, "no exist model helper, uuid = %s", uuid)
os_mutex_lock(helper->mutex_lock);
attr_handler = msdp_get_attr_handler(helper, attr_name);
if (attr_handler) {
log_trace("Exist attribute(%s) handler on devtype:%02x", attr_name,
helper->dev_type);
if (helper->dev_type == DEV_TYPE_GATEWAY) {
PTR_GOTO((attr_handler)->set_cb,
unlock_out, "attribute %s's get_cb is NULL", attr_name);
ret = ((set_attr_cb)attr_handler->set_cb)(attr_value);
log_trace("set attibute \"%s\" handler ret = %d", attr_name, ret);
} else {
// modify by wukong 2017-4-17
char mac[ETHER_ADDR_BYTES] = {0};
get_mac_by_uuid(uuid, mac);
//modify by wukong end 2017-4-17
PTR_GOTO((attr_handler->set_cb),
unlock_out, "subdevice attribute %s's set_cb is NULL", attr_name);
ret = ((set_subdev_attr_cb)attr_handler->set_cb)(mac, attr_value);
log_trace("set attibute \"%s\" handler ret = %d\n", attr_name, ret);
}
} else {
log_error("unsupport attribute \"%s\"", attr_name);
}
unlock_out:
os_mutex_unlock((helper->mutex_lock));
return ret;
}
#define RPC_RESULT_FMT "{\"set\":%s,\"when\":\"%s\",\"extra\":\"\"}"
static int msdp_rpc_handler(const device_helper_ptr helper,
const char *rpc_name,
const char *rpc_args)
{
int ret = SERVICE_RESULT_ERR;
service_handler_ptr phandler = NULL;
int buff_size, count = 0;
char *rpc_result = NULL;
os_mutex_lock((helper->mutex_lock));
phandler = msdp_get_service_handler(helper, rpc_name);
if (phandler) {
log_trace("Exist service(%s) handler", rpc_name);
ret = phandler->service_cb((char *)rpc_args, NULL, 0);
RET_LOG(ret, "excute rpc fail, rpcname:%s", rpc_name);
} else {
log_error("unsupport service \"%s\"", rpc_name);
}
os_mutex_unlock((helper->mutex_lock));
return ret;
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState", "lightSwitchState"]}
<-- {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState"],"wlanSwitchState":{"value":"1","when":"1404443369"}}
*/
static int msdp_get_status(char *params)
{
int ret = SERVICE_RESULT_ERR;
char *attrset;
char *json_out = NULL;
char params_in[512] = {0};
int attrset_size, attrset_len = 0;
//char szPostString[1024] = "{\"uuid\":\"2427287C75CD579897D3DB5854E46A2F\",\"wlanSwitchState\":{\"value\":\"1\",\"when\":\"1404443369\"}}";
attrset = json_get_value_by_name(params, strlen(params), JSON_KEY_ATTRSET,
&attrset_len, NULL);
if (attrset) {
attrset_size = json_get_array_size(attrset, attrset_len);
}
if (NULL == attrset || attrset_size == 0) {
char uuid[MAX_UUID_LEN] = {0};
int uuid_len = 0;
char *uuid_ptr = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&uuid_len, NULL);
PTR_RETURN(uuid_ptr, SERVICE_RESULT_ERR, CALL_FUCTION_FAILED,
"json_get_value_by_name(uuid)");
strncpy(uuid, uuid_ptr, sizeof(uuid) > uuid_len ? uuid_len : sizeof(uuid) - 1);
char attrset[512] = {0};
ret = msdp_get_all_attrname(uuid, attrset, sizeof(attrset));
RET_RETURN(ret, "get all attribute name fail, uuid:%s", uuid);
log_trace("attrset = %s\n", attrset);
snprintf(params_in, sizeof(params_in) - 1, GET_DEVICE_ATTR_STRING_FMT, uuid,
attrset);
params = params_in;
}
//遍历attrset并调用厂商注册的接口返回属性json串
ret = msdp_get_device_status_handler(params, msdp_get_attr_each_cb,
__get_attribute, &json_out);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_status_handler");
log_trace("json_out = %s", json_out ? (json_out) : "NULL");
//todo: postDeviceData/deviceDataChange
if (json_out) {
int str_len, post_ret = SERVICE_RESULT_ERR;
char devid_str[18] = {0};
char *dev_id = json_get_value_by_name(params, strlen(params), JSON_KEY_DEVID,
&str_len, NULL);
if (dev_id != NULL) {
post_ret = lmns_post_device_data(devid_str, json_out);
RET_GOTO(post_ret, end, CALL_FUCTION_FAILED, "lmns_post_device_data");
} else {
int post_ret = msdp_add_asyncpost_task(json_out);
RET_GOTO(post_ret, end, "add async post task fail, params:%s", json_out);
json_out = NULL;
}
}
end:
if (json_out) {
msdp_free_buff(json_out);
}
return ret;
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState"],"wlanSwitchState":{"value":"1","when":"1404443369"}}
*/
static int msdp_set_status(char *params)
{
int ret = SERVICE_RESULT_OK;
char *json_out = NULL;
//log_trace("json_in = %s\n", json_in);
//遍历attrset设置属性值
ret = msdp_set_device_status_handler(params, msdp_set_attr_each_cb,
__set_attribute);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_set_attr_each_cb");
//遍历attrset获取属性值
ret = msdp_get_device_status_handler(params, msdp_get_attr_each_cb,
__get_attribute, &json_out);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_get_attr_each_cb");
log_trace("json_out = %s", json_out ? (json_out) : "NULL");
//todo: postDeviceData/deviceDataChange
if (json_out) {
int str_len, post_ret = SERVICE_RESULT_ERR;
char *dev_id = json_get_value_by_name(params, strlen(params), JSON_KEY_DEVID,
&str_len, NULL);
if (dev_id != NULL) {
char devid_str[18] = {0};
strncpy(devid_str, dev_id, str_len);
post_ret = lmns_post_device_data(devid_str, json_out);
RET_GOTO(post_ret, end, CALL_FUCTION_FAILED, "lmns_post_device_data");
} else {
int post_ret = msdp_add_asyncpost_task(json_out);
RET_GOTO(post_ret, end, "add async post task fail, params:%s", json_out);
json_out = NULL;
}
}
end:
if (json_out) {
msdp_free_buff(json_out);
}
return ret;
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","service\":"startBwCheck","args":{}}
<-- {"uuid": "42E6E69DAEF6483FBBA412A28AF7CD76", "service": "stopBwCheck", "code": "1", "result": [ ] }
*/
static int msdp_rpc(char *params)
{
int ret = SERVICE_RESULT_ERR;
char *json_ptr, *rpc_name, *rpc_args;
json_ptr = rpc_name = rpc_args = NULL;
int len = 0;
log_trace("params = %s", params);
json_ptr = json_get_value_by_name(params, strlen(params), JSON_KEY_SERVICE,
&len, NULL);
PTR_GOTO(json_ptr, end, CALL_FUCTION_FAILED, "json_get_value_by_name");
rpc_name = msdp_dup_buff(json_ptr, len + 1);
PTR_GOTO(rpc_name, end, "pmalloc fail");
rpc_name[len] = '\0';
json_ptr = json_get_value_by_name(params, strlen(params), JSON_KEY_ARGS, &len,
NULL);
PTR_GOTO(json_ptr, end, CALL_FUCTION_FAILED, "json_get_value_by_name");
rpc_args = msdp_dup_buff(json_ptr, len + 1);
PTR_GOTO(rpc_args, end, "pmalloc fail");
rpc_args[len] = '\0';
char uuid[MAX_UUID_LEN] = {0};
json_ptr = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID, &len,
NULL);
PTR_GOTO(json_ptr, end, CALL_FUCTION_FAILED, "json_get_value_by_name");
strncpy(uuid, json_ptr, len);
device_helper_ptr helper = msdp_get_helper(uuid);
PTR_GOTO(helper, end, "no exist model helper, uuid = %s", uuid);
ret = msdp_rpc_handler(helper, rpc_name, rpc_args);
RET_GOTO(ret, end, CALL_FUCTION_FAILED, "msdp_service_handler");
ret = SERVICE_RESULT_OK;
end:
if (rpc_name) {
msdp_free_buff(rpc_name);
}
if (rpc_args) {
msdp_free_buff(rpc_args);
}
return ret;
}
int msdp_get_gw_attr(const char *gw_uuid, const char *attr_name,
char *attr_value_buff, int buff_size)
{
int ret = SERVICE_RESULT_ERR;
char *output = NULL;
ret = __get_attribute(gw_uuid, attr_name, &output);
RET_RETURN(ret, "get attr fail, attr_name:%s", attr_name);
if (output != NULL) {
if (strlen(output) >= buff_size) {
ret = SERVICE_RESULT_ERR;
log_error("the buffer size is too small");
goto out;
}
strncpy(attr_value_buff, output, buff_size - 1);
} else {
ret = SERVICE_RESULT_ERR;
}
out:
if (output) {
msdp_free_buff(output);
}
return ret;
}
int msdp_gw_init()
{
dev_option_cb callback[MAX_CALLBACK_NUM] = {NULL};
/*默认cmd callback*/
callback[ACB_GET_DEVICE_STATUS] = msdp_get_status;
callback[ACB_SET_DEVICE_STATUS] = msdp_set_status;
callback[ACB_SET_DEVICE_STATUS_ARRAY] = msdp_set_status_array;
callback[ACB_REQUEST_REMOTE_SERVICE] = msdp_rpc;
/*注册网关设备事件处理接口*/
return msdp_register_device_helper(DEV_TYPE_GATEWAY, callback);
#ifdef ROUTER_SDK
/*注册WIFI下联子设备model*/
return msdp_register_device_helper(DEV_TYPE_WIFI_SUB, callback);
#endif
return 0;
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aos/errno.h>
#include "msdp_ut.h"
#include "msdp.h"
#define GW_UUID "123412412312312312312sdfsdgdgdew"
#define ZBDEV_UUID "5465465465465464865465asdfa12312"
#define ATTR1_NAME "attr1"
#define ATTR2_NAME "attr2"
//static char attr1_value[32] = "attrvalue1";
//static char attr2_value[32] = "attrvalue2";
static char attr1_value[128] = "{\"element\":\"value1\"}";
static char attr2_value[128] = "[\"element1\",\"element2\"]";
void dump_all_type_handler();
int stdd_zbnet_supervision_interval_cb(uint8_t ieee_addr[8], uint8_t interval)
{
return 0;
}
int devmgr_read_attr_cache(const char *devid_or_uuid, const char *attr_name,
char **attr_value)
{
log_trace("read attr cache, devid:%s, attr_name:%s", devid_or_uuid, attr_name);
char *value_str = NULL;
if (strcmp(attr_name, ATTR1_NAME) == 0) {
value_str = (char *)attr1_value;
} else if (strcmp(attr_name, ATTR2_NAME) == 0) {
value_str = (char *)attr2_value;
} else {
return -1;
}
*attr_value = malloc(strlen(value_str) + 1);
memset(*attr_value, 0, strlen(value_str) + 1);
strcpy(*attr_value, value_str);
return 0;
}
int devmgr_get_dev_type(const char *devid_or_uuid, uint8_t *dev_type)
{
*dev_type = DEV_TYPE_ZIGBEE;
return 0;
}
int32_t alink_post(const char *method, char *buff)
{
log_trace("alink post, mehtod:%s, buff:%s", method, buff);
return 0;
}
int stdd_zbnet_get_attr(const char *devid_or_uuid, const char *attr_name)
{
log_trace("get attibute, uuid:%s, attrname:%s", devid_or_uuid, attr_name);
return 0;
}
int stdd_zbnet_set_attr(const char *devid_or_uuid, const char *attr_name,
const char *attr_value)
{
log_trace("set attribute, uuid:%s, attrname:%s, attrvalue:%s", devid_or_uuid,
attr_name, attr_value);
if (strcmp(attr_name, ATTR1_NAME) == 0) {
strcpy(attr1_value, attr_value);
} else if (strcmp(attr_name, ATTR2_NAME) == 0) {
strcpy(attr2_value, attr_value);
} else {
return -1;
}
return 0;
}
int stdd_zbnet_exec_rpc(const char *devid_or_uuid, const char *rpc_name,
const char *rpc_args)
{
log_trace("exec_rpc success, uuid:%s", devid_or_uuid);
return 0;
}
int stdd_get_device_attrset(const char *devid_or_uuid, char *attrset_buff,
int buff_size)
{
log_trace("get device attrset, uuid:%s", devid_or_uuid);
snprintf(attrset_buff, buff_size, "[\"attr1\",\"attr2\"]");
return 0;
}
const char *config_get_main_uuid(void)
{
return GW_UUID;
}
int gw_get_attr1_cb(char *attr_value_buff, int buff_size)
{
log_trace("get attr1, value:%s", attr1_value);
strcpy(attr_value_buff, attr1_value);
return 0;
}
int gw_set_attr1_cb(char *attr_value)
{
log_trace("set attr1, value:%s", attr_value);
strcpy(attr1_value, attr_value);
return 0;
}
int gw_get_attr2_cb(char *attr_value_buff, int buff_size)
{
log_trace("get attr2, value:%s", attr2_value);
strcpy(attr_value_buff, attr2_value);
return 0;
}
int gw_set_attr2_cb(char *attr_value)
{
log_trace("set attr2, value:%s", attr_value);
strcpy(attr2_value, attr_value);
}
int gw_rpc_reboot_cb(char *args, char *rpc_result, int buff_size)
{
log_trace("rpc reboot, args:%s", args);
return 0;
}
void dev_attr_init()
{
msdp_register_attr_cb(DEV_TYPE_GATEWAY, ATTR1_NAME, gw_get_attr1_cb,
gw_set_attr1_cb);
msdp_register_attr_cb(DEV_TYPE_GATEWAY, ATTR2_NAME, gw_get_attr2_cb,
gw_set_attr2_cb);
msdp_register_service_cb(DEV_TYPE_GATEWAY, "reboot", gw_rpc_reboot_cb);
}
int get_attr_ut()
{
int ret = SERVICE_RESULT_ERR;
char params[1024] = {0};
sprintf(params, GET_DEVICE_ATTR_STRING_FMT, GW_UUID, "[]");
log_trace("params:%s", params);
ret = msdp_dispatch_event(GW_UUID, METHOD_GET_DEVICE_STATUS, params);
RET_RETURN(ret, "get device status fail, params:%s", params);
log_trace("get device status success\n");
return ret;
}
int set_attr_ut()
{
int ret = SERVICE_RESULT_ERR;
char params[1024] = {0};
sprintf(params, SET_DEVICE_ATTR_STRING_FMT, GW_UUID, "[\"attr1\",\"attr2\"]",
"\"attr1\":{\"value\":[\"element1\",\"element2\"]},\"attr2\":{\"value\":{\"element\":\"elementvalue\"}}");
log_trace("params:%s", params);
ret = msdp_dispatch_event(GW_UUID, METHOD_SET_DEVICE_STATUS, params);
RET_RETURN(ret, "set device status fail, params:%s", params);
ret = msdp_set_device_status(ZBDEV_UUID, ATTR1_NAME, "attr_value");
RET_RETURN(ret, "set device status fail");
ret = msdp_request_remote_service(ZBDEV_UUID, "reboot", "{\"args\":\"test\"");
RET_RETURN(ret, "request remote service fail");
log_trace("set device status success, params:%s\n", params);
return ret;
}
int main(int argc, char *argv[])
{
int ret = msdp_init();
RET_RETURN(ret, "msdp_init fail");
dev_attr_init();
dump_all_type_handler();
//get_attr_ut();
set_attr_ut();
//get_attr_ut();
return 0;
}

View file

@ -0,0 +1,227 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __MSDP_UT__H__
#define __MSDP_UT__H__
#include <stdint.h>
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
#define os_mutex_init() \
((void *)0x010101010)
#define os_mutex_lock(mutex)
#define os_mutex_unlock(mutex)
#define os_mutex_destroy(mutex) (mutex = NULL)
#define CALL_FUCTION_FAILED "Call function \"%s\" failed\n"
#define MAX_UUID_LEN 33
#define MAX_ATTR_NAME_LEN 80
#define MAX_SERVICE_NAME_LEN 80
typedef int (*ALINK_SERVICE_EXECUTE_CB)(const char *args,
char *json_out_buf, unsigned int buf_sz);
#define log_print(fmt, args...) \
do { \
printf("[MSDP] %s:%4d %20s: " fmt "\n", __FILE__, __LINE__, __func__, ##args); \
} while(0)
#define log_fatal(FMT, args...) log_print(FMT, ##args)
#define log_error(FMT, args...) log_print(FMT, ##args)
#define log_info(FMT, args...) log_print(FMT, ##args)
#define log_dump(FMT, args...) log_print(FMT, ##args)
#define log_debug(FMT, args...) log_print(FMT, ##args)
#define log_trace(FMT, args...) log_print(FMT, ##args)
#define RET_FAILED(ret) (ret != SERVICE_RESULT_OK)
#define RET_GOTO(Ret,gotoTag,strError, args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
goto gotoTag; \
}\
}
#define RET_FALSE(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
return false; \
}\
}
#define RET_RETURN(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_trace(strError, ##args); \
return Ret; \
}\
}
#define RET_LOG(Ret,strError,args...) \
{\
if ( RET_FAILED(Ret) ) \
{ \
log_error(strError, ##args); \
}\
}
#define PTR_RETURN(Pointer,Ret,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return Ret; \
}\
}
#define PTR_FALSE(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return FALSE; \
}\
}
#define PTR_LOG(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_error(strError, ##args); \
}\
}
#define PTR_GOTO(Pointer, gotoTag, strError, args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
goto gotoTag; \
}\
}
#define POINTER_RETURN(Pointer,strError,args...) \
{\
if ( !Pointer) \
{ \
log_trace(strError, ##args); \
return Pointer; \
}\
}
enum SERVICE_CODE {
SERVICE_BUFFER_INSUFFICENT = -3,
SERVICE_CODE_UNKNOWN = -2,
SERVICE_RESULT_ERR = -1,
SERVICE_RESULT_OK = 0,
SERVICE_CODE_BEGIN = 0x0100,
SERVICE_EVENT,
SERVICE_DATA,
SERVICE_CONN_INIT,
SERVICE_CONN_READY,
SERVICE_CONN_CLOSE,
SERVICE_ATTACH,
SERVICE_DETACH,
SERVICE_STATE_INIT,
SERVICE_STATE_PREPARE,
SERVICE_STATE_READY,
SERVICE_STATE_BUSY,
SERVICE_STATE_STOP,
SERVICE_CODE_END = 0x01FF,
};
/**
* command argument
*/
typedef struct cmd_argument {
char arg_name[32];
unsigned char data_type;
struct cmd_argument *next_arg;
} cmd_argument_t;
/**
* attr element
*/
typedef struct attr_element {
struct attr_element *next_element;
unsigned char data_type;/**< defined by zigbee protocol */
char element_name[32];
struct attr_element *child_element;
} attr_element_t;
/**
* alink attribute profile description
*/
typedef struct attr_profile {
char attr_name[32];
unsigned char data_type;
unsigned short cluster_id;
unsigned short attribute_id;
attr_element_t *attr_element;
unsigned char reserved[4];
} attr_profile_t;
/**
* alink command profile description
*/
typedef struct cmd_profile {
char cmd_name[32];
unsigned short cluster_id;
unsigned char cmd_id;
unsigned char direction; /**< 0:c to s; 1:s to c */
cmd_argument_t *args;
unsigned char reserved[4];
} cmd_profile_t;
int devmgr_get_dev_type(const char *devid_or_uuid, uint8_t *dev_type);
int32_t alink_post(const char *method, char *buff);
int devmgr_read_attr_cache(const char *devid_or_uuid, const char *attr_name,
char **attr_value);
const char *config_get_main_uuid(void);
int stdd_zbnet_update_attr_profile_cb(attr_profile_t *profile[]);
int stdd_zbnet_update_cmd_profile_cb(cmd_profile_t *profile[]);
int stdd_zbnet_get_attr_cb(uint8_t ieee_addr[8], \
uint8_t endpoint_id, const char *attr_set[]);
int stdd_zbnet_set_attr_cb(uint8_t ieee_addr[8], uint8_t endpoint_id, \
const char *attr_name, const char *attr_value);
int stdd_zbnet_exec_cmd_cb(uint8_t ieee_addr[8], uint8_t endpoint_id, \
const char *cmd_name, const char *cmd_args);
int stdd_zbnet_get_attr(const char *devid_or_uuid, const char *attr_name);
int stdd_zbnet_set_attr(const char *devid_or_uuid, const char *attr_name,
const char *attr_value);
int stdd_zbnet_exec_rpc(const char *devid_or_uuid, const char *rpc_name,
const char *rpc_args);
int stdd_get_device_attrset(const char *devid_or_uuid, char *attrset_buff,
int buff_size);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,228 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "aos/aos.h"
#include "alink_export_internal.h"
#include "json_parser.h"
#include "service.h"
#include "devmgr_cache.h"
#include "msdp_common.h"
#define MODULE_NAME MODULE_NAME_MSDP
static int stdd_zbnet_get_attr(const char *devid_or_uuid, const char *attr_name)
{
log_info("zbnet_get_attr, uuid:%s attr_name:%s\n", devid_or_uuid, attr_name);
return 0;
}
static int stdd_zbnet_set_attr(const char *devid_or_uuid, const char *attr_name,
const char *attr_value)
{
log_info("zbnet_set_attr, uuid:%s attr_name:%s attr_value:%s\n", devid_or_uuid,
attr_name, attr_value);
return 0;
}
#define DEV_ATTR_SET "[\"BackLightMode\",\"BatteryPercentage\",\"Rssi\",\"Switch\"]"
static int stdd_get_device_attrset(const char *devid_or_uuid,
char *attrset_buff, int buff_size)
{
strncpy(attrset_buff, DEV_ATTR_SET, buff_size);
log_info("zbnet get device attrset, uuid:%s\n", devid_or_uuid);
return 0;
}
static int stdd_zbnet_exec_rpc(const char *devid_or_uuid, const char *rpc_name,
const char *rpc_args)
{
return 0;
}
static int __get_attribute(const char *uuid, const char *attr_name,
char **attr_value)
{
int ret = SERVICE_RESULT_ERR;
char *attr_cache = NULL;
log_trace("uuid:%s, attr_name:%s", uuid, attr_name);
ret = stdd_zbnet_get_attr(uuid, attr_name);
RET_LOG(ret, "get attribute fail, attrname:%s", attr_name);
return ret;
}
static int __set_attribute(const char *uuid, const char *attr_name,
char *attr_value)
{
int ret = SERVICE_RESULT_ERR;
ret = stdd_zbnet_set_attr(uuid, attr_name, attr_value);
RET_RETURN(ret, CALL_FUCTION_FAILED, "stdd_zbnet_set_attr");
return ret;
}
/*获取指定设备所有属性*/
static int __get_all_attrname(const char *uuid, char *attr_set, int buff_size)
{
int count, ret = SERVICE_RESULT_ERR;
ret = stdd_get_device_attrset(uuid, attr_set, buff_size);
RET_RETURN(ret, "get device all attribute name fail, uuid:%s", uuid);
return ret;
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState", "lightSwitchState"]}
<-- {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState"],"wlanSwitchState":{"value":"1","when":"1404443369"}}
*/
static int msdp_get_status(char *params)
{
#if 0
int ret = SERVICE_RESULT_ERR;
char *str_pos, *params_ptr = params;
int str_len = 0;
char params_buff[512] = {0};
int attrset_size = 0;
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_ATTRSET,
&str_len, NULL);
if (str_pos) {
log_trace("attrset:%s", str_pos);
attrset_size = json_get_array_size(str_pos, str_len);
}
if (NULL == str_pos || attrset_size == 0) {
//uuid
char uuid[MAX_UUID_LEN] = {0};
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&str_len, NULL);
PTR_RETURN(str_pos, SERVICE_RESULT_ERR, "get uuid fail, params:%s", params);
strncpy(uuid, str_pos, str_len);
//else,todo:get devid
char all_attr[256] = {0};
ret = __get_all_attrname(uuid, all_attr, sizeof(all_attr));
RET_RETURN(ret, "__get_all_attrname(%s)", uuid);
log_trace("attrset:%s", all_attr);
snprintf(params_buff, sizeof(params_buff) - 1, GET_DEVICE_ATTR_STRING_FMT, uuid,
all_attr);
params_ptr = params_buff;
}
log_trace("params_ptr:%s", params_ptr);
char *json_out = NULL;
ret = msdp_get_device_status_handler(params_ptr, msdp_get_attr_each_cb,
__get_attribute, &json_out);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_status_handler");
if (json_out) {
log_trace("post device data: params:%s", json_out);
if (SERVICE_RESULT_OK != msdp_add_asyncpost_task(json_out)) {
log_error("add async post task fail, params:%s", json_out);
msdp_free_buff(json_out);
}
json_out = NULL;
}
return ret;
#else
aos_cloud_trigger(GET_SUB_DEVICE_STATUS, params);
return SERVICE_RESULT_OK;
#endif
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","attrSet":["wlanSwitchState"],"wlanSwitchState":{"value":"1","when":"1404443369"}}
*/
static int msdp_set_status(char *params)
{
#if 0
int ret = SERVICE_RESULT_ERR;
//log_trace("params:%s\n", params);
//遍历attrset设置属性
ret = msdp_set_device_status_handler(params, msdp_set_attr_each_cb,
__set_attribute);
RET_RETURN(ret, CALL_FUCTION_FAILED, "msdp_set_attr_each_cb");
return ret;
#else
aos_cloud_trigger(SET_SUB_DEVICE_STATUS, params);
return SERVICE_RESULT_OK;
#endif
}
/*
--> {"uuid":"42E6E69DAEF6483FBBA412A28AF7CD76","service\":"startBwCheck","args":{}}
<-- {"uuid": "42E6E69DAEF6483FBBA412A28AF7CD76", "service": "stopBwCheck", "code": "1", "result": [ ] }
*/
static int msdp_rpc(char *params)
{
int ret = SERVICE_RESULT_ERR;
char rpc_name[MAX_SERVICE_NAME_LEN] = {0};
char uuid[MAX_UUID_LEN] = {0};
char rpc_args[256] = {0};
char *str_pos = NULL;
int str_len = 0;
log_trace("params:%s", params);
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_SERVICE,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get service name fail, params:%s", params);
strncpy(rpc_name, str_pos, str_len);
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_ARGS,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get service args fail, params:%s", params);
strncpy(rpc_args, str_pos, str_len);
str_pos = json_get_value_by_name(params, strlen(params), JSON_KEY_UUID,
&str_len, NULL);
PTR_RETURN(str_pos, ret, "get uuid fail, params:%s", params);
strncpy(uuid, str_pos, str_len);
ret = stdd_zbnet_exec_rpc(uuid, rpc_name, rpc_args);
RET_RETURN(ret, "exeute rpc fail, uuid:%s, rpc_name:%s, args:%s", uuid,
rpc_name, rpc_args);
return ret;
}
int msdp_zbnet_init()
{
dev_option_cb callback[MAX_CALLBACK_NUM] = {NULL};
/*默认cmd callback*/
callback[ACB_GET_DEVICE_STATUS] = msdp_get_status;
callback[ACB_SET_DEVICE_STATUS] = msdp_set_status;
callback[ACB_REQUEST_REMOTE_SERVICE] = msdp_rpc;
/*注册zigbee设备事件处理接口*/
return msdp_register_device_helper(DEV_TYPE_ZIGBEE, callback);
}
void mdsp_zbnet_exit()
{
msdp_unregister_device_helper(DEV_TYPE_ZIGBEE);
}

View file

@ -0,0 +1,8 @@
src = Split('''
msdp.c
msdp_common.c
msdp_zigbee.c
msdp_gateway.c
''')
component = aos_component('msdp', src)

View file

@ -0,0 +1,10 @@
src = Split('''
gateway_service.c
''')
component = aos_component('gateway', src)
component.add_global_macros('MESH_GATEWAY_SERVICE')
component.add_global_macros('GATEWAY_SDK')
component.add_comp_deps('utility/cjson', 'kernel/protocols/mesh', 'framework/protocol/alink',
'framework/gateway/devmgr', 'framework/gateway/msdp')