Discover multiple USB-IrDA devices, open and connect a socket for each

♀尐吖头ヾ 提交于 2020-01-04 02:32:07

问题


For any good sockets programmers out there:
Is it possible to enumerate multiple active IrDA devices connected to the PC through USB ports using sockets?
If so, how? This is really my main question. The remainder of the post rounds out the details and describes what I have tried.

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 devices in range, connect using sockets, and communicate 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.

I have successfully used sockets calls to enumerate, create a socket, connect and communicate to a single IrDA device. This works well.
However, I am not sure how to setup the code to successfully enumerate multiple IrDA devices.

So far, I am only able to connect to one device at a time. Even though It is clear that Windows is "Discovering" three IrDA dongles, as seen in the following images - overall scenario (1st image), device manager (2nd image), device properties (3rd image):

Illustration 1: Overall scenario:

Illustration 2: From Device Manager:

Illustration 3: Properties of each 'found' IrDA device
(second two arrows are included to show Port-Hub address of all three devices)

The simple scenario I am using:
(some of the variable names are different from scenario description above, but are consistent within the code)

1st - I place two active IrDA devices sitting in front of two dongles (separated by several feet, so there is no signal ambiguity between the two devices) Using only 2 for now to keep it simple.

2nd - I create 2 IrDA sockets, get two handles using: socket(AF_IRDA, SOCK_STREAM, 0);

3rd - I call:

if ((errorCode = getsockopt(gSocketHandle[0],
                 SOL_IRLMP,
                 IRLMP_ENUMDEVICES,
                 (char*)pDeviceList,
                 &deviceListLength)) == SOCKET_ERROR)  

4th - I then populate the destinIrdaDeviceAddr with the new information in pDeviceList and

    memcpy(&destinIrdaDeviceAddr.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);

5th - call:

connect(gSocketHandle[0],(const struct sockaddr*)&destinIrdaDeviceAddr,(int) sizeof(SOCKADDR_IRDA))

After this call completes, I repeat (step 3 ) using the next socket handle (gSocketHandle1). But instead of getting another enumerated device, I just get the same device. This second call results in the same information in pDeviceList as was in the first device. Stated another way, I am only enumerating a single device.

Here is the code attempting to enumerate two IrDA devices:

    // adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/ms691754(v=vs.85).aspx

    #include <windows.h>
    #include <winsock2.h>
    #include <ansi_c.h>
    #include <af_irda.h>

    #pragma comment(lib, "ws2_32.lib")

    #define DEVICE_LIST_LEN 5
    #define MAX_RETRIES 10

    SOCKET conn1, conn2;

    char* iGetLastErrorText(DWORD nErrorCode);

    void main()
    {
        WSADATA         wsaData;
        // discovery buffer
        BYTE          DevListBuff[sizeof(DEVICELIST) - sizeof(IRDA_DEVICE_INFO) + 
                      (sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
        int           DevListLen = sizeof(DevListBuff);
        PDEVICELIST   pDevList   = (PDEVICELIST) &DevListBuff;
        int           DevNum, i;

        if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
        {
        printf("IR-Client: Unable to load the Winsock library!\n");
            getchar();
        }
        else printf("IR-Client: Winsock library 2.2 loaded!\n");

        SOCKADDR_IRDA DstAddrIR = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" };

        //Create socket handles
        if ((conn1 = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
        {
        // WSAGetLastError
        }
        if ((conn2 = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
        {
        // WSAGetLastError
        }

        /////////////////////////
        //enumerate devices - socket conn1
        /////////////////////////
        // search for the peer device
        pDevList->numDevice = 0;
        if (getsockopt(conn1, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen)
        == SOCKET_ERROR)
        {
        // WSAGetLastError
        }

        if (pDevList->numDevice == 0)
        {
        printf("no devices found\n");
        }

        // assume first device, we should have a common dialog here
        memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);
        printf("%x\n", &DstAddrIR.irdaDeviceID[0]);


        // nothing special for IrCOMM from now on...
        if (connect(conn1, (const struct sockaddr *) &DstAddrIR, sizeof(SOCKADDR_IRDA)) 
        == SOCKET_ERROR)
        {
        // WSAGetLastError
        }

        /////////////////////////
        //enumerate devices - socket conn2
        /////////////////////////
        // search for the peer device
        pDevList->numDevice = 0;

        if (getsockopt(conn2, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen) == SOCKET_ERROR)
        {
        // WSAGetLastError
        }

        if (pDevList->numDevice == 0)
        {
        printf("no devices found\n");
        }

        // assume first device, we should have a common dialog here
        memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);
        printf("%x\n", &DstAddrIR.irdaDeviceID[0]);

        // nothing special for IrCOMM from now on...
        if (connect(conn2, (const struct sockaddr *) &DstAddrIR, sizeof(SOCKADDR_IRDA)) 
        == SOCKET_ERROR)
        {
        // WSAGetLastError
        }
        getchar(); //to view irdaDeviceID
    }

    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);
    }

The following image shows values for ->irdaDeviceID[0]. Both values are the same indicating only one device was enumerated.

来源:https://stackoverflow.com/questions/17710790/discover-multiple-usb-irda-devices-open-and-connect-a-socket-for-each

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!