diff options
author | tcave | 2013-03-20 09:14:17 -0500 |
---|---|---|
committer | tcave | 2013-03-20 09:14:17 -0500 |
commit | 5e920e84ebbf20213e906a7518803b7740227a7e (patch) | |
tree | 2a339c113f23b20a46b7feb8a9a5be88b603cbc5 | |
download | zllhostinterfaceexample-5e920e84ebbf20213e906a7518803b7740227a7e.tar.gz zllhostinterfaceexample-5e920e84ebbf20213e906a7518803b7740227a7e.tar.xz zllhostinterfaceexample-5e920e84ebbf20213e906a7518803b7740227a7e.zip |
Initial check in
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | Manifest.pdf | bin | 0 -> 123749 bytes | |||
-rw-r--r-- | readme.txt | 1 | ||||
-rw-r--r-- | zllSocCmd.c | 1190 | ||||
-rw-r--r-- | zllSocCmd.h | 113 | ||||
-rw-r--r-- | zll_controller.c | 448 |
6 files changed, 1776 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..abb5d6d --- /dev/null +++ b/Makefile | |||
@@ -0,0 +1,24 @@ | |||
1 | |||
2 | SBU_REV= "0.1" | ||
3 | |||
4 | GCC = gcc | ||
5 | |||
6 | CFLAGS = -Wall -DVERSION_NUMBER=${SBU_REV} | ||
7 | OBJECTS = zll_controller.o zllSocCmd.o | ||
8 | |||
9 | DEFS += -D_GNU_SOURCE | ||
10 | |||
11 | APP_NAME=zllController.bin | ||
12 | |||
13 | .PHONY: all, clean | ||
14 | |||
15 | ${APP_NAME}: ${OBJECTS} | ||
16 | $(GCC) $(CFLAGS) $(OBJECTS) -o ${APP_NAME} | ||
17 | |||
18 | %.o: %.c | ||
19 | ${GCC} ${CFLAGS} ${INCLUDE} ${DEFS} -c -o $@ $< | ||
20 | |||
21 | all: ${APP_NAME} | ||
22 | |||
23 | clean: | ||
24 | rm -rf *.o ${APP_NAME} | ||
diff --git a/Manifest.pdf b/Manifest.pdf new file mode 100644 index 0000000..ba02bab --- /dev/null +++ b/Manifest.pdf | |||
Binary files differ | |||
diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..1d3178f --- /dev/null +++ b/readme.txt | |||
@@ -0,0 +1 @@ | |||
documentation for this example can be found at http://processors.wiki.ti.com/index.php/ZStack-Lighting-1.0.1_Host_Interface_C_Examples | |||
diff --git a/zllSocCmd.c b/zllSocCmd.c new file mode 100644 index 0000000..1908662 --- /dev/null +++ b/zllSocCmd.c | |||
@@ -0,0 +1,1190 @@ | |||
1 | /* | ||
2 | * zllSocCmd.c | ||
3 | * | ||
4 | * This module contains the API for the zll SoC Host Interface. | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | |||
40 | /********************************************************************* | ||
41 | * INCLUDES | ||
42 | */ | ||
43 | #include <termios.h> | ||
44 | #include <string.h> | ||
45 | #include <stdio.h> | ||
46 | #include <stdlib.h> | ||
47 | #include <unistd.h> | ||
48 | #include <fcntl.h> | ||
49 | #include <sys/ioctl.h> | ||
50 | |||
51 | #include <errno.h> | ||
52 | #include <string.h> | ||
53 | |||
54 | #include "zllSocCmd.h" | ||
55 | |||
56 | |||
57 | /********************************************************************* | ||
58 | * MACROS | ||
59 | */ | ||
60 | |||
61 | #define APPCMDHEADER(len) \ | ||
62 | 0xFE, \ | ||
63 | len, /*RPC payload Len */ \ | ||
64 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ \ | ||
65 | 0x00, /*MT_APP_MSG */ \ | ||
66 | 0x0B, /*Application Endpoint */ \ | ||
67 | 0x02, /*short Addr 0x0002 */ \ | ||
68 | 0x00, /*short Addr 0x0002 */ \ | ||
69 | 0x0B, /*Dst EP */ \ | ||
70 | 0xFF, /*Cluster ID 0xFFFF invalid, used for key */ \ | ||
71 | 0xFF, /*Cluster ID 0xFFFF invalid, used for key */ \ | ||
72 | |||
73 | #define BUILD_UINT16(loByte, hiByte) \ | ||
74 | ((uint16_t)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8))) | ||
75 | |||
76 | /********************************************************************* | ||
77 | * CONSTANTS | ||
78 | */ | ||
79 | #define ZLL_MT_APP_RPC_CMD_TOUCHLINK 0x01 | ||
80 | #define ZLL_MT_APP_RPC_CMD_RESET_TO_FN 0x02 | ||
81 | #define ZLL_MT_APP_RPC_CMD_CH_CHANNEL 0x03 | ||
82 | #define ZLL_MT_APP_RPC_CMD_JOIN_HA 0x04 | ||
83 | #define ZLL_MT_APP_RPC_CMD_PERMIT_JOIN 0x05 | ||
84 | #define ZLL_MT_APP_RPC_CMD_SEND_RESET_TO_FN 0x06 | ||
85 | |||
86 | #define MT_APP_RSP 0x80 | ||
87 | #define MT_APP_ZLL_TL_IND 0x81 | ||
88 | #define MT_APP_ZLL_NEW_DEV_IND 0x82 | ||
89 | |||
90 | #define MT_DEBUG_MSG 0x80 | ||
91 | |||
92 | #define COMMAND_LIGHTING_MOVE_TO_HUE 0x00 | ||
93 | #define COMMAND_LIGHTING_MOVE_TO_SATURATION 0x03 | ||
94 | #define COMMAND_LEVEL_MOVE_TO_LEVEL 0x00 | ||
95 | |||
96 | /*** Foundation Command IDs ***/ | ||
97 | #define ZCL_CMD_READ 0x00 | ||
98 | #define ZCL_CMD_READ_RSP 0x01 | ||
99 | #define ZCL_CMD_WRITE 0x02 | ||
100 | #define ZCL_CMD_WRITE_UNDIVIDED 0x03 | ||
101 | #define ZCL_CMD_WRITE_RSP 0x04 | ||
102 | |||
103 | // General Clusters | ||
104 | #define ZCL_CLUSTER_ID_GEN_IDENTIFY 0x0003 | ||
105 | #define ZCL_CLUSTER_ID_GEN_GROUPS 0x0004 | ||
106 | #define ZCL_CLUSTER_ID_GEN_SCENES 0x0005 | ||
107 | #define ZCL_CLUSTER_ID_GEN_ON_OFF 0x0006 | ||
108 | #define ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL 0x0008 | ||
109 | // Lighting Clusters | ||
110 | #define ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL 0x0300 | ||
111 | |||
112 | /*******************************/ | ||
113 | /*** Scenes Cluster Commands ***/ | ||
114 | /*******************************/ | ||
115 | #define COMMAND_SCENE_STORE 0x04 | ||
116 | #define COMMAND_SCENE_RECALL 0x05 | ||
117 | |||
118 | /*******************************/ | ||
119 | /*** Groups Cluster Commands ***/ | ||
120 | /*******************************/ | ||
121 | #define COMMAND_GROUP_ADD 0x00 | ||
122 | |||
123 | #define ATTRID_ON_OFF 0x0000 | ||
124 | #define ATTRID_LEVEL_CURRENT_LEVEL 0x0000 | ||
125 | #define ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_HUE 0x0000 | ||
126 | #define ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_SATURATION 0x0001 | ||
127 | |||
128 | /* The 3 MSB's of the 1st command field byte are for command type. */ | ||
129 | #define MT_RPC_CMD_TYPE_MASK 0xE0 | ||
130 | |||
131 | /* The 5 LSB's of the 1st command field byte are for the subsystem. */ | ||
132 | #define MT_RPC_SUBSYSTEM_MASK 0x1F | ||
133 | |||
134 | #define MT_RPC_SOF 0xFE | ||
135 | |||
136 | typedef enum { | ||
137 | MT_RPC_CMD_POLL = 0x00, | ||
138 | MT_RPC_CMD_SREQ = 0x20, | ||
139 | MT_RPC_CMD_AREQ = 0x40, | ||
140 | MT_RPC_CMD_SRSP = 0x60, | ||
141 | MT_RPC_CMD_RES4 = 0x80, | ||
142 | MT_RPC_CMD_RES5 = 0xA0, | ||
143 | MT_RPC_CMD_RES6 = 0xC0, | ||
144 | MT_RPC_CMD_RES7 = 0xE0 | ||
145 | } mtRpcCmdType_t; | ||
146 | |||
147 | typedef enum { | ||
148 | MT_RPC_SYS_RES0, /* Reserved. */ | ||
149 | MT_RPC_SYS_SYS, | ||
150 | MT_RPC_SYS_MAC, | ||
151 | MT_RPC_SYS_NWK, | ||
152 | MT_RPC_SYS_AF, | ||
153 | MT_RPC_SYS_ZDO, | ||
154 | MT_RPC_SYS_SAPI, /* Simple API. */ | ||
155 | MT_RPC_SYS_UTIL, | ||
156 | MT_RPC_SYS_DBG, | ||
157 | MT_RPC_SYS_APP, | ||
158 | MT_RPC_SYS_OTA, | ||
159 | MT_RPC_SYS_ZNP, | ||
160 | MT_RPC_SYS_SPARE_12, | ||
161 | MT_RPC_SYS_UBL = 13, // 13 to be compatible with existing RemoTI. | ||
162 | MT_RPC_SYS_MAX // Maximum value, must be last (so 14-32 available, not yet assigned). | ||
163 | } mtRpcSysType_t; | ||
164 | |||
165 | /************************************************************ | ||
166 | * TYPEDEFS | ||
167 | */ | ||
168 | |||
169 | /********************************************************************* | ||
170 | * GLOBAL VARIABLES | ||
171 | */ | ||
172 | |||
173 | /********************************************************************* | ||
174 | * LOCAL VARIABLES | ||
175 | */ | ||
176 | int serialPortFd = 0; | ||
177 | uint8_t transSeqNumber = 0; | ||
178 | |||
179 | zllSocCallbacks_t zllSocCb; | ||
180 | |||
181 | /********************************************************************* | ||
182 | * LOCAL FUNCTIONS | ||
183 | */ | ||
184 | void calcFcs(uint8_t *msg, int size); | ||
185 | |||
186 | /********************************************************************* | ||
187 | * @fn calcFcs | ||
188 | * | ||
189 | * @brief populates the Frame Check Sequence of the RPC payload. | ||
190 | * | ||
191 | * @param msg - pointer to the RPC message | ||
192 | * | ||
193 | * @return none | ||
194 | */ | ||
195 | void calcFcs(uint8_t *msg, int size) | ||
196 | { | ||
197 | uint8_t result = 0; | ||
198 | int idx = 1; //skip SOF | ||
199 | int len = (size - 1); // skip FCS | ||
200 | |||
201 | while ((len--) != 0) { | ||
202 | result ^= msg[idx++]; | ||
203 | } | ||
204 | |||
205 | msg[(size-1)] = result; | ||
206 | } | ||
207 | |||
208 | /********************************************************************* | ||
209 | * API FUNCTIONS | ||
210 | */ | ||
211 | |||
212 | /********************************************************************* | ||
213 | * @fn zllSocOpen | ||
214 | * | ||
215 | * @brief opens the serial port to the CC253x. | ||
216 | * | ||
217 | * @param devicePath - path to the UART device | ||
218 | * | ||
219 | * @return status | ||
220 | */ | ||
221 | int32_t zllSocOpen( char *devicePath ) | ||
222 | { | ||
223 | struct termios tio; | ||
224 | |||
225 | /* open the device to be non-blocking (read will return immediatly) */ | ||
226 | serialPortFd = open(devicePath, O_RDWR | O_NOCTTY | O_NONBLOCK); | ||
227 | if (serialPortFd <0) | ||
228 | { | ||
229 | perror(devicePath); | ||
230 | printf("%s open failed\n",devicePath); | ||
231 | return(-1); | ||
232 | } | ||
233 | |||
234 | /* c-iflags | ||
235 | B115200 : set board rate to 115200 | ||
236 | CRTSCTS : HW flow control (disabled below) | ||
237 | CS8 : 8n1 (8bit,no parity,1 stopbit) | ||
238 | CLOCAL : local connection, no modem contol | ||
239 | CREAD : enable receiving characters*/ | ||
240 | tio.c_cflag = B38400 | /*CRTSCTS |*/ CS8 | CLOCAL | CREAD; | ||
241 | /* c-iflags | ||
242 | ICRNL : maps 0xD (CR) to 0x10 (LR), we do not want this. | ||
243 | IGNPAR : ignore bits with parity erros, I guess it is | ||
244 | better to ignStateore an erronious bit then interprit it incorrectly. */ | ||
245 | tio.c_iflag = IGNPAR & ~ICRNL; | ||
246 | tio.c_oflag = 0; | ||
247 | tio.c_lflag = 0; | ||
248 | |||
249 | tcflush(serialPortFd, TCIFLUSH); | ||
250 | tcsetattr(serialPortFd,TCSANOW,&tio); | ||
251 | |||
252 | return serialPortFd; | ||
253 | } | ||
254 | |||
255 | void zllSocClose( void ) | ||
256 | { | ||
257 | tcflush(serialPortFd, TCOFLUSH); | ||
258 | close(serialPortFd); | ||
259 | |||
260 | return; | ||
261 | } | ||
262 | |||
263 | /********************************************************************* | ||
264 | * @fn zllSocRegisterCallbacks | ||
265 | * | ||
266 | * @brief opens the serial port to the CC253x. | ||
267 | * | ||
268 | * @param devicePath - path to the UART device | ||
269 | * | ||
270 | * @return status | ||
271 | */ | ||
272 | void zllSocRegisterCallbacks( zllSocCallbacks_t zllSocCallbacks) | ||
273 | { | ||
274 | //copy the callback function pointers | ||
275 | memcpy(&zllSocCb, &zllSocCallbacks, sizeof(zllSocCallbacks_t)); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | |||
280 | /********************************************************************* | ||
281 | * @fn zllSocTouchLink | ||
282 | * | ||
283 | * @brief Send the touchLink command to the CC253x. | ||
284 | * | ||
285 | * @param none | ||
286 | * | ||
287 | * @return none | ||
288 | */ | ||
289 | void zllSocTouchLink(void) | ||
290 | { | ||
291 | uint8_t tlCmd[] = { | ||
292 | APPCMDHEADER(13) | ||
293 | 0x06, //Data Len | ||
294 | 0x02, //Address Mode | ||
295 | 0x00, //2dummy bytes | ||
296 | 0x00, | ||
297 | ZLL_MT_APP_RPC_CMD_TOUCHLINK, | ||
298 | 0x00, // | ||
299 | 0x00, // | ||
300 | 0x00 //FCS - fill in later | ||
301 | }; | ||
302 | |||
303 | calcFcs(tlCmd, sizeof(tlCmd)); | ||
304 | write(serialPortFd,tlCmd, sizeof(tlCmd)); | ||
305 | tcflush(serialPortFd, TCOFLUSH); | ||
306 | } | ||
307 | |||
308 | |||
309 | /********************************************************************* | ||
310 | * @fn zllSocResetToFn | ||
311 | * | ||
312 | * @brief Send the reset to factory new command to the CC253x. | ||
313 | * | ||
314 | * @param none | ||
315 | * | ||
316 | * @return none | ||
317 | */ | ||
318 | void zllSocResetToFn(void) | ||
319 | { | ||
320 | uint8_t tlCmd[] = { | ||
321 | APPCMDHEADER(13) | ||
322 | 0x06, //Data Len | ||
323 | 0x02, //Address Mode | ||
324 | 0x00, //2dummy bytes | ||
325 | 0x00, | ||
326 | ZLL_MT_APP_RPC_CMD_RESET_TO_FN, | ||
327 | 0x00, // | ||
328 | 0x00, // | ||
329 | 0x00 //FCS - fill in later | ||
330 | }; | ||
331 | |||
332 | calcFcs(tlCmd, sizeof(tlCmd)); | ||
333 | write(serialPortFd,tlCmd, sizeof(tlCmd)); | ||
334 | tcflush(serialPortFd, TCOFLUSH); | ||
335 | } | ||
336 | |||
337 | /********************************************************************* | ||
338 | * @fn zllSocSendResetToFn | ||
339 | * | ||
340 | * @brief Send the reset to factory new command to a ZLL device. | ||
341 | * | ||
342 | * @param none | ||
343 | * | ||
344 | * @return none | ||
345 | */ | ||
346 | void zllSocSendResetToFn(void) | ||
347 | { | ||
348 | uint8_t tlCmd[] = { | ||
349 | APPCMDHEADER(13) | ||
350 | 0x06, //Data Len | ||
351 | 0x02, //Address Mode | ||
352 | 0x00, //2dummy bytes | ||
353 | 0x00, | ||
354 | ZLL_MT_APP_RPC_CMD_SEND_RESET_TO_FN, | ||
355 | 0x00, // | ||
356 | 0x00, // | ||
357 | 0x00 //FCS - fill in later | ||
358 | }; | ||
359 | |||
360 | calcFcs(tlCmd, sizeof(tlCmd)); | ||
361 | write(serialPortFd,tlCmd, sizeof(tlCmd)); | ||
362 | tcflush(serialPortFd, TCOFLUSH); | ||
363 | } | ||
364 | |||
365 | /********************************************************************* | ||
366 | * @fn zllSocSetState | ||
367 | * | ||
368 | * @brief Send the on/off command to a ZLL light. | ||
369 | * | ||
370 | * @param state - 0: Off, 1: On. | ||
371 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
372 | * @param endpoint - endpoint of the Light. | ||
373 | * @param addrMode - Unicast or Group cast. | ||
374 | * | ||
375 | * @return none | ||
376 | */ | ||
377 | void zllSocSetState(uint8_t state, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
378 | { | ||
379 | uint8_t cmd[] = { | ||
380 | 0xFE, | ||
381 | 11, /*RPC payload Len */ | ||
382 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
383 | 0x00, /*MT_APP_MSG */ | ||
384 | 0x0B, /*Application Endpoint */ | ||
385 | (dstAddr & 0x00ff), | ||
386 | (dstAddr & 0xff00) >> 8, | ||
387 | endpoint, /*Dst EP */ | ||
388 | (ZCL_CLUSTER_ID_GEN_ON_OFF & 0x00ff), | ||
389 | (ZCL_CLUSTER_ID_GEN_ON_OFF & 0xff00) >> 8, | ||
390 | 0x04, //Data Len | ||
391 | addrMode, | ||
392 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
393 | transSeqNumber++, | ||
394 | (state ? 1:0), | ||
395 | 0x00 //FCS - fill in later | ||
396 | }; | ||
397 | |||
398 | calcFcs(cmd, sizeof(cmd)); | ||
399 | |||
400 | write(serialPortFd,cmd,sizeof(cmd)); | ||
401 | tcflush(serialPortFd, TCOFLUSH); | ||
402 | } | ||
403 | |||
404 | /********************************************************************* | ||
405 | * @fn zllSocSetLevel | ||
406 | * | ||
407 | * @brief Send the level command to a ZLL light. | ||
408 | * | ||
409 | * @param level - 0-128 = 0-100% | ||
410 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
411 | * @param endpoint - endpoint of the Light. | ||
412 | * @param addrMode - Unicast or Group cast. | ||
413 | * | ||
414 | * @return none | ||
415 | */ | ||
416 | void zllSocSetLevel(uint8_t level, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
417 | { | ||
418 | uint8_t cmd[] = { | ||
419 | 0xFE, | ||
420 | 14, //RPC payload Len | ||
421 | 0x29, //MT_RPC_CMD_AREQ + MT_RPC_SYS_APP | ||
422 | 0x00, //MT_APP_MSG | ||
423 | 0x0B, //Application Endpoint | ||
424 | (dstAddr & 0x00ff), | ||
425 | (dstAddr & 0xff00) >> 8, | ||
426 | endpoint, //Dst EP | ||
427 | (ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL & 0x00ff), | ||
428 | (ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL & 0xff00) >> 8, | ||
429 | 0x07, //Data Len | ||
430 | addrMode, | ||
431 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
432 | transSeqNumber++, | ||
433 | COMMAND_LEVEL_MOVE_TO_LEVEL, | ||
434 | (level & 0xff), | ||
435 | (time & 0xff), | ||
436 | (time & 0xff00) >> 8, | ||
437 | 0x00 //FCS - fill in later | ||
438 | }; | ||
439 | |||
440 | calcFcs(cmd, sizeof(cmd)); | ||
441 | |||
442 | write(serialPortFd,cmd,sizeof(cmd)); | ||
443 | tcflush(serialPortFd, TCOFLUSH); | ||
444 | } | ||
445 | |||
446 | /********************************************************************* | ||
447 | * @fn zllSocSetHue | ||
448 | * | ||
449 | * @brief Send the hue command to a ZLL light. | ||
450 | * | ||
451 | * @param hue - 0-128 represent the 360Deg hue color wheel : 0=red, 42=blue, 85=green | ||
452 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
453 | * @param endpoint - endpoint of the Light. | ||
454 | * @param addrMode - Unicast or Group cast. | ||
455 | * | ||
456 | * @return none | ||
457 | */ | ||
458 | void zllSocSetHue(uint8_t hue, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
459 | { | ||
460 | uint8_t cmd[] = { | ||
461 | 0xFE, | ||
462 | 15, //RPC payload Len | ||
463 | 0x29, //MT_RPC_CMD_AREQ + MT_RPC_SYS_APP | ||
464 | 0x00, //MT_APP_MSG | ||
465 | 0x0B, //Application Endpoint | ||
466 | (dstAddr & 0x00ff), | ||
467 | (dstAddr & 0xff00) >> 8, | ||
468 | endpoint, //Dst EP | ||
469 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0x00ff), | ||
470 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0xff00) >> 8, | ||
471 | 0x08, //Data Len | ||
472 | addrMode, | ||
473 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
474 | transSeqNumber++, | ||
475 | COMMAND_LIGHTING_MOVE_TO_HUE, | ||
476 | (hue & 0xff), | ||
477 | 0x00, //Move with shortest distance | ||
478 | (time & 0xff), | ||
479 | (time & 0xff00) >> 8, | ||
480 | 0x00 //FCS - fill in later | ||
481 | }; | ||
482 | |||
483 | calcFcs(cmd, sizeof(cmd)); | ||
484 | write(serialPortFd,cmd,sizeof(cmd)); | ||
485 | tcflush(serialPortFd, TCOFLUSH); | ||
486 | } | ||
487 | |||
488 | /********************************************************************* | ||
489 | * @fn zllSocSetSat | ||
490 | * | ||
491 | * @brief Send the satuartion command to a ZLL light. | ||
492 | * | ||
493 | * @param sat - 0-128 : 0=white, 128: fully saturated color | ||
494 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
495 | * @param endpoint - endpoint of the Light. | ||
496 | * @param addrMode - Unicast or Group cast. | ||
497 | * | ||
498 | * @return none | ||
499 | */ | ||
500 | void zllSocSetSat(uint8_t sat, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
501 | { | ||
502 | uint8_t cmd[] = { | ||
503 | 0xFE, | ||
504 | 14, //RPC payload Len | ||
505 | 0x29, //MT_RPC_CMD_AREQ + MT_RPC_SYS_APP | ||
506 | 0x00, //MT_APP_MSG | ||
507 | 0x0B, //Application Endpoint | ||
508 | (dstAddr & 0x00ff), | ||
509 | (dstAddr & 0xff00) >> 8, | ||
510 | endpoint, //Dst EP | ||
511 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0x00ff), | ||
512 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0xff00) >> 8, | ||
513 | 0x07, //Data Len | ||
514 | addrMode, | ||
515 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
516 | transSeqNumber++, | ||
517 | COMMAND_LIGHTING_MOVE_TO_SATURATION, | ||
518 | (sat & 0xff), | ||
519 | (time & 0xff), | ||
520 | (time & 0xff00) >> 8, | ||
521 | 0x00 //FCS - fill in later | ||
522 | }; | ||
523 | |||
524 | calcFcs(cmd, sizeof(cmd)); | ||
525 | write(serialPortFd,cmd,sizeof(cmd)); | ||
526 | tcflush(serialPortFd, TCOFLUSH); | ||
527 | } | ||
528 | |||
529 | /********************************************************************* | ||
530 | * @fn zllSocSetHueSat | ||
531 | * | ||
532 | * @brief Send the hue and satuartion command to a ZLL light. | ||
533 | * | ||
534 | * @param hue - 0-128 represent the 360Deg hue color wheel : 0=red, 42=blue, 85=green | ||
535 | * @param sat - 0-128 : 0=white, 128: fully saturated color | ||
536 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
537 | * @param endpoint - endpoint of the Light. | ||
538 | * @param addrMode - Unicast or Group cast. | ||
539 | * | ||
540 | * @return none | ||
541 | */ | ||
542 | void zllSocSetHueSat(uint8_t hue, uint8_t sat, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
543 | { | ||
544 | uint8_t cmd[] = { | ||
545 | 0xFE, | ||
546 | 15, //RPC payload Len | ||
547 | 0x29, //MT_RPC_CMD_AREQ + MT_RPC_SYS_APP | ||
548 | 0x00, //MT_APP_MSG | ||
549 | 0x0B, //Application Endpoint | ||
550 | (dstAddr & 0x00ff), | ||
551 | (dstAddr & 0xff00) >> 8, | ||
552 | endpoint, //Dst EP | ||
553 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0x00ff), | ||
554 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0xff00) >> 8, | ||
555 | 0x08, //Data Len | ||
556 | addrMode, | ||
557 | 0x01, //ZCL Header Frame Control | ||
558 | transSeqNumber++, | ||
559 | 0x06, //ZCL Header Frame Command (COMMAND_LEVEL_MOVE_TO_HUE_AND_SAT) | ||
560 | hue, //HUE - fill it in later | ||
561 | sat, //SAT - fill it in later | ||
562 | (time & 0xff), | ||
563 | (time & 0xff00) >> 8, | ||
564 | 0x00 //fcs | ||
565 | }; | ||
566 | |||
567 | calcFcs(cmd, sizeof(cmd)); | ||
568 | write(serialPortFd,cmd,sizeof(cmd)); | ||
569 | tcflush(serialPortFd, TCOFLUSH); | ||
570 | } | ||
571 | |||
572 | /********************************************************************* | ||
573 | * @fn zllSocAddGroup | ||
574 | * | ||
575 | * @brief Add Group. | ||
576 | * | ||
577 | * @param groupId - Group ID of the Scene. | ||
578 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
579 | * @param endpoint - endpoint of the Light. | ||
580 | * @param addrMode - Unicast or Group cast. | ||
581 | * | ||
582 | * @return none | ||
583 | */ | ||
584 | void zllSocAddGroup(uint16_t groupId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
585 | { | ||
586 | uint8_t cmd[] = { | ||
587 | 0xFE, | ||
588 | 14, /*RPC payload Len */ | ||
589 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
590 | 0x00, /*MT_APP_MSG */ | ||
591 | 0x0B, /*Application Endpoint */ | ||
592 | (dstAddr & 0x00ff), | ||
593 | (dstAddr & 0xff00) >> 8, | ||
594 | endpoint, /*Dst EP */ | ||
595 | (ZCL_CLUSTER_ID_GEN_GROUPS & 0x00ff), | ||
596 | (ZCL_CLUSTER_ID_GEN_GROUPS & 0xff00) >> 8, | ||
597 | 0x07, //Data Len | ||
598 | addrMode, | ||
599 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
600 | transSeqNumber++, | ||
601 | COMMAND_GROUP_ADD, | ||
602 | (groupId & 0x00ff), | ||
603 | (groupId & 0xff00) >> 8, | ||
604 | 0, //Null group name - Group Name not pushed to the devices | ||
605 | 0x00 //FCS - fill in later | ||
606 | }; | ||
607 | |||
608 | printf("zllSocAddGroup: dstAddr 0x%x\n", dstAddr); | ||
609 | |||
610 | calcFcs(cmd, sizeof(cmd)); | ||
611 | |||
612 | write(serialPortFd,cmd,sizeof(cmd)); | ||
613 | tcflush(serialPortFd, TCOFLUSH); | ||
614 | } | ||
615 | |||
616 | /********************************************************************* | ||
617 | * @fn zllSocStoreScene | ||
618 | * | ||
619 | * @brief Store Scene. | ||
620 | * | ||
621 | * @param groupId - Group ID of the Scene. | ||
622 | * @param sceneId - Scene ID of the Scene. | ||
623 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
624 | * @param endpoint - endpoint of the Light. | ||
625 | * @param addrMode - Unicast or Group cast. | ||
626 | * | ||
627 | * @return none | ||
628 | */ | ||
629 | void zllSocStoreScene(uint16_t groupId, uint8_t sceneId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
630 | { | ||
631 | uint8_t cmd[] = { | ||
632 | 0xFE, | ||
633 | 14, /*RPC payload Len */ | ||
634 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
635 | 0x00, /*MT_APP_MSG */ | ||
636 | 0x0B, /*Application Endpoint */ | ||
637 | (dstAddr & 0x00ff), | ||
638 | (dstAddr & 0xff00) >> 8, | ||
639 | endpoint, /*Dst EP */ | ||
640 | (ZCL_CLUSTER_ID_GEN_SCENES & 0x00ff), | ||
641 | (ZCL_CLUSTER_ID_GEN_SCENES & 0xff00) >> 8, | ||
642 | 0x07, //Data Len | ||
643 | addrMode, | ||
644 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
645 | transSeqNumber++, | ||
646 | COMMAND_SCENE_STORE, | ||
647 | (groupId & 0x00ff), | ||
648 | (groupId & 0xff00) >> 8, | ||
649 | sceneId++, | ||
650 | 0x00 //FCS - fill in later | ||
651 | }; | ||
652 | |||
653 | calcFcs(cmd, sizeof(cmd)); | ||
654 | |||
655 | write(serialPortFd,cmd,sizeof(cmd)); | ||
656 | tcflush(serialPortFd, TCOFLUSH); | ||
657 | } | ||
658 | |||
659 | /********************************************************************* | ||
660 | * @fn zllSocRecallScene | ||
661 | * | ||
662 | * @brief Recall Scene. | ||
663 | * | ||
664 | * @param groupId - Group ID of the Scene. | ||
665 | * @param sceneId - Scene ID of the Scene. | ||
666 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be controled. | ||
667 | * @param endpoint - endpoint of the Light. | ||
668 | * @param addrMode - Unicast or Group cast. | ||
669 | |||
670 | * @return none | ||
671 | */ | ||
672 | void zllSocRecallScene(uint16_t groupId, uint8_t sceneId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
673 | { | ||
674 | uint8_t cmd[] = { | ||
675 | 0xFE, | ||
676 | 14, /*RPC payload Len */ | ||
677 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
678 | 0x00, /*MT_APP_MSG */ | ||
679 | 0x0B, /*Application Endpoint */ | ||
680 | (dstAddr & 0x00ff), | ||
681 | (dstAddr & 0xff00) >> 8, | ||
682 | endpoint, /*Dst EP */ | ||
683 | (ZCL_CLUSTER_ID_GEN_SCENES & 0x00ff), | ||
684 | (ZCL_CLUSTER_ID_GEN_SCENES & 0xff00) >> 8, | ||
685 | 0x07, //Data Len | ||
686 | addrMode, | ||
687 | 0x01, //0x01 ZCL frame control field. (send to the light cluster only) | ||
688 | transSeqNumber++, | ||
689 | COMMAND_SCENE_RECALL, | ||
690 | (groupId & 0x00ff), | ||
691 | (groupId & 0xff00) >> 8, | ||
692 | sceneId++, | ||
693 | 0x00 //FCS - fill in later | ||
694 | }; | ||
695 | |||
696 | calcFcs(cmd, sizeof(cmd)); | ||
697 | |||
698 | write(serialPortFd,cmd,sizeof(cmd)); | ||
699 | tcflush(serialPortFd, TCOFLUSH); | ||
700 | } | ||
701 | |||
702 | /********************************************************************* | ||
703 | * @fn zllSocGetState | ||
704 | * | ||
705 | * @brief Send the get state command to a ZLL light. | ||
706 | * | ||
707 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be sent the command. | ||
708 | * @param endpoint - endpoint of the Light. | ||
709 | * @param addrMode - Unicast or Group cast. | ||
710 | * | ||
711 | * @return none | ||
712 | */ | ||
713 | void zllSocGetState(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
714 | { | ||
715 | uint8_t cmd[] = { | ||
716 | 0xFE, | ||
717 | 13, /*RPC payload Len */ | ||
718 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
719 | 0x00, /*MT_APP_MSG */ | ||
720 | 0x0B, /*Application Endpoint */ | ||
721 | (dstAddr & 0x00ff), | ||
722 | (dstAddr & 0xff00) >> 8, | ||
723 | endpoint, /*Dst EP */ | ||
724 | (ZCL_CLUSTER_ID_GEN_ON_OFF & 0x00ff), | ||
725 | (ZCL_CLUSTER_ID_GEN_ON_OFF & 0xff00) >> 8, | ||
726 | 0x06, //Data Len | ||
727 | addrMode, | ||
728 | 0x00, //0x00 ZCL frame control field. not specific to a cluster (i.e. a SCL founadation command) | ||
729 | transSeqNumber++, | ||
730 | ZCL_CMD_READ, | ||
731 | (ATTRID_ON_OFF & 0x00ff), | ||
732 | (ATTRID_ON_OFF & 0xff00) >> 8, | ||
733 | 0x00 //FCS - fill in later | ||
734 | }; | ||
735 | |||
736 | calcFcs(cmd, sizeof(cmd)); | ||
737 | |||
738 | write(serialPortFd,cmd,sizeof(cmd)); | ||
739 | tcflush(serialPortFd, TCOFLUSH); | ||
740 | } | ||
741 | |||
742 | /********************************************************************* | ||
743 | * @fn zllSocGetLevel | ||
744 | * | ||
745 | * @brief Send the get level command to a ZLL light. | ||
746 | * | ||
747 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be sent the command. | ||
748 | * @param endpoint - endpoint of the Light. | ||
749 | * @param addrMode - Unicast or Group cast. | ||
750 | * | ||
751 | * @return none | ||
752 | */ | ||
753 | void zllSocGetLevel(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
754 | { | ||
755 | uint8_t cmd[] = { | ||
756 | 0xFE, | ||
757 | 13, /*RPC payload Len */ | ||
758 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
759 | 0x00, /*MT_APP_MSG */ | ||
760 | 0x0B, /*Application Endpoint */ | ||
761 | (dstAddr & 0x00ff), | ||
762 | (dstAddr & 0xff00) >> 8, | ||
763 | endpoint, /*Dst EP */ | ||
764 | (ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL & 0x00ff), | ||
765 | (ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL & 0xff00) >> 8, | ||
766 | 0x06, //Data Len | ||
767 | addrMode, | ||
768 | 0x00, //0x00 ZCL frame control field. not specific to a cluster (i.e. a SCL founadation command) | ||
769 | transSeqNumber++, | ||
770 | ZCL_CMD_READ, | ||
771 | (ATTRID_LEVEL_CURRENT_LEVEL & 0x00ff), | ||
772 | (ATTRID_LEVEL_CURRENT_LEVEL & 0xff00) >> 8, | ||
773 | 0x00 //FCS - fill in later | ||
774 | }; | ||
775 | |||
776 | calcFcs(cmd, sizeof(cmd)); | ||
777 | |||
778 | write(serialPortFd,cmd,sizeof(cmd)); | ||
779 | tcflush(serialPortFd, TCOFLUSH); | ||
780 | } | ||
781 | |||
782 | /********************************************************************* | ||
783 | * @fn zllSocGetHue | ||
784 | * | ||
785 | * @brief Send the get hue command to a ZLL light. | ||
786 | * | ||
787 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be sent the command. | ||
788 | * @param endpoint - endpoint of the Light. | ||
789 | * @param addrMode - Unicast or Group cast. | ||
790 | * | ||
791 | * @return none | ||
792 | */ | ||
793 | void zllSocGetHue(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
794 | { | ||
795 | uint8_t cmd[] = { | ||
796 | 0xFE, | ||
797 | 13, /*RPC payload Len */ | ||
798 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
799 | 0x00, /*MT_APP_MSG */ | ||
800 | 0x0B, /*Application Endpoint */ | ||
801 | (dstAddr & 0x00ff), | ||
802 | (dstAddr & 0xff00) >> 8, | ||
803 | endpoint, /*Dst EP */ | ||
804 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0x00ff), | ||
805 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0xff00) >> 8, | ||
806 | 0x06, //Data Len | ||
807 | addrMode, | ||
808 | 0x00, //0x00 ZCL frame control field. not specific to a cluster (i.e. a SCL founadation command) | ||
809 | transSeqNumber++, | ||
810 | ZCL_CMD_READ, | ||
811 | (ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_HUE & 0x00ff), | ||
812 | (ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_HUE & 0xff00) >> 8, | ||
813 | 0x00 //FCS - fill in later | ||
814 | }; | ||
815 | |||
816 | calcFcs(cmd, sizeof(cmd)); | ||
817 | |||
818 | write(serialPortFd,cmd,sizeof(cmd)); | ||
819 | tcflush(serialPortFd, TCOFLUSH); | ||
820 | } | ||
821 | |||
822 | /********************************************************************* | ||
823 | * @fn zllSocGetSat | ||
824 | * | ||
825 | * @brief Send the get saturation command to a ZLL light. | ||
826 | * | ||
827 | * @param dstAddr - Nwk Addr or Group ID of the Light(s) to be sent the command. | ||
828 | * @param endpoint - endpoint of the Light. | ||
829 | * @param addrMode - Unicast or Group cast. | ||
830 | * | ||
831 | * @return none | ||
832 | */ | ||
833 | void zllSocGetSat(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode) | ||
834 | { | ||
835 | uint8_t cmd[] = { | ||
836 | 0xFE, | ||
837 | 13, /*RPC payload Len */ | ||
838 | 0x29, /*MT_RPC_CMD_AREQ + MT_RPC_SYS_APP */ | ||
839 | 0x00, /*MT_APP_MSG */ | ||
840 | 0x0B, /*Application Endpoint */ | ||
841 | (dstAddr & 0x00ff), | ||
842 | (dstAddr & 0xff00) >> 8, | ||
843 | endpoint, /*Dst EP */ | ||
844 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0x00ff), | ||
845 | (ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL & 0xff00) >> 8, | ||
846 | 0x06, //Data Len | ||
847 | addrMode, | ||
848 | 0x00, //0x00 ZCL frame control field. not specific to a cluster (i.e. a SCL founadation command) | ||
849 | transSeqNumber++, | ||
850 | ZCL_CMD_READ, | ||
851 | (ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_SATURATION & 0x00ff), | ||
852 | (ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_SATURATION & 0xff00) >> 8, | ||
853 | 0x00 //FCS - fill in later | ||
854 | }; | ||
855 | |||
856 | calcFcs(cmd, sizeof(cmd)); | ||
857 | |||
858 | write(serialPortFd,cmd,sizeof(cmd)); | ||
859 | tcflush(serialPortFd, TCOFLUSH); | ||
860 | } | ||
861 | |||
862 | /************************************************************************************************* | ||
863 | * @fn processRpcSysAppTlInd() | ||
864 | * | ||
865 | * @brief process the TL Indication from the ZLL controller | ||
866 | * | ||
867 | * @param none | ||
868 | * | ||
869 | * @return length of current Rx Buffer | ||
870 | *************************************************************************************************/ | ||
871 | void processRpcSysAppTlInd(uint8_t *TlIndBuff) | ||
872 | { | ||
873 | epInfo_t epInfo; | ||
874 | |||
875 | epInfo.nwkAddr = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
876 | TlIndBuff+=2; | ||
877 | epInfo.endpoint = *TlIndBuff++; | ||
878 | epInfo.profileID = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
879 | TlIndBuff+=2; | ||
880 | epInfo.deviceID = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
881 | TlIndBuff+=2; | ||
882 | epInfo.version = *TlIndBuff++; | ||
883 | epInfo.status = *TlIndBuff++; | ||
884 | |||
885 | if(zllSocCb.pfnTlIndicationCb) | ||
886 | { | ||
887 | zllSocCb.pfnTlIndicationCb(&epInfo); | ||
888 | } | ||
889 | } | ||
890 | |||
891 | /************************************************************************************************* | ||
892 | * @fn processRpcSysAppNewDevInd() | ||
893 | * | ||
894 | * @brief process the New Device Indication from the ZLL controller | ||
895 | * | ||
896 | * @param none | ||
897 | * | ||
898 | * @return length of current Rx Buffer | ||
899 | *************************************************************************************************/ | ||
900 | void processRpcSysAppNewDevInd(uint8_t *TlIndBuff) | ||
901 | { | ||
902 | epInfo_t epInfo; | ||
903 | |||
904 | |||
905 | epInfo.nwkAddr = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
906 | TlIndBuff+=2; | ||
907 | epInfo.endpoint = *TlIndBuff++; | ||
908 | epInfo.profileID = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
909 | TlIndBuff+=2; | ||
910 | epInfo.deviceID = BUILD_UINT16(TlIndBuff[0], TlIndBuff[1]); | ||
911 | TlIndBuff+=2; | ||
912 | epInfo.version = *TlIndBuff++; | ||
913 | epInfo.status = *TlIndBuff++; | ||
914 | |||
915 | printf("processRpcSysAppNewDevInd: %x:%x\n", epInfo.nwkAddr, epInfo.endpoint); | ||
916 | if(zllSocCb.pfnNewDevIndicationCb) | ||
917 | { | ||
918 | zllSocCb.pfnNewDevIndicationCb(&epInfo); | ||
919 | } | ||
920 | } | ||
921 | |||
922 | /************************************************************************************************* | ||
923 | * @fn processRpcSysAppZclRsp() | ||
924 | * | ||
925 | * @brief process the ZCL Rsp from the ZLL controller | ||
926 | * | ||
927 | * @param none | ||
928 | * | ||
929 | * @return length of current Rx Buffer | ||
930 | *************************************************************************************************/ | ||
931 | void processRpcSysAppZclRsp(uint8_t *zclRspBuff) | ||
932 | { | ||
933 | uint8_t zclHdrLen = 3; | ||
934 | uint16_t nwkAddr, clusterID; | ||
935 | uint8_t endpoint, appEP, zclFrameLen, transSeqNum, commandID, zclFrameFrameControl; | ||
936 | |||
937 | //This is a ZCL response | ||
938 | appEP = *zclRspBuff++; | ||
939 | nwkAddr = BUILD_UINT16(zclRspBuff[0], zclRspBuff[1]); | ||
940 | zclRspBuff+=2; | ||
941 | |||
942 | endpoint = *zclRspBuff++; | ||
943 | clusterID = BUILD_UINT16(zclRspBuff[0], zclRspBuff[1]); | ||
944 | zclRspBuff+=2; | ||
945 | |||
946 | zclFrameLen = *zclRspBuff++; | ||
947 | zclFrameFrameControl = *zclRspBuff++; | ||
948 | //is it manufacturer specific | ||
949 | if ( zclFrameFrameControl & (1 <<2) ) | ||
950 | { | ||
951 | //currently not supported shown for reference | ||
952 | uint16_t ManSpecCode; | ||
953 | //manu spec code | ||
954 | ManSpecCode = BUILD_UINT16(zclRspBuff[0], zclRspBuff[1]); | ||
955 | zclRspBuff+=2; | ||
956 | //Manufacturer specif commands have 2 extra byte in te header | ||
957 | zclHdrLen+=2; | ||
958 | } | ||
959 | |||
960 | transSeqNum = *zclRspBuff++; | ||
961 | commandID = *zclRspBuff++; | ||
962 | |||
963 | if(commandID == ZCL_CMD_READ_RSP) | ||
964 | { | ||
965 | uint16_t attrID; | ||
966 | uint8_t status; | ||
967 | |||
968 | attrID = BUILD_UINT16(zclRspBuff[0], zclRspBuff[1]); | ||
969 | zclRspBuff+=2; | ||
970 | status = *zclRspBuff++; | ||
971 | //skip over data type; | ||
972 | zclRspBuff++; | ||
973 | |||
974 | if( (clusterID == ZCL_CLUSTER_ID_GEN_ON_OFF) && (attrID == ATTRID_ON_OFF) ) | ||
975 | { | ||
976 | if(zllSocCb.pfnZclGetStateCb) | ||
977 | { | ||
978 | uint8_t state = zclRspBuff[0]; | ||
979 | zllSocCb.pfnZclGetStateCb(state, nwkAddr, endpoint); | ||
980 | } | ||
981 | } | ||
982 | else if( (clusterID == ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL) && (attrID == ATTRID_LEVEL_CURRENT_LEVEL) ) | ||
983 | { | ||
984 | if(zllSocCb.pfnZclGetLevelCb) | ||
985 | { | ||
986 | uint8_t level = zclRspBuff[0]; | ||
987 | zllSocCb.pfnZclGetLevelCb(level, nwkAddr, endpoint); | ||
988 | } | ||
989 | } | ||
990 | else if( (clusterID == ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL) && (attrID == ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_HUE) ) | ||
991 | { | ||
992 | if(zllSocCb.pfnZclGetHueCb) | ||
993 | { | ||
994 | uint8_t hue = zclRspBuff[0]; | ||
995 | zllSocCb.pfnZclGetHueCb(hue, nwkAddr, endpoint); | ||
996 | } | ||
997 | } | ||
998 | else if( (clusterID == ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL) && (attrID == ATTRID_LIGHTING_COLOR_CONTROL_CURRENT_SATURATION) ) | ||
999 | { | ||
1000 | if(zllSocCb.pfnZclGetSatCb) | ||
1001 | { | ||
1002 | uint8_t sat = zclRspBuff[0]; | ||
1003 | zllSocCb.pfnZclGetSatCb(sat, nwkAddr, endpoint); | ||
1004 | } | ||
1005 | } | ||
1006 | else | ||
1007 | { | ||
1008 | //unsupported ZCL Read Rsp | ||
1009 | printf("processRpcSysAppZclRsp: Unsupported ZCL Rsp"); | ||
1010 | } | ||
1011 | } | ||
1012 | else | ||
1013 | { | ||
1014 | //unsupported ZCL Rsp | ||
1015 | printf("processRpcSysAppZclRsp: Unsupported ZCL Rsp");; | ||
1016 | } | ||
1017 | |||
1018 | return; | ||
1019 | } | ||
1020 | |||
1021 | /************************************************************************************************* | ||
1022 | * @fn processRpcSysApp() | ||
1023 | * | ||
1024 | * @brief read and process the RPC App message from the ZLL controller | ||
1025 | * | ||
1026 | * @param none | ||
1027 | * | ||
1028 | * @return length of current Rx Buffer | ||
1029 | *************************************************************************************************/ | ||
1030 | void processRpcSysApp(uint8_t *rpcBuff) | ||
1031 | { | ||
1032 | if( rpcBuff[1] == MT_APP_ZLL_TL_IND ) | ||
1033 | { | ||
1034 | processRpcSysAppTlInd(&rpcBuff[2]); | ||
1035 | } | ||
1036 | else if( rpcBuff[1] == MT_APP_ZLL_NEW_DEV_IND ) | ||
1037 | { | ||
1038 | processRpcSysAppNewDevInd(&rpcBuff[2]); | ||
1039 | } | ||
1040 | else if( rpcBuff[1] == MT_APP_RSP ) | ||
1041 | { | ||
1042 | processRpcSysAppZclRsp(&rpcBuff[2]); | ||
1043 | } | ||
1044 | else if( rpcBuff[1] == 0 ) | ||
1045 | { | ||
1046 | if( rpcBuff[2] == 0) | ||
1047 | { | ||
1048 | printf("processRpcSysApp: Command Received Successfully\n\n"); | ||
1049 | } | ||
1050 | else | ||
1051 | { | ||
1052 | printf("processRpcSysApp: Command Error\n\n"); | ||
1053 | } | ||
1054 | } | ||
1055 | else | ||
1056 | { | ||
1057 | printf("processRpcSysApp: Unsupported MT App Msg\n"); | ||
1058 | } | ||
1059 | |||
1060 | return; | ||
1061 | |||
1062 | } | ||
1063 | |||
1064 | /************************************************************************************************* | ||
1065 | * @fn processRpcSysDbg() | ||
1066 | * | ||
1067 | * @brief read and process the RPC debug message from the ZLL controller | ||
1068 | * | ||
1069 | * @param none | ||
1070 | * | ||
1071 | * @return length of current Rx Buffer | ||
1072 | *************************************************************************************************/ | ||
1073 | void processRpcSysDbg(uint8_t *rpcBuff) | ||
1074 | { | ||
1075 | if( rpcBuff[1] == MT_DEBUG_MSG ) | ||
1076 | { | ||
1077 | //we got a debug string | ||
1078 | printf("lcd_debug message from zll controller: %s\n", (char*) &(rpcBuff[2])); | ||
1079 | } | ||
1080 | else if( rpcBuff[1] == 0 ) | ||
1081 | { | ||
1082 | if( rpcBuff[2] == 0) | ||
1083 | { | ||
1084 | printf("processRpcSysDbg: Command Received Successfully\n\n"); | ||
1085 | } | ||
1086 | else | ||
1087 | { | ||
1088 | printf("processRpcSysDbg: Command Error\n\n"); | ||
1089 | } | ||
1090 | } | ||
1091 | else | ||
1092 | { | ||
1093 | printf("processRpcSysDbg: Unsupported MT App Msg\n"); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /************************************************************************************************* | ||
1099 | * @fn zllSocProcessRpc() | ||
1100 | * | ||
1101 | * @brief read and process the RPC from the ZLL controller | ||
1102 | * | ||
1103 | * @param none | ||
1104 | * | ||
1105 | * @return length of current Rx Buffer | ||
1106 | *************************************************************************************************/ | ||
1107 | void zllSocProcessRpc (void) | ||
1108 | { | ||
1109 | uint8_t rpcLen, bytesRead, sofByte, *rpcBuff, rpcBuffIdx; | ||
1110 | static uint8_t retryAttempts = 0; | ||
1111 | |||
1112 | //read first byte and check it is a SOF | ||
1113 | read(serialPortFd, &sofByte, 1); | ||
1114 | if ( sofByte == MT_RPC_SOF ) | ||
1115 | { | ||
1116 | retryAttempts = 0; | ||
1117 | |||
1118 | //read len | ||
1119 | bytesRead = read(serialPortFd, &rpcLen, 1); | ||
1120 | |||
1121 | if( bytesRead == 1) | ||
1122 | { | ||
1123 | //allocating RPC payload (+ cmd0, cmd1 and fcs) | ||
1124 | rpcLen += 3; | ||
1125 | |||
1126 | rpcBuff = malloc(rpcLen); | ||
1127 | |||
1128 | //non blocking read, so we need to wait for the rpc to be read | ||
1129 | rpcBuffIdx = 0; | ||
1130 | while(rpcLen > 0) | ||
1131 | { | ||
1132 | //read rpc | ||
1133 | bytesRead = read(serialPortFd, &(rpcBuff[rpcBuffIdx]), rpcLen); | ||
1134 | |||
1135 | //check for error | ||
1136 | if( bytesRead > rpcLen) | ||
1137 | { | ||
1138 | //there was an error | ||
1139 | //printf("zllSocProcessRpc: read of %d bytes failed - %s\n", rpcLen, strerror(errno) ); | ||
1140 | |||
1141 | if( retryAttempts++ < 5 ) | ||
1142 | { | ||
1143 | //sleep for 10ms | ||
1144 | usleep(10000); | ||
1145 | //try again | ||
1146 | bytesRead = 0; | ||
1147 | } | ||
1148 | else | ||
1149 | { | ||
1150 | //something went wrong. | ||
1151 | printf("zllSocProcessRpc: failed\n"); | ||
1152 | return; | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | rpcLen -= bytesRead; | ||
1157 | rpcBuffIdx += bytesRead; | ||
1158 | } | ||
1159 | |||
1160 | //Read CMD0 | ||
1161 | switch (rpcBuff[0] & MT_RPC_SUBSYSTEM_MASK) | ||
1162 | { | ||
1163 | case MT_RPC_SYS_DBG: | ||
1164 | { | ||
1165 | processRpcSysDbg(rpcBuff); | ||
1166 | break; | ||
1167 | } | ||
1168 | case MT_RPC_SYS_APP: | ||
1169 | { | ||
1170 | processRpcSysApp(rpcBuff); | ||
1171 | break; | ||
1172 | } | ||
1173 | default: | ||
1174 | { | ||
1175 | printf("zllSocProcessRpc: CMD0:%x, CMD1:%x, not handled\n", rpcBuff[0], rpcBuff[1] ); | ||
1176 | break; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | free(rpcBuff); | ||
1181 | } | ||
1182 | else | ||
1183 | { | ||
1184 | printf("zllSocProcessRpc: No valid Start Of Frame found\n"); | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | return; | ||
1189 | } | ||
1190 | |||
diff --git a/zllSocCmd.h b/zllSocCmd.h new file mode 100644 index 0000000..3b370b0 --- /dev/null +++ b/zllSocCmd.h | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * zllSocCmd.h | ||
3 | * | ||
4 | * This module contains the API for the zll SoC Host Interface. | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef ZLLSOCCMD_H | ||
40 | #define ZLLSOCCMD_H | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" | ||
44 | { | ||
45 | #endif | ||
46 | |||
47 | #include <stdint.h> | ||
48 | |||
49 | /********************************************************************/ | ||
50 | // ZLL Soc Types | ||
51 | |||
52 | // Endpoint information record entry | ||
53 | typedef struct | ||
54 | { | ||
55 | uint16_t nwkAddr; // Network address | ||
56 | uint8_t endpoint; // Endpoint identifier | ||
57 | uint16_t profileID; // Profile identifier | ||
58 | uint16_t deviceID; // Device identifier | ||
59 | uint8_t version; // Version | ||
60 | char* deviceName; | ||
61 | uint8_t status; | ||
62 | } epInfo_t; | ||
63 | |||
64 | typedef uint8_t (*zllSocTlIndicationCb_t)(epInfo_t *epInfo); | ||
65 | typedef uint8_t (*zllNewDevIndicationCb_t)(epInfo_t *epInfo); | ||
66 | typedef uint8_t (*zllSocZclGetStateCb_t)(uint8_t state, uint16_t nwkAddr, uint8_t endpoint); | ||
67 | typedef uint8_t (*zllSocZclGetLevelCb_t)(uint8_t level, uint16_t nwkAddr, uint8_t endpoint); | ||
68 | typedef uint8_t (*zllSocZclGetHueCb_t)(uint8_t hue, uint16_t nwkAddr, uint8_t endpoint); | ||
69 | typedef uint8_t (*zllSocZclGetSatCb_t)(uint8_t sat, uint16_t nwkAddr, uint8_t endpoint); | ||
70 | |||
71 | |||
72 | typedef struct | ||
73 | { | ||
74 | zllSocTlIndicationCb_t pfnTlIndicationCb; // TouchLink Indication callback | ||
75 | zllNewDevIndicationCb_t pfnNewDevIndicationCb; // New device Indication callback | ||
76 | zllSocZclGetStateCb_t pfnZclGetStateCb; // ZCL response callback for get State | ||
77 | zllSocZclGetLevelCb_t pfnZclGetLevelCb; // ZCL response callback for get Level | ||
78 | zllSocZclGetHueCb_t pfnZclGetHueCb; // ZCL response callback for get Hue | ||
79 | zllSocZclGetSatCb_t pfnZclGetSatCb; // ZCL response callback for get Sat | ||
80 | } zllSocCallbacks_t; | ||
81 | |||
82 | /********************************************************************/ | ||
83 | // ZLL Soc API | ||
84 | |||
85 | //configuration API's | ||
86 | int32_t zllSocOpen( char *devicePath ); | ||
87 | void zllSocRegisterCallbacks( zllSocCallbacks_t zllSocCallbacks); | ||
88 | void zllSocClose( void ); | ||
89 | void zllSocProcessRpc (void); | ||
90 | |||
91 | //ZLL API's | ||
92 | void zllSocTouchLink(void); | ||
93 | void zllSocResetToFn(void); | ||
94 | void zllSocSendResetToFn(void); | ||
95 | //ZCL Set API's | ||
96 | void zllSocSetState(uint8_t state, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
97 | void zllSocSetLevel(uint8_t level, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
98 | void zllSocSetHue(uint8_t hue, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
99 | void zllSocSetSat(uint8_t sat, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
100 | void zllSocSetHueSat(uint8_t hue, uint8_t sat, uint16_t time, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
101 | void zllSocAddGroup(uint16_t groupId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
102 | void zllSocStoreScene(uint16_t groupId, uint8_t sceneId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
103 | void zllSocRecallScene(uint16_t groupId, uint8_t sceneId, uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
104 | //ZCL Get API's | ||
105 | void zllSocGetState(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
106 | void zllSocGetLevel(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
107 | void zllSocGetHue(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
108 | void zllSocGetSat(uint16_t dstAddr, uint8_t endpoint, uint8_t addrMode); | ||
109 | #ifdef __cplusplus | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | #endif /* ZLLSOCCMD_H */ | ||
diff --git a/zll_controller.c b/zll_controller.c new file mode 100644 index 0000000..3b91873 --- /dev/null +++ b/zll_controller.c | |||
@@ -0,0 +1,448 @@ | |||
1 | /* | ||
2 | * zll_controller.c | ||
3 | * | ||
4 | * This module demonstrates how to use the API for the zll SoC | ||
5 | * Host Interface. | ||
6 | * | ||
7 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
8 | * | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in the | ||
19 | * documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
23 | * its contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | */ | ||
39 | #include <termios.h> | ||
40 | #include <string.h> | ||
41 | #include <stdio.h> | ||
42 | #include <unistd.h> | ||
43 | #include <fcntl.h> | ||
44 | #include <stdlib.h> | ||
45 | #include <poll.h> | ||
46 | |||
47 | #include "zllSocCmd.h" | ||
48 | |||
49 | #define MAX_CONSOLE_CMD_LEN 128 | ||
50 | |||
51 | void usage( char* exeName ); | ||
52 | void commandUsage( void ); | ||
53 | void processConsoleCommand( void ); | ||
54 | void getConsoleCommandParams(char* cmdBuff, uint16_t *nwkAddr, uint8_t *addrMode, uint8_t *ep, uint8_t *value, uint16_t *transitionTime); | ||
55 | uint32_t getParam( char *cmdBuff, char *paramId, uint32_t *paramInt); | ||
56 | uint8_t tlIndicationCb(epInfo_t *epInfo); | ||
57 | uint8_t zclGetStateCb(uint8_t state, uint16_t nwkAddr, uint8_t endpoint); | ||
58 | uint8_t zclGetLevelCb(uint8_t level, uint16_t nwkAddr, uint8_t endpoint); | ||
59 | uint8_t zclGetHueCb(uint8_t hue, uint16_t nwkAddr, uint8_t endpoint); | ||
60 | uint8_t zclGetSatCb(uint8_t sat, uint16_t nwkAddr, uint8_t endpoint); | ||
61 | |||
62 | static zllSocCallbacks_t zllSocCbs = | ||
63 | { | ||
64 | tlIndicationCb, // pfnTlIndicationCb - TouchLink Indication callback | ||
65 | NULL, // pfnNewDevIndicationCb - New Device Indication callback | ||
66 | zclGetStateCb, // pfnZclGetHueCb - ZCL response callback for get Hue | ||
67 | zclGetLevelCb, //pfnZclGetSatCb - ZCL response callback for get Sat | ||
68 | zclGetHueCb, //pfnZclGetLevelCb_t - ZCL response callback for get Level | ||
69 | zclGetSatCb //pfnZclGetStateCb - ZCL response callback for get State | ||
70 | }; | ||
71 | |||
72 | static uint16_t savedNwkAddr; | ||
73 | static uint8_t savedAddrMode; | ||
74 | static uint8_t savedEp; | ||
75 | static uint8_t savedValue; | ||
76 | static uint16_t savedTransitionTime; | ||
77 | |||
78 | void usage( char* exeName ) | ||
79 | { | ||
80 | printf("Usage: ./%s <port>\n", exeName); | ||
81 | printf("Eample: ./%s /dev/ttyACM0\n", exeName); | ||
82 | } | ||
83 | |||
84 | void commandUsage( void ) | ||
85 | { | ||
86 | printf("Commands:\n"); | ||
87 | printf("touchlink\n"); | ||
88 | printf("sendresettofn\n"); | ||
89 | printf("resettofn\n"); | ||
90 | printf("setstate\n"); | ||
91 | printf("setlevel\n"); | ||
92 | printf("sethue\n"); | ||
93 | printf("setsat\n"); | ||
94 | printf("getstate\n"); | ||
95 | printf("getlevel\n"); | ||
96 | printf("gethue\n"); | ||
97 | printf("getsat\n\n"); | ||
98 | printf("exit\n\n"); | ||
99 | |||
100 | printf("Parameters:\n"); | ||
101 | printf("-n<network address>\n"); | ||
102 | printf("-e<end point>\n"); | ||
103 | printf("-m<address mode 1=groupcast, 2=unicast>\n"); | ||
104 | printf("-v<value>\n"); | ||
105 | printf("-t<transition time in 10ms>\n\n"); | ||
106 | |||
107 | printf("A successful touchlink will set the network address and endpoint of the newly\n"); | ||
108 | printf("paired device. so all the new Light can be turn on with the following command\n"); | ||
109 | printf("setsat -v1\n\n"); | ||
110 | |||
111 | printf("The below example will send a MoveToHue command to network address 0x0003\n"); | ||
112 | printf("end point 0xb, which will cause the device to move to a red hue over 3s\n"); | ||
113 | printf("(be sure that the saturation is set high to see the change):\n"); | ||
114 | printf("sethue -n0x0003 -e0xb -m0x2 -v0 -t30\n\n"); | ||
115 | |||
116 | printf("parameters are remembered, so the blow command directly after the above will\n"); | ||
117 | printf("change to a blue hue:\n"); | ||
118 | printf("sethue -v0xAA \n\n"); | ||
119 | |||
120 | printf("The value of hue is a 0x0-0xFF representation of the 360Deg color wheel where:\n"); | ||
121 | printf("0Deg or 0x0 is red\n"); | ||
122 | printf("120Deg or 0x55 is a green hue\n"); | ||
123 | printf("240Deg or 0xAA is a blue hue\n\n"); | ||
124 | |||
125 | printf("The value of saturation is a 0x0-0xFE value where:\n"); | ||
126 | printf("0x0 is white\n"); | ||
127 | printf("0xFE is the fully saturated color specified by the hue value\n"); | ||
128 | } | ||
129 | |||
130 | int main(int argc, char* argv[]) | ||
131 | { | ||
132 | int retval = 0; | ||
133 | int zllSoc_fd; | ||
134 | |||
135 | printf("%s -- %s %s\n", argv[0], __DATE__, __TIME__ ); | ||
136 | |||
137 | // accept only 1 | ||
138 | if( argc != 2 ) | ||
139 | { | ||
140 | usage(argv[0]); | ||
141 | printf("attempting to use /dev/ttyACM0\n"); | ||
142 | zllSoc_fd = zllSocOpen( "/dev/ttyACM0" ); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | zllSoc_fd = zllSocOpen( argv[1] ); | ||
147 | } | ||
148 | |||
149 | if( zllSoc_fd == -1 ) | ||
150 | { | ||
151 | exit(-1); | ||
152 | } | ||
153 | |||
154 | zllSocRegisterCallbacks( zllSocCbs ); | ||
155 | |||
156 | //set some default values | ||
157 | savedNwkAddr = 0x0002; | ||
158 | savedAddrMode = 0x02; | ||
159 | savedEp = 0x0b; | ||
160 | savedValue = 0x0; | ||
161 | savedTransitionTime = 0x1; | ||
162 | |||
163 | while(1) | ||
164 | { | ||
165 | struct pollfd pollFds[2]; | ||
166 | |||
167 | //set the zllSoC serial port FD in the poll file descriptors | ||
168 | pollFds[0].fd = zllSoc_fd; | ||
169 | pollFds[0].events = POLLIN; | ||
170 | |||
171 | //set the stdin FD in the poll file descriptors | ||
172 | pollFds[1].fd = 0; //stdin | ||
173 | pollFds[1].events = POLLIN; | ||
174 | |||
175 | poll(pollFds, 2, -1); | ||
176 | |||
177 | //did the poll unblock because of the zllSoC serial? | ||
178 | if(pollFds[0].revents) | ||
179 | { | ||
180 | zllSocProcessRpc(); | ||
181 | //printf("main: zllSocProcessRpc - %x\n", pollFds[0].revents); | ||
182 | } | ||
183 | //did the poll unblock because of the stdin? | ||
184 | else if(pollFds[1].revents) | ||
185 | { | ||
186 | processConsoleCommand(); | ||
187 | //printf("main: processConsoleCommand - %x\n", pollFds[1].revents); | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | printf("zllMain: unhandled poll\n"); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | return retval; | ||
196 | } | ||
197 | |||
198 | void processConsoleCommand( void ) | ||
199 | { | ||
200 | char cmdBuff[MAX_CONSOLE_CMD_LEN]; | ||
201 | uint32_t bytesRead; | ||
202 | uint16_t nwkAddr; | ||
203 | uint8_t addrMode; | ||
204 | uint8_t endpoint; | ||
205 | uint8_t value; | ||
206 | uint16_t transitionTime; | ||
207 | |||
208 | //read stdin | ||
209 | bytesRead = read(0, cmdBuff, (MAX_CONSOLE_CMD_LEN-1)); | ||
210 | cmdBuff[bytesRead] = '\0'; | ||
211 | |||
212 | getConsoleCommandParams(cmdBuff, &nwkAddr, &addrMode, &endpoint, &value, &transitionTime); | ||
213 | |||
214 | if((strstr(cmdBuff, "touchlink")) != 0) | ||
215 | { | ||
216 | zllSocTouchLink(); | ||
217 | printf("touchlink command executed\n\n"); | ||
218 | } | ||
219 | else if((strstr(cmdBuff, "sendresettofn")) != 0) | ||
220 | { | ||
221 | //sending of reset to fn must happen within a touchlink | ||
222 | zllSocTouchLink(); | ||
223 | printf("press a key when device identyfies\n"); | ||
224 | getc(stdin); | ||
225 | zllSocSendResetToFn(); | ||
226 | } | ||
227 | else if((strstr(cmdBuff, "resettofn")) != 0) | ||
228 | { | ||
229 | zllSocResetToFn(); | ||
230 | printf("resettofn command executed\n\n"); | ||
231 | } | ||
232 | else if((strstr(cmdBuff, "setstate")) != 0) | ||
233 | { | ||
234 | zllSocSetState(value, nwkAddr, endpoint, addrMode); | ||
235 | printf("setstate command executed with params: \n"); | ||
236 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n Value :0x%02x\n\n", | ||
237 | nwkAddr, endpoint, addrMode, value); | ||
238 | } | ||
239 | else if((strstr(cmdBuff, "setlevel")) != 0) | ||
240 | { | ||
241 | zllSocSetLevel(value, transitionTime, nwkAddr, endpoint, addrMode); | ||
242 | printf("setlevel command executed with params: \n"); | ||
243 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n Value :0x%02x\n Transition Time :0x%04x\n\n", | ||
244 | nwkAddr, endpoint, addrMode, value, transitionTime); | ||
245 | } | ||
246 | else if((strstr(cmdBuff, "sethue")) != 0) | ||
247 | { | ||
248 | zllSocSetHue(value, transitionTime, nwkAddr, endpoint, addrMode); | ||
249 | printf("sethue command executed with params: \n"); | ||
250 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n Value :0x%02x\n Transition Time :0x%04x\n\n", | ||
251 | nwkAddr, endpoint, addrMode, value, transitionTime); | ||
252 | } | ||
253 | else if((strstr(cmdBuff, "setsat")) != 0) | ||
254 | { | ||
255 | zllSocSetSat(value, transitionTime, nwkAddr, endpoint, addrMode); | ||
256 | printf("setsat command executed with params: \n"); | ||
257 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n Value :0x%02x\n Transition Time :0x%04x\n\n", | ||
258 | nwkAddr, endpoint, addrMode, value, transitionTime); | ||
259 | } | ||
260 | else if((strstr(cmdBuff, "getstate")) != 0) | ||
261 | { | ||
262 | zllSocGetState(nwkAddr, endpoint, addrMode); | ||
263 | printf("getstate command executed wtih params: \n"); | ||
264 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n\n", | ||
265 | nwkAddr, endpoint, addrMode); | ||
266 | } | ||
267 | else if((strstr(cmdBuff, "getlevel")) != 0) | ||
268 | { | ||
269 | zllSocGetLevel(nwkAddr, endpoint, addrMode); | ||
270 | printf("getlevel command executed with params: \n"); | ||
271 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n\n", | ||
272 | nwkAddr, endpoint, addrMode); | ||
273 | } | ||
274 | else if((strstr(cmdBuff, "gethue")) != 0) | ||
275 | { | ||
276 | zllSocGetHue(nwkAddr, endpoint, addrMode); | ||
277 | printf("gethue command executed with params: \n"); | ||
278 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n\n", | ||
279 | nwkAddr, endpoint, addrMode); | ||
280 | } | ||
281 | else if((strstr(cmdBuff, "getsat")) != 0) | ||
282 | { | ||
283 | zllSocGetSat(nwkAddr, endpoint, addrMode); | ||
284 | printf("getsat command executed with params: \n"); | ||
285 | printf(" Network Addr :0x%04x\n End Point :0x%02x\n Addr Mode :0x%02x\n\n", | ||
286 | nwkAddr, endpoint, addrMode); | ||
287 | } | ||
288 | else if((strstr(cmdBuff, "exit")) != 0) | ||
289 | { | ||
290 | printf("Closing. \n"); | ||
291 | zllSocClose(); | ||
292 | exit(0); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | printf("invalid command\n\n"); | ||
297 | commandUsage(); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | void getConsoleCommandParams(char* cmdBuff, uint16_t *nwkAddr, uint8_t *addrMode, uint8_t *ep, uint8_t *value, uint16_t *transitionTime) | ||
302 | { | ||
303 | //set some default values | ||
304 | uint32_t tmpInt; | ||
305 | |||
306 | if( getParam( cmdBuff, "-n", &tmpInt) ) | ||
307 | { | ||
308 | savedNwkAddr = (uint16_t) tmpInt; | ||
309 | } | ||
310 | if( getParam( cmdBuff, "-m", &tmpInt) ) | ||
311 | { | ||
312 | savedAddrMode = (uint8_t) tmpInt; | ||
313 | } | ||
314 | if( getParam( cmdBuff, "-e", &tmpInt) ) | ||
315 | { | ||
316 | savedEp = (uint8_t) tmpInt; | ||
317 | } | ||
318 | if( getParam( cmdBuff, "-v", &tmpInt) ) | ||
319 | { | ||
320 | savedValue = (uint8_t) tmpInt; | ||
321 | } | ||
322 | if( getParam( cmdBuff, "-t", &tmpInt) ) | ||
323 | { | ||
324 | savedTransitionTime = (uint16_t) tmpInt; | ||
325 | } | ||
326 | |||
327 | *nwkAddr = savedNwkAddr; | ||
328 | *addrMode = savedAddrMode; | ||
329 | *ep = savedEp; | ||
330 | *value = savedValue; | ||
331 | *transitionTime = savedTransitionTime; | ||
332 | |||
333 | return; | ||
334 | } | ||
335 | |||
336 | uint32_t getParam( char *cmdBuff, char *paramId, uint32_t *paramInt) | ||
337 | { | ||
338 | char* paramStrStart; | ||
339 | char* paramStrEnd; | ||
340 | //0x1234+null termination | ||
341 | char paramStr[7]; | ||
342 | uint32_t rtn = 0; | ||
343 | |||
344 | memset(paramStr, 0, sizeof(paramStr)); | ||
345 | paramStrStart = strstr(cmdBuff, paramId); | ||
346 | |||
347 | if( paramStrStart ) | ||
348 | { | ||
349 | //index past the param idenentifier "-?" | ||
350 | paramStrStart+=2; | ||
351 | //find the the end of the param text | ||
352 | paramStrEnd = strstr(paramStrStart, " "); | ||
353 | if( paramStrEnd ) | ||
354 | { | ||
355 | if(paramStrEnd-paramStrStart > (sizeof(paramStr)-1)) | ||
356 | { | ||
357 | //we are not on the last param, but the param str is too long | ||
358 | strncpy( paramStr, paramStrStart, (sizeof(paramStr)-1)); | ||
359 | paramStr[sizeof(paramStr)-1] = '\0'; | ||
360 | } | ||
361 | else | ||
362 | { | ||
363 | //we are not on the last param so use the " " as the delimiter | ||
364 | strncpy( paramStr, paramStrStart, paramStrEnd-paramStrStart); | ||
365 | paramStr[paramStrEnd-paramStrStart] = '\0'; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | else | ||
370 | { | ||
371 | //we are on the last param so use the just go the the end of the string | ||
372 | //(which will be null terminate). But make sure that it is not bigger | ||
373 | //than our paramStr buffer. | ||
374 | if(strlen(paramStrStart) > (sizeof(paramStr)-1)) | ||
375 | { | ||
376 | //command was entered wrong and paramStrStart will over flow the | ||
377 | //paramStr buffer. | ||
378 | strncpy( paramStr, paramStrStart, (sizeof(paramStr)-1)); | ||
379 | paramStr[sizeof(paramStr)-1] = '\0'; | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | //Param is the correct size so just copy it. | ||
384 | strcpy( paramStr, paramStrStart); | ||
385 | paramStr[strlen(paramStrStart)-1] = '\0'; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | //was the param in hex or dec? | ||
390 | if(strstr(paramStr, "0x")) | ||
391 | { | ||
392 | //convert the hex value to an int. | ||
393 | sscanf(paramStr, "0x%x", paramInt); | ||
394 | } | ||
395 | else | ||
396 | { | ||
397 | //assume that it ust be dec and convert to int. | ||
398 | sscanf(paramStr, "%d", paramInt); | ||
399 | } | ||
400 | |||
401 | //paramInt was set | ||
402 | rtn = 1; | ||
403 | |||
404 | } | ||
405 | |||
406 | return rtn; | ||
407 | } | ||
408 | |||
409 | uint8_t tlIndicationCb(epInfo_t *epInfo) | ||
410 | { | ||
411 | printf("\ntlIndicationCb:\n Network Addr : 0x%04x\n End Point : 0x%02x\n Profile ID : 0x%04x\n", | ||
412 | epInfo->nwkAddr, epInfo->endpoint, epInfo->profileID); | ||
413 | printf(" Device ID : 0x%04x\n Version : 0x%02x\n Status : 0x%02x\n\n", | ||
414 | epInfo->deviceID, epInfo->version, epInfo->status); | ||
415 | |||
416 | //control this device by default | ||
417 | savedNwkAddr = epInfo->nwkAddr; | ||
418 | savedEp = epInfo->endpoint; | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | uint8_t zclGetStateCb(uint8_t state, uint16_t nwkAddr, uint8_t endpoint) | ||
424 | { | ||
425 | printf("\nzclGetStateCb:\n Network Addr : 0x%04x\n End Point : 0x%02x\n State : 0x%02x\n\n", | ||
426 | nwkAddr, endpoint, state); | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | uint8_t zclGetLevelCb(uint8_t level, uint16_t nwkAddr, uint8_t endpoint) | ||
431 | { | ||
432 | printf("\nzclGetLevelCb:\n Network Addr : 0x%04x\n End Point : 0x%02x\n Level : %02x\n\n", | ||
433 | nwkAddr, endpoint, level); | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | uint8_t zclGetHueCb(uint8_t hue, uint16_t nwkAddr, uint8_t endpoint) | ||
438 | { | ||
439 | printf("\nzclGetHueCb:\n Network Addr : 0x%04x\n End Point : 0x%02x\n Hue : %02x\n\n", nwkAddr, endpoint, hue); | ||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | uint8_t zclGetSatCb(uint8_t sat, uint16_t nwkAddr, uint8_t endpoint) | ||
444 | { | ||
445 | printf("\nzclGetSatCb:\n Network Addr : 0x%04x\n End Point : 0x%02x\n Saturation : %02x\n\n", | ||
446 | nwkAddr, endpoint, sat); | ||
447 | return 0; | ||
448 | } | ||