rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
rlsiemenstcp.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rlsiemenstcp.cpp - description
3  -------------------
4  begin : Mon Mar 08 2004
5  copyright : (C) 2004 by R. Lehrig
6  email : lehrig@t-online.de
7 
8  S7_200 update : Wed Mar 21 2007
9  copyright : (C) 2007 by Aljosa Merljak
10  Email : aljosa.merljak@datapan.si
11  ***************************************************************************/
12 
13 /***************************************************************************
14  * *
15  * This library is free software; you can redistribute it and/or modify *
16  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
17  * published by the Free Software Foundation *
18  * *
19  ***************************************************************************/
20 
21 #include "rlsiemenstcp.h"
22 #include "rlwthread.h"
23 #include "rlcutil.h"
24 #include <stdio.h>
25 #include <string.h>
26 #define TIMEOUT 2000
27 #define ISO_PORT 102
28 
29 extern int rlDebugPrintfState;
30 
31 rlSiemensTCP::rlSiemensTCP(const char *a, int _plc_type, int _fetch_write, int _function, int _rack_slot)
32  :rlSocket(a,ISO_PORT,1)
33 {
34  plc_type = _plc_type;
35  fetch_write = _fetch_write;
36  function = _function;
37  rack_slot = _rack_slot;
38  //doConnect();
39  use_cb = 0;
40  unsigned char connect_block[22];
41  getDefaultConnectBlock(connect_block);
42  memcpy(cb,connect_block,sizeof(cb));
43 }
44 
46 {
48 }
49 
50 int rlSiemensTCP::getDefaultConnectBlock(unsigned char *connect_block)
51 {
52  static const unsigned char default_connect_block[] =
53  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,0 ,1 ,0xC0,1,9};
54  memcpy(connect_block,default_connect_block,sizeof(default_connect_block));
55  return 22;
56 }
57 
58 int rlSiemensTCP::setConnectBlock(const unsigned char *connect_block)
59 {
60  memcpy(cb,connect_block,sizeof(cb));
61  use_cb = 1;
62  return 0;
63 }
64 
65 int rlSiemensTCP::getConnectBlock(unsigned char *connect_block)
66 {
67  memcpy(connect_block,cb,sizeof(cb));
68  return 0;
69 }
70 
72 {
73  int i,i2,ret,length;
74  static const unsigned char s7_200_connect_block[] =
75  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,'M','W',0xC2,2,'M','W',0xC0,1,9};
76  static const unsigned char s7_300_connect_block[] =
77  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,1 ,2 ,0xC0,1,9};
78  static const unsigned char s7_400_connect_block[] =
79  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,1 ,3 ,0xC0,1,9};
80  static const unsigned char s7_1200_connect_block[] =
81  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,1 ,0 ,0xC0,1,9};
82  static const unsigned char other_connect_block[] =
83  {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,0 ,1 ,0xC0,1,9};
84  unsigned char connect_block[22];
85 
86  unsigned char connect_block2[] =
87  {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};
88  unsigned char buf[512];
89 
90  if(use_cb)
91  {
92  memcpy(connect_block,cb,sizeof(cb));
93  }
94  else
95  {
96  if (plc_type == S7_200) memcpy(connect_block,s7_200_connect_block,sizeof(connect_block));
97  else if(plc_type == S7_300) memcpy(connect_block,s7_300_connect_block,sizeof(connect_block));
98  else if(plc_type == S7_400) memcpy(connect_block,s7_400_connect_block,sizeof(connect_block));
99  else if(plc_type == S7_1200) memcpy(connect_block,s7_1200_connect_block,sizeof(connect_block));
100  else memcpy(connect_block,other_connect_block,sizeof(connect_block));
101 
102  // according to an unproofen theory siemens chooses the TSAP as follows
103  // connect_block[17] = 2; Function (1=PG,2=OP,3=Step7Basic)
104  // connect_block[18] = upper_3_bit_is_rack / lower_5_bit_is_slot
105  // Hint: use tcpdump to figure it out (host = ip_adr of your PLC)
106  // tcpdump -A -i eth0 -t -q -s 0 "host 192.168.1.14 && port 102"
107  if(function != -1) connect_block[17] = function;
108  if(rack_slot != -1) connect_block[18] = rack_slot;
109  }
110 
111  for(i=0; i<3; i++)
112  {
113  if(rlSocket::connect() >= 0)
114  {
115  // exchange TSAP
116  rlDebugPrintf("write connect_block\n");
117  rlSocket::write(connect_block,sizeof(connect_block));
118  ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
119  rlDebugPrintf("read ih ret=%d\n",ret);
120  if(ret <= 0) { rlSocket::disconnect(); continue; }
121  length = ih.length_high*256 + ih.length_low;
122  rlDebugPrintf("read buf length=%d\n",length);
123  ret = rlSocket::read(buf,length-sizeof(ih),TIMEOUT);
124  rlDebugPrintf("read buf ret=%d\n",ret);
125  if(ret <= 0) { rlSocket::disconnect(); continue; }
126  if(length == 22)
127  {
128  for(i2=0; i2<3; i2++)
129  {
130  rlDebugPrintf("write connect_block2\n");
131  rlSocket::write(connect_block2,sizeof(connect_block2));
132  ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
133  rlDebugPrintf("read2 ih ret=%d\n",ret);
134  length = ih.length_high*256 + ih.length_low;
135  rlDebugPrintf("read2 buf length=%d\n",length);
136  ret = rlSocket::read(buf,length-sizeof(ih),TIMEOUT);
137  rlDebugPrintf("read2 buf ret=%d\n",ret);
138  if(ret <= 0) { rlSocket::disconnect(); continue; }
139  if(ret > 0)
140  {
141  rlDebugPrintf("connect success\n");
142  return;
143  }
144  }
146  return;
147  }
148  }
149  else
150  {
151  rlsleep(100);
152  rlDebugPrintf("connect failed\n");
153  }
154  }
155 }
156 
158 {
159  int ret;
160  switch(org)
161  {
162  case ORG_DB: ret = 0x84; break; //[10] Datenbaustein
163  case ORG_M: ret = 0x83; break; //[10] Merker
164  case ORG_E: ret = 0x81; break; //[10] Eingang
165  case ORG_A: ret = 0x82; break; //[10] Ausgang
166  case ORG_PEPA: ret = 0x80; break; //[10] Peripheral Area R/W [tested by VSA]
167  case ORG_Z: ret = 0x84; break; //[10] not tested
168  case ORG_T: ret = 29; break; //[10] Timer
169  default: return 0x83; break;
170  }
171  return ret;
172 }
173 
174 int rlSiemensTCP::write(int org, int dbnr, int start_adr, int len, const unsigned char *buf, int function)
175 {
176  int i,ibuf,ret,len_byte,length;
177  if(rlSocket::isConnected() == 0) doConnect();
178  if(rlSocket::isConnected() == 0) return -1;
179 
180  len_byte = len;
181  if(len_byte > (int) sizeof(pdu)) return -1;
182  //if(org == ORG_DB) len_byte *= 2;
183  //if(org == ORG_Z) len_byte *= 2;
184  //if(org == ORG_T) len_byte *= 2;
185 
186  if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
187  {
188  rlDebugPrintf("using fetch_write\n");
189  length = sizeof(ih) + sizeof(wh) + len_byte;
190  unsigned char total_buf[sizeof(ih) + sizeof(wh) + sizeof(pdu)];
191  ih.version = 3;
192  ih.reserved = 0;
193  ih.length_high = length / 256;
194  ih.length_low = length & 0x0ff;
195  wh.ident[0] = 'S';
196  wh.ident[1] = '5';
197  wh.header_len = 16;
198  wh.ident_op_code = 1;
199  wh.op_code_len = 3;
200  wh.op_code = 3;
201  wh.ident_org_block = 3;
202  wh.len_org_block = 8;
203  wh.org_block = (unsigned char) org;
204  wh.dbnr = (unsigned char) dbnr;
205  wh.start_adr[0] = (unsigned char) start_adr / 256;
206  wh.start_adr[1] = (unsigned char) start_adr & 0x0ff;;
207  wh.len[0] = (unsigned char) len / 256;
208  wh.len[1] = (unsigned char) len & 0x0ff;;
209  wh.spare1 = 0x0ff;
210  wh.spare1_len = 2;
211  memcpy(total_buf, &ih, sizeof(ih));
212  memcpy(total_buf+sizeof(ih), &wh, sizeof(wh));
213  memcpy(total_buf+sizeof(ih)+sizeof(wh), buf, len_byte);
214  ret = rlSocket::write(total_buf, sizeof(ih)+sizeof(wh)+len_byte);
215  rlDebugPrintf("write total_buf ret=%d\n",ret);
216  if(ret < 0) return ret;
217  /*
218  ret = rlSocket::write(&ih,sizeof(ih));
219  rlDebugPrintf("write ih ret=%d\n",ret);
220  if(ret < 0) return ret;
221  ret = rlSocket::write(&wh,sizeof(wh));
222  rlDebugPrintf("write wh ret=%d\n",ret);
223  if(ret < 0) return ret;
224  ret = rlSocket::write(buf,len_byte);
225  rlDebugPrintf("write buf ret=%d\n",ret);
226  if(ret < 0) return ret;
227  */
228  ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
229  rlDebugPrintf("read ih ret=%d\n",ret);
230  if(ret <= 0) return ret;
231  ret = rlSocket::read(&wa,sizeof(wa),TIMEOUT);
232  rlDebugPrintf("read wa ret=%d\n",ret);
233  if(ret <= 0) return ret;
234  if(wa.error_block != 0) return -1;
235  }
236  else
237  {
238  rlDebugPrintf("not using fetch_write\n");
239  i = 0;
240  pdu[i++] = 0x02;
241  pdu[i++] = 0xF0;
242  pdu[i++] = 0x80;
243  pdu[i++] = 0x32;
244  pdu[i++] = 0x01;
245  pdu[i++] = 0x00;
246  pdu[i++] = 0x00;
247  pdu[i++] = 0x00;
248  pdu[i++] = 0x00;
249  pdu[i++] = 0x00;
250  // The S7 update by Aljosa Merljak was tested on S7_200 only
251  // You could set your plc_type to S7_200 also, even if you have S7_300 || S7_400
252  // But only the else part has been tested with S7_300 and S7_400 up to now
253  //if(plc_type == S7_200)
254  // Hi Ken, currently only S7_200 was tested with this. But try if this also works with S7_400
255  if(plc_type >0) // works for all known plc_type == S7_200 || plc_type == S7_300 || plc_type == S7_400)
256  {
257  ret = 0;
258  switch(function)
259  {
260  case WriteBit: ret = write_bit (i, org, dbnr, start_adr, len, buf); break;
261  case WriteByte: ret = write_byte (i, org, dbnr, start_adr, len, buf); break;
262  }
263  if(ret < 0) return ret;
264  }
265  else // will only work for WriteByte with len_byte = 4
266  {
267  pdu[i++] = 0x0E;
268  pdu[i++] = 0x00;
269  pdu[i++] = 0x08;
270  pdu[i++] = 0x05; //0 write
271  pdu[i++] = 0x01; //1
272  pdu[i++] = 0x12; //2
273  pdu[i++] = 0x0A; //3
274  pdu[i++] = 0x10; //4
275  pdu[i++] = 0x02; //5
276  pdu[i++] = len_byte / 256; //6 0x00;
277  pdu[i++] = len_byte & 0x0ff; //7 0x04;
278  pdu[i++] = dbnr / 256; //8 0x00;
279  pdu[i++] = dbnr & 0x0ff; //9 0x00;
280  pdu[i++] = getOrg(org); //10
281  pdu[i++] = ((start_adr*8)/0x010000) & 0x0ff; //0x00; // [11] start adr/bits
282  pdu[i++] = ((start_adr*8)/0x0100) & 0x0ff; //0x00; // [12] start adr/bits
283  pdu[i++] = (start_adr*8) & 0x0ff; //0x00; // [13] start adr/bits
284  pdu[i++] = 0x00;
285  pdu[i++] = 0x04;
286  pdu[i++] = 0x00;
287  pdu[i++] = 0x20;
288  for(ibuf=0; ibuf<len_byte; ibuf++)
289  {
290  pdu[i++] = buf[ibuf];
291  if(i > (int) sizeof(pdu)) return -1;
292  }
293  }
294  ret = write_iso(pdu,i);
295  if(ret < 0) return ret;
296  ret = read_iso(pdu);
297  if(ret < 0) return ret;
298  if(pdu[15] != 0x05) return -1;
299  if(pdu[16] != 0x01) return -1;
300 
301  // CODE from Víctor Centelles
302  if(pdu[17] != 0xff)
303  {
304  if(pdu[17] == 0x0a){
305  fprintf( stderr, " > Error: Trying to access a DB that does not exist\n");
306  fprintf( stderr, "          Please, check that DB is set.   (error code: 10 (0x0a))\n");
307  return -(pdu[17]);
308  }
309  else if(pdu[17] == 0x05){
310  fprintf(stderr, " > Error: Trying to access an address that does not exist.\n");
311  fprintf(stderr, "          Please, check the address range. (error code: 5 (0x05))\n");
312  return -(pdu[17]);
313  }
314  else if(pdu[17] == 0x07){
315  fprintf(stderr, " > Error: the write data size doesn't fit item size\n"); // NO TESTED!!!
316  fprintf(stderr, "          Please, check the data size.     (error code: 7 (0x07))\n");
317  return -(pdu[17]);
318  }
319  else{
320  fprintf(stderr, " > Error: unknown error  (código %x!=0xff)\n", pdu[17]);
321  return -(pdu[17]);
322  }
323  }
324  }
325 
326  return len_byte;
327 }
328 
329 int rlSiemensTCP::write_bit(int& i, int org, int dbnr, int start_adr, int len, const unsigned char *buf)
330 {
331  int j;
332  pdu[i++] = 14 + 12 * (len - 1);
333  pdu[i++] = 0x00;
334  pdu[i++] = 6 * len - 1;
335  pdu[i++] = 0x05;
336  pdu[i++] = len;
337  for(j=0; j<len; j++)
338  {
339  pdu[i++] = 0x12;
340  pdu[i++] = 0x0a;
341  pdu[i++] = 0x10;
342  pdu[i++] = 0x01;
343  pdu[i++] = len / 256; //6 0x00;
344  pdu[i++] = 0x01; //7 number of bytes in group
345  pdu[i++] = dbnr / 256; //8 0x00;
346  pdu[i++] = dbnr & 0x0ff; //9 0x00;
347  pdu[i++] = getOrg(org); //10
348  pdu[i++] = ((start_adr / 8)/0x010000) & 0x0ff;
349  pdu[i++] = (start_adr / 0x0100) & 0x0ff; //0x00; // [12] start adr/bits
350  pdu[i++] = (start_adr + j) & 0x0ff; //0x00; // [13] start adr/bits
351  }
352  for(j=0; j<len; j++)
353  {
354  pdu[i++] = 0x00;
355  pdu[i++] = 0x03;
356  pdu[i++] = 0x00;
357  pdu[i++] = 0x01;
358  pdu[i++] = (buf[j]>0) ? 0x01 : 0x00;
359  if(j < len - 1 ) pdu[i++] = 0x00;
360  if(i > (int) sizeof(pdu)) return -1;
361  }
362  return i;
363 }
364 
365 int rlSiemensTCP::write_byte(int& i, int org, int dbnr, int start_adr, int len, const unsigned char *buf)
366 {
367  pdu[i++] = 0x0e;
368  pdu[i++] = 0x00;
369  pdu[i++] = 5 + len - 1;
370  pdu[i++] = 0x05;
371  pdu[i++] = 0x01;
372  pdu[i++] = 0x12;
373  pdu[i++] = 0x0a;
374  pdu[i++] = 0x10;
375  pdu[i++] = 0x02;
376  pdu[i++] = len / 256; //6 0x00;
377  pdu[i++] = len & 0x0ff; //7 number of bytes
378  pdu[i++] = dbnr / 256; //8 0x00;
379  pdu[i++] = dbnr & 0x0ff; //9 0x00;
380  pdu[i++] = getOrg(org); //10
381  pdu[i++] = start_adr /0x10000 & 0x0ff;
382  pdu[i++] = ((start_adr*8)/0x0100) & 0x0ff; //0x00; // [12] start adr/bits
383  pdu[i++] = (start_adr*8) & 0x0ff; //0x00; // [13] start adr/bits
384  pdu[i++] = 0x00;
385  pdu[i++] = 0x04;
386  pdu[i++] = (len * 8) / 256;
387  pdu[i++] = (len * 8) & 0xff;
388  for(int ibuf=0; ibuf<len; ibuf++)
389  {
390  pdu[i++] = buf[ibuf];
391  if(i > (int) sizeof(pdu)) return -1;
392  }
393  return i;
394 }
395 
396 int rlSiemensTCP::fetch(int org, int dbnr, int start_adr, int len, unsigned char *buf)
397 {
398  int i,ret,len_byte,length;
399 
400  if(rlSocket::isConnected() == 0) doConnect();
401  if(rlSocket::isConnected() == 0) return -1;
402 
403  len_byte = len;
404  //if(org == ORG_DB) len_byte *= 2;
405  //if(org == ORG_Z) len_byte *= 2;
406  //if(org == ORG_T) len_byte *= 2;
407 
408  if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
409  {
410  length = sizeof(ih) + sizeof(fh);
411  ih.version = 3;
412  ih.reserved = 0;
413  ih.length_high = length / 256;
414  ih.length_low = length & 0x0ff;
415  fh.ident[0] = 'S';
416  fh.ident[1] = '5';
417  fh.header_len = 16;
418  fh.ident_op_code = 1;
419  fh.op_code_len = 3;
420  fh.op_code = 5;
421  fh.ident_org_block = 3;
422  fh.len_org_block = 8;
423  fh.org_block = (unsigned char) org;
424  fh.dbnr = (unsigned char) dbnr;
425  fh.start_adr[0] = (unsigned char) start_adr / 256;
426  fh.start_adr[1] = (unsigned char) start_adr & 0x0ff;;
427  fh.len[0] = (unsigned char) len / 256;
428  fh.len[1] = (unsigned char) len & 0x0ff;;
429  fh.spare1 = 0x0ff;
430  fh.spare1_len = 2;
431  unsigned char total_buf[sizeof(ih)+sizeof(fh)];
432  memcpy(total_buf, &ih, sizeof(ih));
433  memcpy(total_buf+sizeof(ih), &fh, sizeof(fh));
434  ret = rlSocket::write(total_buf, sizeof(ih)+sizeof(fh));
435  rlDebugPrintf("fetch write ih ret=%d\n",ret);
436  if(ret < 0) return ret;
437  /*
438  ret = rlSocket::write(&ih,sizeof(ih));
439  rlDebugPrintf("fetch write ih ret=%d\n",ret);
440  if(ret < 0) return ret;
441  ret = rlSocket::write(&fh,sizeof(fh));
442  rlDebugPrintf("fetch write fh ret=%d\n",ret);
443  if(ret < 0) return ret;
444  */
445  ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
446  rlDebugPrintf("fetch read ih ret=%d\n",ret);
447  if(ret <= 0) return ret;
448  ret = rlSocket::read(&fa,sizeof(fa),TIMEOUT);
449  rlDebugPrintf("fetch read fa ret=%d\n",ret);
450  if(ret <= 0) return ret;
451  if(fa.error_block != 0) return -1;
452  ret = rlSocket::read(buf,len_byte,TIMEOUT);
453  rlDebugPrintf("fetch read buf ret=%d\n",ret);
454  if(ret <= 0) return ret;
455  }
456  else
457  {
458  rlDebugPrintf("fetch:starting org=%d dbnr=%d start_adr=%d len=%d\n", org, dbnr, start_adr, len);
459  i = 0;
460  pdu[i++] = 0x02; // [0]
461  pdu[i++] = 0xF0; // [0]
462  pdu[i++] = 0x80; // [0]
463  pdu[i++] = 0x32; // [0]
464  pdu[i++] = 0x01; // [0]
465  pdu[i++] = 0x00; // [0]
466  pdu[i++] = 0x00; // [0]
467  pdu[i++] = 0x00; // [0]
468  pdu[i++] = 0x00; // [0]
469  pdu[i++] = 0x00; // [0]
470  pdu[i++] = 0x0E; // [0]
471  pdu[i++] = 0x00; // [0]
472  pdu[i++] = 0x00; // [0]
473  pdu[i++] = 0x04; // [0] read
474  pdu[i++] = 0x01; // [1]
475  pdu[i++] = 0x12; // [2]
476  pdu[i++] = 0x0A; // [3]
477  pdu[i++] = 0x10; // [4]
478  pdu[i++] = 0x02; // [5]
479  pdu[i++] = len_byte / 256; //0x00; // [6] len/bytes
480  pdu[i++] = len_byte & 0x0ff; //0x40; // [7] len/bytes
481  pdu[i++] = dbnr / 256; //0x00; // [8] dbnum
482  pdu[i++] = dbnr & 0x0ff; //0x01; // [9] dbnum
483  pdu[i++] = getOrg(org); //10
484  pdu[i] = ((start_adr*8)/0x010000) & 0x0ff; //0x00; // [11] start adr/bits
485  if (plc_type == S7_200) pdu[i] = start_adr / 0x10000;
486  i++;
487  pdu[i++] = ((start_adr*8)/0x0100) & 0x0ff; //0x00; // [12] start adr/bits
488  pdu[i++] = (start_adr*8) & 0x0ff; //0x00; // [13] start adr/bits
489  ret = write_iso(pdu,i);
490  if(ret < 0)
491  {
492  rlDebugPrintf("fetch:write_iso error ret==%d -> return -1\n", ret);
493  return ret;
494  }
495  ret = read_iso(pdu);
496  if(ret < 0)
497  {
498  rlDebugPrintf("fetch:read_iso error ret==%d -> return -1\n", ret);
499  return ret;
500  }
501  if(pdu[15] != 0x04)
502  {
503  rlDebugPrintf("fetch:pdu[15]=%d is not equal 0x04-> return -1\n", pdu[15]);
504  return -1;
505  }
506  if(pdu[16] != 0x01)
507  {
508  rlDebugPrintf("fetch:pdu[16]=%d is not equal 0x04-> return -1\n", pdu[16]);
509  return -1;
510  }
511  i = 21;
512  if(ret < i+len_byte) return -1;
513  for(int ibuf = 0; ibuf < len_byte; ibuf++)
514  {
515  buf[ibuf] = pdu[i++];
516  }
517  }
518  rlDebugPrintf("fetch:success len_byte=%d\n", len_byte);
519 
520  return len_byte;
521 }
522 
523 int rlSiemensTCP::read_iso(unsigned char *buf)
524 {
525  int i,ret,len;
526 
527  ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
528  if(ret < 0)
529  {
530  rlDebugPrintf("read_iso:failure to read iso header ret=%d -> disconnecting\n", ret);
532  return ret;
533  }
534  if(ih.version != 3)
535  {
536  rlDebugPrintf("read_iso:header vesion mismatch version==%d -> disconnecting\n", ret);
538  return -1;
539  }
540  len = ih.length_high*256 + ih.length_low - 4;
541  if(len <= 0)
542  {
543  rlDebugPrintf("read_iso:len==%d from iso header is negative -> disconnecting\n", len);
545  return -1;
546  }
547  if(len > (int) sizeof(pdu))
548  {
549  rlDebugPrintf("read_iso:len==%d from iso header is larger than max PDU size -> disconnecting\n", len);
551  return -1;
552  }
553  ret = rlSocket::read(buf,len,TIMEOUT);
554  if(ret < 0)
555  {
556  rlDebugPrintf("read_iso:read buf got timeout -> disconnecting\n");
558  return ret;
559  }
560  if(rlDebugPrintfState != 0)
561  {
562  ::printf("read_iso() len=%d\n", len);
563  for(i=0; i<len; i++) ::printf("%02x,",buf[i]);
564  ::printf("\n");
565  }
566  return len;
567 }
568 
569 int rlSiemensTCP::write_iso(unsigned char *buf, int len)
570 {
571  int i,ret;
572 
573  if(len > (int) sizeof(pdu)) return -1;
574  if(rlSocket::isConnected() == 0) doConnect();
575  if(rlSocket::isConnected() == 0) return -1;
576 
577  // speedup siemens communication as suggested by Vincent Segui Pascual
578  // do only 1 write
579  unsigned char total_buf[sizeof(ih)+sizeof(pdu)];
580  ih.version = 3;
581  ih.reserved = 0;
582  ih.length_high = (len+4) / 256;
583  ih.length_low = (len+4) & 0x0ff;
584  memcpy(total_buf, &ih, sizeof(ih));
585  memcpy(total_buf + sizeof(ih), buf, sizeof(ih)+len);
586  ret = rlSocket::write(total_buf, sizeof(ih)+len);
587  if(ret < 0)
588  {
589  rlDebugPrintf("write_iso:failure to write buf -> disconnecting\n");
591  return ret;
592  }
593 /*
594  ih.version = 3;
595  ih.reserved = 0;
596  ih.length_high = (len+4) / 256;
597  ih.length_low = (len+4) & 0x0ff;
598  ret = rlSocket::write(&ih,sizeof(ih));
599  if(ret < 0)
600  {
601  rlDebugPrintf("write_iso:failure to write iso header -> disconnecting\n");
602  rlSocket::disconnect();
603  return ret;
604  }
605  ret = rlSocket::write(buf,len);
606  if(ret < 0)
607  {
608  rlDebugPrintf("write_iso:failure to write buf -> disconnecting\n");
609  rlSocket::disconnect();
610  return ret;
611  }
612 */
613  if(rlDebugPrintfState != 0)
614  {
615  ::printf("write_iso() len=%d\n", len);
616  for(i=0; i<len; i++) ::printf("%02x,",buf[i]);
617  ::printf("\n");
618  }
619  return len;
620 }