複数のデバイスの列挙に関する最初の質問を投稿して以来、複数の列挙が行われない理由を発見しました。デバイスはすべて同じ 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);
}