Re[3]: IrDA
От: ioni Россия  
Дата: 17.06.02 17:55
Оценка:
Здравствуйте Den, Вы писали:

Den>Ок. Псиб. поищу книжку. Но если не трудно, глянь плиз какой нить там простенький примерчик для IrDA. Буду премного благодарен.


вот пример клиента и сервера из книги
//
// Winsock1.1, IrDA1.1, WindowsNT5.0, Windows98 and WindowsCE1.0.
// Define one of _WIN32_WINNT, _WIN32_WINDOWS, _WIN32_WCE.
//

#ifndef __AFIRDA__
#define __AFIRDA__

#ifndef _WINSOCKAPI_
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
#endif

#define WINDOWS_AF_IRDA 26
#define WINDOWS_PF_IRDA WINDOWS_AF_IRDA

#define WCE_AF_IRDA 22
#define WCE_PF_IRDA WCE_AF_IRDA


#if defined(_WIN32_WINNT) || defined(_WIN32_WINDOWS)
#ifndef AF_IRDA
#define AF_IRDA WINDOWS_AF_IRDA
#endif
#define IRDA_PROTO_SOCK_STREAM 1
#elif defined(_WIN32_WCE)
#define AF_IRDA WCE_AF_IRDA
#else
#pragma message("One of _WIN32_WINNT | _WIN32_WINDOWS | _WIN32_WCE must be defined.")
#endif

#define PF_IRDA AF_IRDA

// WINNT, WIN98, WINCE
#define SOL_IRLMP 0x00FF

#define IRLMP_ENUMDEVICES 0x00000010
#define IRLMP_IAS_SET 0x00000011
#define IRLMP_IAS_QUERY 0x00000012

// WINNT, WINCE
#define IRLMP_SEND_PDU_LEN 0x00000013
#define IRLMP_EXCLUSIVE_MODE 0x00000014
#define IRLMP_IRLPT_MODE 0x00000015
#define IRLMP_9WIRE_MODE 0x00000016

// WIN98
#define IRLMP_TINYTP_MODE 0x00000017
#define IRLMP_PARAMETERS 0x00000018
#define IRLMP_DISCOVERY_MODE 0x00000019

// WINCE
#define IRLMP_SHARP_MODE 0x00000020

#if defined(_WIN32_WINNT) // WSAIoctl for lazy discovery
#define SIO_LAZY_DISCOVERY _IOR('t', 127, u_long)
#endif

#define IAS_ATTRIB_NO_CLASS 0x00000010
#define IAS_ATTRIB_NO_ATTRIB 0x00000000
#define IAS_ATTRIB_INT 0x00000001
#define IAS_ATTRIB_OCTETSEQ 0x00000002
#define IAS_ATTRIB_STR 0x00000003

#define IAS_MAX_USER_STRING 256
#define IAS_MAX_OCTET_STRING 1024
#define IAS_MAX_CLASSNAME 64
#define IAS_MAX_ATTRIBNAME 256

// WINNT, WIN98
enum
{
LM_HB_Extension = 128, // Any hint byte

LM_HB1_PnP = 1, // First hint byte
LM_HB1_PDA_Palmtop = 2,
LM_HB1_Computer = 4,
LM_HB1_Printer = 8,
LM_HB1_Modem = 16,
LM_HB1_Fax = 32,
LM_HB1_LANAccess = 64,

LM_HB2_Telephony = 1, // Second hint byte
LM_HB2_FileServer = 2,
};

#define LmCharSetASCII 0
#define LmCharSetISO_8859_1 1
#define LmCharSetISO_8859_2 2
#define LmCharSetISO_8859_3 3
#define LmCharSetISO_8859_4 4
#define LmCharSetISO_8859_5 5
#define LmCharSetISO_8859_6 6
#define LmCharSetISO_8859_7 7
#define LmCharSetISO_8859_8 8
#define LmCharSetISO_8859_9 9
#define LmCharSetUNICODE 0xff

// WIN98
typedef u_long LM_BAUD_RATE;

#define LM_BAUD_1200 1200
#define LM_BAUD_2400 2400
#define LM_BAUD_9600 9600
#define LM_BAUD_19200 19200
#define LM_BAUD_38400 38400
#define LM_BAUD_57600 57600
#define LM_BAUD_115200 115200
#define LM_BAUD_576K 576000
#define LM_BAUD_1152K 1152000
#define LM_BAUD_4M 4000000

typedef struct
{
u_long nTXDataBytes; // Max tx data bytes per packet
u_long nRXDataBytes; // Max rx data bytes per packet
LM_BAUD_RATE nBaudRate; // Negotiated baud rate
u_long thresholdTime; // Threshold (ms)
u_long discTime; // Disconnect (ms)
u_short nMSLinkTurn; // Link turn around (ms)
u_char nTXPackets; // Number packets in transmit window
u_char nRXPackets; // Number packets in receive window
} LM_IRPARMS,*PLM_IRPARMS;

typedef struct _SOCKADDR_IRDA
{
u_short irdaAddressFamily;
u_char irdaDeviceID[4];
char irdaServiceName[25];
} SOCKADDR_IRDA, *PSOCKADDR_IRDA, FAR *LPSOCKADDR_IRDA;

typedef struct _WINDOWS_IRDA_DEVICE_INFO
{
u_char irdaDeviceID[4];
char irdaDeviceName[22];
u_char irdaDeviceHints1;
u_char irdaDeviceHints2;
u_char irdaCharSet;
} WINDOWS_IRDA_DEVICE_INFO, *PWINDOWS_IRDA_DEVICE_INFO, FAR *LPWINDOWS_IRDA_DEVICE_INFO;

typedef struct _WCE_IRDA_DEVICE_INFO
{
u_char irdaDeviceID[4];
char irdaDeviceName[22];
u_char Reserved[2];
} WCE_IRDA_DEVICE_INFO, *PWCE_IRDA_DEVICE_INFO;

#if defined(_WIN32_WINNT) || defined(_WIN32_WINDOWS)
typedef WINDOWS_IRDA_DEVICE_INFO IRDA_DEVICE_INFO, *PIRDA_DEVICE_INFO, FAR *LPIRDA_DEVICE_INFO;
#elif defined(_WIN32_WCE)
typedef WCE_IRDA_DEVICE_INFO IRDA_DEVICE_INFO, *PIRDA_DEVICE_INFO;
#else
#pragma message("One of _WIN32_WINNT | _WIN32_WINDOWS | _WIN32_WCE must be defined.")
#endif

typedef struct _WINDOWS_DEVICELIST
{
ULONG numDevice;
WINDOWS_IRDA_DEVICE_INFO Device[1];
} WINDOWS_DEVICELIST, *PWINDOWS_DEVICELIST, FAR *LPWINDOWS_DEVICELIST;

typedef struct _WCE_DEVICELIST
{
ULONG numDevice;
WCE_IRDA_DEVICE_INFO Device[1];
} WCE_DEVICELIST, *PWCE_DEVICELIST;

#if defined(_WIN32_WINNT) || defined(_WIN32_WINDOWS)
typedef WINDOWS_DEVICELIST DEVICELIST, *PDEVICELIST, FAR *LPDEVICELIST;
#elif defined(_WIN32_WCE)
typedef WCE_DEVICELIST DEVICELIST, *PDEVICELIST;
#else
#pragma message("One of _WIN32_WINNT | _WIN32_WINDOWS | _WIN32_WCE must be defined.")
#endif

typedef struct _WINDOWS_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;
} WINDOWS_IAS_SET, *PWINDOWS_IAS_SET, FAR *LPWINDOWS_IAS_SET;

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;
} WINDOWS_IAS_QUERY, *PWINDOWS_IAS_QUERY, FAR *LPWINDOWS_IAS_QUERY;

typedef struct _WCE_IAS_SET
{
char irdaClassName[61];
char irdaAttribName[61];
u_short irdaAttribType;
union
{
int irdaAttribInt;
struct
{
int Len;
u_char OctetSeq[1];
u_char Reserved[3];
} irdaAttribOctetSeq;
struct
{
int Len;
u_char CharSet;
u_char UsrStr[1];
u_char Reserved[2];
} irdaAttribUsrStr;
} irdaAttribute;
} WCE_IAS_SET, *PWCE_IAS_SET;

typedef struct _WCE_IAS_QUERY
{
u_char irdaDeviceID[4];
char irdaClassName[61];
char irdaAttribName[61];
u_short irdaAttribType;
union
{
int irdaAttribInt;
struct
{
int Len;
u_char OctetSeq[1];
u_char Reserved[3];
} irdaAttribOctetSeq;
struct
{
int Len;
u_char CharSet;
u_char UsrStr[1];
u_char Reserved[2];
} irdaAttribUsrStr;
} irdaAttribute;
} WCE_IAS_QUERY, *PWCE_IAS_QUERY;

#if defined(_WIN32_WINNT) || defined(_WIN32_WINDOWS)
typedef WINDOWS_IAS_SET IAS_SET, *PIAS_SET, FAR *LPIASSET;
typedef WINDOWS_IAS_QUERY IAS_QUERY, *PIAS_QUERY, FAR *LPIASQUERY;
#elif defined(_WIN32_WCE)
typedef WCE_IAS_SET IAS_SET, *PIAS_SET;
typedef WCE_IAS_QUERY IAS_QUERY, *PIAS_QUERY, FAR *LPIASQUERY;
#else
#pragma message("One of _WIN32_WINNT | _WIN32_WINDOWS | _WIN32_WCE must be defined.")
#endif

#endif // __AFIRDA__
/////////////////////////////////////////////////////////////////////////////////////////
// Module Name: Ircommon.h
//
// Description:
// This header file simply contains prototypes for two basic
// functions used by both client and server. The functions
// themselves are in Ircommon.c
//
int senddata(SOCKET s, char *buf, int *len);
int recvdata(SOCKET s, char *buf, int *len);
//////////////////////////////////////////////////////////////////////////////////////////
// Module Name: Ircommon.c
//
// Description:
// This file contains two simple functions, one for sending
// data on a connected socket and the other for receiving.
// These two functions are common to both client and server
// so they were pulled out into a seperate file.
//
// Compile:
// cl /c Ircommon.c
//
#ifdef _WIN32_WCE
#include <windows.h>
#include <winsock.h>
#else
#include <winsock2.h>
#endif

#include "ircommon.h"

int senddata(SOCKET s, char *buf, int *len)
{
int ret,
index=0,
slen;
DWORD dwErr;

slen = *len;
while (len > 0)
{
ret = send(s, &buf[index], slen, 0);
if (ret == SOCKET_ERROR)
{
if ((dwErr = WSAGetLastError()) != WSAEWOULDBLOCK)
{
return dwErr;
}
}
else if (ret == 0)
{
*len = 0;
return 0;
}
slen -= ret;
index += ret;
}
*len = index;
return 0;
}

int recvdata(SOCKET s, char *buf, int *len)
{
int ret,
index=0;
DWORD dwErr;

ret = recv(s, buf, *len, 0);
if (ret == SOCKET_ERROR)
{
if ((dwErr = WSAGetLastError()) != WSAEWOULDBLOCK)
{
return dwErr;
}
else if (ret == 0)
{
*len = 0;
return 0;
}
}
*len = ret;
return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////
// Module Name: Irclient.c
//
// Description:
// This sample illustrates how to create an IrSock client. This
// sample is targeted for Windows 98 and NT 5 but can be used on
// Windows CE. There are conditional defines to mark the major
// differences in the platforms. Mainly, CE requires Winsock 1.1
// while the others require 2.2. Also, CE must be a Windows app
// so you can't use main(). The only thing you need to do to for
// CE is paste this file into a project file in VC to compile it
// for the given target processor type.
//
// Compile:
// CE: Paste into VC project and target for yur device. Link with
// winsock.lib
// NT:
// cl /D"_WIN32_WINNT" -o Irclient Irclient.c
// Ircommon.obj ws2_32.lib
// Windows 98:
// cl /D"_WIN32_WINDOWS" -o Irclient Irclient.c
// Ircommon.obj ws2_32.lib
//
// Command line parameters/options:
// None. The client is hardcode to attach to "MyServer". Change
// the define IR_SERVICE_NAME if you desire something else (don't
// forget to change the server too).
//
#ifdef _WIN32_WCE
#include <windows.h>
#include <winsock.h>
#else
#include <winsock2.h>
#endif

#include "af_irda.h"

#include <stdio.h>
#include <stdlib.h>

#include "ircommon.h"

#define IR_SERVICE_NAME "MyServer"
#define TEST_STRING "This is a test of the client"
#define MAX_RETRIES 10
#define MAX_BUFFER 4096

//
// Function: FindDevices
//
// Description:
// This function attempts to locate any IR capable devices within
// range. This is done by calling the IRLMP_ENUMDEVICES socket
// option. We call this several times in a loop to make a good
// effort to find any. Upon success a DEVICELIST structure is
// filled in with the device IDs of the discovered device.
//
int FindDevices(SOCKET s, DEVICELIST *devlist)
{
DWORD dwNumRetries=0,
dwDevListSz;
int ret;

dwDevListSz = sizeof(*devlist);

devlist->numDevice = 0;
while ((devlist->numDevice == 0)
&& (dwNumRetries <= MAX_RETRIES))
{
ret = getsockopt(s, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *)devlist, &dwDevListSz);
if (ret == SOCKET_ERROR)
{
fprintf(stderr, "getsockopt(IRLMP_ENUMDEVICES) "
"failed: %d\n", WSAGetLastError());
return 0;
}
dwNumRetries++;
Sleep(1000);
}
if (dwNumRetries > MAX_RETRIES)
{
return 0;
}
return devlist->numDevice;
}

