Impresion via IRDA

User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Impresion via IRDA

Post by Arturo Lopesoria »

Amigos del foro:
Deseo saber cuales son los elementos y el procedimiento para abrir el puerto IRDA, establecer comunicacion con la impresora, enviar los datos a imprimir a la impresora y cerrar el puerto. El entorno del dispositivo es windows mobile 5.0, procesador PXA 270 y la impresora portatil con puerto IRDA .
Arturo LS
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Arturo,

Haz una búsqueda en estos foros por IRDA (botón "search" arriba) y encontrarás muchos comentarios que se han hecho de ese tema, gracias
regards, saludos

Antonio Linares
www.fivetechsoft.com
R.F.
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Post by R.F. »

No es posible hacerlo directamente via FWPPC, yo lo hago mediante un programa externo.
Saludos
R.F.
User avatar
jlcapel
Posts: 229
Joined: Wed Oct 12, 2005 5:32 pm
Location: Valencia - España
Contact:

Post by jlcapel »

User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Re

Post by Arturo Lopesoria »

Muchas Gracias Jose Luis. esta muy completa la informacion. Ahora mismo lo voy a probar
jlcapel wrote:Arturo,

Mira por aquí.... http://www.pocketpcdn.com/articles/irda.html
Arturo LS
User avatar
jlcapel
Posts: 229
Joined: Wed Oct 12, 2005 5:32 pm
Location: Valencia - España
Contact:

Post by jlcapel »

Arturo,

¿Como te fue la información?
¿Era lo que buscabas?
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

jlcapel wrote:Arturo,

¿Como te fue la información?
¿Era lo que buscabas?
Jose Luis:
Gracias, primeramente he elegido el camino de emular una comunicacion serial, pues tengo una impresora que soporta serial e IRDA via IR. Todavia no lo pruebo, pero cualquiera que sea el resultado se los hare saber.
Saludos.
Arturo LS
User avatar
luis.santeliz
Posts: 47
Joined: Mon May 29, 2006 9:04 pm

Post by luis.santeliz »

yo logre que imprimiera directamente desde FWPPC utilizando una libreria que me proporciona el fabricante, estoy usando una BROTHER MW100 MOBILE PRINTER imprime perfecto, graficos y todo.
Luis Santeliz
Móvil SoftWare, C.A.
---------------------------------------------
MySQL DBA,
MySQL Server Performance Tunning,
DPxBase, FiveWin, Java,
Linux Redhat, Windows

Caracas Venezuela
luissanteliz@cantv.net
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Luis: Interesante.. No conozco mucho de drivers.., esos DLL que usaste qué tipo de protocolo establecen con la impresora? Lo hacen controlando todo desde tu aplicación como se haría con una impresora serial o se usan como un driver de windows? De cualquier manera voy a averiguar si EXTECH puede proporcionarme algún DLL de ese tipo a pesar de que no soy partner de ellos.
GRACIAS
luis.santeliz wrote:yo logre que imprimiera directamente desde FWPPC utilizando una libreria que me proporciona el fabricante, estoy usando una BROTHER MW100 MOBILE PRINTER imprime perfecto, graficos y todo.
Arturo LS
User avatar
luis.santeliz
Posts: 47
Joined: Mon May 29, 2006 9:04 pm

Post by luis.santeliz »

Bueno el protocolo nose cual usa ya que todo lo gestiona la libreria y no es una dll es una .lib q se baja desde la pagina del fabricante, el modo de trabajar seria como un driver de windows ya que obtienes el DC (device context) y operas sobre el con las funciones GDI habituales, la libreria tambien tiene funciones propias para fines de impresion, administracion e informacion de estado.
Luis Santeliz
Móvil SoftWare, C.A.
---------------------------------------------
MySQL DBA,
MySQL Server Performance Tunning,
DPxBase, FiveWin, Java,
Linux Redhat, Windows

Caracas Venezuela
luissanteliz@cantv.net
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Antonio Linares wrote:Arturo,

Haz una búsqueda en estos foros por IRDA (botón "search" arriba) y encontrarás muchos comentarios que se han hecho de ese tema, gracias
Antonio:
He leído ya cada uno de los distintos protocolos disponibles para IRDA. Hasta donde he podido entender el código siguiente debe funcionar. Sólo necesitaría de tu ayuda para ponerlo de manera adecuada usando las sentencias de BEGIN..PRAGMA dump.
Saludos. He Aquí:

---------------------------
// Tomado de
// http://www.pocketpcjunkies.com/Uwe/Foru ... nting-FREE
// By Kevin

