123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044 |
- /**************************************************************************************************
- Filename: sapi.c
- Revised: $Date: 2010-05-03 17:46:57 -0700 (Mon, 03 May 2010) $
- Revision: $Revision: 22364 $
- Description: Z-Stack Simple Application Interface.
- Copyright 2007-2010 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 "hal_drivers.h"
- #include "OSAL.h"
- #include "OSAL_Tasks.h"
- //#include "OSAL_Custom.h"
- #if defined ( MT_TASK )
- #include "MT.h"
- #include "MT_TASK.h"
- #endif
- #include "nwk.h"
- #include "APS.h"
- #include "ZDApp.h"
- #include "osal_nv.h"
- #include "NLMEDE.h"
- #include "AF.h"
- #include "OnBoard.h"
- #include "nwk_util.h"
- #include "ZDProfile.h"
- #include "ZDObject.h"
- #include "hal_led.h"
- #include "hal_key.h"
- #include "sapi.h"
- #include "MT_SAPI.h"
- extern uint8 zgStartDelay;
- extern uint8 zgSapiEndpoint;
- /*********************************************************************
- * CONSTANTS
- */
- #if !defined OSAL_SAPI
- #define OSAL_SAPI TRUE
- #endif
- #if !defined SAPI_CB_FUNC
- #define SAPI_CB_FUNC TRUE
- #endif
- // Message ID's for application user messages must be in 0xE0-0xEF range
- #define ZB_USER_MSG 0xE0
- #define SAPICB_DATA_CNF 0xE0
- #define SAPICB_BIND_CNF 0xE1
- #define SAPICB_START_CNF 0xE2
- /*********************************************************************
- * TYPEDEFS
- */
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- #if OSAL_SAPI
- // The order in this table must be identical to the task initialization calls below in osalInitTask.
- const pTaskEventHandlerFn tasksArr[] = {
- macEventLoop,
- nwk_event_loop,
- Hal_ProcessEvent,
- #if defined( MT_TASK )
- MT_ProcessEvent,
- #endif
- APS_event_loop,
- ZDApp_event_loop,
- SAPI_ProcessEvent
- };
- const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
- uint16 *tasksEvents;
- #endif
- endPointDesc_t sapi_epDesc;
- uint8 sapi_TaskID;
- static uint16 sapi_bindInProgress;
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- void SAPI_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
- static void SAPI_SendCback( uint8 event, uint8 status, uint16 data );
- static void SAPI_StartConfirm( uint8 status );
- static void SAPI_SendDataConfirm( uint8 handle, uint8 status );
- static void SAPI_BindConfirm( uint16 commandId, uint8 status );
- static void SAPI_FindDeviceConfirm( uint8 searchType,
- uint8 *searchKey, uint8 *result );
- static void SAPI_ReceiveDataIndication( uint16 source,
- uint16 command, uint16 len, uint8 *pData );
- static void SAPI_AllowBindConfirm( uint16 source );
- /******************************************************************************
- * @fn zb_SystemReset
- *
- * @brief The zb_SystemReset function reboots the ZigBee device. The
- * zb_SystemReset function can be called after a call to
- * zb_WriteConfiguration to restart Z-Stack with the updated
- * configuration.
- *
- * @param none
- *
- * @return none
- */
- void zb_SystemReset ( void )
- {
- SystemResetSoft(); // Especially useful for CC2531 to not break comm with USB Host.
- }
- /******************************************************************************
- * @fn zb_StartRequest
- *
- * @brief The zb_StartRequest function starts the ZigBee stack. When the
- * ZigBee stack starts, the device reads configuration parameters
- * from Nonvolatile memory and the device joins its network. The
- * ZigBee stack calls the zb_StartConrifm callback function when
- * the startup process completes.
- *
- * @param none
- *
- * @return none
- */
- void zb_StartRequest()
- {
- uint8 logicalType;
- zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
- // Check for bad combinations of compile flag definitions and device type setting.
- if ((logicalType > ZG_DEVICETYPE_ENDDEVICE) ||
- #if !ZG_BUILD_ENDDEVICE_TYPE // Only RTR or Coord possible.
- (logicalType == ZG_DEVICETYPE_ENDDEVICE) ||
- #endif
- #if !ZG_BUILD_RTR_TYPE // Only End Device possible.
- (logicalType == ZG_DEVICETYPE_ROUTER) ||
- (logicalType == ZG_DEVICETYPE_COORDINATOR) ||
- #elif ZG_BUILD_RTRONLY_TYPE // Only RTR possible.
- (logicalType == ZG_DEVICETYPE_COORDINATOR) ||
- #elif !ZG_BUILD_JOINING_TYPE // Only Coord possible.
- (logicalType == ZG_DEVICETYPE_ROUTER) ||
- #endif
- (0))
- {
- logicalType = ZB_INVALID_PARAMETER;
- SAPI_SendCback(SAPICB_START_CNF, logicalType, 0);
- }
- else
- {
- logicalType = ZB_SUCCESS;
- ZDOInitDevice(zgStartDelay);
- }
-
- return;
- }
- /******************************************************************************
- * @fn zb_BindDevice
- *
- * @brief The zb_BindDevice function establishes or removes a ‘binding’
- * between two devices. Once bound, an application can send
- * messages to a device by referencing the commandId for the
- * binding.
- *
- * @param create - TRUE to create a binding, FALSE to remove a binding
- * commandId - The identifier of the binding
- * pDestination - The 64-bit IEEE address of the device to bind to
- *
- * @return The status of the bind operation is returned in the
- * zb_BindConfirm callback.
- */
- void zb_BindDevice ( uint8 create, uint16 commandId, uint8 *pDestination )
- {
- zAddrType_t destination;
- uint8 ret = ZB_ALREADY_IN_PROGRESS;
- if ( create )
- {
- if (sapi_bindInProgress == 0xffff)
- {
- if ( pDestination )
- {
- destination.addrMode = Addr64Bit;
- osal_cpyExtAddr( destination.addr.extAddr, pDestination );
- ret = APSME_BindRequest( sapi_epDesc.endPoint, commandId,
- &destination, sapi_epDesc.endPoint );
- if ( ret == ZSuccess )
- {
- // Find nwk addr
- ZDP_NwkAddrReq(pDestination, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
- }
- }
- else
- {
- ret = ZB_INVALID_PARAMETER;
- destination.addrMode = Addr16Bit;
- destination.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
- if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumOutClusters,
- sapi_epDesc.simpleDesc->pAppOutClusterList ) )
- {
- // Try to match with a device in the allow bind mode
- ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR,
- sapi_epDesc.simpleDesc->AppProfId, 1, &commandId, 0, (cId_t *)NULL, 0 );
- }
- else if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumInClusters,
- sapi_epDesc.simpleDesc->pAppInClusterList ) )
- {
- ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR,
- sapi_epDesc.simpleDesc->AppProfId, 0, (cId_t *)NULL, 1, &commandId, 0 );
- }
- if ( ret == ZB_SUCCESS )
- {
- // Set a timer to make sure bind completes
- #if ( ZG_BUILD_RTR_TYPE )
- osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, AIB_MaxBindingTime);
- #else
- // AIB_MaxBindingTime is not defined for an End Device
- osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, zgApsDefaultMaxBindingTime);
- #endif
- sapi_bindInProgress = commandId;
- return; // dont send cback event
- }
- }
- }
- SAPI_SendCback( SAPICB_BIND_CNF, ret, commandId );
- }
- else
- {
- // Remove local bindings for the commandId
- BindingEntry_t *pBind;
- // Loop through bindings an remove any that match the cluster
- while ( pBind = bindFind( sapi_epDesc.simpleDesc->EndPoint, commandId, 0 ) )
- {
- bindRemoveEntry(pBind);
- }
- osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
- }
- return;
- }
- /******************************************************************************
- * @fn zb_PermitJoiningRequest
- *
- * @brief The zb_PermitJoiningRequest function is used to control the
- * joining permissions and thus allow or disallow new devices from
- * joining the network.
- *
- * @param destination - The destination parameter indicates the address
- * of the device for which the joining permissions
- * should be set. This is usually the local device
- * address or the special broadcast address that denotes
- * all routers and coordinator ( 0xFFFC ). This way
- * the joining permissions of a single device or the
- * whole network can be controlled.
- * timeout - Indicates the amount of time in seconds for which
- * the joining permissions should be turned on.
- * If timeout is set to 0x00, the device will turn off the
- * joining permissions indefinitely. If it is set to 0xFF,
- * the joining permissions will be turned on indefinitely.
- *
- *
- * @return ZB_SUCCESS or a failure code
- *
- */
- uint8 zb_PermitJoiningRequest ( uint16 destination, uint8 timeout )
- {
- #if defined( ZDO_MGMT_PERMIT_JOIN_REQUEST )
- zAddrType_t dstAddr;
- dstAddr.addrMode = Addr16Bit;
- dstAddr.addr.shortAddr = destination;
- return( (uint8) ZDP_MgmtPermitJoinReq( &dstAddr, timeout, 0, 0 ) );
- #else
- (void)destination;
- (void)timeout;
- return ZUnsupportedMode;
- #endif
- }
- /******************************************************************************
- * @fn zb_AllowBind
- *
- * @brief The zb_AllowBind function puts the device into the
- * Allow Binding Mode for a given period of time. A peer device
- * can establish a binding to a device in the Allow Binding Mode
- * by calling zb_BindDevice with a destination address of NULL
- *
- * @param timeout - The number of seconds to remain in the allow binding
- * mode. Valid values range from 1 through 65.
- * If 0, the Allow Bind mode will be set false without TO
- * If greater than 64, the Allow Bind mode will be true
- *
- * @return ZB_SUCCESS if the device entered the allow bind mode, else
- * an error code.
- */
- void zb_AllowBind ( uint8 timeout )
- {
- osal_stop_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER);
- if ( timeout == 0 )
- {
- afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
- }
- else
- {
- afSetMatch(sapi_epDesc.simpleDesc->EndPoint, TRUE);
- if ( timeout != 0xFF )
- {
- if ( timeout > 64 )
- {
- timeout = 64;
- }
- osal_start_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER, timeout*1000);
- }
- }
- return;
- }
- /******************************************************************************
- * @fn zb_SendDataRequest
- *
- * @brief The zb_SendDataRequest function initiates transmission of data
- * to a peer device
- *
- * @param destination - The destination of the data. The destination can
- * be one of the following:
- * - 16-Bit short address of device [0-0xfffD]
- * - ZB_BROADCAST_ADDR sends the data to all devices
- * in the network.
- * - ZB_BINDING_ADDR sends the data to a previously
- * bound device.
- *
- * commandId - The command ID to send with the message. If the
- * ZB_BINDING_ADDR destination is used, this parameter
- * also indicates the binding to use.
- *
- * len - The size of the pData buffer in bytes
- * handle - A handle used to identify the send data request.
- * txOptions - TRUE if requesting acknowledgement from the destination.
- * radius - The max number of hops the packet can travel through
- * before it is dropped.
- *
- * @return none
- */
- void zb_SendDataRequest ( uint16 destination, uint16 commandId, uint8 len,
- uint8 *pData, uint8 handle, uint8 txOptions, uint8 radius )
- {
- afStatus_t status;
- afAddrType_t dstAddr;
- txOptions |= AF_DISCV_ROUTE;
- // Set the destination address
- if (destination == ZB_BINDING_ADDR)
- {
- // Binding
- dstAddr.addrMode = afAddrNotPresent;
- }
- else
- {
- // Use short address
- dstAddr.addr.shortAddr = destination;
- dstAddr.addrMode = afAddr16Bit;
- if ( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( destination ) )
- {
- txOptions &= ~AF_ACK_REQUEST;
- }
- }
- dstAddr.panId = 0; // Not an inter-pan message.
- dstAddr.endPoint = sapi_epDesc.simpleDesc->EndPoint; // Set the endpoint.
- // Send the message
- status = AF_DataRequest(&dstAddr, &sapi_epDesc, commandId, len,
- pData, &handle, txOptions, radius);
- if (status != afStatus_SUCCESS)
- {
- SAPI_SendCback( SAPICB_DATA_CNF, status, handle );
- }
- }
- /******************************************************************************
- * @fn zb_ReadConfiguration
- *
- * @brief The zb_ReadConfiguration function is used to get a
- * Configuration Protperty from Nonvolatile memory.
- *
- * @param configId - The identifier for the configuration property
- * len - The size of the pValue buffer in bytes
- * pValue - A buffer to hold the configuration property
- *
- * @return none
- */
- uint8 zb_ReadConfiguration( uint8 configId, uint8 len, void *pValue )
- {
- uint8 size;
- size = (uint8)osal_nv_item_len( configId );
- if ( size > len )
- {
- return ZFailure;
- }
- else
- {
- return( osal_nv_read(configId, 0, size, pValue) );
- }
- }
- /******************************************************************************
- * @fn zb_WriteConfiguration
- *
- * @brief The zb_WriteConfiguration function is used to write a
- * Configuration Property to nonvolatile memory.
- *
- * @param configId - The identifier for the configuration property
- * len - The size of the pValue buffer in bytes
- * pValue - A buffer containing the new value of the
- * configuration property
- *
- * @return none
- */
- uint8 zb_WriteConfiguration( uint8 configId, uint8 len, void *pValue )
- {
- return( osal_nv_write(configId, 0, len, pValue) );
- }
- /******************************************************************************
- * @fn zb_GetDeviceInfo
- *
- * @brief The zb_GetDeviceInfo function retrieves a Device Information
- * Property.
- *
- * @param param - The identifier for the device information
- * pValue - A buffer to hold the device information
- *
- * @return none
- */
- void zb_GetDeviceInfo ( uint8 param, void *pValue )
- {
- switch(param)
- {
- case ZB_INFO_DEV_STATE:
- osal_memcpy(pValue, &devState, sizeof(uint8));
- break;
- case ZB_INFO_IEEE_ADDR:
- osal_memcpy(pValue, &aExtendedAddress, Z_EXTADDR_LEN);
- break;
- case ZB_INFO_SHORT_ADDR:
- osal_memcpy(pValue, &_NIB.nwkDevAddress, sizeof(uint16));
- break;
- case ZB_INFO_PARENT_SHORT_ADDR:
- osal_memcpy(pValue, &_NIB.nwkCoordAddress, sizeof(uint16));
- break;
- case ZB_INFO_PARENT_IEEE_ADDR:
- osal_memcpy(pValue, &_NIB.nwkCoordExtAddress, Z_EXTADDR_LEN);
- break;
- case ZB_INFO_CHANNEL:
- osal_memcpy(pValue, &_NIB.nwkLogicalChannel, sizeof(uint8));
- break;
- case ZB_INFO_PAN_ID:
- osal_memcpy(pValue, &_NIB.nwkPanId, sizeof(uint16));
- break;
- case ZB_INFO_EXT_PAN_ID:
- osal_memcpy(pValue, &_NIB.extendedPANID, Z_EXTADDR_LEN);
- break;
- }
- }
- /******************************************************************************
- * @fn zb_FindDeviceRequest
- *
- * @brief The zb_FindDeviceRequest function is used to determine the
- * short address for a device in the network. The device initiating
- * a call to zb_FindDeviceRequest and the device being discovered
- * must both be a member of the same network. When the search is
- * complete, the zv_FindDeviceConfirm callback function is called.
- *
- * @param searchType - The type of search to perform. Can be one of following:
- * ZB_IEEE_SEARCH - Search for 16-bit addr given IEEE addr.
- * searchKey - Value to search on.
- *
- * @return none
- */
- void zb_FindDeviceRequest( uint8 searchType, void *searchKey )
- {
- if (searchType == ZB_IEEE_SEARCH)
- {
- ZDP_NwkAddrReq((uint8*) searchKey, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- }
- }
- /******************************************************************************
- * @fn SAPI_StartConfirm
- *
- * @brief The SAPI_StartConfirm callback is called by the ZigBee stack
- * after a start request operation completes
- *
- * @param status - The status of the start operation. Status of
- * ZB_SUCCESS indicates the start operation completed
- * successfully. Else the status is an error code.
- *
- * @return none
- */
- void SAPI_StartConfirm( uint8 status )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_START_CNF ) )
- {
- zb_MTCallbackStartConfirm( status );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_StartConfirm( status );
- #endif
- }
- }
- /******************************************************************************
- * @fn SAPI_SendDataConfirm
- *
- * @brief The SAPI_SendDataConfirm callback function is called by the
- * ZigBee after a send data operation completes
- *
- * @param handle - The handle identifying the data transmission.
- * status - The status of the operation.
- *
- * @return none
- */
- void SAPI_SendDataConfirm( uint8 handle, uint8 status )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_SEND_DATA_CNF ) )
- {
- zb_MTCallbackSendDataConfirm( handle, status );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_SendDataConfirm( handle, status );
- #endif
- }
- }
- /******************************************************************************
- * @fn SAPI_BindConfirm
- *
- * @brief The SAPI_BindConfirm callback is called by the ZigBee stack
- * after a bind operation completes.
- *
- * @param commandId - The command ID of the binding being confirmed.
- * status - The status of the bind operation.
- * allowBind - TRUE if the bind operation was initiated by a call
- * to zb_AllowBindRespones. FALSE if the operation
- * was initiated by a call to ZB_BindDevice
- *
- * @return none
- */
- void SAPI_BindConfirm( uint16 commandId, uint8 status )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_BIND_CNF ) )
- {
- zb_MTCallbackBindConfirm( commandId, status );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_BindConfirm( commandId, status );
- #endif
- }
- }
- /******************************************************************************
- * @fn SAPI_AllowBindConfirm
- *
- * @brief Indicates when another device attempted to bind to this device
- *
- * @param
- *
- * @return none
- */
- void SAPI_AllowBindConfirm( uint16 source )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_ALLOW_BIND_CNF ) )
- {
- zb_MTCallbackAllowBindConfirm( source );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_AllowBindConfirm( source );
- #endif
- }
- }
- /******************************************************************************
- * @fn SAPI_FindDeviceConfirm
- *
- * @brief The SAPI_FindDeviceConfirm callback function is called by the
- * ZigBee stack when a find device operation completes.
- *
- * @param searchType - The type of search that was performed.
- * searchKey - Value that the search was executed on.
- * result - The result of the search.
- *
- * @return none
- */
- void SAPI_FindDeviceConfirm( uint8 searchType, uint8 *searchKey, uint8 *result )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_FIND_DEV_CNF ) )
- {
- zb_MTCallbackFindDeviceConfirm( searchType, searchKey, result );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_FindDeviceConfirm( searchType, searchKey, result );
- #endif
- }
- }
- /******************************************************************************
- * @fn SAPI_ReceiveDataIndication
- *
- * @brief The SAPI_ReceiveDataIndication callback function is called
- * asynchronously by the ZigBee stack to notify the application
- * when data is received from a peer device.
- *
- * @param source - The short address of the peer device that sent the data
- * command - The commandId associated with the data
- * len - The number of bytes in the pData parameter
- * pData - The data sent by the peer device
- *
- * @return none
- */
- void SAPI_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData )
- {
- #if defined ( MT_SAPI_CB_FUNC )
- /* First check if MT has subscribed for this callback. If so , pass it as
- a event to MonitorTest and return control to calling function after that */
- if ( SAPICB_CHECK( SPI_CB_SAPI_RCV_DATA_IND ) )
- {
- zb_MTCallbackReceiveDataIndication( source, command, len, pData );
- }
- else
- #endif //MT_SAPI_CB_FUNC
- {
- #if ( SAPI_CB_FUNC )
- zb_ReceiveDataIndication( source, command, len, pData );
- #endif
- }
- }
- /*********************************************************************
- * @fn SAPI_ProcessEvent
- *
- * @brief Simple API Task event processor. This function
- * is called to process all events for the task. Events
- * include timers, messages and any other user defined events.
- *
- * @param task_id - The OSAL assigned task ID.
- * @param events - events to process. This is a bit map and can
- * contain more than one event.
- *
- * @return none
- */
- UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )
- {
- osal_event_hdr_t *pMsg;
- afIncomingMSGPacket_t *pMSGpkt;
- afDataConfirm_t *pDataConfirm;
- if ( events & SYS_EVENT_MSG )
- {
- pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id );
- while ( pMsg )
- {
- switch ( pMsg->event )
- {
- case ZDO_CB_MSG:
- SAPI_ProcessZDOMsgs( (zdoIncomingMsg_t *)pMsg );
- break;
- case AF_DATA_CONFIRM_CMD:
- // This message is received as a confirmation of a data packet sent.
- // The status is of ZStatus_t type [defined in ZComDef.h]
- // The message fields are defined in AF.h
- pDataConfirm = (afDataConfirm_t *) pMsg;
- SAPI_SendDataConfirm( pDataConfirm->transID, pDataConfirm->hdr.status );
- break;
- case AF_INCOMING_MSG_CMD:
- pMSGpkt = (afIncomingMSGPacket_t *) pMsg;
- SAPI_ReceiveDataIndication( pMSGpkt->srcAddr.addr.shortAddr, pMSGpkt->clusterId,
- pMSGpkt->cmd.DataLength, pMSGpkt->cmd.Data);
- break;
- case ZDO_STATE_CHANGE:
- // If the device has started up, notify the application
- if (pMsg->status == DEV_END_DEVICE ||
- pMsg->status == DEV_ROUTER ||
- pMsg->status == DEV_ZB_COORD )
- {
- SAPI_StartConfirm( ZB_SUCCESS );
- }
- else if (pMsg->status == DEV_HOLD ||
- pMsg->status == DEV_INIT)
- {
- SAPI_StartConfirm( ZB_INIT );
- }
- break;
- case ZDO_MATCH_DESC_RSP_SENT:
- SAPI_AllowBindConfirm( ((ZDO_MatchDescRspSent_t *)pMsg)->nwkAddr );
- break;
- case KEY_CHANGE:
- #if ( SAPI_CB_FUNC )
- zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
- #endif
- break;
- case SAPICB_DATA_CNF:
- SAPI_SendDataConfirm( (uint8)((sapi_CbackEvent_t *)pMsg)->data,
- ((sapi_CbackEvent_t *)pMsg)->hdr.status );
- break;
- case SAPICB_BIND_CNF:
- SAPI_BindConfirm( ((sapi_CbackEvent_t *)pMsg)->data,
- ((sapi_CbackEvent_t *)pMsg)->hdr.status );
- break;
- case SAPICB_START_CNF:
- SAPI_StartConfirm( ((sapi_CbackEvent_t *)pMsg)->hdr.status );
- break;
- default:
- // User messages should be handled by user or passed to the application
- if ( pMsg->event >= ZB_USER_MSG )
- {
- }
- break;
- }
- // Release the memory
- osal_msg_deallocate( (uint8 *) pMsg );
- // Next
- pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id );
- }
- // Return unprocessed events
- return (events ^ SYS_EVENT_MSG);
- }
- if ( events & ZB_ALLOW_BIND_TIMER )
- {
- afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
- return (events ^ ZB_ALLOW_BIND_TIMER);
- }
- if ( events & ZB_BIND_TIMER )
- {
- // Send bind confirm callback to application
- SAPI_BindConfirm( sapi_bindInProgress, ZB_TIMEOUT );
- sapi_bindInProgress = 0xffff;
- return (events ^ ZB_BIND_TIMER);
- }
- if ( events & ZB_ENTRY_EVENT )
- {
- uint8 startOptions;
- // Give indication to application of device startup
- #if ( SAPI_CB_FUNC )
- zb_HandleOsalEvent( ZB_ENTRY_EVENT );
- #endif
- // LED off cancels HOLD_AUTO_START blink set in the stack
- HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);
- zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
- if ( startOptions & ZCD_STARTOPT_AUTO_START )
- {
- zb_StartRequest();
- }
- else
- {
- // blink leds and wait for external input to config and restart
- HalLedBlink(HAL_LED_2, 0, 50, 500);
- }
- return (events ^ ZB_ENTRY_EVENT );
- }
- // This must be the last event to be processed
- if ( events & ( ZB_USER_EVENTS ) )
- {
- // User events are passed to the application
- #if ( SAPI_CB_FUNC )
- zb_HandleOsalEvent( events );
- #endif
- // Do not return here, return 0 later
- }
- // Discard unknown events
- return 0;
- }
- /*********************************************************************
- * @fn SAPI_ProcessZDOMsgs()
- *
- * @brief Process response messages
- *
- * @param none
- *
- * @return none
- */
- void SAPI_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
- {
- switch ( inMsg->clusterID )
- {
- case NWK_addr_rsp:
- {
- // Send find device callback to application
- ZDO_NwkIEEEAddrResp_t *pNwkAddrRsp = ZDO_ParseAddrRsp( inMsg );
- SAPI_FindDeviceConfirm( ZB_IEEE_SEARCH, (uint8*)&pNwkAddrRsp->nwkAddr, pNwkAddrRsp->extAddr );
- }
- break;
- case Match_Desc_rsp:
- {
- zAddrType_t dstAddr;
- ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
- if ( sapi_bindInProgress != 0xffff )
- {
- // Create a binding table entry
- dstAddr.addrMode = Addr16Bit;
- dstAddr.addr.shortAddr = pRsp->nwkAddr;
- if ( APSME_BindRequest( sapi_epDesc.simpleDesc->EndPoint,
- sapi_bindInProgress, &dstAddr, pRsp->epList[0] ) == ZSuccess )
- {
- osal_stop_timerEx(sapi_TaskID, ZB_BIND_TIMER);
- osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
- // Find IEEE addr
- ZDP_IEEEAddrReq( pRsp->nwkAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- #if defined ( MT_SAPI_CB_FUNC )
- zb_MTCallbackBindConfirm( sapi_bindInProgress, ZB_SUCCESS );
- #endif
- // Send bind confirm callback to application
- #if ( SAPI_CB_FUNC )
- zb_BindConfirm( sapi_bindInProgress, ZB_SUCCESS );
- #endif
- sapi_bindInProgress = 0xffff;
- }
- }
- }
- break;
- }
- }
- /*********************************************************************
- * @fn SAPI_Init
- *
- * @brief Initialization function for the Simple API Task.
- * This is called during initialization and should contain
- * any application specific initialization (ie. hardware
- * initialization/setup, table initialization, power up
- * notification ... ).
- *
- * @param task_id - the ID assigned by OSAL. This ID should be
- * used to send messages and set timers.
- *
- * @return none
- */
- void SAPI_Init( byte task_id )
- {
- sapi_TaskID = task_id;
- sapi_bindInProgress = 0xffff;
- sapi_epDesc.task_id = &sapi_TaskID;
- sapi_epDesc.endPoint = 0;
-
- #if ( SAPI_CB_FUNC )
- sapi_epDesc.endPoint = zb_SimpleDesc.EndPoint;
- sapi_epDesc.task_id = &sapi_TaskID;
- sapi_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&zb_SimpleDesc;
- sapi_epDesc.latencyReq = noLatencyReqs;
- // Register the endpoint/interface description with the AF
- afRegister( &sapi_epDesc );
- #endif
- // Turn off match descriptor response by default
- afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
- // Register callback evetns from the ZDApp
- ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp );
- ZDO_RegisterForZDOMsg( sapi_TaskID, Match_Desc_rsp );
- #if ( SAPI_CB_FUNC )
- #if (defined HAL_KEY) && (HAL_KEY == TRUE)
- // Register for HAL events
- RegisterForKeys( sapi_TaskID );
- if ( HalKeyRead () == HAL_KEY_SW_5)
- {
- // If SW5 is pressed and held while powerup, force auto-start and nv-restore off and reset
- uint8 startOptions = ZCD_STARTOPT_CLEAR_STATE | ZCD_STARTOPT_CLEAR_CONFIG;
- zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
- zb_SystemReset();
- }
- #endif // HAL_KEY
- // Set an event to start the application
- osal_set_event(task_id, ZB_ENTRY_EVENT);
- #endif
- }
- /*********************************************************************
- * @fn SAPI_SendCback
- *
- * @brief Sends a message to the sapi task ( itself ) so that a
- * callback can be generated later.
- *
- * @return none
- */
- void SAPI_SendCback( uint8 event, uint8 status, uint16 data )
- {
- sapi_CbackEvent_t *pMsg;
- pMsg = (sapi_CbackEvent_t *)osal_msg_allocate( sizeof(sapi_CbackEvent_t) );
- if( pMsg )
- {
- pMsg->hdr.event = event;
- pMsg->hdr.status = status;
- pMsg->data = data;
- osal_msg_send( sapi_TaskID, (uint8 *)pMsg );
- }
- }
- #if OSAL_SAPI
- /*********************************************************************
- * @fn osalInitTasks
- *
- * @brief This function invokes the initialization function for each task.
- *
- * @param void
- *
- * @return none
- */
- void osalInitTasks( void )
- {
- uint8 taskID = 0;
- tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
- osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
- macTaskInit( taskID++ );
- nwk_init( taskID++ );
- Hal_Init( taskID++ );
- #if defined( MT_TASK )
- MT_TaskInit( taskID++ );
- #endif
- APS_Init( taskID++ );
- ZDApp_Init( taskID++ );
- SAPI_Init( taskID );
- }
- #endif
- /*********************************************************************
- *********************************************************************/
|