0

複数のデバイスの列挙に関する最初の質問を投稿して以来、複数の列挙が行われない理由を発見しました。デバイスはすべて同じ deviceID を持っています。この発見により、うまくいけば回避策につながる新しい質問を提起したいと思います...

[編集]
新しい質問:
すべてのデバイスが同じ deviceID を使用している場合、一意の列挙以外に、多くのデバイスのそれぞれに専用のソケットを取得する方法はありますか?

シナリオとルール:
Microsoft SDK と ANSI C コンパイラを使用して、Windows 7 でアプリケーションを開発しています。アプリケーションの設計では、範囲内の IrDA デバイスを検出し、ソケットを使用して接続し、通信する必要があります。通信は、複数の IrDA ドングル (デバイスごとに 1 つのドングル) を介して複数のデバイスに行われ、各ドングルは USB 経由で PC に接続されます。注: 仮想 COM ポートの使用は避けてください。
目的:各デバイスを独自のソケットに接続して、デバイスとアプリケーション ソフトウェア間の専用通信チャネルを提供します。

図とソース コード (IrDA デバイスの列挙用) は以下のとおりです。

[編集]
図 1: 全体的なシナリオ:
ここに画像の説明を入力

図 2: デバイス マネージャーから:
ここに画像の説明を入力

図 3: 「見つかった」各 IrDA デバイスのプロパティ:
ここに画像の説明を入力

2 つ以上の一意の IrDA デバイスを列挙するコードを次に示します (テスト済みで、正常に動作しています)。

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

1 に答える 1

0

この古い質問のループを閉じる: 簡単な答えはノーです。別の方法はありません。

IrDA ソケットが作成され、私の場合、Windows 7 では、アクティブで範囲内にあるすべての IrDA 信号の Windows問い合わせに基づいて列挙されます。列挙プロセスは、検出した一意のデバイス ID (具体的には IrDA Dev id)ごとにデータを保存します。3 つの一意のデバイス ID が検出された場合、それぞれのデータを保存して、接続を完了するために使用できます。その後、確立された接続ごとに、これらの各デバイスと個別の会話を行うことができます。ただし、同じ 3 つのデバイスがアクティブで範囲内にあるが、デバイス ID が同一である場合、Windows はその 1 つの ID に対応するデータのみを保存し、1 つの接続のみを確立できます。

于 2014-02-05T21:06:56.977 に答える