该程序根据目标地址列表中的地址,间隔一段时间循环发送唤醒请求报文,并打印出唤醒的参数信息。观察目标节点可以看到被唤醒的标志,比如LED指示灯亮起,并持续一段时间后再次熄灭。
#include <conio.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include "API-WiMinet.h"
// -----------------------------------------------------------------------------
// DESCRIPTION:
// -----------------------------------------------------------------------------
#define TIME_OUT_TIMER 20UL
// -----------------------------------------------------------------------------
// DESCRIPTION: Convert from 100ns to mili-second
// -----------------------------------------------------------------------------
#define X64_MIS_TIMER_CONST ( 10000UL )
// -----------------------------------------------------------------------------
// DESCRIPTION: Convert from 100ns to mili-second, and then to second
// -----------------------------------------------------------------------------
#define X64_SEC_TIMER_CONST ( X64_MIS_TIMER_CONST * 1000UL )
// -----------------------------------------------------------------------------
// DESCRIPTION:
// -----------------------------------------------------------------------------
char * pOutputFileName[] = {
"D:\\BMP\\1.bwrg.mLZO",
"D:\\BMP\\2.bwrg.mLZO",
"D:\\BMP\\3.bwrg.mLZO",
"D:\\BMP\\4.bwrg.mLZO",
"D:\\BMP\\5.bwrg.mLZO",
"D:\\BMP\\6.bwrg.mLZO",
"D:\\BMP\\7.bwrg.mLZO",
"D:\\BMP\\8.bwrg.mLZO",
"D:\\BMP\\9.bwrg.mLZO",
"D:\\BMP\\10.bwrg.mLZO",
"D:\\BMP\\11.bwrg.mLZO",
"D:\\BMP\\12.bwrg.mLZO",
"D:\\BMP\\13.bwrg.mLZO",
"D:\\BMP\\14.bwrg.mLZO" };
/*
// -----------------------------------------------------------------------------
// DESCRIPTION:
// -----------------------------------------------------------------------------
char * pOutputFileName[] = {
"D:\\BMP\\1.bmp.mLZO",
"D:\\BMP\\2.bmp.mLZO",
"D:\\BMP\\3.bmp.mLZO",
"D:\\BMP\\4.bmp.mLZO",
"D:\\BMP\\5.bmp.mLZO",
"D:\\BMP\\6.mp.mLZO",
"D:\\BMP\\7.bmp.mLZO",
"D:\\BMP\\8.bmp.mLZO",
"D:\\BMP\\9.bmp.mLZO",
"D:\\BMP\\10.bmp.mLZO",
"D:\\BMP\\11.bmp.mLZO",
"D:\\BMP\\12.bmp.mLZO",
"D:\\BMP\\13.bmp.mLZO",
"D:\\BMP\\14.bmp.mLZO" };
*/
/*
// -----------------------------------------------------------------------------
// DESCRIPTION:
// -----------------------------------------------------------------------------
char * pOutputFileName[] = {
"D:\\BMP\\1.bwrg",
"D:\\BMP\\2.bwrg",
"D:\\BMP\\3.bwrg",
"D:\\BMP\\4.bwrg",
"D:\\BMP\\5.bwrg",
"D:\\BMP\\6.bwrg",
"D:\\BMP\\7.bwrg",
"D:\\BMP\\8.bwrg",
"D:\\BMP\\9.bwrg",
"D:\\BMP\\10.bwrg",
"D:\\BMP\\11.bwrg",
"D:\\BMP\\12.bwrg",
"D:\\BMP\\13.bwrg",
"D:\\BMP\\14.bwrg" };
*/
/*
// -----------------------------------------------------------------------------
// DESCRIPTION:
// -----------------------------------------------------------------------------
// The file table
char * pOutputFileName[] = {
"D:\\BMP\\1.bmp",
"D:\\BMP\\2.bmp",
"D:\\BMP\\3.bmp",
"D:\\BMP\\4.bmp",
"D:\\BMP\\5.bmp",
"D:\\BMP\\6.bmp",
"D:\\BMP\\7.bmp",
"D:\\BMP\\8.bmp",
"D:\\BMP\\9.bmp",
"D:\\BMP\\10.bmp",
"D:\\BMP\\11.bmp",
"D:\\BMP\\12.bmp",
"D:\\BMP\\13.bmp",
"D:\\BMP\\14.bmp" };
*/
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
unsigned long Translate_Output_File_Number( unsigned long dwChar )
{
// Select the file ID
if ( ( dwChar >= '0' ) && ( dwChar <= '9' ) )
{
// Skip off the base value
dwChar -= '0';
}
else if ( ( dwChar >= 'a' ) && ( dwChar <= 'f' ) )
{
// Skip off the base value
dwChar -= 'a';
// Add the basic value
dwChar += 0X0A;
}
else if ( ( dwChar >= 'A' ) && ( dwChar <= 'F' ) )
{
// Skip off the base value
dwChar -= 'A';
// Add the basic value
dwChar += 0X0A;
}
else
{
dwChar = 0XFFFFFFFF;
}
// The new output file number
return dwChar;
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
char Validate_Output_File_Number( unsigned long dwFile )
{
// Validate the file index
if ( dwFile >= ( sizeof( pOutputFileName ) / sizeof( pOutputFileName[0X00] ) ) )
{
return 0X00;
}
// The file name
return 0X01;
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
void Wait_Tx_Active_Ready( void )
{
unsigned char iStatus;
// Query the TxStatus
while ( 0X01 )
{
// Query the Tx status
QueryTxMsgStatus( 0X00, ( char * )&iStatus );
// Check if end of the Tx procedure
if ( iStatus & TXD_TASK_STATUS_REPORTTABLE )
{
break;
}
// Waiting the task is free
printf( "%02X ", iStatus );
// Release the control of the processor
Sleep( 0X01 );
}
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
void Print_Tx_Task_Status( unsigned long dwIndex )
{
float fTimer;
unsigned char iStatus;
unsigned char iProgress;
unsigned long dwTimerA;
unsigned long dwTimerB;
unsigned long dwTimerX;
// The initial time counter
dwTimerA = GetTickCount();
// The default Tx progress
iProgress = 0XFF;
// Query the TxStatus
while ( 0X01 )
{
// Release the control of the processor
Sleep( 0X01 );
// Query the Tx status
QueryTxMsgStatus( 0X00, ( char * )&iStatus );
// Check if end of the Tx procedure
if ( iStatus & TXD_TASK_STATUS_REPORTTABLE )
{
break;
}
// Compare the progress value
if ( iStatus == iProgress )
{
continue;
}
// Current time counter
dwTimerB = GetTickCount();
// The offset timer
dwTimerX = dwTimerB - dwTimerA;
// Update the progress value
iProgress = iStatus;
// Current Tx progress
printf( "%9lu ms --> %d%%\r\n", dwTimerX, iStatus );
}
// The seconds timer
fTimer = 0.001f * GetTickCount();
// Query the Tx timer
GetTxMessageTime( 0X00, &dwTimerX );
// The task completed status
switch ( iStatus )
{
case TXD_TASK_STATUS_END_SUCCESS:
{
printf(
"\r\n[%.3f]+%lu Tx Completed Successfully,Time=%lu(ms)\r\n\r\n",
fTimer,
dwIndex,
dwTimerX );
}
break;
case TXD_TASK_STATUS_END_FAILURE:
{
printf(
"\r\n[%.3f]+%lu Tx Completed With Error,Time=%lu(ms)\r\n\r\n",
fTimer,
dwIndex,
dwTimerX );
}
break;
case TXD_TASK_STATUS_END_NOCRC32:
{
printf(
"\r\n[%.3f]+%lu Tx Completed Without CRC32,Time=%lu(ms)\r\n\r\n",
fTimer,
dwIndex,
dwTimerX );
}
break;
default:
{
printf(
"\r\n[%.3f]+%lu Tx Completed With Unknown Error,Time=%lu(ms)\r\n\r\n",
fTimer,
dwIndex,
dwTimerX );
}
break;
}
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
char Tx_Message_To_Client( unsigned short iObject, unsigned long dwFile )
{
char * pBuffer;
FILE * pFile;
unsigned long dwSize;
// The total file size
dwSize = sizeof( pOutputFileName ) / sizeof( pOutputFileName[0X00] );
// Regulate the index value
dwFile %= dwSize;
// Open the file
pFile = fopen( pOutputFileName[dwFile], "rb" );
// Validate the file pointer
if ( !pFile )
{
printf( "Failed To Open File!\r\n" );
return 0X00;
}
// Seek to the file end
fseek( pFile, 0X00, SEEK_END );
// The file size
dwSize = ftell( pFile );
// Seek to the file head
fseek( pFile, 0X00, SEEK_SET );
// allocate the buffer
pBuffer = ( char * )malloc( dwSize );
// Read this file contents
fread( pBuffer, 0X01, dwSize, pFile );
// Close this file
fclose( pFile );
// Set the message format
// Parameter-1: Shell Number
// Parameter-2: Media Type
// 0X00 = Common Data
// 0X01 = Firmware
//
// Parameter-3: Compress Mode
// 0X00 = None Compress
// 0X01 = Compress Mode
SetMessageFormat( 0X00, 0X00, 0X01 );
// The task status
printf( "[WiMinet TxSize=%lu]:Object=0X%04X\r\n", dwSize, iObject );
// Send message via TCP on all nodes
SendHiQoSMessage( 0X00, iObject, pBuffer, dwSize );
// Send message via UDP on the end node, TCP on other nodes
//SendMxQoSMessage( 0X00, iObject, pBuffer, dwSize );
// Send message via UDP on all nodes
//SendNoQoSMessage( 0X00, iObject, pBuffer, dwSize );
// delete this buffer
free( pBuffer );
// The operation status
return 0X01;
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
unsigned char Print_WiMinet_Notice( void )
{
char buffer[0XFF];
unsigned char iExit;
unsigned char iSize;
unsigned char iError;
unsigned char iEvent;
unsigned char iRetVal;
unsigned short iObject;
ULARGE_INTEGER qwTimerA;
ULARGE_INTEGER qwTimerB;
WiMinet_TxReport * pTxReport;
// The exit condition
iExit = 0X00;
// The error code
iError = 0X00;
// Update the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerA );
// Wait some timer
while ( iExit != 0X03 )
{
// Update the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerB );
// Get the offset value
qwTimerB.QuadPart -= qwTimerA.QuadPart;
// Check the time out value
if ( qwTimerB.QuadPart >= 0X02UL * X64_SEC_TIMER_CONST )
{
// Convert to mini-second timer
qwTimerB.QuadPart /= X64_MIS_TIMER_CONST;
// The error status
printf( "\r\n[WiMinet Notice=%I64u]:Time Out Error\r\n", qwTimerB.QuadPart );
return 0XFF;
}
// The max buffer size
iSize = sizeof( buffer );
// Get the wiminet notice
iRetVal = GetWiMinetNotice( 0X00, &iEvent, &iObject, buffer, &iSize );
// Check the status
if ( !iRetVal )
{
continue;
}
// Convert to mini-second timer
qwTimerB.QuadPart /= X64_MIS_TIMER_CONST;
// The notice header
printf( "\r\n[WiMinet Notice=%I64u]:\r\n", qwTimerB.QuadPart );
// The event of the object
switch ( iEvent )
{
case WIMINET_EVENT_COMMUTE_END:
{
iExit |= 0X02;
printf( " [1] Event=Commute Success\r\n" );
printf( " [2] Object=0X%04X\r\n", iObject );
// The TxReport status
pTxReport = ( WiMinet_TxReport * )buffer;
// The report status
printf( " [3] Size=%d Bytes\r\n", iSize );
printf( " [4] Error=0X%02X", pTxReport->m_iQError );
// The detailed error code: No Header
if ( pTxReport->m_iQError & WIMINET_IO_REPORT_NO_HEADER )
{
printf( "[No Header]" );
}
// The detailed error code: Invalid Size
if ( pTxReport->m_iQError & WIMINET_IO_REPORT_ER_AMOUNT )
{
printf( "[Invalid Size]" );
}
// The detailed error code: Invalid CRC32
if ( pTxReport->m_iQError & WIMINET_IO_REPORT_ER_CRCODE )
{
printf( "[Invalid CRC32]" );
}
// The end of this line
printf( "\r\n" );
// The Tx data size
printf( " [5] Count=%lu\r\n", pTxReport->m_dwCount );
// The error code
iError |= pTxReport->m_iQError;
}
break;
case WIMINET_EVENT_COMMUTE_ERR:
{
iExit |= 0X02;
printf( " [1] Event=Commute Failure\r\n" );
printf( " [2] Object=0X%04X\r\n", iObject );
// The error code
iError |= 0X10;
}
break;
case WIMINET_EVENT_CONNECT_ERR:
{
iExit |= 0X02;
printf( " [1] Event=Connect Failure\r\n" );
printf( " [2] Object=0X%04X\r\n", iObject );
// The error code
iError |= 0X20;
}
break;
case WIMINET_EVENT_WOR_COMMUTE:
{
iExit |= 0X01;
printf( " [1] Event=eWOR Commute\r\n" );
printf( " [2] Object=0X%04X\r\n", iObject );
// The TxReport status
pTxReport = ( WiMinet_TxReport * )buffer;
// The report status
printf( " [3] Size=%d Bytes\r\n", iSize );
// The Tx data size
printf( " [4] Count=%lu\r\n", pTxReport->m_dwCount );
}
break;
default:
{
// The message code
printf( " [1] Code=0X%02X\r\n", iEvent );
printf( " [2] Object=0X%04X\r\n", iObject );
}
break;
}
}
// The unknown error code
return iError;
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
unsigned char Print_WiMinet_BATVol( void )
{
unsigned char iExit;
unsigned char iAttr;
unsigned char iStatus;
unsigned long dwSize;
unsigned short iSource;
ULARGE_INTEGER qwTimerA;
ULARGE_INTEGER qwTimerB;
WiMinet_RxReport report;
// The exit condition
iExit = 0X00;
// Update the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerA );
// Wait some timer
while ( !iExit )
{
// Update the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerB );
// Get the offset value
qwTimerB.QuadPart -= qwTimerA.QuadPart;
// Check the time out value
if ( qwTimerB.QuadPart >= 0X02UL * X64_SEC_TIMER_CONST )
{
// Convert to mini-second timer
qwTimerB.QuadPart /= X64_MIS_TIMER_CONST;
// The error status
printf( "\r\n[WiMinet Report=%I64u]:Time Out Error\r\n", qwTimerB.QuadPart );
return 0XFF;
}
// Query the Rx status
QueryRxMsgStatus( 0X00, ( char * )&iStatus );
// No received packet arrived
if ( iStatus == RXD_TASK_STATUS_JOB_WAITING )
{
continue;
}
// Check if ready to report
if ( !( iStatus & RXD_TASK_STATUS_REPORTTABLE ) )
{
continue;
}
// Convert to mini-second timer
qwTimerB.QuadPart /= X64_MIS_TIMER_CONST;
// The notice header
printf( "\r\n[WiMinet Report=%I64u]:\r\n", qwTimerB.QuadPart );
// The source node address
GetRxMessageNode( 0X00, ( short * )&iSource );
// The packet size
GetRxMessageSize( 0X00, &dwSize );
// The packet attribute
GetRxMessageAttr( 0X00, ( char * )&iAttr );
// Clear this object
memset( &report, 0X00, sizeof( report ) );
// Read this message
ReadInputMessage( 0X00, ( char * )&report, sizeof( report ) );
// The report status
printf( " [1] Size=%lu\r\n", dwSize );
printf( " [2] Attr=0X%02X\r\n", iAttr );
printf( " [3] Source=0X%04X\r\n", iSource );
printf( " [4] Device=0X%02X(%d)\r\n", report.m_iDevice, report.m_iDevice );
printf( " [5] Version=0X%08lX", report.m_dwBuild );
// The build version for firmware update
printf(
" --> [20%u.%u.%u+R%u]\r\n",
( unsigned char )( report.m_dwBuild >> 0X18 ),
( unsigned char )( report.m_dwBuild >> 0X10 ),
( unsigned char )( report.m_dwBuild >> 0X08 ),
( unsigned char )( report.m_dwBuild >> 0X00 ) );
// The received byte size by the remote endpoint
dwSize = ( ( unsigned long )report.m_iMBSize << 0X10 ) + report.m_iLBSize;
// The client received byte size
printf( " [6] Counter=%lu Bytes\r\n", dwSize );
// The battery voltage
printf( " [7] Battery=%.3f(V)\r\n", report.m_iBATVol * 0.001f );
// The RxRSSI voltage
printf( " [8] RxRSSI=%d(dBm)\r\n", report.m_iRxRSSI );
// The RxRSSI voltage
printf( " [9] TxRSSI=%d(dBm)\r\n", report.m_iTxRSSI );
// The client receive error code
printf( " [A] Error=0X%02X", report.m_iQError );
// The detailed error code: Rx Time Out
if ( report.m_iQError & WIMIET_IO_REPORT_RX_TIMEOUT )
{
printf( " [Rx Time Out]" );
}
// The detailed error code: No Header
if ( report.m_iQError & WIMINET_IO_REPORT_NO_HEADER )
{
printf( "[No Header]" );
}
// The detailed error code: Invalid Size
if ( report.m_iQError & WIMINET_IO_REPORT_ER_AMOUNT )
{
printf( "[Invalid Size]" );
}
// The detailed error code: Invalid CRC32
if ( report.m_iQError & WIMINET_IO_REPORT_ER_CRCODE )
{
printf( "[Invalid CRC32]" );
}
// The end of this line
printf( "\r\n\r\n" );
// The error code
return report.m_iQError;
}
// The unknown error code
return 0X80;
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
char iRetVal;
char iAutoMode;
char iTRequest;
char iShiftBMP;
unsigned char iErrorA;
unsigned char iErrorB;
unsigned long dwChar;
unsigned long dwFile;
unsigned long dwThis;
unsigned long dwSize;
unsigned long dwIndex;
unsigned short iObject;
ULARGE_INTEGER qwTimerA;
ULARGE_INTEGER qwTimerB;
unsigned short pObject[] = { 0X34F1 }; //0X0930 0X5028
// COM port interface
//iRetVal = OpenWiMinetShell( "COM6",115200, 0X01 );
// Ethernet interface
//iRetVal = OpenWiMinetShell( "192.168.0.240",12580, 0X01 );
// Ethernet interface
iRetVal = OpenWiMinetShell( "192.168.1.240",12580, 0X01 );
// Validate the shell open interface
if ( !iRetVal )
{
printf( "Open shell failed!\r\n" );
return 0X00;
}
// The default Tx status report
SetTxStateReport( 0X00, 0X01 );
// The Tx performance
SetTxPerformance( 0X00, 0X05 );
// The notice for user input
printf( "Please select '0'-'9' for file, 'q' or 'Q' to exit!\r\n\r\n" );
// Auto mode or step mode
iAutoMode = 0X00;
// The initial request status
iTRequest = 0X00;
// The BMP status
iShiftBMP = 0X00;
// The main service
while ( 0X01 )
{
// Release the processor control
Sleep( 0X01 );
// Check the keyboard input
if ( _kbhit() )
{
// Get the input character
dwChar = _getch();
// Check if time to exit this process
if ( ( dwChar == 'q' ) || ( dwChar == 'Q' ) )
{
break;
}
else if ( ( dwChar == 't' ) || ( dwChar == 'T' ) )
{
iAutoMode = 0X01;
printf( "CMD:Auto Mode\r\n" );
continue;
}
else if ( ( dwChar == 'm' ) || ( dwChar == 'M' ) )
{
iAutoMode = 0X00;
printf( "CMD:Manual Mode\r\n" );
continue;
}
else if ( ( dwChar == 'y' ) || ( dwChar == 'Y' ) )
{
iShiftBMP = 0X01;
printf( "CMD:Dynamic BMP\r\n" );
continue;
}
else if ( ( dwChar == 's' ) || ( dwChar == 'S' ) )
{
iShiftBMP = 0X00;
printf( "CMD:Static BMP\r\n" );
continue;
}
// Translate the input character
dwFile = Translate_Output_File_Number( dwChar );
// The request conunter
dwIndex = 0X00;
// Start the new request
iTRequest = 0X01;
// Get the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerA );
// Cut off the initial timer
qwTimerA.QuadPart -= ( TIME_OUT_TIMER * X64_SEC_TIMER_CONST );
}
// Check if there is a new request
if ( !iTRequest )
{
continue;
}
// Get the output file name
if ( !Validate_Output_File_Number( dwFile ) )
{
// The error message
printf( "Invalid File Number\r\n" );
// Clear the request
iTRequest = 0X00;
continue;
}
// Get current timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerB );
// Check if in auto mode
if ( iAutoMode )
{
// Get the offset value
qwTimerB.QuadPart -= qwTimerA.QuadPart;
// Convert 100ns to miliseconds, then seconds
qwTimerB.QuadPart /= X64_SEC_TIMER_CONST;
// Validate the timeout timer
if ( qwTimerB.QuadPart < TIME_OUT_TIMER )
{
continue;
}
}
// Wait for the Tx Ready
Wait_Tx_Active_Ready();
// The counter of the object
dwSize = sizeof( pObject ) / sizeof( pObject[0X00] );
// The object index value
iObject = pObject[dwIndex % dwSize];
// Set the Wakeup Request: Parameter-4=iAck
// 0X00: Dont Send Report
// 0X01: Need Send Report
//
// ++++++ IMPORTANT NOTES ++++++
// (1) if iACK=0, then client will never send out the UDP report
// (2) if iACK=0, then Print_WiMinet_BATVol will encounter time out error
//
SetWakeupRequest( 0X00, iObject, 5000, 0X01, NULL, 0X00 );
// The file index
dwThis = dwFile;
// Check if in auto mode and dynamic BMP
if ( iShiftBMP && iAutoMode )
{
dwThis += dwIndex;
}
// Send File to Remote Client
iRetVal = Tx_Message_To_Client( iObject, dwThis );
// Validate the Operation Result
if ( !iRetVal )
{
// Clear the request
iTRequest = 0X00;
continue;
}
// The request counter
dwIndex++;
// Print the Tx Task status
Print_Tx_Task_Status( dwIndex );
// The wiminet notice
iErrorA = Print_WiMinet_Notice();
// The client voltage
iErrorB = Print_WiMinet_BATVol();
// Check if there are errors
if ( iErrorA || iErrorB )
{
// Clear the auto mode
iAutoMode = 0X00;
// Report the error status
printf( "Error:A=0X%02X,B=0X%02X\r\n", iErrorA, iErrorB );
}
// Check if in auto mode
if ( !iAutoMode )
{
// Clear the request
iTRequest = 0X00;
continue;
}
// Update the start timer
GetSystemTimeAsFileTime( ( LPFILETIME )&qwTimerA );
}
// Stop the shell
StopWiMinetShell( 0X00 );
// Exit this main program
return 0X01;
}