0% found this document useful (0 votes)
107 views10 pages

Switch Code

This document contains code for initializing and running a switch device application on a Zigbee network. It defines functions for initializing the network stack, registering callbacks, handling messages, and running the main processing loop. The Switch_task function registers NV storage and initializes the application. Switch_initialization sets up variables, clocks, keys, LCD, and LEDs. Switch_initializeZStack initializes endpoints, callbacks, attributes, and starts the network device. Switch_process is an infinite loop that handles messages, keys, timers and updates the display.

Uploaded by

Priya Garg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
107 views10 pages

Switch Code

This document contains code for initializing and running a switch device application on a Zigbee network. It defines functions for initializing the network stack, registering callbacks, handling messages, and running the main processing loop. The Switch_task function registers NV storage and initializes the application. Switch_initialization sets up variables, clocks, keys, LCD, and LEDs. Switch_initializeZStack initializes endpoints, callbacks, attributes, and starts the network device. Switch_process is an infinite loop that handles messages, keys, timers and updates the display.

Uploaded by

Priya Garg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 10

void Switch_task(NVINTF_nvFuncts_t *pfnNV)

{
// Save and register the function pointers to the NV drivers
pfnZswNV = pfnNV;
zclport_registerNV(pfnZswNV, ZCL_PORT_SCENE_TABLE_NV_ID);

// Initialize application
Switch_initialization();

// No return from task process


Switch_process();
}

static void Switch_initialization(void)


{
/* Initialize variables */
zswDstAddr.addrMode = zstack_AFAddrMode_NONE;
zswDstAddr.addr.shortAddr = 0;
zswDstAddr.endpoint = 0;
zswDstAddr.panID = 0;

#if defined (ZCL_EZMODE)


zclport_registerEZModeTimerCB(Switch_setEzmodeTimerCallback);
#endif

Switch_initializeClocks();

/* Initialize keys */
Board_Key_initialize(Switch_processKeyChangeCallback);

/* Initialize the LCD */


Board_LCD_open();
LCD_WRITE_STRING( (char *)sDeviceName, LCD_PAGE1 );
#if defined (ZCL_EZMODE)
LCD_WRITE_STRING( (char *)sSwEZMode, LCD_PAGE2 );
#elif defined (ZSTACK_MANUAL_START)
LCD_WRITE_STRING( (char *)sSwStart, LCD_PAGE2 );
#else
LCD_WRITE_STRING( (char *)sClearLine, LCD_PAGE2 );
#endif
LCD_WRITE_STRING( (char *)sSwHelp, LCD_PAGE3 );

/* Initialize the LEDS */


Board_Led_initialize();

// Register the current thread as an ICall dispatcher application


// so that the application can send and receive messages.
ICall_registerApp(&zswEntity, &sem);

// Initialize the ZStack


Switch_initializeZStack();
}

static void Switch_initializeZStack(void)


{
// Initialize the ZStack Thread
bool startDev = true; // default to auto-start
// Setup the endpoints
zswRegEndpoints();

// Setup indications from ZStack


zswSetupZStackCallbacks();

#if defined (ZSTACK_MANUAL_START) || defined (ZCL_EZMODE)


// Check to see if the device is already part of a network,
// to see if we need to invoke EZMode or Manual startup
startDev = zclport_isAlreadyPartOfNetwork(zswEntity);
#endif

#if defined (ZSTACK_MANUAL_START)


// Setup the Manual Start module
Switch_initializeZstartDiscovery();
#endif

#if defined (ZCL_EZMODE)


{
// Register EZ-Mode
zcl_RegisterEZMode(&ezmodeRegisterData);
Board_Led_control(board_led_type_LED1, board_led_state_BLINK);
}
#endif

if(startDev)
{
zstack_devStartReq_t startReq = {0};

// Start the ZStack Thread


startReq.startDelay = 0;
(void)Zstackapi_DevStartReq(zswEntity, &startReq);

#if defined (ZCL_EZMODE)


// Clear the EZ Mode line
LCD_WRITE_STRING( (char *)sClearLine, LCD_PAGE2 );
#endif
}

// Register the ZCL General Cluster Library callback functions


zclGeneral_RegisterCmdCallbacks(SWITCH_EP, &cmdCallbacks);

// Register the application's attribute list


zcl_registerAttrList(SWITCH_EP, SWITCH_MAX_ATTRIBUTES, zswAttrs);

// Update the ZStack Parameters


zswWriteParameters();
}

static void Switch_process(void)


