Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
k-sdk
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈伟灿
k-sdk
Commits
b8f242aa
Commit
b8f242aa
authored
Sep 16, 2020
by
尹佳钦
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
以配置的方式加载表
parent
9a29244b
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1638 additions
and
358 deletions
+1638
-358
platform/zigbee/app/builder/Z3GatewayHost/ZB/dev_map_table.json
...rm/zigbee/app/builder/Z3GatewayHost/ZB/dev_map_table.json
+21
-0
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.c
...m/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.c
+560
-339
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.h
...m/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.h
+6
-14
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.c
...bee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.c
+149
-2
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.h
...bee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.h
+12
-3
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_set.h
...zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_set.h
+2
-0
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.c
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.c
+681
-0
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.h
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.h
+207
-0
No files found.
platform/zigbee/app/builder/Z3GatewayHost/ZB/dev_map_table.json
0 → 100644
View file @
b8f242aa
{
"mapTable"
:
[
{
"modleId"
:
"00068611"
,
"productCode"
:
"3001"
,
"productName"
:
"星辰系列.白色零火线单路灯控面板Z3S(KONKE)"
},{
"modleId"
:
"00068612"
,
"productCode"
:
"3002"
,
"productName"
:
"星辰系列.白色零火线双路灯控面板Z3S(KONKE)"
},{
"modleId"
:
"00068613"
,
"productCode"
:
"3003"
,
"productName"
:
"星辰系列.白色零火线三路灯控面板Z3S(KONKE)"
},{
"modleId"
:
"01020001"
,
"productCode"
:
"3073"
,
"productName"
:
"幻彩灯带控制器Z3S(KONKE)"
}
]
}
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.c
View file @
b8f242aa
#include "kk_device_manager.h"
#include "kk_device_manager.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#include "sqlite3.h"
/****************** ******************************************************************
/****************** ******************************************************************
...
@@ -12,296 +15,16 @@
...
@@ -12,296 +15,16 @@
#define KK_GP_EP 242
#define KK_GP_EP 242
kk_device_table_s
*
kk_zb_device_table
=
NULL
;
static
void
kk_device_table_save
(
void
);
static
void
kk_device_table_load
(
void
);
void
kk_print_device_table
(
void
)
{
int
i
,
cnt
=
0
;
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
emberAfCorePrintln
(
"
\n
-----------kk device table-----------
\n
"
);
while
(
ptr
!=
NULL
){
emberAfAppPrint
(
"
\n
%d:"
,
++
cnt
);
emberAfAppPrint
(
"
\n
MAC = "
);
emberAfPrintBigEndianEui64
(
ptr
->
mac
);
emberAfAppPrint
(
"
\n
productCode = %s"
,(
ptr
->
productCode
!=
NULL
)
?
ptr
->
productCode
:
"unknow"
);
emberAfAppPrint
(
"
\n
identifyCnt = %d"
,
ptr
->
identifyCnt
);
ptr
=
ptr
->
next
;
}
}
static
kk_device_table_s
*
kk_device_table_create
()
{
emberAfCorePrintln
(
"
\n
[KK device table] add!"
);
kk_device_table_s
*
node
=
(
kk_device_table_s
*
)
malloc
(
sizeof
(
kk_device_table_s
));
if
(
node
==
NULL
){
emberAfCorePrintln
(
"[KK device table] malloc fail!!!%s"
,
__LINE__
);
return
node
;
}
MEMSET
(
node
,
0
,
sizeof
(
kk_device_table_s
));
return
node
;
}
static
kk_device_table_s
*
kk_device_table_find_next_empty
()
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
if
(
ptr
==
NULL
)
return
ptr
;
while
(
ptr
!=
NULL
){
if
(
ptr
->
next
==
NULL
)
return
ptr
;
ptr
=
ptr
->
next
;
}
}
static
void
kk_device_fill
(
kk_device_table_s
*
ptr
,
EmberEUI64
mac
,
EmberNodeId
nodeId
,
char
*
productCode
,
uint16_t
deviceId
)
{
memcpy
(
ptr
->
mac
,
mac
,
sizeof
(
EmberEUI64
));
ptr
->
nodeId
=
nodeId
;
ptr
->
deviceId
=
deviceId
;
ptr
->
identifyCnt
=
KK_MAX_READ_MODLE_ID_COUNT
;
memcpy
(
ptr
->
productCode
,
productCode
,
strlen
(
productCode
));
}
kk_device_table_s
*
kk_device_find_by_mac
(
EmberEUI64
mac
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
while
(
ptr
!=
NULL
){
if
(
MEMCOMPARE
(
ptr
->
mac
,
mac
,
sizeof
(
EmberEUI64
))
==
0
){
return
ptr
;
}
ptr
=
ptr
->
next
;
}
return
NULL
;
}
kk_device_table_s
*
kk_device_find_by_node
(
EmberNodeId
node
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
while
(
ptr
!=
NULL
){
if
(
ptr
->
nodeId
==
node
){
return
ptr
;
}
ptr
=
ptr
->
next
;
}
return
NULL
;
}
bool
kk_device_find_by_mac11111
(
EmberEUI64
mac
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
while
(
ptr
!=
NULL
){
if
(
MEMCOMPARE
(
ptr
->
mac
,
mac
,
sizeof
(
EmberEUI64
))
==
0
){
return
true
;
}
ptr
=
ptr
->
next
;
}
return
false
;
}
void
kk_device_table_add
(
EmberEUI64
mac
,
EmberNodeId
nodeId
,
const
char
*
productCode
,
uint16_t
deviceId
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
kk_device_table_s
*
newNode
;
UTIL_LOG_INFO
(
"
\n
********************kk device table add********************
\n
"
);
emberAfAppPrint
(
"mac:"
);
emberAfPrintBigEndianEui64
(
mac
);
kk_sub_tsl_add
(
mac
,
productCode
);
if
(
kk_device_find_by_node
(
nodeId
)
!=
NULL
){
emberAfAppPrintln
(
" is already in device table!!!"
);
return
;
}
emberAfAppPrintln
(
",nodeId:0x%02x,productCode:%s,device id:0x%04x"
,
nodeId
,(
productCode
==
NULL
)
?
"nukown"
:
productCode
,
deviceId
);
if
(
ptr
==
NULL
){
kk_zb_device_table
=
kk_device_table_create
();
ptr
=
kk_zb_device_table
;
kk_device_fill
(
ptr
,
mac
,
nodeId
,
productCode
,
deviceId
);
return
;
}
ptr
=
kk_device_table_find_next_empty
();
if
(
ptr
!=
NULL
){
newNode
=
kk_device_table_create
();
if
(
newNode
!=
NULL
){
ptr
->
next
=
newNode
;
kk_device_fill
(
newNode
,
mac
,
nodeId
,
productCode
,
deviceId
);
}
}
else
{
emberAfCorePrintln
(
"[KK device table] fatal!!!%s"
,
__LINE__
);
}
}
void
kk_device_table_delete
(
EmberEUI64
mac
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
kk_device_table_s
*
ptr_temp
=
kk_zb_device_table
;
if
(
ptr
==
NULL
){
emberAfCorePrintln
(
"[KK device table] is empty!!!"
);
return
;
}
while
(
ptr
!=
NULL
){
if
(
MEMCOMPARE
(
ptr
->
mac
,
mac
,
sizeof
(
EmberEUI64
))
==
0
){
if
(
ptr
->
next
==
NULL
){
free
(
ptr
);
kk_zb_device_table
=
NULL
;
emberAfCorePrintln
(
"[KK device table]delete,now is empty !!!"
);
return
;
}
else
{
if
(
ptr
==
kk_zb_device_table
){
kk_zb_device_table
=
ptr
->
next
;
emberAfCorePrintln
(
"[KK device table] delete list header"
);
free
(
ptr
);
return
;
}
else
{
ptr_temp
->
next
=
ptr
->
next
;
free
(
ptr
);
emberAfCorePrintln
(
"[KK device table] delete "
);
return
;
}
}
}
ptr_temp
=
ptr
;
ptr
=
ptr
->
next
;
}
}
static
void
kk_device_table_save
(
void
)
{
FILE
*
fp
;
int
i
;
uint16_t
pLen
;
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
fp
=
fopen
(
"kk_devices.txt"
,
"w"
);
while
(
ptr
!=
NULL
){
for
(
i
=
0
;
i
<
8
;
i
++
)
{
fprintf
(
fp
,
"%x "
,
ptr
->
mac
[
i
]);
}
fprintf
(
fp
,
"%x "
,
ptr
->
nodeId
);
fprintf
(
fp
,
"%x "
,
ptr
->
deviceId
);
if
(
ptr
->
productCode
==
NULL
){
pLen
=
0
;
}
else
{
pLen
=
strlen
(
ptr
->
productCode
);
}
fprintf
(
fp
,
"%x "
,
pLen
);
for
(
i
=
0
;
i
<
pLen
;
i
++
){
fprintf
(
fp
,
"%x "
,
ptr
->
productCode
[
i
]);
}
ptr
=
ptr
->
next
;
}
fclose
(
fp
);
}
static
void
kk_device_table_load
(
void
)
{
UTIL_LOG_INFO
(
"
\n
********************kk load device table********************
\n
"
);
FILE
*
fp
;
int
i
;
EmberEUI64
mac
;
uint16_t
nodeId
;
uint16_t
deviceId
;
uint16_t
len
;
char
pCode
[
33
];
fp
=
fopen
(
"kk_devices.txt"
,
"r"
);
if
(
fp
==
NULL
)
return
;
while
(
feof
(
fp
)
==
false
){
emberAfDebugPrintln
(
"111"
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
fscanf
(
fp
,
"%x "
,
&
mac
[
i
]);
}
emberAfDebugPrintln
(
"222"
);
fscanf
(
fp
,
"%x"
,
&
nodeId
);
fscanf
(
fp
,
"%x "
,
&
deviceId
);
emberAfDebugPrintln
(
"len=%d"
,
len
);
fscanf
(
fp
,
"%x"
,
&
len
);
for
(
i
=
0
;
i
<
len
;
i
++
){
fscanf
(
fp
,
"%x "
,
&
pCode
[
i
]);
}
pCode
[
i
]
=
0
;
if
(
len
==
0
){
kk_device_table_add
(
mac
,
nodeId
,
NULL
,
deviceId
);
}
else
{
kk_device_table_add
(
mac
,
nodeId
,
pCode
,
deviceId
);
}
}
fclose
(
fp
);
//kk_device_table_add(EmberEUI64 mac,EmberNodeId nodeId,uint8_t epNum,uint8_t* epVal,char *productCode)
//kk_print_device_table();
}
void
kk_device_table_clear
(
void
)
{
kk_device_table_s
*
ptr
=
kk_zb_device_table
;
kk_device_table_s
*
ptr_temp
=
kk_zb_device_table
;
if
(
ptr
==
NULL
){
return
;
}
while
(
ptr
!=
NULL
){
if
(
ptr
->
next
==
NULL
){
free
(
ptr
);
kk_zb_device_table
=
NULL
;
return
;
}
else
{
if
(
ptr
==
kk_zb_device_table
){
kk_zb_device_table
=
ptr
->
next
;
free
(
ptr
);
return
;
}
else
{
ptr_temp
->
next
=
ptr
->
next
;
free
(
ptr
);
return
;
}
}
ptr_temp
=
ptr
;
ptr
=
ptr
->
next
;
}
kk_device_table_save
();
}
static
const
char
*
kk_match_tsl_productCode
(
const
char
*
modelId
)
static
const
char
*
kk_match_tsl_productCode
(
const
char
*
modelId
)
{
{
int
i
;
int
i
;
int
num
=
kk_get_product_code_table_size
();
int
num
=
kk_get_product_code_table_size
();
UTIL_LOG_INFO
(
"device model id:%s
\n
"
,
modelId
);
UTIL_LOG_INFO
(
"device model id:%s
,%d
\n
"
,
modelId
,
strlen
(
modelId
)
);
for
(
i
=
0
;
i
<
num
&&
kk_product_code
[
i
].
modelId
!=
NULL
;
i
++
){
for
(
i
=
0
;
i
<
num
&&
kk_product_code
[
i
].
modelId
!=
NULL
;
i
++
){
emberAfDebugPrint
(
"i=%d,%s
\n
"
,
i
,
kk_product_code
[
i
].
modelId
);
if
(
strstr
(
modelId
,
kk_product_code
[
i
].
modelId
)
!=
NULL
){
if
(
strstr
(
modelId
,
kk_product_code
[
i
].
modelId
)
!=
NULL
){
UTIL_LOG_INFO
(
"match model id:%s
\n
"
,
kk_product_code
[
i
].
modelId
);
UTIL_LOG_INFO
(
"match model id:%s
\n
"
,
kk_product_code
[
i
].
modelId
);
UTIL_LOG_INFO
(
"tsl product code:%s
\n
"
,
kk_product_code
[
i
].
code
);
UTIL_LOG_INFO
(
"tsl product code:%s
\n
"
,
kk_product_code
[
i
].
code
);
...
@@ -318,25 +41,7 @@ static const char *kk_match_tsl_productCode(const char* modelId)
...
@@ -318,25 +41,7 @@ static const char *kk_match_tsl_productCode(const char* modelId)
////////////////////////////////////////////////////
////////////////////////////////////////////////////
void
kk_db
()
{
sqlite3
*
db
=
NULL
;
char
create
[]
=
"create table kk_device(number integer PRIMARY KEY, name text, sex text, age integer);"
;
int
ret
=
sqlite3_open
(
"kk_device.db"
,
&
db
);
if
(
ret
)
{
emberAfDebugPrintln
(
"can not open database.
\n
"
);
}
else
{
emberAfDebugPrintln
(
"open database succsee.
\n
"
);
}
}
void
emberAfPluginDeviceTableInitialized
(
void
)
{
kk_device_table_load
();
kk_db
();
}
static
int
kk_match_device_id
(
uint16_t
deviceId
)
static
int
kk_match_device_id
(
uint16_t
deviceId
)
...
@@ -367,7 +72,7 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
...
@@ -367,7 +72,7 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
uint8_t
*
data
)
uint8_t
*
data
)
{
{
kk_device_table_s
*
ptr
=
kk_
zb_device_table
;
kk_device_table_s
*
ptr
=
kk_
get_device_table_pointer
()
;
EmberEUI64
eui64
;
EmberEUI64
eui64
;
uint8_t
modelID
[
33
]
=
{
0
};
uint8_t
modelID
[
33
]
=
{
0
};
char
*
pCode
=
NULL
;
char
*
pCode
=
NULL
;
...
@@ -381,7 +86,7 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
...
@@ -381,7 +86,7 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
emberAfCorePrintln
(
"[warring]modle id size = %d,max = 32!!!"
);
emberAfCorePrintln
(
"[warring]modle id size = %d,max = 32!!!"
);
}
}
memcpy
(
modelID
,
data
,
dataSize
);
memcpy
(
modelID
,
data
,
dataSize
);
pCode
=
kk_match_
tsl_
productCode
(
modelID
);
pCode
=
kk_match_productCode
(
modelID
);
if
(
pCode
==
NULL
){
if
(
pCode
==
NULL
){
emberAfCorePrintln
(
"not match pCode!!!"
);
emberAfCorePrintln
(
"not match pCode!!!"
);
return
;
return
;
...
@@ -389,8 +94,9 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
...
@@ -389,8 +94,9 @@ static void kk_device_modle_id_identify(EmberNodeId nodeId,
memcpy
(
ptr
->
productCode
,
pCode
,
strlen
(
pCode
));
memcpy
(
ptr
->
productCode
,
pCode
,
strlen
(
pCode
));
if
(
ptr
->
productCode
!=
NULL
){
if
(
ptr
->
productCode
!=
NULL
){
if
(
emberAfDeviceTableGetEui64FromNodeId
(
ptr
->
nodeId
,
eui64
)){
if
(
emberAfDeviceTableGetEui64FromNodeId
(
ptr
->
nodeId
,
eui64
)){
kk_rpc_reportDevices
(
eui64
,
ptr
->
productCode
);
kk_msg_report_dev_joined
(
eui64
,
ptr
->
productCode
);
kk_device_table_save
();
kk_device_db_update
(
eui64
,
ptr
->
nodeId
,
ptr
->
deviceId
,
ptr
->
productCode
);
kk_device_config_map_add
(
ptr
->
productCode
);
}
else
{
}
else
{
UTIL_LOG_WARNING
(
"not find mac from node in device table!!!"
);
UTIL_LOG_WARNING
(
"not find mac from node in device table!!!"
);
}
}
...
@@ -449,46 +155,22 @@ void emberAfPluginDeviceTableDeviceLeftCallback(EmberEUI64 nodeEui64)
...
@@ -449,46 +155,22 @@ void emberAfPluginDeviceTableDeviceLeftCallback(EmberEUI64 nodeEui64)
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"left"
,
deviceTable
[
deviceTableIndex
].
eui64
);
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"left"
,
deviceTable
[
deviceTableIndex
].
eui64
);
rpc_printfJSON
(
"left"
,
nodeJson
);
rpc_printfJSON
(
"left"
,
nodeJson
);
kk_
rpc_reportLeftDevices
(
deviceTable
[
deviceTableIndex
].
eui64
);
kk_
msg_report_dev_leave
(
deviceTable
[
deviceTableIndex
].
eui64
);
}
}
void
kk_device_joined
(
EmberNodeId
node
)
{
EmberEUI64
mac
;
uint16_t
deviceId
;
uint16_t
deviceTableIndex
;
EmberAfPluginDeviceTableEntry
*
devPtr
;
UTIL_LOG_INFO
(
"
\n
********************kk device joined********************
\n
"
);
if
(
emberAfDeviceTableGetEui64FromNodeId
(
node
,
mac
)
==
false
){
deviceTableIndex
=
emberAfDeviceTableGetIndexFromNodeId
(
node
);
if
(
deviceTableIndex
!=
0xffff
){
devPtr
=
emberAfDeviceTablePointer
();
kk_add_device_to_table
(
mac
,
node
,
devPtr
[
deviceTableIndex
].
deviceId
);
}
}
else
{
emberAfDebugPrintln
(
"[not find 111]"
);
if
(
emberLookupEui64ByNodeId
(
node
,
mac
)
==
EMBER_SUCCESS
){
deviceTableIndex
=
emberAfDeviceTableGetIndexFromNodeId
(
node
);
if
(
deviceTableIndex
!=
0xffff
){
devPtr
=
emberAfDeviceTablePointer
();
kk_add_device_to_table
(
mac
,
node
,
devPtr
[
deviceTableIndex
].
deviceId
);
}
}
else
{
emberAfDebugPrintln
(
"[not find 222]"
);
}
}
}
void
kk_productCode_tick
()
void
kk_productCode_tick
()
{
{
kk_device_table_s
*
ptr
=
kk_
zb_device_table
;
kk_device_table_s
*
ptr
=
kk_
get_device_table_pointer
()
;
EmberEUI64
eui64
;
EmberEUI64
eui64
;
EmberStatus
status
;
EmberStatus
status
;
while
(
ptr
!=
NULL
){
while
(
ptr
!=
NULL
){
if
(
ptr
->
productCode
==
NULL
){
emberAfCorePrintln
(
"%d"
,
strlen
(
ptr
->
productCode
));
if
(
strlen
(
ptr
->
productCode
)
==
0
){
if
(
ptr
->
nodeId
!=
0xffff
&&
ptr
->
identifyCnt
!=
0
){
if
(
ptr
->
nodeId
!=
0xffff
&&
ptr
->
identifyCnt
!=
0
){
status
=
zclGRead
(
ptr
->
nodeId
,
status
=
zclGRead
(
ptr
->
nodeId
,
1
,
1
,
...
@@ -520,7 +202,7 @@ void kk_add_device_to_table(EmberEUI64 mac,EmberNodeId nodeId,uint16_t deviceId)
...
@@ -520,7 +202,7 @@ void kk_add_device_to_table(EmberEUI64 mac,EmberNodeId nodeId,uint16_t deviceId)
kk_match_device_id
(
deviceId
);
kk_match_device_id
(
deviceId
);
kk_device_table_add
(
mac
,
nodeId
,
NULL
,
deviceId
);
kk_device_table_add
(
mac
,
nodeId
,
NULL
,
deviceId
);
kk_device_
table_save
(
);
kk_device_
db_insert
(
mac
,
nodeId
,
deviceId
,
""
);
}
}
...
@@ -534,7 +216,8 @@ void kk_network_check(void)
...
@@ -534,7 +216,8 @@ void kk_network_check(void)
panId
=
HIGH_LOW_TO_INT
(
eui64
[
1
],
eui64
[
0
]);
panId
=
HIGH_LOW_TO_INT
(
eui64
[
1
],
eui64
[
0
]);
status
=
kk_network_form
(
true
,
panId
,
KK_NETWORK_PARAMETER_TX_POWER
,
KK_NETWORK_PARAMETER_CHANNEL
);
status
=
kk_network_form
(
true
,
panId
,
KK_NETWORK_PARAMETER_TX_POWER
,
KK_NETWORK_PARAMETER_CHANNEL
);
if
(
status
==
EMBER_SUCCESS
){
if
(
status
==
EMBER_SUCCESS
){
emberAfAppPrintln
(
"network form success~~~~~~"
);
UTIL_LOG_INFO
(
"network form success~~~~~~"
);
kk_print_network_info
();
}
else
{
}
else
{
emberAfAppPrintln
(
"network form fail!!!,status=0x%x"
,
status
);
emberAfAppPrintln
(
"network form fail!!!,status=0x%x"
,
status
);
}
}
...
@@ -549,6 +232,8 @@ int kk_permit_join(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* da
...
@@ -549,6 +232,8 @@ int kk_permit_join(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* da
EmberStatus
status
;
EmberStatus
status
;
uint8_t
isEnable
=
*
(
uint8_t
*
)
data
;
uint8_t
isEnable
=
*
(
uint8_t
*
)
data
;
kk_network_check
();
if
(
isEnable
==
0
){
if
(
isEnable
==
0
){
status
=
nwkPermitJoinCMD
(
FALSE
);
status
=
nwkPermitJoinCMD
(
FALSE
);
emberAfCorePrintln
(
"Disable Permit join
\r\n
"
);
emberAfCorePrintln
(
"Disable Permit join
\r\n
"
);
...
@@ -569,8 +254,524 @@ error_return:
...
@@ -569,8 +254,524 @@ error_return:
#define KK_DEVICE_MAP_TABLE_FILE "./ZB/dev_map_table.json"
#define KK_DEVICE_MAP_TABLE_ARRAY_IDENTIFY "mapTable"
#define KK_DEVICE_CONFIG_MAP_TABLE_ARRAY_IDENTIFY "config"
typedef
struct
kk_dev_map
{
char
*
modleId
;
char
*
productCode
;
char
*
productName
;
struct
kk_dev_map
*
next
;
}
kk_dev_map
;
static
kk_dev_map
*
device_map
=
NULL
;
bool
kk_device_map_add
(
const
char
*
modleId
,
const
char
*
productCode
,
const
char
*
productName
)
{
int
len
;
kk_dev_map
*
ptr
,
*
pre
;
ptr
=
pre
=
device_map
;
if
(
modleId
==
NULL
&&
productCode
==
NULL
)
return
false
;
while
(
ptr
!=
NULL
){
pre
=
ptr
;
ptr
=
ptr
->
next
;
}
ptr
=
(
kk_dev_map
*
)
malloc
(
sizeof
(
kk_dev_map
));
memset
(
ptr
,
0
,
sizeof
(
kk_dev_map
));
len
=
strlen
(
modleId
);
ptr
->
modleId
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
modleId
,
modleId
,
len
);
ptr
->
modleId
[
len
]
=
'\0'
;
len
=
strlen
(
productCode
);
ptr
->
productCode
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
productCode
,
productCode
,
len
);
ptr
->
productCode
[
len
]
=
'\0'
;
if
(
productName
!=
NULL
){
len
=
strlen
(
productName
);
ptr
->
productName
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
productName
,
productName
,
len
);
ptr
->
productName
[
len
]
=
'\0'
;
}
if
(
device_map
==
NULL
){
device_map
=
ptr
;
}
else
{
pre
->
next
=
ptr
;
}
return
true
;
}
void
kk_device_map_print
(
void
)
{
int
cnt
=
1
;
kk_dev_map
*
ptr
=
device_map
;
UTIL_LOG_INFO
(
"
\n
***************device map list print***************
\n
"
);
while
(
ptr
!=
NULL
){
emberAfCorePrintln
(
"--------------------%d--------------------
\n
"
,
cnt
++
);
emberAfCorePrintln
(
"modleId:%s
\n
"
,
ptr
->
modleId
);
emberAfCorePrintln
(
"productCode:%s
\n
"
,
ptr
->
productCode
);
if
(
ptr
->
productName
){
emberAfCorePrintln
(
"productName:%s
\n
"
,
ptr
->
productName
);
}
ptr
=
ptr
->
next
;
}
}
void
kk_load_dev_map_table
(
void
)
{
int
len
;
int
bufferSize
;
int
fd
=
open
(
KK_DEVICE_MAP_TABLE_FILE
,
O_RDONLY
);
struct
stat
statbuff
;
stat
(
KK_DEVICE_MAP_TABLE_FILE
,
&
statbuff
);
bufferSize
=
statbuff
.
st_size
+
128
;
uint8_t
*
buffer
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memset
(
buffer
,
0
,
bufferSize
);
UTIL_LOG_INFO
(
"
\n
***************load device map table***************
\n
"
);
if
(
fd
<
0
){
free
(
buffer
);
UTIL_LOG_ERR
(
"can not open %s,fd=%d!!!
\n
"
,
KK_DEVICE_MAP_TABLE_FILE
,
fd
);
return
;
}
len
=
read
(
fd
,
buffer
,
bufferSize
);
if
(
len
<
0
){
free
(
buffer
);
close
(
fd
);
UTIL_LOG_ERR
(
"can not read %s!!!
\n
"
,
KK_DEVICE_MAP_TABLE_FILE
);
return
;
}
cJSON
*
map
=
rpc_cJSON_Parse
(
buffer
);
if
(
map
==
NULL
){
free
(
buffer
);
UTIL_LOG_INFO
(
"can not load dev map table!!!
\n
"
);
return
;
}
char
*
p
=
rpc_cJSON_Print
(
map
);
if
(
p
!=
NULL
){
emberAfCorePrintln
(
"device map table JSON:
\n
%s
\n
"
,
p
);
free
(
p
);
}
kk_add_dev_map_table_to_list
(
map
);
free
(
buffer
);
close
(
fd
);
rpc_cJSON_Delete
(
map
);
}
void
kk_add_dev_map_table_to_list
(
cJSON
*
root
)
{
int
i
,
len
,
size
;
cJSON
*
item
,
*
modelId
,
*
productCode
,
*
productName
;
cJSON
*
table
=
rpc_cJSON_GetObjectItem
(
root
,
KK_DEVICE_MAP_TABLE_ARRAY_IDENTIFY
);
if
(
table
==
NULL
){
UTIL_LOG_INFO
(
"can not add dev map to list!!!
\n
"
);
return
;
}
size
=
rpc_cJSON_GetArraySize
(
table
);
for
(
i
=
0
;
i
<
size
;
i
++
){
item
=
rpc_cJSON_GetArrayItem
(
table
,
i
);
modelId
=
cJSON_GetObjectItem
(
item
,
"modleId"
);
productCode
=
cJSON_GetObjectItem
(
item
,
"productCode"
);
productName
=
cJSON_GetObjectItem
(
item
,
"productName"
);
kk_device_map_add
(
modelId
->
valuestring
,
productCode
->
valuestring
,
productName
->
valuestring
);
}
}
char
*
kk_match_productCode
(
const
char
*
modelId
)
{
kk_dev_map
*
ptr
=
device_map
;
UTIL_LOG_INFO
(
"
\n
***************match productCode***************
\n
"
);
UTIL_LOG_INFO
(
"device model id:%s
\n
"
,
modelId
);
while
(
ptr
!=
NULL
){
if
(
strstr
(
modelId
,
ptr
->
modleId
)
!=
NULL
){
UTIL_LOG_INFO
(
"match model id:%s
\n
"
,
ptr
->
modleId
);
UTIL_LOG_INFO
(
"tsl product code:%s
\n
"
,
ptr
->
productCode
);
if
(
ptr
->
productName
!=
NULL
){
UTIL_LOG_INFO
(
"match product:%s
\n
"
,
ptr
->
productName
);
}
return
ptr
->
productCode
;
}
ptr
=
ptr
->
next
;
}
return
NULL
;
}
typedef
struct
kk_dev_config_item
{
char
*
identity
;
char
*
reportFuncName
;
char
*
controlFuncName
;
kk_rpc_report
*
reportFunc
;
kk_rpc_set
*
controlFunc
;
uint8_t
endpoint
;
uint16_t
cluster
;
uint16_t
attribute
;
struct
kk_dev_config_item
*
next
;
}
kk_dev_config_item
;
typedef
struct
kk_dev_config_map
{
char
*
productCode
;
kk_dev_config_item
item
;
struct
kk_dev_config_map
*
next
;
}
kk_dev_config_map
;
static
kk_dev_config_map
*
dev_config_map
=
NULL
;
#define KK_DEVICE_CONFIG_MAP_TABLE_FILE_PREFIX "./ZB/dev_config_table/device_%s.json"
kk_dev_config_item
*
kk_device_config_item_find_by_identity
(
kk_dev_config_map
*
map
,
const
char
*
identity
)
{
kk_dev_config_item
*
item
;
item
=
&
map
->
item
;
while
(
item
!=
NULL
){
if
(
!
strcmp
(
item
->
identity
,
identity
)){
return
item
;
}
}
return
NULL
;
}
kk_dev_config_map
*
kk_device_config_find
(
const
char
*
productCode
)
{
kk_dev_config_map
*
ptr
,
*
pre
;
ptr
=
pre
=
dev_config_map
;
if
(
productCode
==
NULL
)
return
NULL
;
while
(
ptr
!=
NULL
){
if
(
!
memcmp
(
ptr
->
productCode
,
productCode
,
strlen
(
productCode
))){
return
ptr
;
}
pre
=
ptr
;
ptr
=
ptr
->
next
;
}
return
NULL
;
}
void
kk_device_config_item_report
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clu
,
EmberAfAttributeId
attr
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int
status
;
kk_dev_config_item
*
item
;
kk_dev_config_map
*
cfgMap
;
char
*
pCode
;
kk_zigbee_property_report
func
;
pCode
=
kk_device_find_productCode
(
eui64
);
cfgMap
=
kk_device_config_find
(
pCode
);
if
(
cfgMap
==
NULL
)
return
;
item
=
&
cfgMap
->
item
;
while
(
item
!=
NULL
){
if
(
item
->
endpoint
==
EP
&&
item
->
cluster
==
clu
&&
item
->
attribute
==
attr
){
if
(
item
->
reportFunc
!=
NULL
){
func
=
item
->
reportFunc
;
emberAfCorePrintln
(
"[call]:%s
\n
"
,
item
->
reportFuncName
);
status
=
func
(
eui64
,
EP
,
clu
,
attr
,
dataType
,
len
,
data
);
emberAfDebugPrintln
(
"report status:%d"
,
status
);
break
;
}
}
}
}
kk_rpc_set
kk_find_rpc_set_function_api
(
const
char
*
name
)
{
int
rpcFuncSize
=
kk_get_rpc_set_api_size
();
for
(
int
i
=
0
;
i
<
rpcFuncSize
;
i
++
){
if
(
!
strcmp
(
kk_rpc_set_api
[
i
].
name
,
name
)){
return
kk_rpc_set_api
[
i
].
set
;
}
}
}
kk_rpc_report
kk_find_rpc_report_function_api
(
const
char
*
name
)
{
int
rpcFuncSize
=
kk_get_rpc_report_api_size
();
for
(
int
i
=
0
;
i
<
rpcFuncSize
;
i
++
){
if
(
!
strcmp
(
kk_rpc_report_api
[
i
].
name
,
name
)){
return
kk_rpc_report_api
[
i
].
report
;
}
}
}
bool
kk_device_config_exist_check
(
const
char
*
productCode
)
{
kk_dev_config_map
*
ptr
=
dev_config_map
;
while
(
ptr
!=
NULL
){
if
(
!
strcmp
(
ptr
->
productCode
,
productCode
))
return
true
;
ptr
=
ptr
->
next
;
}
return
false
;
}
bool
kk_device_config_add
(
const
char
*
productCode
,
const
char
*
identity
,
uint8_t
ep
,
uint16_t
clu
,
uint16_t
attr
,
const
char
*
reportFuncName
,
const
char
*
controlFuncName
)
{
int
len
;
kk_dev_config_map
*
ptr
,
*
pre
,
*
pTemp
;
kk_dev_config_item
*
item
,
*
itemPre
,
*
newItem
;
ptr
=
kk_device_config_find
(
productCode
);
if
(
ptr
==
NULL
){
ptr
=
(
kk_dev_config_map
*
)
malloc
(
sizeof
(
kk_dev_config_map
));
memset
(
ptr
,
0
,
sizeof
(
kk_dev_config_map
));
len
=
strlen
(
productCode
);
ptr
->
productCode
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
productCode
,
productCode
,
len
);
ptr
->
productCode
[
len
]
=
'\0'
;
len
=
strlen
(
identity
);
ptr
->
item
.
identity
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
item
.
identity
,
identity
,
len
);
ptr
->
item
.
identity
[
len
]
=
'\0'
;
ptr
->
item
.
endpoint
=
ep
;
ptr
->
item
.
cluster
=
clu
;
ptr
->
item
.
attribute
=
attr
;
len
=
strlen
(
reportFuncName
);
ptr
->
item
.
reportFuncName
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
item
.
reportFuncName
,
reportFuncName
,
len
);
ptr
->
item
.
reportFuncName
[
len
]
=
'\0'
;
len
=
strlen
(
controlFuncName
);
ptr
->
item
.
controlFuncName
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
ptr
->
item
.
controlFuncName
,
controlFuncName
,
len
);
ptr
->
item
.
controlFuncName
[
len
]
=
'\0'
;
newItem
->
reportFunc
=
kk_find_rpc_report_function_api
(
reportFuncName
);
newItem
->
controlFunc
=
kk_find_rpc_set_function_api
(
controlFuncName
);
if
(
dev_config_map
==
NULL
){
dev_config_map
=
ptr
;
}
else
{
pTemp
=
dev_config_map
;
while
(
pTemp
!=
NULL
){
pre
=
pTemp
;
pTemp
=
pTemp
->
next
;
}
pTemp
=
pre
;
pTemp
->
next
=
ptr
;
}
}
else
{
item
=
&
ptr
->
item
;
while
(
item
!=
NULL
){
itemPre
=
item
;
item
=
item
->
next
;
}
newItem
=
(
kk_dev_config_item
*
)
malloc
(
sizeof
(
kk_dev_config_item
));
memset
(
newItem
,
0
,
sizeof
(
kk_dev_config_item
));
len
=
strlen
(
identity
);
newItem
->
identity
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
newItem
->
identity
,
identity
,
len
);
newItem
->
identity
[
len
]
=
'\0'
;
newItem
->
endpoint
=
ep
;
newItem
->
cluster
=
clu
;
newItem
->
attribute
=
attr
;
len
=
strlen
(
reportFuncName
);
newItem
->
reportFuncName
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
newItem
->
reportFuncName
,
reportFuncName
,
len
);
newItem
->
reportFuncName
[
len
]
=
'\0'
;
len
=
strlen
(
controlFuncName
);
newItem
->
controlFuncName
=
(
char
*
)
malloc
(
len
+
1
);
memcpy
(
newItem
->
controlFuncName
,
controlFuncName
,
len
);
newItem
->
controlFuncName
[
len
]
=
'\0'
;
newItem
->
reportFunc
=
kk_find_rpc_report_function_api
(
reportFuncName
);
newItem
->
controlFunc
=
kk_find_rpc_set_function_api
(
controlFuncName
);
itemPre
->
next
=
newItem
;
}
return
true
;
}
void
kk_add_dev_config_map_table_to_list
(
cJSON
*
root
,
const
char
*
productCode
)
{
uint8_t
ep
;
uint16_t
clu
;
uint16_t
attr
;
int
i
,
len
,
size
;
cJSON
*
item
,
*
identity
;
cJSON
*
endpoint
,
*
cluster
,
*
attribute
,
*
reportFuncName
,
*
controlFuncName
;
cJSON
*
table
=
rpc_cJSON_GetObjectItem
(
root
,
KK_DEVICE_CONFIG_MAP_TABLE_ARRAY_IDENTIFY
);
if
(
table
==
NULL
){
UTIL_LOG_INFO
(
"can not add dev map to list!!!
\n
"
);
return
;
}
size
=
rpc_cJSON_GetArraySize
(
table
);
for
(
i
=
0
;
i
<
size
;
i
++
){
item
=
rpc_cJSON_GetArrayItem
(
table
,
i
);
identity
=
cJSON_GetObjectItem
(
item
,
"identity"
);
endpoint
=
cJSON_GetObjectItem
(
item
,
"endpoint"
);
cluster
=
cJSON_GetObjectItem
(
item
,
"cluster"
);
attribute
=
cJSON_GetObjectItem
(
item
,
"attribute"
);
reportFuncName
=
cJSON_GetObjectItem
(
item
,
"reportFunc"
);
controlFuncName
=
cJSON_GetObjectItem
(
item
,
"controlFunc"
);
ep
=
endpoint
->
valueint
;
len
=
strlen
(
cluster
->
valuestring
);
if
(
len
>=
4
){
clu
=
rpc_get_u16
(
&
cluster
->
valuestring
[
len
-
4
]);
}
else
{
continue
;
}
len
=
strlen
(
attribute
->
valuestring
);
if
(
len
>=
4
){
attr
=
rpc_get_u16
(
&
attribute
->
valuestring
[
len
-
4
]);
}
else
{
continue
;
}
kk_device_config_add
(
productCode
,
identity
->
valuestring
,
ep
,
clu
,
attr
,
reportFuncName
->
valuestring
,
controlFuncName
->
valuestring
);
}
kk_device_config_map_print
();
}
void
kk_device_config_map_load
(
const
char
*
devFile
,
const
char
*
productCode
)
{
int
len
;
int
bufferSize
;
int
fd
=
open
(
devFile
,
O_RDONLY
);
struct
stat
statbuff
;
if
(
kk_device_config_exist_check
(
productCode
)
==
true
){
UTIL_LOG_ERR
(
"devFile[%s] is already load!!!
\n
"
,
devFile
);
return
;
}
stat
(
devFile
,
&
statbuff
);
bufferSize
=
statbuff
.
st_size
+
128
;
uint8_t
*
buffer
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memset
(
buffer
,
0
,
bufferSize
);
UTIL_LOG_INFO
(
"
\n
***************load device config map table***************
\n
"
);
if
(
fd
<
0
){
free
(
buffer
);
UTIL_LOG_ERR
(
"can not open %s,fd=%d!!!
\n
"
,
devFile
,
fd
);
return
;
}
len
=
read
(
fd
,
buffer
,
bufferSize
);
if
(
len
<
0
){
free
(
buffer
);
close
(
fd
);
UTIL_LOG_ERR
(
"can not read %s!!!
\n
"
,
devFile
);
return
;
}
cJSON
*
map
=
rpc_cJSON_Parse
(
buffer
);
if
(
map
==
NULL
){
UTIL_LOG_INFO
(
"len=%d,data:%s
\n
"
,
len
,
buffer
);
UTIL_LOG_INFO
(
"can not load dev map table!!!
\n
"
);
free
(
buffer
);
return
;
}
char
*
p
=
rpc_cJSON_Print
(
map
);
if
(
p
!=
NULL
){
emberAfCorePrintln
(
"device map table JSON:
\n
%s
\n
"
,
p
);
free
(
p
);
}
free
(
buffer
);
close
(
fd
);
kk_add_dev_config_map_table_to_list
(
map
,
productCode
);
rpc_cJSON_Delete
(
map
);
}
bool
kk_device_config_map_add
(
const
char
*
productCode
)
{
int
len
;
char
devfile
[
128
];
UTIL_LOG_INFO
(
"
\n
***************device config map add***************
\n
"
);
if
(
productCode
==
NULL
)
return
false
;
sprintf
(
devfile
,
KK_DEVICE_CONFIG_MAP_TABLE_FILE_PREFIX
,
productCode
);
emberAfCorePrintln
(
"devfile:%s
\n
"
,
devfile
);
kk_device_config_map_load
(
devfile
,
productCode
);
return
true
;
}
void
kk_device_config_map_print
(
void
)
{
int
cnt1
,
cnt2
=
1
;
kk_dev_config_map
*
ptr
=
dev_config_map
;
kk_dev_config_item
*
item
;
UTIL_LOG_INFO
(
"
\n
***************device config map list print***************
\n
"
);
while
(
ptr
!=
NULL
){
emberAfCorePrintln
(
"--------------------%d--------------------
\n
"
,
cnt1
++
);
emberAfCorePrintln
(
"productCode:%s
\n
"
,
ptr
->
productCode
);
item
=
&
ptr
->
item
;
cnt2
=
0
;
while
(
item
!=
NULL
){
emberAfCorePrintln
(
"**************%d**************
\n
"
,
cnt2
++
);
emberAfCorePrintln
(
"identity:%s
\n
"
,
item
->
identity
);
emberAfCorePrintln
(
"endpoint:%d
\n
"
,
item
->
endpoint
);
emberAfCorePrintln
(
"cluster:0x%04X
\n
"
,
item
->
cluster
);
emberAfCorePrintln
(
"attribute:0x%04X
\n
"
,
item
->
attribute
);
emberAfCorePrintln
(
"reportFunc:%s
\n
"
,
item
->
reportFuncName
);
emberAfCorePrintln
(
"controlFunc:%s
\n
"
,
item
->
controlFuncName
);
item
=
item
->
next
;
}
ptr
=
ptr
->
next
;
}
}
...
@@ -579,12 +780,32 @@ error_return:
...
@@ -579,12 +780,32 @@ error_return:
void
kk_rpc_report_attribute
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int
i
,
j
,
num
,
status
;
char
macString
[
19
]
=
{
0
};
sub_dev_node_t
*
node
=
NULL
;
char
*
pCode
;
int
res
=
0
;
UTIL_LOG_INFO
(
"
\n
********************kk rpc report attribute********************
\n
"
);
emberAfDebugPrint
(
"mac:"
);
emberAfDebugPrintln
(
",ep:%d,clu:0x%04X,attr:0x%04X,dataType=0x%02x,len=%d,data:"
,
EP
,
clusterId
,
attributeId
,
dataType
,
len
);
emberAfDebugPrintBuffer
(
data
,
len
,
true
);
kk_device_config_item_report
(
eui64
,
EP
,
clusterId
,
attributeId
,
dataType
,
len
,
data
);
}
...
...
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_device_manager.h
View file @
b8f242aa
...
@@ -4,33 +4,21 @@
...
@@ -4,33 +4,21 @@
#include "kk_sub_tsl.h"
#include "kk_sub_tsl.h"
#include "kk_tsl_zigbee_map.h"
#include "kk_tsl_zigbee_map.h"
#include "kk_product_code.h"
#include "kk_product_code.h"
#include "kk_zb_com.h"
/****************** ******************************************************************
/****************** ******************************************************************
* File Name : kk_device_manager.h
* File Name : kk_device_manager.h
* Author : yjq
* Author : yjq
* data : 2020/09/01
* data : 2020/09/01
*************************************************************************************/
*************************************************************************************/
typedef
struct
kk_device_table_s
{
EmberEUI64
mac
;
EmberNodeId
nodeId
;
uint16_t
deviceId
;
uint16_t
identifyCnt
;
char
productCode
[
33
];
struct
kk_device_table_s
*
next
;
}
kk_device_table_s
;
#define KK_MAX_SUPPORT_ENDPOINT_NUMBER 32
#define KK_MAX_SUPPORT_ENDPOINT_NUMBER 32
#define KK_MAX_READ_MODLE_ID_COUNT 30
#define KK_MAX_READ_MODLE_ID_COUNT 30
#define KK_NETWORK_PARAMETER_TX_POWER 10
#define KK_NETWORK_PARAMETER_TX_POWER 10
#define KK_NETWORK_PARAMETER_CHANNEL 0x0B
#define KK_NETWORK_PARAMETER_CHANNEL 0x0B
void
kk_print_device_table
(
void
);
kk_device_table_s
*
kk_device_find_by_mac
(
EmberEUI64
mac
);
void
kk_device_table_add
(
EmberEUI64
mac
,
EmberNodeId
nodeId
,
const
char
*
productCode
,
uint16_t
deviceId
);
void
kk_device_table_delete
(
EmberEUI64
mac
);
void
kk_add_device_to_table
(
EmberEUI64
mac
,
EmberNodeId
nodeId
,
uint16_t
deviceId
);
void
kk_productCode_tick
();
void
kk_productCode_tick
();
void
kk_read_attr_response
(
EmberNodeId
nodeId
,
void
kk_read_attr_response
(
EmberNodeId
nodeId
,
...
@@ -47,8 +35,12 @@ int kk_permit_join(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* da
...
@@ -47,8 +35,12 @@ int kk_permit_join(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* da
void
kk_load_dev_map_table
(
void
);
void
kk_add_dev_map_table_to_list
(
cJSON
*
root
);
char
*
kk_match_productCode
(
const
char
*
modelId
);
bool
kk_device_config_map_add
(
const
char
*
productCode
);
...
...
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.c
View file @
b8f242aa
#include "kk_tsl_property_report.h"
#include "kk_tsl_property_report.h"
#include "kk_tsl_zigbee_map.h"
const
char
*
kk_tsl_rpt_status_string
[]
=
{
const
char
*
kk_tsl_rpt_status_string
[]
=
{
"Success"
,
"Success"
,
...
@@ -8,6 +8,7 @@ const char *kk_tsl_rpt_status_string[] = {
...
@@ -8,6 +8,7 @@ const char *kk_tsl_rpt_status_string[] = {
"Invaild Len"
,
"Invaild Len"
,
"Invaild Type"
"Invaild Type"
};
};
//todo: fix it
static
int
kk_tsl_report
(
EmberEUI64
mac
,
uint8_t
EP
,
int
status
,
uint16_t
clusterId
,
uint16_t
attributeId
)
static
int
kk_tsl_report
(
EmberEUI64
mac
,
uint8_t
EP
,
int
status
,
uint16_t
clusterId
,
uint16_t
attributeId
)
{
{
cJSON
*
root
;
cJSON
*
root
;
...
@@ -38,7 +39,7 @@ static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId
...
@@ -38,7 +39,7 @@ static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId
}
}
rpc_cJSON_AddNumberToObject
(
root
,
Identify
,
status
);
rpc_cJSON_AddNumberToObject
(
root
,
Identify
,
status
);
kk_
rpc_report_status
(
root
,
mac
);
kk_
msg_report_property
(
root
,
mac
);
return
tsl_rpt_success
;
return
tsl_rpt_success
;
}
}
...
@@ -153,12 +154,158 @@ int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClu
...
@@ -153,12 +154,158 @@ int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClu
int
kk_tsl_report_metering_summationDelivered
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
uint64_t
summation
;
emberAfAppPrintln
(
"[tsl report:meter(Smart Energy)] Summation Delivered~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT48U_ATTRIBUTE_TYPE
){
if
(
len
==
6
){
summation
=
KK_GET_U48
(
data
);
kk_tsl_report
(
eui64
,
EP
,
summation
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_ias_zoneStatus
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
uint64_t
Status
;
emberAfAppPrintln
(
"[tsl report:IAS] Zone Status~~~~~~~~~"
);
if
(
dataType
==
ZCL_BITMAP16_ATTRIBUTE_TYPE
){
if
(
len
==
2
){
Status
=
KK_GET_U16
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Status
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_global_Level
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
uint8_t
level
;
emberAfAppPrintln
(
"[tsl report:Gloabl] Level~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT8U_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
level
=
data
[
0
];
kk_tsl_report
(
eui64
,
EP
,
level
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_temperature_measure
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int16_t
Value
;
emberAfAppPrintln
(
"[tsl report:temperature measurement] Measure Value~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT16S_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
Value
=
KK_GET_U16
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Value
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_illuminance_measure
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
uint16_t
Value
;
emberAfAppPrintln
(
"[tsl report:illuminance measurement] Measure Value~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT16U_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
Value
=
KK_GET_U16
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Value
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_local_temperature
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int16_t
Value
;
emberAfAppPrintln
(
"[tsl report:local temperature] Value~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT16S_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
Value
=
KK_GET_U16
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Value
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_OccupiedHeatingSetpoint
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int16_t
Value
;
emberAfAppPrintln
(
"[tsl report:Occupied Heating Setpoint] Value~~~~~~~~~"
);
if
(
dataType
==
ZCL_INT16S_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
Value
=
KK_GET_U16
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Value
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_Concentration
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
int32_t
Value
;
emberAfAppPrintln
(
"[tsl report:Formaldehyde] Value~~~~~~~~~"
);
if
(
dataType
==
ZCL_FLOAT_SINGLE_ATTRIBUTE_TYPE
){
if
(
len
==
1
){
Value
=
KK_GET_U32
(
data
);
kk_tsl_report
(
eui64
,
EP
,
Value
,
clusterId
,
attributeId
);
return
tsl_rpt_success
;
}
return
tsl_rpt_invaild_len
;
}
return
tsl_rpt_invaild_type
;
}
int
kk_tsl_report_Formaldehyde
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
emberAfAppPrintln
(
"[tsl report:Formaldehyde] Value~~~~~~~~~"
);
return
kk_tsl_report_Concentration
(
eui64
,
EP
,
clusterId
,
attributeId
,
dataType
,
len
,
data
);
}
int
kk_tsl_report_PM2_5
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
emberAfAppPrintln
(
"[tsl report:PM2.5] Value~~~~~~~~~"
);
return
kk_tsl_report_Concentration
(
eui64
,
EP
,
clusterId
,
attributeId
,
dataType
,
len
,
data
);
}
int
kk_tsl_report_CO2
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
)
{
emberAfAppPrintln
(
"[tsl report:CO2] Value~~~~~~~~~"
);
return
kk_tsl_report_Concentration
(
eui64
,
EP
,
clusterId
,
attributeId
,
dataType
,
len
,
data
);
}
...
...
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_report.h
View file @
b8f242aa
#ifndef __KK_TSL_PROPERTY_REPORT_H
#ifndef __KK_TSL_PROPERTY_REPORT_H
#define __KK_TSL_PROPERTY_REPORT_H
#define __KK_TSL_PROPERTY_REPORT_H
#include "kk_test.h"
#include "kk_zb_com.h"
#include "kk_msg_report.h"
typedef
enum
{
typedef
enum
{
...
@@ -26,11 +27,19 @@ int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClu
...
@@ -26,11 +27,19 @@ int kk_tsl_report_windowCovering_position(EmberEUI64 eui64,uint8_t EP,EmberAfClu
int
kk_tsl_report_ias_zoneStatus
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_metering_summationDelivered
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_global_Level
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_temperature_measure
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_illuminance_measure
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_local_temperature
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_OccupiedHeatingSetpoint
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_Formaldehyde
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_PM2_5
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
int
kk_tsl_report_CO2
(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
...
...
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_tsl_property_set.h
View file @
b8f242aa
...
@@ -12,6 +12,8 @@ int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned
...
@@ -12,6 +12,8 @@ int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned
int
kk_tsl_set_windowCovering_position
(
jrpc_context
*
ctx
,
EmberNodeId
node
,
unsigned
char
ep
,
void
*
data
);
int
kk_tsl_set_windowCovering_position
(
jrpc_context
*
ctx
,
EmberNodeId
node
,
unsigned
char
ep
,
void
*
data
);
#define RPC_KK_TEST_FUNCTION_TABLE \
{(rpc_function*)kk_tsl_property_operation,"/thing/service/property/set"}\
...
...
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.c
View file @
b8f242aa
#include "kk_zigbee_api.h"
#include "kk_zigbee_api.h"
kk_rpc_set_api_s
kk_rpc_set_api
[]
=
KK_RPC_SET_FUNCTION_TABLE
;
kk_rpc_report_api_s
kk_rpc_report_api
[]
=
KK_RPC_REPORT_FUNCTION_TABLE
;
void
kk_rpc_test
(
void
)
{
emberAfAppPrintln
(
"!!!!!!!!!!!kk_rpc_test!!!!!!!!!!!!!!"
);
}
uint8_t
kk_get_rpc_set_api_size
(
void
)
{
return
sizeof
(
kk_rpc_set_api
)
/
sizeof
(
kk_rpc_set_api_s
);
}
uint8_t
kk_get_rpc_report_api_size
(
void
)
{
return
sizeof
(
kk_rpc_report_api
)
/
sizeof
(
kk_rpc_report_api_s
);
}
// network leave
// network leave
EmberStatus
kk_network_leave
(
void
)
EmberStatus
kk_network_leave
(
void
)
{
{
...
@@ -736,3 +757,663 @@ EmberStatus zclColorControlStepcolortemp(uint16_t node,
...
@@ -736,3 +757,663 @@ EmberStatus zclColorControlStepcolortemp(uint16_t node,
return
status
;
return
status
;
}
}
EmberStatus
zclGroupsAddGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
,
char
*
name
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
if
(
name
==
NULL
)
return
EMBER_INVALID_CALL
;
len
=
strlen
(
name
);
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_ADD_GROUP_COMMAND_ID
);
zclBufferAddWord
(
id
);
for
(
i
=
0
;
i
<
len
;
i
++
){
zclBufferAddByte
(
name
[
i
]);
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Add Group] id:%d,Name:%s,status:0x%02x
\r\n
"
,
id
,
name
,
status
);
return
status
;
}
EmberStatus
zclGroupsViewGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_VIEW_GROUP_COMMAND_ID
);
zclBufferAddWord
(
id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[View Group] id:%d,status:0x%02x
\r\n
"
,
id
,
status
);
return
status
;
}
EmberStatus
zclGroupsGetGroupMembership
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
count
,
uint16_t
*
list
)
{
uint8_t
i
;
EmberStatus
status
;
if
(
count
==
0
||
list
==
NULL
)
return
EMBER_INVALID_CALL
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_GET_GROUP_MEMBERSHIP_COMMAND_ID
);
zclBufferAddWord
(
count
);
for
(
i
=
0
;
i
<
count
;
i
++
){
zclBufferAddWord
(
list
[
i
]);
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Get Group Membership] count:%d,status:0x%02x
\r\n
"
,
count
,
status
);
return
status
;
}
EmberStatus
zclGroupsRemoveGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_REMOVE_GROUP_COMMAND_ID
);
zclBufferAddWord
(
id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Remove Group] id:%d,status:0x%02x
\r\n
"
,
id
,
status
);
return
status
;
}
EmberStatus
zclGroupsRemoveAllGroups
(
uint16_t
node
,
uint8_t
ep
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_REMOVE_ALL_GROUPS_COMMAND_ID
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Remove All Groups]status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclGroupsAddGroupIfIdentifying
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
,
char
*
name
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
if
(
name
==
NULL
)
return
EMBER_INVALID_CALL
;
len
=
strlen
(
name
);
zcl_clu_client_cmd_buffer_setup
(
ZCL_GROUPS_CLUSTER_ID
,
ZCL_ADD_GROUP_IF_IDENTIFYING_COMMAND_ID
);
zclBufferAddWord
(
id
);
for
(
i
=
0
;
i
<
len
;
i
++
){
zclBufferAddByte
(
name
[
i
]);
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Add Group if Identifying] id:%d,Name:%s,status:0x%02x
\r\n
"
,
id
,
name
,
status
);
return
status
;
}
EmberStatus
zclScenesAddScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trs_time
,
char
*
name
,
uint8_t
extLen
,
uint8_t
*
extData
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_ADD_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
zclBufferAddWord
(
trs_time
);
if
(
name
!=
NULL
){
len
=
strlen
(
name
);
for
(
i
=
0
;
i
<
len
;
i
++
){
zclBufferAddByte
(
name
[
i
]);
}
for
(
i
=
0
;
i
<
extLen
;
i
++
){
zclBufferAddByte
(
extData
[
i
]);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Add Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesViewScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_VIEW_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[View Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesRemoveScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_REMOVE_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Remove Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesRemoveAllScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_REMOVE_ALL_SCENES_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Remove All Scene] g_id:%d,status:0x%02x
\r\n
"
,
g_id
,
status
);
return
status
;
}
EmberStatus
zclScenesStoreScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_STORE_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Store Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesRecallScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trsTime
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_RECALL_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
zclBufferAddWord
(
trsTime
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Recall Scene] g_id:%d,s_id:%d,trsTime:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
trsTime
,
status
);
return
status
;
}
EmberStatus
zclScenesGetSceneMembership
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_GET_SCENE_MEMBERSHIP_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[View Scene] g_id:%d,status:0x%02x
\r\n
"
,
g_id
,
status
);
return
status
;
}
EmberStatus
zclScenesEnhancedAddScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trs_time
,
char
*
name
,
uint8_t
extLen
,
uint8_t
*
extData
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_ENHANCED_ADD_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
zclBufferAddWord
(
trs_time
);
if
(
name
!=
NULL
){
len
=
strlen
(
name
);
for
(
i
=
0
;
i
<
len
;
i
++
){
zclBufferAddByte
(
name
[
i
]);
}
for
(
i
=
0
;
i
<
extLen
;
i
++
){
zclBufferAddByte
(
extData
[
i
]);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Enhanced Add Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesEnhancedViewScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID
);
zclBufferAddWord
(
g_id
);
zclBufferAddWord
(
s_id
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Enhanced View Scene] g_id:%d,s_id:%d,status:0x%02x
\r\n
"
,
g_id
,
s_id
,
status
);
return
status
;
}
EmberStatus
zclScenesCopyScene
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint16_t
gidFrom
,
uint16_t
sidFrom
,
uint16_t
gidTo
,
uint16_t
sidTo
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_SCENES_CLUSTER_ID
,
ZCL_COPY_SCENE_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddWord
(
gidFrom
);
zclBufferAddWord
(
sidFrom
);
zclBufferAddWord
(
gidTo
);
zclBufferAddWord
(
sidTo
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Copy Scene] mode:%d,gidFrom:%d,sidFrom:%d,gidTo:%d,sidTo:%d,status:0x%02x
\r\n
"
,
mode
,
gidFrom
,
sidFrom
,
gidTo
,
sidTo
,
status
);
return
status
;
}
EmberStatus
zclLevel_MoveToLevel
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
level
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_MOVE_TO_LEVEL_COMMAND_ID
);
zclBufferAddByte
(
level
);
zclBufferAddWord
(
trsTime
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move To Level] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_Move
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
rate
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_STEP_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddByte
(
rate
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_Step
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
size
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_STEP_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddByte
(
size
);
zclBufferAddWord
(
trsTime
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] step:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_Stop
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_STOP_COMMAND_ID
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] step:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_MoveToLevelWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
level
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID
);
zclBufferAddByte
(
level
);
zclBufferAddWord
(
trsTime
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move To Level] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_MoveWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
rate
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_MOVE_WITH_ON_OFF_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddByte
(
rate
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_StepWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
size
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_STEP_WITH_ON_OFF_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddByte
(
size
);
zclBufferAddWord
(
trsTime
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] step:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclLevel_StopWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
*
mask
,
uint8_t
*
override
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_LEVEL_CONTROL_CLUSTER_ID
,
ZCL_STOP_WITH_ON_OFF_COMMAND_ID
);
if
(
mask
!=
NULL
){
zclBufferAddByte
(
mask
);
if
(
override
!=
NULL
){
zclBufferAddByte
(
override
);
}
}
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Move] step:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclWD_StartWarning
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint16_t
duration
,
uint8_t
cycle
,
uint8_t
level
)
{
uint8_t
i
,
len
;
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_IAS_WD_CLUSTER_ID
,
ZCL_START_WARNING_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddWord
(
duration
);
zclBufferAddByte
(
cycle
);
zclBufferAddByte
(
level
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Start Warning] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclWD_Squawk
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_IAS_WD_CLUSTER_ID
,
ZCL_SQUAWK_COMMAND_ID
);
zclBufferAddByte
(
mode
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Squawk] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclThermostat_Setpoint_Raise_Lower
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
amount
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_THERMOSTAT_CLUSTER_ID
,
ZCL_SETPOINT_RAISE_LOWER_COMMAND_ID
);
zclBufferAddByte
(
mode
);
zclBufferAddByte
(
amount
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Setpoint Raise/Lower] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
/*
EmberStatus zclThermostat_Set_Weekly_Schedule(uint16_t node,
uint8_t ep,
uint8_t mode,
uint8_t amount)
{
EmberStatus status;
zcl_clu_client_cmd_buffer_setup( ZCL_THERMOSTAT_CLUSTER_ID,
ZCL_SET_WEEKLY_SCHEDULE_COMMAND_ID);
zclBufferAddByte(mode);
zclBufferAddByte(amount);
status = rpcSendCommand(node,1,ep,false);
emberAfCorePrintln("[Setpoint Raise/Lower] status:0x%02x\r\n",status);
return status;
}*/
EmberStatus
zclThermostat_GetWeeklySchedule
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
days
,
uint8_t
mode
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_THERMOSTAT_CLUSTER_ID
,
ZCL_GET_WEEKLY_SCHEDULE_COMMAND_ID
);
zclBufferAddByte
(
days
);
zclBufferAddByte
(
mode
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Get Weekly Schedule] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclThermostat_ClearWeeklySchedule
(
uint16_t
node
,
uint8_t
ep
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_THERMOSTAT_CLUSTER_ID
,
ZCL_CLEAR_WEEKLY_SCHEDULE_COMMAND_ID
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Clear Weekly Schedule] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
EmberStatus
zclThermostat_GetRelayStatusLog
(
uint16_t
node
,
uint8_t
ep
)
{
EmberStatus
status
;
zcl_clu_client_cmd_buffer_setup
(
ZCL_THERMOSTAT_CLUSTER_ID
,
ZCL_GET_RELAY_STATUS_LOG_COMMAND_ID
);
status
=
rpcSendCommand
(
node
,
1
,
ep
,
false
);
emberAfCorePrintln
(
"[Get Relay Status Log] status:0x%02x
\r\n
"
,
status
);
return
status
;
}
platform/zigbee/app/builder/Z3GatewayHost/ZB/kk_zigbee_api.h
View file @
b8f242aa
...
@@ -2,6 +2,41 @@
...
@@ -2,6 +2,41 @@
#define __KK_ZIGBEE_API_H
#define __KK_ZIGBEE_API_H
#include "kk_test.h"
#include "kk_test.h"
typedef
int
(
*
kk_rpc_set
)(
jrpc_context
*
ctx
,
EmberNodeId
node
,
unsigned
char
ep
,
void
*
data
);
typedef
int
(
*
kk_rpc_report
)(
EmberEUI64
eui64
,
uint8_t
EP
,
EmberAfClusterId
clusterId
,
EmberAfAttributeId
attributeId
,
uint8_t
dataType
,
uint8_t
len
,
uint8_t
*
data
);
typedef
struct
{
const
char
*
name
;
kk_rpc_set
set
;
}
kk_rpc_set_api_s
;
typedef
struct
{
const
char
*
name
;
kk_rpc_report
report
;
}
kk_rpc_report_api_s
;
void
kk_rpc_test
(
void
);
#define KK_RPC_SET_FUNCTION_TABLE {\
{"zclOnOff_On",zclOnOff_On},\
{"zclOnOff_Off",zclOnOff_Off}\
}
#define KK_RPC_REPORT_FUNCTION_TABLE {\
{"kk_tsl_report_global_onoff",kk_tsl_report_global_onoff},\
{"kk_tsl_report_global_onoff",kk_tsl_report_global_onoff}\
}
kk_rpc_set_api_s
kk_rpc_set_api
[];
kk_rpc_report_api_s
kk_rpc_report_api
[];
uint8_t
kk_get_rpc_set_api_size
(
void
);
uint8_t
kk_get_rpc_report_api_size
(
void
);
EmberStatus
kk_network_leave
(
void
);
EmberStatus
kk_network_leave
(
void
);
EmberStatus
kk_network_form
(
bool
centralized
,
EmberPanId
panId
,
int8_t
radioTxPower
,
uint8_t
channel
);
EmberStatus
kk_network_form
(
bool
centralized
,
EmberPanId
panId
,
int8_t
radioTxPower
,
uint8_t
channel
);
void
kk_print_network_info
(
void
);
void
kk_print_network_info
(
void
);
...
@@ -199,11 +234,183 @@ EmberStatus zclColorControlStepcolortemp(uint16_t node,
...
@@ -199,11 +234,183 @@ EmberStatus zclColorControlStepcolortemp(uint16_t node,
EmberStatus
zclGroupsAddGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
,
char
*
name
);
EmberStatus
zclGroupsViewGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
);
EmberStatus
zclGroupsGetGroupMembership
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
count
,
uint16_t
*
list
);
EmberStatus
zclGroupsRemoveGroup
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
);
EmberStatus
zclGroupsRemoveAllGroups
(
uint16_t
node
,
uint8_t
ep
);
EmberStatus
zclGroupsAddGroupIfIdentifying
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
id
,
char
*
name
);
EmberStatus
zclScenesAddScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trs_time
,
char
*
name
,
uint8_t
extLen
,
uint8_t
*
extData
);
EmberStatus
zclScenesViewScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
);
EmberStatus
zclScenesRemoveScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
);
EmberStatus
zclScenesRemoveAllScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
);
EmberStatus
zclScenesStoreScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
);
EmberStatus
zclScenesRecallScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trsTime
);
EmberStatus
zclScenesGetSceneMembership
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
);
EmberStatus
zclScenesEnhancedAddScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
,
uint16_t
trs_time
,
char
*
name
,
uint8_t
extLen
,
uint8_t
*
extData
);
EmberStatus
zclScenesEnhancedViewScene
(
uint16_t
node
,
uint8_t
ep
,
uint16_t
g_id
,
uint16_t
s_id
);
EmberStatus
zclScenesCopyScene
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint16_t
gidFrom
,
uint16_t
sidFrom
,
uint16_t
gidTo
,
uint16_t
sidTo
);
EmberStatus
zclLevel_MoveToLevel
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
level
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_Move
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
rate
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_Step
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
size
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_Stop
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_MoveToLevelWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
level
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_MoveWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
rate
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_StepWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
size
,
uint16_t
trsTime
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclLevel_StopWithOnOff
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
*
mask
,
uint8_t
*
override
);
EmberStatus
zclWD_StartWarning
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint16_t
duration
,
uint8_t
cycle
,
uint8_t
level
);
EmberStatus
zclWD_Squawk
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
);
EmberStatus
zclThermostat_Setpoint_Raise_Lower
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
mode
,
uint8_t
amount
);
EmberStatus
zclThermostat_GetWeeklySchedule
(
uint16_t
node
,
uint8_t
ep
,
uint8_t
days
,
uint8_t
mode
);
EmberStatus
zclThermostat_ClearWeeklySchedule
(
uint16_t
node
,
uint8_t
ep
);
EmberStatus
zclThermostat_GetRelayStatusLog
(
uint16_t
node
,
uint8_t
ep
);
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment