实验 ZStack 广播通信实验
【实验目的】
1. 了解 ZigBee 广播通信的原理
2. 掌握在 ZigBee 网络中进行广播通信的方法
【实验设备】
1. 装有 IAR 开发工具的 PC 机一台
2. 实验箱一台
3. CCDebugger(以及 USB A-B 延长线)一个
4. USB Mini 延长线一根
【实验要求】
1. 编程要求:使用协议栈提供的 API 函数编写应用程序。
2. 实现功能:送节点向加入到同一 PANID 的 ZigBee 网络的所有节点以广播形式发送消息。
3. 实验现象:带有广播信息接收功能的节点收到广播信息后连续、快速闪烁节点上的通信指示灯
LED_D8(并通过串口输出接收到的信息——字符串“Broadcast Message”)。
【实验原理】
 ZigBee 网络中设置一个广播信息发送节点,若干个广播信息接收节点,发送节点周期性的向所有
节点广播消息,广播发送节点发送广播消息后通信指示灯会连续闪烁 3 次,允许接收广播消息的节点接收
到广播信息后,控制节点的通信指示灯 LED_D8 连续闪烁四次。通过观察各个节点的通信指示灯就可以判断是否接收到广播信息。

实验流程图


实验步骤

.打开Tools中的f8wConfig.cfg,将里面DZAPP_CONFIG_PAN_ID=0xFFFF

的0xFFFF改成其他值;

PAN_ID改成0x0020

2. 在工程目录结构树上方的下拉列表中,选择“CoordinatorEB” ,将实验箱的一个节点指定为协调器,编译调试,将代码烧进节点里;

3. “SAPP_Device.h”文件中,取消“HAS_BROADCASTSEND”的注释,

 

 

4.在工程目录结构树上方的下拉列表中,选择“EndDeviceEB”, 转换实验箱节点,将此节点指定为发送节点,编译调试,将代码烧进节点里;

5. “SAPP_Device.h”文件中,取消“HAS_BROADCASTSEND”的注释,

 

转换实验箱节点,将此节点指定为接收节点,编译调试,将代码烧进节点里,重复几次第5步骤,可多设置接收节点;

实验现象:可以看到协调器节点和发送端的节点的通信灯同时闪烁,接收器节点的D8连续闪烁4次,表示接收到信息。

实验感想:

通过此次实验了解了 ZigBee 广播通信的原理,掌握在 ZigBee 网络中进行广播通信的方法,通过课上教授的知识,学以致用。

实验完整代码:

节点定义广播发送和接收

APP_Base.c
#include "APP_Base.h"

 

#if defined(SAPP_ZSTACK_DEMO)

#include "hal_led.h"

// 任务建立实验范例代码

// 任务处理函数

uint16 Hello_ProcessEvent(uint8 task_id, uint16 events);

uint16 Hello_ProcessEvent(uint8 task_id, uint16 events)

{

    if(events & 0x0001)

    {

        // 控制LED闪烁

        HalLedBlink(HAL_LED_1, 1, 50, 250);

        // 启动定时器, 设置1秒钟后再次触发该任务

        osal_start_timerEx(task_id, 0x0001, 1000);

    }

    // 清除定时器事件标志

    return (events ^ 0x0001);

}

#endif

 

// 任务列表

const pTaskEventHandlerFn tasksArr[] = {

    macEventLoop,

    nwk_event_loop,

    Hal_ProcessEvent,

#if defined( MT_TASK )

    MT_ProcessEvent,

#endif

    APS_event_loop,

#if defined ( ZIGBEE_FRAGMENTATION )

    APSF_ProcessEvent,

#endif

    ZDApp_event_loop,

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )

    ZDNwkMgr_event_loop,

#endif

#if defined(SAPP_ZSTACK)

    sapp_controlEpProcess,

    sapp_functionEpProcess,

#endif

#if defined(SAPP_ZSTACK_DEMO)

    // 任务建立实验范例代码

    // 任务列表

    Hello_ProcessEvent,

#endif

};

const uint8 tasksCnt = sizeof(tasksArr)/sizeof(tasksArr[0]);

 

// 初始化任务

void osalInitTasks( void )

{

    uint8 taskID = 0;

 

    macTaskInit( taskID++ );

    nwk_init( taskID++ );

    Hal_Init( taskID++ );

#if defined( MT_TASK )

    MT_TaskInit( taskID++ );

#endif

    APS_Init( taskID++ );

#if defined ( ZIGBEE_FRAGMENTATION )

    APSF_Init( taskID++ );

#endif

    ZDApp_Init( taskID++ );

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )

    ZDNwkMgr_Init( taskID++ );

#endif

#if defined(SAPP_ZSTACK)

    sapp_taskInitProcess();

#endif

#if defined(SAPP_ZSTACK_DEMO)

    // 任务建立实验范例代码

    // 启动定时器

    osal_start_timerEx(taskID, 0x0001, 1000);

#endif

}

APP_Base.h

#ifndef _APP_BASE_H_

#define _APP_BASE_H_

#include "ZComDef.h"

#include "hal_drivers.h"

#include "OSAL.h"

#include "ZGlobals.h"

#include "AF.h"

#include "aps_groups.h"

 

#include "nwk.h"

#include "APS.h"

#if defined ( ZIGBEE_FRAGMENTATION )

  #include "aps_frag.h"

#endif

 

#include "MT.h"

#include "MT_UART.h"

#if defined( MT_TASK )

#include "MT_TASK.h"

#endif

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )

  #include "ZDNwkMgr.h"

#endif

 

#include "ZDApp.h"

#include "ZComDef.h"

#include "OSAL_Tasks.h"

#include "aps_groups.h"

#include "OnBoard.h"

#if defined(SAPP_ZSTACK)

#include "SAPP_FrameWork.h"

#endif

 

#endif//_APP_BASE_H_

SAPP_Device.c

#if defined(SAPP_ZSTACK)

#include "SAPP_Device.h"

#include "hal_io.h"

#include <string.h>

 

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

/* 传感器列表                                                 */

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

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

/* 燃气传感器                   */

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

#if defined(HAS_GAS)

#define GAS_IO_GROUP        0

#define GAS_IO_BIT          0

void sensorGasResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorGasResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        HalIOSetInput(GAS_IO_GROUP, GAS_IO_BIT, Pull_Down);

        HalIOIntSet(ep->ep, GAS_IO_GROUP, GAS_IO_BIT, IOInt_Rising, 0);

    }

    //IO端口中断触发,中断源检测

    if(type == ResIOInt)

    {

        uint8 GasValue = 1;

        SendData(ep->ep, &GasValue, 0x0000, TRANSFER_ENDPOINT, sizeof(GasValue));

    }

}

void sensorGasTimeout(struct ep_info_t *ep);

void sensorGasTimeout(struct ep_info_t *ep)

{

    uint8 value = HalIOGetLevel(GAS_IO_GROUP, GAS_IO_BIT);

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 温度传感器                   */

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

#if defined(HAS_TEMP) || defined(HAS_HUMM)

#include "sht10.h"

static uint16 TempValue = 0;

#endif

#if defined(HAS_TEMP)

void sensorTempResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorTempResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        SHT10_init(0x01);

    }

}

void sensorTempTimeout(struct ep_info_t *ep);

void sensorTempTimeout(struct ep_info_t *ep)

{

    unsigned int value = 0;

    unsigned char checksum = 0;

    SHT10_Measure(&value,&checksum, TEMPERATURE);

    TempValue = (value << 2) - 3960;

    SendData(ep->ep, &TempValue, 0x0000, TRANSFER_ENDPOINT, sizeof(TempValue));

}

#endif

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

/* 湿度传感器                   */

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

#if defined(HAS_HUMM)

void sensorHummResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorHummResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        SHT10_init(0x01);

    }

}

void sensorHummTimeout(struct ep_info_t *ep);

void sensorHummTimeout(struct ep_info_t *ep)

{

    const float C1 = -4.0f;              // for 8 Bit

    const float C2 = +0.648f;            // for 8 Bit

    const float C3 = -0.0000072f;        // for 8 Bit

    const float T1 = 0.01f;              // for 8 bit

    const float T2 = 0.00128f;           // for 8 bit

    float rh_lin    =   0.0f;                     // rh_lin: Humidity linear

    float rh_true   =   0.0f;                    // rh_true: Temperature compensated humidity

    float t_C   = 0.0f;                        // t_C   : Temperature []

 

    unsigned int HumiValue = 0;

    unsigned char checksum = 0;

    SHT10_Measure(&HumiValue,&checksum, HUMIDITY);

    rh_lin=C3*HumiValue*HumiValue + C2*HumiValue + C1;     //calc. humidity from ticks to [%RH]

    rh_true=(t_C-25)*(T1+T2*HumiValue)+rh_lin;   //calc. temperature compensated humidity [%RH]

    if(rh_true>100)

        rh_true=100;       //cut if the value is outside of

    if(rh_true<0.1)

        rh_true=0.1f;       //the physical possible range

    HumiValue = (unsigned int)(rh_true * 100);

    SendData(ep->ep, &HumiValue, 0x0000, TRANSFER_ENDPOINT, sizeof(HumiValue));

}

#endif

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

/* 雨滴传感器                   */

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

#if defined(HAS_RAIN)

#define RAIN_IO_GROUP       0

#define RAIN_IO_BIT         0

void sensorRainResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorRainResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        HalIOSetInput(RAIN_IO_GROUP, RAIN_IO_BIT, Pull_None);

        HalIOIntSet(ep->ep, RAIN_IO_GROUP, RAIN_IO_BIT, IOInt_Rising, 0);

    }

    //IO端口中断触发,中断源检测

    if(type == ResIOInt)

    {

        uint8 RainValue = 1;

        SendData(ep->ep, &RainValue, 0x0000, TRANSFER_ENDPOINT, sizeof(RainValue));

    }

}

void sensorRainTimeout(struct ep_info_t *ep);

void sensorRainTimeout(struct ep_info_t *ep)

{

    uint8 value = HalIOGetLevel(RAIN_IO_GROUP, RAIN_IO_BIT);

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 火焰传感器                   */

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

#if defined(HAS_FIRE)

#define FIRE_IO_GROUP       0

#define FIRE_IO_BIT         0

void sensorFireResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorFireResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        HalIOSetInput(FIRE_IO_GROUP, FIRE_IO_BIT, Pull_Down);

        HalIOIntSet(ep->ep, FIRE_IO_GROUP, FIRE_IO_BIT, IOInt_Rising, 0);

    }

    //IO端口中断触发,中断源检测

    if(type == ResIOInt)

    {

        uint8 FireValue = 1;

        SendData(ep->ep, &FireValue, 0x0000, TRANSFER_ENDPOINT, sizeof(FireValue));

    }

}

void sensorFireTimeout(struct ep_info_t *ep);

void sensorFireTimeout(struct ep_info_t *ep)

{

    uint8 value = HalIOGetLevel(FIRE_IO_GROUP, FIRE_IO_BIT);

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 烟雾传感器                   */

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

#if defined(HAS_SMOKE)

#define SMOKE_IO_GROUP      0

#define SMOKE_IO_BIT        0

void sensorSmokeResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorSmokeResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        HalIOSetInput(SMOKE_IO_GROUP, SMOKE_IO_BIT, Pull_Down);

        HalIOIntSet(ep->ep, SMOKE_IO_GROUP, SMOKE_IO_BIT, IOInt_Rising, 0);

    }

    //IO端口中断触发,中断源检测

    if(type == ResIOInt)

    {

        uint8 SmokeValue = 1;

        SendData(ep->ep, &SmokeValue, 0x0000, TRANSFER_ENDPOINT, sizeof(SmokeValue));

    }

}

void sensorSmokeTimeout(struct ep_info_t *ep);

void sensorSmokeTimeout(struct ep_info_t *ep)

{

    uint8 value = HalIOGetLevel(SMOKE_IO_GROUP, SMOKE_IO_BIT);

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 光照度传感器                 */

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

#if defined(HAS_ILLUM)

#include "hal_adc.h"

void sensorILLumTimeout(struct ep_info_t *ep);

void sensorILLumTimeout(struct ep_info_t *ep)

{

    uint16 LightValue = 256 - (HalAdcRead(0, HAL_ADC_RESOLUTION_14) >> 3);

    // 将AD值变换为光照度的100倍

    LightValue = LightValue * 39;// * 10000 / 256;

    SendData(ep->ep, &LightValue, 0x0000, TRANSFER_ENDPOINT, sizeof(LightValue));

}

#endif

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

/* 安防传感器                   */

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

#if defined(HAS_IRPERS)

#define SAFTY_IO_GROUP      1

#define SAFTY_IO_BIT        0

void sensorIRPersResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorIRPersResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        HalIOSetInput(SAFTY_IO_GROUP, SAFTY_IO_BIT, Pull_Down);

        HalIOIntSet(ep->ep, SAFTY_IO_GROUP, SAFTY_IO_BIT, IOInt_Rising, 0);

    }

    //IO端口中断触发,中断源检测

    if(type == ResIOInt)

    {

        uint8 IRPersValue = 1;

        SendData(ep->ep, &IRPersValue, 0x0000, TRANSFER_ENDPOINT, sizeof(IRPersValue));

    }

}

void sensorIRPersTimeout(struct ep_info_t *ep);

void sensorIRPersTimeout(struct ep_info_t *ep)

