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:
Illustration 2: From Device Manager:
Illustration 3: Properties of each 'found' IrDA device:
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);
}