上一篇文章写到终端节点向应用层发送绑定确认,即zb_BindConfirm函数,我们可以看下源代码。
void zb_BindConfirm( uint16 commandId, uint8 status )
{
(void)commandId;
if ( ( status == ZB_SUCCESS )&& ( myAppState == APP_START ) )//条件成立
{
myAppState =APP_BOUND;//将应用状态修改为 绑定状态
//Startreporting sensor values
myApp_StartReporting();//开始传输函数
}
else
{
// Continueto discover a collector
osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT,myBindRetryDelay );
}
查看传输函数源代码:
void myApp_StartReporting( void )
{
osal_start_timerEx( sapi_TaskID,MY_REPORT_TEMP_EVT, myTempReportPeriod );//传输温度事件
osal_start_timerEx( sapi_TaskID,MY_REPORT_BATT_EVT, myBatteryCheckPeriod );//传输电压事件
HalLedSet( HAL_LED_1, HAL_LED_MODE_ON);//点亮LED_1;
}
我们看终端节点sapi层如何处理这两个时间,首先找到SAPI_ProcessEvent函数中的:
if ( events & ( ZB_USER_EVENTS) )
{
// Userevents are passed to the application
#if ( SAPI_CB_FUNC )
zb_HandleOsalEvent( events );//事件处理函数
#endif
// Do notreturn here, return 0 later
}
进入到函数中去:
void zb_HandleOsalEvent( uint16 event )
{
uint8 pData[2];
if ( event & MY_START_EVT)
{
zb_StartRequest();
}
if ( event & MY_REPORT_TEMP_EVT)
{
// Read andreport temperature value
pData[0] =TEMP_REPORT;//要发送的数据的类型
pData[1]= myApp_ReadTemperature();//利用此函数接收读取的温度值
zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, 2, pData, 0,AF_ACK_REQUEST, 0 );//发送数据
osal_start_timerEx( sapi_TaskID, MY_REPORT_TEMP_EVT,myTempReportPeriod );
}
if ( event &MY_REPORT_BATT_EVT )
{
// Readbattery value
// Ifbattery level low, report battery value
pData[0] =BATTERY_REPORT;//要发送的数据的类型
pData[1]= myApp_ReadBattery();//利用此函数接收读取的温度值
zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, 2, pData, 0,AF_ACK_REQUEST, 0 );//发送数据
osal_start_timerEx( sapi_TaskID, MY_REPORT_BATT_EVT,myBatteryCheckPeriod );
}
if ( event &MY_FIND_COLLECTOR_EVT )
{
// Find andbind to a collector device
zb_BindDevice( TRUE, SENSOR_REPORT_CMD_ID, (uint8 *)NULL );
}
}
好,然后我们看下协调器是怎么接收数据的,首先切换工作空间为协调器模式,查看sapi.c文件,查看SAPI_ProcessEvent函数,找到:
case AF_INCOMING_MSG_CMD:
pMSGpkt = (afIncomingMSGPacket_t *) pMsg;
SAPI_ReceiveDataIndication(pMSGpkt->srcAddr.addr.shortAddr,pMSGpkt->clusterId,
pMSGpkt->cmd.DataLength,pMSGpkt->cmd.Data);//协调器在此函数中进行数据的接收工作。
break;
查看此函数:
void SAPI_ReceiveDataIndication( uint16 source, uint16 command,uint16 len, uint8 *pData )
{
#if defined ( MT_SAPI_CB_FUNC )
if ( SAPICB_CHECK( SPI_CB_SAPI_RCV_DATA_IND ))
{
zb_MTCallbackReceiveDataIndication( source, command, len,pData );
}
else
#endif //MT_SAPI_CB_FUNC
{
#if ( SAPI_CB_FUNC )//编译通过
zb_ReceiveDataIndication( source, command, len,pData );
#endif
}
}
查看源代码:
oid zb_FindDeviceConfirm( uint8 searchType, uint8 *searchKey,uint8 *result )
{
}
CONST uint8 strDevice[] = "Device:0x";
CONST uint8 strTemp[] = "Temp: ";
CONST uint8 strBattery[] = "Battery: ";
void zb_ReceiveDataIndication( uint16 source, uint16 command,uint16 len, uint8 *pData )
{
uint8 buf[32];
uint8 *pBuf;
uint8 tmpLen;
uint8 sensorReading;
if (command ==SENSOR_REPORT_CMD_ID)//条件成立
{
// Receivedreport from a sensor
sensorReading = pData[1];
// Iftool available, write to serial port
tmpLen =(uint8)osal_strlen( (char*)strDevice );
pBuf =osal_memcpy( buf, strDevice, tmpLen );
_ltoa(source, pBuf, 16 );
pBuf +=4;
*pBuf++ = '';
if (pData[0] == BATTERY_REPORT )//如果是电压传送,执行下面函数
{
tmpLen = (uint8)osal_strlen( (char*)strBattery );
pBuf = osal_memcpy( pBuf, strBattery, tmpLen );
*pBuf++ = (sensorReading / 10 ) +'0'; //convent msb to ascii
*pBuf++ ='.'; // decimal point ( battery reading is in units of 0.1 V
*pBuf++ = (sensorReading % 10 ) +'0'; //convert lsb to ascii
*pBuf++ = ' ';
*pBuf++ = 'V';
}
else//如果是温度传送,执行下面函数
{
tmpLen = (uint8)osal_strlen( (char*)strTemp );
pBuf = osal_memcpy( pBuf, strTemp, tmpLen );
*pBuf++ = (sensorReading / 10 ) +'0'; //convent msb to ascii
*pBuf++ = (sensorReading % 10 ) +'0'; //convert lsb to ascii
*pBuf++ = ' ';
*pBuf++ = 'C';
}
*pBuf++ ='\r';
*pBuf++ ='\n';
*pBuf ='\0';
#if defined( MT_TASK)//若定义了MT_TASK ,则执行下面函数即串口函数,发送到PC机上显示。
debug_str((uint8 *)buf );
#endif
// canalso write directly to uart
}
}
到此为止,终端节点向协调器发送数据,协调器接收数据并发送到串口
完成。。。