{
/* Forever loop */
for(;;)
{
ICall_ServiceEnum stackid;
ICall_EntityID dest;
zstackmsg_genericReq_t *pMsg = NULL;
/* Wait for response message */
if(ICall_wait(ICALL_TIMEOUT_FOREVER) == ICALL_ERRNO_SUCCESS)
{
/* Retrieve the response message */
if(ICall_fetchServiceMsg(&stackid, &dest, (void **)&pMsg)
== ICALL_ERRNO_SUCCESS)
{
if( (stackid == ICALL_SERVICE_CLASS_ZSTACK)
&& (dest == zswEntity) )
{
if(pMsg)
{
Switch_processZStackMsgs(pMsg);

// Free any separately allocated memory


Zstackapi_freeIndMsg(pMsg);
}
}

if(pMsg)
{
ICall_freeMsg(pMsg);
}
}

if(events & SWITCH_KEY_EVENT)


{
// Process Key Presses
Switch_handleKeys(keys);
keys = 0;
events &= ~SWITCH_KEY_EVENT;
}

if(events & SWITCH_IDENTIFY_TIMEOUT_EVT)


{
// Process the Identify timer expiration
if(zswIdentifyTime > 0)
{
zswIdentifyTime--;
}
Switch_processIdentifyTimeChange();

events &= ~SWITCH_IDENTIFY_TIMEOUT_EVT;


}

if(events & SWITCH_MAIN_SCREEN_EVT)


{
// Update the display
giSwScreenMode = SWITCH_MAINMODE;
Switch_updateLcdMainScreen();
events &= ~SWITCH_MAIN_SCREEN_EVT;
}

#ifdef ZCL_EZMODE
if(events & SWITCH_EZMODE_NEXTSTATE_EVT)
{
// going on to next state
zcl_EZModeAction(EZMODE_ACTION_PROCESS, NULL);
events &= ~SWITCH_EZMODE_NEXTSTATE_EVT;
}

if(events & SWITCH_EZMODE_TIMEOUT_EVT)


{
// EZ-Mode timed out
zcl_EZModeAction(EZMODE_ACTION_TIMED_OUT, NULL);
events &= ~SWITCH_EZMODE_TIMEOUT_EVT;
}
#endif // ZLC_EZMODE

#if defined (ZSTACK_MANUAL_START)


if(events & SWITCH_MANUAL_START_CLK_EVT)
{
// Manual start timeout
Zstart_processClockEvt();
events &= ~SWITCH_MANUAL_START_CLK_EVT;
}
#endif
}
}
}
-
static void Switch_processZStackMsgs(zstackmsg_genericReq_t *pMsg)
{
switch(pMsg->hdr.event)
{
case zstackmsg_CmdIDs_DEV_STATE_CHANGE_IND:
{
// The ZStack Thread is indicating a State change
zstackmsg_devStateChangeInd_t *pInd =
(zstackmsg_devStateChangeInd_t *)pMsg;

// Only process the state change if it actually changed.


if(savedState != pInd->req.state)
{
// Save the new state
savedState = pInd->req.state;

if( (pInd->req.state == zstack_DevState_DEV_ZB_COORD)


|| (pInd->req.state == zstack_DevState_DEV_ROUTER)
|| (pInd->req.state == zstack_DevState_DEV_END_DEVICE) )
{
// The device is part of a network, get the device's
// network parameters.
pNwkInfo = zclport_getDeviceInfo(zswEntity);

// Update the display with network information


giSwScreenMode = SWITCH_MAINMODE;
Switch_updateLcdDisplay();
Board_Led_control(board_led_type_LED1,
board_led_state_OFF);

if(pInd->req.state != zstack_DevState_DEV_END_DEVICE)
{
// Don't turn on LED if Power saving end device
Board_Led_control(board_led_type_LED4,
board_led_state_ON);
}
else
{
// Change the default poll rate from 1 second to
// the config
// setting (znwk_config.h)
Switch_setPollRate(ZNWK_POLL_RATE);
}
}
#if defined (ZSTACK_MANUAL_START)
{
zstart_params *pParams = Zstart_processStateChange(
pInd->req.state);
if(pParams->state == ZSTART_STATE_JOINED)
{
// Device joined
}
else if(pParams->state == ZSTART_STATE_REJOINED)
{
// Device has rejoined
}
else if(pParams->state == ZSTART_STATE_HOLD)
{

}
}
#endif
}
}
break;

case zstackmsg_CmdIDs_AF_INCOMING_MSG_IND:
{
// Process incoming data messages
zstackmsg_afIncomingMsgInd_t *pInd =
(zstackmsg_afIncomingMsgInd_t *)pMsg;
Switch_processAfIncomingMsgInd( &(pInd->req) );
}
break;

#if defined (ZSTACK_MANUAL_START)


case zstackmsg_CmdIDs_ZDO_BEACON_NOTIFY_IND:
{
// ZStart will process this message
zstackmsg_zdoBeaconNotifyInd_t *pInd
= (zstackmsg_zdoBeaconNotifyInd_t *)pMsg;
Zstart_processBeacon( &(pInd->req) );
}
break;

case zstackmsg_CmdIDs_ZDO_NWK_DISC_CNF:
{
// ZStart will process this message
zstackmsg_zdoNwkDiscCnf_t *pInd =
(zstackmsg_zdoNwkDiscCnf_t *)pMsg;
if(Zstart_processNwkDiscCnf(pInd->req.status) == true)
{
// Scan process is over
zstart_params *pParams = Zstart_getParameters();
if(pParams->state == ZSTART_STATE_SCAN_COMPLETE)
{
// Scan is complete and it's time to join
// In the zstart_params structure, the zstart has
// selected
// a network and device to join, you could change it by
// looking
// through the found network list
// [Zstart_getNetworkList()] and
// setting your own network(pParams->chosenNetwork) and
// device (pParams->chosenRouter) to join. Or, you
// could go with
// what was selected, like this example.
Zstart_join();
}
else if(pParams->state ==
ZSTART_STATE_SCAN_COMPLETE_NO_RESULTS)
{
// No results means that no networks found (that passed
// filtering)
// If you would like to delay the start of scanning,
// setup a timer
// to start scanning on timeout. For now, start a new
// discovery now.
Switch_initializeZstartDiscovery();

Zstart_discovery();
}
}
}
break;

case zstackmsg_CmdIDs_ZDO_JOIN_CNF:
{
zstackmsg_zdoJoinConf_t *pInd =
(zstackmsg_zdoJoinConf_t *)pMsg;
zstack_ZStatusValues status =
(zstack_ZStatusValues)pInd->hdr.status;

// ZStart will process this message


Zstart_processJoinCnf( status, &(pInd->req) );
if(status != zstack_ZStatusValues_ZSuccess)
{
zstart_params *pParams = Zstart_getParameters();
if(pParams && pParams->state == ZSTART_STATE_JOINING)
{
// Join didn't go well, let's add this device to the
// blacklist
// to skip this device next time, and restart the
// discovery process
zstart_NwkDiscItem *pNwk;

pNwk = Zstart_getNwk(pParams->chosenNetwork);
if(pNwk)
{
zstack_routerInfo *pRouter = Zstart_getRouter(
pNwk,
pParams
->chosenRouter);
if(pRouter)
{
Zstart_addToBlackList( (uint8_t *)&(pNwk->
extendedPANID),
pRouter->sourceAddr );
}
}
// You could add delay here -> timer, event

// Restart discovery process


Switch_initializeZstartDiscovery();
Zstart_discovery();
}
}
}
break;
#endif // ZSTACK_MANUAL_START

default:
break;
}
}

