Professional Documents
Culture Documents
/*
Microchip ZigBee2006 Residential Stack
Demo Coordinator
At startup the devices do not belong to a group, and the lit LEDs just indicate
they are on the network.
*********************************************************************
* FileName: Coordinator.c
* Dependencies:
* Processor: PIC18F/PIC24F
* Complier: MCC18 v3.20 or higher
* Complier: MCC30 v3.10 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* Copyright (c) 2004-2008 Microchip Technology Inc. All rights reserved.
*
* Microchip licenses to you the right to use, copy and distribute Software
* only when embedded on a Microchip microcontroller or digital signal
* controller and used with a Microchip radio frequency transceiver, which
* are integrated into your product or third party product (pursuant to the
* sublicense terms in the accompanying license agreement). You may NOT
* modify or create derivative works of the Software.
*
* If you intend to use this Software in the development of a product for
* sale, you must be a member of the ZigBee Alliance. For more information,
* go to www.zigbee.org.
*
* You should refer to the license agreement accompanying this Software for
* additional information regarding your rights and obligations.
*
* 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 MICROCHIP 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.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* DF/KO/yy 01/09/06 Microchip ZigBee Stack v1.0-3.5
* DPL 08/01/08 Microchip ZigBee-2006 Stack v2.0-2.6
********************************************************************/
#include "zAPL.h"
#include "zNVM.h"
#ifdef I_SUPPORT_SECURITY
#include "zSecurity.h"
extern NETWORK_KEY_INFO currentNetworkKeyInfo;
#ifdef USE_EXTERNAL_NVM
extern NETWORK_KEY_INFO plainSecurityKey[2];
//******************************************************************************
// Configuration Bits
//******************************************************************************
#if defined(MCHP_C18)
#if defined(__18F4620)
#pragma romdata CONFIG1H = 0x300001
const rom unsigned char config1H = 0b00000110; // HSPLL oscillator
#endif
#pragma romdata
#elif defined(__PIC24F__)
// Explorer 16 board
_CONFIG2(FNOSC_PRI & POSCMOD_XT) // Primary XT OSC with 4X PLL
_CONFIG1(JTAGEN_OFF & FWDTEN_OFF) // JTAG off, watchdog timer off
#elif defined(__dsPIC33F__) || defined(__PIC24H__)
// Explorer 16 board
_FOSCSEL(FNOSC_PRI) // primary osc
_FOSC(OSCIOFNC_OFF & POSCMD_XT) // XT Osc
_FWDT(FWDTEN_OFF) // Disable Watchdog timer
// JTAG should be disabled as well
#elif defined(__dsPIC30F__)
// dsPICDEM 1.1 board
_FOSC(XT_PLL16) // XT Osc + 16X PLL
_FWDT(WDT_OFF) // Disable Watchdog timer
_FBORPOR(MCLR_EN & PBOR_OFF & PWRT_OFF)
#else
#error Other compilers are not yet supported.
#endif
//******************************************************************************
// Compilation Configuration
//******************************************************************************
//******************************************************************************
// Constants
//******************************************************************************
#if defined(__C30__)
#define PB_LEFT_SWITCH PORTDbits.RD6
#define PB_RIGHT_SWITCH PORTDbits.RD7
#define GROUP_INDICATION LATAbits.LATA6
#define MESSAGE_INDICATION LATAbits.LATA7
#else
#define PB_LEFT_SWITCH PORTBbits.RB5
#define PB_RIGHT_SWITCH PORTBbits.RB4
#if defined(__18F4620)
#define GROUP_INDICATION LATAbits.LATA0
#define MESSAGE_INDICATION LATAbits.LATA1
#else
#define GROUP_INDICATION LATDbits.LATD0
#define MESSAGE_INDICATION LATDbits.LATD1
#endif
#endif
//******************************************************************************
// Function Prototypes
//******************************************************************************
//******************************************************************************
// Application Variables
//******************************************************************************
ZIGBEE_PRIMITIVE currentPrimitive;
SHORT_ADDR destinationAddress;
#ifdef I_SUPPORT_SECURITY
extern KEY_VAL KeyVal;
#ifdef USE_EXTERNAL_NVM
extern WORD trustCenterLongAddr;
extern NETWORK_KEY_INFO plainSecurityKey[2];
#else
extern ROM LONG_ADDR trustCenterLongAddr;
#endif
#endif
static union
{
struct
{
BYTE bBroadcastSwitchToggled : 1;
BYTE bLightSwitchToggled : 1;
BYTE bTryingToBind : 1;
BYTE bIsBound : 1;
BYTE bDestinationAddressKnown : 1;
BYTE bBindRequestDone : 1;
} bits;
BYTE Val;
} myStatusFlags;
#define STATUS_FLAGS_INIT 0x00
#define TOGGLE_BOUND_FLAG 0x08
#define bBindSwitchToggled bBroadcastSwitchToggled
BYTE FIRST_RUN = 1;
BYTE apsACK = 0;
SHORT_ADDR discoveredAddress;
BYTE routeDiscovery;
/* Menu System */
ROM char * const menu =
"\r\n 1: Enable/Disable Joining by Other Devices"
"\r\n 2: Request Data From Another Device"
"\r\n 3: Request Data From a Group of Devices"
"\r\n 4: Send Data To Another Device"
"\r\n 5: Send Data To a Group of Devices"
"\r\n 6: Add/Remove Device to/from a Group"
"\r\n 7: Dump Neighborhood Information"
//************************************************************************************
//************************************************************************************
"\r\n 8: Funcoes de Leitura do Medidor"
//************************************************************************************
//************************************************************************************
;
WORD_VAL MSGPacketCount;
BYTE RX_On = 1;
BYTE i, temp2;
BOOL gettingAcks = FALSE;
extern BOOL bDisableShortAddress;
extern BOOL APSSaveAPSAddress(APS_ADDRESS_MAP *AddressMap);
BOOL group_state_ID5 = TRUE;
BOOL group_state_ID4 = TRUE;
BYTE GROUP_ID4 = 0x04;
BYTE GROUP_ID5 = 0x05;
TICK PB_LEFT_press_time;
TICK PB_RIGHT_press_time;
TICK tickDifference;
TICK tick2Difference;
//******************************************************************************
//******************************************************************************
//******************************************************************************
#if defined(__C30__)
int main(void)
#else
void main(void)
#endif
{
#if defined(__18F87J10)
NOP();
NOP();
NOP();
NOP();
NOP();
OSCTUNEbits.PLLEN = 1;
NOP();
NOP();
NOP();
NOP();
NOP();
#endif
CLRWDT();
ENABLE_WDT();
currentPrimitive = NO_PRIMITIVE;
/* Initialize the UART such that data can be sent and recieved on terminal */
ConsoleInit();
NWKClearNeighborTable();
/* Refreash the tables anew each time the Node is booted up */
#if defined(I_SUPPORT_BINDING)
ClearBindingTable();
#endif
myStatusFlags.Val = STATUS_FLAGS_INIT;
while (1)
{
/* Clear the watch dog timer */
CLRWDT();
void ProcessZigBeePrimitives(void)
{
switch (currentPrimitive)
{
case NLME_DIRECT_JOIN_confirm:
if (params.NLME_DIRECT_JOIN_confirm.Status == NWK_TABLE_FULL)
{
ConsolePutROMString( (ROM char *)" Neighbor table is full.\r\n" );
}
else
{
ConsolePutROMString( (ROM char *)" Direct join successful.\r\n" );
}
PrintMenu();
currentPrimitive = NO_PRIMITIVE;
break;
case NLME_NETWORK_FORMATION_confirm:
if (!params.NLME_NETWORK_FORMATION_confirm.Status)
{
ConsolePutROMString( (ROM char *)"PAN " );
PrintChar( macPIB.macPANId.byte.MSB );
PrintChar( macPIB.macPANId.byte.LSB );
ConsolePutROMString( (ROM char *)" started successfully.\r\n" );
params.NLME_PERMIT_JOINING_request.PermitDuration = 0xFF;
params.NLME_PERMIT_JOINING_request._updatePayload = TRUE;
currentPrimitive = NLME_PERMIT_JOINING_request;
}
else
{
PrintChar( params.NLME_NETWORK_FORMATION_confirm.Status );
ConsolePutROMString( (ROM char *)" Error forming network. Trying
again...\r\n" );
currentPrimitive = NO_PRIMITIVE;
}
break;
case NLME_PERMIT_JOINING_confirm:
if (!params.NLME_PERMIT_JOINING_confirm.Status)
{
ConsolePutROMString( (ROM char *)"Joining permitted.\r\n" );
currentPrimitive = NO_PRIMITIVE;
}
else
{
PrintChar( params.NLME_PERMIT_JOINING_confirm.Status );
ConsolePutROMString( (ROM char *)" Join permission unsuccessful. We cannot
allow joins.\r\n" );
currentPrimitive = NO_PRIMITIVE;
}
PrintMenu();
break;
case NLME_ROUTE_DISCOVERY_confirm:
if (!params.NLME_ROUTE_DISCOVERY_confirm.Status)
{
ConsolePutROMString( (ROM char *)"..Route Reply Successful...\r\n" );
}
else
{
PrintChar( params.NLME_PERMIT_JOINING_confirm.Status );
ConsolePutROMString( (ROM char *)"..Route Reply not Successful..\r\n" );
}
currentPrimitive = NO_PRIMITIVE;
PrintMenu();
break;
case NLME_JOIN_indication:
ConsolePutROMString( (ROM char *)"\r\nNode " );
PrintChar( params.NLME_JOIN_indication.ShortAddress.byte.MSB );
PrintChar( params.NLME_JOIN_indication.ShortAddress.byte.LSB );
ConsolePutROMString( (ROM char *)" With MAC Address " );
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[7]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[6]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[5]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[4]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[3]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[2]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[1]);
PrintChar(params.NLME_JOIN_indication.ExtendedAddress.v[0]);
ConsolePutROMString( (ROM char *)" just joined.\r\n" );
/* For Zigbee 2006: If a new device with the same old longAddress address
* joins the PAN, then make sure the old short address is no longer used and is
* overwritten with the new shortAddress & longAddress combination
*/
{ /* same long address check block */
APS_ADDRESS_MAP currentAPSAddress1;
currentAPSAddress1.shortAddr = params.NLME_JOIN_indication.ShortAddress;
currentAPSAddress1.longAddr =
params.NLME_JOIN_indication.ExtendedAddress;
if(LookupAPSAddress(¶ms.NLME_JOIN_indication.ExtendedAddress) )
{
} /* end if */
} /* end address check block */
#ifdef I_SUPPORT_SECURITY
#ifdef I_AM_TRUST_CENTER
{
BOOL AllowJoin = TRUE;
// decide if you allow this device to join
if( !AllowJoin )
{
// no need to set deviceAddress, since it is overlap with
NLME_JOIN_indication
//params.NLME_LEAVE_request.DeviceAddress =
params.NLME_JOIN_indication.ExtendedAddress;
params.NLME_LEAVE_request.RemoveChildren = TRUE;
currentPrimitive = NLME_LEAVE_request;
break;
}
#ifdef I_SUPPORT_SECURITY_SPEC
if( params.NLME_JOIN_indication.secureJoin )
{
BYTE i;
for(i = 0; i < 16; i++)
{
KeyVal.v[i] = 0;
}
params.APSME_TRANSPORT_KEY_request.Key = &KeyVal;
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.KeySeqNumber = 0;
} else {
BYTE i;
GetNwkActiveKeyNumber(&i);
#ifdef USE_EXTERNAL_NVM
currentNetworkKeyInfo = plainSecurityKey[i-1];
#else
GetNwkKeyInfo(¤tNetworkKeyInfo, (ROM void
*)&(NetworkKeyInfo[i-1]));
#endif
params.APSME_TRANSPORT_KEY_request.Key =
&(currentNetworkKeyInfo.NetKey);
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.KeySeqNumber =
currentNetworkKeyInfo.SeqNumber.v[0];
}
#else
#ifdef PRECONFIGURE_KEY
{
BYTE i;
for(i = 0; i < 16; i++)
{
KeyVal.v[i] = 0;
}
params.APSME_TRANSPORT_KEY_request.Key = &KeyVal;
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.KeySeqNumber = 0;
params.APSME_TRANSPORT_KEY_request._UseSecurity = TRUE;
}
#else
if( params.NLME_JOIN_indication.secureJoin )
{
BYTE i;
for(i = 0; i < 16; i++)
{
KeyVal.v[i] = 0;
}
params.APSME_TRANSPORT_KEY_request.Key = &KeyVal;
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.KeySeqNumber = 0;
params.APSME_TRANSPORT_KEY_request._UseSecurity = TRUE;
}
else
{
BYTE i;
GetNwkActiveKeyNumber(&i);
#ifdef USE_EXTERNAL_NVM
currentNetworkKeyInfo = plainSecurityKey[i-1];
#else
GetNwkKeyInfo(¤tNetworkKeyInfo, (ROM void
*)&(networkKeyInfo[i-1]));
#endif
params.APSME_TRANSPORT_KEY_request.Key =
&(currentNetworkKeyInfo.NetKey);
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.KeySeqNumber =
currentNetworkKeyInfo.SeqNumber.v[0];
params.APSME_TRANSPORT_KEY_request._UseSecurity = FALSE;
}
#endif
#endif
params.APSME_TRANSPORT_KEY_request.KeyType = ID_NetworkKey;
params.APSME_TRANSPORT_KEY_request.DestinationAddress =
params.NLME_JOIN_indication.ExtendedAddress;
params.APSME_TRANSPORT_KEY_request.TransportKeyData.NetworkKey.UseParent
= FALSE;
currentPrimitive = APSME_TRANSPORT_KEY_request;
}
#else
#ifdef I_SUPPORT_SECURITY_SPEC
params.APSME_UPDATE_DEVICE_request.Status =
(params.NLME_JOIN_indication.secureJoin ) ? 0x00 : 0x01;
#else
#ifdef PRECONFIGURE_KEY
params.APSME_UPDATE_DEVICE_request.Status = 0x00;
#else
params.APSME_UPDATE_DEVICE_request.Status = 0x01;
#endif
#endif
params.APSME_UPDATE_DEVICE_request.DeviceShortAddress =
params.NLME_JOIN_indication.ShortAddress;
params.APSME_UPDATE_DEVICE_request.DeviceAddress =
params.NLME_JOIN_indication.ExtendedAddress;
GetTrustCenterAddress(¶ms.APSME_UPDATE_DEVICE_request.DestAddress);
for(i=0; i < 8; i++)
params.APSME_UPDATE_DEVICE_request.DestAddress.v[i] = 0xaa;
currentPrimitive = APSME_UPDATE_DEVICE_request;
#endif
#else
currentPrimitive = NO_PRIMITIVE;
#endif
break;
case NLME_LEAVE_indication:
{
#if defined(__C30__)
LONG_ADDR myLongAddr;
GetMACAddress(&myLongAddr);
if(!memcmppgm2ram( ¶ms.NLME_LEAVE_indication.DeviceAddress, &myLongAddr,
8 ))
#else
if (!memcmppgm2ram( ¶ms.NLME_LEAVE_indication.DeviceAddress, (ROM void
*)&macLongAddr, 8 ))
#endif
{
ConsolePutROMString( (ROM char *)"Node has left the network.\r\n" );
}
else
{
ConsolePutROMString( (ROM char *)" Another node has left the network.\r\n" );
}
}
#ifdef I_SUPPORT_SECURITY
{
SHORT_ADDR LeavingChildShortAddress;
if( !APSFromLongToShort(¶ms.NLME_LEAVE_indication.DeviceAddress) )
{
currentPrimitive = NO_PRIMITIVE;
break;
}
LeavingChildShortAddress = currentAPSAddress.shortAddr;
#ifdef I_AM_TRUST_CENTER
params.APSME_UPDATE_DEVICE_indication.Status = 0x02;
params.APSME_UPDATE_DEVICE_indication.DeviceAddress =
params.NLME_LEAVE_indication.DeviceAddress;
GetMACAddress(¶ms.APSME_UPDATE_DEVICE_indication.SrcAddress);
params.APSME_UPDATE_DEVICE_indication.DeviceShortAddress =
LeavingChildShortAddress;
currentPrimitive = APSME_UPDATE_DEVICE_indication;
break;
#else
params.APSME_UPDATE_DEVICE_request.Status = 0x02;
GetTrustCenterAddress(¶ms.APSME_UPDATE_DEVICE_request.DestAddress);
params.APSME_UPDATE_DEVICE_request.DeviceShortAddress =
LeavingChildShortAddress;
currentPrimitive = APSME_UPDATE_DEVICE_request;
break;
#endif
}
#else
currentPrimitive = NO_PRIMITIVE;
#endif
break;
case NLME_RESET_confirm:
ConsolePutROMString( (ROM char *)"ZigBee Stack has been reset.\r\n" );
currentPrimitive = NO_PRIMITIVE;
break;
case NLME_LEAVE_confirm:
ConsolePutROMString( (ROM char *)"Device has left the network\r\n" );
PrintChar(params.NLME_LEAVE_confirm.Status);
currentPrimitive = NO_PRIMITIVE;
break;
case APSDE_DATA_confirm:
if (params.APSDE_DATA_confirm.Status)
{
ConsolePutROMString( (ROM char *)"Error " );
PrintChar( params.APSDE_DATA_confirm.Status );
ConsolePutROMString( (ROM char *)" sending message.\r\n" );
}
else
{
ConsolePutROMString( (ROM char *)" Message sent successfully.\r\n" );
}
currentPrimitive = NO_PRIMITIVE;
break;
case APSDE_DATA_indication:
{
BYTE command = 0;
BYTE data;
BYTE frameHeader;
BYTE sequenceNumber = 0;
BYTE transaction;
BYTE transByte = 0;
currentPrimitive = NO_PRIMITIVE;
switch (params.APSDE_DATA_indication.DstEndpoint)
{
/* Process anything sent to ZDO */
case EP_ZDO:
#define dataLength command
if (1)
{
for (transaction=0; transaction < 1; transaction++)
{
sequenceNumber = APLGet();
switch( params.APSDE_DATA_indication.ClusterId.Val )
{
//
********************************************************
// Put a case here to handle each ZDO response that
application requested.
//
********************************************************
case BIND_rsp:
case UNBIND_rsp:
data = APLGet();
if (data == SUCCESS)
{
ConsolePutROMString( (ROM char
*)"Binding/Unbinding done successfully.\r\n" );
myStatusFlags.bits.bBindRequestDone = 1;
}
else
{
PrintChar( data );
ConsolePutROMString( (ROM char *)" Error doing
binding/unbinding...\r\n" );
}
break;
case NWK_ADDR_rsp:
if (APLGet() == SUCCESS)
{
/* update our table when device recieves the
address it requested */
ConsolePutROMString( (ROM char *)"Receiving
NWK_ADDR_rsp.\r\n" );
//
************************************************************************
// Place a case for each user defined endpoint.
//
************************************************************************
default:
/* In this example every endpoint except Endpoint EP_ZDO is processed
here */
{
BYTE i;
BYTE frameHeaderIndex = TxData;
WORD_VAL clusterID = params.APSDE_DATA_indication.ClusterId;
frameHeader = 1;
for(transaction=0; transaction<frameHeader; transaction++)
{
BYTE PacketLen;
BYTE transactionNumber;
switch( clusterID.Val )
{
//
***************************************************************************************************
**
//
***************************************************************************************************
**
case 0x0096: //Enviando Leitura
{
int LEITURA;
int Wh;
int AUX1;
int AUX2;
int AUX3;
LEITURA = APLGet();
LEITURA = APLGet();
printf("\r\nLeitura do Medidor ");
PrintChar(params.APSDE_DATA_indication.SrcAddress.ShortAddr.byte.MSB);
PrintChar(params.APSDE_DATA_indication.SrcAddress.ShortAddr.byte.LSB);
printf(" = ");
Wh = ( LEITURA * 0.9);
AUX1 = ( Wh / 10 );
AUX2 = ( AUX1 * 6 );
AUX3 = ( Wh + AUX2 );
PrintChar (AUX3);
printf(" Wh \r\n");
}
break;
//
***************************************************************************************************
**
//
***************************************************************************************************
**
case TRANSMIT_COUNTED_PACKETS_CLUSTER:
{
WORD_VAL Seq;
PacketLen = APLGet();
Seq.v[0] = APLGet();
Seq.v[1] = APLGet();
if( Seq.Val > MSGPacketCount.Val )
{
MSGPacketCount.Val = Seq.Val;
}
for(i = 0; i < PacketLen-2; i++)
APLGet();
}
break;
case RESET_PACKET_COUNT_CLUSTER:
MSGPacketCount.Val = 0;
break;
case RETRIEVE_PACKET_COUNT_CLUSTER:
TxBuffer[TxData++] = sequenceNumber;
TxBuffer[TxData++] = 2;
TxBuffer[TxData++] = MSGPacketCount.v[0];
TxBuffer[TxData++] = MSGPacketCount.v[1];
MSGPacketCount.Val++;
transactionNumber = TxBuffer[frameHeaderIndex] &
APL_FRAME_COUNT_MASK;
TxBuffer[frameHeaderIndex] &= APL_FRAME_TYPE_MASK;
TxBuffer[frameHeaderIndex] |= (transactionNumber+1);
if( transactionNumber == 0 )
{
ZigBeeBlockTx();
params.APSDE_DATA_request.DstAddrMode =
params.APSDE_DATA_indication.SrcAddrMode;
params.APSDE_DATA_request.DstAddress.ShortAddr =
params.APSDE_DATA_indication.SrcAddress.ShortAddr;
params.APSDE_DATA_request.RadiusCounter =
DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute =
ROUTE_DISCOVERY_ENABLE;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
i = params.APSDE_DATA_indication.SrcEndpoint;
params.APSDE_DATA_request.SrcEndpoint =
params.APSDE_DATA_indication.DstEndpoint;
params.APSDE_DATA_request.DstEndpoint = i;
params.APSDE_DATA_request.ClusterId.Val =
PACKET_COUNT_RESPONSE_CLUSTER;
currentPrimitive = APSDE_DATA_request;
}
break;
case PACKET_COUNT_RESPONSE_CLUSTER:
{
BYTE PC_LSB = APLGet();
BYTE PC_MSB = APLGet();
case BUFFER_TEST_REQUEST_CLUSTER:
{
BYTE SeqLen = APLGet();
#ifdef I_SUPPORT_SECURITY
if( SeqLen < 66 )
#else
if( SeqLen < 84 )
#endif
{
TxBuffer[TxData++] = SeqLen;
TxBuffer[TxData++] = SUCCESS;
for(i = 0; i < SeqLen; i++)
{
TxBuffer[TxData++] = i;
}
} else {
TxBuffer[TxData++] = SeqLen;
TxBuffer[TxData++] = 0x01;
}
if(params.APSDE_DATA_indication.SrcAddress.ShortAddr.Val==(macPIB.macShortAddress.Val))
{
printf(" \r\n Sending to myself\r\n");
APSDiscardRx();
currentPrimitive = NO_PRIMITIVE;
break;
}
ZigBeeBlockTx();
params.APSDE_DATA_request.DstAddrMode =
params.APSDE_DATA_indication.SrcAddrMode;
params.APSDE_DATA_request.DstAddress.ShortAddr =
params.APSDE_DATA_indication.SrcAddress.ShortAddr;
params.APSDE_DATA_request.RadiusCounter =
DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute =
ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
i = params.APSDE_DATA_indication.SrcEndpoint;
params.APSDE_DATA_request.SrcEndpoint =
params.APSDE_DATA_indication.DstEndpoint;
params.APSDE_DATA_request.DstEndpoint = i;
params.APSDE_DATA_request.ClusterId.Val =
BUFFER_TEST_RESPONSE_CLUSTER;
currentPrimitive = APSDE_DATA_request;
}
}
/* Group 4 uses End Point 4 so here that application
* is Toggling LED1 it received a request from Group 4
*/
if(params.APSDE_DATA_indication.SrcEndpoint == GROUP_ID4)
MESSAGE_INDICATION = !MESSAGE_INDICATION;
break;
case BUFFER_TEST_RESPONSE_CLUSTER:
{
BYTE len = APLGet();
printf("\r\nLen: ");
PrintChar(len);
printf("\r\n");
printf("From Address: ");
PrintChar(params.APSDE_DATA_indication.SrcAddress.ShortAddr.byte.MSB);
PrintChar(params.APSDE_DATA_indication.SrcAddress.ShortAddr.byte.LSB);
printf("\r\n");
for(i = 0; i < len+1; i++) {
PrintChar(APLGet());
}
printf("\r\n");
}
break;
case FREEFORM_MSG_REQUEST_CLUSTER:
{
BYTE requestType = APLGet();
TxBuffer[TxData++] = requestType; /* return the type
*/
switch(requestType)
{
case 0x00:
TxBuffer[TxData++] = 0x42;
break;
case 0x01:
TxBuffer[TxData++] = 0x5a;
TxBuffer[TxData++] = 0x69;
TxBuffer[TxData++] = 0x67;
TxBuffer[TxData++] = 0x42;
TxBuffer[TxData++] = 0x65;
TxBuffer[TxData++] = 0x65;
break;
case 0x02:
TxBuffer[TxData++] = 0x12;
TxBuffer[TxData++] = 0x34;
TxBuffer[TxData++] = 0x56;
TxBuffer[TxData++] = 0x78;
break;
}
{
ZigBeeBlockTx();
params.APSDE_DATA_request.DstAddrMode =
params.APSDE_DATA_indication.SrcAddrMode;
params.APSDE_DATA_request.DstAddress.ShortAddr =
params.APSDE_DATA_indication.SrcAddress.ShortAddr;
params.APSDE_DATA_request.RadiusCounter =
DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute =
ROUTE_DISCOVERY_ENABLE;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
i = params.APSDE_DATA_indication.SrcEndpoint;
params.APSDE_DATA_request.SrcEndpoint =
params.APSDE_DATA_indication.DstEndpoint;
params.APSDE_DATA_request.DstEndpoint = i;
params.APSDE_DATA_request.ClusterId.Val =
FREEFORM_MSG_RESPONSE_CLUSTER;
currentPrimitive = APSDE_DATA_request;
}
}
break;
case FREEFORM_MSG_RESPONSE_CLUSTER:
{
BYTE len = APLGet();
for(i = 0; i < len; i++)
APLGet();
break;
}
default:
/* Catch all place for all none ZDO msgs not
processed above */
printf("Got message.....");
break;
}
}
if( currentPrimitive != APSDE_DATA_request )
TxData = TX_DATA_START;
}
break;
}
APLDiscardRx();
}
break;
case APSME_ADD_GROUP_confirm:
case APSME_REMOVE_GROUP_confirm:
case APSME_REMOVE_ALL_GROUPS_confirm:
currentPrimitive = NO_PRIMITIVE;
break;
//
************************************************************************
// Place all processes that can send messages here. Be sure to call
// ZigBeeBlockTx() when currentPrimitive is set to APSDE_DATA_request.
//
************************************************************************
currentPrimitive = APSME_ADD_GROUP_request;
GROUP_INDICATION = 1;
printf(" \r\nAdded node to group 4\r\n");
}
else
{
params.APSME_REMOVE_GROUP_request.Endpoint =
GROUP_ID4;
params.APSME_REMOVE_GROUP_request.GroupAddress.v[1] = 0x00;
params.APSME_REMOVE_GROUP_request.GroupAddress.v[0] =
GROUP_ID4;
currentPrimitive = APSME_REMOVE_GROUP_request;
GROUP_INDICATION = 0;
printf(" \r\nRemoved node from group 4\r\n");
}
group_state_ID4 = !group_state_ID4;
break;
}
}
else /* Debounce Timeout period calculation */
{
TICK t = TickGet();
tick2Difference.Val = TickGetDiff(t,PB_RIGHT_press_time);
params.APSDE_DATA_request.SrcEndpoint = GROUP_ID4;
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute =
ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
break;
}
}
else /* Debounce Timeout period calculation */
{
TICK t = TickGet();
tickDifference.Val = TickGetDiff(t,PB_LEFT_press_time);
}
}
break;
default:
PrintChar( currentPrimitive );
ConsolePutROMString( (ROM char *)" Unhandled primitive.\r\n" );
currentPrimitive = NO_PRIMITIVE;
break;
}
}
void ProcessNONZigBeeTasks(void)
{
// *********************************************************************
// Place any non-ZigBee related processing here. Be sure that the code
// will loop back and execute ZigBeeTasks() in a timely manner.
// *********************************************************************
{
}
}
/*******************************************************************************
HardwareInit
All port directioning and SPI must be initialized before calling ZigBeeInit().
*******************************************************************************/
#if defined(__C30__)
void HardwareInit(void)
{
#if(CLOCK_FREQ < 1000000)
SPI1CON1 = 0b0000000100111111; // CLOCK_FREQ as SPI CLOCK
SPI1STAT = 0x8000;
#ifdef USE_EXTERNAL_NVM
EEPROM_nCS = 1;
EEPROM_nCS_TRIS = 0;
IFS2bits.SPI2IF = 1;
#endif
PHY_RESETn = 0;
PHY_RESETn_TRIS = 0;
PHY_CS = 1;
PHY_CS_TRIS = 0;
TRISAbits.TRISA6 = 0;
TRISAbits.TRISA7 = 0;
RFIF = 0;
RFIE = 1;
if(RF_INT_PIN == 0)
{
RFIF = 1;
}
TRISDbits.TRISD6 = 1;
TRISDbits.TRISD7 = 1;
CNEN1bits.CN15IE = 1;
CNEN2bits.CN16IE = 1;
CNPU1bits.CN15PUE = 1;
CNPU2bits.CN16PUE = 1;
IFS1bits.CNIF = 0;
IEC1bits.CNIE = 1;
}
#else
void HardwareInit(void)
{
#ifdef USE_EXTERNAL_NVM
EEPROM_nCS = 1;
EEPROM_nCS_TRIS = 0;
#endif
RF_SSPSTAT_REG = 0x40;
RF_SSPCON1_REG = 0x21;
EE_SSPSTAT_REG = 0x40;
EE_SSPCON1_REG = 0x21;
#else
// Initialize the SPI pins and directions
LATCbits.LATC3 = 0; // SCK
LATCbits.LATC5 = 1; // SDO
TRISCbits.TRISC3 = 0; // SCK
TRISCbits.TRISC4 = 1; // SDI
TRISCbits.TRISC5 = 0; // SDO
SSPSTAT_REG = 0x40;
SSPCON1_REG = 0x20;
#endif
//-------------------------------------------------------------------------
// This section is required for application-specific hardware
// initialization.
//-------------------------------------------------------------------------
/*******************************************************************************
User Interrupt Handler
The stack uses some interrupts for its internal processing. Once it is done
checking for its interrupts, the stack calls this function to allow for any
additional interrupt processing.
*******************************************************************************/
#if defined(__C30__)
void UserInterruptHandler(void)
{
}
IFS1bits.CNIF = 0;
}
}
#else
void UserInterruptHandler(void)
{
// *************************************************************************
// Place any application-specific interrupt processing here
// *************************************************************************
INTCONbits.RBIF = 0;
}
}
#endif
while (!ConsoleIsGetReady());
c = ConsoleGet();
ConsolePut(c);
return c;
}
//ConsolePutROMString( (ROM char * const) "\r\n\r\nEnter last MAC byte in hex: " );
oneByte = GetHexDigit() << 4;
oneByte += GetHexDigit();
//ConsolePutROMString( (ROM char * const) "\r\n\r\n" );
return oneByte;
}
BYTE c;
DISABLE_WDT();
}
break;
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_16_BIT;
printf("\r\nWhat is the short address of device you want data from: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = 0x7f01;
params.APSDE_DATA_request.ClusterId.Val = BUFFER_TEST_REQUEST_CLUSTER;
currentPrimitive = APSDE_DATA_request;
break;
ZigBeeBlockTx();
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_GROUP;
printf("\r\nPlease enter the Group ID of the Data Request: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 0;
params.APSDE_DATA_request.ProfileId.Val = 0x7f01;
params.APSDE_DATA_request.ClusterId.Val = BUFFER_TEST_REQUEST_CLUSTER;
currentPrimitive = APSDE_DATA_request;
break;
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_16_BIT;
printf("\r\nPlease enter the short address of the destination device: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = MY_PROFILE_ID;
//params.APSDE_DATA_request.asduLength; TxData
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = TRUE;
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.ClusterId.Val = TRANSMIT_COUNTED_PACKETS_CLUSTER;
ZigBeeBlockTx();
currentPrimitive = APSDE_DATA_request;
break;
case '5':
printf("\r\nPlease enter the number of bytes to send (hex): ");
temp2 = GetMACByte();
if(temp2 > 0x52)
temp2 = 0x52;
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_GROUP;
printf("\r\nEnter the GroupID of devices to send data: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = MY_PROFILE_ID;
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = TRUE;
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 0;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.ClusterId.Val = TRANSMIT_COUNTED_PACKETS_CLUSTER;
ZigBeeBlockTx();
currentPrimitive = APSDE_DATA_request;
break;
while( !ConsoleIsGetReady());
c = ConsoleGet();
ConsolePut(c);
switch(c)
{
case '0':
case '1':
printf("\r\nEnter 16-bit Group ID (Hex): ");
params.APSME_ADD_GROUP_request.GroupAddress.v[1] = GetMACByte();
params.APSME_ADD_GROUP_request.GroupAddress.v[0] = GetMACByte();
if(c == '0')
{
/* Using a Fixed endpoint here to simplify things in this application */
params.APSME_ADD_GROUP_request.Endpoint = GROUP_ID4;
currentPrimitive = APSME_ADD_GROUP_request;
GROUP_INDICATION = 1;
}
else
{
params.APSME_REMOVE_GROUP_request.Endpoint = GROUP_ID4;
currentPrimitive = APSME_REMOVE_GROUP_request;
GROUP_INDICATION = 0;
}
break;
case '2':
params.APSME_REMOVE_ALL_GROUPS_request.Endpoint = GROUP_ID4;
currentPrimitive = APSME_REMOVE_ALL_GROUPS_request;
GROUP_INDICATION = 0;
break;
}
break;
case '7':
#ifdef USE_EXTERNAL_NVM
pCurrentNeighborRecord = neighborTable; //+ (WORD)neighborIndex *
(WORD)sizeof(NEIGHBOR_RECORD);
#else
pCurrentNeighborRecord = &(neighborTable[0]);
#endif
printf("\r\nShort MAC Type Rntlship ");
for ( i=0; i < MAX_NEIGHBORS; i++ )
{
printf(" | ");
if((currentNeighborRecord.deviceInfo.bits.deviceType == 0x01))
printf("RTR");
else
printf("UKN");
printf(" | ");
if(currentNeighborRecord.deviceInfo.bits.Relationship == 0x01)
printf("CHILD ");
else if(currentNeighborRecord.deviceInfo.bits.Relationship == 0x00)
printf("PARENT");
else
printf("UNKWN ");
}
#ifdef USE_EXTERNAL_NVM
pCurrentNeighborRecord += (WORD)sizeof(NEIGHBOR_RECORD);
#else
pCurrentNeighborRecord++;
# e n d i f
}
printf("\r\n");
break;
params.NLME_ROUTE_DISCOVERY_request.Radius = DEFAULT_RADIUS;
ZigBeeBlockTx();
currentPrimitive = NLME_ROUTE_DISCOVERY_request;
break;
//************************************************************************************
//************************************************************************************
/* Funes do Medidor*/
case '8':
while( !ConsoleIsGetReady());
c = ConsoleGet();
ConsolePut( c );
switch (c)
{
/* Efetuar a Leitura do Medidor */
case '1':
TxBuffer[TxData++] = 0x00;
ZigBeeBlockTx();
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_16_BIT;
printf("\r\nShort address of device: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = 0x7f01;
params.APSDE_DATA_request.ClusterId.Val = 0X0099; //Ler Medidor
currentPrimitive = APSDE_DATA_request;
break;
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_16_BIT;
printf("\r\nShort address of device: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = 0x7f01;
params.APSDE_DATA_request.ClusterId.Val = 0x0098; //Ligar a Saida do Medidor
currentPrimitive = APSDE_DATA_request;
break;
params.APSDE_DATA_request.DstAddrMode = APS_ADDRESS_16_BIT;
printf("\r\nShort address of device: ");
params.APSDE_DATA_request.DstAddress.ShortAddr.v[1] = GetMACByte();
params.APSDE_DATA_request.DstAddress.ShortAddr.v[0] = GetMACByte();
params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS;
params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_SUPPRESS;
#ifdef I_SUPPORT_SECURITY
params.APSDE_DATA_request.TxOptions.Val = 1;
#else
params.APSDE_DATA_request.TxOptions.Val = 0;
#endif
params.APSDE_DATA_request.TxOptions.bits.acknowledged = 1;
params.APSDE_DATA_request.SrcEndpoint = 1;
params.APSDE_DATA_request.DstEndpoint = 240;
params.APSDE_DATA_request.ProfileId.Val = 0x7f01;
params.APSDE_DATA_request.ClusterId.Val = 0x0097; //Desligar a Saida do Medidor
currentPrimitive = APSDE_DATA_request;
break;
}
break;
break;
//************************************************************************************
//************************************************************************************
default:
break;
PrintMenu();
ENABLE_WDT();