zcl_ss.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520
  1. /**************************************************************************************************
  2. Filename: zcl_ss.c
  3. Revised: $Date: 2010-02-09 15:28:14 -0800 (Tue, 09 Feb 2010) $
  4. Revision: $Revision: 21679 $
  5. Description: Zigbee Cluster Library - Security and Safety ( SS )
  6. Copyright 2006-2010 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*******************************************************************************
  34. * INCLUDES
  35. */
  36. #include "ZComDef.h"
  37. #include "OSAL.h"
  38. #include "zcl.h"
  39. #include "zcl_general.h"
  40. #include "zcl_ss.h"
  41. #if defined ( INTER_PAN )
  42. #include "stub_aps.h"
  43. #endif
  44. /*******************************************************************************
  45. * MACROS
  46. */
  47. #define zclSS_ZoneTypeSupported( a ) ( (a) == SS_IAS_ZONE_TYPE_STANDARD_CIE || \
  48. (a) == SS_IAS_ZONE_TYPE_MOTION_SENSOR || \
  49. (a) == SS_IAS_ZONE_TYPE_CONTACT_SWITCH || \
  50. (a) == SS_IAS_ZONE_TYPE_FIRE_SENSOR || \
  51. (a) == SS_IAS_ZONE_TYPE_WATER_SENSOR || \
  52. (a) == SS_IAS_ZONE_TYPE_GAS_SENSOR || \
  53. (a) == SS_IAS_ZONE_TYPE_PERSONAL_EMERGENCY_DEVICE || \
  54. (a) == SS_IAS_ZONE_TYPE_VIBRATION_MOVEMENT_SENSOR || \
  55. (a) == SS_IAS_ZONE_TYPE_REMOTE_CONTROL || \
  56. (a) == SS_IAS_ZONE_TYPE_KEY_FOB || \
  57. (a) == SS_IAS_ZONE_TYPE_KEYPAD || \
  58. (a) == SS_IAS_ZONE_TYPE_STANDARD_WARNING_DEVICE )
  59. /*******************************************************************************
  60. * CONSTANTS
  61. */
  62. /*******************************************************************************
  63. * TYPEDEFS
  64. */
  65. typedef struct zclSSCBRec
  66. {
  67. struct zclSSCBRec *next;
  68. uint8 endpoint; // Used to link it into the endpoint descriptor
  69. zclSS_AppCallbacks_t *CBs; // Pointer to Callback function
  70. } zclSSCBRec_t;
  71. typedef struct zclSS_ZoneItem
  72. {
  73. struct zclSS_ZoneItem *next;
  74. uint8 endpoint; // Used to link it into the endpoint descriptor
  75. IAS_ACE_ZoneTable_t zone; // Zone info
  76. } zclSS_ZoneItem_t;
  77. /*******************************************************************************
  78. * GLOBAL VARIABLES
  79. */
  80. const uint8 zclSS_UknownIeeeAddress[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  81. /*******************************************************************************
  82. * GLOBAL FUNCTIONS
  83. */
  84. /*******************************************************************************
  85. * LOCAL VARIABLES
  86. */
  87. static zclSSCBRec_t *zclSSCBs = (zclSSCBRec_t *)NULL;
  88. static uint8 zclSSPluginRegisted = FALSE;
  89. #if defined(ZCL_ZONE) || defined(ZCL_ACE)
  90. static zclSS_ZoneItem_t *zclSS_ZoneTable = (zclSS_ZoneItem_t *)NULL;
  91. #endif // ZCL_ZONE || ZCL_ACE
  92. /*******************************************************************************
  93. * LOCAL FUNCTIONS
  94. */
  95. static ZStatus_t zclSS_HdlIncoming( zclIncoming_t *pInHdlrMsg );
  96. static ZStatus_t zclSS_HdlInSpecificCommands( zclIncoming_t *pInMsg );
  97. static zclSS_AppCallbacks_t *zclSS_FindCallbacks( uint8 endpoint );
  98. #ifdef ZCL_ZONE
  99. static ZStatus_t zclSS_ProcessInZoneStatusCmdsServer( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  100. static ZStatus_t zclSS_ProcessInZoneStatusCmdsClient( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  101. static void zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  102. static ZStatus_t zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  103. static void zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  104. #endif // ZCL_ZONE
  105. #ifdef ZCL_ACE
  106. static ZStatus_t zclSS_ProcessInACECmdsServer( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  107. static ZStatus_t zclSS_ProcessInACECmdsClient( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  108. static ZStatus_t zclSS_ProcessInCmd_ACE_Arm( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  109. static void zclSS_ProcessInCmd_ACE_Bypass( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  110. static void zclSS_ProcessInCmd_ACE_Emergency( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  111. static void zclSS_ProcessInCmd_ACE_Fire( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  112. static void zclSS_ProcessInCmd_ACE_Panic( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  113. static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneIDMap( zclIncoming_t *pInMsg );
  114. static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneInformation( zclIncoming_t *pInMsg );
  115. static void zclSS_ProcessInCmd_ACE_ArmResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  116. static void zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  117. static void zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  118. #endif // ZCL_ACE
  119. #ifdef ZCL_WD
  120. static ZStatus_t zclSS_ProcessInWDCmds( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  121. static void zclSS_ProcessInCmd_WD_StartWarning( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  122. static void zclSS_ProcessInCmd_WD_Squawk( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
  123. #endif // ZCL_WD
  124. #ifdef ZCL_ZONE
  125. static uint8 zclSS_GetNextFreeZoneID( void );
  126. static ZStatus_t zclSS_AddZone( uint8 endpoint, IAS_ACE_ZoneTable_t *zone );
  127. static uint8 zclSS_CountAllZones( void );
  128. static uint8 zclSS_ZoneIDAvailable( uint8 zoneID );
  129. #endif // ZCL_ZONE
  130. #if defined(ZCL_ZONE) || defined(ZCL_ACE)
  131. static IAS_ACE_ZoneTable_t *zclSS_FindZone( uint8 endpoint, uint8 zoneID );
  132. #endif // ZCL_ZONE || ZCL_ACE
  133. /******************************************************************************
  134. * @fn zclSS_RegisterCmdCallbacks
  135. *
  136. * @brief Register an applications command callbacks
  137. *
  138. * @param endpoint - application's endpoint
  139. * @param callbacks - pointer to the callback record.
  140. *
  141. * @return ZMemError if not able to allocate
  142. */
  143. ZStatus_t zclSS_RegisterCmdCallbacks( uint8 endpoint, zclSS_AppCallbacks_t *callbacks )
  144. {
  145. zclSSCBRec_t *pNewItem;
  146. zclSSCBRec_t *pLoop;
  147. // Register as a ZCL Plugin
  148. if ( !zclSSPluginRegisted )
  149. {
  150. zcl_registerPlugin( ZCL_CLUSTER_ID_SS_IAS_ZONE,
  151. ZCL_CLUSTER_ID_SS_IAS_WD,
  152. zclSS_HdlIncoming );
  153. zclSSPluginRegisted = TRUE;
  154. }
  155. // Fill in the new profile list
  156. pNewItem = osal_mem_alloc( sizeof( zclSSCBRec_t ) );
  157. if ( pNewItem == NULL )
  158. return (ZMemError);
  159. pNewItem->next = (zclSSCBRec_t *)NULL;
  160. pNewItem->endpoint = endpoint;
  161. pNewItem->CBs = callbacks;
  162. // Find spot in list
  163. if ( zclSSCBs == NULL )
  164. {
  165. zclSSCBs = pNewItem;
  166. }
  167. else
  168. {
  169. // Look for end of list
  170. pLoop = zclSSCBs;
  171. while ( pLoop->next != NULL )
  172. pLoop = pLoop->next;
  173. // Put new item at end of list
  174. pLoop->next = pNewItem;
  175. }
  176. return ( ZSuccess );
  177. }
  178. #ifdef ZCL_ZONE
  179. /*******************************************************************************
  180. * @fn zclSS_Send_IAS_ZoneStatusChangeNotificationCmd
  181. *
  182. * @brief Call to send out a Change Notification Command
  183. *
  184. * @param srcEP - Sending application's endpoint
  185. * @param dstAddr - where you want the message to go
  186. * @param zoneStatus - current zone status - bit map
  187. * @param extendedStatus - bit map, currently set to All zeros ( reserved)
  188. *
  189. * @return ZStatus_t
  190. */
  191. ZStatus_t zclSS_IAS_Send_ZoneStatusChangeNotificationCmd( uint8 srcEP, afAddrType_t *dstAddr,
  192. uint16 zoneStatus, uint8 extendedStatus,
  193. uint8 disableDefaultRsp, uint8 seqNum )
  194. {
  195. uint8 buf[3];
  196. buf[0] = LO_UINT16( zoneStatus );
  197. buf[1] = HI_UINT16( zoneStatus );
  198. buf[2] = extendedStatus;
  199. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
  200. COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION, TRUE,
  201. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 3, buf );
  202. }
  203. /*******************************************************************************
  204. * @fn zclSS_Send_IAS_ZoneStatusEnrollRequestCmd
  205. *
  206. * @brief Call to send out a Enroll Request Command
  207. *
  208. * @param srcEP - Sending application's endpoint
  209. * @param dstAddr - where you want the message to go
  210. * @param zoneType - current value of Zone Type attribute
  211. * @param manufacturerCode - manuf. code from node descriptor for the device
  212. *
  213. * @return ZStatus_t
  214. */
  215. ZStatus_t zclSS_IAS_Send_ZoneStatusEnrollRequestCmd( uint8 srcEP, afAddrType_t *dstAddr,
  216. uint16 zoneType, uint16 manufacturerCode,
  217. uint8 disableDefaultRsp, uint8 seqNum )
  218. {
  219. uint8 buf[4];
  220. buf[0] = LO_UINT16( zoneType );
  221. buf[1] = HI_UINT16( zoneType );
  222. buf[2] = LO_UINT16( manufacturerCode );
  223. buf[3] = HI_UINT16( manufacturerCode );
  224. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
  225. COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST, TRUE,
  226. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 4, buf );
  227. }
  228. /*******************************************************************************
  229. * @fn zclSS_IAS_Send_ZoneStatusEnrollResponseCmd
  230. *
  231. * @brief Call to send out a Enroll Response Command
  232. *
  233. * @param srcEP - Sending application's endpoint
  234. * @param dstAddr - where you want the message to go
  235. * @param responseCode - value of response Code
  236. * @param zoneID - index to the zone table of the CIE
  237. *
  238. * @return ZStatus_t
  239. */
  240. ZStatus_t zclSS_IAS_Send_ZoneStatusEnrollResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
  241. uint8 responseCode, uint8 zoneID,
  242. uint8 disableDefaultRsp, uint8 seqNum )
  243. {
  244. uint8 buf[2];
  245. buf[0] = responseCode;
  246. buf[1] = zoneID;
  247. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
  248. COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE, TRUE,
  249. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 2, buf );
  250. }
  251. #endif // ZCL_ZONE
  252. #ifdef ZCL_ACE
  253. /*******************************************************************************
  254. * @fn zclSS_Send_IAS_ACE_ArmCmd
  255. *
  256. * @brief Call to send out a Arm Command ( IAS ACE Cluster )
  257. *
  258. * @param srcEP - Sending application's endpoint
  259. * @param dstAddr - where you want the message to go
  260. * @param armMode - value of armMode
  261. *
  262. * @return ZStatus_t
  263. */
  264. ZStatus_t zclSS_Send_IAS_ACE_ArmCmd( uint8 srcEP, afAddrType_t *dstAddr,
  265. uint8 armMode, uint8 disableDefaultRsp, uint8 seqNum )
  266. {
  267. uint8 buf[1];
  268. buf[0] = armMode;
  269. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  270. COMMAND_SS_IAS_ACE_ARM, TRUE,
  271. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
  272. }
  273. /*********************************************************************
  274. * @fn zclSS_Send_IAS_ACE_BypassCmd
  275. *
  276. * @brief Call to send out a Bypass Command ( IAS ACE Cluster )
  277. *
  278. * @param srcEP - Sending application's endpoint
  279. * @param dstAddr - where you want the message to go
  280. * @param numberOfZones - one byte
  281. * @param bypassBuf - zone IDs array of 256 entries one byte each
  282. *
  283. * @return ZStatus_t
  284. */
  285. ZStatus_t zclSS_Send_IAS_ACE_BypassCmd( uint8 srcEP, afAddrType_t *dstAddr,
  286. uint8 numberOfZones, uint8 *bypassBuf,
  287. uint8 disableDefaultRsp, uint8 seqNum )
  288. {
  289. uint8 *buf;
  290. uint8 *pBuf;
  291. uint8 len = 1 + numberOfZones;
  292. ZStatus_t stat;
  293. buf = osal_mem_alloc( len );
  294. if ( buf )
  295. {
  296. pBuf = buf;
  297. *pBuf++ = numberOfZones;
  298. osal_memcpy( pBuf, bypassBuf, numberOfZones );
  299. stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  300. COMMAND_SS_IAS_ACE_BYPASS, TRUE,
  301. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, len, buf );
  302. osal_mem_free( buf );
  303. }
  304. else
  305. stat = ZFailure;
  306. return ( stat );
  307. }
  308. /*********************************************************************
  309. * @fn zclSS_Send_IAS_ACE_GetZoneInformationCmd
  310. *
  311. * @brief Call to send out a Get Zone Information Command ( IAS ACE Cluster )
  312. *
  313. * @param srcEP - Sending application's endpoint
  314. * @param dstAddr - where you want the message to go
  315. * @param zoneID - 8 bit value from 0 to 255
  316. *
  317. * @return ZStatus_t
  318. */
  319. ZStatus_t zclSS_Send_IAS_ACE_GetZoneInformationCmd( uint8 srcEP, afAddrType_t *dstAddr,
  320. uint8 zoneID, uint8 disableDefaultRsp, uint8 seqNum )
  321. {
  322. uint8 buf[1];
  323. buf[0] = zoneID;
  324. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  325. COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION, TRUE,
  326. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
  327. }
  328. /*******************************************************************************
  329. * @fn zclSS_Send_IAS_ACE_ArmRespponse
  330. *
  331. * @brief Call to send out a Arm Response Command ( IAS ACE Cluster )
  332. *
  333. * @param srcEP - Sending application's endpoint
  334. * @param dstAddr - where you want the message to go
  335. * @param armNotification
  336. *
  337. * @return ZStatus_t
  338. */
  339. ZStatus_t zclSS_Send_IAS_ACE_ArmResponse( uint8 srcEP, afAddrType_t *dstAddr,
  340. uint8 armNotification, uint8 disableDefaultRsp, uint8 seqNum )
  341. {
  342. uint8 buf[1];
  343. buf[0] = armNotification;
  344. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  345. COMMAND_SS_IAS_ACE_ARM_RESPONSE, TRUE,
  346. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
  347. }
  348. /*********************************************************************
  349. * @fn zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd
  350. *
  351. * @brief Call to send out a Get Zone ID Map Response Cmd ( IAS ACE Cluster )
  352. *
  353. * @param srcEP - Sending application's endpoint
  354. * @param dstAddr - where you want the message to go
  355. * @param zoneIDMap - pointer to an array of 16 uint16
  356. *
  357. * @return ZStatus_t
  358. */
  359. ZStatus_t zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
  360. uint16 *zoneIDMap, uint8 disableDefaultRsp, uint8 seqNum )
  361. {
  362. uint8 *buf;
  363. uint8 *pIndex;
  364. uint8 j,len = 32;
  365. ZStatus_t stat;
  366. buf = osal_mem_alloc( len );
  367. if ( buf )
  368. {
  369. pIndex = buf;
  370. for( j = 0; j < 16; j++ )
  371. {
  372. *pIndex++ = LO_UINT16( *zoneIDMap );
  373. *pIndex++ = HI_UINT16( *zoneIDMap++ );
  374. }
  375. stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  376. COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE, TRUE,
  377. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
  378. osal_mem_free( buf );
  379. }
  380. else
  381. stat = ZMemError;
  382. return ( stat );
  383. }
  384. /*******************************************************************************
  385. * @fn zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd
  386. *
  387. * @brief Call to send out Get Zone Information Response Cmd (IAS ACE Cluster)
  388. *
  389. * @param srcEP - Sending application's endpoint
  390. * @param dstAddr - where you want the message to go
  391. * @param zoneID - 8 bit value from 0 to 255
  392. * @param zoneType - 16 bit
  393. * @param ieeeAddress - pointer to 64 bit address ( 8bytes*8)
  394. *
  395. * @return ZStatus_t
  396. */
  397. ZStatus_t zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
  398. uint8 zoneID, uint16 zoneType, uint8 *ieeeAddress,
  399. uint8 disableDefaultRsp, uint8 seqNum )
  400. {
  401. uint8 *buf;
  402. uint8 len = 11; // zoneID (1) + zoneType (2) + zoneAddress (8)
  403. ZStatus_t stat;
  404. buf = osal_mem_alloc( len );
  405. if ( buf )
  406. {
  407. buf[0] = zoneID;
  408. buf[1] = LO_UINT16( zoneType);
  409. buf[2] = HI_UINT16( zoneType);
  410. osal_cpyExtAddr( &buf[3], ieeeAddress );
  411. stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
  412. COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE, TRUE,
  413. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
  414. osal_mem_free( buf );
  415. }
  416. else
  417. stat = ZMemError;
  418. return ( stat );
  419. }
  420. #endif // ZCL_ACE
  421. #ifdef ZCL_WD
  422. /*******************************************************************************
  423. * @fn zclSS_Send_IAS_WD_StartWarningCmd
  424. *
  425. * @brief Call to send out a Start Warning Command (IAS WD Cluster)
  426. *
  427. * @param warning - 3 bytes of type zclCmdSSWDStartWarningPayload_t
  428. *
  429. * @return ZStatus_t
  430. */
  431. ZStatus_t zclSS_Send_IAS_WD_StartWarningCmd( uint8 srcEP, afAddrType_t *dstAddr,
  432. zclCmdSSWDStartWarningPayload_t *warning,
  433. uint8 disableDefaultRsp, uint8 seqNum )
  434. {
  435. uint8 buf[3];
  436. buf[0] = warning->warningmessage.warningbyte;
  437. buf[1] = LO_UINT16( warning->duration );
  438. buf[2] = HI_UINT16( warning->duration );
  439. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_WD,
  440. COMMAND_SS_IAS_WD_START_WARNING, TRUE,
  441. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 3, buf );
  442. }
  443. /******************************************************************************
  444. * @fn zclSS_Send_IAS_WD_StartWarningCmd
  445. *
  446. * @brief Call to send out a Squawk Command ( IAS WD Cluster )
  447. *
  448. * @param squawk - one byte of type zclCmdSSWDSquawkPayload_t
  449. *
  450. * @return ZStatus_t
  451. */
  452. ZStatus_t zclSS_Send_IAS_WD_SquawkCmd( uint8 srcEP, afAddrType_t *dstAddr,
  453. zclCmdSSWDSquawkPayload_t *squawk,
  454. uint8 disableDefaultRsp, uint8 seqNum )
  455. {
  456. uint8 buf[1];
  457. buf[0] = squawk->squawkbyte;
  458. return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_WD,
  459. COMMAND_SS_IAS_WD_SQUAWK, TRUE,
  460. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf);
  461. }
  462. #endif // ZCL_WD
  463. /*********************************************************************
  464. * @fn zclSS_FindCallbacks
  465. *
  466. * @brief Find the callbacks for an endpoint
  467. *
  468. * @param endpoint
  469. *
  470. * @return pointer to the callbacks
  471. */
  472. static zclSS_AppCallbacks_t *zclSS_FindCallbacks( uint8 endpoint )
  473. {
  474. zclSSCBRec_t *pCBs;
  475. pCBs = zclSSCBs;
  476. while ( pCBs )
  477. {
  478. if ( pCBs->endpoint == endpoint )
  479. return ( pCBs->CBs );
  480. pCBs = pCBs->next;
  481. }
  482. return ( (zclSS_AppCallbacks_t *)NULL );
  483. }
  484. /*********************************************************************
  485. * @fn zclSS_HdlIncoming
  486. *
  487. * @brief Callback from ZCL to process incoming Commands specific
  488. * to this cluster library or Profile commands for attributes
  489. * that aren't in the attribute list
  490. *
  491. * @param pInMsg - pointer to the incoming message
  492. * @param logicalClusterID
  493. *
  494. * @return ZStatus_t
  495. */
  496. static ZStatus_t zclSS_HdlIncoming( zclIncoming_t *pInMsg )
  497. {
  498. ZStatus_t stat = ZSuccess;
  499. #if defined ( INTER_PAN )
  500. if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) )
  501. return ( stat ); // Cluster not supported thru Inter-PAN
  502. #endif
  503. if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
  504. {
  505. // Is this a manufacturer specific command?
  506. if ( pInMsg->hdr.fc.manuSpecific == 0 )
  507. {
  508. stat = zclSS_HdlInSpecificCommands( pInMsg );
  509. }
  510. else
  511. {
  512. // We don't support any manufacturer specific command -- ignore it.
  513. stat = ZFailure;
  514. }
  515. }
  516. else
  517. {
  518. // Handle all the normal (Read, Write...) commands
  519. stat = ZFailure;
  520. }
  521. return ( stat );
  522. }
  523. /*********************************************************************
  524. * @fn zclSS_HdlInSpecificCommands
  525. *
  526. * @brief Callback from ZCL to process incoming Commands specific
  527. * to this cluster library
  528. * @param pInMsg - pointer to the incoming message
  529. *
  530. * @return ZStatus_t
  531. */
  532. static ZStatus_t zclSS_HdlInSpecificCommands( zclIncoming_t *pInMsg )
  533. {
  534. ZStatus_t stat = ZSuccess;
  535. zclSS_AppCallbacks_t *pCBs;
  536. // make sure endpoint exists
  537. pCBs = (void*)zclSS_FindCallbacks( pInMsg->msg->endPoint );
  538. if ( pCBs == NULL )
  539. return ( ZFailure );
  540. switch ( pInMsg->msg->clusterId )
  541. {
  542. #ifdef ZCL_ZONE
  543. case ZCL_CLUSTER_ID_SS_IAS_ZONE:
  544. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  545. stat = zclSS_ProcessInZoneStatusCmdsServer( pInMsg, pCBs );
  546. else
  547. stat = zclSS_ProcessInZoneStatusCmdsClient( pInMsg, pCBs );
  548. break;
  549. #endif // ZCL_ZONE
  550. #ifdef ZCL_ACE
  551. case ZCL_CLUSTER_ID_SS_IAS_ACE:
  552. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  553. stat = zclSS_ProcessInACECmdsServer( pInMsg, pCBs );
  554. else
  555. stat = zclSS_ProcessInACECmdsClient( pInMsg, pCBs );
  556. break;
  557. #endif // ZCL_ACE
  558. #ifdef ZCL_WD
  559. case ZCL_CLUSTER_ID_SS_IAS_WD:
  560. stat = zclSS_ProcessInWDCmds( pInMsg, pCBs );
  561. break;
  562. #endif // ZCL_WD
  563. default:
  564. stat = ZFailure;
  565. break;
  566. }
  567. return ( stat );
  568. }
  569. #ifdef ZCL_ZONE
  570. /*********************************************************************
  571. * @fn zclSS_ProcessInZoneStatusCmdsServer
  572. *
  573. * @brief Callback from ZCL to process incoming Commands specific
  574. * to this cluster library on a command ID basis
  575. * @param pInMsg - pointer to the incoming message
  576. *
  577. * @return ZStatus_t
  578. */
  579. static ZStatus_t zclSS_ProcessInZoneStatusCmdsServer( zclIncoming_t *pInMsg,
  580. zclSS_AppCallbacks_t *pCBs )
  581. {
  582. ZStatus_t stat = ZSuccess;
  583. if ( pInMsg->hdr.commandID == COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE )
  584. zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( pInMsg, pCBs );
  585. else
  586. stat = ZFailure;
  587. return ( stat );
  588. }
  589. /*********************************************************************
  590. * @fn zclSS_ProcessInZoneStatusCmdsClient
  591. *
  592. * @brief Callback from ZCL to process incoming Commands specific
  593. * to this cluster library on a command ID basis
  594. * @param pInMsg - pointer to the incoming message
  595. *
  596. * @return ZStatus_t
  597. */
  598. static ZStatus_t zclSS_ProcessInZoneStatusCmdsClient( zclIncoming_t *pInMsg,
  599. zclSS_AppCallbacks_t *pCBs )
  600. {
  601. ZStatus_t stat = ZSuccess;
  602. switch ( pInMsg->hdr.commandID )
  603. {
  604. case COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION:
  605. zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( pInMsg, pCBs );
  606. break;
  607. case COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST:
  608. stat = zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( pInMsg, pCBs );
  609. break;
  610. default:
  611. stat = ZFailure;
  612. break;
  613. }
  614. return ( stat );
  615. }
  616. #endif // ZCL_ZONE
  617. #ifdef ZCL_ACE
  618. /*********************************************************************
  619. * @fn zclSS_ProcessInACECmdsServer
  620. *
  621. * @brief Callback from ZCL to process incoming Commands specific
  622. * to this cluster library on a command ID basis
  623. * @param pInMsg - pointer to the incoming message
  624. *
  625. * @return ZStatus_t
  626. */
  627. static ZStatus_t zclSS_ProcessInACECmdsServer( zclIncoming_t *pInMsg,
  628. zclSS_AppCallbacks_t *pCBs )
  629. {
  630. ZStatus_t stat = ZSuccess;
  631. switch ( pInMsg->hdr.commandID )
  632. {
  633. case COMMAND_SS_IAS_ACE_ARM:
  634. stat = zclSS_ProcessInCmd_ACE_Arm( pInMsg, pCBs );
  635. break;
  636. case COMMAND_SS_IAS_ACE_BYPASS:
  637. zclSS_ProcessInCmd_ACE_Bypass( pInMsg, pCBs );
  638. break;
  639. case COMMAND_SS_IAS_ACE_EMERGENCY:
  640. zclSS_ProcessInCmd_ACE_Emergency( pInMsg, pCBs );
  641. break;
  642. case COMMAND_SS_IAS_ACE_FIRE:
  643. zclSS_ProcessInCmd_ACE_Fire( pInMsg, pCBs );
  644. break;
  645. case COMMAND_SS_IAS_ACE_PANIC:
  646. zclSS_ProcessInCmd_ACE_Panic( pInMsg, pCBs );
  647. break;
  648. case COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP:
  649. stat = zclSS_ProcessInCmd_ACE_GetZoneIDMap( pInMsg );
  650. break;
  651. case COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION:
  652. stat = zclSS_ProcessInCmd_ACE_GetZoneInformation( pInMsg );
  653. break;
  654. default:
  655. stat = ZFailure;
  656. break;
  657. }
  658. return ( stat );
  659. }
  660. /*********************************************************************
  661. * @fn zclSS_ProcessInACECmdsClient
  662. *
  663. * @brief Callback from ZCL to process incoming Commands specific
  664. * to this cluster library on a command ID basis
  665. * @param pInMsg - pointer to the incoming message
  666. *
  667. * @return ZStatus_t
  668. */
  669. static ZStatus_t zclSS_ProcessInACECmdsClient( zclIncoming_t *pInMsg,
  670. zclSS_AppCallbacks_t *pCBs )
  671. {
  672. ZStatus_t stat = ZSuccess;
  673. switch ( pInMsg->hdr.commandID )
  674. {
  675. case COMMAND_SS_IAS_ACE_ARM_RESPONSE:
  676. zclSS_ProcessInCmd_ACE_ArmResponse( pInMsg, pCBs );
  677. break;
  678. case COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE:
  679. zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( pInMsg, pCBs );
  680. break;
  681. case COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE:
  682. zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( pInMsg, pCBs );
  683. break;
  684. default:
  685. stat = ZFailure;
  686. break;
  687. }
  688. return ( stat );
  689. }
  690. #endif // ZCL_ACE
  691. #ifdef ZCL_ZONE
  692. /*********************************************************************
  693. * @fn zclSS_AddZone
  694. *
  695. * @brief Add a zone for an endpoint
  696. *
  697. * @param endpoint -
  698. * @param zone - new zone item
  699. *
  700. * @return ZStatus_t
  701. */
  702. static ZStatus_t zclSS_AddZone( uint8 endpoint, IAS_ACE_ZoneTable_t *zone )
  703. {
  704. zclSS_ZoneItem_t *pNewItem;
  705. zclSS_ZoneItem_t *pLoop;
  706. // Fill in the new profile list
  707. pNewItem = osal_mem_alloc( sizeof( zclSS_ZoneItem_t ) );
  708. if ( pNewItem == NULL )
  709. return ( ZMemError );
  710. // Fill in the plugin record.
  711. pNewItem->next = (zclSS_ZoneItem_t *)NULL;
  712. pNewItem->endpoint = endpoint;
  713. osal_memcpy( (uint8*)&(pNewItem->zone), (uint8*)zone, sizeof ( IAS_ACE_ZoneTable_t ));
  714. // Find spot in list
  715. if ( zclSS_ZoneTable == NULL )
  716. {
  717. zclSS_ZoneTable = pNewItem;
  718. }
  719. else
  720. {
  721. // Look for end of list
  722. pLoop = zclSS_ZoneTable;
  723. while ( pLoop->next != NULL )
  724. pLoop = pLoop->next;
  725. // Put new item at end of list
  726. pLoop->next = pNewItem;
  727. }
  728. return ( ZSuccess );
  729. }
  730. /*********************************************************************
  731. * @fn zclSS_CountAllZones
  732. *
  733. * @brief Count the total number of zones
  734. *
  735. * @param none
  736. *
  737. * @return number of zones
  738. */
  739. uint8 zclSS_CountAllZones( void )
  740. {
  741. zclSS_ZoneItem_t *pLoop;
  742. uint8 cnt = 0;
  743. // Look for end of list
  744. pLoop = zclSS_ZoneTable;
  745. while ( pLoop )
  746. {
  747. cnt++;
  748. pLoop = pLoop->next;
  749. }
  750. return ( cnt );
  751. }
  752. /*********************************************************************
  753. * @fn zclSS_GetNextFreeZoneID
  754. *
  755. * @brief Get the next free zone ID
  756. *
  757. * @param none
  758. *
  759. * @return free zone ID (0-254)
  760. */
  761. static uint8 zclSS_GetNextFreeZoneID( void )
  762. {
  763. static uint8 nextAvailZoneID = 0;
  764. if ( zclSS_ZoneIDAvailable( nextAvailZoneID ) == FALSE )
  765. {
  766. uint8 zoneID = nextAvailZoneID;
  767. // Look for next available zone ID
  768. do
  769. {
  770. if ( ++zoneID == ZCL_SS_MAX_ZONE_ID )
  771. zoneID = 0; // roll over
  772. } while ( (zoneID != nextAvailZoneID) && (zclSS_ZoneIDAvailable( nextAvailZoneID ) == FALSE) );
  773. // Did we found a free zone ID?
  774. if ( zoneID != nextAvailZoneID )
  775. nextAvailZoneID = zoneID;
  776. }
  777. return ( nextAvailZoneID );
  778. }
  779. /*********************************************************************
  780. * @fn zclSS_ZoneIDAvailable
  781. *
  782. * @brief Check to see whether zoneID is available for use
  783. *
  784. * @param zoneID - ID to look for zone
  785. *
  786. * @return TRUE if zoneID is available, FALSE otherwise
  787. */
  788. static uint8 zclSS_ZoneIDAvailable( uint8 zoneID )
  789. {
  790. zclSS_ZoneItem_t *pLoop;
  791. if ( zoneID < ZCL_SS_MAX_ZONE_ID )
  792. {
  793. pLoop = zclSS_ZoneTable;
  794. while ( pLoop )
  795. {
  796. if ( pLoop->zone.zoneID == zoneID )
  797. {
  798. return ( FALSE );
  799. }
  800. pLoop = pLoop->next;
  801. }
  802. // Zone ID not in use
  803. return ( TRUE );
  804. }
  805. return ( FALSE );
  806. }
  807. #endif // ZCL_ZONE
  808. #if defined(ZCL_ZONE) || defined(ZCL_ACE)
  809. /*********************************************************************
  810. * @fn zclSS_FindZone
  811. *
  812. * @brief Find a zone with endpoint and ZoneID
  813. *
  814. * @param endpoint -
  815. * @param zoneID - ID to look for zone
  816. *
  817. * @return a pointer to the zone information, NULL if not found
  818. */
  819. static IAS_ACE_ZoneTable_t *zclSS_FindZone( uint8 endpoint, uint8 zoneID )
  820. {
  821. zclSS_ZoneItem_t *pLoop;
  822. // Look for end of list
  823. pLoop = zclSS_ZoneTable;
  824. while ( pLoop )
  825. {
  826. if ( pLoop->endpoint == endpoint && pLoop->zone.zoneID == zoneID )
  827. {
  828. return ( &(pLoop->zone) );
  829. }
  830. pLoop = pLoop->next;
  831. }
  832. return ( (IAS_ACE_ZoneTable_t *)NULL );
  833. }
  834. /*********************************************************************
  835. * @fn zclSS_RemoveZone
  836. *
  837. * @brief Remove a zone with endpoint and zoneID
  838. *
  839. * @param endpoint -
  840. * @param zoneID - ID to look for zone
  841. *
  842. * @return TRUE if removed, FALSE if not found
  843. */
  844. uint8 zclSS_RemoveZone( uint8 endpoint, uint8 zoneID )
  845. {
  846. zclSS_ZoneItem_t *pLoop;
  847. zclSS_ZoneItem_t *pPrev;
  848. // Look for end of list
  849. pLoop = zclSS_ZoneTable;
  850. pPrev = NULL;
  851. while ( pLoop )
  852. {
  853. if ( pLoop->endpoint == endpoint && pLoop->zone.zoneID == zoneID )
  854. {
  855. if ( pPrev == NULL )
  856. zclSS_ZoneTable = pLoop->next;
  857. else
  858. pPrev->next = pLoop->next;
  859. // Free the memory
  860. osal_mem_free( pLoop );
  861. return ( TRUE );
  862. }
  863. pPrev = pLoop;
  864. pLoop = pLoop->next;
  865. }
  866. return ( FALSE );
  867. }
  868. /*********************************************************************
  869. * @fn zclSS_UpdateZoneAddress
  870. *
  871. * @brief Update Zone Address for zoneID
  872. *
  873. * @param endpoint -
  874. * @param zoneID - ID to look for zone
  875. * @param ieeeAddr - Device IEEE Address
  876. *
  877. * @return none
  878. */
  879. void zclSS_UpdateZoneAddress( uint8 endpoint, uint8 zoneID, uint8 *ieeeAddr )
  880. {
  881. IAS_ACE_ZoneTable_t *zone;
  882. zone = zclSS_FindZone( endpoint, zoneID );
  883. if ( zone != NULL )
  884. {
  885. // Update the zone address
  886. osal_cpyExtAddr( zone->zoneAddress, ieeeAddr );
  887. }
  888. }
  889. #endif // ZCL_ZONE || ZCL_ACE
  890. #ifdef ZCL_ZONE
  891. /*******************************************************************************
  892. * @fn zclSS_ProcessInCmd_ZoneStatus_ChangeNotification
  893. *
  894. * @brief Process in the received StatusChangeNotification Command.
  895. *
  896. * @param pInMsg - pointer to the incoming message
  897. *
  898. * @return ZStatus_t
  899. */
  900. static void zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( zclIncoming_t *pInMsg,
  901. zclSS_AppCallbacks_t *pCBs )
  902. {
  903. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION )
  904. return; // Error ignore the command
  905. if ( pCBs->pfnChangeNotification )
  906. {
  907. zclZoneChangeNotif_t cmd;
  908. cmd.zoneStatus = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
  909. cmd.extendedStatus = pInMsg->pData[2];
  910. pCBs->pfnChangeNotification( &cmd );
  911. }
  912. }
  913. /*******************************************************************************
  914. * @fn zclSS_ProcessInCmd_ZoneStatus_EnrollRequest
  915. *
  916. * @brief Process in the received StatusEnrollRequest Command.
  917. *
  918. * @param pInMsg - pointer to the incoming message
  919. *
  920. * @return ZStatus_t
  921. */
  922. static ZStatus_t zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( zclIncoming_t *pInMsg,
  923. zclSS_AppCallbacks_t *pCBs )
  924. {
  925. IAS_ACE_ZoneTable_t zone;
  926. uint16 zoneType;
  927. uint16 manuCode;
  928. uint8 zoneID;
  929. uint8 status;
  930. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST )
  931. return ( ZFailure ); // Error ignore the command
  932. zoneType = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
  933. manuCode = BUILD_UINT16( pInMsg->pData[2], pInMsg->pData[3] );
  934. if ( zclSS_ZoneTypeSupported( zoneType ) )
  935. {
  936. // What if the entry already exists?????
  937. if ( zclSS_CountAllZones() < ZCL_SS_MAX_ZONES-1 )
  938. {
  939. // Add zone to the table
  940. zoneID = zclSS_GetNextFreeZoneID();
  941. zone.zoneID = zoneID;
  942. zone.zoneType = zoneType;
  943. // The application will fill in the right IEEE Address later
  944. osal_cpyExtAddr( zone.zoneAddress, (void *)zclSS_UknownIeeeAddress );
  945. if ( zclSS_AddZone( pInMsg->msg->endPoint, &zone ) == ZSuccess )
  946. {
  947. status = ZCL_STATUS_SUCCESS;
  948. }
  949. else
  950. {
  951. // CIE does not permit new zones to enroll at this time
  952. status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_NO_ENROLL_PERMIT;
  953. }
  954. }
  955. else
  956. {
  957. // CIE reached its limit of number of enrolled zones
  958. status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_TOO_MANY_ZONES;
  959. }
  960. }
  961. else
  962. {
  963. // Zone type is not known to CIE and is not supported
  964. status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_NOT_SUPPORTED;
  965. }
  966. // Send a response back
  967. zclSS_IAS_Send_ZoneStatusEnrollResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
  968. status, zoneID, true, pInMsg->hdr.transSeqNum );
  969. if ( status == ZCL_STATUS_SUCCESS )
  970. {
  971. // Callback the application so it can fill in the Device IEEE Address
  972. if ( pCBs->pfnEnrollRequest )
  973. {
  974. zclZoneEnrollReq_t req;
  975. req.srcAddr = &(pInMsg->msg->srcAddr);
  976. req.zoneID = zoneID;
  977. req.zoneType = zoneType;
  978. req.manufacturerCode = manuCode;
  979. pCBs->pfnEnrollRequest( &req );
  980. }
  981. }
  982. return ( ZCL_STATUS_CMD_HAS_RSP );
  983. }
  984. /*******************************************************************************
  985. * @fn zclSS_ProcessInCmd_ZoneStatus_EnrollResponse
  986. *
  987. * @brief Process in the received STATUS_ENROLL_RESPONSE Command.
  988. *
  989. * @param pInMsg - pointer to the incoming message
  990. *
  991. * @return ZStatus_t
  992. */
  993. static void zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( zclIncoming_t *pInMsg,
  994. zclSS_AppCallbacks_t *pCBs )
  995. {
  996. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE )
  997. return; // Error ignore the command
  998. if ( pCBs->pfnEnrollResponse )
  999. {
  1000. zclZoneEnrollRsp_t rsp;
  1001. rsp.responseCode = pInMsg->pData[0];
  1002. rsp.zoneID = pInMsg->pData[1];
  1003. pCBs->pfnEnrollResponse( &rsp );
  1004. }
  1005. }
  1006. #endif // ZCL_ZONE
  1007. #ifdef ZCL_ACE
  1008. /*********************************************************************
  1009. * @fn zclSS_ProcessInCmd_ACE_Arm
  1010. *
  1011. * @brief Process in the received Arm Command.
  1012. *
  1013. * @param pInMsg - pointer to the incoming message
  1014. *
  1015. */
  1016. static ZStatus_t zclSS_ProcessInCmd_ACE_Arm( zclIncoming_t *pInMsg,
  1017. zclSS_AppCallbacks_t *pCBs )
  1018. {
  1019. uint8 armNotification;
  1020. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_ARM )
  1021. return ( ZFailure ); // Error ignore the command
  1022. if ( pCBs->pfnACE_Arm )
  1023. {
  1024. armNotification = pCBs->pfnACE_Arm( pInMsg->pData[0] );
  1025. // Send a response back
  1026. zclSS_Send_IAS_ACE_ArmResponse( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
  1027. armNotification, true, pInMsg->hdr.transSeqNum );
  1028. }
  1029. return ( ZCL_STATUS_CMD_HAS_RSP );
  1030. }
  1031. /*********************************************************************
  1032. * @fn zclSS_ProcessInCmd_ACE_Bypass
  1033. *
  1034. * @brief Process in the received Bypass Command.
  1035. *
  1036. * @param pInMsg - pointer to the incoming message
  1037. *
  1038. */
  1039. static void zclSS_ProcessInCmd_ACE_Bypass( zclIncoming_t *pInMsg,
  1040. zclSS_AppCallbacks_t *pCBs )
  1041. {
  1042. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_BYPASS )
  1043. return; // Error ignore the command
  1044. if ( pCBs->pfnACE_Bypass )
  1045. {
  1046. zclACEBypass_t cmd;
  1047. cmd.numberOfZones = pInMsg->pData[0];
  1048. cmd.bypassBuf = &(pInMsg->pData[1]);
  1049. pCBs->pfnACE_Bypass( &cmd ) ;
  1050. }
  1051. }
  1052. /*********************************************************************
  1053. * @fn zclSS_ProcessInCmd_ACE_Emergency
  1054. *
  1055. * @brief Process in the received Emergency Command.
  1056. *
  1057. * @param pInMsg - pointer to the incoming message
  1058. *
  1059. */
  1060. static void zclSS_ProcessInCmd_ACE_Emergency( zclIncoming_t *pInMsg,
  1061. zclSS_AppCallbacks_t *pCBs )
  1062. {
  1063. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_EMERGENCY )
  1064. return; // Error ignore the command
  1065. if ( pCBs->pfnACE_Emergency )
  1066. pCBs->pfnACE_Emergency();
  1067. }
  1068. /*********************************************************************
  1069. * @fn zclSS_ProcessInCmd_ACE_Fire
  1070. *
  1071. * @brief Process in the received Fire Command.
  1072. *
  1073. * @param pInMsg - pointer to the incoming message
  1074. *
  1075. */
  1076. static void zclSS_ProcessInCmd_ACE_Fire( zclIncoming_t *pInMsg,
  1077. zclSS_AppCallbacks_t *pCBs )
  1078. {
  1079. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_FIRE )
  1080. return; // Error ignore the command
  1081. if ( pCBs->pfnACE_Fire )
  1082. pCBs->pfnACE_Fire();
  1083. }
  1084. /*********************************************************************
  1085. * @fn zclSS_ProcessInCmd_ACE_Panic
  1086. *
  1087. * @brief Process in the received Panic Command.
  1088. *
  1089. * @param pInMsg - pointer to the incoming message
  1090. *
  1091. */
  1092. static void zclSS_ProcessInCmd_ACE_Panic( zclIncoming_t *pInMsg,
  1093. zclSS_AppCallbacks_t *pCBs )
  1094. {
  1095. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_PANIC )
  1096. return; // Error ignore the command
  1097. if ( pCBs->pfnACE_Panic )
  1098. pCBs->pfnACE_Panic();
  1099. }
  1100. /*********************************************************************
  1101. * @fn zclSS_ProcessInCmd_ACE_GetZoneIDMap
  1102. *
  1103. * @brief Process in the received GetZoneIDMap Command.
  1104. *
  1105. * @param pInMsg - pointer to the incoming message
  1106. *
  1107. */
  1108. static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneIDMap( zclIncoming_t *pInMsg )
  1109. {
  1110. uint16 zoneIDMap[16];
  1111. uint16 mapSection;
  1112. uint8 zoneID;
  1113. uint8 i, j;
  1114. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP )
  1115. return ( ZFailure ); // Error ignore the command
  1116. for ( i = 0; i < 16; i++ )
  1117. {
  1118. mapSection = 0;
  1119. // Find out Zone IDs that are allocated for this map section
  1120. for ( j = 0; j < 16; j++ )
  1121. {
  1122. zoneID = 16 * i + j;
  1123. if ( zclSS_FindZone( pInMsg->msg->endPoint, zoneID ) != NULL )
  1124. {
  1125. // Set the corresponding bit
  1126. mapSection |= (0x01 << j );
  1127. }
  1128. }
  1129. zoneIDMap[i] = mapSection;
  1130. }
  1131. // Send a response back
  1132. zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
  1133. zoneIDMap, true, pInMsg->hdr.transSeqNum );
  1134. return ( ZCL_STATUS_CMD_HAS_RSP );
  1135. }
  1136. /*********************************************************************
  1137. * @fn zclSS_ProcessInCmd_ACE_GetZoneInformation
  1138. *
  1139. * @brief Process in the received GetZoneInformation Command.
  1140. *
  1141. * @param pInMsg - pointer to the incoming message
  1142. *
  1143. */
  1144. static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneInformation( zclIncoming_t *pInMsg )
  1145. {
  1146. IAS_ACE_ZoneTable_t zone;
  1147. IAS_ACE_ZoneTable_t *pZone;
  1148. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION )
  1149. return ( ZFailure ); // Error ignore the command
  1150. pZone = zclSS_FindZone( pInMsg->msg->endPoint, pInMsg->pData[0] );
  1151. if ( pZone == NULL )
  1152. {
  1153. // Zone not found
  1154. pZone = &zone;
  1155. pZone->zoneID = pInMsg->pData[0];
  1156. pZone->zoneType = SS_IAS_ZONE_TYPE_INVALID_ZONE_TYPE;
  1157. osal_cpyExtAddr( pZone->zoneAddress, (void *)zclSS_UknownIeeeAddress );
  1158. }
  1159. // Send a response back
  1160. zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
  1161. pZone->zoneID, pZone->zoneType,
  1162. pZone->zoneAddress, true, pInMsg->hdr.transSeqNum );
  1163. return ( ZCL_STATUS_CMD_HAS_RSP );
  1164. }
  1165. /*********************************************************************
  1166. * @fn zclSS_ProcessInCmd_ACE_ArmResponse
  1167. *
  1168. * @brief Process in the received Arm Response Command.
  1169. *
  1170. * @param pInMsg - pointer to the incoming message
  1171. *
  1172. */
  1173. static void zclSS_ProcessInCmd_ACE_ArmResponse( zclIncoming_t *pInMsg,
  1174. zclSS_AppCallbacks_t *pCBs )
  1175. {
  1176. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_ARM_RESPONSE )
  1177. return; // Error ignore the command
  1178. if ( pCBs->pfnACE_ArmResponse )
  1179. pCBs->pfnACE_ArmResponse(pInMsg->pData[0]);
  1180. }
  1181. /*********************************************************************
  1182. * @fn zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse
  1183. *
  1184. * @brief Process in the received GetZoneIDMapResponse Command.
  1185. *
  1186. * @param pInMsg - pointer to the incoming message
  1187. *
  1188. */
  1189. static void zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( zclIncoming_t *pInMsg,
  1190. zclSS_AppCallbacks_t *pCBs )
  1191. {
  1192. uint16 *buf;
  1193. uint16 *pIndex;
  1194. uint8 *pData;
  1195. uint8 i, len = 32; // 16 fields of 2 octects
  1196. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE )
  1197. return; // Error ignore the command
  1198. buf = osal_mem_alloc( len );
  1199. if ( buf )
  1200. {
  1201. pIndex = buf;
  1202. pData = pInMsg->pData;
  1203. for ( i = 0; i < 16; i++ )
  1204. {
  1205. *pIndex++ = BUILD_UINT16( pData[0], pData[1] );
  1206. pData += 2;
  1207. }
  1208. if ( pCBs->pfnACE_GetZoneIDMapResponse )
  1209. pCBs->pfnACE_GetZoneIDMapResponse( buf );
  1210. osal_mem_free( buf );
  1211. }
  1212. }
  1213. /*********************************************************************
  1214. * @fn zclSS_ProcessInCmd_ACE_GetZoneInformationResponse
  1215. *
  1216. * @brief Process in the received GetZoneInformationResponse Command.
  1217. *
  1218. * @param pInMsg - pointer to the incoming message
  1219. *
  1220. */
  1221. static void zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( zclIncoming_t *pInMsg,
  1222. zclSS_AppCallbacks_t *pCBs )
  1223. {
  1224. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE )
  1225. return; // Error ignore the command
  1226. if ( pCBs->pfnACE_GetZoneInformationResponse )
  1227. {
  1228. zclACEGetZoneInfoRsp_t rsp;
  1229. rsp.zoneID = pInMsg->pData[0];
  1230. rsp.zoneType = BUILD_UINT16( pInMsg->pData[1], pInMsg->pData[2] );
  1231. rsp.ieeeAddr = &(pInMsg->pData[3]);
  1232. pCBs->pfnACE_GetZoneInformationResponse( &rsp );
  1233. }
  1234. }
  1235. #endif // ZCL_ACE
  1236. #ifdef ZCL_WD
  1237. /*********************************************************************
  1238. * @fn zclSS_ProcessInWDCmds
  1239. *
  1240. * @brief Callback from ZCL to process incoming Commands specific
  1241. * to this cluster library on a command ID basis
  1242. * @param pInMsg - pointer to the incoming message
  1243. *
  1244. * @return ZStatus_t
  1245. */
  1246. static ZStatus_t zclSS_ProcessInWDCmds( zclIncoming_t *pInMsg,
  1247. zclSS_AppCallbacks_t *pCBs )
  1248. {
  1249. ZStatus_t stat = ZSuccess;
  1250. switch ( pInMsg->hdr.commandID )
  1251. {
  1252. case COMMAND_SS_IAS_WD_START_WARNING:
  1253. zclSS_ProcessInCmd_WD_StartWarning( pInMsg, pCBs );
  1254. break;
  1255. case COMMAND_SS_IAS_WD_SQUAWK:
  1256. zclSS_ProcessInCmd_WD_Squawk( pInMsg, pCBs );
  1257. break;
  1258. default:
  1259. stat = ZFailure;
  1260. break;
  1261. }
  1262. return ( stat );
  1263. }
  1264. /*********************************************************************
  1265. * @fn zclSS_ProcessInCmd_WD_StartWarning
  1266. *
  1267. * @brief Process in the received StartWarning Command.
  1268. *
  1269. * @param pInMsg - pointer to the incoming message
  1270. *
  1271. */
  1272. static void zclSS_ProcessInCmd_WD_StartWarning( zclIncoming_t *pInMsg,
  1273. zclSS_AppCallbacks_t *pCBs )
  1274. {
  1275. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_WD_START_WARNING )
  1276. return; // Error ignore the command
  1277. if ( pCBs->pfnWD_StartWarning )
  1278. {
  1279. zclWDStartWarning_t cmd;
  1280. cmd.warnings.warningbyte = pInMsg->pData[0];
  1281. cmd.duration = BUILD_UINT16( pInMsg->pData[1], pInMsg->pData[2] );
  1282. pCBs->pfnWD_StartWarning( &cmd );
  1283. }
  1284. }
  1285. /*********************************************************************
  1286. * @fn zclSS_ProcessInCmd_WD_Squawk
  1287. *
  1288. * @brief Process in the received Squawk Command.
  1289. *
  1290. * @param pInMsg - pointer to the incoming message
  1291. *
  1292. */
  1293. static void zclSS_ProcessInCmd_WD_Squawk( zclIncoming_t *pInMsg,
  1294. zclSS_AppCallbacks_t *pCBs )
  1295. {
  1296. zclCmdSSWDSquawkPayload_t squawk;
  1297. if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_WD_SQUAWK )
  1298. return; // Error ignore the command
  1299. if ( pCBs->pfnWD_Squawk )
  1300. {
  1301. squawk.squawkbyte = pInMsg->pData[0];
  1302. pCBs->pfnWD_Squawk( squawk );
  1303. }
  1304. }
  1305. #endif // ZCL_WD
  1306. /*******************************************************************************
  1307. *******************************************************************************/