//
// Function: main (WinMain)
//
// Description:
// This is the main function for the client. The appropriate
// Winsock library is loaded, an IR socket is created, and then
// we enumerate any IR devices within range. We then attempt to
// connect to each of these devices to a particular service.
// The first connection attemp that succeeds, we take. Once
// connected we send and receive data.
//
#ifdef _WIN32_WCE
int WINAPI WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
#else
int main(int argc, char **argv)
#endif
{
WSADATA wsd;
SOCKET sock;
SOCKADDR_IRDA irAddr = {AF_IRDA, 0, 0, 0, 0, "\0"};
DWORD dwIrSize = sizeof(SOCKADDR_IRDA),
dwErr;
int i, j,
ret,
optval,
len;
BOOL bDone=FALSE;
DEVICELIST devlist;
char szRecvBuff[MAX_BUFFER];
WORD wVersion;

#ifdef _WIN32_WCE
wVersion = MAEKWORD(1, 1);
#else
wVersion = MAKEWORD(2, 2);
#endif

if (WSAStartup(wVersion, &wsd) != 0)
{
printf("Unable to load the Winsock library!\n");
return 1;
}
sock = socket(AF_IRDA, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
printf("socket() failed: %d", WSAGetLastError());
return 1;
}
if (FindDevices(sock, &devlist) == 0)
{
printf("No IrDA devices in range!\n");
return 1;
}
// Setup the SOCKADDR_IRDA structure with the service
// name we want to connect to
//
strcpy(irAddr.irdaServiceName, IR_SERVICE_NAME);

for(i = 0; i < devlist.numDevice; i++)
{
for(j = 0; j < 4; i++)
{
irAddr.irdaDeviceID[i] =
devlist.Device[i].irdaDeviceID[j];
}
if (connect(sock, (struct sockaddr *)&irAddr,
sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
{
if (i == (devlist.numDevice — 1))
{
printf("Unable to locate service: '%s'\n",
irAddr.irdaServiceName);
return 1;
}
continue;
}
else
break;
}
// Make the socket non-blocking
//
optval = 1;
if (ioctlsocket(sock, FIONBIO, &optval) == SOCKET_ERROR)
{
printf("ioctlsocket(FIONBIO) failed: %d\n",
WSAGetLastError());
return 1;
}
// Read data from the server and echo it back until the server
// closes the connection. I should probably use a select() call
// to test for readability/writeability before calling
// send()/recv().
//
while (!bDone)
{
len = strlen(TEST_STRING);
if ((ret = senddata(sock, TEST_STRING, &len)) != 0)
{
printf("send() failed: %d\n", ret);
break;
}
if (len == 0) // Graceful close
break;

len = MAX_BUFFER;
if ((ret = recvdata(sock, szRecvBuff, &len)) != 0)
{
printf("recv() failed: %d\n", ret);
break;
}
if (len == 0) // Graceful close
break;
}

closesocket(sock);
WSACleanup();

return 1;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Module Name: Irserver.c
//
// Description:
// This sample illustrates a IrSock server. This sampe is targeted
// towards Windows 98 and Windows 2000 but can also be used on
// Windows CE. There are conditional defines to make the major
// differences in the platforms. Mainly, Windows CE requires
// Winsock 1.1 while the others require 2.2. Also, Windows CE
// must be a Windows application so you can't use main(). The only
// thing you need to do to for Windows CE is paste this file into
// a project file in VC to compile it for the given target
// processor type.
//
// Compile:
// Windows CE: Paste into VC project and target for yur device.
// Link with winsock.lib
// Windows NT:
// cl /D"_WIN32_WINNT" -o Irserver Irserver.c
// Ircommon.obj ws2_32.lib
// Windows 98:
// cl /D"_WIN32_WINDOWS" -o Irserver Irserver.c
// Ircommon.obj ws2_32.lib
//
// Command line parameters/options:
// None. The server is hardcode to listen on "MyServer". Change
// the define IR_SERVICE_NAME if you desire something else (don't
// forget to change the server too).
//

#ifdef _WIN32_WCE
#include <windows.h>
#include <winsock.h>
#else
#include <winsock2.h>
#endif

#include "af_irda.h"

#include <stdio.h>
#include <stdlib.h>

#define IR_SERVICE_NAME "MyServer"
#define MAX_BUFFER 4096

//
// Function: ClientThread
//
// Description:
// This is a client thread that is spawned with each client
// connection. The thread simply reads data and writes it
// back to the client until the socket is closed.
//
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET s = (SOCKET)lpParam;
int ret,
len;
char szRecvBuff[MAX_BUFFER];

while (1)
{
// Read data from client
//
len = MAX_BUFFER;
if ((ret = recvdata(s, szRecvBuff, &len)) != 0)
{
printf("recv() failed: %d\n", ret);
break;
}
if (len == 0) // Graceful close
break;
szRecvBuff[len] = 0;
printf("Read: %d bytes\n", len);
//
// Write data back until socket closure, len will
// equal 0 when the socket has been gracefully closed
//
if ((ret = senddata(s, szRecvBuff, &len)) != 0)
{
printf("send() failed: %d\n", ret);
break;
}
if (len == 0) // Graceful close
break;
printf("Wrote: %d bytes\n", len);
}
closesocket(s);
return 0;
}

//
// Function: main (Winmain)
//
// Description:
// This is the main function of the server. The appropriate
// Winsock library is loaded first, an IR listening socket is
// created, and we bind the socket to our server name.
// Afterwards we block on an accept() in a loop. Once a client
// connection is made, we spawn a thread to handle the connection.
//
#ifdef _WIN32_WCE
int WINAPI WinMain(HANDLE hInstance, HANDLE hPrevIntance,
LPTSTR lpCmdLine, int nCmdShow)
#else
int main(int argc, char **argv)
#endif
{
WSADATA wsd;
SOCKET sock,
sockClient;
SOCKADDR_IRDA irAddr = { AF_IRDA, 0, 0, 0, 0, "\0" },
remoteIrAddr;
DWORD dwIrSize = sizeof(SOCKADDR_IRDA),
dwRet,
dwErr,
dwId;
BOOL bDone = FALSE;
char szRecvBuff[MAX_BUFFER];
int optval;
HANDLE hThread;
WORD wVersion;

#ifdef _WIN32_WCE
wVersion = MAKEWORD(1, 1);
#else
wVersion = MAKEWORD(2, 2);
#endif

if (WSAStartup(wVersion, &wsd) != 0)
{
fprintf(stderr, "Unable to load Winsock library!\n");
return 0;
}
sock = socket(AF_IRDA, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError());
return 0;
}

strcpy(irAddr.irdaServiceName, IR_SERVICE_NAME);
//
// Bind our socket to the local service name
//
printf("Binding to service class name: %s\n",
irAddr.irdaServiceName);
if (bind(sock, (struct sockaddr *)&irAddr, sizeof(SOCKADDR_IRDA))
== SOCKET_ERROR)
{
fprintf(stderr, "bind() failed: %d\n", WSAGetLastError());
return 0;
}

listen(sock, 10);

while (1)
{
sockClient = accept(sock, (struct sockaddr *)&remoteIrAddr,
&dwIrSize);
if (sockClient == SOCKET_ERROR)
{
fprintf(stderr, "accept() failed: %d\n",
WSAGetLastError());
return 0;
}
// Make the client socket non-blocking
//
optval = 1;
if (ioctlsocket(sockClient, FIONBIO, &optval)
== SOCKET_ERROR)
{
fprintf(stderr, "ioctlsocket(FIONBIO) failed: %d\n",
WSAGetLastError());
return 0;
}
hThread = CreateThread(NULL, 0, ClientThread,
(LPVOID)sockClient, 0, &dwId);
if (hThread == NULL)
{
// Unable to create thread
}
CloseHandle(hThread);
}
// Close and cleanup
//
closesocket(sockClient);
closesocket(sock);

WSACleanup();

return 1;
}
//////////////////////////////////////////////////////////////////////////////////////
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.