WAP API Sample for Usage at the WTP Layer

A version of this page is also available for

Windows Embedded CE 6.0 R3

4/8/2010

Using WAP APIs at the WTP layer requires filling in certain structures, such as WTP_INVOKE.

Note

If the structure elements are not correctly initialized, the WAP API returns the error 0x80070057, "The parameter is incorrect."

The following code example shows how to send a WTP invoke request and read a WTP invoke indication.

#include <windows.h>
#include <wap.h>

//
//  The following routine illustrates
//  how to send a WTP invoke request and
//  read a WTP invoke indication.
//
bool WtpInvokeRequestIndication( void ) {

    bool bReqIndOk = false;

    HRESULT hResult;
    DWORD dwResult;
    TCHAR tszDbgMsg[ 256 ];

    //  open WAP for sending WTP invoke request
    const WAP_LAYER wlWtp = WAP_LAYER_WTP;
    const DWORD dwSendPort = 3000L;
    WAP_HANDLE hWapInvokeReq = 0L;
    HANDLE hWapInvokeReqMsgEvent = NULL;


    //  open WAP for reading WTP invoke indication
    const DWORD dwRecvPort = 3001L;
    WAP_HANDLE hWapInvokeInd = 0L;
    HANDLE hWapInvokeIndMsgEvent = NULL;

    //  create WTP invoke request structure with no user data
    WAP_ADDRESS waInvokeReqInd;
    const TCHAR *const tszIpLoopbackAddr = _T("127.0.0.1");

    WTP_INVOKE WtpPrimInvokeReq;
    DWORD dwWtpPrimInvokeIndSize = 0L;
    BYTE *pcbWtpPrimInvokeInd = NULL;
    
    hResult = WapOpen( wlWtp, dwSendPort, &hWapInvokeReq, &hWapInvokeReqMsgEvent );

    if ( FAILED(hResult) || !hWapInvokeReq || !hWapInvokeReqMsgEvent ) {
        OutputDebugString( _T("WapOpen() for sending WTP invoke request failed") );
        return false;
    }

    hResult = WapOpen( wlWtp, dwRecvPort, &hWapInvokeInd, &hWapInvokeIndMsgEvent );
    if ( FAILED(hResult) || !hWapInvokeInd || !hWapInvokeIndMsgEvent ) {
        OutputDebugString( _T("WapOpen() for reading WTP invoke indication failed") );
        hWapInvokeInd = 0L;
        goto exit_label;
    }

    _tcsncpy( waInvokeReqInd.ptsAddress, tszIpLoopbackAddr, MAX_WAP_ADDRESS_LENGTH );
    waInvokeReqInd.watAddressType = WAP_ADDRESS_TYPE_UDP;

    memset( &WtpPrimInvokeReq, 0, sizeof(WtpPrimInvokeReq) );
    WtpPrimInvokeReq.wpiPrimitiveID = WAP_PRIMITIVE_ID_TR_INVOKE;
    WtpPrimInvokeReq.wptPrimitiveType = WAP_PRIMITIVE_TYPE_REQUEST;
    WtpPrimInvokeReq.dwValidFields = ( WTP_FIELD_SOURCEADDRESS |
                                       WTP_FIELD_SOURCEPORT |
                                       WTP_FIELD_DESTINATIONADDRESS |
                                       WTP_FIELD_DESTINATIONPORT |
                                       WTP_FIELD_WANTSECURETRANSACTION |
                                       WTP_FIELD_USERACKNOWLEDGEMENT |
                                       WTP_FIELD_CLASSTYPE |
                                       WTP_FIELD_USERDATA );
    WtpPrimInvokeReq.waSourceAddress = waInvokeReqInd;
    WtpPrimInvokeReq.dwSourcePort = dwSendPort;
    WtpPrimInvokeReq.waDestinationAddress = WtpPrimInvokeReq.waSourceAddress;
    WtpPrimInvokeReq.dwDestinationPort = dwRecvPort;
    WtpPrimInvokeReq.wtctClassType = WTP_TRANSACTION_CLASS_TYPE_0;

    //  send WTP invoke request
    hResult = WapSend( hWapInvokeReq, (WAP_PRIMITIVE_BASE *)&WtpPrimInvokeReq );
    if ( FAILED(hResult) ) {
        OutputDebugString( _T("WapSend() with WTP invoke request failed") );
        goto exit_label;
    }

    _sntprintf( tszDbgMsg, 255, _T("WTP invoke request handle: %#x"),
                WtpPrimInvokeReq.wthTransactionHandle );
    tszDbgMsg[ 255 ] = _T('\0');
    OutputDebugString( tszDbgMsg );

    //  wait for WTP invoke indication
    dwResult = WaitForSingleObject( hWapInvokeIndMsgEvent, 10000L );
    if ( dwResult != WAIT_OBJECT_0 ) {
        OutputDebugString( _T("Failed to wait for or timed out waiting for expected WTP invoke indication") );
        goto exit_label;
    }

    //  allocate memory for storing WTP invoke indication

    hResult = WapGetNextPrimitiveSize( hWapInvokeInd, &dwWtpPrimInvokeIndSize );
    if ( FAILED(hResult) || (dwWtpPrimInvokeIndSize < sizeof(WTP_INVOKE)) ) {
        OutputDebugString( _T("WapGetNextPrimitiveSize() failed") );
        goto exit_label;
    }

    pcbWtpPrimInvokeInd = new BYTE[ dwWtpPrimInvokeIndSize ];
    if ( !pcbWtpPrimInvokeInd ) {
        OutputDebugString( _T("Failed to allocate memory for storing WTP invoke indication") );
        goto exit_label;
    }

    //  read WTP invoke indication
    hResult = WapRead( hWapInvokeInd, (WAP_PRIMITIVE_BASE *)pcbWtpPrimInvokeInd, dwWtpPrimInvokeIndSize );
    if ( FAILED(hResult) ) {
        OutputDebugString( _T("WapRead() failed") );
        goto exit_label;
    }

    _sntprintf( tszDbgMsg, 255, _T("WTP invoke indication handle: %#x"),
                ((WTP_INVOKE *)pcbWtpPrimInvokeInd)->wthTransactionHandle );
    tszDbgMsg[ 255 ] = _T('\0');

    OutputDebugString( tszDbgMsg );
    bReqIndOk = true;

    exit_label:
    //  close WAP
    if ( hWapInvokeReq ){
        hResult = WapClose( hWapInvokeReq );
        if ( FAILED(hResult) ) {
            OutputDebugString( _T("WapClose() for sending WTP invoke request failed") );
            bReqIndOk = false;
        } 
        else {
            hWapInvokeReq = 0L;
        }
    }

    if ( hWapInvokeInd ) {
        hResult = WapClose( hWapInvokeInd );
        if ( FAILED(hResult) ) {
            OutputDebugString( _T("WapClose() for reading WTP invoke indication failed") );
            bReqIndOk = false;
        } 
        else {
            hWapInvokeInd = 0L;
        }
    }

    if ( pcbWtpPrimInvokeInd ) {
        delete [] pcbWtpPrimInvokeInd;
        pcbWtpPrimInvokeInd = NULL;
    }

    return bReqIndOk;
}

See Also

Concepts

Wireless Application Protocol (WAP) API