实验 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. Java多线程之synchronized及其优化

    Synchronized和同步阻塞synchronized是jvm提供的同步和锁机制,与之对应的是jdk层面的J.U.C提供的基于AbstractQueuedSynchronizer的并发组件.syn ...

  2. php封装curl,模拟POST和GET请求HTTPS请求

    <?php /** * @title 封装代理请求 * @author victor **/ class ApiRequest { /** * curl提交数据 * @param String ...

  3. paramiko向服务器自动上传下载文件

    import paramikoimport os def download_from(ip,u,p): file_list=['file2',file3','file4'] file_path=&qu ...

  4. Android中软键盘展示、EditText焦点获取及windowSoftInputMode属性探究

    2017-08-14 21:44:23 有很多中情况,分别展示. 1.Activity不做任何设置,布局使用LinearLayout 会自动滚动EditText之上的所有View,代码: <?x ...

  5. 作业:K-means算法应用:图片压缩

    from sklearn.datasets import load_sample_image from sklearn.cluster import KMeans import matplotlib. ...

  6. Windows下Caffe实现图像分类

    前言:最近参加百度点石大赛,完成商家招牌的分类和检测,把实验过程简单记录下来,具体步骤如下. 环境配置:windows下的visual studio2013和caffe(cpu版本)环境搭建请看我另一 ...

  7. Windows创建Sciter的第一个程序.HelloWorld

    介绍什么的就免了.直接进入正题 平台: Windows 10 IDE : Visual studio 2017 首先从官网下载最新的SDK,https://sciter.com/download/ 创 ...

  8. bootstrap-fileinput多图片上传

    在页面写一个input框: <input id="subGraphAddress1" name="subGraphAddress" type=" ...

  9. C# FTP操作报550错误

    最近在做FTP创建文件夹和上传文件的功能,测试之后一直提示“远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)”,我在网上找了很久的解决方案也没有解决掉这个问题,网上找到的 ...

  10. css中关于单位的一些问题

    Css中关于单位的一些问题 相对字体长度: Em:Em 是一个相对单位.起初排版度量时是基于当前字体大写字母”M”的尺寸的.当改变font-family时,它的尺寸不会发生改变,但在改变font-si ...