liblnp.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // $HeadURL: file:///s:/svn/lego_programs/lib/liblnp/liblnp.cpp $
00003 // revision  $LastChangedRevision: 2 $ at $LastChangedDate: 2006-01-24 18:20:16 +0100 (Tue, 24 Jan 2006) $
00004 //------------------------------------------------------------------------------
00005 
00006 //                  LIBLNP
00007 //                  ======
00008 //
00009 //a library that can be linked to your application making it capable of
00010 //sending and receiving messages according the LNP protocol
00011 //
00012 //This is the a port of the linux liblnp source code to windows. The
00013 //interface file is exactly the same. The only difference is that there
00014 //is no support for tcp/ip. Therefore it is not necessary to have a separate 
00015 //lnpd daemon running. All you have to do is :
00016 //  - make a C++ project (C projects do not compile because C++ code
00017 //    is called to communicate with the com port)
00018 //  - add the  liblnp.cpp and liblnp.h file to your visual C++ project
00019 //  - include the liblnp.h header file into the file where you want to
00020 //    give lnp commands.
00021 //
00022 //For usage see the LNP documentation. ( a good start is the Documentation
00023 //of Mike Ash at : http://legos.sourceforge.net/HOWTO/x405.html and the general 
00024 //documentation from Martin Cornelius on the winlnp website
00025 //http://www.geocities.com/winlnp/doclnp.html )
00026 //
00027 //There is an alternative for this implementation which is the winlnp project
00028 //at http://www.geocities.com/winlnp/. But I prefer this implementation because
00029 //it maintains the same interface as on linux.
00030 
00031 //
00032 //SUCCESS!!
00033 //
00034 // =======================================================================
00035 //#include "stdafx.h"
00036 
00037 #include <cstdio>
00038 #include <ctime>
00039 #include <atlbase.h>
00040 
00041 #include "liblnp.h"
00042 
00043 
00044 // =======================================================================
00045 
00046 // DEBUGGING PARAMETERS
00047 #define DEBUGLNP 0
00048 #define LNPCHECKSOMSTOP 0
00049 #define LNPBLOCK 0
00050 
00051 // =======================================================================
00052 
00053 // lnp parameters
00054 #define DEFAULT_LNP_ADDR 0x80
00055 #define DEFAULT_LNP_MASK 0xf0
00056 #define MAX_LNP_PACKET (256+3)
00057 
00058 // Infraredtower parameters 
00059 #define TOWER_KEEP_ALIVE_CHAR   0xFF
00060 #define TOWER_KEEP_ALIVE_DELAY   2000 //ms
00061 
00062 // comport parameters
00063 //#define BAUDRATE   2400
00064 #define BAUDRATE   4800
00065 #define STOPBITS   0  // 1 stopbit
00066 #define PARITY     0  // no parity
00067 #define BYTESIZE   8  // read per 8 bits synchroon  ( bits arive at fixed time intervals )
00068 // read the separate bytes asynchroon (bytes are at random time intervals)        
00069 
00070 // Com timings 
00071 #define READTIMEOUT 2000 // package reading timeout in milliseconds
00072 // packages of 250 bytes take 1500 milliseconds
00073 #define AFTERWRITESLEEPTIME 500 // time to sleep after write :
00074 // to give incoming messages also sometime to
00075 // be handled (when having many writes after each other)
00076 // REMARK :  the package which is written to the tower will be send by the tower, but\
00077 //           ALSO will be send back to the pc. ( needed for correct broadcast!!)
00078 //           Therefore sending many packages will generate the same packages on the input
00079 //           which may delve the packages of others!!!
00080 
00081 
00082 // =======================================================================
00083 // LNP variables
00084 
00085 static unsigned char lnp_host_address;
00086 static unsigned char lnp_host_mask;
00087 static unsigned char lnp_port_mask;
00088 
00089 static int connected=0;
00090 static int lnp_stop=0;
00091 
00092 static lnp_tx_result tx_result;
00093 
00094 static unsigned char lnp_buffer[MAX_LNP_PACKET];
00095 
00096 static lnp_integrity_handler_t integrity_handler;
00097 static lnp_addressing_handler_t addressing_handler[256];
00098 
00099 // states for the integrity layer state machine
00100 typedef enum lnp_integrity_state_t
00101 {
00102     LNPwaitHeader,
00103     LNPwaitLength,
00104     LNPwaitData,
00105     LNPwaitCRC
00106 } lnp_integrity_state_t;
00107 
00108 // the integrity layer state 
00109 static lnp_integrity_state_t lnp_integrity_state=LNPwaitHeader;
00110 
00111 
00112 // =======================================================================
00113 // Com variables
00114 
00115 static CComAutoCriticalSection crit_sect;   // protected area for locking
00116 static HANDLE comHandle=NULL;                    // communication port file handle
00117 static HANDLE h_KeepAliveComThread;
00118 static HANDLE h_ComReaderThread;
00119 static char *ComPort="com1";              // com1 or com2 ; default com1
00120 static char *USBPort="\\\\.\\legotower1";
00121 
00122 static BOOL UseUSB = true;
00123 
00124 // =======================================================================
00125 
00126 
00127 static time_t stoptime=-1;  // to see how long you are already reading a 
00128                             // package -> prevent too long reading !!
00129 
00130 // =======================================================================
00131 
00132 
00133 // compute checksum of lnp packet
00134 
00135 static unsigned char 
00136 lnp_checksum( const unsigned char *data, unsigned length )
00137 {
00138     unsigned char a = 0xff;
00139     unsigned char b = 0xff;
00140 
00141     while (length > 0) 
00142     {
00143         a = a + *data;
00144         b = b + a;
00145         data++;
00146         length--;
00147     }
00148 
00149     return a + (b << 8);
00150 }
00151 
00152 
00153 
00154 static void 
00155 block_rcv(void)
00156 {
00157     crit_sect.Lock();
00158 }
00159 
00160 
00161 static void 
00162 unblock_rcv(void)
00163 {
00164     crit_sect.Unlock();
00165 }
00166 
00167 
00168 
00169 void 
00170 lnp_shutdown(void)
00171 {
00172     block_rcv();
00173     connected = 0;
00174     lnp_stop=1;
00175     lnp_integrity_state=LNPwaitHeader;
00176     unblock_rcv();
00177     DWORD rvalue=0;
00178     GetExitCodeThread(h_ComReaderThread,&rvalue);
00179     while ( rvalue == STILL_ACTIVE ) 
00180     {
00181         GetExitCodeThread(h_ComReaderThread,&rvalue);
00182     };
00183     CloseHandle(h_ComReaderThread);
00184     if( ! UseUSB )
00185     {
00186         GetExitCodeThread(h_KeepAliveComThread,&rvalue);
00187         while ( rvalue == STILL_ACTIVE ) 
00188         {
00189             GetExitCodeThread(h_KeepAliveComThread,&rvalue);
00190         }; 
00191         CloseHandle(h_KeepAliveComThread);
00192     }
00193     lnp_stop=0;
00194     CloseHandle( comHandle );
00195     comHandle=NULL;
00196 }
00197 
00198 
00199 // returns true if communication tower is online, 
00200 // this is to check if you have to run lnp_init
00201 bool lnp_test(void)
00202 {
00203    return ( comHandle != NULL );
00204 }
00205 
00206 
00207 static lnp_tx_result 
00208 lnp_logical_write( unsigned char *data, int length )
00209 {
00210     BOOL fWriteStat;
00211     DWORD nWritten = 0;
00212 
00213     if( ! connected ) 
00214     {
00215         return( TX_ERROR );
00216     }
00217 
00218     // block rcv signal
00219 #if LNPBLOCK
00220     printf("write BLOCK\n");
00221 #endif
00222     block_rcv();
00223 #if LNPBLOCK
00224     printf("write BLOCKED\n");
00225 #endif
00226     // send data
00227     fWriteStat = WriteFile( comHandle, 
00228                             data, 
00229                             (unsigned long)length,
00230                             &nWritten, 
00231                             NULL ); 
00232 #if LNPBLOCK
00233     printf("write UNBLOCK\n");
00234 #endif
00235     unblock_rcv();
00236 
00237     if( !fWriteStat ) 
00238     {
00239         printf("write error\n");
00240         return( TX_ERROR );
00241         // lnp_shutdown();
00242     }
00243 
00244     if( nWritten != (unsigned long) length ) 
00245     {
00246         printf("write error\n");
00247         return( TX_FAILURE );
00248         // lnp_shutdown();
00249     }
00250 
00251     // give incoming messages time to be read
00252     Sleep( AFTERWRITESLEEPTIME );
00253 
00254     return( TX_SUCCESS );
00255 }   
00256 
00257 
00258 lnp_tx_result 
00259 lnp_integrity_write( const unsigned char *data,unsigned char length ) 
00260 {
00261     lnp_buffer[0]=0xf0;
00262     lnp_buffer[1]=length;
00263     memcpy( lnp_buffer+2, data, length );
00264     lnp_buffer[length+2]=(unsigned char) lnp_checksum( lnp_buffer, length+2 );
00265 #if DEBUGLNP
00266     printf("send broadcat package of length %d from this host 0x%02x ",
00267         length,lnp_host_address);
00268 #endif
00269     return( lnp_logical_write( lnp_buffer, length+3 ) );
00270 }
00271 
00272 
00273 lnp_tx_result 
00274 lnp_addressing_write( const unsigned char *data, 
00275                       unsigned char length,
00276                       unsigned char dest,
00277                       unsigned char srcport ) 
00278 {
00279     lnp_buffer[0]=0xf1;
00280     lnp_buffer[1]=length+2;
00281     lnp_buffer[2]=dest;
00282     lnp_buffer[3]=lnp_host_address | (srcport & lnp_port_mask);
00283     memcpy( lnp_buffer+4, data, length );
00284     lnp_buffer[length+4]=(unsigned char) lnp_checksum( lnp_buffer, length+4 );
00285 #if DEBUGLNP
00286     printf("send package of length %d to dest 0x%02x from this host 0x%02x from port 0x%x\n",
00287         length,dest,lnp_host_address,(srcport & lnp_port_mask));
00288 #endif 
00289     return( lnp_logical_write( lnp_buffer, length+5 ) );
00290 }
00291 
00292 
00293 void 
00294 lnp_integrity_set_handler( lnp_integrity_handler_t handler )
00295 {
00296 #if LNPBLOCK
00297     printf( "integrity handler BLOCK\n" );
00298 #endif
00299     block_rcv();
00300 #if LNPBLOCK
00301     printf( "integrity handler BLOCKED\n" );
00302 #endif
00303     integrity_handler = handler;
00304 #if LNPBLOCK
00305     printf( "integrity handler UNBLOCK\n" );
00306 #endif
00307     unblock_rcv();
00308 }
00309 
00310 
00311 void 
00312 lnp_addressing_set_handler( unsigned char port, 
00313                             lnp_addressing_handler_t handler )
00314 {
00315 #if LNPBLOCK
00316     printf( "addressing handler BLOCK\n" );
00317 #endif
00318     block_rcv();
00319 #if LNPBLOCK
00320     printf( "addressing handler BLOCKED\n" );
00321 #endif
00322     addressing_handler[port] = handler;
00323 #if LNPBLOCK
00324     printf( "addressing handler UNBLOCK\n" );
00325 #endif
00326     unblock_rcv();
00327 }
00328 
00329 
00330 
00331 void 
00332 lnp_receive_packet( const unsigned char *data ) 
00333 {
00334     unsigned char header=*(data++);
00335     unsigned char length=*(data++);
00336 
00337 
00338     // only handle non-degenerate packets in boot protocol 0xf0
00339     //
00340     switch(header) 
00341     {
00342     case 0xf0:         // raw integrity layer packet, no addressing.
00343 #if DEBUGLNP
00344         printf("send to integrity handler\n");
00345 #endif 
00346         if( integrity_handler )           
00347         {
00348             integrity_handler(data,length);
00349         }
00350         break;
00351     case 0xf1:         // addressing layer.
00352         
00353 #if DEBUGLNP
00354         printf("send to addressing handler for port %x if hostmatch %02x=%02x&%02x \n",
00355             (*data & lnp_port_mask),lnp_host_address ,*data , lnp_host_mask);
00356 #endif
00357         if( length > 2 ) 
00358         {
00359             unsigned char dest=*(data++);
00360             if( lnp_host_address == (dest & lnp_host_mask)) 
00361             {
00362                 unsigned char port=dest & lnp_port_mask;
00363 
00364                 if(addressing_handler[port]) 
00365                 {
00366                     unsigned char src=*(data++);
00367                     addressing_handler[port](data,length-2,src);
00368                 }
00369             }
00370         }
00371     } // switch(header)
00372 }
00373 
00374 
00375 
00376 // return whether a packet is currently being received
00377 static int 
00378 lnp_integrity_active( void )
00379 {
00380     return( lnp_integrity_state != LNPwaitHeader );
00381 }
00382 
00383 
00384 
00385 // reset the integrity layer on error or timeout.
00386 
00387 static void 
00388 lnp_integrity_reset( void )
00389 {
00390     lnp_integrity_state=LNPwaitHeader;
00391 }
00392 
00393 
00394 // receive a byte, decoding LNP packets with a state machine.
00395 
00396 void 
00397 lnp_integrity_byte(unsigned char b)
00398 {
00399     static unsigned char buffer[MAX_LNP_PACKET];
00400     static int bytesRead,endOfData;
00401 
00402     if( lnp_integrity_state == LNPwaitHeader )
00403     {
00404         bytesRead=0;
00405     }
00406 
00407     buffer[bytesRead++]=b;
00408 
00409     switch( lnp_integrity_state ) 
00410     {
00411     case LNPwaitHeader:
00412     // valid headers are 0xf0 .. 0xf7
00413     // if((b & (unsigned char) 0xf8) == (unsigned char) 0xf0)
00414     // more restricted : the only valid headers are 0xf0 and 0xf1
00415 #if DEBUGLNP
00416         printf("header 0x%02x ",b);
00417 #endif
00418     // b may only be 0xf0 or 0xf1 ( integrity resp adressing packet)
00419         if( (b & (unsigned char) 0xfe) == (unsigned char) 0xf0 )
00420         {
00421             lnp_integrity_state= LNPwaitLength ;
00422 
00423             // set stoptime for which the total packet must be read,
00424             // exceeding this time restarts reading on a new package
00425             stoptime = clock() + CLOCKS_PER_SEC * READTIMEOUT / 1000;
00426 #if DEBUGLNP
00427             printf(" SETTING stoptime %ld at currentime %ld", stoptime,clock());
00428 #endif
00429             // let com port be blocked -> do not unblock : do nothing
00430         } else {
00431             // unblock comport 
00432 #if LNPBLOCK
00433             printf("read UNBLOCK\n");   
00434 #endif
00435             unblock_rcv();
00436         }
00437         break;
00438     case LNPwaitLength:
00439         endOfData=b+2;
00440         lnp_integrity_state=LNPwaitData;
00441 #if DEBUGLNP
00442         printf("\n  length 0x%02x \n",b);
00443         printf(" currentime %ld  stoptime %ld ",clock(),stoptime);
00444 #endif
00445         break;
00446 
00447     case LNPwaitData:
00448         if( bytesRead == endOfData )
00449         {
00450             lnp_integrity_state=LNPwaitCRC;
00451         }
00452 #if DEBUGLNP
00453         printf("data 0x%02x ",b);
00454         printf(" currentime %ld  stoptime %ld ",clock(),stoptime);
00455 #endif
00456         break;
00457 
00458     case LNPwaitCRC:   
00459         if( b == (unsigned char)lnp_checksum(buffer,endOfData) )
00460         {
00461 #if DEBUGLNP
00462             printf( "\n\nCORRECT checksum\n" );
00463             printf( "checksum %02x %d \n", b, b );
00464             printf( "stoptime-currenttime %d \n", (stoptime-clock()) );
00465             printf( "\nreceive packet\n");
00466 #endif
00467 #if LNPCHECKSOMSTOP
00468             getchar( );
00469 #endif   
00470 #if LNPBLOCK
00471             printf( "read UNBLOCK\n" );   
00472 #endif
00473             unblock_rcv( );
00474             lnp_receive_packet( buffer );
00475         } else {
00476 #if DEBUGLNP
00477             printf( "\n\nFALSE checksum\n" );
00478             printf( "checksum %02x %d != %02x %d \n", b, b, lnp_checksum( buffer, endOfData ), lnp_checksum( buffer, endOfData ) );
00479 #endif   
00480 #if LNPCHECKSOMSTOP
00481             getchar( );
00482 #endif
00483 #if LNPBLOCK
00484             printf( "read UNBLOCK\n" );   
00485 #endif
00486             unblock_rcv( );
00487         }
00488         lnp_integrity_reset( );
00489     }
00490 }
00491 
00492 
00493 // Thread to constantly read out the COM port
00494 static DWORD WINAPI 
00495 ComReaderThread(LPVOID pParam)
00496 {
00497     //unsigned char buffer[MAX_LNP_PACKET];
00498     unsigned char recvd_byte;
00499     int totalsleep=0;
00500     DWORD dwRead=0;
00501     BOOL fReadStat;
00502     while( ! lnp_stop ) // read per byte
00503     {
00504         //Sleep(5);
00505         if( lnp_integrity_state==LNPwaitHeader ) 
00506         {
00507 #if LNPBLOCK
00508             printf("read header BLOCK\n");
00509 #endif
00510             block_rcv();
00511 #if LNPBLOCK
00512             printf("read header BLOCKED\n");
00513 #endif
00514         }
00515         
00516         fReadStat = ReadFile( comHandle, 
00517                               &recvd_byte, 
00518                               1, 
00519                               &dwRead, 
00520                               NULL );
00521         
00522         // max sure parameters are reset at beginning new package
00523         if( lnp_integrity_state == LNPwaitHeader ) 
00524         {
00525             stoptime=-1;
00526             totalsleep=0;
00527         }
00528 
00529         if ( fReadStat && (dwRead == 1) ) 
00530         {
00531             lnp_integrity_byte( recvd_byte );
00532             totalsleep=0;
00533         } 
00534 
00535         if ( ! fReadStat ) 
00536         {
00537 #if LNPBLOCK
00538             printf("read header UNBLOCK\n");
00539 #endif
00540             unblock_rcv();
00541 
00542 
00543             //printf(" read error");
00544             // read error -> package probably corrupt, restart
00545             if( lnp_integrity_state != LNPwaitHeader ) 
00546             {
00547                 lnp_integrity_state=LNPwaitHeader;
00548                 totalsleep=0;
00549                 unblock_rcv( );
00550             }
00551             Sleep( 50 );
00552             continue;
00553         }
00554 
00555         if( dwRead == 0 ) 
00556         {
00557             //Sleep(5000000);
00558             //  printf(" currentime %ld ",clock());
00559             if( lnp_integrity_state==LNPwaitHeader ) 
00560             {
00561 #if LNPBLOCK
00562                 printf( "read header UNBLOCK\n" );
00563 #endif
00564                 unblock_rcv( );
00565 
00566                 // no packet yet arrived, -> sleep a while
00567                 // -> active polling for packet every 50 milliseconds
00568                 //    in this sleep time the program can do its thing
00569                 Sleep( 50 );
00570 #if DEBUGLNP
00571                 printf( "sleep 50 , %d ", totalsleep );
00572 #endif
00573                 continue;
00574             } else {
00575                 // we are in the process of reading a packet, what went
00576                 // wrong ?
00577                 // -> reading a packet to fast, that is we were finished 
00578                 //    reading for the next byte arrived ( it it is possible?)
00579                 //   (reading a byte timed out after 20 milliseconds 
00580                 //    see CommTimeOuts.ReadTotalTimeoutConstant in lnp_init())
00581                 // -> therefore we give the next byte extra time
00582 
00583 
00585                 // when nothing is read this thread is waiting 5 milliseconds 
00586                 // for the next byte to arrive  : this can be done 
00587                 //  only for maximal 6 times = 5x6=30 milliseconds
00588                 //  if passed :  reset to start reading a new package
00589                 if( totalsleep > 30 ) 
00590                 {
00591                     lnp_integrity_state=LNPwaitHeader;
00592                     totalsleep=0;
00593 #if DEBUGLNP
00594                     printf( "\n\nREADING SLEEPED TOO LONG\n\n" );
00595 #endif
00596                     unblock_rcv( );
00597                     Sleep( 50 );
00598                 }
00599 
00601                 // reading a package blocks the com port, the com port
00602                 // may not be blocked longer than timeout milliseconds
00603                 time_t currenttime;
00604                 currenttime=clock( ); 
00605 
00606                 //if((stoptime != -1 ) && (currenttime > stoptime))  {
00607                 if(currenttime > stoptime)  
00608                 {
00609                     // receiving message failed within timeout milliseconds
00610                     lnp_integrity_state= LNPwaitHeader;
00611                     // unblock com poort
00612 #if DEBUGLNP
00613                     printf( "\n\nPACKET TAKES TOO LONG : currentime %d  stoptime %d \n\n", currenttime, stoptime );
00614 #endif
00615 #if LNPBLOCK
00616                     printf( "read timeout UNBLOCK\n" );
00617 #endif
00618                     unblock_rcv( );      
00619                     Sleep( 50 );
00620                 }
00621 
00622                 // if all checks PASS : 
00623                 // SLEEP for 5 milliseconds to wait for the next byte
00624 #if DEBUGLNP
00625                 printf( "sleep 5 , %d ", totalsleep );
00626 #endif
00627                 Sleep( 5 );            
00628                 totalsleep=totalsleep+5;
00629                 continue;
00630             }
00631         }     
00632 
00633 
00634 
00635         //   return(1); never stop the thread early (could be blocked!!!
00636     }
00637 
00638     ExitThread( 0 );
00639     // _endthread();
00640     return( 1 );
00641 }
00642 
00643 
00644 
00645 
00646 // Thread to keep COM active listening to infrared signals
00647 static DWORD WINAPI 
00648 KeepAliveComThread(LPVOID pParam)
00649 {
00650     unsigned char cKeepAliveByte = TOWER_KEEP_ALIVE_CHAR;
00651 
00652     while ( ! lnp_stop )
00653     {      
00654 #if DEBUGLNP
00655         printf( "\n\n   TRY to start wakeup tower   \n\n" );
00656 #endif
00657         lnp_logical_write( &cKeepAliveByte, 1 );
00658 #if DEBUGLNP
00659         printf( "\n\n   wakeup tower DONE  \n\n" );
00660 #endif
00661         Sleep( (unsigned long)TOWER_KEEP_ALIVE_DELAY );
00662     }
00663     //_endthread();
00664     ExitThread( 0 );   
00665     return( 1 );
00666 }
00667 
00668 
00669 static int 
00670 lnp_init_com()
00671 {
00672     //   HANDLE comHandle;    global defined   //  communication port file handle
00673     COMMTIMEOUTS CommTimeOuts;   // timeout settings for communication port
00674     DCB dcb;                   // device control block to setup communication port       
00675     BOOL fRetVal;  // some return values from system calls
00676 
00677     // open COMM device
00678     if( ( comHandle = CreateFile( ComPort, 
00679                                   GENERIC_READ | GENERIC_WRITE,
00680                                   0,                    // exclusive access
00681                                   NULL,                 // no security attrs
00682                                   OPEN_EXISTING,
00683                                   FILE_ATTRIBUTE_NORMAL, // |
00684                                   NULL ) ) == INVALID_HANDLE_VALUE )
00685     {
00686         printf( "Cannot open communication port" );
00687         comHandle=NULL;
00688         return( INIT_ERROR );
00689     }
00690 
00691     // setup device : size of input en output buffer
00692     SetupComm( comHandle, 4096, 4096 );
00693 
00694     // purge any information in the buffer : reset buffers for fresh start
00695     PurgeComm( comHandle, 
00696                PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
00697 
00698     //  setting the comm port to receive separate bytes one for one : 
00699     //   - read a byte within timeout of 20 ms
00700     //   - write a package (set of bytes) within timeout of 2000 ms
00701 
00702     // set up timeouts for serial port
00703     CommTimeOuts.ReadIntervalTimeout = 0;  // only read per byte   
00704     CommTimeOuts.ReadTotalTimeoutMultiplier = 0;  //  only read per byte
00705     CommTimeOuts.ReadTotalTimeoutConstant = 20;  //   reading a byte may take maximal 20 ms
00706     CommTimeOuts.WriteTotalTimeoutMultiplier = 0; //  only read per byte
00707     CommTimeOuts.WriteTotalTimeoutConstant = 2000;//  writing a packet (bytestring) may take maximal 2000 ms 
00708     SetCommTimeouts(comHandle, &CommTimeOuts ) ;
00709 
00710     // communication parameters
00711     dcb.DCBlength = sizeof( DCB ) ;
00712     // assign dcb pointer to device control block of comport
00713     GetCommState( comHandle, &dcb ); 
00714 
00715     // set the parameters for dcb
00716     dcb.BaudRate = BAUDRATE;
00717     dcb.ByteSize = BYTESIZE;
00718     dcb.Parity   = PARITY;
00719     dcb.StopBits = STOPBITS;
00720 
00721     fRetVal = SetCommState( comHandle, &dcb );
00722     
00723          // when activating the next line will probably disable
00724     // echoing on a tower on a com port  (however nobody is 
00725     // implementing a wait handler for the events this line
00726     // will disable? -> probably nothing to do with echo
00727     //
00728          //  however I'm pretty sure this is not going to
00729     // disable echoing because echoing is done by the tower's
00730     // hardware and is not done by the local serial driver
00731          // on the pc (turning echoing of is saying to serial
00732          // driver to turn of echoing)
00733          // ( tower on usb port
00734     //  never does this echoing -> usb is already good)
00735  //SetCommMask(comHandle,0) // no more events, terminate pending waits 
00736     
00737          EscapeCommFunction( comHandle, SETDTR );
00738 
00739     if ( ! fRetVal )
00740     {
00741         CloseHandle( comHandle );
00742         comHandle=NULL;
00743         printf( "SetCommState()\n" );
00744         return( INIT_ERROR );
00745     }
00746 
00747     return( INIT_OK );
00748 }
00749 
00750 static int 
00751 lnp_init_usb()
00752 {
00753 
00754     // open COMM device
00755     if( ( comHandle = CreateFile( USBPort, 
00756                                   GENERIC_ALL,
00757                                   0,                    // exclusive access
00758                                   NULL,                 // no security attrs
00759                                   OPEN_EXISTING,
00760                                   FILE_ATTRIBUTE_NORMAL, // |
00761                                   NULL ) ) == INVALID_HANDLE_VALUE )
00762     {
00763         printf( "Cannot open communication port" );
00764         comHandle=NULL;
00765         return( INIT_ERROR );
00766     }
00767 
00768     return( INIT_OK );
00769 }
00770 
00771 
00772 
00773 
00774 static int 
00775 lnp_init_threads( )
00776 {
00777     DWORD dwThreadID;
00778 
00779     // Only use KeepAlive on Serial Tower
00780     if( ! UseUSB )
00781     {
00782         h_KeepAliveComThread = CreateThread( NULL,
00783                                              0,
00784                                              KeepAliveComThread,
00785                                              0,
00786                                              NULL,
00787                                              &dwThreadID );
00788 
00789         if( !h_KeepAliveComThread )
00790         {
00791             return( INIT_ERROR );
00792         }
00793         
00794         SetThreadPriority( h_KeepAliveComThread, THREAD_PRIORITY_HIGHEST );
00795         Sleep( 1000 );
00796     }
00797 
00798     h_ComReaderThread = CreateThread( NULL,
00799                                       0,
00800                                       ComReaderThread,
00801                                       0,
00802                                       NULL,
00803                                       &dwThreadID );   
00804     
00805     if (!h_ComReaderThread) 
00806     {
00807         return( INIT_ERROR );
00808     }
00809 
00810     SetThreadPriority( h_ComReaderThread, THREAD_PRIORITY_ABOVE_NORMAL );
00811     
00812     return( INIT_OK );
00813 }
00814 
00815 
00816 
00817 lnp_init_result 
00818 lnp_init ( char *tcp_hostname, 
00819            unsigned short tcp_port,
00820            unsigned char lnp_address, 
00821            unsigned char lnp_mask, 
00822            int flags )
00823 {   
00824     int returnvalue;
00825     if( lnp_stop ) 
00826     { 
00827         return( INIT_ERROR );
00828     }
00829      
00830 
00831         // check if initialization is already done
00832 
00833     if ( lnp_test() )
00834 
00835         {
00836 
00837                 return( INIT_OK );
00838 
00839         };
00840 
00841 
00842     lnp_host_address = lnp_address ? lnp_address : DEFAULT_LNP_ADDR;
00843     lnp_host_mask = lnp_mask ? lnp_mask : DEFAULT_LNP_MASK;
00844     lnp_port_mask = lnp_host_mask ^ 0xFF;
00845     if( ( lnp_host_address & lnp_host_mask ) != lnp_host_address )
00846     {
00847         return( INIT_BAD_PARAM );
00848     }
00849 
00850     lnp_integrity_state=LNPwaitHeader;
00851     connected = 1;
00852 
00853     // determine USB or COM
00854     char *rcxtty = getenv( "RCXTTY" );
00855 
00856     UseUSB = ( strcmpi( rcxtty, "COM" ) != 0 );
00857     
00858         
00859     if( UseUSB )
00860     {
00861         returnvalue = lnp_init_usb( );
00862     } else {
00863         returnvalue = lnp_init_com( );
00864     }
00865 
00866 
00867     // if port not connected
00868     if( returnvalue != INIT_OK )
00869     {
00870         lnp_shutdown( );
00871         return( INIT_ERROR );
00872     }
00873 
00874     returnvalue = lnp_init_threads( );
00875 
00876     // if threads not started
00877 
00878     if( returnvalue != INIT_OK )
00879     {
00880         lnp_shutdown();
00881         return( INIT_ERROR );
00882     }
00883 
00884     return( INIT_OK );
00885 }
00886 
00887 

Generated on Wed Nov 29 01:27:41 2006 by  doxygen 1.4.6