BOOL CWarehouseClientApp::IrDAPrint(CString tText)
{

SOCKET sock; // Socket bound to the server
DEVICELIST devList; // Device list
int iCount = 0, // Number of retries
index = 0, // Integer index
iDevListLen = sizeof(devList); // Size of the device list
TCHAR szError[100]; // Error message string
WSADATA wsaData;
WORD wVersion = MAKEWORD(1,1); // Winsock Version 1.1
BYTE IASQueryBuff[sizeof(IAS_QUERY) - 3 + IAS_MAX_ATTRIBNAME];
int IASQueryLen = sizeof(IASQueryBuff);
PIAS_QUERY pIASQuery = (PIAS_QUERY) &IASQueryBuff;
char szServiceName[12];
SOCKADDR_IRDA iraddr;
linger l;

// -------------------------------------------------

if(WSAStartup(wVersion, &wsaData) != 0)
{
wsprintf(szError, TEXT("WSAStartup failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
return FALSE;
}

// Create a socket that is bound to the server.
if((sock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wsprintf(szError, TEXT("Allocating socket failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
WSACleanup();
return FALSE;
}

// Initialize the number of devices to zero.
devList.numDevice = 0;

while((devList.numDevice == 0) && (iCount <= NUMRETRY))
{
// Retrieve the socket option
if(getsockopt(sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (char *)&devList,
&iDevListLen) == SOCKET_ERROR)
{
wsprintf(szError, TEXT("Server could not be located, getsockopt failed.
Error: %d"), WSAGetLastError());
AfxMessageBox(szError, MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}
if(devList.numDevice == 0)
{
iCount++;
Sleep(1000);
}
}

if(iCount > NUMRETRY)
{
AfxMessageBox(TEXT("Server could not be located!"), MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}

// ------------------------------------------------

memcpy(&pIASQuery->irdaDeviceID, devList.Device[0].irdaDeviceID, 4);
memcpy(&pIASQuery->irdaClassName, "IrLPT", 6);
memcpy(&pIASQuery->irdaAttribName, "IrDA:IrLMP:LsapSel", 19);

if (getsockopt(sock, SOL_IRLMP, IRLMP_IAS_QUERY, (char *)pIASQuery,
&IASQueryLen) == SOCKET_ERROR)
{
wsprintf(szError, TEXT("getsockopt failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}

sprintf(szServiceName, "LSAP-SEL%d",
pIASQuery->irdaAttribute.irdaAttribInt);

memset(&iraddr, 0, sizeof(iraddr));
iraddr.irdaAddressFamily = AF_IRDA;
memcpy (iraddr.irdaDeviceID, devList.Device[0].irdaDeviceID, 4);
memcpy (iraddr.irdaServiceName, szServiceName, strlen(szServiceName) + 1);

// Establish a connection to the socket.
if(connect(sock, (struct sockaddr *)&iraddr, sizeof(iraddr)) ==
SOCKET_ERROR )
{
wsprintf(szError, TEXT("Connecting to the server failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}

// Turn on SO_LINGER
l.l_onoff = 1;
l.l_linger = 0;
if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(struct
linger)) == SOCKET_ERROR )
{
wsprintf(szError, TEXT("setsockopt failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}

// Send a string from the client socket to the server socket.
char * aText = StringUtil::ConvertCStringToCharPtr(tText);
if(send(sock, aText, tText.GetLength() + 1, 0) == SOCKET_ERROR)
{
free(aText);
wsprintf(szError, TEXT("Sending data to the server failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
closesocket(sock);
WSACleanup();
return FALSE;
}
free(aText);

// Close the socket.
if(closesocket(sock) == SOCKET_ERROR)
{
wsprintf(szError, TEXT("closesocket failed. Error: %d"),
WSAGetLastError());
AfxMessageBox(szError, MB_OK);
WSACleanup();
return FALSE;
}

//
WSACleanup();
return TRUE;

}

BOOL CWarehouseClientApp::NetworkPrint(CString tText, CString tPrinterShare)
{
//
BOOL aRetVal = TRUE;
// create file name
CString aFileName = _T("\\Temp\\report.prn");
// open the file
FILE *aFile = NULL;
aFile = _tfopen(aFileName, _T("wt"));
//
if(aFile == NULL)
{
aRetVal = FALSE;
}
else
{
// put the text
_fputts(tText, aFile);
// close the file
fclose(aFile);
// copy file to network share
if(CopyFile(aFileName, tPrinterShare, FALSE) == FALSE)
{
AfxMessageBox(_T("Failed to Print to Network Shared Printer"),
MB_ICONEXCLAMATION);
aRetVal = FALSE;
}
}
//
return aRetVal;
}
Arturo LS
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Arturo Lopesoria wrote:
Antonio:
He leído ya cada uno de los distintos protocolos disponibles para IRDA. Hasta donde he podido entender el código siguiente debe funcionar. Sólo necesitaría de tu ayuda para ponerlo de manera adecuada usando las sentencias de BEGIN..PRAGMA dump.
Saludos. He Aquí:
Además en el mismo foro, este código ha sido comentado y aparentemente mejorado: (Agradecería sus comentarios)

Looks pretty much the right sort of thing to me.

Except... Have you tried printing a large amount of text? I would expect
that after 10 or 10's of KB of data the data transfer will stop and will
never restart on that connection. This is explained, and fixed, in #1.
There is also a code simplification, see #2. There are other things in the
code that could be tidied up too, including that I'm not sure why you set
the linger mode to the 'abort/discard' mode.

Anyway:
1. Change the socket to use IrLMP

IrLPT uses IrLMP alone (note that the IAS attribute name used is,
"IrDA:IrLMP:LsapSel") and not also the usual TinyTP layer. The code you
have posted does not enable IrLMP mode. This has two effects. Firstly
there is a extra byte (the TinyTP header) being sent to the printer in each
packet of data, it will luckily be zero in most cases--which for text only
printing will likely be ignored.

However in the reverse direction the PPC is using a credit based protocol
(TinyTP) but the printer is not, and is therefore not advancing credits.
The PPC will eventually run out of credit and stop sending data.

To fix this add a setsockopt ( IRLMP_IRLPT_MODE ) after you create the
socket, immediately after the socket creation would be easiest.

See
http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813385

2. The IAS_QUERY does not need to be explicit

Connecting to a service name requires: 1) looking up the service name to
find the 'port number' then, 2) connecting to the port number. Your code
does this explicitly, however connect() will do both if it is given the
service name.

See
http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813377

Only do this after you've done step 1... You can remove all the code from
"memcpy(&pIASQuery->irdaDeviceID" all the way through to "// Establish a
connection". Then change the line:
memcpy (iraddr.irdaServiceName, szServiceName,
strlen(szServiceName) + 1);
to
memcpy (iraddr.irdaServiceName, "IrLPT", 6);

Let me know how that works out.

[...]

So for step 2, instead of:

>> memcpy(&pIASQuery->irdaDeviceID, devList.Device[0].irdaDeviceID, 4);
>> memcpy(&pIASQuery->irdaClassName, "IrLPT", 6);
>> memcpy(&pIASQuery->irdaAttribName, "IrDA:IrLMP:LsapSel", 19);
>>
>> if (getsockopt(sock, SOL_IRLMP, IRLMP_IAS_QUERY, (char *)pIASQuery,
>> &IASQueryLen) == SOCKET_ERROR)
[...]

>> sprintf(szServiceName, "LSAP-SEL%d",
>> pIASQuery->irdaAttribute.irdaAttribInt);
[quoted text clipped - 6 lines]
>>
>> // Establish a connection to the socket.

Use the following:

memset(&iraddr, 0, sizeof(iraddr));
iraddr.irdaAddressFamily = AF_IRDA;
memcpy (iraddr.irdaDeviceID, devList.Device[0].irdaDeviceID, 4);
memcpy (iraddr.irdaServiceName, "IrLPT", 6);

// Establish a connection to the socket.

Signature


Alan J. McFarlane
http://homepage.ntlworld.com/alanjmcf/
Please follow-up in the newsgroup for the benefit of all.


Reply to this Message KS - 25 Mar 2004 19:12 GMT
Thanks for the updates, I'll incorporate them and test them.

I had to set the linger mode because for some reason the ONeil printer
wouldn't disconnect properly and would print a "** VOID ** VOID ** VOID **
VOID **" after I printed. The manufacturer said that it does this if the
socket wasn't closed properly. From what I can tell the SO_LINGER makes the
data transfer wait since it's set to 1 (true) and the timeout is set to 0.

Thanks,
KS


> > PS.. Let me know if you have any comments either :)
> >
[quoted text clipped - 25 lines]
>
> See

http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813385


> 2. The IAS_QUERY does not need to be explicit
>
[quoted text clipped - 4 lines]
>
> See

http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813377


> Only do this after you've done step 1... You can remove all the code from
> "memcpy(&pIASQuery->irdaDeviceID" all the way through to "// Establish a
[quoted text clipped - 35 lines]
>
> // Establish a connection to the socket.
Reply to this Message KS - 25 Mar 2004 21:43 GMT
Actually setting the IRLMP_IRLPT_MODE seems to be causing problems, same
thing with changing the irdaServiceName name.

You're right about the number of bytes, It seems to stop printing after
about 816 characters. Going to do some more digging ....

KS


> > PS.. Let me know if you have any comments either :)
> >
[quoted text clipped - 25 lines]
>
> See

http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813385


> 2. The IAS_QUERY does not need to be explicit
>
[quoted text clipped - 4 lines]
>
> See

http://homepage.ntlworld.com/alanjmcf/c ... ows%20IrDA%
20programming.html#_Toc46813377


> Only do this after you've done step 1... You can remove all the code from
> "memcpy(&pIASQuery->irdaDeviceID" all the way through to "// Establish a
[quoted text clipped - 35 lines]
>
> // Establish a connection to the socket.
Arturo LS
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Arturo,

Aqui tienes el código que he ido ordenando y poniendo en formato que podamos usar desde FWPPC:

Code: Select all

#pragma BEGINDUMP

#include <windows.h>
#include <WinSock2.h>

HB_FUNC( WSASTARTUP )
{
   WORD WSAVerReq = MAKEWORD( 1, 1 );
   WSADATA WSAData;

   if( WSAStartup( WSAVerReq, &WSAData ) != 0 )
   {
      // wrong winsock dlls?
   }
}

SOCKET ServSock;

HB_FUNC( SOCKET )
{
   if( ( ServSock = socket( AF_IRDA, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
   {
      // WSAGetLastError()
   }
}

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

int sizeOfSockAddr;

HB_FUNC( BIND )
{
   SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" };

   if( bind( ServSock, ( const struct sockaddr * ) &ServSockAddr,
             sizeof( SOCKADDR_IRDA ) ) == SOCKET_ERROR )
   {
      // WSAGetLastError()
   }
}   

HB_FUNC( LISTEN )
{
   if( listen( ServSock, 2 ) == SOCKET_ERROR )
   {
      // WSAGetLastError()
   }
}	

HB_FUNC( ACCEPT )
{
   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
   }
}	

#define BUFF_LEN 4096

int  BytesRead, BytesSent;
char Buffer[ BUFF_LEN ];

HB_FUNC( RECV )
{
   if( ( BytesRead = recv( ServSock, 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
   }
}

HB_FUNC( SEND )
{
   if( ( BytesSent = send( ServSock, Buffer, sizeof( Buffer ), 0 ) ) == SOCKET_ERROR )
   {
      // WSAGetLastError()
   }
   // check that BytesSent == sizeof(Buffer)
}		

HB_FUNC( CLOSESOCKET )
{
   if( closesocket( ServSock ) == SOCKET_ERROR )
   {
      // WSAGetLastError()
   }
}	

#pragma ENDDUMP
Compila bien a excepción de PeerSockAddr, que no se aún de donde lo obtiene exactamente
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Al final del texto él muestra dos ejemplos un un servidor IrComm y de un cliente IrComm, pero usa datos que no están declarados en el texo.

Tampoco he podido acceder a las direcciones de las páginas que has facilitado. Solo he podido revisar el documento Word que me has enviado por email:

Code: Select all

#pragma BEGINDUMP

#include <windows.h>
#include <WinSock2.h>

#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 9wire 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 via 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 9wire 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 9wire 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
}

#pragma ENDDUMP
Que es IAS_SET ? De donde lo obtiene ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Esta es la primera función que has localizado y creo que es la que tiene más posibilidades de funcionar bien. No le falta nada:
http://www.pocketpcjunkies.com/Uwe/Foru ... nting-FREE

Code: Select all

#include "FWCE.ch"

function Main()

   IrdaPrint( "Hello World!" )

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>

#define _WIN32_WCE 

#include <WinSock2.h>
#include <af_irda.h>

#define NUMRETRY 10 // No está definido en el ejemplo. Usamos 10 a ver que tal

HB_FUNC( IRDAPRINT ) // cText
{
   SOCKET   sock;           // Socket bound to the server
   DEVICELIST  devList;     // Device list
   int    iCount = 0,       // Number of retries
          index = 0,        // Integer index
          iDevListLen = sizeof(devList);  // Size of the device list
   TCHAR    szError[ 100 ]; // Error message string
   WSADATA   wsaData;
   WORD    wVersion = MAKEWORD( 1, 1 );  // Winsock Version 1.1
   BYTE    IASQueryBuff[ sizeof( IAS_QUERY ) - 3 + IAS_MAX_ATTRIBNAME ];
   int    IASQueryLen = sizeof( IASQueryBuff );
   PIAS_QUERY  pIASQuery = ( PIAS_QUERY ) &IASQueryBuff;
   char    szServiceName[ 12 ];
   SOCKADDR_IRDA iraddr;
   struct linger   l;   

   if( WSAStartup( wVersion, &wsaData ) != 0 )
   {
      wsprintf( szError, TEXT( "WSAStartup failed. Error: %d" ),
                WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "error" ), 0 );
      return;
   }
   
   // Create a socket that is bound to the server.
   if( ( sock = socket( AF_IRDA, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
   {
      wsprintf( szError, TEXT( "Allocating socket failed. Error: %d" ),
                WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "error" ), 0 );
      WSACleanup();
      return;
   }

   // Initialize the number of devices to zero.
   devList.numDevice = 0;

   while( ( devList.numDevice == 0 ) && ( iCount <= NUMRETRY ) )
   {
      // Retrieve the socket option
      if( getsockopt( sock, SOL_IRLMP, IRLMP_ENUMDEVICES, ( char * ) &devList,
                      &iDevListLen) == SOCKET_ERROR )
      {
         wsprintf( szError, TEXT( "Server could not be located, getsockopt failed. Error: %d"), WSAGetLastError() );
         MessageBox( 0, szError, TEXT( "Error" ), 0 );
         closesocket( sock );
         WSACleanup();
         return;
      }
      if( devList.numDevice == 0 )
      {
         iCount++;
         Sleep( 1000 );
      }
   }

   if( iCount > NUMRETRY )
   {
      MessageBox( 0, TEXT( "Server could not be located!" ),  TEXT( "Error" ), 0 );
      closesocket( sock );
      WSACleanup();
      return;
   }

   memcpy( &pIASQuery->irdaDeviceID, devList.Device[ 0 ].irdaDeviceID, 4 );
   memcpy( &pIASQuery->irdaClassName,  "IrLPT", 6 );
   memcpy( &pIASQuery->irdaAttribName, "IrDA:IrLMP:LsapSel", 19 );

   if( getsockopt( sock, SOL_IRLMP, IRLMP_IAS_QUERY, ( char * ) pIASQuery,
                   &IASQueryLen) == SOCKET_ERROR )
   {
      wsprintf( szError, TEXT( "getsockopt failed. Error: %d" ), WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "Error" ), 0 );
      closesocket( sock );
      WSACleanup();
      return;
   }

   sprintf( szServiceName, "LSAP-SEL%d", pIASQuery->irdaAttribute.irdaAttribInt );

   memset( &iraddr, 0, sizeof( iraddr ) );
   iraddr.irdaAddressFamily = AF_IRDA;
   memcpy( iraddr.irdaDeviceID, devList.Device[ 0 ].irdaDeviceID, 4 );
   memcpy( iraddr.irdaServiceName, szServiceName, strlen( szServiceName ) + 1 );

   // Establish a connection to the socket.
   if( connect( sock, ( struct sockaddr * ) &iraddr, sizeof( iraddr ) ) == SOCKET_ERROR )
   {
      wsprintf( szError, TEXT( "Connecting to the server failed. Error: %d" ), WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "Error" ), MB_OK );
      closesocket( sock );
      WSACleanup();
      return;
   }
   
   // Turn on SO_LINGER
   l.l_onoff = 1;
   l.l_linger = 0;
   if( setsockopt( sock, SOL_SOCKET, SO_LINGER, ( char * ) &l, 
                   sizeof( struct linger ) ) == SOCKET_ERROR )
   {
      wsprintf( szError, TEXT( "setsockopt failed. Error: %d" ), WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "Error" ), MB_OK );
      closesocket( sock );
      WSACleanup();
      return;
   }
   
   // Send a string from the client socket to the server socket.
   if( send( sock, hb_parc( 1 ), hb_parclen( 1 ) + 1, 0 ) == SOCKET_ERROR )
   {
      wsprintf( szError, TEXT( "Sending data to the server failed. Error: %d" ),
                WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "Error" ), MB_OK );
      closesocket( sock );
      WSACleanup();
      return;
   }

   // Close the socket.
   if( closesocket( sock ) == SOCKET_ERROR )
   {
      wsprintf( szError, TEXT( "closesocket failed. Error: %d" ),
                WSAGetLastError() );
      MessageBox( 0, szError, TEXT( "Error" ), 0 );
      WSACleanup();
      return;
   }

   WSACleanup();
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply