实验九 ZStack 广播通信实验
实验九 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 广播通信实验的更多相关文章
- 实验十 ZStack 网状网络实验
实验十 ZStack 网状网络实验[实验目的]1. 了解 ZigBee 网状网络结构2. 掌握构建网状网络的方法[实验设备]1. 装有 IAR 开发工具的 PC 机一台2. 实验箱一台3. CCDeb ...
- Linux进程间通信(九)---综合实验之有名管道通信实验
实验目的 通过编写有名管道多路通信实验,进一步掌握管道的创建.读写等操作,同时复习使用select()函数实现管道的通信. 实验内容 这里采用管道函数创建有名管道(不是在控制台下输入命令mknod), ...
- 20155235 《网络攻防》 实验九 Web安全基础
20155235 <网络攻防> 实验九 Web安全基础 实验内容 SQL注入攻击 XSS攻击 CSRF攻击 WebGoat WebGoat是OWASP组织研制出的用于进行web漏洞实验的应 ...
- 20155328 《网络对抗》 实验九 Web安全
20155328 <网络对抗> 实验九 Web安全 基础 实验过程记录 在实验开始之前先把webgoat的jar包放到home目录下.打开终端,用命令java -jar webgoat-c ...
- WUST 设计模式 实验九 观察者模式的应用
实验九 观察者模式的应用 一.实验目的 掌握外观模式(Observer)的特点: 分析具体问题,使用外观模式进行设计. 二.实验内容和要求 网上商店中如果商品(product)在名称(name). ...
- Linux基础入门(新版)(实验九-实验十二)
实验九 简单文本入门 一.常用的文本处理命令 二.文本处理命令 1.tr 命令 tr 命令可以用来删除一段文本信息中的某些文字.或者将其进行转换. 使用方式: tr [option]...SET1 [ ...
- 2017-2018-2 20155228 《网络对抗技术》 实验九:Web安全基础
2017-2018-2 20155228 <网络对抗技术> 实验九:Web安全基础 1. 实践内容 1.1 标理解常用网络攻击技术的基本原理 1.2 在Webgoat实验环境下实践相关实验 ...
- 2017-2018-2 20155225《网络对抗技术》实验九 Web安全基础
2017-2018-2 20155225<网络对抗技术>实验九 Web安全基础 WebGoat 1.String SQL Injection 题目是想办法得到数据库所有人的信用卡号,用Sm ...
- 20155201 网络攻防技术 实验九 Web安全基础
20155201 网络攻防技术 实验九 Web安全基础 一.实践内容 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 二.报告内容: 1. 基础问题回答 1)SQL注入攻击 ...
随机推荐
- Java多线程之synchronized及其优化
Synchronized和同步阻塞synchronized是jvm提供的同步和锁机制,与之对应的是jdk层面的J.U.C提供的基于AbstractQueuedSynchronizer的并发组件.syn ...
- php封装curl,模拟POST和GET请求HTTPS请求
<?php /** * @title 封装代理请求 * @author victor **/ class ApiRequest { /** * curl提交数据 * @param String ...
- paramiko向服务器自动上传下载文件
import paramikoimport os def download_from(ip,u,p): file_list=['file2',file3','file4'] file_path=&qu ...
- Android中软键盘展示、EditText焦点获取及windowSoftInputMode属性探究
2017-08-14 21:44:23 有很多中情况,分别展示. 1.Activity不做任何设置,布局使用LinearLayout 会自动滚动EditText之上的所有View,代码: <?x ...
- 作业:K-means算法应用:图片压缩
from sklearn.datasets import load_sample_image from sklearn.cluster import KMeans import matplotlib. ...
- Windows下Caffe实现图像分类
前言:最近参加百度点石大赛,完成商家招牌的分类和检测,把实验过程简单记录下来,具体步骤如下. 环境配置:windows下的visual studio2013和caffe(cpu版本)环境搭建请看我另一 ...
- Windows创建Sciter的第一个程序.HelloWorld
介绍什么的就免了.直接进入正题 平台: Windows 10 IDE : Visual studio 2017 首先从官网下载最新的SDK,https://sciter.com/download/ 创 ...
- bootstrap-fileinput多图片上传
在页面写一个input框: <input id="subGraphAddress1" name="subGraphAddress" type=" ...
- C# FTP操作报550错误
最近在做FTP创建文件夹和上传文件的功能,测试之后一直提示“远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)”,我在网上找了很久的解决方案也没有解决掉这个问题,网上找到的 ...
- css中关于单位的一些问题
Css中关于单位的一些问题 相对字体长度: Em:Em 是一个相对单位.起初排版度量时是基于当前字体大写字母”M”的尺寸的.当改变font-family时,它的尺寸不会发生改变,但在改变font-si ...