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
d6ef290b
Commit
d6ef290b
authored
Sep 01, 2020
by
黄振令
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【修改内容】1. midware从数据库中导入网关的ip地址;2. 网关ip地址获取错误
【提交人】huang.zhenling
parent
1b05821a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
2472 additions
and
2342 deletions
+2472
-2342
common/api/tcp_channel.c
common/api/tcp_channel.c
+707
-685
midware/midware/dm/kk_property_db.c
midware/midware/dm/kk_property_db.c
+89
-0
midware/midware/dm/kk_property_db.h
midware/midware/dm/kk_property_db.h
+14
-8
midware/midware/midware.c
midware/midware/midware.c
+698
-687
platform/zigbee/app/builder/Z3GatewayHost/libapi_com.so
platform/zigbee/app/builder/Z3GatewayHost/libapi_com.so
+0
-0
platform/zigbee/app/builder/Z3GatewayHost/rpc_api/src/rpc_interface_parse.c
...p/builder/Z3GatewayHost/rpc_api/src/rpc_interface_parse.c
+964
-962
No files found.
common/api/tcp_channel.c
View file @
d6ef290b
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include "com_api.h"
#define CCU_TCP_PORT 16565
#define BUFFER_SIZE 1024
#define MAX_LISTEN_NUM 10
#define MAX_IP_LEN 16
#define DEVICE_CODE_LEN 33
typedef
struct
{
char
deviceCode
[
DEVICE_CODE_LEN
];
char
ip
[
MAX_IP_LEN
];
int
sock
;
int
isConnect
;
}
kk_tcp_ctrl_t
;
static
kk_tcp_ctrl_t
g_tcp_ctrl
[
MAX_LISTEN_NUM
];
static
struct
ev_loop
*
g_loop
=
NULL
;
static
pthread_t
g_pTh
=
NULL
;
static
int
g_init
=
0
;
static
ipc_cb
*
g_cb
=
NULL
;
static
struct
ev_io
w_accept
;
// Save/Load the gateway list
void
kk_gw_list_save
(
void
)
{
FILE
*
fp
;
uint8_t
i
;
uint8_t
j
;
int
len
=
MAX_LISTEN_NUM
*
sizeof
(
kk_tcp_ctrl_t
);
// Save device table
fp
=
fopen
(
"gwlist.txt"
,
"w"
);
fwrite
(
g_tcp_ctrl
,
len
,
1
,
fp
);
fclose
(
fp
);
}
void
kk_gw_list_load
(
void
)
{
uint16_t
i
;
FILE
*
fp
;
int
readLen
=
MAX_LISTEN_NUM
*
sizeof
(
kk_tcp_ctrl_t
);
int
retLen
=
0
;
fp
=
fopen
(
"gwlist.txt"
,
"r"
);
if
(
!
fp
)
{
printf
(
"open gatewaylist.txt failed!
\n
"
);
goto
error1
;
}
char
buf
[
1024
]
=
{
0
};
retLen
=
fread
(
g_tcp_ctrl
,
readLen
,
1
,
fp
);
printf
(
"read gatewaylist.txt retLen= %d, readLen=%d !
\n
"
,
retLen
,
readLen
);
if
(
retLen
!=
readLen
){
printf
(
"read gatewaylist.txt failed!
\n
"
);
}
fclose
(
fp
);
// Set the rest of the device table to null.
error1:
for
(
i
=
0
;
i
<
MAX_LISTEN_NUM
;
i
++
)
{
printf
(
"deviceCode ip sock [%s] [%s] [%d]
\n
"
,
g_tcp_ctrl
[
i
].
deviceCode
,
g_tcp_ctrl
[
i
].
ip
==
NULL
?
""
:
g_tcp_ctrl
[
i
].
ip
,
g_tcp_ctrl
[
i
].
sock
);
g_tcp_ctrl
[
i
].
sock
=
-
1
;
}
}
static
int
get_idx_by_ip
(
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
return
i
;
}
}
return
-
1
;
}
static
int
get_sock_by_deviceCode
(
char
deviceCode
[
DEVICE_CODE_LEN
]){
int
i
=
0
;
if
(
deviceCode
==
NULL
||
strlen
(
deviceCode
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
deviceCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
return
g_tcp_ctrl
[
i
].
sock
;
}
}
return
-
1
;
}
static
kk_tcp_ctrl_t
*
get_channel_by_ip
(
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
NULL
;
}
printf
(
"[%s] ip=%s
\n
"
,
__FUNCTION__
,
ip
);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
ip
,
g_tcp_ctrl
[
i
].
sock
);
return
&
g_tcp_ctrl
[
i
];
}
}
return
NULL
;
}
static
int
set_status_by_ip
(
char
ip
[
MAX_IP_LEN
],
int
status
){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
g_tcp_ctrl
[
i
].
isConnect
=
status
;
return
0
;
}
}
return
-
1
;
}
static
int
reset_by_sock
(
int
sock
){
int
i
=
0
;
if
(
sock
<
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
sock
==
g_tcp_ctrl
[
i
].
sock
){
g_tcp_ctrl
[
i
].
isConnect
=
0
;
g_tcp_ctrl
[
i
].
isConnect
=
-
1
;
return
0
;
}
}
return
-
1
;
}
static
int
set_sock_by_ip
(
char
ip
[
MAX_IP_LEN
],
int
sock
){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
printf
(
"[%s] ip=%s
\n
"
,
__FUNCTION__
,
ip
);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
g_tcp_ctrl
[
i
].
sock
=
sock
;
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
ip
,
g_tcp_ctrl
[
i
].
sock
);
return
0
;
}
}
return
-
1
;
}
int
kk_is_tcp_channel
(
char
devCode
[
DEVICE_CODE_LEN
]){
int
i
=
0
;
if
(
devCode
==
NULL
||
strlen
(
devCode
)
==
0
){
return
-
1
;
}
//printf("[%s] devCode=%s \n", __FUNCTION__,devCode);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
devCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
devCode
,
g_tcp_ctrl
[
i
].
sock
);
return
i
;
}
}
return
-
1
;
}
int
kk_set_tcp_channel
(
char
devCode
[
DEVICE_CODE_LEN
],
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
int
isEmptyIdx
=
-
1
;
if
(
devCode
==
NULL
||
strlen
(
devCode
)
==
0
||
ip
==
NULL
||
strlen
(
ip
)
==
0
){
printf
(
"paramenter error
\n
"
);
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
devCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
strncpy
(
g_tcp_ctrl
[
i
].
ip
,
ip
,
strlen
(
ip
));
printf
(
"find and replace it [%d][%s][%s]
\n
"
,
i
,
g_tcp_ctrl
[
i
].
ip
,
devCode
);
kk_gw_list_save
();
break
;
}
if
(
strlen
(
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
&&
isEmptyIdx
==
-
1
){
isEmptyIdx
=
i
;
}
}
if
(
i
<
MAX_LISTEN_NUM
){
return
0
;
}
if
(
isEmptyIdx
!=
-
1
){
strncpy
(
g_tcp_ctrl
[
isEmptyIdx
].
ip
,
ip
,
strlen
(
ip
));
strncpy
(
g_tcp_ctrl
[
isEmptyIdx
].
deviceCode
,
devCode
,
strlen
(
devCode
));
printf
(
"idx deviceCode ip[%d][%s][%s]"
,
isEmptyIdx
,
g_tcp_ctrl
[
isEmptyIdx
].
deviceCode
,
g_tcp_ctrl
[
isEmptyIdx
].
ip
);
kk_gw_list_save
();
return
0
;
}
return
-
1
;
}
/*初始化服务端*/
static
int
server_socket_init
(
int
*
sd
,
char
*
ipaddr
,
uint16_t
port
)
{
//创建socket
int
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
-
1
==
sock
){
printf
(
"error socket
\n
"
);
goto
err1
;
}
//设置立即释放端口并可以再次使用
int
reuse
=
1
;
if
(
-
1
==
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
reuse
,
sizeof
(
reuse
))){
printf
(
"error setsockopt
\n
"
);
goto
err2
;
}
//设置为非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
)){
printf
(
"================== fcntl
\n
"
);
goto
err2
;
}
struct
sockaddr_in
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
NULL
==
ipaddr
)
{
addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
}
else
{
addr
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddr
);
}
//绑定监听
if
(
-
1
==
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))){
printf
(
"error bind
\n
"
);
goto
err2
;
}
if
(
-
1
==
listen
(
sock
,
MAX_LISTEN_NUM
)){
printf
(
"error listen
\n
"
);
goto
err2
;
}
*
sd
=
sock
;
return
0
;
err2:
close
(
sock
);
err1:
return
-
1
;
}
/*读回调*/
static
void
read_cb
(
struct
ev_loop
*
loop
,
struct
ev_io
*
watcher
,
int
revents
)
{
printf
(
"================== read_cb
\n
"
);
char
buffer
[
BUFFER_SIZE
]
=
{
0
};
if
(
EV_ERROR
&
revents
)
{
printf
(
"read got invalid event...
\r\n
"
);
return
;
}
int
res
=
0
;
kk_tcp_ctrl_t
*
tcp_ctrl
=
(
kk_tcp_ctrl_t
*
)
watcher
->
data
;
int32_t
bytes
=
read
(
watcher
->
fd
,
buffer
,
sizeof
(
buffer
));
if
(
-
1
==
bytes
)
{
//tcp Error
if
(
EINTR
!=
errno
&&
EAGAIN
!=
errno
)
{
res
=
1
;
}
}
else
if
(
0
==
bytes
)
{
//tcp Close
res
=
2
;
}
if
(
0
!=
res
)
{
//关闭事件循环并释放watcher
printf
(
"TCP CLOSE
\r\n
"
);
reset_by_sock
(
watcher
->
fd
);
ev_io_stop
(
loop
,
watcher
);
free
(
watcher
);
}
else
{
//intf("READ:\r\n %s\r\n", buffer);
printf
(
"read_cb deviceCode ip sock [%s][%s][%d]"
,
tcp_ctrl
->
deviceCode
,
tcp_ctrl
->
ip
,
tcp_ctrl
->
sock
);
if
(
g_cb
!=
NULL
){
g_cb
(
buffer
,
bytes
,
tcp_ctrl
->
deviceCode
);
}
}
}
/*accept回调函数*/
static
void
accept_cb
(
struct
ev_loop
*
loop
,
struct
ev_io
*
watcher
,
int
revents
)
{
printf
(
"================== accept_cb
\n
"
);
struct
sockaddr_in
client_addr
;
socklen_t
client_len
=
sizeof
(
client_addr
);
if
(
EV_ERROR
&
revents
)
{
printf
(
"accept got invalid event...
\r\n
"
);
return
;
}
//accept连接
int
sock
=
accept
(
watcher
->
fd
,
(
struct
sockaddr
*
)
&
client_addr
,
&
client_len
);
if
(
-
1
==
sock
)
{
return
;
}
//设置非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
))
{
close
(
sock
);
return
;
}
if
(
set_sock_by_ip
(
inet_ntoa
(
client_addr
.
sin_addr
),
sock
)
<
0
){
//ip无效,reject it
printf
(
"This ip[%s][%u] is invaild, reject it!
\r\n
"
,
inet_ntoa
(
client_addr
.
sin_addr
),
client_addr
.
sin_port
);
close
(
sock
);
return
;
}
printf
(
"Successfully connected with client: %s:%u
\r\n
"
,
\
inet_ntoa
(
client_addr
.
sin_addr
),
client_addr
.
sin_port
);
//加入事件循环
struct
ev_io
*
w_client
=
(
struct
ev_io
*
)
malloc
(
sizeof
(
struct
ev_io
));
if
(
w_client
==
NULL
){
printf
(
"malloc w_client failed
\r\n
"
);
return
;
}
w_client
->
data
=
get_channel_by_ip
(
inet_ntoa
(
client_addr
.
sin_addr
));
ev_io_init
(
w_client
,
read_cb
,
sock
,
EV_READ
);
ev_io_start
(
loop
,
w_client
);
}
/*int run()
{
int sd;
struct ev_io w_accept;
g_loop = ev_loop_new(EVBACKEND_EPOLL);
if (NULL == g_loop) {
printf("loop create failed\r\n");
return -1;
}
if (server_socket_init(&sd, NULL, CCU_TCP_PORT) < 0) {
printf("server init failed\r\n");
return -1;
}
ev_io_init(&w_accept, accept_cb, sd, EV_READ);
ev_io_start(g_loop, &w_accept);
ev_run(g_loop, 0);
return 0;
}*/
static
void
loop_tcp_thread
(
void
*
arg
){
printf
(
"loop_tcp_thread start!
\r\n
"
);
int
sd
;
g_loop
=
ev_loop_new
(
EVBACKEND_EPOLL
);
if
(
NULL
==
g_loop
)
{
printf
(
"loop create failed
\r\n
"
);
return
-
1
;
}
if
(
server_socket_init
(
&
sd
,
NULL
,
CCU_TCP_PORT
)
<
0
)
{
printf
(
"server init failed
\r\n
"
);
return
-
1
;
}
ev_io_init
(
&
w_accept
,
accept_cb
,
sd
,
EV_READ
);
ev_io_start
(
g_loop
,
&
w_accept
);
ev_run
(
g_loop
,
0
);
close
(
sd
);
printf
(
"loop_tcp_thread================== end
\n
"
);
}
int
kk_tcp_channel_ser_send
(
char
*
data
,
int
len
,
char
chalMark
[
DEVICE_CODE_LEN
]){
int
ret
=
0
;
if
(
data
!=
NULL
){
int
sd
=
get_sock_by_deviceCode
(
chalMark
);
if
(
sd
>
-
1
){
ret
=
write
(
sd
,
data
,
len
);
if
(
ret
<
0
){
printf
(
"[%s] write failed!!!!
\n
"
,
__FUNCTION__
);
}
}
}
}
int
kk_TCP_channel_init
(
ipc_cb
cb
)
{
int
i
=
0
;
int
sd
;
if
(
g_init
==
1
){
printf
(
"kk_TCP_channel_init has been inited
\n
"
);
return
-
1
;
}
g_init
=
1
;
memset
(
g_tcp_ctrl
,
0
,
sizeof
(
kk_tcp_ctrl_t
)
*
MAX_LISTEN_NUM
);
kk_gw_list_load
();
if
(
g_pTh
==
NULL
&&
0
!=
pthread_create
(
&
g_pTh
,
NULL
,
loop_tcp_thread
,
NULL
))
{
printf
(
"create pthread failed
\r\n
"
);
return
-
1
;
};
g_cb
=
cb
;
return
0
;
}
int
kk_TCP_channel_deinit
(
ipc_type
type
)
{
int
i
=
0
;
for
(
i
=
0
;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
g_tcp_ctrl
[
i
].
sock
>
-
1
){
//close(g_tcp_ctrl[i].sock);
}
}
ev_io_stop
(
g_loop
,
&
w_accept
);
ev_break
(
g_loop
,
EVBREAK_ALL
);
pthread_exit
(
g_pTh
);
ev_loop_destroy
(
g_loop
);
g_loop
=
NULL
;
g_pTh
=
NULL
;
g_init
=
0
;
return
0
;
}
void
*
_MutexCreate
(
void
)
{
int
err_num
;
pthread_mutex_t
*
mutex
=
(
pthread_mutex_t
*
)
malloc
(
sizeof
(
pthread_mutex_t
));
if
(
NULL
==
mutex
)
{
return
NULL
;
}
if
(
0
!=
(
err_num
=
pthread_mutex_init
(
mutex
,
NULL
)))
{
printf
(
"create mutex failed"
);
free
(
mutex
);
return
NULL
;
}
return
mutex
;
}
void
_MutexDestroy
(
void
*
mutex
)
{
int
err_num
;
if
(
!
mutex
)
{
printf
(
"mutex want to destroy is NULL!"
);
return
;
}
if
(
0
!=
(
err_num
=
pthread_mutex_destroy
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"destroy mutex failed"
);
}
free
(
mutex
);
}
void
_MutexLock
(
void
*
mutex
)
{
int
err_num
;
if
(
0
!=
(
err_num
=
pthread_mutex_lock
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"lock mutex failed: - '%s' (%d)"
,
strerror
(
err_num
),
err_num
);
}
}
void
_MutexUnlock
(
void
*
mutex
)
{
int
err_num
;
if
(
0
!=
(
err_num
=
pthread_mutex_unlock
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"unlock mutex failed - '%s' (%d)"
,
strerror
(
err_num
),
err_num
);
}
}
//client
/*初始化服务端*/
typedef
struct
{
void
*
mutex
;
int
sd
;
int
isConnect
;
char
ip
[
MAX_IP_LEN
];
int
port
;
ipc_cb
*
cb
;
}
kk_tcp_client_t
;
static
kk_tcp_client_t
g_client_ctrl
=
{
NULL
,
-
1
,
0
,{
0
},
0
,
NULL
};
static
int
_init_client
(){
memset
(
&
g_client_ctrl
,
0
,
sizeof
(
kk_tcp_client_t
));
/* Create Mutex */
g_client_ctrl
.
mutex
=
_MutexCreate
();
if
(
g_client_ctrl
.
mutex
==
NULL
)
{
return
-
1
;
}
g_client_ctrl
.
sd
=
-
1
;
}
static
int
client_socket_init
(
int
*
sd
,
char
*
ipaddr
,
uint16_t
port
)
{
//创建socket
int
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
-
1
==
sock
){
printf
(
"error socket
\n
"
);
goto
err1
;
}
//设置立即释放端口并可以再次使用
int
reuse
=
1
;
if
(
-
1
==
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
reuse
,
sizeof
(
reuse
))){
printf
(
"error setsockopt
\n
"
);
goto
err2
;
}
//设置为非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
)){
printf
(
"================== fcntl
\n
"
);
goto
err2
;
}
struct
sockaddr_in
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
NULL
==
ipaddr
)
{
addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
}
else
{
addr
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddr
);
}
//连接
int
retry
=
0
;
for
(;
retry
<
10
;
retry
++
){
if
(
-
1
!=
connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))){
break
;
}
printf
(
"==================connect retry=%d
\n
"
,
retry
);
sleep
(
1
);
}
if
(
retry
>=
10
){
printf
(
"==================connect failed
\n
"
);
goto
err2
;
}
printf
(
"==================[%s] ok sock=%d
\n
"
,
__FUNCTION__
,
sock
);
*
sd
=
sock
;
return
0
;
err2:
close
(
sock
);
err1:
return
-
1
;
}
static
void
loop_tcp_client_thread
(
void
*
arg
){
printf
(
"loop_tcp_client_thread start!
\r\n
"
);
char
buf
[
1024
]
=
{
0
};
int
ret
=
0
;
while
(
1
){
if
(
-
1
==
client_socket_init
(
&
g_client_ctrl
.
sd
,
g_client_ctrl
.
ip
,
g_client_ctrl
.
port
)){
printf
(
"connect failed
\n
"
);
sleep
(
1
);
continue
;
}
g_client_ctrl
.
isConnect
=
1
;
while
(
g_client_ctrl
.
isConnect
){
_MutexLock
(
g_client_ctrl
.
mutex
);
ret
=
read
(
g_client_ctrl
.
sd
,
buf
,
sizeof
(
buf
));
_MutexUnlock
(
g_client_ctrl
.
mutex
);
if
(
-
1
==
ret
){
//printf("=================read error \n");
//break ;
}
else
if
(
ret
>
0
){
printf
(
"buf = %s
\n
"
,
buf
);
if
(
g_client_ctrl
.
cb
!=
NULL
){
g_client_ctrl
.
cb
(
buf
,
ret
,
""
);
}
}
usleep
(
100000
);
}
printf
(
"network error, try connect again!
\n
"
);
close
(
g_client_ctrl
.
sd
);
}
printf
(
"loop_tcp_client_thread================== end
\n
"
);
}
int
kk_tcp_client_send
(
char
*
data
,
int
len
){
int
ret
=
0
;
int
cnt
=
0
;
if
(
data
!=
NULL
){
while
(
g_client_ctrl
.
sd
==
-
1
&&
cnt
<
5
){
printf
(
"[%s] tcp don't connect, sleep 1s !!!!
\n
"
,
__FUNCTION__
);
sleep
(
1
);
cnt
++
;
}
if
(
g_client_ctrl
.
sd
<
0
){
printf
(
"[%s] The tcp socket created fialid !!!!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
_MutexLock
(
g_client_ctrl
.
mutex
);
ret
=
write
(
g_client_ctrl
.
sd
,
data
,
len
);
_MutexUnlock
(
g_client_ctrl
.
mutex
);
if
(
ret
<
0
){
printf
(
"[%s] write failed ret=%d, reconnect !!!!
\n
"
,
__FUNCTION__
,
ret
);
g_client_ctrl
.
isConnect
=
0
;
ret
=
-
1
;
}
}
return
ret
;
}
int
kk_tcp_client_init
(
char
ip
[
MAX_IP_LEN
],
int
port
,
ipc_cb
cb
)
{
//kk_tcp_client_deinit();
_init_client
();
g_client_ctrl
.
port
=
port
;
memcpy
(
g_client_ctrl
.
ip
,
ip
,
strlen
(
ip
));
if
(
g_pTh
==
NULL
&&
0
!=
pthread_create
(
&
g_pTh
,
NULL
,
loop_tcp_client_thread
,
NULL
))
{
printf
(
"create pthread failed
\r\n
"
);
return
-
1
;
};
g_client_ctrl
.
cb
=
cb
;
}
kk_tcp_client_deinit
(){
if
(
g_client_ctrl
.
sd
>
-
1
){
close
(
g_client_ctrl
.
sd
);
}
_MutexDestroy
(
g_client_ctrl
.
mutex
);
}
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include "com_api.h"
#define CCU_TCP_PORT 16565
#define BUFFER_SIZE 1024
#define MAX_LISTEN_NUM 10
#define MAX_IP_LEN 16
#define DEVICE_CODE_LEN 33
typedef
struct
{
char
deviceCode
[
DEVICE_CODE_LEN
];
char
ip
[
MAX_IP_LEN
];
int
sock
;
int
isConnect
;
}
kk_tcp_ctrl_t
;
static
kk_tcp_ctrl_t
g_tcp_ctrl
[
MAX_LISTEN_NUM
];
static
struct
ev_loop
*
g_loop
=
NULL
;
static
pthread_t
g_pTh
=
NULL
;
static
int
g_init
=
0
;
static
ipc_cb
*
g_cb
=
NULL
;
static
struct
ev_io
w_accept
;
// Save/Load the gateway list
void
kk_gw_list_save
(
void
)
{
FILE
*
fp
;
uint8_t
i
;
uint8_t
j
;
int
len
=
MAX_LISTEN_NUM
*
sizeof
(
kk_tcp_ctrl_t
);
// Save device table
fp
=
fopen
(
"gwlist.txt"
,
"w"
);
fwrite
(
g_tcp_ctrl
,
len
,
1
,
fp
);
fclose
(
fp
);
}
void
kk_gw_list_load
(
void
)
{
uint16_t
i
;
FILE
*
fp
;
int
readLen
=
MAX_LISTEN_NUM
*
sizeof
(
kk_tcp_ctrl_t
);
int
retLen
=
0
;
fp
=
fopen
(
"gwlist.txt"
,
"r"
);
if
(
!
fp
)
{
printf
(
"open gatewaylist.txt failed!
\n
"
);
goto
error1
;
}
char
buf
[
1024
]
=
{
0
};
retLen
=
fread
(
g_tcp_ctrl
,
readLen
,
1
,
fp
);
printf
(
"read gatewaylist.txt retLen= %d, readLen=%d !
\n
"
,
retLen
,
readLen
);
if
(
retLen
!=
readLen
){
printf
(
"read gatewaylist.txt failed!
\n
"
);
}
fclose
(
fp
);
// Set the rest of the device table to null.
error1:
for
(
i
=
0
;
i
<
MAX_LISTEN_NUM
;
i
++
)
{
printf
(
"deviceCode ip sock [%s] [%s] [%d]
\n
"
,
g_tcp_ctrl
[
i
].
deviceCode
,
g_tcp_ctrl
[
i
].
ip
==
NULL
?
""
:
g_tcp_ctrl
[
i
].
ip
,
g_tcp_ctrl
[
i
].
sock
);
g_tcp_ctrl
[
i
].
sock
=
-
1
;
}
}
static
int
get_idx_by_ip
(
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
return
i
;
}
}
return
-
1
;
}
static
int
get_sock_by_deviceCode
(
char
deviceCode
[
DEVICE_CODE_LEN
]){
int
i
=
0
;
if
(
deviceCode
==
NULL
||
strlen
(
deviceCode
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
deviceCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
return
g_tcp_ctrl
[
i
].
sock
;
}
}
return
-
1
;
}
static
kk_tcp_ctrl_t
*
get_channel_by_ip
(
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
NULL
;
}
printf
(
"[%s] ip=%s
\n
"
,
__FUNCTION__
,
ip
);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
ip
,
g_tcp_ctrl
[
i
].
sock
);
return
&
g_tcp_ctrl
[
i
];
}
}
return
NULL
;
}
static
int
set_status_by_ip
(
char
ip
[
MAX_IP_LEN
],
int
status
){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
g_tcp_ctrl
[
i
].
isConnect
=
status
;
return
0
;
}
}
return
-
1
;
}
static
int
reset_by_sock
(
int
sock
){
int
i
=
0
;
if
(
sock
<
0
){
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
sock
==
g_tcp_ctrl
[
i
].
sock
){
g_tcp_ctrl
[
i
].
isConnect
=
0
;
g_tcp_ctrl
[
i
].
isConnect
=
-
1
;
return
0
;
}
}
return
-
1
;
}
static
int
set_sock_by_ip
(
char
ip
[
MAX_IP_LEN
],
int
sock
){
int
i
=
0
;
if
(
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
printf
(
"[%s] ip=%s
\n
"
,
__FUNCTION__
,
ip
);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
ip
,
g_tcp_ctrl
[
i
].
ip
)
==
0
){
g_tcp_ctrl
[
i
].
sock
=
sock
;
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
ip
,
g_tcp_ctrl
[
i
].
sock
);
return
0
;
}
}
return
-
1
;
}
int
kk_is_tcp_channel
(
char
devCode
[
DEVICE_CODE_LEN
]){
int
i
=
0
;
if
(
devCode
==
NULL
||
strlen
(
devCode
)
==
0
){
return
-
1
;
}
//printf("[%s] devCode=%s \n", __FUNCTION__,devCode);
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
devCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
printf
(
"[%s] idx=%d ip=%s sock=%d
\n
"
,
__FUNCTION__
,
i
,
devCode
,
g_tcp_ctrl
[
i
].
sock
);
return
i
;
}
}
return
-
1
;
}
int
kk_set_tcp_channel_by_idx
(
int
idx
,
char
devCode
[
DEVICE_CODE_LEN
],
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
if
(
idx
>=
MAX_LISTEN_NUM
){
printf
(
"kk_set_tcp_channel_by_idx idx[] need less than %d
\n
"
,
idx
,
MAX_LISTEN_NUM
);
return
-
1
;
}
if
(
devCode
==
NULL
||
strlen
(
devCode
)
==
0
||
ip
==
NULL
||
strlen
(
ip
)
==
0
){
return
-
1
;
}
//printf("[%s] devCode=%s \n", __FUNCTION__,devCode);
memcpy
(
g_tcp_ctrl
[
idx
].
deviceCode
,
devCode
,
strlen
(
devCode
));
memcpy
(
g_tcp_ctrl
[
idx
].
ip
,
ip
,
strlen
(
ip
));
return
0
;
}
int
kk_set_tcp_channel
(
char
devCode
[
DEVICE_CODE_LEN
],
char
ip
[
MAX_IP_LEN
]){
int
i
=
0
;
int
isEmptyIdx
=
-
1
;
if
(
devCode
==
NULL
||
strlen
(
devCode
)
==
0
||
ip
==
NULL
||
strlen
(
ip
)
==
0
){
printf
(
"paramenter error
\n
"
);
return
-
1
;
}
for
(;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
strcmp
(
devCode
,
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
){
strncpy
(
g_tcp_ctrl
[
i
].
ip
,
ip
,
strlen
(
ip
));
printf
(
"find and replace it [%d][%s][%s]
\n
"
,
i
,
g_tcp_ctrl
[
i
].
ip
,
devCode
);
//kk_gw_list_save();
break
;
}
if
(
strlen
(
g_tcp_ctrl
[
i
].
deviceCode
)
==
0
&&
isEmptyIdx
==
-
1
){
isEmptyIdx
=
i
;
}
}
if
(
i
<
MAX_LISTEN_NUM
){
return
0
;
}
if
(
isEmptyIdx
!=
-
1
){
strncpy
(
g_tcp_ctrl
[
isEmptyIdx
].
ip
,
ip
,
strlen
(
ip
));
strncpy
(
g_tcp_ctrl
[
isEmptyIdx
].
deviceCode
,
devCode
,
strlen
(
devCode
));
printf
(
"idx deviceCode ip[%d][%s][%s]"
,
isEmptyIdx
,
g_tcp_ctrl
[
isEmptyIdx
].
deviceCode
,
g_tcp_ctrl
[
isEmptyIdx
].
ip
);
//kk_gw_list_save();
return
0
;
}
return
-
1
;
}
/*初始化服务端*/
static
int
server_socket_init
(
int
*
sd
,
char
*
ipaddr
,
uint16_t
port
)
{
//创建socket
int
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
-
1
==
sock
){
printf
(
"error socket
\n
"
);
goto
err1
;
}
//设置立即释放端口并可以再次使用
int
reuse
=
1
;
if
(
-
1
==
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
reuse
,
sizeof
(
reuse
))){
printf
(
"error setsockopt
\n
"
);
goto
err2
;
}
//设置为非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
)){
printf
(
"================== fcntl
\n
"
);
goto
err2
;
}
struct
sockaddr_in
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
NULL
==
ipaddr
)
{
addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
}
else
{
addr
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddr
);
}
//绑定监听
if
(
-
1
==
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))){
printf
(
"error bind
\n
"
);
goto
err2
;
}
if
(
-
1
==
listen
(
sock
,
MAX_LISTEN_NUM
)){
printf
(
"error listen
\n
"
);
goto
err2
;
}
*
sd
=
sock
;
return
0
;
err2:
close
(
sock
);
err1:
return
-
1
;
}
/*读回调*/
static
void
read_cb
(
struct
ev_loop
*
loop
,
struct
ev_io
*
watcher
,
int
revents
)
{
printf
(
"================== read_cb
\n
"
);
char
buffer
[
BUFFER_SIZE
]
=
{
0
};
if
(
EV_ERROR
&
revents
)
{
printf
(
"read got invalid event...
\r\n
"
);
return
;
}
int
res
=
0
;
kk_tcp_ctrl_t
*
tcp_ctrl
=
(
kk_tcp_ctrl_t
*
)
watcher
->
data
;
int32_t
bytes
=
read
(
watcher
->
fd
,
buffer
,
sizeof
(
buffer
));
if
(
-
1
==
bytes
)
{
//tcp Error
if
(
EINTR
!=
errno
&&
EAGAIN
!=
errno
)
{
res
=
1
;
}
}
else
if
(
0
==
bytes
)
{
//tcp Close
res
=
2
;
}
if
(
0
!=
res
)
{
//关闭事件循环并释放watcher
printf
(
"TCP CLOSE
\r\n
"
);
reset_by_sock
(
watcher
->
fd
);
ev_io_stop
(
loop
,
watcher
);
free
(
watcher
);
}
else
{
//intf("READ:\r\n %s\r\n", buffer);
printf
(
"read_cb deviceCode ip sock [%s][%s][%d]"
,
tcp_ctrl
->
deviceCode
,
tcp_ctrl
->
ip
,
tcp_ctrl
->
sock
);
if
(
g_cb
!=
NULL
){
g_cb
(
buffer
,
bytes
,
tcp_ctrl
->
deviceCode
);
}
}
}
/*accept回调函数*/
static
void
accept_cb
(
struct
ev_loop
*
loop
,
struct
ev_io
*
watcher
,
int
revents
)
{
printf
(
"================== accept_cb
\n
"
);
struct
sockaddr_in
client_addr
;
socklen_t
client_len
=
sizeof
(
client_addr
);
if
(
EV_ERROR
&
revents
)
{
printf
(
"accept got invalid event...
\r\n
"
);
return
;
}
//accept连接
int
sock
=
accept
(
watcher
->
fd
,
(
struct
sockaddr
*
)
&
client_addr
,
&
client_len
);
if
(
-
1
==
sock
)
{
return
;
}
//设置非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
))
{
close
(
sock
);
return
;
}
if
(
set_sock_by_ip
(
inet_ntoa
(
client_addr
.
sin_addr
),
sock
)
<
0
){
//ip无效,reject it
printf
(
"This ip[%s][%u] is invaild, reject it!
\r\n
"
,
inet_ntoa
(
client_addr
.
sin_addr
),
client_addr
.
sin_port
);
close
(
sock
);
return
;
}
printf
(
"Successfully connected with client: %s:%u
\r\n
"
,
\
inet_ntoa
(
client_addr
.
sin_addr
),
client_addr
.
sin_port
);
//加入事件循环
struct
ev_io
*
w_client
=
(
struct
ev_io
*
)
malloc
(
sizeof
(
struct
ev_io
));
if
(
w_client
==
NULL
){
printf
(
"malloc w_client failed
\r\n
"
);
return
;
}
w_client
->
data
=
get_channel_by_ip
(
inet_ntoa
(
client_addr
.
sin_addr
));
ev_io_init
(
w_client
,
read_cb
,
sock
,
EV_READ
);
ev_io_start
(
loop
,
w_client
);
}
/*int run()
{
int sd;
struct ev_io w_accept;
g_loop = ev_loop_new(EVBACKEND_EPOLL);
if (NULL == g_loop) {
printf("loop create failed\r\n");
return -1;
}
if (server_socket_init(&sd, NULL, CCU_TCP_PORT) < 0) {
printf("server init failed\r\n");
return -1;
}
ev_io_init(&w_accept, accept_cb, sd, EV_READ);
ev_io_start(g_loop, &w_accept);
ev_run(g_loop, 0);
return 0;
}*/
static
void
loop_tcp_thread
(
void
*
arg
){
printf
(
"loop_tcp_thread start!
\r\n
"
);
int
sd
;
g_loop
=
ev_loop_new
(
EVBACKEND_EPOLL
);
if
(
NULL
==
g_loop
)
{
printf
(
"loop create failed
\r\n
"
);
return
-
1
;
}
if
(
server_socket_init
(
&
sd
,
NULL
,
CCU_TCP_PORT
)
<
0
)
{
printf
(
"server init failed
\r\n
"
);
return
-
1
;
}
ev_io_init
(
&
w_accept
,
accept_cb
,
sd
,
EV_READ
);
ev_io_start
(
g_loop
,
&
w_accept
);
ev_run
(
g_loop
,
0
);
close
(
sd
);
printf
(
"loop_tcp_thread================== end
\n
"
);
}
int
kk_tcp_channel_ser_send
(
char
*
data
,
int
len
,
char
chalMark
[
DEVICE_CODE_LEN
]){
int
ret
=
0
;
if
(
data
!=
NULL
){
int
sd
=
get_sock_by_deviceCode
(
chalMark
);
if
(
sd
>
-
1
){
ret
=
write
(
sd
,
data
,
len
);
if
(
ret
<
0
){
printf
(
"[%s] write failed!!!!
\n
"
,
__FUNCTION__
);
}
}
}
}
int
kk_TCP_channel_init
(
ipc_cb
cb
)
{
int
i
=
0
;
int
sd
;
if
(
g_init
==
1
){
printf
(
"kk_TCP_channel_init has been inited
\n
"
);
return
-
1
;
}
g_init
=
1
;
//memset(g_tcp_ctrl, 0, sizeof(kk_tcp_ctrl_t)*MAX_LISTEN_NUM);
//kk_gw_list_load();
for
(
i
=
0
;
i
<
MAX_LISTEN_NUM
;
i
++
){
g_tcp_ctrl
[
i
].
sock
=
-
1
;
}
if
(
g_pTh
==
NULL
&&
0
!=
pthread_create
(
&
g_pTh
,
NULL
,
loop_tcp_thread
,
NULL
))
{
printf
(
"create pthread failed
\r\n
"
);
return
-
1
;
};
g_cb
=
cb
;
return
0
;
}
int
kk_TCP_channel_deinit
(
ipc_type
type
)
{
int
i
=
0
;
for
(
i
=
0
;
i
<
MAX_LISTEN_NUM
;
i
++
){
if
(
g_tcp_ctrl
[
i
].
sock
>
-
1
){
//close(g_tcp_ctrl[i].sock);
}
}
ev_io_stop
(
g_loop
,
&
w_accept
);
ev_break
(
g_loop
,
EVBREAK_ALL
);
pthread_exit
(
g_pTh
);
ev_loop_destroy
(
g_loop
);
g_loop
=
NULL
;
g_pTh
=
NULL
;
g_init
=
0
;
return
0
;
}
void
*
_MutexCreate
(
void
)
{
int
err_num
;
pthread_mutex_t
*
mutex
=
(
pthread_mutex_t
*
)
malloc
(
sizeof
(
pthread_mutex_t
));
if
(
NULL
==
mutex
)
{
return
NULL
;
}
if
(
0
!=
(
err_num
=
pthread_mutex_init
(
mutex
,
NULL
)))
{
printf
(
"create mutex failed"
);
free
(
mutex
);
return
NULL
;
}
return
mutex
;
}
void
_MutexDestroy
(
void
*
mutex
)
{
int
err_num
;
if
(
!
mutex
)
{
printf
(
"mutex want to destroy is NULL!"
);
return
;
}
if
(
0
!=
(
err_num
=
pthread_mutex_destroy
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"destroy mutex failed"
);
}
free
(
mutex
);
}
void
_MutexLock
(
void
*
mutex
)
{
int
err_num
;
if
(
0
!=
(
err_num
=
pthread_mutex_lock
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"lock mutex failed: - '%s' (%d)"
,
strerror
(
err_num
),
err_num
);
}
}
void
_MutexUnlock
(
void
*
mutex
)
{
int
err_num
;
if
(
0
!=
(
err_num
=
pthread_mutex_unlock
((
pthread_mutex_t
*
)
mutex
)))
{
printf
(
"unlock mutex failed - '%s' (%d)"
,
strerror
(
err_num
),
err_num
);
}
}
//client
/*初始化服务端*/
typedef
struct
{
void
*
mutex
;
int
sd
;
int
isConnect
;
char
ip
[
MAX_IP_LEN
];
int
port
;
ipc_cb
*
cb
;
}
kk_tcp_client_t
;
static
kk_tcp_client_t
g_client_ctrl
=
{
NULL
,
-
1
,
0
,{
0
},
0
,
NULL
};
static
int
_init_client
(){
memset
(
&
g_client_ctrl
,
0
,
sizeof
(
kk_tcp_client_t
));
/* Create Mutex */
g_client_ctrl
.
mutex
=
_MutexCreate
();
if
(
g_client_ctrl
.
mutex
==
NULL
)
{
return
-
1
;
}
g_client_ctrl
.
sd
=
-
1
;
}
static
int
client_socket_init
(
int
*
sd
,
char
*
ipaddr
,
uint16_t
port
)
{
//创建socket
int
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
-
1
==
sock
){
printf
(
"error socket
\n
"
);
goto
err1
;
}
//设置立即释放端口并可以再次使用
int
reuse
=
1
;
if
(
-
1
==
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
reuse
,
sizeof
(
reuse
))){
printf
(
"error setsockopt
\n
"
);
goto
err2
;
}
//设置为非阻塞
if
(
-
1
==
fcntl
(
sock
,
F_SETFL
,
fcntl
(
sock
,
F_GETFL
)
|
O_NONBLOCK
)){
printf
(
"================== fcntl
\n
"
);
goto
err2
;
}
struct
sockaddr_in
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
NULL
==
ipaddr
)
{
addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
}
else
{
addr
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddr
);
}
//连接
int
retry
=
0
;
for
(;
retry
<
10
;
retry
++
){
if
(
-
1
!=
connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))){
break
;
}
printf
(
"==================connect retry=%d
\n
"
,
retry
);
sleep
(
1
);
}
if
(
retry
>=
10
){
printf
(
"==================connect failed
\n
"
);
goto
err2
;
}
printf
(
"==================[%s] ok sock=%d
\n
"
,
__FUNCTION__
,
sock
);
*
sd
=
sock
;
return
0
;
err2:
close
(
sock
);
err1:
return
-
1
;
}
static
void
loop_tcp_client_thread
(
void
*
arg
){
printf
(
"loop_tcp_client_thread start!
\r\n
"
);
char
buf
[
1024
]
=
{
0
};
int
ret
=
0
;
while
(
1
){
if
(
-
1
==
client_socket_init
(
&
g_client_ctrl
.
sd
,
g_client_ctrl
.
ip
,
g_client_ctrl
.
port
)){
printf
(
"connect failed
\n
"
);
sleep
(
1
);
continue
;
}
g_client_ctrl
.
isConnect
=
1
;
while
(
g_client_ctrl
.
isConnect
){
_MutexLock
(
g_client_ctrl
.
mutex
);
ret
=
read
(
g_client_ctrl
.
sd
,
buf
,
sizeof
(
buf
));
_MutexUnlock
(
g_client_ctrl
.
mutex
);
if
(
-
1
==
ret
){
//printf("=================read error \n");
//break ;
}
else
if
(
ret
>
0
){
printf
(
"buf = %s
\n
"
,
buf
);
if
(
g_client_ctrl
.
cb
!=
NULL
){
g_client_ctrl
.
cb
(
buf
,
ret
,
""
);
}
}
usleep
(
100000
);
}
printf
(
"network error, try connect again!
\n
"
);
close
(
g_client_ctrl
.
sd
);
}
printf
(
"loop_tcp_client_thread================== end
\n
"
);
}
int
kk_tcp_client_send
(
char
*
data
,
int
len
){
int
ret
=
0
;
int
cnt
=
0
;
if
(
data
!=
NULL
){
while
(
g_client_ctrl
.
sd
==
-
1
&&
cnt
<
5
){
printf
(
"[%s] tcp don't connect, sleep 1s !!!!
\n
"
,
__FUNCTION__
);
sleep
(
1
);
cnt
++
;
}
if
(
g_client_ctrl
.
sd
<
0
){
printf
(
"[%s] The tcp socket created fialid !!!!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
_MutexLock
(
g_client_ctrl
.
mutex
);
ret
=
write
(
g_client_ctrl
.
sd
,
data
,
len
);
_MutexUnlock
(
g_client_ctrl
.
mutex
);
if
(
ret
<
0
){
printf
(
"[%s] write failed ret=%d, reconnect !!!!
\n
"
,
__FUNCTION__
,
ret
);
g_client_ctrl
.
isConnect
=
0
;
ret
=
-
1
;
}
}
return
ret
;
}
int
kk_tcp_client_init
(
char
ip
[
MAX_IP_LEN
],
int
port
,
ipc_cb
cb
)
{
//kk_tcp_client_deinit();
_init_client
();
g_client_ctrl
.
port
=
port
;
memcpy
(
g_client_ctrl
.
ip
,
ip
,
strlen
(
ip
));
if
(
g_pTh
==
NULL
&&
0
!=
pthread_create
(
&
g_pTh
,
NULL
,
loop_tcp_client_thread
,
NULL
))
{
printf
(
"create pthread failed
\r\n
"
);
return
-
1
;
};
g_client_ctrl
.
cb
=
cb
;
}
kk_tcp_client_deinit
(){
if
(
g_client_ctrl
.
sd
>
-
1
){
close
(
g_client_ctrl
.
sd
);
}
_MutexDestroy
(
g_client_ctrl
.
mutex
);
}
midware/midware/dm/kk_property_db.c
View file @
d6ef290b
...
...
@@ -3,6 +3,7 @@
#include "sqlite3.h"
#include "kk_log.h"
#include "kk_dm_mng.h"
#include "kk_property_db.h"
#define KK_PROPERTIES_DB_FILE "kk_properties.db"
...
...
@@ -185,6 +186,93 @@ int kk_property_db_update_value(const char *deviceCode,const char *identifier,co
return
SUCCESS_RETURN
;
}
int
kk_property_db_get_value
(
const
char
*
deviceCode
,
const
char
*
identifier
,
void
*
value
)
{
char
*
sqlCmd
=
NULL
;
int
rc
=
0
;
char
*
zErrMsg
=
0
;
sqlite3_stmt
*
stmt
;
char
*
valueStr
=
NULL
;
int
valueType
=
0
;
kk_property_db_ctx_t
*
ctx
=
_kk_property_db_get_ctx
();
_kk_property_db_lock
();
sqlCmd
=
sqlite3_mprintf
(
"select * from PropertiesInfo WHERE deviceCode= '%s' and identifier = '%s'"
,
deviceCode
,
identifier
);
DEBUG_PRINT
(
"kk_property_db_get_value sqlCmd:%s
\n
"
,
sqlCmd
);
sqlite3_prepare_v2
(
ctx
->
pDb
,
sqlCmd
,
strlen
(
sqlCmd
),
&
stmt
,
NULL
);
while
(
sqlite3_step
(
stmt
)
==
SQLITE_ROW
){
valueStr
=
sqlite3_column_text
(
stmt
,
DB_VALUE
);
valueType
=
sqlite3_column_int
(
stmt
,
DB_VALUETYPE
);
if
(
valueType
==
KK_TSL_DATA_TYPE_INT
||
valueType
==
KK_TSL_DATA_TYPE_ENUM
||
valueType
==
KK_TSL_DATA_TYPE_BOOL
){
int
value_int
=
atoi
(
valueStr
);
*
(
int
*
)
value
=
value_int
;
}
else
if
(
valueType
==
KK_TSL_DATA_TYPE_FLOAT
){
float
value_float
=
atoi
(
valueStr
);
*
(
float
*
)
value
=
value_float
;
}
else
if
(
valueType
==
KK_TSL_DATA_TYPE_DOUBLE
){
double
value_double
=
atoi
(
valueStr
);
*
(
double
*
)
value
=
value_double
;
}
else
{
memcpy
(
value
,
valueStr
,
strlen
(
valueStr
));
}
}
sqlite3_free
(
sqlCmd
);
_kk_property_db_unlock
();
sqlite3_finalize
(
stmt
);
return
SUCCESS_RETURN
;
}
int
kk_property_db_get_rawdata
(
const
char
*
identifier
,
const
int
dev_type
,
kk_prop_raw_struct_t
*
raw
,
int
count
)
{
char
*
sqlCmd
=
NULL
;
int
rc
=
0
;
char
*
zErrMsg
=
0
;
sqlite3_stmt
*
stmt
;
char
*
valueStr
=
NULL
;
char
*
devcode
=
NULL
;
int
valueType
=
0
;
int
idx
=
0
;
kk_prop_raw_struct_t
*
curData
=
NULL
;
kk_property_db_ctx_t
*
ctx
=
_kk_property_db_get_ctx
();
_kk_property_db_lock
();
sqlCmd
=
sqlite3_mprintf
(
"select * from PropertiesInfo WHERE devType= '%d' and identifier = '%s'"
,
dev_type
,
identifier
);
DEBUG_PRINT
(
"kk_property_db_get_gw_value sqlCmd:%s
\n
"
,
sqlCmd
);
sqlite3_prepare_v2
(
ctx
->
pDb
,
sqlCmd
,
strlen
(
sqlCmd
),
&
stmt
,
NULL
);
curData
=
raw
;
while
(
sqlite3_step
(
stmt
)
==
SQLITE_ROW
&&
idx
<
count
){
devcode
=
sqlite3_column_text
(
stmt
,
DB_DEVICECODE
);
valueStr
=
sqlite3_column_text
(
stmt
,
DB_VALUE
);
valueType
=
sqlite3_column_int
(
stmt
,
DB_VALUETYPE
);
memcpy
(
curData
->
deviceCode
,
devcode
,
strlen
(
devcode
));
memcpy
(
curData
->
raw
,
valueStr
,
strlen
(
valueStr
));
curData
->
type
=
valueType
;
curData
++
;
idx
++
;
}
sqlite3_free
(
sqlCmd
);
_kk_property_db_unlock
();
sqlite3_finalize
(
stmt
);
return
SUCCESS_RETURN
;
}
int
kk_property_db_update
(
const
char
*
deviceCode
)
{
int
res
=
0
;
...
...
@@ -285,6 +373,7 @@ int kk_property_sync_values(const char *deviceCode)
}
sqlite3_free
(
sqlCmd
);
_kk_property_db_unlock
();
sqlite3_finalize
(
stmt
);
...
...
midware/midware/dm/kk_property_db.h
View file @
d6ef290b
#ifndef _KK_PROPERTY_DB_H_
#define _KK_PROPERTY_DB_H_
#include "kk_tsl_common.h"
int
kk_property_db_init
(
void
);
#endif
#ifndef _KK_PROPERTY_DB_H_
#define _KK_PROPERTY_DB_H_
#include "kk_tsl_common.h"
typedef
struct
{
int
type
;
char
deviceCode
[
DEVICE_CODE_MAXLEN
];
char
raw
[
60
];
}
kk_prop_raw_struct_t
;
int
kk_property_db_init
(
void
);
#endif
midware/midware/midware.c
View file @
d6ef290b
#include<stdio.h>
#include"com_api.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include "cJSON.h"
#include "kk_product.h"
#include "kk_tsl_common.h"
#include "kk_tsl_api.h"
#include "kk_dm_api.h"
#include "kk_dm_msg.h"
#include "kk_dm_mng.h"
#include "kk_log.h"
#include "kk_dm_queue.h"
char
*
g_filerToPlatTable
[]
=
{
{
KK_REGISTER_TOPIC_REPLY
},
{
KK_ADD_TOPIC_REPLY
},
{
KK_LOGIN_TOPIC_REPLY
},
{
KK_THING_OTA_DEVICE_UPGRADE
},
{
KK_THING_CLOUDSTATE_MSG
},
};
static
int
_kk_filter_to_plat
(
const
char
*
msgtype
)
{
int
i
=
0
,
num
=
0
;
num
=
sizeof
(
g_filerToPlatTable
)
/
sizeof
(
char
*
);
for
(
i
=
0
;
i
<
num
;
i
++
){
if
(
strstr
(
msgtype
,
g_filerToPlatTable
[
i
]))
{
return
1
;
}
}
return
0
;
}
void
kk_sendData2gw
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
chalMark
==
NULL
||
strlen
(
chalMark
)
==
0
){
ERROR_PRINT
(
" chalMark is null"
);
return
;
}
if
(
kk_is_tcp_channel
(
chalMark
)
>
-
1
){
kk_tcp_channel_ser_send
(
data
,
len
,
chalMark
);
}
else
{
kk_ipc_send_ex
(
IPC_MID2PLAT
,
data
,
len
,
chalMark
);
}
}
void
mid_cb
(
void
*
data
,
int
len
){
if
(
data
!=
NULL
){
char
*
out
;
cJSON
*
json
;
cJSON
*
info_root
,
*
info
,
*
type
;
cJSON
*
payload
;
cJSON
*
deviceCode
;
int
res
;
void
*
buf
=
malloc
(
len
);
memcpy
(
buf
,
data
,
len
);
res
=
dm_queue_msg_insert
((
void
*
)
buf
);
if
(
res
!=
SUCCESS_RETURN
)
{
free
(
buf
);
//return FAIL_RETURN;
}
json
=
cJSON_Parse
(
data
);
if
(
!
json
)
{
printf
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
info_root
=
cJSON_GetObjectItem
(
json
,
MSG_INFO_STR
);
deviceCode
=
cJSON_GetObjectItem
(
info_root
,
MSG_DEVICE_CODE_STR
);
type
=
cJSON_GetObjectItem
(
info_root
,
MSG_TYPE_STR
);
if
(
_kk_filter_to_plat
(
type
->
valuestring
)){
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
return
;
}
int
devType
=
0
;
dm_mgr_get_devicetype_by_devicecode
(
deviceCode
->
valuestring
,
&
devType
);
if
(
devType
==
KK_DM_DEVICE_GATEWAY
){
kk_sendData2gw
(
data
,
strlen
(
data
),
deviceCode
->
valuestring
);
//send to gw itself
}
else
if
(
devType
==
KK_DM_DEVICE_SUBDEV
){
dm_mgr_dev_node_t
*
gw_node
=
NULL
;
res
=
dm_mgr_get_device_by_devicecode
(
deviceCode
->
valuestring
,
&
gw_node
);
if
(
res
!=
SUCCESS_RETURN
)
{
ERROR_PRINT
(
"res:%d
\n
"
,
res
);
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
return
;
}
kk_sendData2gw
(
data
,
strlen
(
data
),
gw_node
->
fatherDeviceCode
);
//send to sub device
}
else
{
ERROR_PRINT
(
"wrong type
\n
"
);
}
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
}
}
}
void
mid2p_cb
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
data
!=
NULL
){
//printf("mid2plat_cb: %s RECEIVED \r\n", data);
int
res
=
0
;
void
*
buf
=
NULL
;
dm_queue_msg_t
*
queue_msg
=
NULL
;
queue_msg
=
malloc
(
sizeof
(
dm_queue_msg_t
));
if
(
queue_msg
==
NULL
){
ERROR_PRINT
(
"mid2p_cb malloc queue_msg failed "
);
return
;
}
buf
=
malloc
(
len
);
if
(
buf
==
NULL
){
ERROR_PRINT
(
"mid2p_cb malloc buf failed "
);
return
;
}
memcpy
(
buf
,
data
,
len
);
queue_msg
->
data
=
buf
;
memset
(
queue_msg
->
chalMark
,
0
,
sizeof
(
queue_msg
->
chalMark
));
if
(
chalMark
!=
NULL
){
memcpy
(
queue_msg
->
chalMark
,
chalMark
,
sizeof
(
chalMark
));
}
res
=
dm_queue_msg_insert2
((
void
*
)
queue_msg
);
if
(
res
!=
SUCCESS_RETURN
)
{
free
(
queue_msg
);
free
(
buf
);
return
;
}
//kk_ipc_send(IPC_MID2APP, data, len);
}
}
void
gw2mid_cb
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
data
!=
NULL
){
printf
(
"gw2mid_cb chalMark=%s, data: %s RECEIVED
\r\n
"
,
chalMark
,
data
);
mid2p_cb
(
data
,
len
,
chalMark
);
}
}
void
kk_platMsg_handle
(
void
*
data
,
char
*
chalMark
){
char
*
out
;
int
res
=
0
;
cJSON
*
json
;
cJSON
*
info
;
cJSON
*
info_dcode
;
cJSON
*
params
;
cJSON
*
jsonPay
;
cJSON
*
msgType
;
cJSON
*
proCode
;
cJSON
*
devCode
;
cJSON
*
mac
;
cJSON
*
payload
;
json
=
cJSON_Parse
(
data
);
if
(
!
json
)
{
WARNING_PRINT
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
info
=
cJSON_GetObjectItem
(
json
,
"info"
);
payload
=
cJSON_GetObjectItem
(
json
,
"payload"
);
if
(
info
==
NULL
||
payload
==
NULL
){
ERROR_PRINT
(
"info or payload params is error
\n
"
);
goto
error
;
}
msgType
=
cJSON_GetObjectItem
(
info
,
"msgType"
);
info_dcode
=
cJSON_GetObjectItem
(
info
,
"deviceCode"
);
jsonPay
=
cJSON_GetObjectItem
(
payload
,
"params"
);
if
(
msgType
==
NULL
||
info_dcode
==
NULL
||
jsonPay
==
NULL
){
ERROR_PRINT
(
"msgType info_dcode or jsonPay params are error
\n
"
);
goto
error
;
}
dm_mgr_update_timestamp_by_devicecode
(
info_dcode
->
valuestring
,
HAL_UptimeMs
());
if
(
strcmp
(
msgType
->
valuestring
,
"/thing/topo/add"
)
==
0
){
proCode
=
cJSON_GetObjectItem
(
jsonPay
,
"productCode"
);
devCode
=
cJSON_GetObjectItem
(
jsonPay
,
"deviceCode"
);
mac
=
cJSON_GetObjectItem
(
jsonPay
,
"mac"
);
if
(
proCode
==
NULL
||
devCode
==
NULL
||
mac
==
NULL
){
ERROR_PRINT
(
"productCode, deviceCode mac params are error
\n
"
);
goto
error
;
}
INFO_PRINT
(
"deviceCode productCode mac: [%s][%s] [%s]
\n
"
,
devCode
->
valuestring
,
proCode
->
valuestring
,
mac
->
valuestring
);
//判断网关还是子设备
if
(
strcmp
(
info_dcode
->
valuestring
,
devCode
->
valuestring
)
==
0
){
char
ccu_deviceCode
[
DEVICE_CODE_MAXLEN
]
=
{
0
};
HAL_GetDevice_Code
(
ccu_deviceCode
);
kk_mid_subdev_add
(
KK_DM_DEVICE_GATEWAY
,
proCode
->
valuestring
,
devCode
->
valuestring
,
mac
->
valuestring
,
ccu_deviceCode
);
}
else
{
kk_mid_subdev_add
(
KK_DM_DEVICE_SUBDEV
,
proCode
->
valuestring
,
devCode
->
valuestring
,
mac
->
valuestring
,
info_dcode
->
valuestring
);
}
}
else
if
(
strstr
(
msgType
->
valuestring
,
"property/post"
)
!=
NULL
){
INFO_PRINT
(
"save property and send to cloud
\n
"
);
char
*
outstr
=
cJSON_Print
(
payload
);
kk_tsl_property_set_by_devicecode
(
info_dcode
->
valuestring
,
outstr
,
strlen
(
outstr
)
+
1
);
kk_property_db_update
(
info_dcode
->
valuestring
);
free
(
outstr
);
}
else
if
(
strstr
(
msgType
->
valuestring
,
"/thing/topo/delete"
)
!=
NULL
){
INFO_PRINT
(
"kk_platMsg_handle data: handle delete
\n
"
);
devCode
=
cJSON_GetObjectItem
(
jsonPay
,
"deviceCode"
);
kk_ipc_send
(
IPC_MID2APP
,
data
,
strlen
(
data
));
dm_mgr_subdev_delete
(
devCode
->
valuestring
);
}
else
{
INFO_PRINT
(
"kk_platMsg_handle data: don't handle it [%s]
\n
"
,
data
);
//kk_tsl_service_property_set(topic->valuestring, payload->valuestring, strlen(payload->valuestring), NULL);
}
error:
cJSON_Delete
(
json
);
}
}
void
kk_platMsg_dispatch
(
void
)
{
int
count
=
0
;
void
*
data
=
NULL
;
while
(
CONFIG_DISPATCH_QUEUE_MAXLEN
==
0
||
count
++
<
CONFIG_DISPATCH_QUEUE_MAXLEN
)
{
if
(
dm_queue_msg_next2
(
&
data
)
==
SUCCESS_RETURN
)
{
dm_queue_msg_t
*
msg
=
(
dm_queue_msg_t
*
)
data
;
INFO_PRINT
(
"kk_handle_platMsg_dispatch get call
\n
"
);
if
(
kk_platMsg_handle
)
{
kk_platMsg_handle
(
msg
->
data
,
msg
->
chalMark
);
}
if
(
msg
->
data
!=
NULL
){
free
(
msg
->
data
);
}
free
(
data
);
data
=
NULL
;
}
else
{
break
;
}
}
}
time_t
getSysTime
(){
time_t
t
;
t
=
time
(
NULL
);
return
t
;
}
typedef
struct
{
int
auto_add_subdev
;
int
master_devid
;
int
cloud_connected
;
int
master_initialized
;
int
subdev_index
;
int
permit_join
;
void
*
g_mid_dispatch_thread
;
void
*
g_ota_dispatch_thread
;
void
*
g_ccuProChg_dispatch_thread
;
void
*
g_udp_dispatch_thread
;
int
g_mid_dispatch_thread_running
;
int
g_ota_dispatch_thread_running
;
int
g_ccuProChg_dispatch_thread_running
;
int
g_udp_dispatch_thread_running
;
}
mid_ctx_t
;
#define MID_YIELD_TIMEOUT_MS (200)
static
mid_ctx_t
g_mid_ctx
;
static
mid_ctx_t
*
kk_mid_get_ctx
(
void
)
{
return
&
g_mid_ctx
;
}
extern
void
IOT_Linkkit_Yield
(
int
timeout_ms
);
void
*
mid_dispatch_yield
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
while
(
mid_ctx
->
g_mid_dispatch_thread_running
)
{
IOT_Linkkit_Yield
(
MID_YIELD_TIMEOUT_MS
);
}
return
NULL
;
}
void
*
ota_dispatch_yield
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
while
(
mid_ctx
->
g_ota_dispatch_thread_running
)
{
dm_ota_yield
(
MID_YIELD_TIMEOUT_MS
);
}
return
NULL
;
}
#define UDP_LAN_PORT 25556
#define UDP_LAN_PORT_HOST 25555
#define test_
void
*
udp_dispatch_yield
(
void
*
args
){
INFO_PRINT
(
"udp_dispatch_yield udp thread create
\n
"
);
// 绑定地址
struct
sockaddr_in
addrto
;
bzero
(
&
addrto
,
sizeof
(
struct
sockaddr_in
));
addrto
.
sin_family
=
AF_INET
;
addrto
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
addrto
.
sin_port
=
htons
(
UDP_LAN_PORT
);
// 发送地址
struct
sockaddr_in
addrto_host
;
bzero
(
&
addrto_host
,
sizeof
(
struct
sockaddr_in
));
addrto_host
.
sin_family
=
AF_INET
;
addrto_host
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
//addrto_host.sin_port = htons(UDP_LAN_PORT);
// 接收到的广播地址
struct
sockaddr_in
from
;
bzero
(
&
from
,
sizeof
(
struct
sockaddr_in
));
int
sock
=
-
1
;
int
sock_host
=
-
1
;
if
((
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
ERROR_PRINT
(
"socket error
\n
"
);
}
if
((
sock_host
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
ERROR_PRINT
(
"socket error
\n
"
);
}
if
(
bind
(
sock
,(
struct
sockaddr
*
)
&
(
addrto
),
sizeof
(
struct
sockaddr_in
))
==
-
1
)
{
ERROR_PRINT
(
"bind error...
\n
"
);
}
socklen_t
len
=
sizeof
(
struct
sockaddr_in
);
cJSON
*
json
=
NULL
;
cJSON
*
info
=
NULL
;
cJSON
*
payload
=
NULL
;
cJSON
*
infoObj
=
NULL
;
cJSON
*
payloadObj
=
NULL
;
cJSON
*
msgtype
=
NULL
;
cJSON
*
proCode
=
NULL
;
cJSON
*
devCode
=
NULL
;
cJSON
*
params
=
NULL
;
cJSON
*
macstr
=
NULL
;
char
szOut
[
128
]
=
{
0
};
char
szDec
[
1024
]
=
{
0
};
char
host_ip
[
32
]
=
{
0
};
char
mac
[
32
]
=
{
0
};
char
device_code
[
DEVICE_CODE_LEN
]
=
{
0
};
int
devId
=
0
;
kk_TCP_channel_init
(
gw2mid_cb
);
while
(
1
)
{
//从广播地址接受消息
memset
(
szDec
,
0
,
sizeof
(
szDec
));
int
size
=
recvfrom
(
sock
,
szDec
,
sizeof
(
szDec
),
0
,
(
struct
sockaddr
*
)
&
from
,(
socklen_t
*
)
&
len
);
if
(
size
<=
0
)
{
WARNING_PRINT
(
"read error....
\n
"
);
}
else
{
DEBUG_PRINT
(
"lan recmsg: %s
\n
"
,
szDec
);
//DEBUG_PRINT("udp client ip:%s ,port is :%d htons(UDP_LAN_PORT)=%d \n",inet_ntoa(from.sin_addr),from.sin_port, htons(UDP_LAN_PORT));
#ifdef test_
//"search_kk_ccu|deviceCode=1122334455667788;protocol=tcp"
if
(
strstr
(
szDec
,
"search_kk_ccu|"
)
!=
NULL
){
char
*
getConnet
=
szDec
+
strlen
(
"search_kk_ccu|"
);
char
*
tmp
=
NULL
;
char
*
endIdx
=
NULL
;
int
itemLen
=
0
;
int
itemConnetLen
=
0
;
char
gwDevCode
[
DEVICE_CODE_LEN
]
=
{
0
};
char
proto
[
10
]
=
{
0
};
tmp
=
strstr
(
getConnet
,
"deviceCode="
);
itemLen
=
strlen
(
"deviceCode="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
gwDevCode
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
getConnet
,
"protocol="
);
itemLen
=
strlen
(
"protocol="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
proto
,
tmp
+
itemLen
,
itemConnetLen
);
}
DEBUG_PRINT
(
"gwDevCode =%s proto=%s
\n
"
,
gwDevCode
,
proto
);
if
(
strcmp
(
proto
,
"tcp"
)
==
0
){
//
kk_set_tcp_channel
(
gwDevCode
,
inet_ntoa
(
from
.
sin_addr
));
}
memset
(
host_ip
,
0
,
sizeof
(
host_ip
));
memset
(
mac
,
0
,
sizeof
(
mac
));
memset
(
szOut
,
0
,
sizeof
(
szOut
));
HAL_Get_IP
(
host_ip
,
"ens33"
);
HAL_GetDevice_Code
(
device_code
);
sprintf
(
szOut
,
"search_kk_ccu_ack|deviceCode=%s;ip=%s;port=%d"
,
device_code
,
host_ip
,
16565
);
DEBUG_PRINT
(
"szOut:%s
\n
"
,
szOut
);
DEBUG_PRINT
(
"udp client ip:%s ,port is :%d
\n
"
,
inet_ntoa
(
from
.
sin_addr
),
from
.
sin_port
);
//sendto(sock, szOut, strlen(szOut), 0, (struct sockaddr*)&from,len);
addrto_host
.
sin_addr
.
s_addr
=
inet_addr
(
inet_ntoa
(
from
.
sin_addr
));
addrto_host
.
sin_port
=
htons
(
UDP_LAN_PORT_HOST
);
//addrto_host.sin_port = from.sin_port;
//if(strcmp(host_ip,inet_ntoa(from.sin_addr)) == 0)
//{
sendto
(
sock_host
,
szOut
,
strlen
(
szOut
),
0
,
(
struct
sockaddr
*
)
&
addrto_host
,
sizeof
(
addrto_host
));
//}
//else
//{
// DEBUG_PRINT("udp client is not local ip , refused send ack to it\n");
//}
}
#else
json
=
cJSON_Parse
(
szDec
);
if
(
!
json
)
{
ERROR_PRINT
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
infoObj
=
cJSON_GetObjectItem
(
json
,
"info"
);
payloadObj
=
cJSON_GetObjectItem
(
json
,
"payload"
);
if
(
infoObj
!=
NULL
&&
payloadObj
!=
NULL
){
msgtype
=
cJSON_GetObjectItem
(
infoObj
,
"msgtype"
);
if
(
msgtype
==
NULL
||
strstr
(
msgtype
->
valuestring
,
"/thing/topo/add"
)
==
NULL
){
ERROR_PRINT
(
"msgtype parameter is error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
proCode
=
cJSON_GetObjectItem
(
infoObj
,
"productCode"
);
devCode
=
cJSON_GetObjectItem
(
infoObj
,
"deviceCode"
);
params
=
cJSON_GetObjectItem
(
payloadObj
,
"params"
);
if
(
proCode
==
NULL
||
devCode
==
NULL
||
params
==
NULL
){
ERROR_PRINT
(
"productType productCode deviceCode params parameters are error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
macstr
=
cJSON_GetObjectItem
(
params
,
"mac"
);
if
(
macstr
==
NULL
){
ERROR_PRINT
(
"mac parameter is error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
INFO_PRINT
(
" productCode deviceCode mac: [%s][%s][%s]
\n
"
,
proCode
->
valuestring
,
devCode
->
valuestring
,
macstr
->
valuestring
);
char
device_code
[
DEVICE_CODE_LEN
]
=
{
0
};
HAL_GetDevice_Code
(
device_code
);
int
res
=
kk_mid_subdev_add
(
KK_DM_DEVICE_GATEWAY
,
proCode
->
valuestring
,
devCode
->
valuestring
,
macstr
->
valuestring
,
device_code
);
if
(
res
!=
SUCCESS_RETURN
)
{
WARNING_PRINT
(
"dm_mgr_gw_create error"
);
}
//kk_ipc_send(IPC_MID2APP, szDec, size);
memset
(
host_ip
,
0
,
sizeof
(
host_ip
));
memset
(
mac
,
0
,
sizeof
(
mac
));
memset
(
szOut
,
0
,
sizeof
(
szOut
));
HAL_Get_IP
(
host_ip
,
"ens33"
);
HAL_Get_mac
(
mac
);
sprintf
(
szOut
,
"/thing/topo/add_reply|mac=%s;ip=%s"
,
mac
,
host_ip
);
DEBUG_PRINT
(
"szOut:%s
\n
"
,
szOut
);
DEBUG_PRINT
(
"udp client ip:%s ,port is :%d
\n
"
,
inet_ntoa
(
from
.
sin_addr
),
from
.
sin_port
);
//sendto(sock, szOut, strlen(szOut), 0, (struct sockaddr*)&from,len);
addrto_host
.
sin_addr
.
s_addr
=
inet_addr
(
inet_ntoa
(
from
.
sin_addr
));
addrto_host
.
sin_port
=
htons
(
UDP_LAN_PORT_HOST
);
//addrto_host.sin_port = from.sin_port;
if
(
strcmp
(
host_ip
,
inet_ntoa
(
from
.
sin_addr
))
==
0
)
{
sendto
(
sock_host
,
szOut
,
strlen
(
szOut
),
0
,
(
struct
sockaddr
*
)
&
addrto_host
,
sizeof
(
addrto_host
));
}
else
{
DEBUG_PRINT
(
"udp client is not local ip , refused send ack to it
\n
"
);
}
}
else
{
INFO_PRINT
(
"error format json: [%s]
\n
"
,
szDec
);
}
cJSON_Delete
(
json
);
}
#endif
}
usleep
(
100000
);
}
close
(
sock
);
close
(
sock_host
);
}
void
*
ccu_property_monitor
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
char
s_IP
[
NETWORK_ADDR_LEN
];
char
*
s_IP_TSL
=
NULL
;
int
res
=
0
;
int
needReport
=
0
;
int
time_second
=
60
;
while
(
mid_ctx
->
g_ccuProChg_dispatch_thread_running
)
{
if
(
kk_get_cloud_recv_status
()
==
0
){
iotx_dm_ccu_cloud_check
();
sleep
(
10
);
continue
;
}
//dm_ota_yield(MID_YIELD_TIMEOUT_MS);
HAL_Get_IP
(
s_IP
,
NULL
);
res
=
kk_tsl_get_value
(
kk_tsl_get_property_value
,
0
,
KK_TSL_CCU_WANIP_IDENTIFIER
,
NULL
,
&
s_IP_TSL
);
if
(
res
!=
SUCCESS_RETURN
){
ERROR_PRINT
(
"kk_tsl_get_value Failed
\n
"
);
}
else
{
if
(
strcmp
(
s_IP
,
s_IP_TSL
)){
kk_tsl_set_value
(
kk_tsl_set_property_value
,
0
,
KK_TSL_CCU_WANIP_IDENTIFIER
,
NULL
,
s_IP
);
INFO_PRINT
(
"current ip:%s,before ip:%s
\n
"
,
s_IP
,
s_IP_TSL
);
kk_property_db_update
(
"CCU_66666"
);
needReport
=
1
;
}
}
if
(
needReport
&&
(
kk_get_cloudstatus
()
==
1
)){
needReport
=
0
;
kk_tsl_post_property
(
0
,
NULL
);
}
sleep
(
time_second
);
}
return
NULL
;
}
static
int
kk_set_product_info
(
void
)
{
HAL_SetProduct_Type
(
PRODUCT_TPYE
);
HAL_SetProduct_Code
(
PRODUCT_CODE
);
return
0
;
}
int
main
(
const
int
argc
,
const
char
**
argv
)
{
int
res
=
0
;
char
*
tsl_str
;
int
i
;
kk_tsl_t
*
dev_shadow
[
30
]
=
{
NULL
};
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
kk_zlog_init
(
"midware"
);
memset
(
mid_ctx
,
0
,
sizeof
(
mid_ctx_t
));
kk_set_product_info
();
kk_tsl_api_init
();
kk_ipc_init
(
IPC_MID2APP
,
mid_cb
,
NULL
,
NULL
);
kk_ipc_init
(
IPC_MID2PLAT
,
mid2p_cb
,
NULL
,
"*"
);
kk_init_dmproc
();
kk_subDb_init
();
kk_heartbeat_init
();
mid_ctx
->
g_mid_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_mid_dispatch_thread
,
NULL
,
mid_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate mid Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
mid_ctx
->
g_ota_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_ota_dispatch_thread
,
NULL
,
ota_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate ota Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
// recv gateway add cmd and ack to gateway
res
=
pthread_create
(
&
mid_ctx
->
g_udp_dispatch_thread
,
NULL
,
udp_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate udp Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
mid_ctx
->
g_ccuProChg_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_ccuProChg_dispatch_thread
,
NULL
,
ccu_property_monitor
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate Failed
\n
"
);
return
-
1
;
}
int
ct
=
0
;
for
(;;)
{
usleep
(
200000
);
kk_platMsg_dispatch
();
/*if (ct == 0){
ct =1;
void* buf = "{\
\"info\": {\
\"msgtype\": \"/thing/topo/add\",\
\"productType\": \"gw\",\
\"productCode\": \"2\",\
\"deviceCode\": \"1122334455667788\"\
},\
\"payload\": {\
\"msgId\": \"1\",\
\"version\": \"1.0\",\
\"params\": {\
\"deviceCode\": \"588E81FFFED3834A\",\
\"productCode\": \"24\",\
\"mac\": \"588E81FFFED3834A\"\
}\
}\
}";
kk_platMsg_handle(buf, "1122334455667788");
//kk_set_tsl_by_productKey("a1OYuSallan","model.json");
//kk_mid_subdev_add("a1OYuSallan","allanWno8yDdsjCX15iq","","aabbccddeeff1122");
}*/
}
}
#include<stdio.h>
#include"com_api.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include "cJSON.h"
#include "kk_product.h"
#include "kk_tsl_common.h"
#include "kk_tsl_api.h"
#include "kk_dm_api.h"
#include "kk_dm_msg.h"
#include "kk_dm_mng.h"
#include "kk_log.h"
#include "kk_dm_queue.h"
#include "kk_property_db.h"
char
*
g_filerToPlatTable
[]
=
{
{
KK_REGISTER_TOPIC_REPLY
},
{
KK_ADD_TOPIC_REPLY
},
{
KK_LOGIN_TOPIC_REPLY
},
{
KK_THING_OTA_DEVICE_UPGRADE
},
{
KK_THING_CLOUDSTATE_MSG
},
};
static
int
_kk_filter_to_plat
(
const
char
*
msgtype
)
{
int
i
=
0
,
num
=
0
;
num
=
sizeof
(
g_filerToPlatTable
)
/
sizeof
(
char
*
);
for
(
i
=
0
;
i
<
num
;
i
++
){
if
(
strstr
(
msgtype
,
g_filerToPlatTable
[
i
]))
{
return
1
;
}
}
return
0
;
}
void
kk_sendData2gw
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
chalMark
==
NULL
||
strlen
(
chalMark
)
==
0
){
ERROR_PRINT
(
" chalMark is null"
);
return
;
}
if
(
kk_is_tcp_channel
(
chalMark
)
>
-
1
){
kk_tcp_channel_ser_send
(
data
,
len
,
chalMark
);
}
else
{
kk_ipc_send_ex
(
IPC_MID2PLAT
,
data
,
len
,
chalMark
);
}
}
void
mid_cb
(
void
*
data
,
int
len
){
if
(
data
!=
NULL
){
char
*
out
;
cJSON
*
json
;
cJSON
*
info_root
,
*
info
,
*
type
;
cJSON
*
payload
;
cJSON
*
deviceCode
;
int
res
;
void
*
buf
=
malloc
(
len
);
memcpy
(
buf
,
data
,
len
);
res
=
dm_queue_msg_insert
((
void
*
)
buf
);
if
(
res
!=
SUCCESS_RETURN
)
{
free
(
buf
);
//return FAIL_RETURN;
}
json
=
cJSON_Parse
(
data
);
if
(
!
json
)
{
printf
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
info_root
=
cJSON_GetObjectItem
(
json
,
MSG_INFO_STR
);
deviceCode
=
cJSON_GetObjectItem
(
info_root
,
MSG_DEVICE_CODE_STR
);
type
=
cJSON_GetObjectItem
(
info_root
,
MSG_TYPE_STR
);
if
(
_kk_filter_to_plat
(
type
->
valuestring
)){
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
return
;
}
int
devType
=
0
;
dm_mgr_get_devicetype_by_devicecode
(
deviceCode
->
valuestring
,
&
devType
);
if
(
devType
==
KK_DM_DEVICE_GATEWAY
){
kk_sendData2gw
(
data
,
strlen
(
data
),
deviceCode
->
valuestring
);
//send to gw itself
}
else
if
(
devType
==
KK_DM_DEVICE_SUBDEV
){
dm_mgr_dev_node_t
*
gw_node
=
NULL
;
res
=
dm_mgr_get_device_by_devicecode
(
deviceCode
->
valuestring
,
&
gw_node
);
if
(
res
!=
SUCCESS_RETURN
)
{
ERROR_PRINT
(
"res:%d
\n
"
,
res
);
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
return
;
}
kk_sendData2gw
(
data
,
strlen
(
data
),
gw_node
->
fatherDeviceCode
);
//send to sub device
}
else
{
ERROR_PRINT
(
"wrong type
\n
"
);
}
cJSON_Delete
(
json
);
cJSON_Delete
(
info
);
}
}
}
void
mid2p_cb
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
data
!=
NULL
){
//printf("mid2plat_cb: %s RECEIVED \r\n", data);
int
res
=
0
;
void
*
buf
=
NULL
;
dm_queue_msg_t
*
queue_msg
=
NULL
;
queue_msg
=
malloc
(
sizeof
(
dm_queue_msg_t
));
if
(
queue_msg
==
NULL
){
ERROR_PRINT
(
"mid2p_cb malloc queue_msg failed "
);
return
;
}
buf
=
malloc
(
len
);
if
(
buf
==
NULL
){
ERROR_PRINT
(
"mid2p_cb malloc buf failed "
);
return
;
}
memcpy
(
buf
,
data
,
len
);
queue_msg
->
data
=
buf
;
memset
(
queue_msg
->
chalMark
,
0
,
sizeof
(
queue_msg
->
chalMark
));
if
(
chalMark
!=
NULL
){
memcpy
(
queue_msg
->
chalMark
,
chalMark
,
sizeof
(
chalMark
));
}
res
=
dm_queue_msg_insert2
((
void
*
)
queue_msg
);
if
(
res
!=
SUCCESS_RETURN
)
{
free
(
queue_msg
);
free
(
buf
);
return
;
}
//kk_ipc_send(IPC_MID2APP, data, len);
}
}
void
gw2mid_cb
(
void
*
data
,
int
len
,
char
*
chalMark
){
if
(
data
!=
NULL
){
printf
(
"gw2mid_cb chalMark=%s, data: %s RECEIVED
\r\n
"
,
chalMark
,
data
);
mid2p_cb
(
data
,
len
,
chalMark
);
}
}
void
kk_platMsg_handle
(
void
*
data
,
char
*
chalMark
){
char
*
out
;
int
res
=
0
;
cJSON
*
json
;
cJSON
*
info
;
cJSON
*
info_dcode
;
cJSON
*
params
;
cJSON
*
jsonPay
;
cJSON
*
msgType
;
cJSON
*
proCode
;
cJSON
*
devCode
;
cJSON
*
mac
;
cJSON
*
payload
;
json
=
cJSON_Parse
(
data
);
if
(
!
json
)
{
WARNING_PRINT
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
info
=
cJSON_GetObjectItem
(
json
,
"info"
);
payload
=
cJSON_GetObjectItem
(
json
,
"payload"
);
if
(
info
==
NULL
||
payload
==
NULL
){
ERROR_PRINT
(
"info or payload params is error
\n
"
);
goto
error
;
}
msgType
=
cJSON_GetObjectItem
(
info
,
"msgType"
);
info_dcode
=
cJSON_GetObjectItem
(
info
,
"deviceCode"
);
jsonPay
=
cJSON_GetObjectItem
(
payload
,
"params"
);
if
(
msgType
==
NULL
||
info_dcode
==
NULL
||
jsonPay
==
NULL
){
ERROR_PRINT
(
"msgType info_dcode or jsonPay params are error
\n
"
);
goto
error
;
}
dm_mgr_update_timestamp_by_devicecode
(
info_dcode
->
valuestring
,
HAL_UptimeMs
());
if
(
strcmp
(
msgType
->
valuestring
,
"/thing/topo/add"
)
==
0
){
proCode
=
cJSON_GetObjectItem
(
jsonPay
,
"productCode"
);
devCode
=
cJSON_GetObjectItem
(
jsonPay
,
"deviceCode"
);
mac
=
cJSON_GetObjectItem
(
jsonPay
,
"mac"
);
if
(
proCode
==
NULL
||
devCode
==
NULL
||
mac
==
NULL
){
ERROR_PRINT
(
"productCode, deviceCode mac params are error
\n
"
);
goto
error
;
}
INFO_PRINT
(
"deviceCode productCode mac: [%s][%s] [%s]
\n
"
,
devCode
->
valuestring
,
proCode
->
valuestring
,
mac
->
valuestring
);
//判断网关还是子设备
if
(
strcmp
(
info_dcode
->
valuestring
,
devCode
->
valuestring
)
==
0
){
char
ccu_deviceCode
[
DEVICE_CODE_MAXLEN
]
=
{
0
};
HAL_GetDevice_Code
(
ccu_deviceCode
);
kk_mid_subdev_add
(
KK_DM_DEVICE_GATEWAY
,
proCode
->
valuestring
,
devCode
->
valuestring
,
mac
->
valuestring
,
ccu_deviceCode
);
}
else
{
kk_mid_subdev_add
(
KK_DM_DEVICE_SUBDEV
,
proCode
->
valuestring
,
devCode
->
valuestring
,
mac
->
valuestring
,
info_dcode
->
valuestring
);
}
}
else
if
(
strstr
(
msgType
->
valuestring
,
"property/post"
)
!=
NULL
){
INFO_PRINT
(
"save property and send to cloud
\n
"
);
char
*
outstr
=
cJSON_Print
(
payload
);
kk_tsl_property_set_by_devicecode
(
info_dcode
->
valuestring
,
outstr
,
strlen
(
outstr
)
+
1
);
kk_property_db_update
(
info_dcode
->
valuestring
);
free
(
outstr
);
}
else
if
(
strstr
(
msgType
->
valuestring
,
"/thing/topo/delete"
)
!=
NULL
){
INFO_PRINT
(
"kk_platMsg_handle data: handle delete
\n
"
);
devCode
=
cJSON_GetObjectItem
(
jsonPay
,
"deviceCode"
);
kk_ipc_send
(
IPC_MID2APP
,
data
,
strlen
(
data
));
dm_mgr_subdev_delete
(
devCode
->
valuestring
);
}
else
{
INFO_PRINT
(
"kk_platMsg_handle data: don't handle it [%s]
\n
"
,
data
);
//kk_tsl_service_property_set(topic->valuestring, payload->valuestring, strlen(payload->valuestring), NULL);
}
error:
cJSON_Delete
(
json
);
}
}
void
kk_platMsg_dispatch
(
void
)
{
int
count
=
0
;
void
*
data
=
NULL
;
while
(
CONFIG_DISPATCH_QUEUE_MAXLEN
==
0
||
count
++
<
CONFIG_DISPATCH_QUEUE_MAXLEN
)
{
if
(
dm_queue_msg_next2
(
&
data
)
==
SUCCESS_RETURN
)
{
dm_queue_msg_t
*
msg
=
(
dm_queue_msg_t
*
)
data
;
INFO_PRINT
(
"kk_handle_platMsg_dispatch get call
\n
"
);
if
(
kk_platMsg_handle
)
{
kk_platMsg_handle
(
msg
->
data
,
msg
->
chalMark
);
}
if
(
msg
->
data
!=
NULL
){
free
(
msg
->
data
);
}
free
(
data
);
data
=
NULL
;
}
else
{
break
;
}
}
}
time_t
getSysTime
(){
time_t
t
;
t
=
time
(
NULL
);
return
t
;
}
typedef
struct
{
int
auto_add_subdev
;
int
master_devid
;
int
cloud_connected
;
int
master_initialized
;
int
subdev_index
;
int
permit_join
;
void
*
g_mid_dispatch_thread
;
void
*
g_ota_dispatch_thread
;
void
*
g_ccuProChg_dispatch_thread
;
void
*
g_udp_dispatch_thread
;
int
g_mid_dispatch_thread_running
;
int
g_ota_dispatch_thread_running
;
int
g_ccuProChg_dispatch_thread_running
;
int
g_udp_dispatch_thread_running
;
}
mid_ctx_t
;
#define MID_YIELD_TIMEOUT_MS (200)
static
mid_ctx_t
g_mid_ctx
;
static
mid_ctx_t
*
kk_mid_get_ctx
(
void
)
{
return
&
g_mid_ctx
;
}
extern
void
IOT_Linkkit_Yield
(
int
timeout_ms
);
void
*
mid_dispatch_yield
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
while
(
mid_ctx
->
g_mid_dispatch_thread_running
)
{
IOT_Linkkit_Yield
(
MID_YIELD_TIMEOUT_MS
);
}
return
NULL
;
}
void
*
ota_dispatch_yield
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
while
(
mid_ctx
->
g_ota_dispatch_thread_running
)
{
dm_ota_yield
(
MID_YIELD_TIMEOUT_MS
);
}
return
NULL
;
}
#define UDP_LAN_PORT 25556
#define UDP_LAN_PORT_HOST 25555
#define test_
void
*
udp_dispatch_yield
(
void
*
args
){
INFO_PRINT
(
"udp_dispatch_yield udp thread create
\n
"
);
// 绑定地址
struct
sockaddr_in
addrto
;
bzero
(
&
addrto
,
sizeof
(
struct
sockaddr_in
));
addrto
.
sin_family
=
AF_INET
;
addrto
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
addrto
.
sin_port
=
htons
(
UDP_LAN_PORT
);
// 发送地址
struct
sockaddr_in
addrto_host
;
bzero
(
&
addrto_host
,
sizeof
(
struct
sockaddr_in
));
addrto_host
.
sin_family
=
AF_INET
;
addrto_host
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
//addrto_host.sin_port = htons(UDP_LAN_PORT);
// 接收到的广播地址
struct
sockaddr_in
from
;
bzero
(
&
from
,
sizeof
(
struct
sockaddr_in
));
int
sock
=
-
1
;
int
sock_host
=
-
1
;
if
((
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
ERROR_PRINT
(
"socket error
\n
"
);
}
if
((
sock_host
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
ERROR_PRINT
(
"socket error
\n
"
);
}
if
(
bind
(
sock
,(
struct
sockaddr
*
)
&
(
addrto
),
sizeof
(
struct
sockaddr_in
))
==
-
1
)
{
ERROR_PRINT
(
"bind error...
\n
"
);
}
socklen_t
len
=
sizeof
(
struct
sockaddr_in
);
cJSON
*
json
=
NULL
;
cJSON
*
info
=
NULL
;
cJSON
*
payload
=
NULL
;
cJSON
*
infoObj
=
NULL
;
cJSON
*
payloadObj
=
NULL
;
cJSON
*
msgtype
=
NULL
;
cJSON
*
proCode
=
NULL
;
cJSON
*
devCode
=
NULL
;
cJSON
*
params
=
NULL
;
cJSON
*
macstr
=
NULL
;
char
szOut
[
128
]
=
{
0
};
char
szDec
[
1024
]
=
{
0
};
char
host_ip
[
32
]
=
{
0
};
char
mac
[
32
]
=
{
0
};
char
device_code
[
DEVICE_CODE_LEN
]
=
{
0
};
int
devId
=
0
;
kk_prop_raw_struct_t
ipList
[
10
]
=
{
0
};
int
idx
=
0
;
kk_property_db_get_rawdata
(
"IPAddress"
,
4
,
ipList
,
sizeof
(
ipList
));
for
(;
idx
<
10
;
idx
++
){
DEBUG_PRINT
(
"ipList[%d][%s][%s]
\n
"
,
idx
,
ipList
[
idx
].
deviceCode
,
ipList
[
idx
].
raw
);
if
(
strlen
(
ipList
[
idx
].
deviceCode
)
>
0
&&
strlen
(
ipList
[
idx
].
raw
)
>
0
){
kk_set_tcp_channel_by_idx
(
idx
,
ipList
[
idx
].
deviceCode
,
ipList
[
idx
].
raw
);
}
}
kk_TCP_channel_init
(
gw2mid_cb
);
while
(
1
)
{
//从广播地址接受消息
memset
(
szDec
,
0
,
sizeof
(
szDec
));
int
size
=
recvfrom
(
sock
,
szDec
,
sizeof
(
szDec
),
0
,
(
struct
sockaddr
*
)
&
from
,(
socklen_t
*
)
&
len
);
if
(
size
<=
0
)
{
WARNING_PRINT
(
"read error....
\n
"
);
}
else
{
DEBUG_PRINT
(
"lan recmsg: %s
\n
"
,
szDec
);
//DEBUG_PRINT("udp client ip:%s ,port is :%d htons(UDP_LAN_PORT)=%d \n",inet_ntoa(from.sin_addr),from.sin_port, htons(UDP_LAN_PORT));
#ifdef test_
//"search_kk_ccu|deviceCode=1122334455667788;protocol=tcp"
if
(
strstr
(
szDec
,
"search_kk_ccu|"
)
!=
NULL
){
char
*
getConnet
=
szDec
+
strlen
(
"search_kk_ccu|"
);
char
*
tmp
=
NULL
;
char
*
endIdx
=
NULL
;
int
itemLen
=
0
;
int
itemConnetLen
=
0
;
char
gwDevCode
[
DEVICE_CODE_LEN
]
=
{
0
};
char
proto
[
10
]
=
{
0
};
tmp
=
strstr
(
getConnet
,
"deviceCode="
);
itemLen
=
strlen
(
"deviceCode="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
gwDevCode
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
getConnet
,
"protocol="
);
itemLen
=
strlen
(
"protocol="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
proto
,
tmp
+
itemLen
,
itemConnetLen
);
}
DEBUG_PRINT
(
"gwDevCode =%s proto=%s
\n
"
,
gwDevCode
,
proto
);
if
(
strcmp
(
proto
,
"tcp"
)
==
0
){
//
kk_set_tcp_channel
(
gwDevCode
,
inet_ntoa
(
from
.
sin_addr
));
}
memset
(
host_ip
,
0
,
sizeof
(
host_ip
));
memset
(
mac
,
0
,
sizeof
(
mac
));
memset
(
szOut
,
0
,
sizeof
(
szOut
));
HAL_Get_IP
(
host_ip
,
"ens33"
);
HAL_GetDevice_Code
(
device_code
);
sprintf
(
szOut
,
"search_kk_ccu_ack|deviceCode=%s;ip=%s;port=%d"
,
device_code
,
host_ip
,
16565
);
DEBUG_PRINT
(
"szOut:%s
\n
"
,
szOut
);
DEBUG_PRINT
(
"udp client ip:%s ,port is :%d
\n
"
,
inet_ntoa
(
from
.
sin_addr
),
from
.
sin_port
);
//sendto(sock, szOut, strlen(szOut), 0, (struct sockaddr*)&from,len);
addrto_host
.
sin_addr
.
s_addr
=
inet_addr
(
inet_ntoa
(
from
.
sin_addr
));
addrto_host
.
sin_port
=
htons
(
UDP_LAN_PORT_HOST
);
//addrto_host.sin_port = from.sin_port;
//if(strcmp(host_ip,inet_ntoa(from.sin_addr)) == 0)
//{
sendto
(
sock_host
,
szOut
,
strlen
(
szOut
),
0
,
(
struct
sockaddr
*
)
&
addrto_host
,
sizeof
(
addrto_host
));
//}
//else
//{
// DEBUG_PRINT("udp client is not local ip , refused send ack to it\n");
//}
}
#else
json
=
cJSON_Parse
(
szDec
);
if
(
!
json
)
{
ERROR_PRINT
(
"Error before: [%s]
\n
"
,
"cJSON_Parse"
);
}
else
{
infoObj
=
cJSON_GetObjectItem
(
json
,
"info"
);
payloadObj
=
cJSON_GetObjectItem
(
json
,
"payload"
);
if
(
infoObj
!=
NULL
&&
payloadObj
!=
NULL
){
msgtype
=
cJSON_GetObjectItem
(
infoObj
,
"msgtype"
);
if
(
msgtype
==
NULL
||
strstr
(
msgtype
->
valuestring
,
"/thing/topo/add"
)
==
NULL
){
ERROR_PRINT
(
"msgtype parameter is error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
proCode
=
cJSON_GetObjectItem
(
infoObj
,
"productCode"
);
devCode
=
cJSON_GetObjectItem
(
infoObj
,
"deviceCode"
);
params
=
cJSON_GetObjectItem
(
payloadObj
,
"params"
);
if
(
proCode
==
NULL
||
devCode
==
NULL
||
params
==
NULL
){
ERROR_PRINT
(
"productType productCode deviceCode params parameters are error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
macstr
=
cJSON_GetObjectItem
(
params
,
"mac"
);
if
(
macstr
==
NULL
){
ERROR_PRINT
(
"mac parameter is error
\n
"
);
cJSON_Delete
(
json
);
continue
;
}
INFO_PRINT
(
" productCode deviceCode mac: [%s][%s][%s]
\n
"
,
proCode
->
valuestring
,
devCode
->
valuestring
,
macstr
->
valuestring
);
char
device_code
[
DEVICE_CODE_LEN
]
=
{
0
};
HAL_GetDevice_Code
(
device_code
);
int
res
=
kk_mid_subdev_add
(
KK_DM_DEVICE_GATEWAY
,
proCode
->
valuestring
,
devCode
->
valuestring
,
macstr
->
valuestring
,
device_code
);
if
(
res
!=
SUCCESS_RETURN
)
{
WARNING_PRINT
(
"dm_mgr_gw_create error"
);
}
//kk_ipc_send(IPC_MID2APP, szDec, size);
memset
(
host_ip
,
0
,
sizeof
(
host_ip
));
memset
(
mac
,
0
,
sizeof
(
mac
));
memset
(
szOut
,
0
,
sizeof
(
szOut
));
HAL_Get_IP
(
host_ip
,
"ens33"
);
HAL_Get_mac
(
mac
);
sprintf
(
szOut
,
"/thing/topo/add_reply|mac=%s;ip=%s"
,
mac
,
host_ip
);
DEBUG_PRINT
(
"szOut:%s
\n
"
,
szOut
);
DEBUG_PRINT
(
"udp client ip:%s ,port is :%d
\n
"
,
inet_ntoa
(
from
.
sin_addr
),
from
.
sin_port
);
//sendto(sock, szOut, strlen(szOut), 0, (struct sockaddr*)&from,len);
addrto_host
.
sin_addr
.
s_addr
=
inet_addr
(
inet_ntoa
(
from
.
sin_addr
));
addrto_host
.
sin_port
=
htons
(
UDP_LAN_PORT_HOST
);
//addrto_host.sin_port = from.sin_port;
if
(
strcmp
(
host_ip
,
inet_ntoa
(
from
.
sin_addr
))
==
0
)
{
sendto
(
sock_host
,
szOut
,
strlen
(
szOut
),
0
,
(
struct
sockaddr
*
)
&
addrto_host
,
sizeof
(
addrto_host
));
}
else
{
DEBUG_PRINT
(
"udp client is not local ip , refused send ack to it
\n
"
);
}
}
else
{
INFO_PRINT
(
"error format json: [%s]
\n
"
,
szDec
);
}
cJSON_Delete
(
json
);
}
#endif
}
usleep
(
100000
);
}
close
(
sock
);
close
(
sock_host
);
}
void
*
ccu_property_monitor
(
void
*
args
)
{
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
char
s_IP
[
NETWORK_ADDR_LEN
];
char
*
s_IP_TSL
=
NULL
;
int
res
=
0
;
int
needReport
=
0
;
int
time_second
=
60
;
while
(
mid_ctx
->
g_ccuProChg_dispatch_thread_running
)
{
if
(
kk_get_cloud_recv_status
()
==
0
){
iotx_dm_ccu_cloud_check
();
sleep
(
10
);
continue
;
}
//dm_ota_yield(MID_YIELD_TIMEOUT_MS);
HAL_Get_IP
(
s_IP
,
NULL
);
res
=
kk_tsl_get_value
(
kk_tsl_get_property_value
,
0
,
KK_TSL_CCU_WANIP_IDENTIFIER
,
NULL
,
&
s_IP_TSL
);
if
(
res
!=
SUCCESS_RETURN
){
ERROR_PRINT
(
"kk_tsl_get_value Failed
\n
"
);
}
else
{
if
(
strcmp
(
s_IP
,
s_IP_TSL
)){
kk_tsl_set_value
(
kk_tsl_set_property_value
,
0
,
KK_TSL_CCU_WANIP_IDENTIFIER
,
NULL
,
s_IP
);
INFO_PRINT
(
"current ip:%s,before ip:%s
\n
"
,
s_IP
,
s_IP_TSL
);
kk_property_db_update
(
"CCU_66666"
);
needReport
=
1
;
}
}
if
(
needReport
&&
(
kk_get_cloudstatus
()
==
1
)){
needReport
=
0
;
kk_tsl_post_property
(
0
,
NULL
);
}
sleep
(
time_second
);
}
return
NULL
;
}
static
int
kk_set_product_info
(
void
)
{
HAL_SetProduct_Type
(
PRODUCT_TPYE
);
HAL_SetProduct_Code
(
PRODUCT_CODE
);
return
0
;
}
int
main
(
const
int
argc
,
const
char
**
argv
)
{
int
res
=
0
;
char
*
tsl_str
;
int
i
;
kk_tsl_t
*
dev_shadow
[
30
]
=
{
NULL
};
mid_ctx_t
*
mid_ctx
=
kk_mid_get_ctx
();
kk_zlog_init
(
"midware"
);
memset
(
mid_ctx
,
0
,
sizeof
(
mid_ctx_t
));
kk_set_product_info
();
kk_tsl_api_init
();
kk_ipc_init
(
IPC_MID2APP
,
mid_cb
,
NULL
,
NULL
);
kk_ipc_init
(
IPC_MID2PLAT
,
mid2p_cb
,
NULL
,
"*"
);
kk_init_dmproc
();
kk_subDb_init
();
kk_heartbeat_init
();
mid_ctx
->
g_mid_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_mid_dispatch_thread
,
NULL
,
mid_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate mid Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
mid_ctx
->
g_ota_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_ota_dispatch_thread
,
NULL
,
ota_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate ota Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
// recv gateway add cmd and ack to gateway
res
=
pthread_create
(
&
mid_ctx
->
g_udp_dispatch_thread
,
NULL
,
udp_dispatch_yield
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate udp Failed
\n
"
);
//IOT_Linkkit_Close(mid_ctx->master_devid);
return
-
1
;
}
mid_ctx
->
g_ccuProChg_dispatch_thread_running
=
1
;
res
=
pthread_create
(
&
mid_ctx
->
g_ccuProChg_dispatch_thread
,
NULL
,
ccu_property_monitor
,
NULL
);
if
(
res
<
0
)
{
ERROR_PRINT
(
"HAL_ThreadCreate Failed
\n
"
);
return
-
1
;
}
int
ct
=
0
;
for
(;;)
{
usleep
(
200000
);
kk_platMsg_dispatch
();
/*if (ct == 0){
ct =1;
void* buf = "{\
\"info\": {\
\"msgtype\": \"/thing/topo/add\",\
\"productType\": \"gw\",\
\"productCode\": \"2\",\
\"deviceCode\": \"1122334455667788\"\
},\
\"payload\": {\
\"msgId\": \"1\",\
\"version\": \"1.0\",\
\"params\": {\
\"deviceCode\": \"588E81FFFED3834A\",\
\"productCode\": \"24\",\
\"mac\": \"588E81FFFED3834A\"\
}\
}\
}";
kk_platMsg_handle(buf, "1122334455667788");
//kk_set_tsl_by_productKey("a1OYuSallan","model.json");
//kk_mid_subdev_add("a1OYuSallan","allanWno8yDdsjCX15iq","","aabbccddeeff1122");
}*/
}
}
platform/zigbee/app/builder/Z3GatewayHost/libapi_com.so
View file @
d6ef290b
No preview for this file type
platform/zigbee/app/builder/Z3GatewayHost/rpc_api/src/rpc_interface_parse.c
View file @
d6ef290b
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include "RPC_API.h"
#include "./rpc_api/inc/rpc_interface_parse.h"
#include "rpc_network_operate.h"
#include "rpc_global_cmd.h"
#include "rpc_colorControl.h"
#include "rpc_onoff.h"
#include "kk_test.h"
//#include "kk_log.h"
static
struct
jrpc_server
my_server
;
cJSON
*
test_func
(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
);
typedef
cJSON
(
*
rpc_function
)(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
);
typedef
struct
{
rpc_function
func
;
char
*
name
;
}
rpc_table_s
;
rpc_table_s
rpc_table
[]
=
{
{
test_func
,
"test_func"
},
RPC_KK_TEST_FUNCTION_TABLE
,
RPC_NETWORK_FUNCTION_TABLE
,
RPC_COMMON_FUNCTION_TABLE
,
RPC_GLOBAL_COMMAND_FUNCTION_TABLE
,
RPC_COLOR_CONTROL_COMMAND_FUNCTION_TABLE
,
RPC_OnOff_COMMAND_FUNCTION_TABLE
,
};
void
rpcInterfaceParse
(
void
)
{
emberAfAppPrint
(
"Thread rpc Interface Parse create
\n
"
);
jrpc_server_init
(
&
my_server
,
PORT
);
emberAfAppPrint
(
"sizeof(rpc_table)=%d,sizeof(rpc_table_s)=%d,%d
\n
"
,
sizeof
(
rpc_table
),
sizeof
(
rpc_table_s
),
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
));
for
(
int
i
=
0
;
i
<
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
);
i
++
){
emberAfAppPrint
(
"i=%d,%s
\r\n
"
,
i
,
rpc_table
[
i
].
name
);
jrpc_register_procedure
(
&
my_server
,
rpc_table
[
i
].
func
,
rpc_table
[
i
].
name
,
NULL
);
}
jrpc_server_run
(
&
my_server
);
jrpc_server_destroy
(
&
my_server
);
}
cJSON
*
test_func
(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
)
{
cJSON
*
item1
=
rpc_cJSON_CreateObject
();
cJSON
*
item2
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddNullToObject
(
item1
,
"Null"
);
rpc_cJSON_AddTrueToObject
(
item1
,
"True"
);
rpc_cJSON_AddFalseToObject
(
item1
,
"False"
);
rpc_cJSON_AddNumberToObject
(
item1
,
"Number"
,
12345
);
rpc_cJSON_AddStringToObject
(
item1
,
"String"
,
"hello world!"
);
rpc_cJSON_AddNullToObject
(
item2
,
"1"
);
rpc_cJSON_AddTrueToObject
(
item2
,
"2"
);
rpc_cJSON_AddFalseToObject
(
item2
,
"3"
);
rpc_cJSON_AddNumberToObject
(
item2
,
"4"
,
12345
);
rpc_cJSON_AddStringToObject
(
item2
,
"5"
,
"hello world!"
);
rpc_cJSON_AddItemToObject
(
item1
,
"hhhhhh"
,
item2
);
return
item1
;
}
static
int
send_result_resp
(
cJSON
*
result
,
cJSON
*
id
)
{
int
return_value
=
0
;
cJSON
*
info_root
=
rpc_cJSON_CreateObject
();
if
(
info_root
){
rpc_cJSON_AddStringToObject
(
info_root
,
"msgType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productCode"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"deviceCode"
,
""
);
}
cJSON
*
payload_root
=
rpc_cJSON_CreateObject
();
if
(
payload_root
){
rpc_cJSON_AddItemToObject
(
payload_root
,
"msgId"
,
id
);
rpc_cJSON_AddItemToObject
(
payload_root
,
"code"
,
result
);
rpc_cJSON_AddStringToObject
(
payload_root
,
"data"
,
"{}"
);
}
cJSON
*
result_root
=
rpc_cJSON_CreateObject
();
if
(
result_root
){
rpc_cJSON_AddItemToObject
(
result_root
,
"info"
,
info_root
);
rpc_cJSON_AddItemToObject
(
result_root
,
"payload"
,
payload_root
);
}
char
*
str_result
=
rpc_cJSON_Print
(
result_root
);
printf
(
"send json:
\n
%s
\n
"
,
str_result
);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
free
(
str_result
);
rpc_cJSON_Delete
(
result_root
);
return
return_value
;
}
static
int
send_error_resp
(
int
code
,
char
*
message
,
cJSON
*
id
)
{
int
return_value
=
0
;
cJSON
*
edata
;
cJSON
*
info_root
=
rpc_cJSON_CreateObject
();
if
(
info_root
){
rpc_cJSON_AddStringToObject
(
info_root
,
"msgType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productCode"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"deviceCode"
,
""
);
}
cJSON
*
payload_root
=
rpc_cJSON_CreateObject
();
if
(
payload_root
){
rpc_cJSON_AddItemToObject
(
payload_root
,
"msgId"
,
id
);
rpc_cJSON_AddNumberToObject
(
payload_root
,
"code"
,
code
);
edata
=
rpc_cJSON_CreateObject
();
if
(
edata
){
rpc_cJSON_AddStringToObject
(
edata
,
"message"
,
message
);
}
rpc_cJSON_AddItemToObject
(
payload_root
,
"data"
,
edata
);
}
cJSON
*
result_root
=
rpc_cJSON_CreateObject
();
if
(
result_root
){
rpc_cJSON_AddItemToObject
(
result_root
,
"info"
,
info_root
);
rpc_cJSON_AddItemToObject
(
result_root
,
"payload"
,
payload_root
);
}
char
*
str_result
=
rpc_cJSON_Print
(
result_root
);
//printf("alla=========== :%d\n", strlen(str_result)+1);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
printf
(
"send_error_resp:
\n
%s
\n
"
,
str_result
);
free
(
str_result
);
rpc_cJSON_Delete
(
result_root
);
free
(
message
);
return
return_value
;
}
static
int
invoke_procedure
(
struct
jrpc_server
*
server
,
char
*
name
,
cJSON
*
params
,
cJSON
*
id
,
cJSON
*
mac
)
{
cJSON
*
returned
=
NULL
;
int
procedure_found
=
0
;
jrpc_context
ctx
;
ctx
.
error_code
=
0
;
ctx
.
error_message
=
NULL
;
int
i
=
server
->
procedure_count
;
while
(
i
--
)
{
if
(
!
strcmp
(
server
->
procedures
[
i
].
name
,
name
))
{
procedure_found
=
1
;
ctx
.
data
=
server
->
procedures
[
i
].
data
;
returned
=
server
->
procedures
[
i
].
function
(
&
ctx
,
params
,
id
,
mac
);
break
;
}
}
if
(
!
procedure_found
)
return
send_error_resp
(
JRPC_METHOD_NOT_FOUND
,
strdup
(
"Method not found."
),
id
);
else
{
if
(
ctx
.
error_code
)
return
send_error_resp
(
ctx
.
error_code
,
ctx
.
error_message
,
id
);
else
return
send_result_resp
(
returned
,
id
);
}
}
static
int
eval_request
(
struct
jrpc_server
*
server
,
cJSON
*
root
)
{
cJSON
*
params
,
*
id
,
*
mac
,
*
info
,
*
msgType
,
*
payload
;
info
=
rpc_cJSON_GetObjectItem
(
root
,
"info"
);
if
(
info
!=
NULL
){
msgType
=
rpc_cJSON_GetObjectItem
(
info
,
"msgType"
);
mac
=
rpc_cJSON_GetObjectItem
(
info
,
"deviceCode"
);
}
payload
=
rpc_cJSON_GetObjectItem
(
root
,
"payload"
);
if
(
payload
!=
NULL
){
params
=
rpc_cJSON_GetObjectItem
(
payload
,
"params"
);
id
=
rpc_cJSON_GetObjectItem
(
payload
,
"msgId"
);
}
if
(
id
!=
NULL
&&
params
!=
NULL
&&
msgType
!=
NULL
&&
mac
!=
NULL
){
cJSON
*
id_copy
=
NULL
;
id_copy
=
(
id
->
type
==
cJSON_String
)
?
rpc_cJSON_CreateString
(
id
->
valuestring
)
:
\
rpc_cJSON_CreateNumber
(
id
->
valueint
);
return
invoke_procedure
(
server
,
msgType
->
valuestring
,
params
,
id_copy
,
mac
);
}
send_error_resp
(
JRPC_INVALID_REQUEST
,
strdup
(
"The JSON sent is not a valid Request object."
),
NULL
);
return
-
1
;
}
void
_cb
(
void
*
data
){
if
(
data
!=
NULL
){
//printf("plat2mid_cb: %s RECEIVED \r\n", data);
cJSON
*
root
;
char
*
end_ptr
=
NULL
;
if
((
root
=
rpc_cJSON_Parse_Stream
(
data
,
&
end_ptr
))
!=
NULL
)
{
if
(
1
)
{
char
*
str_result
=
rpc_cJSON_Print
(
root
);
printf
(
"Valid JSON Received:
\n
%s
\n
"
,
str_result
);
free
(
str_result
);
}
if
(
root
->
type
==
cJSON_Object
)
{
eval_request
(
&
my_server
,
root
);
}
//shift processed request, discarding it
rpc_cJSON_Delete
(
root
);
}
else
{
if
(
1
)
{
printf
(
"INVALID JSON Received:
\n
---
\n
%s
\n
---
\n
"
,
data
);
}
send_error_resp
(
JRPC_PARSE_ERROR
,
strdup
(
"Parse error. Invalid JSON was received by the server."
),
NULL
);
}
}
}
int
_init_param
(
struct
jrpc_server
*
server
)
{
memset
(
server
,
0
,
sizeof
(
struct
jrpc_server
));
//kk_zlog_init("paltform");
printf
(
"getenv
\r\n
"
);
char
*
debug_level_env
=
getenv
(
"HOME"
);
printf
(
"getenv(JRPC_DEBUG):%s
\n
"
,
server
->
debug_level
);
if
(
debug_level_env
==
NULL
)
server
->
debug_level
=
0
;
else
{
server
->
debug_level
=
strtol
(
debug_level_env
,
NULL
,
10
);
printf
(
"JSONRPC-C Debug level %d
\n
"
,
server
->
debug_level
);
}
server
->
debug_level
=
1
;
return
0
;
}
char
g_mac
[
19
]
=
{
0
};
char
*
kk_get_gw_mac
(){
int
cnt
=
0
;
EmberEUI64
eui64
;
emberAfGetEui64
(
eui64
);
while
(
eui64
[
0
]
==
0
&&
eui64
[
1
]
==
0
&&
eui64
[
2
]
==
0
&&
cnt
++
<
3
){
sleep
(
1
);
}
if
(
eui64
[
0
]
==
0
&&
eui64
[
1
]
==
0
&&
eui64
[
2
]
==
0
){
printf
(
"get gw mac error !!!
\n
"
);
return
NULL
;
}
rpc_eui64ToString
(
eui64
,
g_mac
);
return
g_mac
;
}
int
search_ccu
(
char
devcode
[
33
],
char
ip
[
16
],
int
*
port
){
char
sendCmdFmt
[]
=
"search_kk_ccu|deviceCode=%s;protocol=%s"
;
char
sendMessage
[
128
]
=
{
0
};
char
revMessage
[
128
]
=
{
0
};
int
sock
;
int
sk_recv
;
int
iSendbytes
;
int
iOptval
=
1
;
int
flag
;
int
iAddrLength
;
int
recvLen
=
0
;
struct
sockaddr_in
Addrto
;
struct
sockaddr_in
AddrRev
;
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
-
1
;
}
sprintf
(
sendMessage
,
sendCmdFmt
,
macString
/*GW_DEVICE_CODE*/
,
GW2CCU_PROTOCOL
);
if
((
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
printf
(
"[%s] socket fail
\n
"
,
__FUNCTION__
);
return
-
1
;
}
if
((
sk_recv
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
printf
(
"[%s] socket sk_recv fail
\n
"
,
__FUNCTION__
);
close
(
sock
);
return
-
1
;
}
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_BROADCAST
|
SO_REUSEADDR
,
&
iOptval
,
sizeof
(
int
))
<
0
)
{
printf
(
"[%s] setsockopt failed
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
if
(
setsockopt
(
sk_recv
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
iOptval
,
sizeof
(
int
))
<
0
)
{
printf
(
"[%s] setsockopt failed
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
flag
=
fcntl
(
sk_recv
,
F_GETFL
,
0
);
if
(
flag
<
0
)
{
printf
(
"[%s] fcntl failed.
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;;
}
flag
|=
O_NONBLOCK
;
if
(
fcntl
(
sk_recv
,
F_SETFL
,
flag
)
<
0
)
{
printf
(
"[%s] fcntl failed.
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
memset
(
&
Addrto
,
0
,
sizeof
(
struct
sockaddr_in
));
Addrto
.
sin_family
=
AF_INET
;
Addrto
.
sin_addr
.
s_addr
=
inet_addr
(
"255.255.255.255"
);
Addrto
.
sin_port
=
htons
(
25556
);
memset
(
&
AddrRev
,
0
,
sizeof
(
struct
sockaddr_in
));
AddrRev
.
sin_family
=
AF_INET
;
AddrRev
.
sin_addr
.
s_addr
=
INADDR_ANY
;
AddrRev
.
sin_port
=
htons
(
25555
);
iAddrLength
=
sizeof
(
struct
sockaddr
);
if
(
bind
(
sk_recv
,
(
struct
sockaddr
*
)
&
AddrRev
,
sizeof
(
AddrRev
))
==
-
1
)
{
printf
(
"[%s] bind failed!
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
while
(
1
)
{
if
((
iSendbytes
=
sendto
(
sock
,
sendMessage
,
strlen
(
sendMessage
)
+
1
,
0
,
(
struct
sockaddr
*
)
&
Addrto
,
sizeof
(
struct
sockaddr
)))
==
-
1
)
{
printf
(
"[%s] sendto fail, errno=%d
\n
"
,
__FUNCTION__
,
errno
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
sleep
(
1
);
recvLen
=
recvfrom
(
sk_recv
,
revMessage
,
sizeof
(
revMessage
),
0
,
(
struct
sockaddr
*
)
&
AddrRev
,
&
iAddrLength
);
if
(
recvLen
>
0
){
printf
(
"[%s] recv:%s
\n
"
,
__FUNCTION__
,
revMessage
);
//"search_kk_ccu_ack|deviceCode=CCU_66666;ip=192.168.36.128;port=16565"
if
(
strstr
(
revMessage
,
"search_kk_ccu_ack|"
)
!=
NULL
){
char
*
ackConnet
=
revMessage
+
strlen
(
"search_kk_ccu_ack|"
);
char
*
tmp
=
NULL
;
char
*
endIdx
=
NULL
;
int
itemLen
=
0
;
int
itemConnetLen
=
0
;
tmp
=
strstr
(
ackConnet
,
"deviceCode="
);
itemLen
=
strlen
(
"deviceCode="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
devcode
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
ackConnet
,
"ip="
);
itemLen
=
strlen
(
"ip="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
ip
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
ackConnet
,
"port="
);
itemLen
=
strlen
(
"port="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
char
portstr
[
20
]
=
{
0
};
memcpy
(
portstr
,
tmp
+
itemLen
,
itemConnetLen
);
*
port
=
atoi
(
portstr
);
}
//memcpy(ip, inet_ntoa(AddrRev.sin_addr), strlen(inet_ntoa(AddrRev.sin_addr)));
printf
(
" recv deviceCode:%s ip:%s port:%d
\n
"
,
devcode
,
ip
,
*
port
);
break
;
}
}
}
close
(
sock
);
close
(
sk_recv
);
return
0
;
}
#define GW_PRODUCT_CODE "2"
#define GW_MAC GW_DEVICE_CODE
void
*
_msg_topo_add
(){
char
msgFmt
[]
=
"{
\"
info
\"
:{
\"
msgtype
\"
:
\"
/thing/topo/add
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
deviceCode
\"
:
\"
%s
\"
},\
\"
payload
\"
:{
\"
msgId
\"
:
\"
%d
\"
,
\"
version
\"
:
\"
1.0
\"
,
\"
params
\"
:{
\"
deviceCode
\"
:
\"
%s
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
mac
\"
:
\"
%s
\"
}}}"
;
char
msg
[
520
]
=
{
0
};
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
NULL
;
}
sprintf
(
msg
,
msgFmt
,
GW_PRODUCT_CODE
,
macString
,
1
,
macString
/*GW_DEVICE_CODE*/
,
GW_PRODUCT_CODE
,
macString
);
cJSON
*
msgObj
=
cJSON_Parse
(
msg
);
char
*
outbuf
=
cJSON_Print
(
msgObj
);
cJSON_Delete
(
msgObj
);
return
outbuf
;
}
void
*
_msg_event_property_post
(
char
ip
[
16
],
int
port
){
char
msgFmt
[]
=
"{
\"
info
\"
:{
\"
msgtype
\"
:
\"
/thing/event/property/post
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
deviceCode
\"
:
\"
%s
\"
},\
\"
payload
\"
:{
\"
msgId
\"
:
\"
%d
\"
,
\"
version
\"
:
\"
1.0
\"
,
\"
params
\"
:{
\"
NetChannelState
\"
:%d,
\"
WhiteListState
\"
:%d,\
\"
OnlineDetectionState
\"
:%d,
\"
SN
\"
:
\"
%s
\"
,
\"
IPAddress
\"
:
\"
%s
\"
,
\"
MACAddress
\"
:
\"
%s
\"
,
\"
Port
\"
:%d},\
\"
time
\"
:1524448722000,
\"
method
\"
:
\"
thing.event.property.post
\"
}\
}"
;
char
msg
[
620
]
=
{
0
};
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
NULL
;
}
sprintf
(
msg
,
msgFmt
,
GW_PRODUCT_CODE
,
macString
/*GW_DEVICE_CODE*/
,
1
,
0
,
0
,
0
,
"12345"
,
ip
,
macString
,
port
);
cJSON
*
msgObj
=
cJSON_Parse
(
msg
);
char
*
outbuf
=
cJSON_Print
(
msgObj
);
cJSON_Delete
(
msgObj
);
return
outbuf
;
}
void
ipcHandle
(
void
)
{
char
deviceCode
[
33
]
=
{
0
};
char
ip
[
16
]
=
{
0
};
int
port
=
0
;
emberAfAppPrint
(
"Thread rpc Interface Parse create
\n
"
);
search_ccu
(
deviceCode
,
ip
,
&
port
);
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail, exit pthread !!!!!!!!!!!!!!!!!
\n
"
,
__FUNCTION__
);
return
;
}
_init_param
(
&
my_server
);
if
(
strcmp
(
GW2CCU_PROTOCOL
,
"tcp"
)
==
0
){
kk_tcp_client_init
(
ip
,
port
,
_cb
);
}
else
{
kk_ipc_init
(
IPC_PLAT2MID
,
_cb
,
macString
/*GW_DEVICE_CODE*/
,
ip
);
}
emberAfAppPrint
(
"sizeof(rpc_table)=%d,sizeof(rpc_table_s)=%d,%d
\n
"
,
sizeof
(
rpc_table
),
sizeof
(
rpc_table_s
),
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
));
for
(
int
i
=
0
;
i
<
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
);
i
++
){
emberAfAppPrint
(
"i=%d,%s
\r\n
"
,
i
,
rpc_table
[
i
].
name
);
jrpc_register_procedure
(
&
my_server
,
rpc_table
[
i
].
func
,
rpc_table
[
i
].
name
,
NULL
);
}
//send add gw to ccu
char
*
outbuf
=
_msg_topo_add
();
if
(
outbuf
==
NULL
){
printf
(
"[%s] topo add msg failed, exit
\n
"
,
__FUNCTION__
);
return
;
}
if
(
strcmp
(
GW2CCU_PROTOCOL
,
"tcp"
)
!=
0
){
printf
(
"check nanomsg is connect(%d)
\n
"
,
kk_ipc_isconnect
(
IPC_PLAT2MID
));
}
kk_sendData2CCU
(
outbuf
,
strlen
(
outbuf
));
free
(
outbuf
);
int
cnt
=
0
;
//handle procidure
while
(
1
){
//
usleep
(
20000
);
cnt
++
;
if
(
cnt
==
2
){
sleep
(
1
);
char
*
postmsg
=
_msg_event_property_post
(
ip
,
port
);
if
(
outbuf
==
NULL
){
printf
(
"[%s] property_post msg failed
\n
"
,
__FUNCTION__
);
continue
;
}
kk_sendData2CCU
(
postmsg
,
strlen
(
postmsg
));
free
(
postmsg
);
}
}
//jrpc_server_run(&my_server);
//jrpc_server_destroy(&my_server);
}
int
jrpc_send_msg
(
cJSON
*
msgJson
)
{
int
return_value
=
0
;
char
*
str_result
=
rpc_cJSON_Print
(
msgJson
);
emberAfAppPrintln
(
"send json:
\n
%s
\n
"
,
str_result
);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
free
(
str_result
);
return
return_value
;
}
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_ID 1
#define ATTRIBUTE_BUFFER_REPORT_DATA_TYPE 2
#define ATTRIBUTE_BUFFER_REPORT_DATA_VALUE 3
// Attribute reading buffer location definitions
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS 0
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS 1
#define ATTRIBUTE_BUFFER_SUCCESS_CODE 2
#define ATTRIBUTE_BUFFER_DATA_TYPE 3
#define ATTRIBUTE_BUFFER_DATA_START 4
static
void
rpc_send_message
(
cJSON
*
data
,
char
*
method
)
{
cJSON
*
item
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
item
,
"jsonrpc"
,
"2.0"
);
rpc_cJSON_AddStringToObject
(
item
,
"method"
,
method
);
rpc_cJSON_AddItemToObject
(
item
,
"params"
,
data
);
char
*
p
=
rpc_cJSON_Print
(
item
);
emberAfAppPrintln
(
"send send json:
\n
%s
\n
"
,
p
);
free
(
p
);
jrpc_send_msg
(
item
);
}
void
rpc_read_attribute_response
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"read_attribute_response"
);
}
void
rpc_report_attribute
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"report_attribute"
);
}
void
rpc_report_devices
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"report_devices"
);
}
void
rpc_control_devices
(
cJSON
*
data
,
char
*
method
)
{
rpc_send_message
(
data
,
method
);
}
bool
rpc_ReportAttributesCallback
(
EmberAfClusterId
clusterId
,
uint8_t
*
buffer
,
uint16_t
bufLen
)
{
EmberEUI64
nodeEui64
;
EmberAfAttributeId
attributeId
;
EmberNodeId
nodeId
=
emberAfCurrentCommand
()
->
source
;
uint8_t
ep
=
emberAfCurrentCommand
()
->
apsFrame
->
sourceEndpoint
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
uint8_t
*
bufferTemp
;
uint8_t
*
bufferPtr
=
buffer
;
uint8_t
i
,
bufferSize
,
typeSize
;
uint8_t
dataLen
,
dataType
;
uint8_t
*
dataPtr
;
kk_print_debug
(
"
\n
********************report callback**********************
\n
"
);
emberAfAppPrint
(
"[ "
);
emberAfAppPrintBuffer
(
buffer
,
bufLen
,
true
);
emberAfAppPrint
(
"]
\n
"
);
if
(
bufLen
==
0
)
{
emberAfAppPrintln
(
"Report attributes callback: zero length buffer"
);
return
false
;
}
kk_print_debug
(
"
\n
mac:"
);
emberAfPrintBigEndianEui64
(
nodeEui64
);
emberAfAppPrintln
(
",EP=%d,cluster=0x%04X
\n
"
,
ep
,
clusterId
);
for
(
i
=
0
;
i
<
bufLen
-
3
;
)
{
dataType
=
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
];
if
(
emberAfIsStringAttributeType
(
dataType
)){
dataLen
=
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
];
typeSize
=
1
;
}
else
if
(
emberAfIsLongStringAttributeType
(
dataType
)){
dataLen
=
HIGH_LOW_TO_INT
(
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
2
],
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
1
]);
typeSize
=
2
;
}
else
{
typeSize
=
0
;
dataLen
=
emberAfGetDataSize
(
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
}
dataPtr
=
&
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
];
bufferSize
=
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
+
dataLen
+
typeSize
;
bufferTemp
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memcpy
(
bufferTemp
,
bufferPtr
,
bufferSize
);
bufferPtr
+=
bufferSize
;
i
+=
bufferSize
;
emberAfAppPrintln
(
"i=%d,bufferSize=%d
\n
"
,
i
,
bufferSize
);
emberAfAppPrintln
(
"Reported attribute: 0x%02X%02X, Type: %02X"
,
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
attributeId
=
HIGH_LOW_TO_INT
(
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
]);
emberAfAppPrintln
(
"attributeId=0x%x"
,
attributeId
);
if
(
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
)){
emberAfAppPrintln
(
"nodeId=0x%x"
,
nodeId
);
kk_dispatch_report_attribute
(
nodeEui64
,
ep
,
clusterId
,
attributeId
,
dataType
,
dataLen
,
dataPtr
);
}
free
(
bufferTemp
);
}
return
false
;
}
bool
rpc_ReadAttributesResponseCallback
(
EmberAfClusterId
clusterId
,
uint8_t
*
buffer
,
uint16_t
bufLen
)
{
EmberEUI64
nodeEui64
;
EmberNodeId
nodeId
=
emberAfCurrentCommand
()
->
source
;
uint8_t
ep
=
emberAfCurrentCommand
()
->
apsFrame
->
sourceEndpoint
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
uint8_t
*
bufferTemp
;
uint8_t
*
bufferPtr
=
buffer
;
uint8_t
i
,
bufferSize
,
typeSize
;
uint8_t
cnt
=
1
;
uint8_t
Status
;
kk_print_debug
(
"
\n
********************read attributes response callback**********************
\n
"
);
emberAfAppPrint
(
"[ "
);
emberAfAppPrintBuffer
(
buffer
,
bufLen
,
true
);
emberAfAppPrint
(
"]
\n
"
);
if
(
bufLen
==
0
)
{
emberAfAppPrintln
(
"read attributes response callback: zero length buffer"
);
return
false
;
}
kk_print_debug
(
"
\n
mac:"
);
emberAfPrintBigEndianEui64
(
nodeEui64
);
emberAfAppPrintln
(
",EP=%d,cluster=0x%04X
\n
"
,
ep
,
clusterId
);
cJSON
*
item
=
rpc_cJSON_CreateObject
();
cJSON
*
array_attr
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddMACToObject
(
item
,
nodeEui64
);
rpc_cJSON_AddNodeToObject
(
item
,
nodeId
);
rpc_cJSON_AddEndpointToObject
(
item
,
ep
);
rpc_cJSON_AddClusterToObject
(
item
,
clusterId
);
array_attr
=
rpc_cJSON_CreateArray
();
rpc_cJSON_AddItemToObject
(
item
,
"attributes"
,
array_attr
);
cJSON
*
item_attr
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddItemToArray
(
array_attr
,
item_attr
);
//todo:check
for
(
i
=
0
;
i
<
bufLen
;
)
{
Status
=
bufferPtr
[
2
];
if
(
Status
==
EMBER_ZCL_STATUS_SUCCESS
){
if
(
emberAfIsStringAttributeType
(
bufferPtr
[
3
])){
bufferSize
=
bufferPtr
[
4
];
typeSize
=
1
;
}
else
if
(
emberAfIsLongStringAttributeType
(
bufferPtr
[
3
])){
bufferSize
=
HIGH_LOW_TO_INT
(
bufferPtr
[
5
],
bufferPtr
[
4
]);
typeSize
=
2
;
}
else
{
typeSize
=
0
;
bufferSize
=
emberAfGetDataSize
(
bufferPtr
[
3
]);
}
bufferSize
=
bufferSize
+
4
+
typeSize
;
bufferTemp
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memcpy
(
bufferTemp
,
bufferPtr
,
bufferSize
);
bufferPtr
=
bufferPtr
+
bufferSize
;
emberAfAppPrintln
(
"i=%d,bufferSize=%d
\n
"
,
i
,
bufferSize
);
emberAfAppPrintln
(
"Read attribute Response: 0x%02X%02X, Type: %02X"
,
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
rpc_cJSON_AddStatusToObject
(
item_attr
,
Status
);
EmberAfAttributeId
attributeId
=
HIGH_LOW_TO_INT
(
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
]);
rpc_cJSON_AddAttributeToObject
(
item_attr
,
attributeId
);
rpc_cJSON_AddDataTypeToObject
(
item_attr
,
bufferTemp
[
3
]);
int
dataLen
=
bufferSize
-
4
-
typeSize
;
rpc_cJSON_AddLengthToObject
(
item_attr
,
dataLen
);
uint8_t
*
dataPtr
=
&
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
1
+
1
+
typeSize
];
rpc_cJSON_AddDataToObject
(
item_attr
,
dataPtr
,
dataLen
);
//rpc_read_response_process_callback(nodeId,ep,clusterId,attributeId,bufferPtr[3],dataLen,dataPtr);
free
(
bufferTemp
);
}
else
{
rpc_cJSON_AddStatusToObject
(
item_attr
,
Status
);
bufferSize
+=
2
;
emberAfAppPrintln
(
"Status=%d
\n
"
,
Status
);
}
i
=
i
+
bufferSize
;
}
rpc_read_attribute_response
(
item
);
return
false
;
}
static
cJSON
*
rpc_reportDeviceState
(
char
*
state
,
EmberEUI64
eui64
)
{
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
cJSON
*
stateJSON
;
rpc_eui64ToString
(
eui64
,
euiString
);
stateJSON
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
stateJSON
,
"mac"
,
euiString
);
rpc_cJSON_AddStringToObject
(
stateJSON
,
"status"
,
state
);
return
stateJSON
;
}
void
rpc_reportDeviceStateChange
(
EmberEUI64
eui64
,
uint8_t
state
)
{
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
cJSON
*
stateChangeJson
;
rpc_eui64ToString
(
eui64
,
euiString
);
stateChangeJson
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
stateChangeJson
,
"mac"
,
euiString
);
rpc_cJSON_AddNumberToObject
(
stateChangeJson
,
"deviceState"
,
state
);
rpc_printfJSON
(
"devicestatechange"
,
stateChangeJson
);
}
void
emberAfPluginDeviceTableStateChangeCallback
(
EmberNodeId
nodeId
,
uint8_t
state
)
{
EmberEUI64
nodeEui64
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
rpc_reportDeviceStateChange
(
nodeEui64
,
state
);
}
void
emberAfPluginDeviceTableRejoinDeviceCallback
(
EmberEUI64
nodeEui64
)
{
uint16_t
deviceTableIndex
=
emberAfDeviceTableGetFirstIndexFromEui64
(
nodeEui64
);
if
(
deviceTableIndex
==
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX
){
return
;
}
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"rejoin"
,
deviceTable
[
deviceTableIndex
].
eui64
);
rpc_printfJSON
(
"rejoin"
,
nodeJson
);
//rpc_send_message(nodeJson,"device rejoin");
kk_rpc_reportDevices
(
deviceTable
[
deviceTableIndex
].
eui64
);
}
void
emberAfPluginDeviceTableDeviceLeftCallback
(
EmberEUI64
nodeEui64
)
{
uint16_t
deviceTableIndex
=
emberAfDeviceTableGetFirstIndexFromEui64
(
nodeEui64
);
if
(
deviceTableIndex
==
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX
){
return
;
}
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"left"
,
deviceTable
[
deviceTableIndex
].
eui64
);
rpc_printfJSON
(
"left"
,
nodeJson
);
//rpc_send_message(nodeJson,"device left");
kk_rpc_reportLeftDevices
(
deviceTable
[
deviceTableIndex
].
eui64
);
}
static
cJSON
*
rpc_buildDeviceEndpoint
(
EmberEUI64
eui64
,
uint8_t
endpoint
)
{
cJSON
*
deviceEndpointObj
;
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
deviceEndpointObj
=
rpc_cJSON_CreateObject
();
rpc_eui64ToString
(
eui64
,
euiString
);
rpc_cJSON_AddStringToObject
(
deviceEndpointObj
,
"mac"
,
euiString
);
rpc_cJSON_AddNumberToObject
(
deviceEndpointObj
,
"ep"
,
endpoint
);
return
deviceEndpointObj
;
}
static
cJSON
*
rpc_buildDeviceEndpointWithClusterInfo
(
EmberEUI64
eui64
,
uint8_t
endpoint
,
uint16_t
*
clusterIds
,
uint8_t
clusterOutStartPosition
)
{
cJSON
*
deviceEndpointObj
;
cJSON
*
clusterInfoArray
;
cJSON
*
clusterInfoItem
;
uint16_t
clusterIdIndex
;
char
clusterIdString
[
RPC_CLUSTERID_STRING_LENGTH
]
=
{
0
};
clusterInfoArray
=
rpc_cJSON_CreateArray
();
deviceEndpointObj
=
rpc_buildDeviceEndpoint
(
eui64
,
endpoint
);
for
(
clusterIdIndex
=
0
;
clusterIdIndex
<
EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE
;
clusterIdIndex
++
)
{
clusterInfoItem
=
rpc_cJSON_CreateObject
();
if
(
clusterIds
[
clusterIdIndex
]
!=
ZCL_NULL_CLUSTER_ID
)
{
sprintf
(
clusterIdString
,
"0x%04X"
,
clusterIds
[
clusterIdIndex
]);
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterId"
,
clusterIdString
);
if
(
clusterIdIndex
<
clusterOutStartPosition
)
{
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterType"
,
"In"
);
}
else
{
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterType"
,
"Out"
);
}
rpc_cJSON_AddItemToArray
(
clusterInfoArray
,
clusterInfoItem
);
clusterInfoItem
=
NULL
;
}
else
{
rpc_cJSON_Delete
(
clusterInfoItem
);
clusterInfoItem
=
NULL
;
break
;
}
}
rpc_cJSON_AddItemToObject
(
deviceEndpointObj
,
"clusterInfo"
,
clusterInfoArray
);
return
deviceEndpointObj
;
}
static
cJSON
*
buildNodeJson
(
uint16_t
nodeIndex
)
{
cJSON
*
nodeJson
;
cJSON
*
deviceEndpoint
;
char
nodeIdString
[
RPC_NODEID_STRING_LENGTH
]
=
{
0
};
char
*
deviceTypeString
;
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
nodeJson
=
rpc_cJSON_CreateObject
();
rpc_nodeIdToString
(
deviceTable
[
nodeIndex
].
nodeId
,
nodeIdString
);
rpc_cJSON_AddStringToObject
(
nodeJson
,
"nodeId"
,
nodeIdString
);
rpc_cJSON_AddNumberToObject
(
nodeJson
,
"deviceState"
,
deviceTable
[
nodeIndex
].
state
);
deviceTypeString
=
rpc_createTwoByteHexString
(
deviceTable
[
nodeIndex
].
deviceId
);
rpc_cJSON_AddStringToObject
(
nodeJson
,
"deviceType"
,
deviceTypeString
);
free
(
deviceTypeString
);
deviceEndpoint
=
rpc_buildDeviceEndpointWithClusterInfo
(
deviceTable
[
nodeIndex
].
eui64
,
deviceTable
[
nodeIndex
].
endpoint
,
deviceTable
[
nodeIndex
].
clusterIds
,
deviceTable
[
nodeIndex
].
clusterOutStartPosition
);
rpc_cJSON_AddItemToObject
(
nodeJson
,
"deviceEndpoint"
,
deviceEndpoint
);
return
nodeJson
;
}
void
rpc_reportDevices
(
void
)
{
uint16_t
nodeIndex
;
cJSON
*
nodeJson
;
cJSON
*
devicesJson
;
cJSON
*
devicesJsonNodeArray
;
devicesJson
=
rpc_cJSON_CreateObject
();
devicesJsonNodeArray
=
rpc_cJSON_CreateArray
();
rpc_cJSON_AddItemToObject
(
devicesJson
,
"devices"
,
devicesJsonNodeArray
);
for
(
nodeIndex
=
0
;
nodeIndex
<
EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE
;
nodeIndex
++
)
{
if
(
emberAfDeviceTableGetNodeIdFromIndex
(
nodeIndex
)
!=
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID
)
{
nodeJson
=
buildNodeJson
(
nodeIndex
);
rpc_cJSON_AddItemToArray
(
devicesJsonNodeArray
,
nodeJson
);
break
;
}
}
rpc_report_devices
(
devicesJson
);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include "RPC_API.h"
#include "./rpc_api/inc/rpc_interface_parse.h"
#include "rpc_network_operate.h"
#include "rpc_global_cmd.h"
#include "rpc_colorControl.h"
#include "rpc_onoff.h"
#include "kk_test.h"
//#include "kk_log.h"
static
struct
jrpc_server
my_server
;
cJSON
*
test_func
(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
);
typedef
cJSON
(
*
rpc_function
)(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
);
typedef
struct
{
rpc_function
func
;
char
*
name
;
}
rpc_table_s
;
rpc_table_s
rpc_table
[]
=
{
{
test_func
,
"test_func"
},
RPC_KK_TEST_FUNCTION_TABLE
,
RPC_NETWORK_FUNCTION_TABLE
,
RPC_COMMON_FUNCTION_TABLE
,
RPC_GLOBAL_COMMAND_FUNCTION_TABLE
,
RPC_COLOR_CONTROL_COMMAND_FUNCTION_TABLE
,
RPC_OnOff_COMMAND_FUNCTION_TABLE
,
};
void
rpcInterfaceParse
(
void
)
{
emberAfAppPrint
(
"Thread rpc Interface Parse create
\n
"
);
jrpc_server_init
(
&
my_server
,
PORT
);
emberAfAppPrint
(
"sizeof(rpc_table)=%d,sizeof(rpc_table_s)=%d,%d
\n
"
,
sizeof
(
rpc_table
),
sizeof
(
rpc_table_s
),
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
));
for
(
int
i
=
0
;
i
<
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
);
i
++
){
emberAfAppPrint
(
"i=%d,%s
\r\n
"
,
i
,
rpc_table
[
i
].
name
);
jrpc_register_procedure
(
&
my_server
,
rpc_table
[
i
].
func
,
rpc_table
[
i
].
name
,
NULL
);
}
jrpc_server_run
(
&
my_server
);
jrpc_server_destroy
(
&
my_server
);
}
cJSON
*
test_func
(
jrpc_context
*
ctx
,
cJSON
*
params
,
cJSON
*
id
)
{
cJSON
*
item1
=
rpc_cJSON_CreateObject
();
cJSON
*
item2
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddNullToObject
(
item1
,
"Null"
);
rpc_cJSON_AddTrueToObject
(
item1
,
"True"
);
rpc_cJSON_AddFalseToObject
(
item1
,
"False"
);
rpc_cJSON_AddNumberToObject
(
item1
,
"Number"
,
12345
);
rpc_cJSON_AddStringToObject
(
item1
,
"String"
,
"hello world!"
);
rpc_cJSON_AddNullToObject
(
item2
,
"1"
);
rpc_cJSON_AddTrueToObject
(
item2
,
"2"
);
rpc_cJSON_AddFalseToObject
(
item2
,
"3"
);
rpc_cJSON_AddNumberToObject
(
item2
,
"4"
,
12345
);
rpc_cJSON_AddStringToObject
(
item2
,
"5"
,
"hello world!"
);
rpc_cJSON_AddItemToObject
(
item1
,
"hhhhhh"
,
item2
);
return
item1
;
}
static
int
send_result_resp
(
cJSON
*
result
,
cJSON
*
id
)
{
int
return_value
=
0
;
cJSON
*
info_root
=
rpc_cJSON_CreateObject
();
if
(
info_root
){
rpc_cJSON_AddStringToObject
(
info_root
,
"msgType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productCode"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"deviceCode"
,
""
);
}
cJSON
*
payload_root
=
rpc_cJSON_CreateObject
();
if
(
payload_root
){
rpc_cJSON_AddItemToObject
(
payload_root
,
"msgId"
,
id
);
rpc_cJSON_AddItemToObject
(
payload_root
,
"code"
,
result
);
rpc_cJSON_AddStringToObject
(
payload_root
,
"data"
,
"{}"
);
}
cJSON
*
result_root
=
rpc_cJSON_CreateObject
();
if
(
result_root
){
rpc_cJSON_AddItemToObject
(
result_root
,
"info"
,
info_root
);
rpc_cJSON_AddItemToObject
(
result_root
,
"payload"
,
payload_root
);
}
char
*
str_result
=
rpc_cJSON_Print
(
result_root
);
printf
(
"send json:
\n
%s
\n
"
,
str_result
);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
free
(
str_result
);
rpc_cJSON_Delete
(
result_root
);
return
return_value
;
}
static
int
send_error_resp
(
int
code
,
char
*
message
,
cJSON
*
id
)
{
int
return_value
=
0
;
cJSON
*
edata
;
cJSON
*
info_root
=
rpc_cJSON_CreateObject
();
if
(
info_root
){
rpc_cJSON_AddStringToObject
(
info_root
,
"msgType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productType"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"productCode"
,
""
);
rpc_cJSON_AddStringToObject
(
info_root
,
"deviceCode"
,
""
);
}
cJSON
*
payload_root
=
rpc_cJSON_CreateObject
();
if
(
payload_root
){
rpc_cJSON_AddItemToObject
(
payload_root
,
"msgId"
,
id
);
rpc_cJSON_AddNumberToObject
(
payload_root
,
"code"
,
code
);
edata
=
rpc_cJSON_CreateObject
();
if
(
edata
){
rpc_cJSON_AddStringToObject
(
edata
,
"message"
,
message
);
}
rpc_cJSON_AddItemToObject
(
payload_root
,
"data"
,
edata
);
}
cJSON
*
result_root
=
rpc_cJSON_CreateObject
();
if
(
result_root
){
rpc_cJSON_AddItemToObject
(
result_root
,
"info"
,
info_root
);
rpc_cJSON_AddItemToObject
(
result_root
,
"payload"
,
payload_root
);
}
char
*
str_result
=
rpc_cJSON_Print
(
result_root
);
//printf("alla=========== :%d\n", strlen(str_result)+1);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
printf
(
"send_error_resp:
\n
%s
\n
"
,
str_result
);
free
(
str_result
);
rpc_cJSON_Delete
(
result_root
);
free
(
message
);
return
return_value
;
}
static
int
invoke_procedure
(
struct
jrpc_server
*
server
,
char
*
name
,
cJSON
*
params
,
cJSON
*
id
,
cJSON
*
mac
)
{
cJSON
*
returned
=
NULL
;
int
procedure_found
=
0
;
jrpc_context
ctx
;
ctx
.
error_code
=
0
;
ctx
.
error_message
=
NULL
;
int
i
=
server
->
procedure_count
;
while
(
i
--
)
{
if
(
!
strcmp
(
server
->
procedures
[
i
].
name
,
name
))
{
procedure_found
=
1
;
ctx
.
data
=
server
->
procedures
[
i
].
data
;
returned
=
server
->
procedures
[
i
].
function
(
&
ctx
,
params
,
id
,
mac
);
break
;
}
}
if
(
!
procedure_found
)
return
send_error_resp
(
JRPC_METHOD_NOT_FOUND
,
strdup
(
"Method not found."
),
id
);
else
{
if
(
ctx
.
error_code
)
return
send_error_resp
(
ctx
.
error_code
,
ctx
.
error_message
,
id
);
else
return
send_result_resp
(
returned
,
id
);
}
}
static
int
eval_request
(
struct
jrpc_server
*
server
,
cJSON
*
root
)
{
cJSON
*
params
,
*
id
,
*
mac
,
*
info
,
*
msgType
,
*
payload
;
info
=
rpc_cJSON_GetObjectItem
(
root
,
"info"
);
if
(
info
!=
NULL
){
msgType
=
rpc_cJSON_GetObjectItem
(
info
,
"msgType"
);
mac
=
rpc_cJSON_GetObjectItem
(
info
,
"deviceCode"
);
}
payload
=
rpc_cJSON_GetObjectItem
(
root
,
"payload"
);
if
(
payload
!=
NULL
){
params
=
rpc_cJSON_GetObjectItem
(
payload
,
"params"
);
id
=
rpc_cJSON_GetObjectItem
(
payload
,
"msgId"
);
}
if
(
id
!=
NULL
&&
params
!=
NULL
&&
msgType
!=
NULL
&&
mac
!=
NULL
){
cJSON
*
id_copy
=
NULL
;
id_copy
=
(
id
->
type
==
cJSON_String
)
?
rpc_cJSON_CreateString
(
id
->
valuestring
)
:
\
rpc_cJSON_CreateNumber
(
id
->
valueint
);
return
invoke_procedure
(
server
,
msgType
->
valuestring
,
params
,
id_copy
,
mac
);
}
send_error_resp
(
JRPC_INVALID_REQUEST
,
strdup
(
"The JSON sent is not a valid Request object."
),
NULL
);
return
-
1
;
}
void
_cb
(
void
*
data
){
if
(
data
!=
NULL
){
//printf("plat2mid_cb: %s RECEIVED \r\n", data);
cJSON
*
root
;
char
*
end_ptr
=
NULL
;
if
((
root
=
rpc_cJSON_Parse_Stream
(
data
,
&
end_ptr
))
!=
NULL
)
{
if
(
1
)
{
char
*
str_result
=
rpc_cJSON_Print
(
root
);
printf
(
"Valid JSON Received:
\n
%s
\n
"
,
str_result
);
free
(
str_result
);
}
if
(
root
->
type
==
cJSON_Object
)
{
eval_request
(
&
my_server
,
root
);
}
//shift processed request, discarding it
rpc_cJSON_Delete
(
root
);
}
else
{
if
(
1
)
{
printf
(
"INVALID JSON Received:
\n
---
\n
%s
\n
---
\n
"
,
data
);
}
send_error_resp
(
JRPC_PARSE_ERROR
,
strdup
(
"Parse error. Invalid JSON was received by the server."
),
NULL
);
}
}
}
int
_init_param
(
struct
jrpc_server
*
server
)
{
memset
(
server
,
0
,
sizeof
(
struct
jrpc_server
));
//kk_zlog_init("paltform");
printf
(
"getenv
\r\n
"
);
char
*
debug_level_env
=
getenv
(
"HOME"
);
printf
(
"getenv(JRPC_DEBUG):%s
\n
"
,
server
->
debug_level
);
if
(
debug_level_env
==
NULL
)
server
->
debug_level
=
0
;
else
{
server
->
debug_level
=
strtol
(
debug_level_env
,
NULL
,
10
);
printf
(
"JSONRPC-C Debug level %d
\n
"
,
server
->
debug_level
);
}
server
->
debug_level
=
1
;
return
0
;
}
char
g_mac
[
19
]
=
{
0
};
char
*
kk_get_gw_mac
(){
int
cnt
=
0
;
EmberEUI64
eui64
;
emberAfGetEui64
(
eui64
);
while
(
eui64
[
0
]
==
0
&&
eui64
[
1
]
==
0
&&
eui64
[
2
]
==
0
&&
cnt
++
<
3
){
sleep
(
1
);
}
if
(
eui64
[
0
]
==
0
&&
eui64
[
1
]
==
0
&&
eui64
[
2
]
==
0
){
printf
(
"get gw mac error !!!
\n
"
);
return
NULL
;
}
rpc_eui64ToString
(
eui64
,
g_mac
);
return
g_mac
;
}
int
search_ccu
(
char
devcode
[
33
],
char
ip
[
16
],
int
*
port
){
char
sendCmdFmt
[]
=
"search_kk_ccu|deviceCode=%s;protocol=%s"
;
char
sendMessage
[
128
]
=
{
0
};
char
revMessage
[
128
]
=
{
0
};
int
sock
;
int
sk_recv
;
int
iSendbytes
;
int
iOptval
=
1
;
int
flag
;
int
iAddrLength
;
int
recvLen
=
0
;
struct
sockaddr_in
Addrto
;
struct
sockaddr_in
AddrRev
;
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
-
1
;
}
sprintf
(
sendMessage
,
sendCmdFmt
,
macString
/*GW_DEVICE_CODE*/
,
GW2CCU_PROTOCOL
);
if
((
sock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
printf
(
"[%s] socket fail
\n
"
,
__FUNCTION__
);
return
-
1
;
}
if
((
sk_recv
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
printf
(
"[%s] socket sk_recv fail
\n
"
,
__FUNCTION__
);
close
(
sock
);
return
-
1
;
}
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_BROADCAST
|
SO_REUSEADDR
,
&
iOptval
,
sizeof
(
int
))
<
0
)
{
printf
(
"[%s] setsockopt failed
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
if
(
setsockopt
(
sk_recv
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
iOptval
,
sizeof
(
int
))
<
0
)
{
printf
(
"[%s] setsockopt failed
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
flag
=
fcntl
(
sk_recv
,
F_GETFL
,
0
);
if
(
flag
<
0
)
{
printf
(
"[%s] fcntl failed.
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;;
}
flag
|=
O_NONBLOCK
;
if
(
fcntl
(
sk_recv
,
F_SETFL
,
flag
)
<
0
)
{
printf
(
"[%s] fcntl failed.
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
memset
(
&
Addrto
,
0
,
sizeof
(
struct
sockaddr_in
));
Addrto
.
sin_family
=
AF_INET
;
Addrto
.
sin_addr
.
s_addr
=
inet_addr
(
"255.255.255.255"
);
Addrto
.
sin_port
=
htons
(
25556
);
memset
(
&
AddrRev
,
0
,
sizeof
(
struct
sockaddr_in
));
AddrRev
.
sin_family
=
AF_INET
;
AddrRev
.
sin_addr
.
s_addr
=
INADDR_ANY
;
AddrRev
.
sin_port
=
htons
(
25555
);
iAddrLength
=
sizeof
(
struct
sockaddr
);
if
(
bind
(
sk_recv
,
(
struct
sockaddr
*
)
&
AddrRev
,
sizeof
(
AddrRev
))
==
-
1
)
{
printf
(
"[%s] bind failed!
\n
"
,
__FUNCTION__
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
while
(
1
)
{
if
((
iSendbytes
=
sendto
(
sock
,
sendMessage
,
strlen
(
sendMessage
)
+
1
,
0
,
(
struct
sockaddr
*
)
&
Addrto
,
sizeof
(
struct
sockaddr
)))
==
-
1
)
{
printf
(
"[%s] sendto fail, errno=%d
\n
"
,
__FUNCTION__
,
errno
);
close
(
sock
);
close
(
sk_recv
);
return
-
1
;
}
sleep
(
1
);
recvLen
=
recvfrom
(
sk_recv
,
revMessage
,
sizeof
(
revMessage
),
0
,
(
struct
sockaddr
*
)
&
AddrRev
,
&
iAddrLength
);
if
(
recvLen
>
0
){
printf
(
"[%s] recv:%s
\n
"
,
__FUNCTION__
,
revMessage
);
//"search_kk_ccu_ack|deviceCode=CCU_66666;ip=192.168.36.128;port=16565"
if
(
strstr
(
revMessage
,
"search_kk_ccu_ack|"
)
!=
NULL
){
char
*
ackConnet
=
revMessage
+
strlen
(
"search_kk_ccu_ack|"
);
char
*
tmp
=
NULL
;
char
*
endIdx
=
NULL
;
int
itemLen
=
0
;
int
itemConnetLen
=
0
;
tmp
=
strstr
(
ackConnet
,
"deviceCode="
);
itemLen
=
strlen
(
"deviceCode="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
devcode
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
ackConnet
,
"ip="
);
itemLen
=
strlen
(
"ip="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
memcpy
(
ip
,
tmp
+
itemLen
,
itemConnetLen
);
}
tmp
=
strstr
(
ackConnet
,
"port="
);
itemLen
=
strlen
(
"port="
);
if
(
tmp
!=
NULL
){
endIdx
=
strstr
(
tmp
,
";"
);
if
(
endIdx
==
NULL
){
itemConnetLen
=
strlen
(
tmp
)
-
itemLen
;
}
else
{
itemConnetLen
=
endIdx
-
tmp
-
itemLen
;
}
char
portstr
[
20
]
=
{
0
};
memcpy
(
portstr
,
tmp
+
itemLen
,
itemConnetLen
);
*
port
=
atoi
(
portstr
);
}
//memcpy(ip, inet_ntoa(AddrRev.sin_addr), strlen(inet_ntoa(AddrRev.sin_addr)));
printf
(
" recv deviceCode:%s ip:%s port:%d
\n
"
,
devcode
,
ip
,
*
port
);
break
;
}
}
}
close
(
sock
);
close
(
sk_recv
);
return
0
;
}
#define GW_PRODUCT_CODE "2"
#define GW_MAC GW_DEVICE_CODE
void
*
_msg_topo_add
(){
char
msgFmt
[]
=
"{
\"
info
\"
:{
\"
msgtype
\"
:
\"
/thing/topo/add
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
deviceCode
\"
:
\"
%s
\"
},\
\"
payload
\"
:{
\"
msgId
\"
:
\"
%d
\"
,
\"
version
\"
:
\"
1.0
\"
,
\"
params
\"
:{
\"
deviceCode
\"
:
\"
%s
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
mac
\"
:
\"
%s
\"
}}}"
;
char
msg
[
520
]
=
{
0
};
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
NULL
;
}
sprintf
(
msg
,
msgFmt
,
GW_PRODUCT_CODE
,
macString
,
1
,
macString
/*GW_DEVICE_CODE*/
,
GW_PRODUCT_CODE
,
macString
);
cJSON
*
msgObj
=
cJSON_Parse
(
msg
);
char
*
outbuf
=
cJSON_Print
(
msgObj
);
cJSON_Delete
(
msgObj
);
return
outbuf
;
}
void
*
_msg_event_property_post
(
char
ip
[
16
],
int
port
){
char
msgFmt
[]
=
"{
\"
info
\"
:{
\"
msgtype
\"
:
\"
/thing/event/property/post
\"
,
\"
productCode
\"
:
\"
%s
\"
,
\"
deviceCode
\"
:
\"
%s
\"
},\
\"
payload
\"
:{
\"
msgId
\"
:
\"
%d
\"
,
\"
version
\"
:
\"
1.0
\"
,
\"
params
\"
:{
\"
NetChannelState
\"
:%d,
\"
WhiteListState
\"
:%d,\
\"
OnlineDetectionState
\"
:%d,
\"
SN
\"
:
\"
%s
\"
,
\"
IPAddress
\"
:
\"
%s
\"
,
\"
MACAddress
\"
:
\"
%s
\"
,
\"
Port
\"
:%d},\
\"
time
\"
:1524448722000,
\"
method
\"
:
\"
thing.event.property.post
\"
}\
}"
;
char
msg
[
620
]
=
{
0
};
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail
\n
"
,
__FUNCTION__
);
return
NULL
;
}
sprintf
(
msg
,
msgFmt
,
GW_PRODUCT_CODE
,
macString
/*GW_DEVICE_CODE*/
,
1
,
0
,
0
,
0
,
"12345"
,
ip
,
macString
,
port
);
cJSON
*
msgObj
=
cJSON_Parse
(
msg
);
char
*
outbuf
=
cJSON_Print
(
msgObj
);
cJSON_Delete
(
msgObj
);
return
outbuf
;
}
void
ipcHandle
(
void
)
{
char
deviceCode
[
33
]
=
{
0
};
char
ip
[
16
]
=
{
0
};
int
port
=
0
;
emberAfAppPrint
(
"Thread rpc Interface Parse create
\n
"
);
search_ccu
(
deviceCode
,
ip
,
&
port
);
char
*
macString
=
kk_get_gw_mac
();
if
(
macString
==
NULL
){
printf
(
"[%s] get mac fail, exit pthread !!!!!!!!!!!!!!!!!
\n
"
,
__FUNCTION__
);
return
;
}
_init_param
(
&
my_server
);
if
(
strcmp
(
GW2CCU_PROTOCOL
,
"tcp"
)
==
0
){
kk_tcp_client_init
(
ip
,
port
,
_cb
);
}
else
{
kk_ipc_init
(
IPC_PLAT2MID
,
_cb
,
macString
/*GW_DEVICE_CODE*/
,
ip
);
}
emberAfAppPrint
(
"sizeof(rpc_table)=%d,sizeof(rpc_table_s)=%d,%d
\n
"
,
sizeof
(
rpc_table
),
sizeof
(
rpc_table_s
),
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
));
for
(
int
i
=
0
;
i
<
sizeof
(
rpc_table
)
/
sizeof
(
rpc_table_s
);
i
++
){
emberAfAppPrint
(
"i=%d,%s
\r\n
"
,
i
,
rpc_table
[
i
].
name
);
jrpc_register_procedure
(
&
my_server
,
rpc_table
[
i
].
func
,
rpc_table
[
i
].
name
,
NULL
);
}
//send add gw to ccu
char
*
outbuf
=
_msg_topo_add
();
if
(
outbuf
==
NULL
){
printf
(
"[%s] topo add msg failed, exit
\n
"
,
__FUNCTION__
);
return
;
}
if
(
strcmp
(
GW2CCU_PROTOCOL
,
"tcp"
)
!=
0
){
printf
(
"check nanomsg is connect(%d)
\n
"
,
kk_ipc_isconnect
(
IPC_PLAT2MID
));
}
kk_sendData2CCU
(
outbuf
,
strlen
(
outbuf
));
free
(
outbuf
);
int
cnt
=
0
;
//handle procidure
while
(
1
){
//
usleep
(
20000
);
cnt
++
;
if
(
cnt
==
2
){
sleep
(
1
);
char
gwIp
[
17
]
=
{
0
};
HAL_Get_IP
(
gwIp
,
NULL
);
char
*
postmsg
=
_msg_event_property_post
(
gwIp
,
port
);
if
(
outbuf
==
NULL
){
printf
(
"[%s] property_post msg failed
\n
"
,
__FUNCTION__
);
continue
;
}
kk_sendData2CCU
(
postmsg
,
strlen
(
postmsg
));
free
(
postmsg
);
}
}
//jrpc_server_run(&my_server);
//jrpc_server_destroy(&my_server);
}
int
jrpc_send_msg
(
cJSON
*
msgJson
)
{
int
return_value
=
0
;
char
*
str_result
=
rpc_cJSON_Print
(
msgJson
);
emberAfAppPrintln
(
"send json:
\n
%s
\n
"
,
str_result
);
return_value
=
kk_sendData2CCU
(
str_result
,
strlen
(
str_result
)
+
1
);
free
(
str_result
);
return
return_value
;
}
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_ID 1
#define ATTRIBUTE_BUFFER_REPORT_DATA_TYPE 2
#define ATTRIBUTE_BUFFER_REPORT_DATA_VALUE 3
// Attribute reading buffer location definitions
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS 0
#define ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS 1
#define ATTRIBUTE_BUFFER_SUCCESS_CODE 2
#define ATTRIBUTE_BUFFER_DATA_TYPE 3
#define ATTRIBUTE_BUFFER_DATA_START 4
static
void
rpc_send_message
(
cJSON
*
data
,
char
*
method
)
{
cJSON
*
item
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
item
,
"jsonrpc"
,
"2.0"
);
rpc_cJSON_AddStringToObject
(
item
,
"method"
,
method
);
rpc_cJSON_AddItemToObject
(
item
,
"params"
,
data
);
char
*
p
=
rpc_cJSON_Print
(
item
);
emberAfAppPrintln
(
"send send json:
\n
%s
\n
"
,
p
);
free
(
p
);
jrpc_send_msg
(
item
);
}
void
rpc_read_attribute_response
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"read_attribute_response"
);
}
void
rpc_report_attribute
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"report_attribute"
);
}
void
rpc_report_devices
(
cJSON
*
data
)
{
rpc_send_message
(
data
,
"report_devices"
);
}
void
rpc_control_devices
(
cJSON
*
data
,
char
*
method
)
{
rpc_send_message
(
data
,
method
);
}
bool
rpc_ReportAttributesCallback
(
EmberAfClusterId
clusterId
,
uint8_t
*
buffer
,
uint16_t
bufLen
)
{
EmberEUI64
nodeEui64
;
EmberAfAttributeId
attributeId
;
EmberNodeId
nodeId
=
emberAfCurrentCommand
()
->
source
;
uint8_t
ep
=
emberAfCurrentCommand
()
->
apsFrame
->
sourceEndpoint
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
uint8_t
*
bufferTemp
;
uint8_t
*
bufferPtr
=
buffer
;
uint8_t
i
,
bufferSize
,
typeSize
;
uint8_t
dataLen
,
dataType
;
uint8_t
*
dataPtr
;
kk_print_debug
(
"
\n
********************report callback**********************
\n
"
);
emberAfAppPrint
(
"[ "
);
emberAfAppPrintBuffer
(
buffer
,
bufLen
,
true
);
emberAfAppPrint
(
"]
\n
"
);
if
(
bufLen
==
0
)
{
emberAfAppPrintln
(
"Report attributes callback: zero length buffer"
);
return
false
;
}
kk_print_debug
(
"
\n
mac:"
);
emberAfPrintBigEndianEui64
(
nodeEui64
);
emberAfAppPrintln
(
",EP=%d,cluster=0x%04X
\n
"
,
ep
,
clusterId
);
for
(
i
=
0
;
i
<
bufLen
-
3
;
)
{
dataType
=
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
];
if
(
emberAfIsStringAttributeType
(
dataType
)){
dataLen
=
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
];
typeSize
=
1
;
}
else
if
(
emberAfIsLongStringAttributeType
(
dataType
)){
dataLen
=
HIGH_LOW_TO_INT
(
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
2
],
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
1
]);
typeSize
=
2
;
}
else
{
typeSize
=
0
;
dataLen
=
emberAfGetDataSize
(
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
}
dataPtr
=
&
bufferPtr
[
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
];
bufferSize
=
ATTRIBUTE_BUFFER_REPORT_DATA_VALUE
+
dataLen
+
typeSize
;
bufferTemp
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memcpy
(
bufferTemp
,
bufferPtr
,
bufferSize
);
bufferPtr
+=
bufferSize
;
i
+=
bufferSize
;
emberAfAppPrintln
(
"i=%d,bufferSize=%d
\n
"
,
i
,
bufferSize
);
emberAfAppPrintln
(
"Reported attribute: 0x%02X%02X, Type: %02X"
,
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
attributeId
=
HIGH_LOW_TO_INT
(
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
]);
emberAfAppPrintln
(
"attributeId=0x%x"
,
attributeId
);
if
(
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
)){
emberAfAppPrintln
(
"nodeId=0x%x"
,
nodeId
);
kk_dispatch_report_attribute
(
nodeEui64
,
ep
,
clusterId
,
attributeId
,
dataType
,
dataLen
,
dataPtr
);
}
free
(
bufferTemp
);
}
return
false
;
}
bool
rpc_ReadAttributesResponseCallback
(
EmberAfClusterId
clusterId
,
uint8_t
*
buffer
,
uint16_t
bufLen
)
{
EmberEUI64
nodeEui64
;
EmberNodeId
nodeId
=
emberAfCurrentCommand
()
->
source
;
uint8_t
ep
=
emberAfCurrentCommand
()
->
apsFrame
->
sourceEndpoint
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
uint8_t
*
bufferTemp
;
uint8_t
*
bufferPtr
=
buffer
;
uint8_t
i
,
bufferSize
,
typeSize
;
uint8_t
cnt
=
1
;
uint8_t
Status
;
kk_print_debug
(
"
\n
********************read attributes response callback**********************
\n
"
);
emberAfAppPrint
(
"[ "
);
emberAfAppPrintBuffer
(
buffer
,
bufLen
,
true
);
emberAfAppPrint
(
"]
\n
"
);
if
(
bufLen
==
0
)
{
emberAfAppPrintln
(
"read attributes response callback: zero length buffer"
);
return
false
;
}
kk_print_debug
(
"
\n
mac:"
);
emberAfPrintBigEndianEui64
(
nodeEui64
);
emberAfAppPrintln
(
",EP=%d,cluster=0x%04X
\n
"
,
ep
,
clusterId
);
cJSON
*
item
=
rpc_cJSON_CreateObject
();
cJSON
*
array_attr
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddMACToObject
(
item
,
nodeEui64
);
rpc_cJSON_AddNodeToObject
(
item
,
nodeId
);
rpc_cJSON_AddEndpointToObject
(
item
,
ep
);
rpc_cJSON_AddClusterToObject
(
item
,
clusterId
);
array_attr
=
rpc_cJSON_CreateArray
();
rpc_cJSON_AddItemToObject
(
item
,
"attributes"
,
array_attr
);
cJSON
*
item_attr
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddItemToArray
(
array_attr
,
item_attr
);
//todo:check
for
(
i
=
0
;
i
<
bufLen
;
)
{
Status
=
bufferPtr
[
2
];
if
(
Status
==
EMBER_ZCL_STATUS_SUCCESS
){
if
(
emberAfIsStringAttributeType
(
bufferPtr
[
3
])){
bufferSize
=
bufferPtr
[
4
];
typeSize
=
1
;
}
else
if
(
emberAfIsLongStringAttributeType
(
bufferPtr
[
3
])){
bufferSize
=
HIGH_LOW_TO_INT
(
bufferPtr
[
5
],
bufferPtr
[
4
]);
typeSize
=
2
;
}
else
{
typeSize
=
0
;
bufferSize
=
emberAfGetDataSize
(
bufferPtr
[
3
]);
}
bufferSize
=
bufferSize
+
4
+
typeSize
;
bufferTemp
=
(
uint8_t
*
)
malloc
(
bufferSize
);
memcpy
(
bufferTemp
,
bufferPtr
,
bufferSize
);
bufferPtr
=
bufferPtr
+
bufferSize
;
emberAfAppPrintln
(
"i=%d,bufferSize=%d
\n
"
,
i
,
bufferSize
);
emberAfAppPrintln
(
"Read attribute Response: 0x%02X%02X, Type: %02X"
,
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
]);
rpc_cJSON_AddStatusToObject
(
item_attr
,
Status
);
EmberAfAttributeId
attributeId
=
HIGH_LOW_TO_INT
(
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_HIGH_BITS
],
bufferTemp
[
ATTRIBUTE_BUFFER_ATTRIBUTEID_LOW_BITS
]);
rpc_cJSON_AddAttributeToObject
(
item_attr
,
attributeId
);
rpc_cJSON_AddDataTypeToObject
(
item_attr
,
bufferTemp
[
3
]);
int
dataLen
=
bufferSize
-
4
-
typeSize
;
rpc_cJSON_AddLengthToObject
(
item_attr
,
dataLen
);
uint8_t
*
dataPtr
=
&
bufferTemp
[
ATTRIBUTE_BUFFER_REPORT_DATA_TYPE
+
1
+
1
+
typeSize
];
rpc_cJSON_AddDataToObject
(
item_attr
,
dataPtr
,
dataLen
);
//rpc_read_response_process_callback(nodeId,ep,clusterId,attributeId,bufferPtr[3],dataLen,dataPtr);
free
(
bufferTemp
);
}
else
{
rpc_cJSON_AddStatusToObject
(
item_attr
,
Status
);
bufferSize
+=
2
;
emberAfAppPrintln
(
"Status=%d
\n
"
,
Status
);
}
i
=
i
+
bufferSize
;
}
rpc_read_attribute_response
(
item
);
return
false
;
}
static
cJSON
*
rpc_reportDeviceState
(
char
*
state
,
EmberEUI64
eui64
)
{
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
cJSON
*
stateJSON
;
rpc_eui64ToString
(
eui64
,
euiString
);
stateJSON
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
stateJSON
,
"mac"
,
euiString
);
rpc_cJSON_AddStringToObject
(
stateJSON
,
"status"
,
state
);
return
stateJSON
;
}
void
rpc_reportDeviceStateChange
(
EmberEUI64
eui64
,
uint8_t
state
)
{
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
cJSON
*
stateChangeJson
;
rpc_eui64ToString
(
eui64
,
euiString
);
stateChangeJson
=
rpc_cJSON_CreateObject
();
rpc_cJSON_AddStringToObject
(
stateChangeJson
,
"mac"
,
euiString
);
rpc_cJSON_AddNumberToObject
(
stateChangeJson
,
"deviceState"
,
state
);
rpc_printfJSON
(
"devicestatechange"
,
stateChangeJson
);
}
void
emberAfPluginDeviceTableStateChangeCallback
(
EmberNodeId
nodeId
,
uint8_t
state
)
{
EmberEUI64
nodeEui64
;
emberAfDeviceTableGetEui64FromNodeId
(
nodeId
,
nodeEui64
);
rpc_reportDeviceStateChange
(
nodeEui64
,
state
);
}
void
emberAfPluginDeviceTableRejoinDeviceCallback
(
EmberEUI64
nodeEui64
)
{
uint16_t
deviceTableIndex
=
emberAfDeviceTableGetFirstIndexFromEui64
(
nodeEui64
);
if
(
deviceTableIndex
==
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX
){
return
;
}
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"rejoin"
,
deviceTable
[
deviceTableIndex
].
eui64
);
rpc_printfJSON
(
"rejoin"
,
nodeJson
);
//rpc_send_message(nodeJson,"device rejoin");
kk_rpc_reportDevices
(
deviceTable
[
deviceTableIndex
].
eui64
);
}
void
emberAfPluginDeviceTableDeviceLeftCallback
(
EmberEUI64
nodeEui64
)
{
uint16_t
deviceTableIndex
=
emberAfDeviceTableGetFirstIndexFromEui64
(
nodeEui64
);
if
(
deviceTableIndex
==
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX
){
return
;
}
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
cJSON
*
nodeJson
=
rpc_reportDeviceState
(
"left"
,
deviceTable
[
deviceTableIndex
].
eui64
);
rpc_printfJSON
(
"left"
,
nodeJson
);
//rpc_send_message(nodeJson,"device left");
kk_rpc_reportLeftDevices
(
deviceTable
[
deviceTableIndex
].
eui64
);
}
static
cJSON
*
rpc_buildDeviceEndpoint
(
EmberEUI64
eui64
,
uint8_t
endpoint
)
{
cJSON
*
deviceEndpointObj
;
char
euiString
[
RPC_EUI64_STRING_LENGTH
]
=
{
0
};
deviceEndpointObj
=
rpc_cJSON_CreateObject
();
rpc_eui64ToString
(
eui64
,
euiString
);
rpc_cJSON_AddStringToObject
(
deviceEndpointObj
,
"mac"
,
euiString
);
rpc_cJSON_AddNumberToObject
(
deviceEndpointObj
,
"ep"
,
endpoint
);
return
deviceEndpointObj
;
}
static
cJSON
*
rpc_buildDeviceEndpointWithClusterInfo
(
EmberEUI64
eui64
,
uint8_t
endpoint
,
uint16_t
*
clusterIds
,
uint8_t
clusterOutStartPosition
)
{
cJSON
*
deviceEndpointObj
;
cJSON
*
clusterInfoArray
;
cJSON
*
clusterInfoItem
;
uint16_t
clusterIdIndex
;
char
clusterIdString
[
RPC_CLUSTERID_STRING_LENGTH
]
=
{
0
};
clusterInfoArray
=
rpc_cJSON_CreateArray
();
deviceEndpointObj
=
rpc_buildDeviceEndpoint
(
eui64
,
endpoint
);
for
(
clusterIdIndex
=
0
;
clusterIdIndex
<
EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE
;
clusterIdIndex
++
)
{
clusterInfoItem
=
rpc_cJSON_CreateObject
();
if
(
clusterIds
[
clusterIdIndex
]
!=
ZCL_NULL_CLUSTER_ID
)
{
sprintf
(
clusterIdString
,
"0x%04X"
,
clusterIds
[
clusterIdIndex
]);
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterId"
,
clusterIdString
);
if
(
clusterIdIndex
<
clusterOutStartPosition
)
{
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterType"
,
"In"
);
}
else
{
rpc_cJSON_AddStringToObject
(
clusterInfoItem
,
"clusterType"
,
"Out"
);
}
rpc_cJSON_AddItemToArray
(
clusterInfoArray
,
clusterInfoItem
);
clusterInfoItem
=
NULL
;
}
else
{
rpc_cJSON_Delete
(
clusterInfoItem
);
clusterInfoItem
=
NULL
;
break
;
}
}
rpc_cJSON_AddItemToObject
(
deviceEndpointObj
,
"clusterInfo"
,
clusterInfoArray
);
return
deviceEndpointObj
;
}
static
cJSON
*
buildNodeJson
(
uint16_t
nodeIndex
)
{
cJSON
*
nodeJson
;
cJSON
*
deviceEndpoint
;
char
nodeIdString
[
RPC_NODEID_STRING_LENGTH
]
=
{
0
};
char
*
deviceTypeString
;
EmberAfPluginDeviceTableEntry
*
deviceTable
=
emberAfDeviceTablePointer
();
nodeJson
=
rpc_cJSON_CreateObject
();
rpc_nodeIdToString
(
deviceTable
[
nodeIndex
].
nodeId
,
nodeIdString
);
rpc_cJSON_AddStringToObject
(
nodeJson
,
"nodeId"
,
nodeIdString
);
rpc_cJSON_AddNumberToObject
(
nodeJson
,
"deviceState"
,
deviceTable
[
nodeIndex
].
state
);
deviceTypeString
=
rpc_createTwoByteHexString
(
deviceTable
[
nodeIndex
].
deviceId
);
rpc_cJSON_AddStringToObject
(
nodeJson
,
"deviceType"
,
deviceTypeString
);
free
(
deviceTypeString
);
deviceEndpoint
=
rpc_buildDeviceEndpointWithClusterInfo
(
deviceTable
[
nodeIndex
].
eui64
,
deviceTable
[
nodeIndex
].
endpoint
,
deviceTable
[
nodeIndex
].
clusterIds
,
deviceTable
[
nodeIndex
].
clusterOutStartPosition
);
rpc_cJSON_AddItemToObject
(
nodeJson
,
"deviceEndpoint"
,
deviceEndpoint
);
return
nodeJson
;
}
void
rpc_reportDevices
(
void
)
{
uint16_t
nodeIndex
;
cJSON
*
nodeJson
;
cJSON
*
devicesJson
;
cJSON
*
devicesJsonNodeArray
;
devicesJson
=
rpc_cJSON_CreateObject
();
devicesJsonNodeArray
=
rpc_cJSON_CreateArray
();
rpc_cJSON_AddItemToObject
(
devicesJson
,
"devices"
,
devicesJsonNodeArray
);
for
(
nodeIndex
=
0
;
nodeIndex
<
EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE
;
nodeIndex
++
)
{
if
(
emberAfDeviceTableGetNodeIdFromIndex
(
nodeIndex
)
!=
EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID
)
{
nodeJson
=
buildNodeJson
(
nodeIndex
);
rpc_cJSON_AddItemToArray
(
devicesJsonNodeArray
,
nodeJson
);
break
;
}
}
rpc_report_devices
(
devicesJson
);
}
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