实验 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 连续闪烁四次。通过观察各个节点的通信指示灯就可以判断是否接收到广播信息。

实验流程图

实验步骤

1.打开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_

实验九 ZStack 广播通信实验的更多相关文章

  1. 实验十 ZStack 网状网络实验

    实验十 ZStack 网状网络实验[实验目的]1. 了解 ZigBee 网状网络结构2. 掌握构建网状网络的方法[实验设备]1. 装有 IAR 开发工具的 PC 机一台2. 实验箱一台3. CCDeb ...

  2. Linux进程间通信(九)---综合实验之有名管道通信实验

    实验目的 通过编写有名管道多路通信实验,进一步掌握管道的创建.读写等操作,同时复习使用select()函数实现管道的通信. 实验内容 这里采用管道函数创建有名管道(不是在控制台下输入命令mknod), ...

  3. 20155235 《网络攻防》 实验九 Web安全基础

    20155235 <网络攻防> 实验九 Web安全基础 实验内容 SQL注入攻击 XSS攻击 CSRF攻击 WebGoat WebGoat是OWASP组织研制出的用于进行web漏洞实验的应 ...

  4. 20155328 《网络对抗》 实验九 Web安全

    20155328 <网络对抗> 实验九 Web安全 基础 实验过程记录 在实验开始之前先把webgoat的jar包放到home目录下.打开终端,用命令java -jar webgoat-c ...

  5. WUST 设计模式 实验九 观察者模式的应用

    实验九 观察者模式的应用 一.实验目的 掌握外观模式(Observer)的特点: 分析具体问题,使用外观模式进行设计. 二.实验内容和要求   网上商店中如果商品(product)在名称(name). ...

  6. Linux基础入门(新版)(实验九-实验十二)

    实验九 简单文本入门 一.常用的文本处理命令 二.文本处理命令 1.tr 命令 tr 命令可以用来删除一段文本信息中的某些文字.或者将其进行转换. 使用方式: tr [option]...SET1 [ ...

  7. 2017-2018-2 20155228 《网络对抗技术》 实验九:Web安全基础

    2017-2018-2 20155228 <网络对抗技术> 实验九:Web安全基础 1. 实践内容 1.1 标理解常用网络攻击技术的基本原理 1.2 在Webgoat实验环境下实践相关实验 ...

  8. 2017-2018-2 20155225《网络对抗技术》实验九 Web安全基础

    2017-2018-2 20155225<网络对抗技术>实验九 Web安全基础 WebGoat 1.String SQL Injection 题目是想办法得到数据库所有人的信用卡号,用Sm ...

  9. 20155201 网络攻防技术 实验九 Web安全基础

    20155201 网络攻防技术 实验九 Web安全基础 一.实践内容 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 二.报告内容: 1. 基础问题回答 1)SQL注入攻击 ...

随机推荐

  1. As The End of The Year Approaches,The Weighted Blanket Season Begins

    Weight blankets are well known for anxiety, insomnia, depression and so on. It is physical therapy, ...

  2. 给listview加动画,让动画执行结束后再刷新

    问题:当给listview的条目加动画时,例如添加一个条目或者移除一个条目,动画效果会和添加删除条目的逻辑同时进行,因为动画并不是阻塞式的,这样会造成动画还没有结束,条目已经添加或者移除,从而动画作用 ...

  3. 第一章 Python基本语法

    寒假不能荒废,终于静下心来认真地开始学习Python,在这里与大家分享一下所学知识,希望能对像我这样的小白有所帮助,如有错误之处,谢大佬不吝赐教!!    编程语言包括机器语言.汇编语言.高级语言.超 ...

  4. IntelliJ IDEA入门系列

    1.Java Web之Helloworld配置 2.Java Web之Maven搭建Helloworld 3.Java Web之Spring MVC简单管理系统

  5. select下拉列表js操作兼容性问题分享

    做一个下拉列表鼠标移入改变对应的图片的值, $("select").mosover(function(){ //var i=$(this).find("selected& ...

  6. Ubuntu16.04安装MongoDB的Ruby驱动

    背景: 1. ruby的安装方式:sudo apt-get install ruby 2. mongod服务已开启 3. ruby版本:2.3, gem已安装 安装驱动的步骤: 1. gem inst ...

  7. ionic3 对android包进行签名

    在已经生成签名文件的前提下 对android包进行签名 如果还未生成签名文件 请参考链接 https://jingyan.baidu.com/article/642c9d34eaeeda644a46f ...

  8. day14 内置函数二

    lamda 语法: 函数名 = lambda 参数: 返回值注意: 1. 函数的参数可以有多个. 多个参数之间⽤逗号隔开 2. 匿名函数不管多复杂. 只能写⼀⾏, 且逻辑结束后直接返回数据 3. 返回 ...

  9. centos 6.5 下 nginx 简单优化_虚拟主机_负载均衡

    # 用了nginx for win很久,安装也是超级简单.# 还是用一下linux版的吧.环境是centos 6.5 x64 # 安装开始: # 先安装依赖 yum install gcc-c++ y ...

  10. 巧用std::shared_ptr全局对象释放单例内存

    巧用std::shared_ptr 单例的使用相对比较广泛,但是需要在程序退出前调用它的析构函数对数据进行释放,常规做法是在main函数末尾进行释放工作, 但是这样相对比较繁琐,因此便有了利用全局变量 ...