{

    uint8 value = HalIOGetLevel(SAFTY_IO_GROUP, SAFTY_IO_BIT);

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 红外测距传感器               */

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

#if defined(HAS_IRDIST)

#include "hal_adc.h"

extern uint16 irDistTab[256];

void sensorIRDistTimeout(struct ep_info_t *ep);

void sensorIRDistTimeout(struct ep_info_t *ep)

{

    uint8 value = HalAdcRead(0, HAL_ADC_RESOLUTION_14) >> 3;

    // 计算距离值value的单位为mm

    uint16 IRDistValue = irDistTab[value];

    SendData(ep->ep, &IRDistValue, 0x0000, TRANSFER_ENDPOINT, sizeof(IRDistValue));

}

#endif

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

/* 语音传感器                   */

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

#if defined(HAS_VOICE)

#include "hal_uart.h"

static struct ep_info_t *voiceEndPoint = NULL;

static uint8 LastVoiceData = 0;

static void sensorVoiceUartProcess( uint8 port, uint8 event );

static void sensorVoiceUartProcess( uint8 port, uint8 event )

{

    (void)event;  // Intentionally unreferenced parameter

    while (Hal_UART_RxBufLen(port))

    {

        HalUARTRead(port, &LastVoiceData, 1);

        if(LastVoiceData == 0xAA)

            LastVoiceData = 1;

        else if(LastVoiceData == 0x55)

            LastVoiceData = 0;

        else

            LastVoiceData = -1;

        if(voiceEndPoint != NULL)

            SendData(voiceEndPoint->ep, &LastVoiceData, 0x0000, TRANSFER_ENDPOINT, 1);

    }

}

void sensorVoiceNwkStateChange(struct ep_info_t *ep);

void sensorVoiceNwkStateChange(struct ep_info_t *ep)

{

    voiceEndPoint = ep;

}

void sensorVoiceResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensorVoiceResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        halUARTCfg_t uartConfig;

 

        voiceEndPoint = ep;

        /* UART Configuration */

        uartConfig.configured           = TRUE;

        uartConfig.baudRate             = HAL_UART_BR_9600;

        uartConfig.flowControl          = FALSE;

        uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;

        uartConfig.rx.maxBufSize        = MT_UART_DEFAULT_MAX_RX_BUFF;

        uartConfig.tx.maxBufSize        = MT_UART_DEFAULT_MAX_TX_BUFF;

        uartConfig.idleTimeout          = MT_UART_DEFAULT_IDLE_TIMEOUT;

        uartConfig.intEnable            = TRUE;

        uartConfig.callBackFunc         = sensorVoiceUartProcess;

        HalUARTOpen(HAL_UART_PORT_1, &uartConfig);

    }

}

void sensorVoiceTimeout(struct ep_info_t *ep);

void sensorVoiceTimeout(struct ep_info_t *ep)

{

    uint8 nulData = 0;

    SendData(ep->ep, &nulData, 0x0000, TRANSFER_ENDPOINT, 1);

}

#endif

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

/* 二进制执行器传感器           */

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

#if defined(HAS_EXECUTEB)

#define ControlInit()   do { HalIOSetOutput(1,4);HalIOSetOutput(1,5);HalIOSetOutput(1,6);HalIOSetOutput(1,7);Control(0); } while(0)

#define Control(mask)   do { HalIOSetLevel(1,4,mask&0x01);HalIOSetLevel(1,5,mask&0x02);HalIOSetLevel(1,6,mask&0x04);HalIOSetLevel(1,7,mask&0x08); } while(0)

void OutputExecuteBResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void OutputExecuteBResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

        ControlInit();

}

void outputExecuteB(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void outputExecuteB(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

    //msg->Data[], msg->DataLength, msg->TransSeqNumber

    Control(msg->Data[0]);

    SendData(ep->ep, &msg->Data[0], 0x0000, TRANSFER_ENDPOINT, 1);

}

void outputExecuteBTimeout(struct ep_info_t *ep);

void outputExecuteBTimeout(struct ep_info_t *ep)

{

    uint8 value = P1 >> 4;

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 模拟执行器传感器             */

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

#if defined(HAS_EXECUTEA)

void outputExecuteA(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void outputExecuteA(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

}

#endif

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

/* 遥控器传感器                 */

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

#if defined(HAS_REMOTER)

#include "IR.h"

static uint8 lastCode[32];

static uint8 lastCodeLen = 0;

void IRSendResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void IRSendResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

        IRSendInit();   // 需要初始化

}

void outputRemoter(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void outputRemoter(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

   lastCodeLen = msg->Data[0];

   memcpy(lastCode, &msg->Data[1], lastCodeLen);

   GenIR(&msg->Data[1], IRGuideLen_9ms, (uint8)lastCodeLen);

   SendData(ep->ep, lastCode, 0x0000, TRANSFER_ENDPOINT, lastCodeLen>>3);

}

void outputRemoterTimeout(struct ep_info_t *ep);

void outputRemoterTimeout(struct ep_info_t *ep)

{

    if(lastCodeLen <= 0)

    {

        uint8 value = 0;

        SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, 1);

    }

    else

        SendData(ep->ep, lastCode, 0x0000, TRANSFER_ENDPOINT, lastCodeLen>>3);

}

#endif

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

/* 虚拟功能                     */

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

#if defined(HAS_TESTFUNCTION)

#define TEST_STRING     "Z-Stack for SAPP"

static uint8 lastData[119] = TEST_STRING;

static uint8 lastLen = 0;

void testFunc_RecvData(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void testFunc_RecvData(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

    lastLen = msg->DataLength;

    memcpy(&lastData[sizeof(TEST_STRING) - 1], msg->Data, lastLen);

    SendData(ep->ep, lastData, 0x0000, TRANSFER_ENDPOINT,

                     lastLen + sizeof(TEST_STRING) - 1);

}

void testFunc_TimeOut(struct ep_info_t *ep);

void testFunc_TimeOut(struct ep_info_t *ep)

{

    SendData(ep->ep, lastData, 0x0000, TRANSFER_ENDPOINT,

                     lastLen + sizeof(TEST_STRING) - 1);

}

#endif

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

/* 广播发送功能                 */

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

#if defined(HAS_BROADCASTSEND)

#define BROADCAST_STRING     "\r\nBroadcast Message\r\n"

void BroadcastSend_TimeOut(struct ep_info_t *ep);

void BroadcastSend_TimeOut(struct ep_info_t *ep)

{

    SendData(ep->ep, BROADCAST_STRING, 0XFFFF, TRANSFER_ENDPOINT,

                     sizeof(BROADCAST_STRING) - 1);

    //广播后指示灯 LED_D9 闪烁2次

    HalLedBlink( HAL_LED_2, 2, 50, 100 );

}

#endif

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

/* 广播接收功能                 */

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

#if defined(HAS_BROADCASTRECEIVE)

void BroadcastReceiveData(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void BroadcastReceiveData(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

    //收到广播数据后 LED_D8 连续闪烁4次!

    HalLedBlink( HAL_LED_1, 4, 50, 120 );

    HalUARTWrite(HAL_UART_PORT_0, msg->Data, msg->DataLength);

}

#define BROADCAST_STRING     "Broadcast Message"

void BroadcastSend_TimeOut(struct ep_info_t *ep);

void BroadcastSend_TimeOut(struct ep_info_t *ep)

{

    SendData(ep->ep, BROADCAST_STRING, 0X0000, TRANSFER_ENDPOINT,

                     sizeof(BROADCAST_STRING) - 1);

}

#endif

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

/* IC卡读卡器                   */

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

#if defined(HAS_125KREADER)

#include "hal_uart.h"

#define CARDID_SIZE     5                   // 卡号长度

static uint8 lastCardId[CARDID_SIZE];       // 用来保存接收到的卡号

static uint8 cardRecvIdx;                   // 上一次接收到的长度

static uint32 lastTick;                     // 上一次接收数据的系统时间

static struct ep_info_t *cardEndPoint;

static void sensor125kReaderUartProcess( uint8 port, uint8 event );

static void sensor125kReaderUartProcess( uint8 port, uint8 event )

{

    (void)event;  // Intentionally unreferenced parameter

    if((lastTick + 100) <= osal_GetSystemClock())

    {                                       // 如果本次接收到的时间距离上次超过了0.1秒

        cardRecvIdx = 0;                    // 则清空计数器,重新接收卡号

    }

    lastTick = osal_GetSystemClock();       // 记录下当前的时间

    while (Hal_UART_RxBufLen(port))

    {

        uint16 restLen = Hal_UART_RxBufLen(port);

        if(restLen > (CARDID_SIZE - cardRecvIdx))

            restLen = CARDID_SIZE - cardRecvIdx;

        HalUARTRead(port, &lastCardId[cardRecvIdx], restLen);

        cardRecvIdx += restLen;

        if(cardRecvIdx >= CARDID_SIZE)      // 如果已经接收完成一个完整的卡号

        {                                   // 则发送给协调器

            SendData(cardEndPoint->ep, lastCardId, 0x0000, TRANSFER_ENDPOINT, CARDID_SIZE);

        }

    }

}

void sensor125kReaderResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void sensor125kReaderResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        halUARTCfg_t uartConfig;

 

        memset(lastCardId, 0, sizeof(lastCardId));

        cardRecvIdx = 0;

        cardEndPoint = ep;

        /* UART Configuration */

        uartConfig.configured           = TRUE;

        uartConfig.baudRate             = HAL_UART_BR_19200;

        uartConfig.flowControl          = FALSE;

        uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;

        uartConfig.rx.maxBufSize        = MT_UART_DEFAULT_MAX_RX_BUFF;

        uartConfig.tx.maxBufSize        = MT_UART_DEFAULT_MAX_TX_BUFF;

        uartConfig.idleTimeout          = MT_UART_DEFAULT_IDLE_TIMEOUT;

        uartConfig.intEnable            = TRUE;

        uartConfig.callBackFunc         = sensor125kReaderUartProcess;

        HalUARTOpen(HAL_UART_PORT_0, &uartConfig);

    }

}

void sensor125kReaderTimeout(struct ep_info_t *ep);

void sensor125kReaderTimeout(struct ep_info_t *ep)

{

    uint8 nullId[CARDID_SIZE] = { 0x00 };

    SendData(cardEndPoint->ep, nullId, 0x0000, TRANSFER_ENDPOINT, CARDID_SIZE);

}

#endif

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

/* 语音播放节点                 */

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

#if defined(HAS_SPEAKER)

void OutputSpeakerResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void OutputSpeakerResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

        HalUART1HwInit();

}

void outputSpeaker(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

void outputSpeaker(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

    //msg->Data[], msg->DataLength, msg->TransSeqNumber

    HalUART1HwTxByte(msg->Data[0]);

//    SendData(ep->ep, &msg->Data[0], 0x0000, TRANSFER_ENDPOINT, 1);

}

void outputSpeakerTimeout(struct ep_info_t *ep);

void outputSpeakerTimeout(struct ep_info_t *ep)

{

    uint8 value = 0;

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 红外接收解码                 */

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

#if defined(HAS_IRDecode)

#include <hal_irdec.h>

void IRDecodeResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res);

void IRDecodeResAvailable(struct ep_info_t *ep, RES_TYPE type, void *res)

{

    if(type == ResInit)

    {

        IRDecodeT1Init(ep->task_id, ep->ep);

    }

    //定时器1通道0一次红外解码结束,向上传送解码结果

    if(type == ResTimerInt)

    {

        OSALIRDecData_t *irData = (OSALIRDecData_t *)res;

        SendData(ep->ep, irData->irCode, 0x0000, TRANSFER_ENDPOINT, irData->irLen);

    }

}

void IRDecodeTimeout(struct ep_info_t *ep);

void IRDecodeTimeout(struct ep_info_t *ep)

{

    uint8 value = 0;

    SendData(ep->ep, &value, 0x0000, TRANSFER_ENDPOINT, sizeof(value));

}

#endif

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

/* 节点功能列表                                    */

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

struct ep_info_t funcList[] = {

#if defined(HAS_GAS)

    {

        // 加入网络,收到数据,超时处理,资源变化

        NULL, NULL, sensorGasTimeout, sensorGasResAvailable,

        { DevGas, 0, 5 },                   // type, id, refresh cycle

    },

#endif

#if defined(HAS_TEMP)

    {

        NULL, NULL, sensorTempTimeout, sensorTempResAvailable,

        { DevTemp, 1, 5 },                 // type, id, refresh cycle

    },

#endif

#if defined(HAS_HUMM)

    {

        NULL, NULL, sensorHummTimeout, sensorHummResAvailable,

        { DevHumm, 0, 5 },                 // type, id, refresh cycle

    },

#endif

#if defined(HAS_ILLUM)

    {

        NULL, NULL, sensorILLumTimeout, NULL,

        { DevILLum, 0, 3 },                // type, id, refresh cycle

    },

#endif

#if defined(HAS_RAIN)

    {

        NULL, NULL, sensorRainTimeout, sensorRainResAvailable,

        { DevRain, 0, 5 },                 // type, id, refresh cycle

    },

#endif

#if defined(HAS_IRDIST)

    {

        NULL, NULL, sensorIRDistTimeout, NULL,

        { DevIRDist, 0, 3 },               // type, id, refresh cycle

    },

#endif

#if defined(HAS_SMOKE)

    {

        NULL, NULL, sensorSmokeTimeout, sensorSmokeResAvailable,

        { DevSmoke, 0, 5 },                 // type, id, refresh cycle

    },

#endif

#if defined(HAS_FIRE)

    {

        NULL, NULL, sensorFireTimeout, sensorFireResAvailable,

        { DevFire, 0, 3 },                  // type, id, refresh cycle

    },

#endif

#if defined(HAS_IRPERS)

    {

        NULL, NULL, sensorIRPersTimeout, sensorIRPersResAvailable,

        { DevIRPers, 0, 2 },                // type, id, refresh cycle

    },

#endif

#if defined(HAS_VOICE)

    {

        sensorVoiceNwkStateChange, NULL, sensorVoiceTimeout, sensorVoiceResAvailable,

        { DevVoice, 0, 5 },                // type, id, refresh cycle

    },

#endif

#if defined(HAS_EXECUTEB)

    {

        NULL, outputExecuteB, outputExecuteBTimeout, OutputExecuteBResAvailable,

        { DevExecuteB, 3, 10 },              // type, id, refresh cycle

    },

#endif

#if defined(HAS_EXECUTEA)

    {

        NULL, outputExecuteA, NULL, NULL,

        { DevExecuteA, 0, 3 },              // type, id, refresh cycle

    },

#endif

#if defined(HAS_REMOTER)

    {

        NULL, outputRemoter, outputRemoterTimeout, IRSendResAvailable,

        { DevRemoter, 0, 3 },              // type, id, refresh cycle

    },

#endif

#if defined(HAS_TESTFUNCTION)

    {

        NULL,

        testFunc_RecvData,

        testFunc_TimeOut,

        NULL,

        { DevTest, 0, 3 },

    },

#endif

#if defined(HAS_BROADCASTSEND)

    {

        NULL,

        NULL,

        BroadcastSend_TimeOut,

        NULL,

        { DevBroadcastSend, 0, 3 },

    },

#endif

#if defined(HAS_BROADCASTRECEIVE)

    {

        NULL,

        BroadcastReceiveData,

        BroadcastSend_TimeOut,

        NULL,

        { DevBroadcastReceive, 0, 30 },

    },

#endif

#if defined(HAS_125KREADER)

    {

        NULL, NULL, sensor125kReaderTimeout, sensor125kReaderResAvailable,

        { Dev125kReader, 0, 10 },

    },

#endif

#if defined(HAS_SPEAKER)

    {

        NULL, outputSpeaker, outputSpeakerTimeout, OutputSpeakerResAvailable,

        { DevSpeaker, 0, 9 },              // type, id, refresh cycle

    },

#endif

#if defined(HAS_IRDecode)

    {

        NULL, NULL, IRDecodeTimeout, IRDecodeResAvailable,

        { DevIRDecode, 0, 5 },              // type, id, refresh cycle

    },

#endif

#if defined(ZDO_COORDINATOR)

    {   // 协调器

        CoordinatorNwkStateChangeRoutine,

        CoordinatorIncomingRoutine,

        CoordinatorTimeoutRoutine,

        CoordinatorResAvailableRoutine,

        { DevCoordinator, 0, 0 },

    },

#elif defined(RTR_NWK)

    {   // 路由器

        RouterNwkStateChangeRoutine,

        RouterIncomingRoutine,

        RouterTimeoutRoutine,

        RouterResAvailableRoutine,

        { DevRouter, 0, 30 },

    },

#endif

};

 

// 不能修改下面的内容!!!

const uint8 funcCount = sizeof(funcList) / sizeof(funcList[0]);

#endif

SAPP_Device.h

#ifndef _SAPP_DEVICE_H_

#define _SAPP_DEVICE_H_

#include "SAPP_FrameWork.h"

#ifdef __cplusplus

extern "C"

{

#endif

 

// 功能类型值定义

enum {

    DevTemp = 1,                    // 空气温度

    DevHumm,                        // 空气湿度

    DevILLum,                       // 光照度

    DevRain,                        // 雨滴

    DevIRDist,                      // 红外测距

    DevGas,                         // 燃气

    DevSmoke,                       // 烟雾

    DevFire,                        // 火焰

    DevIRPers,                      // 人体红外

    DevVoice,                       // 语音识别

    DevExecuteB,                    // 开关量输出执行器

    DevExecuteA,                    // 模拟量输出执行器

    DevRemoter,                     // 红外遥控

    Dev125kReader,                  // 125kHz读卡器

    DevSpeaker,                     // 语音报警

    DevTest,                        // 功能测试

    DevBroadcastSend,               // 广播发送

    DevBroadcastReceive,            // 广播接收

    DevIRDecode,                    // 红外遥控解码

    DevMaxNum,

};

 

#if !defined( ZDO_COORDINATOR ) && !defined( RTR_NWK )

// 节点功能定义

//#define HAS_GAS                   // 瓦斯传感器

//#define HAS_TEMP                  // 温度传感器

//#define HAS_HUMM                  // 湿度传感器

//#define HAS_RAIN                  // 雨滴传感器

//#define HAS_FIRE                  // 火焰传感器

//#define HAS_SMOKE                 // 烟雾传感器

//#define HAS_ILLUM                 // 光照度传感器

//#define HAS_IRPERS                // 人体红外传感器

//#define HAS_IRDIST                // 红外测距传感器

//#define HAS_VOICE                 // 语音传感器, 修改 HAL_UART_DMA 的定义为2

//#define HAS_EXECUTEB              // 执行器

//#define HAS_EXECUTEA              // 模拟执行器(预留扩展)

//#define HAS_REMOTER               // 红外遥控(预留扩展)

//#define HAS_TESTFUNCTION          // 虚拟功能

//#define HAS_BROADCASTSEND         // 广播发送

//#define HAS_BROADCASTRECEIVE      // 广播接收

//#define HAS_125KREADER            // 125K电子标签阅读器

//#define HAS_SPEAKER               // 语音报警器

//#define HAS_IRDecode              // 红外解码

#endif

 

#ifdef __cplusplus

}

#endif

#endif//_SAPP_DEVICE_H_

SAPP_FrameWork.h

#if defined(SAPP_ZSTACK)

#include "SAPP_FrameWork.h"

#include <string.h>

 

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

 * FUNCTIONS

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

static void createEndPoint(struct ep_info_t *epInfo, uint8 *task_id, uint8 ep);

#if defined(ZDO_COORDINATOR)

static uint8 uartMsgProcesser(uint8 *msg);

#endif

 

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

 * Local Variables

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

//uint8 ctrlBuffer[sizeof(TOPOINFO) + sizeof(FUNCTABLE) + FUNC_NUM * sizeof(FUNCINFO)];

static TOPOINFO topoBuffer = { 0x02 };

FUNCTABLE *funcTableBuffer;// = (FUNCTABLE *)(&ctrlBuffer[sizeof(TOPOINFO)]);

 

static devStates_t curNwkState;

static uint8 controlTaskId;

static uint8 functionTaskId;

static struct ep_info_t controlEndPointInfo;

static uint8 isUserTimerRunning = 0;

 

void sapp_taskInitProcess(void)

{

 #if defined ( BUILD_ALL_DEVICES )

    // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START

    // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered

    // together - if they are - we will start up a coordinator. Otherwise,

    // the device will start as a router.

    if ( readCoordinatorJumper() )

        zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;

    else

        zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;

#endif // BUILD_ALL_DEVICES

 

#if defined ( HOLD_AUTO_START )

    // HOLD_AUTO_START is a compile option that will surpress ZDApp

    //  from starting the device and wait for the application to

    //  start the device.

    ZDOInitDevice(0);

#endif

 

    // 构造功能列表

    funcTableBuffer = createFuncTable(funcCount);

    funcTableBuffer->ft_type = 0x01;

    funcTableBuffer->ft_count = funcCount;

    int i;

    for(i = 0; i < funcCount; i++)

    {

        funcTableBuffer->ft_list[i].type = funcList[i].function.type;

        funcTableBuffer->ft_list[i].id = funcList[i].function.id;

        funcTableBuffer->ft_list[i].cycle = funcList[i].function.cycle;

    }

    controlTaskId = tasksCnt - 2;

    functionTaskId = tasksCnt - 1;

    HalIOInit(functionTaskId);

    createEndPoint(&controlEndPointInfo, &controlTaskId, CONTROL_ENDPOINT);

    for(i = 0; i < funcCount; i++)

    {

        struct ep_info_t *ep = &funcList[i];

        createEndPoint(ep, &functionTaskId, i + 1);

        if(ep->res_available)

          (*ep->res_available)(ep, ResInit, NULL);

    }

#if defined(ZDO_COORDINATOR)// || defined(RTR_NWK)

//    RegisterForKeys( SampleApp_TaskID );

    MT_UartRegisterTaskID(controlTaskId);

#endif

}

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

 * LOCAL FUNCTIONS

 */

 

static void createEndPoint(struct ep_info_t *epInfo, uint8 *task_id, uint8 ep)

{

    static cId_t commonClusterId = SAPP_PERIODIC_CLUSTERID;

    // Fill out the endpoint description.

    epInfo->task_id = *task_id;

    epInfo->ep = ep;

    epInfo->timerTick = epInfo->function.cycle;

    epInfo->userTimer = 0;

 

    epInfo->simpleDesc.EndPoint = ep;

    epInfo->simpleDesc.AppProfId = SAPP_PROFID;

    epInfo->simpleDesc.AppDeviceId = SAPP_DEVICEID;

    epInfo->simpleDesc.AppDevVer = SAPP_DEVICE_VERSION;

    epInfo->simpleDesc.Reserved = 0;

    epInfo->simpleDesc.AppNumInClusters = 1;

    epInfo->simpleDesc.pAppInClusterList = &commonClusterId;

    epInfo->simpleDesc.AppNumOutClusters = 1;

    epInfo->simpleDesc.pAppOutClusterList = &commonClusterId;

 

    epInfo->SampleApp_epDesc.endPoint = ep;

    epInfo->SampleApp_epDesc.task_id = task_id;

    epInfo->SampleApp_epDesc.simpleDesc = &epInfo->simpleDesc;

    epInfo->SampleApp_epDesc.latencyReq = noLatencyReqs;

 

    // Register the endpoint description with the AF

    afRegister(&epInfo->SampleApp_epDesc);

}

 

uint16 sapp_controlEpProcess(uint8 task_id, uint16 events)

{

    afIncomingMSGPacket_t *MSGpkt;

 

    if ( events & SYS_EVENT_MSG )

    {

        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(task_id);

        while ( MSGpkt )

        {

            switch ( MSGpkt->hdr.event )

            {

#if defined(ZDO_COORDINATOR)

            case CMD_SERIAL_MSG:

//                SampleApp_UartMessage((uint8 *)MSGpkt);

                uartMsgProcesser((uint8 *)MSGpkt);

                HalLedBlink( HAL_LED_1, 2, 50, 90 );

                break;

#endif

                // Received when a messages is received (OTA) for this endpoint

            case AF_INCOMING_MSG_CMD:

            {

                // TODO: QueryProfile or QueryTopo

                switch(MSGpkt->clusterId)

                {

                case SAPP_PERIODIC_CLUSTERID:

                    switch(MSGpkt->cmd.Data[0])

                    {

                    case 0x01:

                        // CtrlQueryProfile

                        // 获取到数据包的来源地址来当做发送数据的目标

                        SendData(CONTROL_ENDPOINT, funcTableBuffer->ft_data, MSGpkt->srcAddr.addr.shortAddr, MSGpkt->srcAddr.endPoint, sizeof(FUNCTABLE) + funcCount * sizeof(FUNCINFO));

                        break;

                    case 0x02:

                        // CtrlQueryTopo

                        // 获取到数据包的来源地址来当做发送数据的目标

                        SendData(CONTROL_ENDPOINT, (unsigned char *)&topoBuffer, MSGpkt->srcAddr.addr.shortAddr, MSGpkt->srcAddr.endPoint, sizeof(TOPOINFO));

                        break;

                    case 0x03:

                        // CtrlQuerySpecialFunction

                        // cmd.Data[0] = 3, cmd.Data[1] = funcCode, cmd.Data[2] = funcID

                        {

                            uint8 i;

                            for(i = 0; i < funcTableBuffer->ft_count; i++)

                            {

                                if((funcTableBuffer->ft_list[i].type == MSGpkt->cmd.Data[1])

                                   && (funcTableBuffer->ft_list[i].id == MSGpkt->cmd.Data[2]))

                                {

                                    // 0x03, EndPoint, rCycle

                                    uint8 specialFunc[3] = { 0x03, i + 1, funcTableBuffer->ft_list[i].cycle };

                                    SendData(CONTROL_ENDPOINT, specialFunc, MSGpkt->srcAddr.addr.shortAddr, MSGpkt->srcAddr.endPoint, sizeof(specialFunc));

                                    break;

                                }

                            }

                        }

                        break;

                    default:

                        {

                            int i;

                            for(i = 0; i < funcCount; i++)

                            {

                                struct ep_info_t *ep = &funcList[i];

                                if(ep->res_available)   (*ep->res_available)(ep, ResControlPkg, MSGpkt);

                            }

                        }

                        break;

                    }

                    HalLedBlink( HAL_LED_2, 1, 50, 250 );

                    break;

                }

                break;

            }

            // Received whenever the device changes state in the network

            case ZDO_STATE_CHANGE:

            {

                devStates_t st = (devStates_t)(MSGpkt->hdr.status);

                if ( (st == DEV_ZB_COORD)

                        || (st == DEV_ROUTER)

                        || (st == DEV_END_DEVICE) )

                {

//                    topoBuffer->type = 0x02;

                    memcpy(topoBuffer.IEEE, NLME_GetExtAddr(), 8);

#if !defined(ZDO_COORDINATOR)

                    topoBuffer.PAddr = NLME_GetCoordShortAddr();

#else

                    topoBuffer.PAddr = 0xFFFF;

#endif

                    osal_memcpy(&topoBuffer.panid, &_NIB.nwkPanId, sizeof(uint16));

                    osal_memcpy(&topoBuffer.channel, &_NIB.nwkLogicalChannel, sizeof(uint8));

                    //向协调器发送拓扑信息

                    SendData(CONTROL_ENDPOINT, (unsigned char *)&topoBuffer, 0x0000, TRANSFER_ENDPOINT, sizeof(TOPOINFO));

                    HalLedBlink( HAL_LED_2, 4, 50, 250 );

                }

            }

            break;

            default:

                break;

            }

            // Release the memory

            osal_msg_deallocate( (uint8 *)MSGpkt );

            // Next - if one is available

            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id );

        }

        // return unprocessed events

        return (events ^ SYS_EVENT_MSG);

    }

    // 定时器时间到, 遍历所有端点看是否有userTimer

    if(events & SAPP_SEND_PERIODIC_MSG_EVT)

    {

        int i;

        uint8 hasUserTimer = 0;

        for(i = 0; i < funcCount; i++)

        {

            struct ep_info_t *ep = &funcList[i];

            if(ep->userTimer && ep->res_available)

            {

                hasUserTimer = 1;

                ep->userTimer = ep->userTimer - 1;

                if(ep->userTimer <= 1)

                {

                    ep->userTimer = 0;

                    (*ep->res_available)(ep, ResUserTimer, NULL);

                }

            }

        }

        if(hasUserTimer)

        {

            // 重新启动定时器

            osal_start_timerEx(task_id, SAPP_SEND_PERIODIC_MSG_EVT, 1000);

        }

        else

        {

            isUserTimerRunning = 0;

            osal_stop_timerEx(task_id, SAPP_SEND_PERIODIC_MSG_EVT);

        }

        // return unprocessed events

        return (events ^ SAPP_SEND_PERIODIC_MSG_EVT);

    }

    // Discard unknown events

    return 0;

}

 

uint16 sapp_functionEpProcess(uint8 task_id, uint16 events)

{

    afIncomingMSGPacket_t *MSGpkt;

    if(events & SYS_EVENT_MSG)

    {

        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id );

        while ( MSGpkt )

        {

            switch ( MSGpkt->hdr.event )

            {

            // 接收到数据包

            case AF_INCOMING_MSG_CMD:

                {

                    switch ( MSGpkt->clusterId )

                    {

                    case SAPP_PERIODIC_CLUSTERID:

                        if(MSGpkt->endPoint <= funcCount)

                        {

                            struct ep_info_t *ep = &funcList[MSGpkt->endPoint - 1];

                            if(ep->incoming_data)

                                (*ep->incoming_data)(ep, MSGpkt->srcAddr.addr.shortAddr, MSGpkt->srcAddr.endPoint, &MSGpkt->cmd);

                        }

                        HalLedBlink( HAL_LED_2, 1, 50, 250 );

                        break;

                    }

                }

                break;

 

            case ZDO_STATE_CHANGE:

                {

                    curNwkState = (devStates_t)(MSGpkt->hdr.status);

                    if ( (curNwkState == DEV_ZB_COORD)

                            || (curNwkState == DEV_ROUTER)

                            || (curNwkState == DEV_END_DEVICE) )

                    {

                        int i;

                        int hasTimeOut = 0;

                        for(i = 0; i < funcCount; i++)

                        {

                            struct ep_info_t *ep = &funcList[i];

                            if(ep->nwk_stat_change)

                                (*ep->nwk_stat_change)(ep);

                            // 重置端点计数器

                            if(ep->time_out && ep->function.cycle)

                            {

                                ep->timerTick = ep->function.cycle;

                                hasTimeOut = 1;

                            }

                        }

                        if(hasTimeOut)

                        {

                            // 加入网络成功,启动定时器,为各个端点提供定时

                            osal_start_timerEx(task_id,

                                               SAPP_SEND_PERIODIC_MSG_EVT,

                                               1000);

                        }

                    }

                    else

                        osal_stop_timerEx(task_id, SAPP_SEND_PERIODIC_MSG_EVT);

                }

                break;

            case IOPORT_INT_EVENT:

              {

                OSALIOIntData_t* IOIntData;

                IOIntData =(OSALIOIntData_t*)MSGpkt;

                if(IOIntData->endPoint <= funcCount)

                {

                    struct ep_info_t *ep = &funcList[IOIntData->endPoint - 1];

                    if(ep->res_available)

                        (*ep->res_available)(ep, ResIOInt, IOIntData->arg);

                }

              }

              break;

#if defined(HAL_IRDEC) && (HAL_IRDEC == TRUE)

            case IRDEC_INT_EVENT:   //

              {

                OSALIRDecIntData_t* TimerIntData = (OSALIRDecIntData_t*)MSGpkt;

                if(TimerIntData->endPoint <= funcCount)

                {

                    struct ep_info_t *ep = &funcList[TimerIntData->endPoint - 1];

                    if(ep->res_available)

                        (*ep->res_available)(ep, ResTimerInt, TimerIntData->data);

                }

              }

              break;

#endif

            default:

                break;

            }

            // Release the memory

            osal_msg_deallocate( (uint8 *)MSGpkt );

            // Next - if one is available

            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id );

        }

        // return unprocessed events

        return (events ^ SYS_EVENT_MSG);

    }

 

    // 定时器时间到, 遍历所有端点看是否有需要调用time_out

    if(events & SAPP_SEND_PERIODIC_MSG_EVT)

    {

        int i;

        for(i = 0; i < funcCount; i++)

        {

            struct ep_info_t *ep = &funcList[i];

            if(ep->time_out && ep->function.cycle)

            {

                // 端点需要周期执行

                ep->timerTick = ep->timerTick - 1;

                if(ep->timerTick == 0)

                {

                  // 定时时间到,执行time_out函数

                  (*ep->time_out)(ep);

                  ep->timerTick = ep->function.cycle;

                }

            }

#if 0

            if(ep->userTimer && ep->res_available)

            {

                ep->userTimer = ep->userTimer - 1;

                if(ep->userTimer <= 1)

                {

                    (*ep->res_available)(ep, ResUserTimer, NULL);

                    ep->userTimer = 0;

                }

            }

#endif

        }

        // 重新启动定时器

        osal_start_timerEx(task_id, SAPP_SEND_PERIODIC_MSG_EVT, 1000);

        // return unprocessed events

        return (events ^ SAPP_SEND_PERIODIC_MSG_EVT);

    }

    // Discard unknown events

    return 0;

}

 

