WAP API Sample for User Data at the WDP Layer (Compact 2013)
4/26/2013
The following code example illustrates how to send and read a primitive with user data by using WDP_LAYER. The code uses one device as both the initiator and the responder. These two roles are distinguished by using different ports.
Note
If the structure elements are not correctly initialized, the Wireless Application Protocol (WAP) API returns error 0x80070057, "The parameter is incorrect."
#include <windows.h>
#include <wap.h>
// Use UDP bearer if bUDP = true, use SMS bearer if bUDP = false;
bool WdpSendAndReadEcho( bool bUDP )
{
bool bSendReadOK = false;
HRESULT hResult;
// Open WAP for Sending WDP UnitData
const WAP_LAYER wlLayer = WAP_LAYER_WDP;
const DWORD dwSendPort = 3000L;
WAP_HANDLE hWapSend = 0L;
HANDLE hWapSendMsgEvent= NULL;
// Open WAP for reading WDP UnitData
const DWORD dwRecvPort = 3001L;
WAP_HANDLE hWapRecv= 0L;
HANDLE hWapRecvMsgEvent = NULL;
// Create WDP UnitData structure with user data
WAP_ADDRESS waSendRecv;
const TCHAR *const tszIpLoopbackAddr = _T("127.0.0.1");// For UDP bearer
const TCHAR *const tszTelNum = _T("8009352663"); // Sample Phone number, used for SMS bearer
WDP_UNITDATA Wdpunitdata;
DWORD dwWdpRecvDataSize = 0L;
WDP_UNITDATA *pcbWdpRecvData = NULL;
// Use temporary buffer because pbUserData is const BYTE *
BYTE *pbBuffer = NULL;
hResult = WapOpen( wlLayer, dwSendPort, &hWapSend, &hWapSendMsgEvent );
if ( FAILED(hResult) || !hWapSend || !hWapSendMsgEvent )
{
OutputDebugString( _T("WapOpen() for sending WDP UnitData failed") );
hWapSend = 0L;
hWapSendMsgEvent= NULL;
return false;
}
hResult = WapOpen( wlLayer, dwRecvPort, &hWapRecv, &hWapRecvMsgEvent );
if ( FAILED(hResult) || !hWapRecv || !hWapRecvMsgEvent )
{
OutputDebugString( _T("WapOpen() for reading WDP UnitData failed") );
hWapRecv= 0L;
goto exit_label;
}
if(bUDP)
{
_tcsncpy( waSendRecv.ptsAddress, tszIpLoopbackAddr, MAX_WAP_ADDRESS_LENGTH );
}
else
{
_tcsncpy( waSendRecv.ptsAddress, tszTelNum, MAX_WAP_ADDRESS_LENGTH);
}
waSendRecv.watAddressType = bUDP ? WAP_ADDRESS_TYPE_UDP : WAP_ADDRESS_TYPE_GSM_SMS;
// Initialize the WDP UnitData
memset( &Wdpunitdata, 0, sizeof(Wdpunitdata) );
Wdpunitdata.wpiPrimitiveID = WAP_PRIMITIVE_ID_T_DUNITDATA;
Wdpunitdata.wptPrimitiveType = WAP_PRIMITIVE_TYPE_REQUEST;
Wdpunitdata.dwValidFields = (WDP_FIELD_SOURCEADDRESS |
WDP_FIELD_SOURCEPORT |
WDP_FIELD_DESTINATIONADDRESS |
WDP_FIELD_DESTINATIONPORT |
WDP_FIELD_USERDATA );
Wdpunitdata.waSourceAddress = waSendRecv;
Wdpunitdata.dwSourcePort = dwSendPort;
Wdpunitdata.waDestinationAddress = Wdpunitdata.waSourceAddress;
Wdpunitdata.dwDestinationPort = dwRecvPort;
// Set Random user data with size = 0x100
Wdpunitdata.dwUserDataSize = 0x100;
if(pbBuffer = new BYTE[Wdpunitdata.dwUserDataSize])
{
// Fill the user data section with random data
for ( DWORD dw = 0; dw < Wdpunitdata.dwUserDataSize; dw++ )
{
pbBuffer[ dw ] = rand() % 0xFF;
}
}
else
{
goto exit_label;
}
Wdpunitdata.pbUserData = pbBuffer;
// Send WDP Data
hResult = WapSend( hWapSend, (WAP_PRIMITIVE_BASE *)&Wdpunitdata );
if ( FAILED(hResult) )
{
OutputDebugString( _T("WapSend() with WDP Unitdata failed") );
goto exit_label;
}
// Wait for WAP message received Event
if ( WAIT_OBJECT_0 != WaitForSingleObject( hWapRecvMsgEvent , 10000L ))
{
OutputDebugString( _T("Failed to wait for or timed out waiting for expected WDP Data") );
goto exit_label;
}
hResult = WapGetNextPrimitiveSize( hWapRecv, &dwWdpRecvDataSize);
if ( FAILED(hResult) || (0 == dwWdpRecvDataSize) )
{
OutputDebugString( _T("WapGetNextPrimitiveSize() failed") );
goto exit_label;
}
// Allocate memory for storing received WDP Data
pcbWdpRecvData =( WDP_UNITDATA* ) new BYTE[ dwWdpRecvDataSize ];
if ( !pcbWdpRecvData)
{
OutputDebugString( _T("Failed to allocate memory for storing WDP Unit Data") );
goto exit_label;
}
// Read WDP Data
hResult = WapRead( hWapRecv, (WAP_PRIMITIVE_BASE *)pcbWdpRecvData, dwWdpRecvDataSize );
if ( FAILED(hResult) )
{
OutputDebugString( _T("WapRead() failed") );
goto exit_label;
}
// Validate the received primitive and
// Compare the received user data to the sent user data
if (!pcbWdpRecvData)
goto exit_label;
bSendReadOK = true;
bSendReadOK &= (WAP_PRIMITIVE_ID_T_DUNITDATA == pcbWdpRecvData->wpiPrimitiveID);
bSendReadOK &= (WAP_PRIMITIVE_TYPE_INDICATION == pcbWdpRecvData->wptPrimitiveType);
bSendReadOK &= (pcbWdpRecvData->dwValidFields & WDP_FIELD_SOURCEADDRESS ) && ( pcbWdpRecvData->dwValidFields & WDP_FIELD_SOURCEPORT );
bSendReadOK &= (pcbWdpRecvData->dwUserDataSize == Wdpunitdata.dwUserDataSize);
if(bSendReadOK && pcbWdpRecvData->pbUserData)
{
bSendReadOK &= !memcmp(pcbWdpRecvData->pbUserData, Wdpunitdata.pbUserData, pcbWdpRecvData->dwUserDataSize);
}
exit_label:
// Close WAP for Sending WDP UnitData
if ( hWapSend)
{
hResult = WapClose( hWapSend );
if ( FAILED(hResult) )
{
OutputDebugString( _T("WapClose() for sending WDP UnitData failed") );
bSendReadOK = false;
}
else
{
hWapSend = 0L;
}
}
// Close WAP for Receiving WDP UnitData
if ( hWapRecv )
{
hResult = WapClose( hWapRecv );
if ( FAILED(hResult) )
{
OutputDebugString( _T("WapClose() for reading WDP UnitData failed") );
bSendReadOK = false;
}
else
{
hWapRecv = 0L;
}
}
// Clear the buffers
if (pbBuffer)
{
delete[] (BYTE*) pbBuffer;
pbBuffer = NULL;
}
if ( pcbWdpRecvData )
{
delete [] (BYTE*) pcbWdpRecvData;
pcbWdpRecvData = NULL;
}
return bSendReadOK;
}