Impresion via IRDA

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

Post by Arturo Lopesoria »

Gracias Antonio
Ahora mismo las pruebo
Saludos.
Antonio Linares wrote: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
Arturo LS
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Antonio:
Tanto en dispositivo como el emulador marcan el mismo error:
Allocating socket failed Error:10047. No es un error crítico, y en cada intento lo marca.

Alguna Idea?


[quote="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

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

Post by Arturo Lopesoria »

Aparentemente el error corresponde a:
[Error=10047] Address family not supported by protocol family
:(
Arturo Lopesoria wrote:Antonio:
Tanto en dispositivo como el emulador marcan el mismo error:
Allocating socket failed Error:10047. No es un error crítico, y en cada intento lo marca.

Alguna Idea?

Antonio Linares wrote: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

...[/quote][/quote]
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,

Esta es la línea que falla:
if( ( sock = socket( AF_IRDA, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )

a ver que _ ahí...
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Asi es, al abrir el socket, el motivo aparentemente se describe asi:

ERROR: WSAEAFNOSUPPORT 10047

Address family not supported by protocol family.
An address incompatible with the requested protocol was used. All sockets are created with an associated address family (that is, AF_INET for Internet Protocols) and a generic protocol type (that is, SOCK_STREAM). This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto

Ahora mismo estoy incluyendo _ que en el foro de origen hizo AlanMcFlane respecto del protocolo, para atacar todo junto de una vez.
:shock:
Antonio Linares wrote:Arturo,

Esta es la línea que falla:
if( ( sock = socket( AF_IRDA, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )

a ver que _ ahí...
Arturo LS
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Antonio:
Por falta de tiempo se me habia pasado cerrar este asunto del IRDA.
La impresion por IRDA trabaja correctamente con el ejemplo de que hablabamos, unicamente cambie el archivo de cabecera:
wnisock2 por winsock eso fue todo! y asunto solucionado.
Saludos.

Antonio Linares wrote:Arturo,

Esta es la línea que falla:
if( ( sock = socket( AF_IRDA, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )

a ver que _ ahí...
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,

Estupendo, gracias por la información! :-)

Te importaría poner aqui un pequeño ejemplo de prueba, incluyendo el código en C, para que sirva para futuros usuarios ? Gracias!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Arturo Lopesoria
Posts: 84
Joined: Fri Aug 10, 2007 1:47 am
Location: Mexico DF
Contact:

Post by Arturo Lopesoria »

Siguiendo recomendaciones obtenidas en el foro, logre el siguiente ejemplo, que imprime correctamente via IRDA en una impresora EXTECH.

No pude conseguir un protocolo bien estructurado para el control de flujo, pero con el parametro de SleepTime (2000 en el ejemplo) es suficiente para darle tiempo a la impresora de no saturar su buffer de impresion. Si alguien puede contribuir con un control de flujo que permita hacerlo mas robusto a fallas seria magnifico.



#include "FWCE.ch"
*************************************************************************


function Printx(cFile)
local oDlg, cc,


DEFINE DIALOG oDlg RESOURCE "printshow"

cc:=memoread( cFile )

REDEFINE BUTTON ID 105 OF oDlg ; // Imprimir
ACTION ( IrdaPrint( chr(24) + chr(27) + "P" + "#" +;
cc + chr(13) + chr(10), 2000 ) )

ACTIVATE DIALOG oDlg CENTERED
return nil

*************************************************************************
*************************************************************************


#pragma BEGINDUMP
//#pragma comment (lib,"prnIrda")


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

#define _WIN32_WCE
//#define _WIN32_WINDOWS

#include <WinSock.h>
#include <af_irda.h>

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

int fnTest(LPSTR s);

int WSIrdaSend(SOCKET *pSock, char *Buf, int iLen);
int WSSendBlocks(SOCKET *pSock, char *Buf, int iLen, int iTout);


HB_FUNC( XFNTEST )
{
LPSTR lpStr = hb_parc( 1 );
int ret;
ret = 0;
//fnTest(lpStr);
hb_retni( ret );
}



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;
LINGER lingerStruct;
int retries=1, stat_retries;
int stat_connected=0;
fd_set fdread,fdwrite;
int nRet;
unsigned long ul=1;
TIMEVAL tvTimeout ;
int result;


tvTimeout.tv_sec = 0 ;
tvTimeout.tv_usec = 0 ;


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( "Failed to discover devices, Getsockopt failed. Error: %d"), WSAGetLastError() );
MessageBox( 0, szError, TEXT( "Error" ), 0 );
closesocket( sock );
WSACleanup();
return;
}
if( devList.numDevice == 0 )
{
iCount++;
// Sleep( 100 );
}
}

//if( iCount > NUMRETRY )
if( iCount > 0)
{
MessageBox( 0, TEXT( "Server could not be located! The max number of retries were exceded. " ), TEXT( "Error" ), 0 );
closesocket( sock );
WSACleanup();
return;
}else
{
//wsprintf( szError, TEXT( "Addr: %0.2X%0.2X%0.2X%0.2X"), devList.Device[ 0 ].irdaDeviceID[0],devList.Device[ 0 ].irdaDeviceID[1],devList.Device[ 0 ].irdaDeviceID[2],devList.Device[ 0 ].irdaDeviceID[3] );
//MessageBox( 0, szError, TEXT( "About to Connect" ), 0 );
}

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 );



// 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;
}

//CONNECT SOCKET ASYNCHRONOUSLY
Sleep(100);
stat_connected=FALSE;

do{
if( connect( sock, ( struct sockaddr * ) &iraddr, sizeof( iraddr ) ) != SOCKET_ERROR )
{
// At least 1 socket has pending data, in this case only s
MessageBox(0,TEXT("Connected!"),TEXT("Print Irda ExtTech"), MB_OK | MB_APPLMODAL);
stat_connected=TRUE;
}
if (stat_connected==FALSE)
{
// error condition
//MessageBox(0,TEXT("Connect Attempt Failed!"),TEXT("Print Irda ExtTech"), MB_OK | MB_APPLMODAL);
}
}while( (stat_connected==FALSE) && (retries++<=4) );
if (stat_connected==FALSE)
{
MessageBox(0,TEXT("Connect Failed!"),TEXT("Print Irda ExtTech"), MB_OK | MB_APPLMODAL);
return;
}


// Send a string from the client socket to the server socket.
result=WSSendBlocks(&sock,hb_parc( 1 ),hb_parclen( 1 ) + 1, hb_parni(2) );
hb_retni( result );


// 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();
}


int WSSendBlocks(SOCKET *pSock, char *Buf, int iLen, int iTout)
{
TCHAR szError[ 100 ]; // Error message string
int nBlocks;
int nBytes;
int i;
nBlocks=iLen/256;
nBytes=iLen % 256;
for(i=0;i<nBlocks;i++)
{
WSIrdaSend(pSock, Buf + i*256, 256);
//wsprintf( szError, TEXT( "block: %d"),i );
//MessageBox(0,szError,TEXT("Print Irda ExtTech"), MB_OK | MB_APPLMODAL);
Sleep(iTout);
}
if(nBytes!=0)
{
WSIrdaSend(pSock, Buf + nBlocks*256, nBytes);
//wsprintf( szError, TEXT( "bytes: %d"),nBytes);
//MessageBox(0,szError,TEXT("Print Irda ExtTech"), MB_OK | MB_APPLMODAL);
}
return(0);
}


int WSIrdaSend(SOCKET *pSock, char *Buf, int Len)
{
int serr ;
int cbSent = 0 ;
fd_set fdsSend ;
TIMEVAL tvTimeout ;

tvTimeout.tv_sec = 45 ;
tvTimeout.tv_usec = 0 ;

do
{
FD_ZERO( &fdsSend );
FD_SET( *pSock , &fdsSend );

serr = select( 0 , NULL , &fdsSend , NULL , &tvTimeout );
if( serr == SOCKET_ERROR )
{
return(101);
}
else if( serr == 0 )
{
//DEBUGMSG( DF , (TEXT("select(send) timed out. \r\n")));
continue;
}
serr = send( *pSock , Buf + cbSent , Len , 0 );
if( serr != SOCKET_ERROR )
{
Len -= serr ;
cbSent += serr ;
}
else
{
return(102);
}
} while( Len > 0 );

return(0);
}

#pragma ENDDUMP


Antonio Linares wrote:Arturo,

Estupendo, gracias por la información! :-)

Te importaría poner aqui un pequeño ejemplo de prueba, incluyendo el código en C, para que sirva para futuros usuarios ? Gracias!
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,

Muchas gracias! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply