IrDA and getsockopt Using IRLMP_ENUMDEVICES

The Windows Sockets getsockopt function is used to run a discovery. Before a connection can be initiated, a device address must be obtained by performing a discovery operation. An extension to the Winsock getsockopt call returns a list of all currently visible IrDA devices. A device address returned from this list is copied into a SOCKADDR_IRDA structure to be used by the connect function call.

To initiate a discovery

  • Performing a getsockopt function call with the IRLMP_ENUMDEVICES option causes a single discovery to be run on each idle adapter. The list of discovered devices and cached devices (on active adapters) will be returned immediately. The following code demonstrates this:
    #include <windows.h>
    #include <af_irda.h>
    
    #pragma comment(lib, "ws2_32.lib")
    
    #define DEVICE_LIST_LEN    10
    
    void main()
    {
        SOCKADDR_IRDA     DestSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };
    
        unsigned char    DevListBuff[sizeof(DEVICELIST) -
                 sizeof(IRDA_DEVICE_INFO) +
                 (sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
        int        DevListLen    = sizeof(DevListBuff);
        PDEVICELIST    pDevList    = (PDEVICELIST) &amp;DevListBuff;
      int i;
    
        pDevList->numDevice = 0;
    
        // Sock is not in connected state
        if (getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
                       (char *) pDevList, &amp;DevListLen) == SOCKET_ERROR)
        {
        // WSAGetLastError 
        }
    
        if (pDevList->numDevice == 0)
        {
            // no devices discovered or cached
            // not a bad idea to run a couple of times
        }
        else
        {
            // one per discovered device
            for (i = 0; i < (int) pDevList->numDevice; i++)
            {
            // typedef struct _IRDA_DEVICE_INFO
            // {
                    //    u_char    irdaDeviceID[4];
                    //    char    irdaDeviceName[22];
                    //    u_char    irdaDeviceHints1;
                    //     u_char    irdaDeviceHints2;
                    //    u_char    irdaCharSet;
            // } _IRDA_DEVICE_INFO;
    
                // pDevList->Device[i]. see _IRDA_DEVICE_INFO for fields
                // display the device names and let the user select one
            }
        }
    
        // assume the user selected the first device [0]
        memcpy(&amp;DestSockAddr.irdaDeviceID[0], &amp;pDevList->Device[0].irdaDeviceID[0], 4);
    
        if (connect(Sock, (const struct sockaddr *) &amp;DestSockAddr,
                    sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
        {
            // WSAGetLastError
        }
    }
    

To run a lazy discovery

  • It is also possible to run a lazy discovery — the application will not be notified until the discovered device list changes from the last discovery run by the stack.