Vous êtes sur la page 1sur 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();
}

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

Vous aimerez peut-être aussi