偶昏...你用MSDN多少?我的是January 2000,内容也不多,可光这一页我想就能给你不少提示吧?代码都给你了,你还想多详细?如果你熟悉WinSock,你已经可以拿这些来写一个试试了。(BTW:说话最好不要那么多"!",如果你想别人帮你,回答问题的不是奴才,我不在乎你的分!)IrDA and WinSock Reference WSAStartup() Call WSAStartup before making any other IrDA calls.WORD WSAVerReq = MAKEWORD(1,1); WSADATA WSAData;if (WSAStartup(WSAVerReq, &WSAData) != 0) { // wrong winsock dlls? }af_irda.h This header file must be included by WinSock applications to support IrDA. There are several incompatible versions of af_irda.h that have been distributed with Windows CE and Windows 95 Ir3.0 DDKs and SDKs. A common af_irda.h that supports all three platforms is available with the Windows 2000 IrDA DDK, which can be accessed at the Web site www.microsoft.com/ddk/. This file may continue to evolve as the APIs of the systems grow closer together.In order to compile for one of the target platforms, one of the following must be defined:_WIN32_WINNT _WIN32_WCE _WIN32_WINDOWS socket() The WinSock socket() call is used to create a connection endpoint of type SOCKET. This is nothing more than an application anchor for future references to a connection. The connection is not yet established. Both clients and servers begin all communication by opening a socket.SOCKET ServSock;if ((ServSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET) { // WSAGetLastError() }SOCKADDR_IRDA Structure The following sockaddr structure is used for AF_IRDA sockets:typedef struct _SOCKADDR_IRDA { u_short irdaAddressFamily; u_char irdaDeviceID[4]; char irdaServiceName[25]; } SOCKADDR_IRDA, *PSOCKADDR_IRDA, FAR *LPSOCKADDR_IRDA;irdaAddressFamily is always AF_IRDA.Server applications use the irdaServiceName field to specify their well-known service name in a bind() call. The irdaDeviceID field is ignored by the server application.Client applications fill in all fields. The irdaDeviceID is filled in with the device address of the device that the client wishes to connect() to. This address is returned from a previous discovery operation initiated by a getsockopt() call with the IRLMP_ENUMDEVICES option. The irdaServiceName field is initialized to the well-known value that the server specified in its bind() call.It is an error for an IrDA application to issue a connect() call after issuing a bind() call.bind() The bind() call is used by server applications to register that they with to receive incoming connections that are addressed to a specified service name on the specified socket. bind() associates a server socket with an application level address.SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" }; int SizeOfSockAddr;if (bind(ServSock, (const struct sockaddr *) &ServSockAddr, sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR) { // WSAGetLastError() }A WinSock bind () will cause the stack to generate a new local LSAP-SEL and to add it to the IAS database associated with the service name supplied in the SOCKADDR_IRDA.listen() The listen() call is used by server applications to place the stack into a mode where it will receive incoming connections on that socket. listen() does not block. The backlog parameter tells the stack how many inbound connections to accept on behalf of the application before the application is able to further process (accept()) these connections.if (listen(ServSock, 2) == SOCKET_ERROR) { // WSAGetLastError() }accept() Once a server application has put its server socket into listen mode, it calls accept() and blocks until an incoming connection is received. An unusual characteristic of accept() is that it returns a new socket. The reason for this is that the server application might need to continue accepting new inbound connections. To support this, the server typically creates a new thread to handle the new connection, then blocks again on another accept(). There is no requirement that a simple server support multiple connections, and it is free to ignore the old listening socket until it is done with the newly created socket. The SOCKADDR_IRDA passed to accept is filled in with the peer's addresses and can usually be ignored.SOCKET NewSock;while(1) { sizeofSockAddr = sizeof(SOCKADDR_IRDA); if ((NewSock = accept(ServSock, (struct sockaddr *) &PeerSockAddr, &sizeofSockAddr)) == INVALID_SOCKET) { // WSAGetLastError() // exit } // NewSock is a connected socket. // Create a new thread and pass it NewSock, return to accept() on main // or use NewSock here until done, then close it. }send() and recv() These calls are used to transfer data. recv() will block until there is data available and send() will normally not block. send() can block if the peer is not receiving data (has stopped calling recv()). send() will unblock when the peer resumes recv()s. A recv() of length zero has the special meaning that the client has performed a graceful close on the socket. The application can assume that it has received all data that was sent by the peer. If any unrecoverable protocol error occurs during the connection, send() or recv() will return an error code and the connection will be aborted.int BytesRead, BytesSent; char Buffer[4096];// recv() example if ((BytesRead = recv(Sock, Buffer, sizeof(Buffer), 0)) == SOCKET_ERROR) { // WSAGetLastError() } if (BytesRead == 0) { // Peer has closed the connection and I have all the data. // Close the socket now. }// send() example if ((BytesSent = send(Sock, Buffer, sizeof(Buffer), 0)) == SOCKET_ERROR) { // WSAGetLastError() } // Check that BytesSent == sizeof(Buffer).closesocket() closesocket() initiates a graceful close on the connection and releases the socket handle.if (closesocket(Sock) == SOCKET_ERROR) { // WSAGetLastError() }getsockopt(,, IRLMP_ENUMDEVICES,,) and connect() This is the call used to run a discovery. Before a connection can be initiated, a device address must be obtained by doing a discovery operation. An extension to the WinSock getsockopt() call returns a list of all currently visible IrDA devices. A device address returned from this list is copied into a SOCKADDR_IRDA to be used by the connect() call.Discovery can be run in one of two ways. Performing a getsockopt() call with the IRLMP_ENUMDEVICES option will cause a single discovery to be run on each idle adapter. The list of discovered devices and cached devices (on active adapters) will be returned immediately. The following code demonstrates this:SOCKADDR_IRDA DestSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };#define DEVICE_LIST_LEN 10unsigned char DevListBuff[sizeof(DEVICELIST) - sizeof(IRDA_DEVICE_INFO) + (sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)]; int DevListLen = sizeof(DevListBuff); PDEVICELIST pDevList = (PDEVICELIST) &DevListBuff;pDevList->numDevice = 0;// Sock is not in connected state if (getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (char *) pDevList, &DevListLen) == SOCKET_ERROR) { // WSAGetLastError }if (pDevList->numDevice == 0) { // No devices discovered or cached. // Not a bad idea to run a couple of times. } else { // one per discovered device for (i = 0; i < (int) pDevList->numDevice; i++) { // 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);if (connect(Sock, (const struct sockaddr *) &DestSockAddr, sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR) { // WSAGetLastError }It is also possible to run a lazy discovery—the application will not be notified until the discovered device list changes from the last discovery run by the stack.IAS Limited access to the IAS database is available through WinSock, but this is not normally used by applications. It exists to support connections to non–Windows devices that are not compliant with the WinSock/IrDA conventions.This code is used with the IRLMP_IAS_SET setsockopt() to manage the local IAS database:typedef struct _IAS_SET { char irdaClassName[IAS_MAX_CLASSNAME]; char irdaAttribName[IAS_MAX_ATTRIBNAME]; u_long irdaAttribType; union { LONG irdaAttribInt; struct { u_short Len; u_char OctetSeq[IAS_MAX_OCTET_STRING]; } irdaAttribOctetSeq; struct { u_char Len; u_char CharSet; u_char UsrStr[IAS_MAX_USER_STRING]; } irdaAttribUsrStr; } irdaAttribute; } IAS_SET, *PIAS_SET, FAR *LPIAS_SET;This code is used with the IRLMP_IAS_QUERY getsockopt() to query a peer's IAS database:typedef struct _WINDOWS_IAS_QUERY { u_char irdaDeviceID[4]; char irdaClassName[IAS_MAX_CLASSNAME]; char irdaAttribName[IAS_MAX_ATTRIBNAME]; u_long irdaAttribType; union { LONG irdaAttribInt; struct { u_long Len; u_char OctetSeq[IAS_MAX_OCTET_STRING]; } irdaAttribOctetSeq; struct { u_long Len; u_long CharSet; u_char UsrStr[IAS_MAX_USER_STRING]; } irdaAttribUsrStr; } irdaAttribute; } IAS_QUERY, *PIAS_QUERY, FAR *LPIAS_QUERY;IrCOMM Server The following code shows the steps necessary to build a server that listens for incoming IrCOMM connections:#define IAS_SET_ATTRIB_MAX_LEN 32// buffer for IAS set BYTE IASSetBuff[sizeof(IAS_SET) - 3 + IAS_SET_ATTRIB_MAX_LEN]; Int IASSetLen = sizeof(IASSetBuff); PIAS_SET pIASSet = (PIAS_SET) &IASSetBuff;// for the setsockopt call to enable 9 Wire IrCOMM int Enable9WireMode = 1;// server sockaddr with IrCOMM name SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" }; SOCKADDR_IRDA PeerSockAddr; int sizeofSockAddr;SOCKET ServSock; SOCKET NewSock;if ((ServSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET) { // WSAGetLastError }
// Add IrCOMM IAS attributes for 3 Wire cooked and 9 Wire raw, see IrCOMM spec. memcpy(&pIASSet->irdaClassName[0], "IrDA:IrCOMM", 12); memcpy(&pIASSet->irdaAttribName[0], "Parameters", 11);
pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ; pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = 6;memcpy(&pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq[0], "\000\001\006\001\001\001", 6);if (setsockopt(ServSock, SOL_IRLMP, IRLMP_IAS_SET, (const char *) pIASSet, IASSetLen) == SOCKET_ERROR) { // WSAGetLastError }// Enable 9 Wire mode before bind(). if (setsockopt(ServSock, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode, sizeof(int)) == SOCKET_ERROR) { // WSAGetLastError }if (bind(ServSock, (const struct sockaddr *) &ServSockAddr, sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR) { // WSAGetLastError }// Nothing special for IrCOMM from now on... if (listen(ServSock, SERV_BACKLOG) == SOCKET_ERROR) { // WSAGetLastError }IrCOMM Client The following code shows the steps necessary to build a client that connects through 9 Wire IrCOMM:#define DEVICE_LIST_LEN 5// 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;#define IAS_QUERY_ATTRIB_MAX_LEN 32// buffer for IAS query BYTE IASQueryBuff[sizeof(IAS_QUERY) - 3 + IAS_QUERY_ATTRIB_MAX_LEN]; Int IASQueryLen = sizeof(IASQueryBuff); PIAS_QUERY pIASQuery = (PIAS_QUERY) &IASQueryBuff;
// for searching through peers IAS response BOOL Found = FALSE; UCHAR *pPI, *pPL, *pPV;
// for the setsockopt call to enbale 9 Wire IrCOMM int Enable9WireMode = 1;SOCKADDR_IRDA DstAddrIR = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" };if ((pConn->Sock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET) { // WSAGetLastError }// search for the peer device pDevList->numDevice = 0; if (getsockopt(pConn->Sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen) == SOCKET_ERROR) { // WSAGetLastError }// if (pDevList->numDevice == 0) { // No devices found, tell the user. }// Assume first device, we should have a common dialog here. memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);// Query the peer to check for 9 Wire IrCOMM support. memcpy(&pIASQuery->irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);// IrCOMM IAS attributes memcpy(&pIASQuery->irdaClassName[0], "IrDA:IrCOMM", 12); memcpy(&pIASQuery->irdaAttribName[0], "Parameters", 11);if (getsockopt(pConn->Sock, SOL_IRLMP, IRLMP_IAS_QUERY, (char *) pIASQuery, &IASQueryLen) == SOCKET_ERROR) { // WSAGetLastError }if (pIASQuery->irdaAttribType != IAS_ATTRIB_OCTETSEQ) { // Peer's IAS database entry for IrCOMM is bad. // error }if (pIASQuery->irdaAttribute.irdaAttribOctetSeq.Len < 3) { // Peer's IAS database entry for IrCOMM is bad. // error }// Search for the PI value 0x00 and check 9 Wire, see IrCOMM spec. pPI = pIASQuery->irdaAttribute.irdaAttribOctetSeq.OctetSeq; pPL = pPI + 1; pPV = pPI + 2;while (1) { if (*pPI == 0 && (*pPV & 0x04)) { Found = TRUE; break; }
我的DDK是98DDK最新版本! 但是没有IrDA的有关例子!!
WSAStartup()
Call WSAStartup before making any other IrDA calls.WORD WSAVerReq = MAKEWORD(1,1);
WSADATA WSAData;if (WSAStartup(WSAVerReq, &WSAData) != 0)
{
// wrong winsock dlls?
}af_irda.h
This header file must be included by WinSock applications to support IrDA. There are several incompatible versions of af_irda.h that have been distributed with Windows CE and Windows 95 Ir3.0 DDKs and SDKs. A common af_irda.h that supports all three platforms is available with the Windows 2000 IrDA DDK, which can be accessed at the Web site www.microsoft.com/ddk/. This file may continue to evolve as the APIs of the systems grow closer together.In order to compile for one of the target platforms, one of the following must be defined:_WIN32_WINNT
_WIN32_WCE
_WIN32_WINDOWS socket()
The WinSock socket() call is used to create a connection endpoint of type SOCKET. This is nothing more than an application anchor for future references to a connection. The connection is not yet established. Both clients and servers begin all communication by opening a socket.SOCKET ServSock;if ((ServSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
// WSAGetLastError()
}SOCKADDR_IRDA Structure
The following sockaddr structure is used for AF_IRDA sockets:typedef struct _SOCKADDR_IRDA
{
u_short irdaAddressFamily;
u_char irdaDeviceID[4];
char irdaServiceName[25];
} SOCKADDR_IRDA, *PSOCKADDR_IRDA, FAR *LPSOCKADDR_IRDA;irdaAddressFamily is always AF_IRDA.Server applications use the irdaServiceName field to specify their well-known service name in a bind() call. The irdaDeviceID field is ignored by the server application.Client applications fill in all fields. The irdaDeviceID is filled in with the device address of the device that the client wishes to connect() to. This address is returned from a previous discovery operation initiated by a getsockopt() call with the IRLMP_ENUMDEVICES option. The irdaServiceName field is initialized to the well-known value that the server specified in its bind() call.It is an error for an IrDA application to issue a connect() call after issuing a bind() call.bind()
The bind() call is used by server applications to register that they with to receive incoming connections that are addressed to a specified service name on the specified socket. bind() associates a server socket with an application level address.SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };
int SizeOfSockAddr;if (bind(ServSock, (const struct sockaddr *) &ServSockAddr,
sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
{
// WSAGetLastError()
}A WinSock bind () will cause the stack to generate a new local LSAP-SEL and to add it to the IAS database associated with the service name supplied in the SOCKADDR_IRDA.listen()
The listen() call is used by server applications to place the stack into a mode where it will receive incoming connections on that socket. listen() does not block. The backlog parameter tells the stack how many inbound connections to accept on behalf of the application before the application is able to further process (accept()) these connections.if (listen(ServSock, 2) == SOCKET_ERROR)
{
// WSAGetLastError()
}accept()
Once a server application has put its server socket into listen mode, it calls accept() and blocks until an incoming connection is received. An unusual characteristic of accept() is that it returns a new socket. The reason for this is that the server application might need to continue accepting new inbound connections. To support this, the server typically creates a new thread to handle the new connection, then blocks again on another accept(). There is no requirement that a simple server support multiple connections, and it is free to ignore the old listening socket until it is done with the newly created socket. The SOCKADDR_IRDA passed to accept is filled in with the peer's addresses and can usually be ignored.SOCKET NewSock;while(1)
{
sizeofSockAddr = sizeof(SOCKADDR_IRDA); if ((NewSock = accept(ServSock, (struct sockaddr *) &PeerSockAddr,
&sizeofSockAddr)) == INVALID_SOCKET)
{
// WSAGetLastError()
// exit
} // NewSock is a connected socket.
// Create a new thread and pass it NewSock, return to accept() on main
// or use NewSock here until done, then close it.
}send() and recv()
These calls are used to transfer data. recv() will block until there is data available and send() will normally not block. send() can block if the peer is not receiving data (has stopped calling recv()). send() will unblock when the peer resumes recv()s. A recv() of length zero has the special meaning that the client has performed a graceful close on the socket. The application can assume that it has received all data that was sent by the peer. If any unrecoverable protocol error occurs during the connection, send() or recv() will return an error code and the connection will be aborted.int BytesRead, BytesSent;
char Buffer[4096];// recv() example
if ((BytesRead = recv(Sock, Buffer, sizeof(Buffer), 0)) == SOCKET_ERROR)
{
// WSAGetLastError()
}
if (BytesRead == 0)
{
// Peer has closed the connection and I have all the data.
// Close the socket now.
}// send() example
if ((BytesSent = send(Sock, Buffer, sizeof(Buffer), 0)) == SOCKET_ERROR)
{
// WSAGetLastError()
}
// Check that BytesSent == sizeof(Buffer).closesocket()
closesocket() initiates a graceful close on the connection and releases the socket handle.if (closesocket(Sock) == SOCKET_ERROR)
{
// WSAGetLastError()
}getsockopt(,, IRLMP_ENUMDEVICES,,) and connect()
This is the call used to run a discovery. Before a connection can be initiated, a device address must be obtained by doing a discovery operation. An extension to the WinSock getsockopt() call returns a list of all currently visible IrDA devices. A device address returned from this list is copied into a SOCKADDR_IRDA to be used by the connect() call.Discovery can be run in one of two ways. Performing a getsockopt() call with the IRLMP_ENUMDEVICES option will cause a single discovery to be run on each idle adapter. The list of discovered devices and cached devices (on active adapters) will be returned immediately. The following code demonstrates this:SOCKADDR_IRDA DestSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };#define DEVICE_LIST_LEN 10unsigned char DevListBuff[sizeof(DEVICELIST) -
sizeof(IRDA_DEVICE_INFO) +
(sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof(DevListBuff);
PDEVICELIST pDevList = (PDEVICELIST) &DevListBuff;pDevList->numDevice = 0;// Sock is not in connected state
if (getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *) pDevList, &DevListLen) == SOCKET_ERROR)
{
// WSAGetLastError
}if (pDevList->numDevice == 0)
{
// No devices discovered or cached.
// Not a bad idea to run a couple of times.
}
else
{
// one per discovered device
for (i = 0; i < (int) pDevList->numDevice; i++)
{
// 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);if (connect(Sock, (const struct sockaddr *) &DestSockAddr,
sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
{
// WSAGetLastError
}It is also possible to run a lazy discovery—the application will not be notified until the discovered device list changes from the last discovery run by the stack.IAS
Limited access to the IAS database is available through WinSock, but this is not normally used by applications. It exists to support connections to non–Windows devices that are not compliant with the WinSock/IrDA conventions.This code is used with the IRLMP_IAS_SET setsockopt() to manage the local IAS database:typedef struct _IAS_SET
{
char irdaClassName[IAS_MAX_CLASSNAME];
char irdaAttribName[IAS_MAX_ATTRIBNAME];
u_long irdaAttribType;
union
{
LONG irdaAttribInt;
struct
{
u_short Len;
u_char OctetSeq[IAS_MAX_OCTET_STRING];
} irdaAttribOctetSeq;
struct
{
u_char Len;
u_char CharSet;
u_char UsrStr[IAS_MAX_USER_STRING];
} irdaAttribUsrStr;
} irdaAttribute;
} IAS_SET, *PIAS_SET, FAR *LPIAS_SET;This code is used with the IRLMP_IAS_QUERY getsockopt() to query a peer's IAS database:typedef struct _WINDOWS_IAS_QUERY
{
u_char irdaDeviceID[4];
char irdaClassName[IAS_MAX_CLASSNAME];
char irdaAttribName[IAS_MAX_ATTRIBNAME];
u_long irdaAttribType;
union
{
LONG irdaAttribInt;
struct
{
u_long Len;
u_char OctetSeq[IAS_MAX_OCTET_STRING];
} irdaAttribOctetSeq;
struct
{
u_long Len;
u_long CharSet;
u_char UsrStr[IAS_MAX_USER_STRING];
} irdaAttribUsrStr;
} irdaAttribute;
} IAS_QUERY, *PIAS_QUERY, FAR *LPIAS_QUERY;IrCOMM Server
The following code shows the steps necessary to build a server that listens for incoming IrCOMM connections:#define IAS_SET_ATTRIB_MAX_LEN 32// buffer for IAS set
BYTE IASSetBuff[sizeof(IAS_SET) - 3 + IAS_SET_ATTRIB_MAX_LEN];
Int IASSetLen = sizeof(IASSetBuff);
PIAS_SET pIASSet = (PIAS_SET) &IASSetBuff;// for the setsockopt call to enable 9 Wire IrCOMM
int Enable9WireMode = 1;// server sockaddr with IrCOMM name
SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" };
SOCKADDR_IRDA PeerSockAddr;
int sizeofSockAddr;SOCKET ServSock;
SOCKET NewSock;if ((ServSock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
// WSAGetLastError
}
// Add IrCOMM IAS attributes for 3 Wire cooked and 9 Wire raw, see IrCOMM spec.
memcpy(&pIASSet->irdaClassName[0], "IrDA:IrCOMM", 12);
memcpy(&pIASSet->irdaAttribName[0], "Parameters", 11);
pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ;
pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = 6;memcpy(&pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq[0],
"\000\001\006\001\001\001", 6);if (setsockopt(ServSock, SOL_IRLMP, IRLMP_IAS_SET, (const char *) pIASSet, IASSetLen)
== SOCKET_ERROR)
{
// WSAGetLastError
}// Enable 9 Wire mode before bind().
if (setsockopt(ServSock, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode,
sizeof(int)) == SOCKET_ERROR)
{
// WSAGetLastError
}if (bind(ServSock, (const struct sockaddr *) &ServSockAddr, sizeof(SOCKADDR_IRDA))
== SOCKET_ERROR)
{
// WSAGetLastError
}// Nothing special for IrCOMM from now on...
if (listen(ServSock, SERV_BACKLOG) == SOCKET_ERROR)
{
// WSAGetLastError
}IrCOMM Client
The following code shows the steps necessary to build a client that connects through 9 Wire IrCOMM:#define DEVICE_LIST_LEN 5// 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;#define IAS_QUERY_ATTRIB_MAX_LEN 32// buffer for IAS query
BYTE IASQueryBuff[sizeof(IAS_QUERY) - 3 + IAS_QUERY_ATTRIB_MAX_LEN];
Int IASQueryLen = sizeof(IASQueryBuff);
PIAS_QUERY pIASQuery = (PIAS_QUERY) &IASQueryBuff;
// for searching through peers IAS response
BOOL Found = FALSE;
UCHAR *pPI, *pPL, *pPV;
// for the setsockopt call to enbale 9 Wire IrCOMM
int Enable9WireMode = 1;SOCKADDR_IRDA DstAddrIR = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" };if ((pConn->Sock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
// WSAGetLastError
}// search for the peer device
pDevList->numDevice = 0;
if (getsockopt(pConn->Sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen)
== SOCKET_ERROR)
{
// WSAGetLastError
}// if (pDevList->numDevice == 0)
{
// No devices found, tell the user.
}// Assume first device, we should have a common dialog here.
memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);// Query the peer to check for 9 Wire IrCOMM support.
memcpy(&pIASQuery->irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);// IrCOMM IAS attributes
memcpy(&pIASQuery->irdaClassName[0], "IrDA:IrCOMM", 12);
memcpy(&pIASQuery->irdaAttribName[0], "Parameters", 11);if (getsockopt(pConn->Sock, SOL_IRLMP, IRLMP_IAS_QUERY, (char *) pIASQuery,
&IASQueryLen) == SOCKET_ERROR)
{
// WSAGetLastError
}if (pIASQuery->irdaAttribType != IAS_ATTRIB_OCTETSEQ)
{
// Peer's IAS database entry for IrCOMM is bad.
// error
}if (pIASQuery->irdaAttribute.irdaAttribOctetSeq.Len < 3)
{
// Peer's IAS database entry for IrCOMM is bad.
// error
}// Search for the PI value 0x00 and check 9 Wire, see IrCOMM spec.
pPI = pIASQuery->irdaAttribute.irdaAttribOctetSeq.OctetSeq;
pPL = pPI + 1;
pPV = pPI + 2;while (1)
{
if (*pPI == 0 && (*pPV & 0x04))
{
Found = TRUE;
break;
}
if (pPL + *pPL >= pIASQuery->irdaAttribute.irdaAttribOctetSeq.OctetSeq +
pIASQuery->irdaAttribute.irdaAttribOctetSeq.Len)
{
break;
}
pPI = pPL + *pPL;
pPL = pPI + 1;
pPV = pPI + 2;
}if (! Found)
{
// Peer doesn't support 9 Wire mode.
// error
}// Enable 9 Wire mode before connect().
if (setsockopt(ServSock, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode,
sizeof(int)) == SOCKET_ERROR)
{
// WSAGetLastError
}// Nothing special for IrCOMM from now on...
if (connect(pConn->Sock, (const struct sockaddr *) &DstAddrIR, sizeof(SOCKADDR_IRDA))
== SOCKET_ERROR)
{
// WSAGetLastError
}