static void Switch_processAfIncomingMsgInd(zstack_afIncomingMsgInd_t *pInMsg)


{
afIncomingMSGPacket_t afMsg;

/*
* All incoming messages are passed to the ZCL message processor,
* first convert to a structure that ZCL can process.
*/
afMsg.groupId = pInMsg->groupID;
afMsg.clusterId = pInMsg->clusterId;
afMsg.srcAddr.endPoint = pInMsg->srcAddr.endpoint;
afMsg.srcAddr.panId = pInMsg->srcAddr.panID;
afMsg.srcAddr.addrMode = (afAddrMode_t)pInMsg->srcAddr.addrMode;
if( (afMsg.srcAddr.addrMode == afAddr16Bit)
|| (afMsg.srcAddr.addrMode == afAddrGroup)
|| (afMsg.srcAddr.addrMode == afAddrBroadcast) )
{
afMsg.srcAddr.addr.shortAddr = pInMsg->srcAddr.addr.shortAddr;
}
else if(afMsg.srcAddr.addrMode == afAddr64Bit)
{
memcpy(afMsg.srcAddr.addr.extAddr, &(pInMsg->srcAddr.addr.extAddr),
EXTADDR_LEN);
}
afMsg.macDestAddr = pInMsg->macDestAddr;
afMsg.endPoint = pInMsg->endpoint;
afMsg.wasBroadcast = pInMsg->wasBroadcast;
afMsg.LinkQuality = pInMsg->linkQuality;
afMsg.correlation = pInMsg->correlation;
afMsg.rssi = pInMsg->rssi;
afMsg.SecurityUse = pInMsg->securityUse;
afMsg.timestamp = pInMsg->timestamp;
afMsg.nwkSeqNum = pInMsg->nwkSeqNum;
afMsg.macSrcAddr = pInMsg->macSrcAddr;
afMsg.radius = pInMsg->radius;
afMsg.cmd.TransSeqNumber = pInMsg->transSeqNum;
afMsg.cmd.DataLength = pInMsg->n_payload;
afMsg.cmd.Data = pInMsg->pPayload;

zcl_ProcessMessageMSG(&afMsg);
}

