rllib  1
rlsiemenstcp.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           rlsiemenstcp.cpp  -  description
00003                              -------------------
00004     begin                : Mon Mar 08 2004
00005     copyright            : (C) 2004 by Rainer Lehrig
00006     email                : lehrig@t-online.de
00007 
00008     S7_200 update        : Wed Mar 21 2007
00009     copyright            : (C) 2007 by Aljosa Merljak
00010     Email                : aljosa.merljak@datapan.si
00011  ***************************************************************************/
00012 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This library is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as        *
00017  *   published by the Free Software Foundation                             *
00018  *                                                                         *
00019  ***************************************************************************/
00020 
00021 //
00022 // S7_200 tested
00023 // S7_300 not tested
00024 // S7_400 not tested
00025 // S5     not tested
00026 //
00027 #include "rlsiemenstcp.h"
00028 #include "rlwthread.h"
00029 #include "rlcutil.h"
00030 #include <stdio.h>
00031 #include <string.h>
00032 #define TIMEOUT 2000
00033 #define ISO_PORT 102
00034 
00035 extern int rlDebugPrintfState;
00036 
00037 rlSiemensTCP::rlSiemensTCP(const char *a, int _plc_type, int _fetch_write, int _function, int _rack_slot)
00038              :rlSocket(a,ISO_PORT,1)
00039 {
00040   plc_type = _plc_type;
00041   fetch_write = _fetch_write;
00042   function = _function;
00043   rack_slot = _rack_slot;
00044   doConnect();
00045 }
00046 
00047 rlSiemensTCP::~rlSiemensTCP()
00048 {
00049   rlSocket::disconnect();
00050 }
00051 
00052 void rlSiemensTCP::doConnect()
00053 {
00054   int i,i2,ret,length;
00055   static const unsigned char s7_200_connect_block[] =
00056     {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,'M','W',0xC2,2,'M','W',0xC0,1,9};
00057   static const unsigned char s7_300_connect_block[] =
00058     {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1  ,0  ,0xC2,2,1  ,2  ,0xC0,1,9};
00059   static const unsigned char s7_400_connect_block[] =
00060     {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1  ,0  ,0xC2,2,1  ,3  ,0xC0,1,9};
00061   static const unsigned char other_connect_block[] =
00062     {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1  ,0  ,0xC2,2,0  ,1  ,0xC0,1,9};
00063   unsigned char connect_block[22];
00064 
00065   unsigned char connect_block2[] = 
00066     {0x03,0x00,0x00,0x19,0x02,0xF0,0x80,0x32,0x01,0x00,0x00,0xCC,0xC1,0x00,0x08,0x00,0x00,0xF0,0x00,0x00,0x01,0x00,0x01,0x03,0xC0};  
00067   unsigned char buf[512];
00068 
00069   if     (plc_type == S7_200) memcpy(connect_block,s7_200_connect_block,sizeof(connect_block));
00070   else if(plc_type == S7_300) memcpy(connect_block,s7_300_connect_block,sizeof(connect_block));
00071   else if(plc_type == S7_400) memcpy(connect_block,s7_400_connect_block,sizeof(connect_block));
00072   else                        memcpy(connect_block,other_connect_block,sizeof(connect_block));
00073 
00074   // according to an unproofen theory siemens chooses the TSAP as follows
00075   // connect_block[17] = 2; Function (1=PG,2=OP,3=Step7Basic)
00076   // connect_block[18] = upper_3_bit_is_rack / lower_5_bit_is_slot
00077   // Hint: use tcpdump to figure it out (host = ip_adr of your PLC)
00078   // tcpdump -A -i eth0 -t -q -s 0 "host 192.168.1.14 && port 102"
00079   if(function  != -1) connect_block[17] = function;
00080   if(rack_slot != -1) connect_block[18] = rack_slot;
00081 
00082   for(i=0; i<3; i++)
00083   {
00084     if(rlSocket::connect() >= 0)
00085     {
00086       // exchange TSAP
00087       rlDebugPrintf("write connect_block\n");
00088       rlSocket::write(connect_block,sizeof(connect_block));
00089       ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
00090       rlDebugPrintf("read ih ret=%d\n",ret);
00091       if(ret <= 0) { rlSocket::disconnect(); continue; }
00092       length = ih.length_high*256 + ih.length_low;
00093       rlDebugPrintf("read buf length=%d\n",length);
00094       ret = rlSocket::read(buf,length-sizeof(ih),TIMEOUT);
00095       rlDebugPrintf("read buf ret=%d\n",ret);
00096       if(ret <= 0) { rlSocket::disconnect(); continue; }
00097       if(length == 22)
00098       {
00099         for(i2=0; i2<3; i2++)
00100         {
00101           rlDebugPrintf("write connect_block2\n");
00102           rlSocket::write(connect_block2,sizeof(connect_block2));
00103           ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
00104           rlDebugPrintf("read2 ih ret=%d\n",ret);
00105           length = ih.length_high*256 + ih.length_low;
00106           rlDebugPrintf("read2 buf length=%d\n",length);
00107           ret = rlSocket::read(buf,length-sizeof(ih),TIMEOUT);
00108           rlDebugPrintf("read2 buf ret=%d\n",ret);
00109           if(ret <= 0) { rlSocket::disconnect(); continue; }
00110           if(ret > 0) 
00111           {
00112             rlDebugPrintf("connect success\n");
00113             return;
00114           }  
00115         }
00116         rlSocket::disconnect();
00117         return;
00118       }
00119     }
00120     else
00121     {
00122       rlsleep(100);
00123       rlDebugPrintf("connect failed\n");
00124     }
00125   }
00126 }
00127 
00128 int rlSiemensTCP::getOrg(int org)
00129 {
00130   int ret;
00131   switch(org)
00132   {
00133     case ORG_DB:   ret = 0x84;  break;    //[10] Datenbaustein
00134     case ORG_M:    ret = 0x83;  break;    //[10] Merker
00135     case ORG_E:    ret = 0x81;  break;    //[10] Eingang
00136     case ORG_A:    ret = 0x82;  break;    //[10] Ausgang
00137     case ORG_PEPA: ret = 0x84;  break;    //[10] not tested
00138     case ORG_Z:    ret = 0x84;  break;    //[10] not tested
00139     case ORG_T:    ret = 29;    break;    //[10] Timer
00140     default:       return 0x83; break;
00141   }
00142   return ret;
00143 }
00144 
00145 int rlSiemensTCP::write(int org, int dbnr, int start_adr, int len, const unsigned char *buf, int function)
00146 {
00147   int i,ibuf,ret,len_byte,length;
00148   if(rlSocket::isConnected() == 0) doConnect();
00149   if(rlSocket::isConnected() == 0) return -1;
00150 
00151   len_byte = len;
00152   //if(org == ORG_DB) len_byte *= 2;
00153   //if(org == ORG_Z)  len_byte *= 2;
00154   //if(org == ORG_T)  len_byte *= 2;
00155   
00156   if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
00157   {
00158     rlDebugPrintf("using fetch_write\n");
00159     length = sizeof(ih) + sizeof(wh) + len_byte;
00160     ih.version  = 3;
00161     ih.reserved = 0;
00162     ih.length_high = length / 256;
00163     ih.length_low  = length & 0x0ff;
00164     wh.ident[0]        = 'S';
00165     wh.ident[1]        = '5';
00166     wh.header_len      = 16;
00167     wh.ident_op_code   = 1;
00168     wh.op_code_len     = 3;
00169     wh.op_code         = 3;
00170     wh.ident_org_block = 3;
00171     wh.len_org_block   = 8;
00172     wh.org_block       = (unsigned char) org;
00173     wh.dbnr            = (unsigned char) dbnr;
00174     wh.start_adr[0]    = (unsigned char) start_adr / 256;
00175     wh.start_adr[1]    = (unsigned char) start_adr & 0x0ff;;
00176     wh.len[0]          = (unsigned char) len / 256;
00177     wh.len[1]          = (unsigned char) len & 0x0ff;;
00178     wh.spare1          = 0x0ff;
00179     wh.spare1_len      = 2;
00180     ret = rlSocket::write(&ih,sizeof(ih));
00181     rlDebugPrintf("write ih ret=%d\n",ret);
00182     if(ret < 0) return ret;
00183     ret = rlSocket::write(&wh,sizeof(wh));
00184     rlDebugPrintf("write wh ret=%d\n",ret);
00185     if(ret < 0) return ret;
00186     ret = rlSocket::write(buf,len_byte);
00187     rlDebugPrintf("write buf ret=%d\n",ret);
00188     if(ret < 0) return ret;
00189     ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
00190     rlDebugPrintf("read ih ret=%d\n",ret);
00191     if(ret <= 0) return ret;
00192     ret = rlSocket::read(&wa,sizeof(wa),TIMEOUT);
00193     rlDebugPrintf("read wa ret=%d\n",ret);
00194     if(ret <= 0) return ret;
00195     if(wa.error_block != 0) return -1;
00196   }
00197   else
00198   {
00199     rlDebugPrintf("not using fetch_write\n");
00200     i = 0;
00201     pdu[i++] = 0x02;
00202     pdu[i++] = 0xF0;
00203     pdu[i++] = 0x80;
00204     pdu[i++] = 0x32;
00205     pdu[i++] = 0x01;
00206     pdu[i++] = 0x00;
00207     pdu[i++] = 0x00;
00208     pdu[i++] = 0x00;
00209     pdu[i++] = 0x00;
00210     pdu[i++] = 0x00;
00211     // The S7 update by Aljosa Merljak was tested on S7_200 only
00212     // You could set your plc_type to S7_200 also, even if you have S7_300 || S7_400
00213     // But only the else part has been tested with S7_300 and S7_400 up to now
00214     //if(plc_type == S7_200)
00215     // Hi Ken, currently only S7_200 was tested with this. But try if this also works with S7_400
00216     if(plc_type == S7_200 || plc_type == S7_300 || plc_type == S7_400)
00217     {
00218       ret = 0;
00219       switch(function)
00220       {
00221          case WriteBit:   ret = write_bit  (i, org, dbnr, start_adr, len, buf); break;
00222          case WriteByte:  ret = write_byte (i, org, dbnr, start_adr, len, buf); break;
00223       }
00224       if(ret < 0) return ret;
00225     }
00226     else
00227     {
00228       pdu[i++] = 0x0E;
00229       pdu[i++] = 0x00;
00230       pdu[i++] = 0x08;
00231       pdu[i++] = 0x05; //0 write
00232       pdu[i++] = 0x01; //1
00233       pdu[i++] = 0x12; //2
00234       pdu[i++] = 0x0A; //3
00235       pdu[i++] = 0x10; //4
00236       pdu[i++] = 0x02; //5
00237       pdu[i++] = len_byte / 256;   //6 0x00;
00238       pdu[i++] = len_byte & 0x0ff; //7 0x04;
00239       pdu[i++] = dbnr / 256;       //8 0x00;
00240       pdu[i++] = dbnr & 0x0ff;     //9 0x00;
00241       pdu[i++] = getOrg(org);      //10 
00242       pdu[i++] = ((start_adr*8)/0x010000) & 0x0ff; //0x00;  // [11] start adr/bits
00243       pdu[i++] = ((start_adr*8)/0x0100)   & 0x0ff; //0x00;  // [12] start adr/bits
00244       pdu[i++] =  (start_adr*8)           & 0x0ff; //0x00;  // [13] start adr/bits
00245       pdu[i++] = 0x00;
00246       pdu[i++] = 0x04;
00247       pdu[i++] = 0x00;
00248       pdu[i++] = 0x20;
00249       for(ibuf=0; ibuf<len_byte; ibuf++)
00250       {
00251         pdu[i++] = buf[ibuf];
00252         if(i > (int) sizeof(pdu)) return -1;
00253       }
00254     }  
00255     ret = write_iso(pdu,i);
00256     if(ret < 0) return ret;
00257     ret = read_iso(pdu);
00258     if(ret < 0) return ret;
00259     if(pdu[15] != 0x05) return -1;
00260     if(pdu[16] != 0x01) return -1;
00261 
00262     // CODE from Víctor Centelles
00263     if(pdu[17] != 0xff)
00264     {
00265       if(pdu[17] == 0x0a){
00266         fprintf( stderr, " > Error: Trying to access a DB that does not exist\n");
00267         fprintf( stderr, "          Please, check that DB is set.   (error code: 10 (0x0a))\n");
00268         return -(pdu[17]);
00269       }
00270       else if(pdu[17] == 0x05){
00271         fprintf(stderr, " > Error: Trying to access an address that does not exist.\n");
00272         fprintf(stderr, "          Please, check the address range. (error code: 5 (0x05))\n");
00273         return -(pdu[17]);
00274       }
00275       else if(pdu[17] == 0x07){
00276         fprintf(stderr, " > Error: the write data size doesn't fit item size\n"); // NO TESTED!!!
00277         fprintf(stderr, "          Please, check the data size.     (error code: 7 (0x07))\n");
00278         return -(pdu[17]);
00279       }
00280       else{
00281         fprintf(stderr, " > Error: unknown error  (código %x!=0xff)\n", pdu[17]);
00282         return -(pdu[17]);
00283       }
00284     }
00285   }
00286 
00287   return len_byte;
00288 }
00289 
00290 int rlSiemensTCP::write_bit(int& i, int org, int dbnr, int start_adr, int len, const unsigned char *buf)
00291 {
00292   int j;
00293   pdu[i++] = 14 + 12 * (len - 1);
00294   pdu[i++] = 0x00;
00295   pdu[i++] = 6 * len - 1;
00296   pdu[i++] = 0x05;
00297   pdu[i++] = len;    
00298   for(j=0; j<len; j++)
00299   {
00300     pdu[i++] = 0x12;
00301     pdu[i++] = 0x0a;
00302     pdu[i++] = 0x10;
00303     pdu[i++] = 0x01;
00304     pdu[i++] = len / 256;        //6 0x00;
00305     pdu[i++] = 0x01;             //7 number of bytes in group
00306     pdu[i++] = dbnr / 256;       //8 0x00;
00307     pdu[i++] = dbnr & 0x0ff;     //9 0x00;
00308     pdu[i++] = getOrg(org);      //10 
00309     pdu[i++] = ((start_adr / 8)/0x010000)  & 0x0ff;
00310     pdu[i++] =  (start_adr / 0x0100)       & 0x0ff; //0x00;  // [12] start adr/bits
00311     pdu[i++] =  (start_adr + j)            & 0x0ff; //0x00;  // [13] start adr/bits     
00312   }
00313   for(j=0; j<len; j++)
00314   {
00315     pdu[i++] = 0x00;
00316     pdu[i++] = 0x03;
00317     pdu[i++] = 0x00;
00318     pdu[i++] = 0x01;
00319     pdu[i++] = (buf[j]>0) ? 0x01 : 0x00;
00320     if(j < len - 1 ) pdu[i++] = 0x00;
00321     if(i > (int) sizeof(pdu)) return -1;
00322   }
00323   return i;
00324 }
00325 
00326 int rlSiemensTCP::write_byte(int& i, int org, int dbnr, int start_adr, int len, const unsigned char *buf)
00327 {
00328   pdu[i++] = 0x0e;
00329   pdu[i++] = 0x00;
00330   pdu[i++] = 5 + len - 1;
00331   pdu[i++] = 0x05;
00332   pdu[i++] = 0x01;
00333   pdu[i++] = 0x12;
00334   pdu[i++] = 0x0a;
00335   pdu[i++] = 0x10;
00336   pdu[i++] = 0x02;
00337   pdu[i++] = len / 256;   //6 0x00;
00338   pdu[i++] = len;         //7 number of bytes
00339   pdu[i++] = dbnr / 256;       //8 0x00;
00340   pdu[i++] = dbnr & 0x0ff;     //9 0x00;
00341   pdu[i++] = getOrg(org);      //10 
00342   pdu[i++] =     start_adr/0x10000  & 0x0ff;
00343   pdu[i++] = ((start_adr*8)/0x0100) & 0x0ff; //0x00;  // [12] start adr/bits
00344   pdu[i++] =  (start_adr*8)         & 0x0ff; //0x00;  // [13] start adr/bits     
00345   pdu[i++] = 0x00;
00346   pdu[i++] = 0x04;
00347   pdu[i++] = (len * 8) / 256;
00348   pdu[i++] = (len * 8) & 0xff;
00349   for(int ibuf=0; ibuf<len; ibuf++)
00350   {
00351     pdu[i++] = buf[ibuf];
00352     if(i > (int) sizeof(pdu)) return -1;
00353   }
00354   return i;
00355 }
00356 
00357 int rlSiemensTCP::fetch(int org, int dbnr, int start_adr, int len, unsigned char *buf)
00358 {
00359   int i,ret,len_byte,length;
00360 
00361   if(rlSocket::isConnected() == 0) doConnect();
00362   if(rlSocket::isConnected() == 0) return -1;
00363 
00364   len_byte = len;
00365   //if(org == ORG_DB) len_byte *= 2;
00366   //if(org == ORG_Z)  len_byte *= 2;
00367   //if(org == ORG_T)  len_byte *= 2;
00368 
00369   if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
00370   {
00371     length = sizeof(ih) + sizeof(fh);
00372     ih.version  = 3;
00373     ih.reserved = 0;
00374     ih.length_high = length / 256;
00375     ih.length_low  = length & 0x0ff;
00376     fh.ident[0]        = 'S';
00377     fh.ident[1]        = '5';
00378     fh.header_len      = 16;
00379     fh.ident_op_code   = 1;
00380     fh.op_code_len     = 3;
00381     fh.op_code         = 5;
00382     fh.ident_org_block = 3;
00383     fh.len_org_block   = 8;
00384     fh.org_block       = (unsigned char) org;
00385     fh.dbnr            = (unsigned char) dbnr;
00386     fh.start_adr[0]    = (unsigned char) start_adr / 256;
00387     fh.start_adr[1]    = (unsigned char) start_adr & 0x0ff;;
00388     fh.len[0]          = (unsigned char) len / 256;
00389     fh.len[1]          = (unsigned char) len & 0x0ff;;
00390     fh.spare1          = 0x0ff;
00391     fh.spare1_len      = 2;
00392     ret = rlSocket::write(&ih,sizeof(ih));
00393     rlDebugPrintf("fetch write ih ret=%d\n",ret);
00394     if(ret < 0) return ret;  
00395     ret = rlSocket::write(&fh,sizeof(fh));
00396     rlDebugPrintf("fetch write fh ret=%d\n",ret);
00397     if(ret < 0) return ret;
00398     ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
00399     rlDebugPrintf("fetch read ih ret=%d\n",ret);
00400     if(ret <= 0) return ret;
00401     ret = rlSocket::read(&fa,sizeof(fa),TIMEOUT);
00402     rlDebugPrintf("fetch read fa ret=%d\n",ret);
00403     if(ret <= 0) return ret;
00404     if(fa.error_block != 0) return -1;
00405     ret = rlSocket::read(buf,len_byte,TIMEOUT);
00406     rlDebugPrintf("fetch read buf ret=%d\n",ret);
00407     if(ret <= 0) return ret;
00408   }
00409   else
00410   {
00411     rlDebugPrintf("fetch:starting org=%d dbnr=%d start_adr=%d len=%d\n", org, dbnr, start_adr, len);
00412     i = 0;
00413     pdu[i++] = 0x02;  // [0]
00414     pdu[i++] = 0xF0;  // [0]
00415     pdu[i++] = 0x80;  // [0]
00416     pdu[i++] = 0x32;  // [0]
00417     pdu[i++] = 0x01;  // [0]
00418     pdu[i++] = 0x00;  // [0]
00419     pdu[i++] = 0x00;  // [0]
00420     pdu[i++] = 0x00;  // [0]
00421     pdu[i++] = 0x00;  // [0]
00422     pdu[i++] = 0x00;  // [0]
00423     pdu[i++] = 0x0E;  // [0]
00424     pdu[i++] = 0x00;  // [0]
00425     pdu[i++] = 0x00;  // [0]
00426     pdu[i++] = 0x04;  // [0]  read
00427     pdu[i++] = 0x01;  // [1]
00428     pdu[i++] = 0x12;  // [2]
00429     pdu[i++] = 0x0A;  // [3]
00430     pdu[i++] = 0x10;  // [4]
00431     pdu[i++] = 0x02;  // [5] 
00432     pdu[i++] = len_byte / 256;              //0x00;  // [6]  len/bytes
00433     pdu[i++] = len_byte & 0x0ff;            //0x40;  // [7]  len/bytes
00434     pdu[i++] = dbnr / 256;                  //0x00;  // [8]  dbnum
00435     pdu[i++] = dbnr & 0x0ff;                //0x01;  // [9]  dbnum
00436     pdu[i++] = getOrg(org);                 //10 
00437     pdu[i]   = ((start_adr*8)/0x010000) & 0x0ff; //0x00;  // [11] start adr/bits
00438     if (plc_type == S7_200) pdu[i] = start_adr / 0x10000;
00439     i++;
00440     pdu[i++] = ((start_adr*8)/0x0100)   & 0x0ff; //0x00;  // [12] start adr/bits
00441     pdu[i++] =  (start_adr*8)           & 0x0ff; //0x00;  // [13] start adr/bits
00442     ret = write_iso(pdu,i);
00443     if(ret < 0)
00444     {
00445       rlDebugPrintf("fetch:write_iso error ret==%d -> return -1\n", ret);
00446       return ret;
00447     }  
00448     ret = read_iso(pdu);
00449     if(ret < 0)
00450     {
00451       rlDebugPrintf("fetch:read_iso error ret==%d -> return -1\n", ret);
00452       return ret;
00453     }  
00454     if(pdu[15] != 0x04)
00455     {
00456       rlDebugPrintf("fetch:pdu[15]=%d is not equal 0x04-> return -1\n", pdu[15]);
00457       return -1;
00458     }  
00459     if(pdu[16] != 0x01)
00460     {
00461       rlDebugPrintf("fetch:pdu[16]=%d is not equal 0x04-> return -1\n", pdu[16]);
00462       return -1;
00463     }  
00464     i = 21;
00465     if(ret < i+len_byte) return -1;
00466     for(int ibuf = 0; ibuf < len_byte; ibuf++)
00467     {
00468       buf[ibuf] = pdu[i++];
00469     }
00470   }
00471   rlDebugPrintf("fetch:success len_byte=%d\n", len_byte);
00472 
00473   return len_byte;
00474 }
00475 
00476 int rlSiemensTCP::read_iso(unsigned char *buf)
00477 {
00478   int i,ret,len;
00479 
00480   ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
00481   if(ret < 0)                
00482   { 
00483     rlDebugPrintf("read_iso:failure to read iso header ret=%d -> disconnecting\n", ret);
00484     rlSocket::disconnect(); 
00485     return ret; 
00486   }
00487   if(ih.version != 3)
00488   { 
00489     rlDebugPrintf("read_iso:header vesion mismatch version==%d -> disconnecting\n", ret);
00490     rlSocket::disconnect(); 
00491     return -1;  
00492   }
00493   len = ih.length_high*256 + ih.length_low - 4;
00494   if(len <= 0)                
00495   { 
00496     rlDebugPrintf("read_iso:len==%d from iso header is negative -> disconnecting\n", len);
00497     rlSocket::disconnect(); 
00498     return -1;  
00499   }
00500   if(len > (int) sizeof(pdu))
00501   { 
00502     rlDebugPrintf("read_iso:len==%d from iso header is larger than max PDU size -> disconnecting\n", len);
00503     rlSocket::disconnect(); 
00504     return -1;  
00505   }
00506   ret = rlSocket::read(buf,len,TIMEOUT);
00507   if(ret < 0)                 
00508   { 
00509     rlDebugPrintf("read_iso:read buf got timeout -> disconnecting\n");
00510     rlSocket::disconnect(); 
00511     return ret; 
00512   }
00513   if(rlDebugPrintfState != 0)
00514   {
00515     ::printf("read_iso() len=%d\n", len);
00516     for(i=0; i<len; i++) ::printf("%02x,",buf[i]);
00517     ::printf("\n");
00518   }
00519   return len;
00520 }
00521 
00522 int rlSiemensTCP::write_iso(unsigned char *buf, int len)
00523 {
00524   int i,ret;
00525 
00526   if(rlSocket::isConnected() == 0) doConnect();
00527   if(rlSocket::isConnected() == 0) return -1;
00528   ih.version  = 3;
00529   ih.reserved = 0;
00530   ih.length_high = (len+4) / 256;
00531   ih.length_low  = (len+4) & 0x0ff;
00532   ret = rlSocket::write(&ih,sizeof(ih));
00533   if(ret < 0)
00534   { 
00535     rlDebugPrintf("write_iso:failure to write iso header -> disconnecting\n");
00536     rlSocket::disconnect(); 
00537     return ret; 
00538   }  
00539   ret = rlSocket::write(buf,len);
00540   if(ret < 0)
00541   { 
00542     rlDebugPrintf("write_iso:failure to write buf -> disconnecting\n");
00543     rlSocket::disconnect(); 
00544     return ret; 
00545   }
00546   if(rlDebugPrintfState != 0)
00547   {
00548     ::printf("write_iso() len=%d\n", len);
00549     for(i=0; i<len; i++) ::printf("%02x,",buf[i]);
00550     ::printf("\n");
00551   }
00552   return len;
00553 }