#if defined(ZDO_COORDINATOR)

static uint8 uartMsgProcesser(uint8 *msg)

{

    mtOSALSerialData_t *pMsg = (mtOSALSerialData_t *)msg;

    mtUserSerialMsg_t *pMsgBody = (mtUserSerialMsg_t *)pMsg->msg;

    if ( (curNwkState != DEV_ZB_COORD)

            && (curNwkState != DEV_ROUTER)

            && (curNwkState != DEV_END_DEVICE) )

        return 1;

    switch(pMsgBody->cmd)

    {

    case 0x0018:

        {

            switch(pMsgBody->cmdEndPoint)

            {

            case 0xF1:

                {

                    // 转发数据

                    SendData(TRANSFER_ENDPOINT, pMsgBody->data,

                             pMsgBody->addr, pMsgBody->endPoint,

                             pMsgBody->len - 6);

                }

                break;

            }

        }

        break;

    }

    return 1;

}

#endif

 

uint8 SendData(uint8 srcEP, const void *buf, uint16 addr, uint8 dstEP, uint8 Len)

{

    static uint8 transID = 0;

    afAddrType_t SendDataAddr;

    struct ep_info_t *epInfo;

 

    if(srcEP <= funcCount)

        epInfo = &funcList[srcEP - 1];

    else

        epInfo = &controlEndPointInfo;

 

    SendDataAddr.addrMode = (afAddrMode_t)Addr16Bit;         //短地址发送

    SendDataAddr.endPoint = dstEP;

    SendDataAddr.addr.shortAddr = addr;

    if ( AF_DataRequest( &SendDataAddr, //发送的地址和模式

                         // TODO:

                         &epInfo->SampleApp_epDesc,   //终端(比如操作系统中任务ID等)

                         SAPP_PERIODIC_CLUSTERID,//发送串ID

                         Len,

                         (uint8*)buf,

                         &transID,  //信息ID(操作系统参数)

                         AF_DISCV_ROUTE,

                         AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

    {

        HalLedBlink( HAL_LED_1, 1, 50, 250 );

        return 1;

    }

    else

    {

        return 0;

    }

}

 

void CreateUserTimer(struct ep_info_t *ep, uint8 seconds)

{

    if(ep == NULL)

        return;

    if(ep->res_available == NULL)

        return;

    ep->userTimer = seconds;

    if(isUserTimerRunning == 0)

    {

        osal_start_timerEx(controlTaskId,

                           SAPP_SEND_PERIODIC_MSG_EVT,

                           1000);

        isUserTimerRunning = 1;

    }

}

 

void DeleteUserTimer(struct ep_info_t *ep)

{

    if(ep == NULL)

        return;

    ep->userTimer = 0;

}

 

void ModifyRefreshCycle(struct ep_info_t *ep, uint8 seconds)

{

    if(ep == NULL)

        return;

    if(ep->time_out == NULL)

        return;

    ep->function.cycle = seconds;

    if(ep->timerTick > seconds)

        ep->timerTick = seconds;

}

 

#if ! defined(ZDO_COORDINATOR) && defined(RTR_NWK)

void RouterTimeoutRoutine(struct ep_info_t *ep)

{

    SendData(ep->ep, (unsigned char *)&topoBuffer, 0x0000, TRANSFER_ENDPOINT, sizeof(TOPOINFO)); //节点向协调器发送采集数据

}

#endif

 

#if defined(ZDO_COORDINATOR)

void CoordinatorIncomingRoutine(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg)

{

    //msg->Data[], msg->DataLength, msg->TransSeqNumber

    // 转发数据到串口

    if(msg->DataLength > 0)

    {

        mtUserSerialMsg_t *pMsg = osal_mem_alloc(sizeof(mtUserSerialMsg_t) + msg->DataLength - 1);

        pMsg->sop = MT_UART_SOF;

        pMsg->len = msg->DataLength + 6;

        pMsg->cmd = 0x0018;

        pMsg->cmdEndPoint = 0xF1;

        pMsg->addr = addr;

        pMsg->endPoint = endPoint;

        memcpy(pMsg->data, msg->Data, msg->DataLength);

        pMsg->fsc = MT_UartCalcFCS(0, &pMsg->len, 1);

        pMsg->fsc = MT_UartCalcFCS(pMsg->fsc, pMsg->dataBody, pMsg->len);

        HalUARTWrite(HAL_UART_PORT_0, &pMsg->sop, sizeof(mtUserSerialMsg_t) - 2 + msg->DataLength);

        HalUARTWrite(HAL_UART_PORT_0, &pMsg->fsc, 1);

        osal_mem_free(pMsg);

    }

}

#endif

#endif//SAPP_ZSTACK

SAPP_FrameWork.h

#ifndef _SAPP_FRAMEWORK_H_

#define _SAPP_FRAMEWORK_H_

#include <hal_board.h>

#include "ZComDef.h"

#include "hal_drivers.h"

#include "OSAL.h"

#include "ZGlobals.h"

#include "AF.h"

#include "aps_groups.h"

 

#include "nwk.h"

#include "APS.h"

#if defined ( ZIGBEE_FRAGMENTATION )

  #include "aps_frag.h"

#endif

 

#include "MT.h"

#include "MT_UART.h"

#if defined( MT_TASK )

#include "MT_TASK.h"

#endif

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )

  #include "ZDNwkMgr.h"

#endif

 

#include "ZDApp.h"

#include "ZComDef.h"

#include "OSAL_Tasks.h"

#include "aps_groups.h"

#include "OnBoard.h"

/* HAL */

#include "hal_led.h"

#include "hal_io.h"

#include "hal_irdec.h"

 

// These constants are only for example and should be changed to the

// device's needs

#define CONTROL_ENDPOINT             0xF0

#define TRANSFER_ENDPOINT            1

 

#define SAPP_PROFID                  0x0F08

#define SAPP_DEVICEID                0x0001

#define SAPP_DEVICE_VERSION          0

 

#define SAPP_PERIODIC_CLUSTERID      1

 

// Application Events (OSAL) - These are bit weighted definitions.

#define SAPP_SEND_PERIODIC_MSG_EVT   0x0001

 

enum {

    DevRouter = 240,

    DevCoordinator

};

 

typedef struct topo_info_t {

    uint8 type;

    uint8 IEEE[8];

    uint16 PAddr;

    uint16 panid;

    uint8 channel;

} TOPOINFO;

 

typedef struct func_info_t {

    uint8 type;

    uint8 id;

    uint8 cycle;

} FUNCINFO;

typedef union {

    uint8 ft_data[2];

    struct {

        uint8 ft_type;

        uint8 ft_count;

        FUNCINFO ft_list[0];

    } ft_field;

} FUNCTABLE;

#define ft_type ft_field.ft_type

#define ft_count ft_field.ft_count

#define ft_list ft_field.ft_list

#define createFuncTable(count)  (FUNCTABLE *)osal_mem_alloc(sizeof(FUNCTABLE) + count * sizeof(FUNCINFO))

#define destroyFuncTable(ft)    osal_mem_free(ft)

 

typedef enum {

    ResMinType = 0,

    ResInit,            // 表示模块初始化

    ResSerial,

    ResUserTimer,

    ResControlPkg,

    ResIOInt,

    ResTimerInt,

    ResMaxType,

} RES_TYPE;

struct ep_info_t {

    // 网络状态发生变化时会调用该函数

    void (*nwk_stat_change)(struct ep_info_t *ep);

    // 接收到数据时会调用该函数

    void (*incoming_data)(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

    // 周期性调用的函数

    void (*time_out)(struct ep_info_t *ep);

    // 系统资源可用时调用该函数,系统资源指的是:串口接收到数据/中断等等

    void (*res_available)(struct ep_info_t *ep, RES_TYPE type, void *res);

    // NOTE: cycle成员会被用来计数,并周期性调用time_out函数

    struct func_info_t function;

 

    // 当前端点号

    uint8 ep;

    // 与此端点绑定的任务ID

    uint8 task_id;

    // 递减计数,为0时调用time_out函数,并重载初值=cycle

    uint8 timerTick;

    uint8 userTimer;

    endPointDesc_t SampleApp_epDesc;

    SimpleDescriptionFormat_t simpleDesc;

};

 

extern struct ep_info_t funcList[];

extern const uint8 funcCount;

 

extern void sapp_taskInitProcess(void);

extern uint16 sapp_controlEpProcess(uint8 task_id, uint16 events);

extern UINT16 sapp_functionEpProcess( uint8 task_id, uint16 events );

extern uint8 SendData(uint8 srcEP, const void *buf, uint16 addr, uint8 dstEP, uint8 Len);

extern void CreateUserTimer(struct ep_info_t *ep, uint8 seconds);

extern void DeleteUserTimer(struct ep_info_t *ep);

extern void ModifyRefreshCycle(struct ep_info_t *ep, uint8 seconds);

 

#if defined(ZDO_COORDINATOR)

#define CoordinatorNwkStateChangeRoutine    NULL

void CoordinatorIncomingRoutine(struct ep_info_t *ep, uint16 addr, uint8 endPoint, afMSGCommandFormat_t *msg);

#define CoordinatorTimeoutRoutine           NULL

#define CoordinatorResAvailableRoutine      NULL

#elif defined(RTR_NWK)

#define RouterNwkStateChangeRoutine         NULL

#define  RouterIncomingRoutine              NULL

void RouterTimeoutRoutine(struct ep_info_t *ep);

#define RouterResAvailableRoutine           NULL

 

#endif

#endif//_SAPP_FRAMEWORK_H_