1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397 |
- /**************************************************************************************************
- Filename: zcl_general.c
- Revised: $Date: 2011-12-14 16:30:16 -0800 (Wed, 14 Dec 2011) $
- Revision: $Revision: 28678 $
- Description: Zigbee Cluster Library - General. This application receives all
- ZCL messages and initially parses them before passing to application.
- Copyright 2006-2011 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- **************************************************************************************************/
- /*********************************************************************
- * INCLUDES
- */
- #include "ZComDef.h"
- #include "OSAL.h"
- #include "OSAL_Nv.h"
- #include "zcl.h"
- #include "zcl_general.h"
- #include "ZDApp.h"
- #if defined ( INTER_PAN )
- #include "stub_aps.h"
- #endif
- /*********************************************************************
- * MACROS
- */
- #define locationTypeAbsolute( a ) ( (a) & LOCATION_TYPE_ABSOLUTE )
- #define locationType2D( a ) ( (a) & LOCATION_TYPE_2_D )
- #define locationTypeCoordinateSystem( a ) ( (a) & LOCATION_TYPE_COORDINATE_SYSTEM )
- #ifdef ZCL_SCENES
- #define zclGeneral_ScenesRemaingCapacity() ( ZCL_GEN_MAX_SCENES - zclGeneral_CountAllScenes() )
- #endif // ZCL_SCENES
- /*********************************************************************
- * CONSTANTS
- */
- /*********************************************************************
- * TYPEDEFS
- */
- typedef struct zclGenCBRec
- {
- struct zclGenCBRec *next;
- uint8 endpoint; // Used to link it into the endpoint descriptor
- zclGeneral_AppCallbacks_t *CBs; // Pointer to Callback function
- } zclGenCBRec_t;
- typedef struct zclGenSceneItem
- {
- struct zclGenSceneItem *next;
- uint8 endpoint; // Used to link it into the endpoint descriptor
- zclGeneral_Scene_t scene; // Scene info
- } zclGenSceneItem_t;
- typedef struct zclGenAlarmItem
- {
- struct zclGenAlarmItem *next;
- uint8 endpoint; // Used to link it into the endpoint descriptor
- zclGeneral_Alarm_t alarm; // Alarm info
- } zclGenAlarmItem_t;
- // Scene NV types
- typedef struct
- {
- uint16 numRecs;
- } nvGenScenesHdr_t;
- typedef struct zclGenSceneNVItem
- {
- uint8 endpoint;
- zclGeneral_Scene_t scene;
- } zclGenSceneNVItem_t;
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- /*********************************************************************
- * GLOBAL FUNCTIONS
- */
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static zclGenCBRec_t *zclGenCBs = (zclGenCBRec_t *)NULL;
- static uint8 zclGenPluginRegisted = FALSE;
- #ifdef ZCL_SCENES
- static zclGenSceneItem_t *zclGenSceneTable = (zclGenSceneItem_t *)NULL;
- #endif // ZCL_SCENES
- #ifdef ZCL_ALARMS
- static zclGenAlarmItem_t *zclGenAlarmTable = (zclGenAlarmItem_t *)NULL;
- #endif // ZCL_ALARMS
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- static ZStatus_t zclGeneral_HdlIncoming( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_HdlInSpecificCommands( zclIncoming_t *pInMsg );
- static zclGeneral_AppCallbacks_t *zclGeneral_FindCallbacks( uint8 endpoint );
- // Device Configuration and Installation clusters
- #ifdef ZCL_BASIC
- static ZStatus_t zclGeneral_ProcessInBasic( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_BASIC
- #ifdef ZCL_IDENTIFY
- static ZStatus_t zclGeneral_ProcessInIdentity( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_IDENTIFY
- // Groups and Scenes clusters
- #ifdef ZCL_GROUPS
- static ZStatus_t zclGeneral_ProcessInGroupsServer( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInGroupsClient( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- static ZStatus_t zclGeneral_AddGroup( uint8 endPoint, aps_Group_t *group, uint8 *pData );
- #endif // ZCL_GROUPS
- #ifdef ZCL_SCENES
- static ZStatus_t zclGeneral_ProcessInScenesServer( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- static ZStatus_t zclGeneral_ProcessInScenesClient( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_SCENES
- // On/Off and Level Control Configuration clusters
- #ifdef ZCL_ON_OFF
- static ZStatus_t zclGeneral_ProcessInOnOff( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_ONOFF
- #ifdef ZCL_LEVEL_CTRL
- static ZStatus_t zclGeneral_ProcessInLevelControl( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_LEVEL_CTRL
- // Alarms cluster
- #ifdef ZCL_ALARMS
- static ZStatus_t zclGeneral_ProcessInAlarmsServer( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- static ZStatus_t zclGeneral_ProcessInAlarmsClient( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_ALARMS
- // Location cluster
- #ifdef ZCL_LOCATION
- static ZStatus_t zclGeneral_ProcessInLocationServer( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- static ZStatus_t zclGeneral_ProcessInLocationClient( zclIncoming_t *pInMsg, zclGeneral_AppCallbacks_t *pCBs );
- #endif // ZCL_LOCATION
- #ifdef ZCL_SCENES
- static uint8 zclGeneral_ScenesInitNV( void );
- static void zclGeneral_ScenesSetDefaultNV( void );
- static void zclGeneral_ScenesWriteNV( void );
- static uint16 zclGeneral_ScenesRestoreFromNV( void );
- #endif // ZCL_SCENES
- /*********************************************************************
- * @fn zclGeneral_RegisterCmdCallbacks
- *
- * @brief Register an applications command callbacks
- *
- * @param endpoint - application's endpoint
- * @param callbacks - pointer to the callback record.
- *
- * @return ZMemError if not able to allocate
- */
- ZStatus_t zclGeneral_RegisterCmdCallbacks( uint8 endpoint, zclGeneral_AppCallbacks_t *callbacks )
- {
- zclGenCBRec_t *pNewItem;
- zclGenCBRec_t *pLoop;
- // Register as a ZCL Plugin
- if ( zclGenPluginRegisted == FALSE )
- {
- zcl_registerPlugin( ZCL_CLUSTER_ID_GEN_BASIC,
- ZCL_CLUSTER_ID_GEN_MULTISTATE_VALUE_BASIC,
- zclGeneral_HdlIncoming );
- #ifdef ZCL_SCENES
- // Initialize NV items
- zclGeneral_ScenesInitNV();
- // Restore the Scene table
- zclGeneral_ScenesRestoreFromNV();
- #endif // ZCL_SCENES
- zclGenPluginRegisted = TRUE;
- }
- // Fill in the new profile list
- pNewItem = osal_mem_alloc( sizeof( zclGenCBRec_t ) );
- if ( pNewItem == NULL )
- return (ZMemError);
- pNewItem->next = (zclGenCBRec_t *)NULL;
- pNewItem->endpoint = endpoint;
- pNewItem->CBs = callbacks;
- // Find spot in list
- if ( zclGenCBs == NULL )
- {
- zclGenCBs = pNewItem;
- }
- else
- {
- // Look for end of list
- pLoop = zclGenCBs;
- while ( pLoop->next != NULL )
- pLoop = pLoop->next;
- // Put new item at end of list
- pLoop->next = pNewItem;
- }
- return ( ZSuccess );
- }
- #ifdef ZCL_IDENTIFY
- /*********************************************************************
- * @fn zclGeneral_SendIdentify
- *
- * @brief Call to send out an Identify Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param identifyTime - how long the device will continue to identify itself (in seconds)
- * @param seqNum - identification number for the transaction
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendIdentify( uint8 srcEP, afAddrType_t *dstAddr,
- uint16 identifyTime, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[2];
- buf[0] = LO_UINT16( identifyTime );
- buf[1] = HI_UINT16( identifyTime );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_IDENTIFY,
- COMMAND_IDENTIFY, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 2, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendIdentifyQueryResponse
- *
- * @brief Call to send out an Identify Query Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param timeout - how long the device will continue to identify itself (in seconds)
- * @param seqNum - identification number for the transaction
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendIdentifyQueryResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint16 timeout, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[2];
- buf[0] = LO_UINT16( timeout );
- buf[1] = HI_UINT16( timeout );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_IDENTIFY,
- COMMAND_IDENTIFY_QUERY_RSP, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 2, buf );
- }
- #endif // ZCL_IDENTIFY
- #ifdef ZCL_GROUPS
- /*********************************************************************
- * @fn zclGeneral_SendGroupRequest
- *
- * @brief Send a Group Request to a device. You can also use the
- * appropriate macro.
- *
- * @param srcEP - Sending Apps endpoint
- * @param dstAddr - where to send the request
- * @param cmd - one of the following:
- * COMMAND_GROUP_VIEW
- * COMMAND_GROUP_REMOVE
- * @param groupID -
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendGroupRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint16 groupID, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[2];
- buf[0] = LO_UINT16( groupID );
- buf[1] = HI_UINT16( groupID );
- return ( zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_GROUPS,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 2, buf ) );
- }
- /*********************************************************************
- * @fn zclGeneral_SendAddGroupRequest
- *
- * @brief Send the Add Group Request to a device
- *
- * @param srcEP - Sending Apps endpoint
- * @param dstAddr - where to send the request
- * @param cmd - one of the following:
- * COMMAND_GROUP_ADD
- * COMMAND_GROUP_ADD_IF_IDENTIFYING
- * @param groupID - pointer to the group structure
- * @param groupName - pointer to Group Name. This is a Zigbee
- * string data type, so the first byte is the length of the
- * name (in bytes), then the name.
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAddGroupRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint16 groupID, uint8 *groupName,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 len;
- ZStatus_t status;
- len = 2; // Group ID
- len += groupName[0] + 1; // String + 1 for length
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- pBuf = buf;
- *pBuf++ = LO_UINT16( groupID );
- *pBuf++ = HI_UINT16( groupID );
- *pBuf++ = groupName[0]; // string length
- osal_memcpy( pBuf, &(groupName[1]), groupName[0] );
- status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_GROUPS,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- status = ZMemError;
- return ( status );
- }
- /*********************************************************************
- * @fn zclGeneral_SendGroupGetMembershipRequest
- *
- * @brief Send a Get Group Membership (Resposne) Command to a device
- *
- * @param srcEP - Sending Apps endpoint
- * @param dstAddr - where to send the request
- * @param cmd - one of the following:
- * COMMAND_GROUP_GET_MEMBERSHIP
- * COMMAND_GROUP_GET_MEMBERSHIP_RSP
- * @param groupID - pointer to the group structure
- * @param groupName - pointer to Group Name. This is a Zigbee
- * string data type, so the first byte is the length of the
- * name (in bytes), then the name.
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendGroupGetMembershipRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 rspCmd, uint8 direction, uint8 capacity,
- uint8 grpCnt, uint16 *grpList, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 len = 0;
- uint8 i;
- ZStatus_t status;
- if ( rspCmd )
- len++; // Capacity
- len++; // Group Count
- len += sizeof ( uint16 ) * grpCnt; // Group List
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- pBuf = buf;
- if ( rspCmd )
- *pBuf++ = capacity;
- *pBuf++ = grpCnt;
- for ( i = 0; i < grpCnt; i++ )
- {
- *pBuf++ = LO_UINT16( grpList[i] );
- *pBuf++ = HI_UINT16( grpList[i] );
- }
- status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_GROUPS,
- cmd, TRUE, direction,
- disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- status = ZMemError;
- return ( status );
- }
- /*********************************************************************
- * @fn zclGeneral_SendGroupResponse
- *
- * @brief Send Group Response (not Group View Response)
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - either COMMAND_GROUP_ADD_RSP or COMMAND_GROUP_REMOVE_RSP
- * @param status - group command status
- * @param groupID - what group
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendGroupResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 status, uint16 groupID,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[3];
- buf[0] = status;
- buf[1] = LO_UINT16( groupID );
- buf[2] = HI_UINT16( groupID );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_GROUPS,
- cmd, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, 3, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendGroupViewResponse
- *
- * @brief Call to send Group Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - either COMMAND_GROUP_ADD_RSP or COMMAND_GROUP_REMOVE_RSP
- * @param status - group command status
- * @param grp - group info
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendGroupViewResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 status, aps_Group_t *grp, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 len;
- ZStatus_t stat;
- len = 1 + 2; // Status + Group ID
- if ( status == ZCL_STATUS_SUCCESS )
- len += grp->name[0] + 1; // String + 1 for length
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- buf[0] = status;
- buf[1] = LO_UINT16( grp->ID );
- buf[2] = HI_UINT16( grp->ID );
- if ( status == ZCL_STATUS_SUCCESS )
- {
- buf[3] = grp->name[0]; // string length
- osal_memcpy( &buf[4], (&grp->name[1]), grp->name[0] );
- }
- stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_GROUPS,
- COMMAND_GROUP_VIEW_RSP, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- stat = ZMemError;
- return ( stat );
- }
- #endif // ZCL_GROUPS
- #ifdef ZCL_SCENES
- /*********************************************************************
- * @fn zclGeneral_SendAddScene
- *
- * @brief Send the Add Scene Request to a device
- *
- * @param srcEP - Sending Apps endpoint
- * @param dstAddr - where to send the request
- * @param scene - pointer to the scene structure
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAddScene( uint8 srcEP, afAddrType_t *dstAddr,
- zclGeneral_Scene_t *scene, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 len;
- ZStatus_t status;
- len = 2 + 1 + 2; // Group ID + Scene ID + transition time
- len += scene->name[0] + 1; // String + 1 for length
- // Add something for the extension field length
- len += scene->extLen;
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- pBuf = buf;
- *pBuf++ = LO_UINT16( scene->groupID );
- *pBuf++ = HI_UINT16( scene->groupID );
- *pBuf++ = scene->ID;
- *pBuf++ = LO_UINT16( scene->transTime );
- *pBuf++ = HI_UINT16( scene->transTime );
- *pBuf++ = scene->name[0]; // string length
- osal_memcpy( pBuf, &(scene->name[1]), scene->name[0] );
- pBuf += scene->name[0]; // move pass name
- // Add the extension fields
- if ( scene->extLen > 0 )
- osal_memcpy( pBuf, scene->extField, scene->extLen );
- status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_SCENES,
- COMMAND_SCENE_ADD, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- status = ZMemError;
- return ( status );
- }
- /*********************************************************************
- * @fn zclGeneral_SendSceneRequest
- *
- * @brief Send a Scene Request to a device. You can also use the
- * appropriate macro.
- *
- * @param srcEP - Sending Apps endpoint
- * @param dstAddr - where to send the request
- * @param cmd - one of the following:
- * COMMAND_SCENE_VIEW
- * COMMAND_SCENE_REMOVE
- * COMMAND_SCENE_REMOVE_ALL
- * COMMAND_SCENE_STORE
- * COMMAND_SCENE_RECALL
- * COMMAND_SCENE_GET_MEMBERSHIP
- * @param groupID - group ID
- * @param sceneID - scene ID (not applicable to COMMAND_SCENE_REMOVE_ALL and
- * COMMAND_SCENE_GET_MEMBERSHIP)
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendSceneRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint16 groupID, uint8 sceneID,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[3];
- uint8 len = 2;
- buf[0] = LO_UINT16( groupID );
- buf[1] = HI_UINT16( groupID );
- if ( cmd != COMMAND_SCENE_REMOVE_ALL && cmd != COMMAND_SCENE_GET_MEMBERSHIP )
- {
- buf[2] = sceneID;
- len++;
- }
- return ( zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_SCENES,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, len, buf ) );
- }
- /*********************************************************************
- * @fn zclGeneral_SendSceneResponse
- *
- * @brief Send Group Response (not Group View Response)
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - either COMMAND_SCENE_ADD_RSP, COMMAND_SCENE_REMOVE_RSP
- * COMMAND_SCENE_STORE_RSP, or COMMAND_SCENE_REMOVE_ALL_RSP
- * @param status - scene command status
- * @param groupID - what group
- * @param sceneID - what scene (not applicable to COMMAND_SCENE_REMOVE_ALL_RSP)
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendSceneResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 status, uint16 groupID,
- uint8 sceneID, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[4];
- uint8 len = 1 + 2; // Status + Group ID
- buf[0] = status;
- buf[1] = LO_UINT16( groupID );
- buf[2] = HI_UINT16( groupID );
- if ( cmd != COMMAND_SCENE_REMOVE_ALL_RSP )
- {
- buf[3] = sceneID;
- len++;
- }
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_SCENES,
- cmd, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendSceneViewResponse
- *
- * @brief Call to send Scene Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - scene command status
- * @param scene - scene info
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendSceneViewResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 status, zclGeneral_Scene_t *scene,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 len = 1 + 2 + 1; // Status + Group ID + Scene ID
- ZStatus_t stat;
- if ( status == ZCL_STATUS_SUCCESS )
- {
- len += 2; // Transition Time
- len += scene->name[0] + 1; // string + 1 for length
- // Add something for the extension field length
- len += scene->extLen;
- }
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- pBuf = buf;
- *pBuf++ = status;
- *pBuf++ = LO_UINT16( scene->groupID );
- *pBuf++ = HI_UINT16( scene->groupID );
- *pBuf++ = scene->ID;
- if ( status == ZCL_STATUS_SUCCESS )
- {
- *pBuf++ = LO_UINT16( scene->transTime );
- *pBuf++ = HI_UINT16( scene->transTime );
- *pBuf++ = scene->name[0]; // string length
- if ( scene->name[0] != 0 )
- {
- osal_memcpy( pBuf, &(scene->name[1]), scene->name[0] );
- pBuf += scene->name[0]; // move pass name
- }
- // Add the extension fields
- if ( scene->extLen > 0 )
- osal_memcpy( pBuf, scene->extField, scene->extLen );
- }
- stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_SCENES,
- COMMAND_SCENE_VIEW_RSP, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- stat = ZMemError;
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_SendSceneGetMembershipResponse
- *
- * @brief Call to send Scene Get Membership Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - scene command status
- * @param capacity - remaining capacity of the scene table
- * @param sceneCnt - number of scenes in the scene list
- * @param sceneList - list of scene IDs
- * @param groupID - group ID that scene belongs to
- * @param seqNum - sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendSceneGetMembershipResponse( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 status, uint8 capacity, uint8 sceneCnt, uint8 *sceneList,
- uint16 groupID, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 len = 1 + 1 + 2; // Status + Capacity + Group ID;
- uint8 i;
- ZStatus_t stat;
- if ( status == ZCL_STATUS_SUCCESS )
- {
- len++; // Scene Count
- len += sceneCnt; // Scene List (Scene ID is a single octet)
- }
- buf = osal_mem_alloc( len );
- if ( buf )
- {
- pBuf = buf;
- *pBuf++ = status;
- *pBuf++ = capacity;
- *pBuf++ = LO_UINT16( groupID );
- *pBuf++ = HI_UINT16( groupID );
- if ( status == ZCL_STATUS_SUCCESS )
- {
- *pBuf++ = sceneCnt;
- for ( i = 0; i < sceneCnt; i++ )
- *pBuf++ = sceneList[i];
- }
- stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_SCENES,
- COMMAND_SCENE_GET_MEMBERSHIP_RSP, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
- osal_mem_free( buf );
- }
- else
- stat = ZMemError;
- return ( stat );
- }
- #endif // ZCL_SCENES
- #ifdef ZCL_LEVEL_CTRL
- /*********************************************************************
- * @fn zclGeneral_SendLevelControlMoveToLevelRequest
- *
- * @brief Call to send out a Level Control Request. You can also use
- * the appropriate macro.
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - one of the following:
- * COMMAND_LEVEL_MOVE_TO_LEVEL or
- * COMMAND_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF
- * @param level - what level to move to
- * @param transitionTime - how long to take to get to the level (in seconds)
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLevelControlMoveToLevelRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 level, uint16 transTime,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[3];
- buf[0] = level;
- buf[1] = LO_UINT16( transTime );
- buf[2] = HI_UINT16( transTime );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 3, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLevelControlMoveRequest
- *
- * @brief Call to send out a Level Control Request. You can also use
- * the appropriate macro.
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - one of the following:
- * COMMAND_LEVEL_MOVE or
- * COMMAND_LEVEL_MOVE_WITH_ON_OFF
- * @param moveMode - LEVEL_MOVE_UP or
- * LEVEL_MOVE_DOWN
- * @param rate - number of steps to take per second
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLevelControlMoveRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 moveMode, uint8 rate,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[2];
- buf[0] = moveMode;
- buf[1] = rate;
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 2, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLevelControlStepRequest
- *
- * @brief Call to send out a Level Control Request. You can also use
- * the appropriate macro.
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - one of the following:
- * COMMAND_LEVEL_STEP
- * COMMAND_LEVEL_STEP_WITH_ON_OFF
- * @param stepMode - LEVEL_STEP_UP or
- * LEVEL_STEP_DOWN
- * @param amount - number of levels to step
- * @param transitionTime - time, in 1/10ths of a second, to take to perform the step
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLevelControlStepRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 stepMode, uint8 stepSize, uint16 transTime,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[4];
- buf[0] = stepMode;
- buf[1] = stepSize;
- buf[2] = LO_UINT16( transTime );
- buf[3] = HI_UINT16( transTime );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 4, buf );
- }
- #endif // ZCL_LEVEL_CTRL
- #ifdef ZCL_ALARMS
- /*********************************************************************
- * @fn zclGeneral_SendAlarmRequest
- *
- * @brief Call to send out an Alarm Request Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param cmd - either COMMAND_ALARMS_RESET or COMMAND_ALARMS_ALARM
- * @param alarmCode - code for the cause of the alarm
- * @param clusterID - cluster whose attribute generate the alarm
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAlarmRequest( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 cmd, uint8 alarmCode, uint16 clusterID,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[3];
- buf[0] = alarmCode;
- buf[1] = LO_UINT16( clusterID );
- buf[2] = HI_UINT16( clusterID );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_ALARMS,
- cmd, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, 3, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendAlarmGetRespnose
- *
- * @brief Call to send out an Alarm Get Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - SUCCESS or NOT_FOUND
- * @param alarmCode - code for the cause of the alarm
- * @param clusterID - cluster whose attribute generate the alarm
- * @param timeStamp - time at which the alarm occured
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAlarmGetRespnose( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 status, uint8 alarmCode, uint16 clusterID,
- uint32 timeStamp, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[8];
- uint8 len = 1; // Status
- buf[0] = status;
- if ( status == ZCL_STATUS_SUCCESS )
- {
- len += 1 + 2 + 4; // Alarm code + Cluster ID + Time stamp
- buf[1] = alarmCode;
- buf[2] = LO_UINT16( clusterID );
- buf[3] = HI_UINT16( clusterID );
- osal_buffer_uint32( &buf[4], timeStamp );
- }
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_ALARMS,
- COMMAND_ALARMS_GET_RSP, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- }
- #ifdef SE_UK_EXT
- /*********************************************************************
- * @fn zclGeneral_SendAlarmGetEventLog
- *
- * @brief Call to send out an Alarm Get Event Log Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param pEventLog - pointer to Get Event Log Command
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAlarmGetEventLog( uint8 srcEP, afAddrType_t *dstAddr,
- zclGetEventLog_t *pEventLog,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[10];
- buf[0] = pEventLog->logID;
- osal_buffer_uint32( &buf[1], pEventLog->startTime );
- osal_buffer_uint32( &buf[5], pEventLog->endTime );
- buf[9] = pEventLog->numEvents;
-
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_ALARMS,
- COMMAND_ALARMS_GET_EVENT_LOG, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, 10, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendAlarmPublishEventLog
- *
- * @brief Call to send out an Alarm Publish Event Log Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param pEventLog - pointer to Publish Event Log Command
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendAlarmPublishEventLog( uint8 srcEP, afAddrType_t *dstAddr,
- zclPublishEventLog_t *pEventLog,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 bufLen;
-
- // Log ID + Command Index + Total Commands + (numSubLogs * ( Event ID + Event Time))
- bufLen = 1 + 1 + 1 + (pEventLog->numSubLogs * (1 + 4));
-
- buf = osal_mem_alloc( bufLen );
- if ( buf == NULL )
- {
- return (ZMemError);
- }
-
- pBuf = buf;
- *pBuf++ = pEventLog->logID;
- *pBuf++ = pEventLog->cmdIndex;
- *pBuf++ = pEventLog->totalCmds;
-
- for ( uint8 i = 0; i < pEventLog->numSubLogs; i++ )
- {
- zclEventLogPayload_t *pLogs = &(pEventLog->pLogs[i]);
-
- *pBuf++ = pLogs->eventId;
- pBuf = osal_buffer_uint32( pBuf, pLogs->eventTime );
- }
-
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_ALARMS,
- COMMAND_ALARMS_PUBLISH_EVENT_LOG, TRUE, ZCL_FRAME_CLIENT_SERVER_DIR,
- disableDefaultRsp, 0, seqNum, bufLen, buf );
- }
- #endif // SE_UK_EXT
- #endif // ZCL_ALARMS
- #ifdef ZCL_LOCATION
- /*********************************************************************
- * @fn zclGeneral_SendLocationSetAbsolute
- *
- * @brief Call to send out a Set Absolute Location Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param absLoc - absolute location info
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationSetAbsolute( uint8 srcEP, afAddrType_t *dstAddr,
- zclLocationAbsolute_t *absLoc,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[10]; // 5 fields (2 octects each)
- buf[0] = LO_UINT16( absLoc->coordinate1 );
- buf[1] = HI_UINT16( absLoc->coordinate1 );
- buf[2] = LO_UINT16( absLoc->coordinate2 );
- buf[3] = HI_UINT16( absLoc->coordinate2 );
- buf[4] = LO_UINT16( absLoc->coordinate3 );
- buf[5] = HI_UINT16( absLoc->coordinate3 );
- buf[6] = LO_UINT16( absLoc->power );
- buf[7] = HI_UINT16( absLoc->power );
- buf[8] = LO_UINT16( absLoc->pathLossExponent );
- buf[9] = HI_UINT16( absLoc->pathLossExponent );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- COMMAND_LOCATION_SET_ABSOLUTE, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 10, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLocationSetDevCfg
- *
- * @brief Call to send out a Set Device Configuration Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param devCfg - device configuration info
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationSetDevCfg( uint8 srcEP, afAddrType_t *dstAddr,
- zclLocationDevCfg_t *devCfg,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[9]; // 4 fields (2 octects each) + 1 field with 1 octect
- buf[0] = LO_UINT16( devCfg->power );
- buf[1] = HI_UINT16( devCfg->power );
- buf[2] = LO_UINT16( devCfg->pathLossExponent );
- buf[3] = HI_UINT16( devCfg->pathLossExponent );
- buf[4] = LO_UINT16( devCfg->calcPeriod );
- buf[5] = HI_UINT16( devCfg->calcPeriod );
- buf[6] = devCfg->numMeasurements;
- buf[7] = LO_UINT16( devCfg->reportPeriod );
- buf[8] = HI_UINT16( devCfg->reportPeriod );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- COMMAND_LOCATION_SET_DEV_CFG, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 9, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLocationGetDevCfg
- *
- * @brief Call to send out a Get Device Configuration Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param targetAddr - device for which location parameters are being requested
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationGetDevCfg( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 *targetAddr, uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[8];
- osal_cpyExtAddr( buf, targetAddr );
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- COMMAND_LOCATION_GET_DEV_CFG, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 8, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLocationGetData
- *
- * @brief Call to send out a Get Location Data Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param locaData - location information and channel parameters that are requested.
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationGetData( uint8 srcEP, afAddrType_t *dstAddr,
- zclLocationGetData_t *locData,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[10]; // bitmap (1) + number responses (1) + IEEE Address (8)
- uint8 *pBuf = buf;
- uint8 len = 2; // bitmap + number responses
- *pBuf = locData->absoluteOnly;
- *pBuf |= locData->recalculate << 1;
- *pBuf |= locData->brdcastIndicator << 2;
- *pBuf |= locData->brdcastResponse << 3;
- *pBuf |= locData->compactResponse << 4;
- pBuf++; // move past the bitmap field
- *pBuf++ = locData->numResponses;
- if ( locData->brdcastIndicator == 0 )
- {
- osal_cpyExtAddr( pBuf, locData->targetAddr );
- len += 8; // ieee addr
- }
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- COMMAND_LOCATION_GET_DATA, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, len, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLocationDevCfgResponse
- *
- * @brief Call to send out a Device Configuration Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param devCfg - device's location parameters that are requested
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationDevCfgResponse( uint8 srcEP, afAddrType_t *dstAddr,
- zclLocationDevCfgRsp_t *devCfg,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[10]; // 4 fields (2 octects each) + 2 fields (1 octect each)
- uint8 len = 1; // Status
- buf[0] = devCfg->status;
- if ( devCfg->status == ZCL_STATUS_SUCCESS )
- {
- buf[1] = LO_UINT16( devCfg->data.power );
- buf[2] = HI_UINT16( devCfg->data.power );
- buf[3] = LO_UINT16( devCfg->data.pathLossExponent );
- buf[4] = HI_UINT16( devCfg->data.pathLossExponent );
- buf[5] = LO_UINT16( devCfg->data.calcPeriod );
- buf[6] = HI_UINT16( devCfg->data.calcPeriod );
- buf[7] = devCfg->data.numMeasurements;
- buf[8] = LO_UINT16( devCfg->data.reportPeriod );
- buf[9] = HI_UINT16( devCfg->data.reportPeriod );
- len += 9;
- }
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- COMMAND_LOCATION_DEV_CFG_RSP, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_SendLocationData
- *
- * @brief Call to send out location data
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - indicates whether response to request was successful or not
- * @param locData - location information and channel parameters being sent
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_SendLocationData( uint8 srcEP, afAddrType_t *dstAddr, uint8 cmd,
- uint8 status, zclLocationData_t *locData,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[16];
- uint8 *pBuf = buf;
- uint8 len = 0;
- if ( cmd == COMMAND_LOCATION_DATA_RSP )
- {
- // Only response command includes a status field
- *pBuf++ = status;
- len++;
- }
- if ( cmd != COMMAND_LOCATION_DATA_RSP || status == ZCL_STATUS_SUCCESS )
- {
- // Notification or Response with successful status
- *pBuf++ = locData->type;
- *pBuf++ = LO_UINT16( locData->absLoc.coordinate1 );
- *pBuf++ = HI_UINT16( locData->absLoc.coordinate1 );
- *pBuf++ = LO_UINT16( locData->absLoc.coordinate2 );
- *pBuf++ = HI_UINT16( locData->absLoc.coordinate2 );
- len += 5;
- if ( locationType2D(locData->type) == 0 )
- {
- // 2D location doesn't have coordinate 3
- *pBuf++ = LO_UINT16( locData->absLoc.coordinate3 );
- *pBuf++ = HI_UINT16( locData->absLoc.coordinate3 );
- len += 2;
- }
- if ( cmd != COMMAND_LOCATION_COMPACT_DATA_NOTIF )
- {
- // Compact notification doesn't include these fields
- *pBuf++ = LO_UINT16( locData->absLoc.power );
- *pBuf++ = HI_UINT16( locData->absLoc.power );
- *pBuf++ = LO_UINT16( locData->absLoc.pathLossExponent );
- *pBuf++ = HI_UINT16( locData->absLoc.pathLossExponent );
- len += 4;
- }
- if ( locationTypeAbsolute(locData->type) == 0 )
- {
- // Absolute location doesn't include these fields
- if ( cmd != COMMAND_LOCATION_COMPACT_DATA_NOTIF )
- {
- // Compact notification doesn't include this field
- *pBuf++ = locData->calcLoc.locationMethod;
- len++;
- }
- *pBuf++ = locData->calcLoc.qualityMeasure;
- *pBuf++ = LO_UINT16( locData->calcLoc.locationAge );
- *pBuf++ = HI_UINT16( locData->calcLoc.locationAge );
- len += 3;
- }
- }
- return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_GEN_LOCATION,
- cmd, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR,
- disableDefaultRsp, 0, seqNum, len, buf );
- }
- #endif // ZCL_LOCATION
- /*********************************************************************
- * @fn zclGeneral_FindCallbacks
- *
- * @brief Find the callbacks for an endpoint
- *
- * @param endpoint - endpoint to find the application callbacks for
- *
- * @return pointer to the callbacks
- */
- static zclGeneral_AppCallbacks_t *zclGeneral_FindCallbacks( uint8 endpoint )
- {
- zclGenCBRec_t *pCBs;
- pCBs = zclGenCBs;
- while ( pCBs )
- {
- if ( pCBs->endpoint == endpoint )
- return ( pCBs->CBs );
- pCBs = pCBs->next;
- }
- return ( (zclGeneral_AppCallbacks_t *)NULL );
- }
- /*********************************************************************
- * @fn zclGeneral_HdlIncoming
- *
- * @brief Callback from ZCL to process incoming Commands specific
- * to this cluster library or Profile commands for attributes
- * that aren't in the attribute list
- *
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_HdlIncoming( zclIncoming_t *pInMsg )
- {
- ZStatus_t stat = ZSuccess;
- #if defined ( INTER_PAN )
- if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) )
- return ( stat ); // Cluster not supported thru Inter-PAN
- #endif
- if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
- {
- // Is this a manufacturer specific command?
- if ( pInMsg->hdr.fc.manuSpecific == 0 )
- {
- stat = zclGeneral_HdlInSpecificCommands( pInMsg );
- }
- else
- {
- // We don't support any manufacturer specific command.
- stat = ZFailure;
- }
- }
- else
- {
- // Handle all the normal (Read, Write...) commands -- should never get here
- stat = ZFailure;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_HdlInSpecificCommands
- *
- * @brief Callback from ZCL to process incoming Commands specific
- * to this cluster library
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_HdlInSpecificCommands( zclIncoming_t *pInMsg )
- {
- ZStatus_t stat;
- zclGeneral_AppCallbacks_t *pCBs;
- // make sure endpoint exists
- pCBs = zclGeneral_FindCallbacks( pInMsg->msg->endPoint );
- if ( pCBs == NULL )
- return ( ZFailure );
- switch ( pInMsg->msg->clusterId )
- {
- #ifdef ZCL_BASIC
- case ZCL_CLUSTER_ID_GEN_BASIC:
- stat = zclGeneral_ProcessInBasic( pInMsg, pCBs );
- break;
- #endif // ZCL_BASIC
- #ifdef ZCL_IDENTIFY
- case ZCL_CLUSTER_ID_GEN_IDENTIFY:
- stat = zclGeneral_ProcessInIdentity( pInMsg, pCBs );
- break;
- #endif // ZCL_IDENTIFY
- #ifdef ZCL_GROUPS
- case ZCL_CLUSTER_ID_GEN_GROUPS:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInGroupsServer( pInMsg );
- else
- stat = zclGeneral_ProcessInGroupsClient( pInMsg, pCBs );
- break;
- #endif // ZCL_GROUPS
- #ifdef ZCL_SCENES
- case ZCL_CLUSTER_ID_GEN_SCENES:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInScenesServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInScenesClient( pInMsg, pCBs );
- break;
- #endif // ZCL_SCENES
- #ifdef ZCL_ON_OFF
- case ZCL_CLUSTER_ID_GEN_ON_OFF:
- stat = zclGeneral_ProcessInOnOff( pInMsg, pCBs );
- break;
- #endif // ZCL_ON_OFF
- #ifdef ZCL_LEVEL_CTRL
- case ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL:
- stat = zclGeneral_ProcessInLevelControl( pInMsg, pCBs );
- break;
- #endif // ZCL_LEVEL_CTRL
- #ifdef ZCL_ALARMS
- case ZCL_CLUSTER_ID_GEN_ALARMS:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInAlarmsServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInAlarmsClient( pInMsg, pCBs );
- break;
- #endif // ZCL_ALARMS
- #ifdef ZCL_LOCATION
- case ZCL_CLUSTER_ID_GEN_LOCATION:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInLocationServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInLocationClient( pInMsg, pCBs );
- break;
- #endif // ZCL_LOCATION
- case ZCL_CLUSTER_ID_GEN_POWER_CFG:
- case ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG:
- case ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG:
- case ZCL_CLUSTER_ID_GEN_TIME:
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- #ifdef ZCL_BASIC
- /*********************************************************************
- * @fn zclGeneral_ProcessInBasic
- *
- * @brief Process in the received Basic Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInBasic( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- {
- if ( pInMsg->hdr.commandID > COMMAND_BASIC_RESET_FACT_DEFAULT )
- return ( ZFailure ); // Error ignore the command
- if ( pCBs->pfnBasicReset )
- pCBs->pfnBasicReset();
- }
- // no Client command
- return ( ZSuccess );
- }
- #endif // ZCL_BASIC
- #ifdef ZCL_IDENTIFY
- /*********************************************************************
- * @fn zclGeneral_ProcessInIdentity
- *
- * @brief Process in the received Identity Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInIdentity( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- {
- if ( pInMsg->hdr.commandID > COMMAND_IDENTIFY_QUERY )
- return ( ZFailure ); // Error ignore the command
- if ( pInMsg->hdr.commandID == COMMAND_IDENTIFY )
- {
- if ( pCBs->pfnIdentify )
- {
- zclIdentify_t cmd;
- cmd.srcAddr = &(pInMsg->msg->srcAddr);
- cmd.identifyTime = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
- pCBs->pfnIdentify( &cmd );
- }
- }
- else
- {
- zclAttrRec_t attrRec;
- uint16 identifyTime = 0;
- // Retrieve Identify Time
- if ( zclFindAttrRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, ATTRID_IDENTIFY_TIME, &attrRec ) )
- zclReadAttrData( (uint8 *)&identifyTime, &attrRec, NULL );
- // Is device identifying itself?
- if ( identifyTime > 0 )
- {
- zclGeneral_SendIdentifyQueryResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- identifyTime, true, pInMsg->hdr.transSeqNum );
- }
- return ( ZCL_STATUS_CMD_HAS_RSP );
- }
- }
- else // Client Command
- {
- if ( pInMsg->hdr.commandID > COMMAND_IDENTIFY_QUERY_RSP )
- return ( ZFailure ); // Error ignore the command
- if ( pCBs->pfnIdentifyQueryRsp )
- {
- zclIdentifyQueryRsp_t rsp;
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.timeout = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
- pCBs->pfnIdentifyQueryRsp( &rsp );
- }
- }
- return ( ZSuccess );
- }
- #endif // ZCL_IDENTIFY
- #ifdef ZCL_GROUPS
- /*********************************************************************
- * @fn zclGeneral_AddGroup
- *
- * @brief Add a Group.
- *
- * @param endPoint - application endpoint
- * @param group - group to be added
- * @param pData - pointer to the group info
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_AddGroup( uint8 endPoint, aps_Group_t *group, uint8 *pData )
- {
- zclAttrRec_t attrRec;
- uint8 nameLen;
- uint8 nameSupport = FALSE;
- pData += 2; // Move past group ID
- nameLen = *pData++;
- // Retrieve Name Support attribute
- if ( zclFindAttrRec( endPoint, ZCL_CLUSTER_ID_GEN_GROUPS, ATTRID_GROUP_NAME_SUPPORT, &attrRec ) )
- zclReadAttrData( &nameSupport, &attrRec, NULL );
- if ( nameSupport )
- {
- if ( nameLen > (APS_GROUP_NAME_LEN-1) )
- nameLen = (APS_GROUP_NAME_LEN-1);
- group->name[0] = nameLen;
- osal_memcpy( &(group->name[1]), pData, nameLen );
- }
- return ( aps_AddGroup( endPoint, group ) );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInGroupsServer
- *
- * @brief Process in the received Groups Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInGroupsServer( zclIncoming_t *pInMsg )
- {
- zclAttrRec_t attrRec;
- aps_Group_t group;
- aps_Group_t *pGroup;
- uint8 *pData;
- uint8 status;
- uint8 grpCnt;
- uint8 grpRspCnt = 0;
- uint16 *grpList;
- uint16 identifyTime = 0;
- uint8 i;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&group, 0, sizeof( aps_Group_t ) );
- pData = pInMsg->pData;
- group.ID = BUILD_UINT16( pData[0], pData[1] );
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_GROUP_ADD:
- status = zclGeneral_AddGroup( pInMsg->msg->endPoint, &group, pData );
- if ( status != ZSuccess )
- {
- if ( status == ZApsDuplicateEntry )
- status = ZCL_STATUS_DUPLICATE_EXISTS;
- else
- status = ZCL_STATUS_INSUFFICIENT_SPACE;
- }
- zclGeneral_SendGroupAddResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, group.ID, true, pInMsg->hdr.transSeqNum );
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_GROUP_VIEW:
- pGroup = aps_FindGroup( pInMsg->msg->endPoint, group.ID );
- if ( pGroup )
- {
- status = ZCL_STATUS_SUCCESS;
- }
- else
- {
- // Group not found
- status = ZCL_STATUS_NOT_FOUND;
- pGroup = &group;
- }
- zclGeneral_SendGroupViewResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, pGroup, true, pInMsg->hdr.transSeqNum );
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_GROUP_GET_MEMBERSHIP:
- grpCnt = *pData++;
- // Allocate space for the group list
- grpList = osal_mem_alloc( sizeof( uint16 ) * APS_MAX_GROUPS );
- if ( grpList != NULL )
- {
- if ( grpCnt == 0 )
- {
- // Find out all the groups of which the endpoint is a member.
- grpRspCnt = aps_FindAllGroupsForEndpoint( pInMsg->msg->endPoint, grpList );
- }
- else
- {
- // Find out the groups (in the list) of which the endpoint is a member.
- for ( i = 0; i < grpCnt; i++ )
- {
- group.ID = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- if ( aps_FindGroup( pInMsg->msg->endPoint, group.ID ) )
- grpList[grpRspCnt++] = group.ID;
- }
- }
- if ( grpCnt == 0 || grpRspCnt != 0 )
- {
- zclGeneral_SendGroupGetMembershipResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- aps_GroupsRemaingCapacity(), grpRspCnt,
- grpList, true, pInMsg->hdr.transSeqNum );
- }
- osal_mem_free( grpList );
- }
- else
- {
- // Couldn't allocate space for the group list -- send a Default Response command back.
- zclDefaultRspCmd_t defaultRspCmd;
- defaultRspCmd.commandID = pInMsg->hdr.commandID;
- defaultRspCmd.statusCode = ZCL_STATUS_INSUFFICIENT_SPACE;
- zcl_SendDefaultRspCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
- pInMsg->msg->clusterId, &defaultRspCmd,
- ZCL_FRAME_SERVER_CLIENT_DIR, true, 0, pInMsg->hdr.transSeqNum );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_GROUP_REMOVE:
- if ( aps_RemoveGroup( pInMsg->msg->endPoint, group.ID ) )
- status = ZCL_STATUS_SUCCESS;
- else
- status = ZCL_STATUS_NOT_FOUND;
- zclGeneral_SendGroupRemoveResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, group.ID, true, pInMsg->hdr.transSeqNum );
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_GROUP_REMOVE_ALL:
- aps_RemoveAllGroup( pInMsg->msg->endPoint );
- break;
- case COMMAND_GROUP_ADD_IF_IDENTIFYING:
- // Retrieve Identify Time
- if ( zclFindAttrRec( pInMsg->msg->endPoint, ZCL_CLUSTER_ID_GEN_IDENTIFY, ATTRID_IDENTIFY_TIME, &attrRec ) )
- zclReadAttrData( (uint8 *)&identifyTime, &attrRec, NULL );
- // Is device identifying itself?
- if ( identifyTime > 0 )
- zclGeneral_AddGroup( pInMsg->msg->endPoint, &group, pData );
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInGroupsClient
- *
- * @brief Process in the received Groups Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInGroupsClient( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- aps_Group_t group;
- uint8 *pData = pInMsg->pData;
- uint8 grpCnt;
- uint8 nameLen;
- zclGroupRsp_t rsp;
- uint8 i;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&group, 0, sizeof( aps_Group_t ) );
- osal_memset( (uint8*)&rsp, 0, sizeof( zclGroupRsp_t ) );
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_GROUP_ADD_RSP:
- case COMMAND_GROUP_VIEW_RSP:
- case COMMAND_GROUP_REMOVE_RSP:
- rsp.status = *pData++;
- group.ID = BUILD_UINT16( pData[0], pData[1] );
- if ( rsp.status == ZCL_STATUS_SUCCESS && pInMsg->hdr.commandID == COMMAND_GROUP_VIEW_RSP )
- {
- pData += 2; // Move past ID
- nameLen = *pData++;
- if ( nameLen > (APS_GROUP_NAME_LEN-1) )
- nameLen = (APS_GROUP_NAME_LEN-1);
- group.name[0] = nameLen;
- osal_memcpy( &(group.name[1]), pData, nameLen );
- rsp.grpName = group.name;
- }
- if ( pCBs->pfnGroupRsp )
- {
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- rsp.grpCnt = 1;
- rsp.grpList = &group.ID;
- rsp.capacity = 0;
- pCBs->pfnGroupRsp( &rsp );
- }
- break;
- case COMMAND_GROUP_GET_MEMBERSHIP_RSP:
- {
- uint16 *grpList = NULL;
- rsp.capacity = *pData++;
- grpCnt = *pData++;
- if ( grpCnt > 0 )
- {
- // Allocate space for the group list
- grpList = osal_mem_alloc( sizeof( uint16 ) * grpCnt );
- if ( grpList != NULL )
- {
- rsp.grpCnt = grpCnt;
- for ( i = 0; i < grpCnt; i++ )
- {
- grpList[i] = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- }
- }
- }
- if ( pCBs->pfnGroupRsp )
- {
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- rsp.grpList = grpList;
- pCBs->pfnGroupRsp( &rsp );
- }
- if ( grpList != NULL )
- {
- osal_mem_free( grpList );
- }
- }
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- #endif // ZCL_GROUPS
- #ifdef ZCL_SCENES
- /*********************************************************************
- * @fn zclGeneral_AddScene
- *
- * @brief Add a scene for an endpoint
- *
- * @param endpoint -
- * @param scene - new scene item
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_AddScene( uint8 endpoint, zclGeneral_Scene_t *scene )
- {
- zclGenSceneItem_t *pNewItem;
- zclGenSceneItem_t *pLoop;
- // Fill in the new profile list
- pNewItem = osal_mem_alloc( sizeof( zclGenSceneItem_t ) );
- if ( pNewItem == NULL )
- return ( ZMemError );
- // Fill in the plugin record.
- pNewItem->next = (zclGenSceneItem_t *)NULL;
- pNewItem->endpoint = endpoint;
- osal_memcpy( (uint8*)&(pNewItem->scene), (uint8*)scene, sizeof ( zclGeneral_Scene_t ));
- // Find spot in list
- if ( zclGenSceneTable == NULL )
- {
- zclGenSceneTable = pNewItem;
- }
- else
- {
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop->next != NULL )
- pLoop = pLoop->next;
- // Put new item at end of list
- pLoop->next = pNewItem;
- }
- // Update NV
- zclGeneral_ScenesWriteNV();
- return ( ZSuccess );
- }
- /*********************************************************************
- * @fn zclGeneral_FindScene
- *
- * @brief Find a scene with endpoint and sceneID
- *
- * @param endpoint -
- * @param groupID - what group the scene belongs to
- * @param sceneID - ID to look for scene
- *
- * @return a pointer to the scene information, NULL if not found
- */
- zclGeneral_Scene_t *zclGeneral_FindScene( uint8 endpoint, uint16 groupID, uint8 sceneID )
- {
- zclGenSceneItem_t *pLoop;
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop )
- {
- if ( (pLoop->endpoint == endpoint || endpoint == 0xFF)
- && pLoop->scene.groupID == groupID && pLoop->scene.ID == sceneID )
- {
- return ( &(pLoop->scene) );
- }
- pLoop = pLoop->next;
- }
- return ( (zclGeneral_Scene_t *)NULL );
- }
- /*********************************************************************
- * @fn aps_FindAllScensForGroup
- *
- * @brief Find all the scenes with groupID
- *
- * @param endpoint - endpoint to look for
- * @param sceneList - List to hold scene IDs (should hold APS_MAX_SCENES entries)
- *
- * @return number of scenes copied to sceneList
- */
- uint8 zclGeneral_FindAllScenesForGroup( uint8 endpoint, uint16 groupID, uint8 *sceneList )
- {
- zclGenSceneItem_t *pLoop;
- uint8 cnt = 0;
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint && pLoop->scene.groupID == groupID )
- sceneList[cnt++] = pLoop->scene.ID;
- pLoop = pLoop->next;
- }
- return ( cnt );
- }
- /*********************************************************************
- * @fn zclGeneral_RemoveScene
- *
- * @brief Remove a scene with endpoint and sceneID
- *
- * @param endpoint -
- * @param groupID - what group the scene belongs to
- * @param sceneID - ID to look for scene
- *
- * @return TRUE if removed, FALSE if not found
- */
- uint8 zclGeneral_RemoveScene( uint8 endpoint, uint16 groupID, uint8 sceneID )
- {
- zclGenSceneItem_t *pLoop;
- zclGenSceneItem_t *pPrev;
- // Look for end of list
- pLoop = zclGenSceneTable;
- pPrev = NULL;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint
- && pLoop->scene.groupID == groupID && pLoop->scene.ID == sceneID )
- {
- if ( pPrev == NULL )
- zclGenSceneTable = pLoop->next;
- else
- pPrev->next = pLoop->next;
- // Free the memory
- osal_mem_free( pLoop );
- // Update NV
- zclGeneral_ScenesWriteNV();
- return ( TRUE );
- }
- pPrev = pLoop;
- pLoop = pLoop->next;
- }
- return ( FALSE );
- }
- /*********************************************************************
- * @fn zclGeneral_RemoveAllScenes
- *
- * @brief Remove all scenes with endpoint and group Id
- *
- * @param endpoint -
- * @param groupID - ID to look for group
- *
- * @return none
- */
- void zclGeneral_RemoveAllScenes( uint8 endpoint, uint16 groupID )
- {
- zclGenSceneItem_t *pLoop;
- zclGenSceneItem_t *pPrev;
- zclGenSceneItem_t *pNext;
- // Look for end of list
- pLoop = zclGenSceneTable;
- pPrev = NULL;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint && pLoop->scene.groupID == groupID )
- {
- if ( pPrev == NULL )
- zclGenSceneTable = pLoop->next;
- else
- pPrev->next = pLoop->next;
- pNext = pLoop->next;
- // Free the memory
- osal_mem_free( pLoop );
- pLoop = pNext;
- }
- else
- {
- pPrev = pLoop;
- pLoop = pLoop->next;
- }
- }
- // Update NV
- zclGeneral_ScenesWriteNV();
- }
- /*********************************************************************
- * @fn zclGeneral_CountScenes
- *
- * @brief Count the number of scenes for an endpoint
- *
- * @param endpoint -
- *
- * @return number of scenes assigned to an endpoint
- */
- uint8 zclGeneral_CountScenes( uint8 endpoint )
- {
- zclGenSceneItem_t *pLoop;
- uint8 cnt = 0;
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint )
- cnt++;
- pLoop = pLoop->next;
- }
- return ( cnt );
- }
- /*********************************************************************
- * @fn zclGeneral_CountAllScenes
- *
- * @brief Count the total number of scenes
- *
- * @param none
- *
- * @return number of scenes
- */
- uint8 zclGeneral_CountAllScenes( void )
- {
- zclGenSceneItem_t *pLoop;
- uint8 cnt = 0;
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop )
- {
- cnt++;
- pLoop = pLoop->next;
- }
- return ( cnt );
- }
- /*********************************************************************
- * @fn zclGeneral_ReadSceneCountCB
- *
- * @brief Read the number of scenes currently in the device's
- * scene table (i.e., the Scene Count attribute).
- *
- * Note: This function gets called only when the pointer
- * 'dataPtr' to the Scene Count attribute value is
- * NULL in the attribute database registered with
- * the ZCL.
- *
- * @param clusterId - cluster that attribute belongs to
- * @param attrId - attribute to be read
- * @param oper - ZCL_OPER_LEN, ZCL_OPER_READ
- * @param pValue - pointer to attribute value
- * @param pLen - pointer to length of attribute value read
- *
- * @return status
- */
- ZStatus_t zclGeneral_ReadSceneCountCB( uint16 clusterId, uint16 attrId,
- uint8 oper, uint8 *pValue, uint16 *pLen )
- {
- ZStatus_t status = ZCL_STATUS_SUCCESS;
- // This callback function should only be called for the Scene Count attribute
- switch ( oper )
- {
- case ZCL_OPER_LEN:
- *pLen = 1; // uint8
- break;
- case ZCL_OPER_READ:
- *pValue = zclGeneral_CountAllScenes();
- if ( pLen != NULL )
- {
- *pLen = 1;
- }
- break;
- default:
- status = ZCL_STATUS_SOFTWARE_FAILURE; // should never get here!
- break;
- }
- return ( status );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInScenesServer
- *
- * @brief Process in the received Scenes Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInScenesServer( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- zclAttrRec_t attrRec;
- zclGeneral_Scene_t scene;
- zclGeneral_Scene_t *pScene;
- uint8 *pData = pInMsg->pData;
- uint8 nameLen;
- uint8 status;
- uint8 sceneCnt = 0;
- uint8 *sceneList = NULL;
- uint8 sendRsp = FALSE;
- uint8 nameSupport = FALSE;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&scene, 0, sizeof( zclGeneral_Scene_t ) );
- scene.groupID = BUILD_UINT16( pData[0], pData[1] );
- pData += 2; // Move past group ID
- scene.ID = *pData++;
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_SCENE_ADD:
- // Parse the rest of the incoming message
- scene.transTime = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- nameLen= *pData++; // Name length
- // Retrieve Name Support attribute
- if ( zclFindAttrRec( pInMsg->msg->endPoint, ZCL_CLUSTER_ID_GEN_SCENES, ATTRID_SCENES_NAME_SUPPORT, &attrRec ) )
- {
- zclReadAttrData( &nameSupport, &attrRec, NULL );
- }
- if ( nameSupport )
- {
- if ( nameLen > (ZCL_GEN_SCENE_NAME_LEN-1) )
- {
- // truncate to maximum size
- scene.name[0] = ZCL_GEN_SCENE_NAME_LEN-1;
- }
- else
- {
- scene.name[0] = nameLen;
- }
- osal_memcpy( &(scene.name[1]), pData, scene.name[0] );
- }
- pData += nameLen; // move past name, use original length
- scene.extLen = pInMsg->pDataLen - ( (uint16)( pData - pInMsg->pData ) );
- if ( scene.extLen > 0 )
- {
- // Copy the extention field(s)
- if ( scene.extLen > ZCL_GEN_SCENE_EXT_LEN )
- {
- scene.extLen = ZCL_GEN_SCENE_EXT_LEN;
- }
- osal_memcpy( scene.extField, pData, scene.extLen );
- }
- if ( scene.groupID == 0x0000 ||
- aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) != NULL )
- {
- // Either the Scene doesn't belong to a Group (Group ID = 0x0000) or it
- // does and the corresponding Group exits
- pScene = zclGeneral_FindScene( pInMsg->msg->endPoint, scene.groupID, scene.ID );
- if ( pScene || ( zclGeneral_CountAllScenes() < ZCL_GEN_MAX_SCENES ) )
- {
- status = ZCL_STATUS_SUCCESS;
- if ( pScene != NULL )
- {
- // The Scene already exists so update it
- pScene->transTime = scene.transTime;
- osal_memcpy( pScene->name, scene.name, ZCL_GEN_SCENE_NAME_LEN );
- // Use the new extention field(s)
- osal_memcpy( pScene->extField, scene.extField, scene.extLen );
- pScene->extLen = scene.extLen;
- // Update NV
- zclGeneral_ScenesWriteNV();
- }
- else
- {
- // The Scene doesn't exist so add it
- zclGeneral_AddScene( pInMsg->msg->endPoint, &scene );
- }
- }
- else
- {
- status = ZCL_STATUS_INSUFFICIENT_SPACE; // The Scene Table is full
- }
- }
- else
- {
- status = ZCL_STATUS_INVALID_FIELD; // The Group is not in the Group Table
- }
- zclGeneral_SendSceneAddResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, scene.groupID, scene.ID,
- true, pInMsg->hdr.transSeqNum );
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_SCENE_VIEW:
- pScene = zclGeneral_FindScene( pInMsg->msg->endPoint, scene.groupID, scene.ID );
- if ( pScene != NULL )
- {
- status = ZCL_STATUS_SUCCESS;
- }
- else
- {
- // Scene not found
- if ( scene.groupID != 0x0000 &&
- aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) == NULL )
- {
- status = ZCL_STATUS_INVALID_FIELD; // The Group is not in the Group Table
- }
- else
- {
- status = ZCL_STATUS_NOT_FOUND;
- }
- pScene = &scene;
- }
- zclGeneral_SendSceneViewResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, pScene, true, pInMsg->hdr.transSeqNum );
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_SCENE_REMOVE:
- if ( zclGeneral_RemoveScene( pInMsg->msg->endPoint, scene.groupID, scene.ID ) )
- {
- status = ZCL_STATUS_SUCCESS;
- }
- else
- {
- // Scene not found
- if ( aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) == NULL )
- {
- // The Group is not in the Group Table
- status = ZCL_STATUS_INVALID_FIELD;
- }
- else
- {
- status = ZCL_STATUS_NOT_FOUND;
- }
- }
- if ( UNICAST_MSG( pInMsg->msg ) )
- {
- // Addressed to this device (not to a group) - send a response back
- zclGeneral_SendSceneRemoveResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, scene.groupID,
- scene.ID, true, pInMsg->hdr.transSeqNum );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_SCENE_REMOVE_ALL:
- if ( scene.groupID == 0x0000 ||
- aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) != NULL )
- {
- zclGeneral_RemoveAllScenes( pInMsg->msg->endPoint, scene.groupID );
- status = ZCL_STATUS_SUCCESS;
- }
- else
- {
- status = ZCL_STATUS_INVALID_FIELD;
- }
- if ( UNICAST_MSG( pInMsg->msg ) )
- {
- // Addressed to this device (not to a group) - send a response back
- zclGeneral_SendSceneRemoveAllResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, scene.groupID, true, pInMsg->hdr.transSeqNum );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_SCENE_STORE:
- if ( scene.groupID == 0x0000 ||
- aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) != NULL )
- {
- // Either the Scene doesn't belong to a Group (Group ID = 0x0000) or it
- // does and the corresponding Group exits
- pScene = zclGeneral_FindScene( pInMsg->msg->endPoint, scene.groupID, scene.ID );
- if ( pScene || ( zclGeneral_CountAllScenes() < ZCL_GEN_MAX_SCENES ) )
- {
- uint8 sceneChanged = FALSE;
- status = ZCL_STATUS_SUCCESS;
- if ( pScene == NULL )
- {
- // Haven't been added yet
- pScene = &scene;
- }
- if ( pCBs->pfnSceneStoreReq )
- {
- zclSceneReq_t req;
- req.srcAddr = &(pInMsg->msg->srcAddr);
- req.scene = pScene;
- // Get the latest Scene info
- if ( pCBs->pfnSceneStoreReq( &req ) )
- {
- sceneChanged = TRUE;
- }
- }
- if ( pScene == &scene )
- {
- // The Scene doesn't exist so add it
- zclGeneral_AddScene( pInMsg->msg->endPoint, &scene );
- }
- else if ( sceneChanged )
- {
- // The Scene already exists so update only NV
- zclGeneral_ScenesWriteNV();
- }
- }
- else
- {
- status = ZCL_STATUS_INSUFFICIENT_SPACE; // The Scene Table is full
- }
- }
- else
- {
- status = ZCL_STATUS_INVALID_FIELD; // The Group is not in the Group Table
- }
- if ( UNICAST_MSG( pInMsg->msg ) )
- {
- // Addressed to this device (not to a group) - send a response back
- zclGeneral_SendSceneStoreResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, scene.groupID, scene.ID,
- true, pInMsg->hdr.transSeqNum );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_SCENE_RECALL:
- pScene = zclGeneral_FindScene( pInMsg->msg->endPoint, scene.groupID, scene.ID );
- if ( pScene && pCBs->pfnSceneRecallReq )
- {
- zclSceneReq_t req;
- req.srcAddr = &(pInMsg->msg->srcAddr);
- req.scene = pScene;
- pCBs->pfnSceneRecallReq( &req );
- }
- // No response
- break;
- case COMMAND_SCENE_GET_MEMBERSHIP:
- // Find all the Scenes corresponding to the Group ID
- if ( scene.groupID == 0x0000 ||
- aps_FindGroup( pInMsg->msg->endPoint, scene.groupID ) != NULL )
- {
- // Allocate space for the scene list
- sceneList = osal_mem_alloc( ZCL_GEN_MAX_SCENES );
- if ( sceneList != NULL )
- {
- sceneCnt = zclGeneral_FindAllScenesForGroup( pInMsg->msg->endPoint,
- scene.groupID, sceneList );
- status = ZCL_STATUS_SUCCESS;
- if ( UNICAST_MSG( pInMsg->msg ) )
- {
- // Addressed only to this device - send a response back
- sendRsp = TRUE;
- }
- else
- {
- // Addressed to the Group - ONLY send a response if an entry within the
- // Scene Table corresponds to the Group ID
- if ( sceneCnt != 0 )
- {
- sendRsp = TRUE;
- }
- }
- }
- else
- {
- // Couldn't allocate space for the scene list!
- status = ZCL_STATUS_INSUFFICIENT_SPACE;
- sendRsp = TRUE;
- }
- }
- else
- {
- // The Group is not in the Group Table - send a response back
- status = ZCL_STATUS_INVALID_FIELD;
- sendRsp = TRUE;
- }
- if ( sendRsp )
- {
- zclGeneral_SendSceneGetMembershipResponse( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- status, zclGeneral_ScenesRemaingCapacity(), sceneCnt, sceneList,
- scene.groupID, true, pInMsg->hdr.transSeqNum );
- }
- if ( sceneList != NULL )
- {
- osal_mem_free( sceneList );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInScenesClient
- *
- * @brief Process in the received Scenes Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInScenesClient( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- zclGeneral_Scene_t scene;
- uint8 *pData = pInMsg->pData;
- uint8 nameLen;
- zclSceneRsp_t rsp;
- uint8 i;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&scene, 0, sizeof( zclGeneral_Scene_t ) );
- osal_memset( (uint8*)&rsp, 0, sizeof( zclSceneRsp_t ) );
- // Get the status field first
- rsp.status = *pData++;
- if ( pInMsg->hdr.commandID == COMMAND_SCENE_GET_MEMBERSHIP_RSP )
- {
- rsp.capacity = *pData++;
- }
- scene.groupID = BUILD_UINT16( pData[0], pData[1] );
- pData += 2; // Move past group ID
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_SCENE_VIEW_RSP:
- // Parse the rest of the incoming message
- scene.ID = *pData++; // Not applicable to Remove All Response command
- scene.transTime = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- nameLen = *pData++; // Name length
- if ( nameLen > (ZCL_GEN_SCENE_NAME_LEN-1) )
- {
- // truncate to maximum size
- scene.name[0] = ZCL_GEN_SCENE_NAME_LEN-1;
- }
- else
- {
- scene.name[0] = nameLen;
- }
- osal_memcpy( &(scene.name[1]), pData, scene.name[0] );
- pData += nameLen; // move past name, use original length
- //*** Do something with the extension field(s)
- // Fall through to callback - break is left off intentionally
- case COMMAND_SCENE_ADD_RSP:
- case COMMAND_SCENE_REMOVE_RSP:
- case COMMAND_SCENE_REMOVE_ALL_RSP:
- case COMMAND_SCENE_STORE_RSP:
- if ( pCBs->pfnSceneRsp )
- {
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- rsp.scene = &scene;
- pCBs->pfnSceneRsp( &rsp );
- }
- break;
- case COMMAND_SCENE_GET_MEMBERSHIP_RSP:
- {
- uint8 *sceneList = NULL;
- if ( rsp.status == ZCL_STATUS_SUCCESS )
- {
- uint8 sceneCnt = *pData++;
- if ( sceneCnt > 0 )
- {
- // Allocate space for the scene list
- sceneList = osal_mem_alloc( sceneCnt );
- if ( sceneList != NULL )
- {
- rsp.sceneCnt = sceneCnt;
- for ( i = 0; i < sceneCnt; i++ )
- sceneList[i] = *pData++;
- }
- }
- }
- if ( pCBs->pfnSceneRsp )
- {
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- rsp.sceneList = sceneList;
- rsp.scene = &scene;
- pCBs->pfnSceneRsp( &rsp);
- }
- if ( sceneList != NULL )
- {
- osal_mem_free( sceneList );
- }
- }
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- #endif // ZCL_SCENES
- #ifdef ZCL_ON_OFF
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmdOnOff
- *
- * @brief Process in the received On/Off Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInOnOff( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- {
- if ( pInMsg->hdr.commandID > COMMAND_TOGGLE )
- return ( ZFailure ); // Error ignore the command
- if ( pCBs->pfnOnOff )
- pCBs->pfnOnOff( pInMsg->hdr.commandID );
- }
- // no Client command
- return ( ZSuccess );
- }
- #endif // ZCL_ON_OFF
- #ifdef ZCL_LEVEL_CTRL
- /*********************************************************************
- * @fn zclGeneral_ProcessInLevelControl
- *
- * @brief Process in the received Level Control Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInLevelControl( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- uint8 withOnOff = FALSE;
- ZStatus_t stat = ZSuccess;
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- {
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF:
- withOnOff = TRUE;
- // fall through
- case COMMAND_LEVEL_MOVE_TO_LEVEL:
- if ( pCBs->pfnLevelControlMoveToLevel )
- {
- zclLCMoveToLevel_t cmd;
- cmd.level = pInMsg->pData[0];
- cmd.transitionTime = BUILD_UINT16( pInMsg->pData[1], pInMsg->pData[2] );
- cmd.withOnOff = withOnOff;
- pCBs->pfnLevelControlMoveToLevel( &cmd );
- }
- break;
- case COMMAND_LEVEL_MOVE_WITH_ON_OFF:
- withOnOff = TRUE;
- // fall through
- case COMMAND_LEVEL_MOVE:
- if ( pCBs->pfnLevelControlMove )
- {
- zclLCMove_t cmd;
- cmd.moveMode = pInMsg->pData[0];
- cmd.rate = pInMsg->pData[1];
- cmd.withOnOff = withOnOff;
- pCBs->pfnLevelControlMove( &cmd );
- }
- break;
- case COMMAND_LEVEL_STEP_WITH_ON_OFF:
- withOnOff = TRUE;
- // fall through
- case COMMAND_LEVEL_STEP:
- if ( pCBs->pfnLevelControlStep )
- {
- zclLCStep_t cmd;
- cmd.stepMode = pInMsg->pData[0];
- cmd.amount = pInMsg->pData[1];
- cmd.transitionTime = BUILD_UINT16( pInMsg->pData[2], pInMsg->pData[3] );
- cmd.withOnOff = withOnOff;
- pCBs->pfnLevelControlStep( &cmd );
- }
- break;
- case COMMAND_LEVEL_STOP:
- case COMMAND_LEVEL_STOP_WITH_ON_OFF:
- // Both Stop commands are identical
- if ( pCBs->pfnLevelControlStop )
- {
- pCBs->pfnLevelControlStop();
- }
- break;
- default:
- stat = ZFailure;
- break;
- }
- }
- // no Client command
- return ( stat );
- }
- #endif // ZCL_LEVEL_CTRL
- #ifdef ZCL_ALARMS
- /*********************************************************************
- * @fn zclGeneral_AddAlarm
- *
- * @brief Add an alarm for a cluster
- *
- * @param endpoint -
- * @param alarm - new alarm item
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_AddAlarm( uint8 endpoint, zclGeneral_Alarm_t *alarm )
- {
- zclGenAlarmItem_t *pNewItem;
- zclGenAlarmItem_t *pLoop;
- // Fill in the new profile list
- pNewItem = osal_mem_alloc( sizeof( zclGenAlarmItem_t ) );
- if ( pNewItem == NULL )
- return ( ZMemError );
- // Fill in the plugin record.
- pNewItem->next = (zclGenAlarmItem_t *)NULL;
- pNewItem->endpoint = endpoint;
- osal_memcpy( (uint8*)(&pNewItem->alarm), (uint8*)alarm, sizeof ( zclGeneral_Alarm_t ) );
- // Find spot in list
- if ( zclGenAlarmTable == NULL )
- {
- zclGenAlarmTable = pNewItem;
- }
- else
- {
- // Look for end of list
- pLoop = zclGenAlarmTable;
- while ( pLoop->next != NULL )
- pLoop = pLoop->next;
- // Put new item at end of list
- pLoop->next = pNewItem;
- }
- return ( ZSuccess );
- }
- /*********************************************************************
- * @fn zclGeneral_FindAlarm
- *
- * @brief Find an alarm with alarmCode and clusterID
- *
- * @param endpoint -
- * @param groupID - what group the scene belongs to
- * @param sceneID - ID to look for scene
- *
- * @return a pointer to the alarm information, NULL if not found
- */
- zclGeneral_Alarm_t *zclGeneral_FindAlarm( uint8 endpoint, uint8 alarmCode, uint16 clusterID )
- {
- zclGenAlarmItem_t *pLoop;
- // Look for the alarm
- pLoop = zclGenAlarmTable;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint &&
- pLoop->alarm.code == alarmCode && pLoop->alarm.clusterID == clusterID )
- {
- return ( &(pLoop->alarm) );
- }
- pLoop = pLoop->next;
- }
- return ( (zclGeneral_Alarm_t *)NULL );
- }
- /*********************************************************************
- * @fn zclGeneral_FindEarliestAlarm
- *
- * @brief Find an alarm with the earliest timestamp
- *
- * @param endpoint -
- *
- * @return a pointer to the alarm information, NULL if not found
- */
- zclGeneral_Alarm_t *zclGeneral_FindEarliestAlarm( uint8 endpoint )
- {
- zclGenAlarmItem_t *pLoop;
- zclGenAlarmItem_t earliestAlarm;
- zclGenAlarmItem_t *pEarliestAlarm = &earliestAlarm;
- pEarliestAlarm->alarm.timeStamp = 0xFFFFFFFF;
- // Look for alarm with earliest time
- pLoop = zclGenAlarmTable;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint &&
- pLoop->alarm.timeStamp < pEarliestAlarm->alarm.timeStamp )
- {
- pEarliestAlarm = pLoop;
- }
- pLoop = pLoop->next;
- }
- if ( pEarliestAlarm->alarm.timeStamp != 0xFFFFFFFF )
- return ( &(pEarliestAlarm->alarm) );
- // No alarm
- return ( (zclGeneral_Alarm_t *)NULL );
- }
- /*********************************************************************
- * @fn zclGeneral_ResetAlarm
- *
- * @brief Remove a scene with endpoint and sceneID
- *
- * @param endpoint -
- * @param alarmCode -
- * @param clusterID -
- *
- * @return TRUE if removed, FALSE if not found
- */
- void zclGeneral_ResetAlarm( uint8 endpoint, uint8 alarmCode, uint16 clusterID )
- {
- zclGenAlarmItem_t *pLoop;
- zclGenAlarmItem_t *pPrev;
- // Look for end of list
- pLoop = zclGenAlarmTable;
- pPrev = NULL;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint &&
- pLoop->alarm.code == alarmCode && pLoop->alarm.clusterID == clusterID )
- {
- if ( pPrev == NULL )
- zclGenAlarmTable = pLoop->next;
- else
- pPrev->next = pLoop->next;
- // Free the memory
- osal_mem_free( pLoop );
- // Notify the Application so that if the alarm condition still active then
- // a new notification will be generated, and a new alarm record will be
- // added to the alarm log
- // zclGeneral_NotifyReset( alarmCode, clusterID ); // callback function?
- return;
- }
- pPrev = pLoop;
- pLoop = pLoop->next;
- }
- }
- /*********************************************************************
- * @fn zclGeneral_ResetAllAlarms
- *
- * @brief Remove all alarms with endpoint
- *
- * @param endpoint -
- * @param notifyApp -
- *
- * @return none
- */
- void zclGeneral_ResetAllAlarms( uint8 endpoint, uint8 notifyApp )
- {
- zclGenAlarmItem_t *pLoop;
- zclGenAlarmItem_t *pPrev;
- zclGenAlarmItem_t *pNext;
- // Look for end of list
- pLoop = zclGenAlarmTable;
- pPrev = NULL;
- while ( pLoop )
- {
- if ( pLoop->endpoint == endpoint )
- {
- if ( pPrev == NULL )
- zclGenAlarmTable = pLoop->next;
- else
- pPrev->next = pLoop->next;
- pNext = pLoop->next;
- // Free the memory
- osal_mem_free( pLoop );
- pLoop = pNext;
- }
- else
- {
- pPrev = pLoop;
- pLoop = pLoop->next;
- }
- }
- if ( notifyApp )
- {
- // Notify the Application so that if any alarm conditions still active then
- // a new notification will be generated, and a new alarm record will be
- // added to the alarm log
- // zclGeneral_NotifyResetAll(); // callback function?
- }
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInAlarmsServer
- *
- * @brief Process in the received Alarms Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInAlarmsServer( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- zclGeneral_Alarm_t *pAlarm;
- uint8 *pData = pInMsg->pData;
- ZStatus_t stat = ZSuccess;
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_ALARMS_RESET:
- zclGeneral_ResetAlarm( pInMsg->msg->endPoint, pData[0],
- BUILD_UINT16( pData[1], pData[2] ) );
- break;
- case COMMAND_ALARMS_RESET_ALL:
- zclGeneral_ResetAllAlarms( pInMsg->msg->endPoint, TRUE );
- break;
- case COMMAND_ALARMS_GET:
- pAlarm = zclGeneral_FindEarliestAlarm( pInMsg->msg->endPoint );
- if ( pAlarm )
- {
- // Send a response back
- zclGeneral_SendAlarmGetRespnose( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- ZCL_STATUS_SUCCESS, pAlarm->code,
- pAlarm->clusterID, pAlarm->timeStamp,
- true, pInMsg->hdr.transSeqNum );
- // Remove the entry from the Alarm table
- zclGeneral_ResetAlarm( pInMsg->msg->endPoint, pAlarm->code, pAlarm->clusterID );
- }
- else
- {
- // Send a response back
- zclGeneral_SendAlarmGetRespnose( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,
- ZCL_STATUS_NOT_FOUND, 0, 0, 0,
- true, pInMsg->hdr.transSeqNum );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_ALARMS_RESET_LOG:
- zclGeneral_ResetAllAlarms( pInMsg->msg->endPoint, FALSE );
- break;
- #ifdef SE_UK_EXT
- case COMMAND_ALARMS_PUBLISH_EVENT_LOG:
- if ( pCBs->pfnPublishEventLog )
- {
- zclPublishEventLog_t eventLog;
-
- eventLog.logID = *pData++;
- eventLog.cmdIndex = *pData++;
- eventLog.totalCmds = *pData++;
-
- // First try to find out number of Sub Log Payloads
- eventLog.numSubLogs = (pInMsg->pDataLen-3)/(1+4); // event ID + event time
- if ( eventLog.numSubLogs > 0 )
- {
- // Try to alloc space for Log Payload
- eventLog.pLogs = (zclEventLogPayload_t *)osal_mem_alloc( sizeof( zclEventLogPayload_t ) *
- eventLog.numSubLogs );
- if ( eventLog.pLogs != NULL )
- {
- // Copy Log Payload
- for ( uint8 i = 0; i < eventLog.numSubLogs; i++ )
- {
- eventLog.pLogs[i].eventId = *pData++;
- eventLog.pLogs[i].eventTime = osal_build_uint32( pData, 4 );
- pData += 4;
- }
- }
- else
- {
- stat = ZCL_STATUS_SOFTWARE_FAILURE;
- }
- }
- else
- {
- eventLog.pLogs = NULL;
- }
-
- if ( stat == ZSuccess )
- {
- pCBs->pfnPublishEventLog( &(pInMsg->msg->srcAddr), &eventLog );
- }
-
- if ( eventLog.pLogs != NULL )
- {
- osal_mem_free( eventLog.pLogs );
- }
- }
- break;
- #endif // SE_UK_EXT
-
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInAlarmsClient
- *
- * @brief Process in the received Alarms Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInAlarmsClient( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- uint8 *pData = pInMsg->pData;
- zclAlarm_t alarm;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&alarm, 0, sizeof( zclAlarm_t ) );
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_ALARMS_ALARM:
- if ( pCBs->pfnAlarm )
- {
- alarm.srcAddr = &(pInMsg->msg->srcAddr);
- alarm.cmdID = pInMsg->hdr.commandID;
- alarm.status = *pData++;
- alarm.alarmCode = *pData++;
- alarm.clusterID = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- alarm.timeStamp = osal_build_uint32( pData, 4 );
- pCBs->pfnAlarm( &alarm );
- }
- break;
- case COMMAND_ALARMS_GET_RSP:
- if ( pCBs->pfnAlarm )
- {
- alarm.srcAddr = &(pInMsg->msg->srcAddr);
- alarm.cmdID = pInMsg->hdr.commandID;
- alarm.alarmCode = *pData++;
- alarm.clusterID = BUILD_UINT16( pData[0], pData[1] );
- pCBs->pfnAlarm( &alarm );
- }
- break;
- #ifdef SE_UK_EXT
- case COMMAND_ALARMS_GET_EVENT_LOG:
- if ( pCBs->pfnGetEventLog )
- {
- zclGetEventLog_t eventLog;
-
- eventLog.logID = *pData++;
- eventLog.startTime = osal_build_uint32( pData, 4 );
- pData += 4;
- eventLog.endTime = osal_build_uint32( pData, 4 );
- pData += 4;
- eventLog.numEvents = *pData;
-
- pCBs->pfnGetEventLog( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
- &eventLog, pInMsg->hdr.transSeqNum );
- }
- break;
- #endif // SE_UK_EXT
-
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- #endif // ZCL_ALARMS
- #ifdef ZCL_LOCATION
- /*********************************************************************
- * @fn zclGeneral_ProcessInLocationServer
- *
- * @brief Process in the received Location Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInLocationServer( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- uint8 *pData = pInMsg->pData;
- zclLocation_t cmd;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&cmd, 0, sizeof( zclLocation_t ) );
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_LOCATION_SET_ABSOLUTE:
- cmd.un.absLoc.coordinate1 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.absLoc.coordinate2 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.absLoc.coordinate3 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.absLoc.power = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.absLoc.pathLossExponent = BUILD_UINT16( pData[0], pData[1] );
- if ( pCBs->pfnLocation )
- {
- cmd.srcAddr = &(pInMsg->msg->srcAddr);
- cmd.cmdID = pInMsg->hdr.commandID;
- // Update the absolute location info
- pCBs->pfnLocation( &cmd );
- }
- break;
- case COMMAND_LOCATION_SET_DEV_CFG:
- cmd.un.devCfg.power = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.devCfg.pathLossExponent = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.devCfg.calcPeriod = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- cmd.un.devCfg.numMeasurements = *pData++;
- cmd.un.devCfg.reportPeriod = BUILD_UINT16( pData[0], pData[1] );
- if ( pCBs->pfnLocation )
- {
- cmd.srcAddr = &(pInMsg->msg->srcAddr);
- cmd.cmdID = pInMsg->hdr.commandID;
- // Update the device configuration info
- pCBs->pfnLocation( &cmd );
- }
- break;
- case COMMAND_LOCATION_GET_DEV_CFG:
- cmd.un.ieeeAddr = pData;
- if ( pCBs->pfnLocation )
- {
- cmd.srcAddr = &(pInMsg->msg->srcAddr);
- cmd.cmdID = pInMsg->hdr.commandID;
- cmd.seqNum = pInMsg->hdr.transSeqNum;
- // Retreive the Device Configuration
- pCBs->pfnLocation( &cmd );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- case COMMAND_LOCATION_GET_DATA:
- cmd.un.loc.bitmap.locByte = *pData++;
- cmd.un.loc.numResponses = *pData++;
- if ( cmd.un.loc.brdcastResponse == 0 ) // command is sent as a unicast
- osal_cpyExtAddr( cmd.un.loc.targetAddr, pData );
- if ( pCBs->pfnLocation )
- {
- cmd.srcAddr = &(pInMsg->msg->srcAddr);
- cmd.cmdID = pInMsg->hdr.commandID;
- cmd.seqNum = pInMsg->hdr.transSeqNum;
- // Retreive the Location Data
- pCBs->pfnLocation( &cmd );
- }
- stat = ZCL_STATUS_CMD_HAS_RSP;
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInLocationDataRsp
- *
- * @brief Process in the received Location Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static void zclGeneral_ProcessInLocationDataRsp( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- uint8 *pData = pInMsg->pData;
- zclLocationRsp_t rsp;
- osal_memset( (uint8*)&rsp, 0, sizeof( zclLocationRsp_t ) );
- if ( pCBs->pfnLocationRsp )
- {
- if ( pInMsg->hdr.commandID == COMMAND_LOCATION_DATA_RSP )
- rsp.un.loc.status = *pData++;
- if ( pInMsg->hdr.commandID != COMMAND_LOCATION_DATA_RSP ||
- rsp.un.loc.status == ZCL_STATUS_SUCCESS )
- {
- rsp.un.loc.data.type = *pData++;
- rsp.un.loc.data.absLoc.coordinate1 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- rsp.un.loc.data.absLoc.coordinate2 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- if ( locationType2D( rsp.un.loc.data.type ) == 0 )
- {
- rsp.un.loc.data.absLoc.coordinate3 = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- }
- if ( pInMsg->hdr.commandID != COMMAND_LOCATION_COMPACT_DATA_NOTIF )
- {
- rsp.un.loc.data.absLoc.power = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- rsp.un.loc.data.absLoc.pathLossExponent = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- }
- if ( locationTypeAbsolute( rsp.un.loc.data.type ) == 0 )
- {
- if ( pInMsg->hdr.commandID != COMMAND_LOCATION_COMPACT_DATA_NOTIF )
- rsp.un.loc.data.calcLoc.locationMethod = *pData++;
- rsp.un.loc.data.calcLoc.qualityMeasure = *pData++;
- rsp.un.loc.data.calcLoc.locationAge = BUILD_UINT16( pData[0], pData[1] );
- }
- }
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- // Notify the Application
- pCBs->pfnLocationRsp( &rsp );
- }
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInLocationClient
- *
- * @brief Process in the received Location Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_ProcessInLocationClient( zclIncoming_t *pInMsg,
- zclGeneral_AppCallbacks_t *pCBs )
- {
- uint8 *pData = pInMsg->pData;
- zclLocationRsp_t rsp;
- ZStatus_t stat = ZSuccess;
- osal_memset( (uint8*)&rsp, 0, sizeof( zclLocationRsp_t ) );
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_LOCATION_DEV_CFG_RSP:
- if ( pCBs->pfnLocationRsp )
- {
- rsp.un.devCfg.status = *pData++;
- if ( rsp.un.devCfg.status == ZCL_STATUS_SUCCESS )
- {
- rsp.un.devCfg.data.power = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- rsp.un.devCfg.data.pathLossExponent = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- rsp.un.devCfg.data.calcPeriod = BUILD_UINT16( pData[0], pData[1] );
- pData += 2;
- rsp.un.devCfg.data.numMeasurements = *pData++;
- rsp.un.devCfg.data.reportPeriod = BUILD_UINT16( pData[0], pData[1] );
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- // Notify the Application
- pCBs->pfnLocationRsp( &rsp );
- }
- }
- break;
- case COMMAND_LOCATION_DATA_RSP:
- case COMMAND_LOCATION_DATA_NOTIF:
- case COMMAND_LOCATION_COMPACT_DATA_NOTIF:
- zclGeneral_ProcessInLocationDataRsp( pInMsg, pCBs );
- break;
- case COMMAND_LOCATION_RSSI_PING:
- if ( pCBs->pfnLocationRsp )
- {
- rsp.un.locationType = *pData;
- rsp.srcAddr = &(pInMsg->msg->srcAddr);
- rsp.cmdID = pInMsg->hdr.commandID;
- // Notify the Application
- pCBs->pfnLocationRsp( &rsp );
- }
- break;
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
- #endif // ZCL_LOCATION
- #ifdef ZCL_SCENES
- /*********************************************************************
- * @fn zclGeneral_ScenesInitNV
- *
- * @brief Initialize the NV Scene Table Items
- *
- * @param none
- *
- * @return number of scenes
- */
- static uint8 zclGeneral_ScenesInitNV( void )
- {
- uint8 status;
- uint16 size;
- size = (uint16)((sizeof ( nvGenScenesHdr_t ))
- + ( sizeof( zclGenSceneNVItem_t ) * ZCL_GEN_MAX_SCENES ));
- status = osal_nv_item_init( ZCD_NV_SCENE_TABLE, size, NULL );
- if ( status != ZSUCCESS )
- {
- zclGeneral_ScenesSetDefaultNV();
- }
- return status;
- }
- /*********************************************************************
- * @fn zclGeneral_ScenesSetDefaultNV
- *
- * @brief Write the defaults to NV
- *
- * @param none
- *
- * @return none
- */
- static void zclGeneral_ScenesSetDefaultNV( void )
- {
- nvGenScenesHdr_t hdr;
- // Initialize the header
- hdr.numRecs = 0;
- // Save off the header
- osal_nv_write( ZCD_NV_SCENE_TABLE, 0, sizeof( nvGenScenesHdr_t ), &hdr );
- }
- /*********************************************************************
- * @fn zclGeneral_ScenesWriteNV
- *
- * @brief Save the Scene Table in NV
- *
- * @param none
- *
- * @return none
- */
- static void zclGeneral_ScenesWriteNV( void )
- {
- nvGenScenesHdr_t hdr;
- zclGenSceneItem_t *pLoop;
- zclGenSceneNVItem_t item;
- hdr.numRecs = 0;
- // Look for end of list
- pLoop = zclGenSceneTable;
- while ( pLoop )
- {
- // Build the record
- item.endpoint = pLoop->endpoint;
- osal_memcpy( &(item.scene), &(pLoop->scene), sizeof ( zclGeneral_Scene_t ) );
- // Save the record to NV
- osal_nv_write( ZCD_NV_SCENE_TABLE,
- (uint16)((sizeof( nvGenScenesHdr_t )) + (hdr.numRecs * sizeof ( zclGenSceneNVItem_t ))),
- sizeof ( zclGenSceneNVItem_t ), &item );
- hdr.numRecs++;
- pLoop = pLoop->next;
- }
- // Save off the header
- osal_nv_write( ZCD_NV_SCENE_TABLE, 0, sizeof( nvGenScenesHdr_t ), &hdr );
- }
- /*********************************************************************
- * @fn zclGeneral_ScenesRestoreFromNV
- *
- * @brief Restore the Scene table from NV
- *
- * @param none
- *
- * @return Number of entries restored
- */
- static uint16 zclGeneral_ScenesRestoreFromNV( void )
- {
- uint16 x;
- nvGenScenesHdr_t hdr;
- zclGenSceneNVItem_t item;
- uint16 numAdded = 0;
- if ( osal_nv_read( ZCD_NV_SCENE_TABLE, 0, sizeof(nvGenScenesHdr_t), &hdr ) == ZSuccess )
- {
- // Read in the device list
- for ( x = 0; x < hdr.numRecs; x++ )
- {
- if ( osal_nv_read( ZCD_NV_SCENE_TABLE,
- (uint16)(sizeof(nvGenScenesHdr_t) + (x * sizeof ( zclGenSceneNVItem_t ))),
- sizeof ( zclGenSceneNVItem_t ), &item ) == ZSUCCESS )
- {
- // Add the scene
- if ( zclGeneral_AddScene( item.endpoint, &(item.scene) ) == ZSuccess )
- {
- numAdded++;
- }
- }
- }
- }
- return ( numAdded );
- }
- #endif // ZCL_SCENES
- /***************************************************************************
- ****************************************************************************/
|