Is there a method, other than enumeration, to get sockets for many IrDA devices when devices all have same deviceID?

StackOverflow https://stackoverflow.com/questions/17928852

Question

Since posting my original question about enumerating multiple devices, I have discovered the reason multiple enumerations were not occuring; The devices all have the same deviceID. With this discovery, I would like to pose a new question, hopfully leading to a work around...

[EDIT]
The new question:
Is there a method, other than unique enumeration, available to get dedicated sockets for each of many devices, when all devices use the same deviceID?

Scenario and rules:
I am developing an application on Windows 7, using Microsoft SDK and an ANSI C compiler. The application design requires it to detect any IrDA device in range, connect using sockets, and communicate. Communication will be to multiple devices through multiple IrDA dongles (one dongle per device), each dongle is connected to the PC via USB. Note: Using virtual COM ports is to be avoided.
The objective: connect each device to its own socket providing an exclusive communication channel between it and the application software.

illustrations and source code (for enumeration of IrDA devices) are below.

[EDIT]
Illustration 1: Overall scenario:
enter image description here

Illustration 2: From Device Manager:
enter image description here

Illustration 3: Properties of each 'found' IrDA device:
enter image description here

Here is the code to enumerate two or more unique IrDA devices: (tested and working well)

    //Adapted from:  http://msdn.microsoft.com/en-us/library/windows/desktop/ms738544(v=vs.85).aspx
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <af_irda.h>
    #include <stdio.h>
    #include <windows.h>

    // link with Ws2_32.lib
    char* iGetLastErrorText(DWORD nErrorCode);


    int __cdecl main(void)
    {

        //-----------------------------------------
        // Declare and initialize variables
        WSADATA wsaData;

        int iResult;
        int i, tries = 0;
        DWORD dwError;

        SOCKET Sock = INVALID_SOCKET;

    #define DEVICE_LIST_LEN    10


        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;

        pDevList = (PDEVICELIST) & DevListBuff;

        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
        }

        Sock = socket(AF_IRDA, SOCK_STREAM, 0);
        if (Sock == INVALID_SOCKET) {
        dwError = WSAGetLastError();
        printf
            ("socket failed trying to create an AF_IRDA socket with error %d\n",
             dwError);

        if (dwError == WSAEAFNOSUPPORT) {
            printf("Check that the local computer has an infrared device\n");
            printf
            ("and a device driver is installed for the infrared device\n");
        }
        WSACleanup();
        return 1;
        }

        pDevList->numDevice = 0;

        while((pDevList->numDevice < 2)&&( tries++ < 3 ))
        {
            // Sock is not in connected state
            iResult = getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
                     (char *) pDevList, &DevListLen);

            if (iResult == SOCKET_ERROR) {
            printf("getsockopt failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
                iResult = closesocket(Sock);
                if(iResult == SOCKET_ERROR)
                {
                printf("closesocket failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
                WSACleanup();
                    getchar();
                return 1;
                }
            WSACleanup();
                getchar();
            return 1;
            }

            if (pDevList->numDevice == 0) {
            // no devices discovered or cached
            // not a bad idea to run a couple of times
            printf("No IRDA devices were discovered or cached\n");
            } else {
            // one per discovered device
            printf("pDevList->numDevice = %d\n", pDevList->numDevice);
                for (i = 0; i < (int) pDevList->numDevice; i++) {

                    printf( "irdaCharSet: %d\nHints1: %d\nHints2: %d\nDeviceID: %x\nDeviceName: %s\n\n", 
                             pDevList->Device[i].irdaCharSet, 
                             pDevList->Device[i].irdaDeviceHints1, 
                             pDevList->Device[i].irdaDeviceHints2, 
                             pDevList->Device[i].irdaDeviceID, 
                             pDevList->Device[i].irdaDeviceName);





                    // 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(&DestSockAddr.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0],4);

        iResult = connect(Sock, (const struct sockaddr *) &DestSockAddr, sizeof (SOCKADDR_IRDA));
        if (iResult == SOCKET_ERROR) 
        {
            if (iResult == SOCKET_ERROR) {
            printf("connect failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
                iResult = closesocket(Sock);
                if(iResult == SOCKET_ERROR)
                {
                printf("closesocket failed with error %d - %s\n", WSAGetLastError(), iGetLastErrorText(WSAGetLastError()));
                WSACleanup();
                    getchar();
                return 1;
                }
            WSACleanup();
                getchar();
            return 1;
            }
        } 
        else 
        {
            printf("connect to first IRDA device was successful\n");
        }

        getchar();

        WSACleanup();
        return 0;
    }       

    char* iGetLastErrorText(DWORD nErrorCode)
    {
        char* msg;
        // Ask Windows to prepare a standard message for a GetLastError() code:
        FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, nErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
        // Return the message
        if (!msg)
        return("Unknown error");
        else
        return(msg);
    }
Was it helpful?

Solution

Closing the loop on this old question: The short answer is no, There is not another method.

IrDA sockets are created and in my case, in Windows 7, enumerated based on a Windows interrogation of any and all IrDA signals active and in range. The enumeration process stores data for each unique Device ID (specifically, IrDA Dev id) it finds. If it sees 3 unique Device IDs, then data for each can be stored, and made available for a connection to be completed. Subsequently, for each connection made, separate conversations can be held with each of those devices. However, if the same three devices are active, and in range, but have identical Device IDs, Windows will only store data corresponding to that one ID, and only one connection can be made.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top