/*******************************************************************************
* @fn Switch_sendToggle
*
* @brief Send an ON/OFF toggle command
*
* @param none
*
* @return none
*/
static void Switch_sendToggle(void)
{
afAddrType_t dstAddr;

dstAddr.addrMode = (afAddrMode_t)zswDstAddr.addrMode;
dstAddr.addr.shortAddr = zswDstAddr.addr.shortAddr;
dstAddr.endPoint = zswDstAddr.endpoint;
dstAddr.panId = zswDstAddr.panID;

// Send a toggle
zclGeneral_SendOnOff_CmdToggle(SWITCH_EP, &dstAddr, false, 0);

LCD_WRITE_STRING( (char *)sCmdSent, LCD_PAGE2 );


}

/*******************************************************************************
* @fn Switch_handleKeys
*
* @brief Callback service for keys
*
* @param keys - keys that were pressed
*
* @return void
*/
static void Switch_handleKeys(uint8_t keys)
{
if(keys == KEY_UP)
{
// Send the Toggle command through ZCL
Switch_sendToggle();
}

// toggle permit join


if(keys == KEY_LEFT)
{
giSwScreenMode = SWITCH_MAINMODE; // remove help screen if there

if( pNwkInfo
&& ( (savedState == zstack_DevState_DEV_ZB_COORD)
|| (savedState == zstack_DevState_DEV_ROUTER) ) )
{
zstack_zdoMgmtPermitJoinReq_t req;

// toggle permit join


gPermitDuration = gPermitDuration ? 0 : 0xff;
req.nwkAddr = pNwkInfo->nwkAddr;
req.duration = gPermitDuration;
req.tcSignificance = true;

Zstackapi_ZdoMgmtPermitJoinReq(zswEntity, &req);
}
}

if(keys == KEY_SELECT)
{
// Switch between Help and Main screens
if(giSwScreenMode == SWITCH_MAINMODE)
{
// Switch from main screen to help screen
giSwScreenMode = SWITCH_HELPMODE;
}
else
{
// Switch from help screen to main screen
giSwScreenMode = SWITCH_MAINMODE;
LCD_WRITE_STRING( (char *)sClearLine, LCD_PAGE2 );
}
}

if(keys == KEY_RIGHT)
{
#if defined (ZCL_EZMODE)
// Start EZMode Commissioning
{
zclEZMode_InvokeData_t ezModeData;
// only bind on the on/off cluster
static uint16_t clusterIDs[] =
{ ZCL_CLUSTER_ID_GEN_ON_OFF};

// Invoke EZ-Mode
ezModeData.endpoint = SWITCH_EP; // endpoint on which to invoke
// EZ-Mode
if( (savedState == zstack_DevState_DEV_ZB_COORD)
|| (savedState == zstack_DevState_DEV_ROUTER)
|| (savedState == zstack_DevState_DEV_END_DEVICE) )
{
ezModeData.onNetwork = true; // node is already on the
// network
}
else
{
ezModeData.onNetwork = false; // node is not yet on the
// network
}
ezModeData.initiator = true; // OnOffSwitch is an initiator
ezModeData.numActiveOutClusters = 1; // active output cluster
ezModeData.pActiveOutClusterIDs = clusterIDs;
ezModeData.numActiveInClusters = 0; // no active input clusters
ezModeData.pActiveInClusterIDs = NULL;
zcl_InvokeEZMode(&ezModeData);

LCD_WRITE_STRING("EZMode", LCD_PAGE2);
}
#elif defined (ZSTACK_MANUAL_START)
Zstart_discovery();
#endif // ZCL_EZMODE
}

// update the display


Switch_updateLcdDisplay();
}

/*********************************************************************

You might also like