Subversion Repositories HomeAutomation

Rev

Rev 889 | Rev 935 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 889 Rev 907
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
 
2
 
3
# 
3
# 
4
# for use with serial ports, install module with apt-get install libdevice-serialport-perl
4
# for use with serial ports, install module with apt-get install libdevice-serialport-perl
5
# 
5
# 
6
# 
6
# 
7
# 
7
# 
8
 
8
 
9
 
9
 
10
$hubport = 1200;
10
$hubport = 1200;
11
#$udpip = "193.11.254.22";
11
#$udpip = "193.11.254.22";
12
#$udpport = 1100;
12
#$udpport = 1100;
13
 
13
 
14
 
14
 
15
require 5.002;
15
require 5.002;
16
use IO::Socket;
16
use IO::Socket;
17
use IO::Select;
17
use IO::Select;
18
use threads;
18
use threads;
19
use Getopt::Long;
19
use Getopt::Long;
-
 
20
 
-
 
21
use POSIX qw(setsid);
20
 
22
 
21
$binaryname = "canDaemon.pl";
23
$binaryname = "canDaemon.pl";
22
if ( @ARGV > 0 ) {
24
if ( @ARGV > 0 ) {
23
    GetOptions( "baudrate=i"    => \$baudarg,   #
25
    GetOptions( "baudrate=i"    => \$baudarg,           #
24
            "server=s"  => \$serverarg,         #
26
            "server=s"  => \$serverarg,         #
25
            "port=i"    => \$portarg,           #
27
            "port=i"    => \$portarg,           #
26
            "tcpport=i" => \$tcpportarg,        #
28
            "tcpport=i" => \$tcpportarg,        #
27
            "device=s"  => \$devicearg,         #
29
            "device=s"  => \$devicearg,         #
28
            "help"      => \$help,              #
30
            "help"      => \$help,          #
-
 
31
            "xDaemon"   => \$daemon,            #
29
                        );
32
                        );
30
} else {
33
} else {
31
    $help = 1;
34
    $help = 1;
32
}
35
}
33
 
36
 
34
if ($help) {
37
if ($help) {
35
    print "Usage ./$binaryname [options]\n";
38
    print "Usage ./$binaryname [options]\n";
36
    print "Options:\n";
39
    print "Options:\n";
-
 
40
    print "  -x                         Make canDaemon detach as a UNIX daemon\n";
37
    print "  -d <device> (udp or /dev/ttyXYZ)       Choose hardware for communication\n";
41
    print "  -d <device> (udp or /dev/ttyXYZ)       Choose hardware for communication\n";
38
    print "  -b <baudrate>              Baudrate, for serial devices\n";
42
    print "  -b <baudrate>                  Baudrate, for serial devices\n";
39
    print "  -s <server>                    Server, for udp devices\n";
43
    print "  -s <server>                    Server, for udp devices\n";
40
    print "  -p <port>                  Port, for udp devices\n";
44
    print "  -p <port>                  Port, for udp devices\n";
41
    print "  -t <tcpport>                   Port, for tcp server (default 1200)\n";
45
    print "  -t <tcpport>                   Port, for tcp server (default 1200)\n";
42
    print "  -h <help>                  Shows this usage\n";
46
    print "  -h                         Shows this usage\n";
43
    print "\n";
47
    print "\n";
44
    print "example: ./$binaryname -d /dev/ttyUSB0 -b 38400\n";
48
    print "example: ./$binaryname -d /dev/ttyUSB0 -b 38400\n";
45
    print "example: ./$binaryname -d udp -s 192.168.0.10 -p 1100\n";
49
    print "example: ./$binaryname -d udp -s 192.168.0.10 -p 1100\n";
46
 
50
 
47
    exit 0;
51
    exit 0;
48
}
52
}
49
if ($serverarg) {
53
if ($serverarg) {
50
    $udpip = $serverarg;
54
    $udpip = $serverarg;
51
}
55
}
52
#print $udpip;
56
#print $udpip;
53
if ($portarg) {
57
if ($portarg) {
54
    $udpport = $portarg;
58
    $udpport = $portarg;
55
}
59
}
56
if ($tcpportarg) {
60
if ($tcpportarg) {
57
    $hubport = $tcpportarg;
61
    $hubport = $tcpportarg;
-
 
62
}
-
 
63
 
-
 
64
if ($daemon) {
-
 
65
    chdir '/'                 or die "Can't chdir to /: $!";
-
 
66
    umask 0;
-
 
67
    open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
-
 
68
    open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
-
 
69
    #open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
-
 
70
    defined(my $pid = fork)   or die "Can't fork: $!";
-
 
71
    exit if $pid;
-
 
72
    setsid                    or die "Can't start a new session: $!";
58
}
73
}
59
 
74
 
60
$C2SSTARTSTR = 253;
75
$C2SSTARTSTR = 253;
61
$C2SENDSTR = 250;
76
$C2SENDSTR = 250;
62
$C2PINGSTR = 251;
77
$C2PINGSTR = 251;
63
 
78
 
64
### create a tcp server ###
79
### create a tcp server ###
65
$linelength=1000;
80
$linelength=1000;
66
&tcpServerInit;
81
&tcpServerInit;
67
$thr = threads->new(\&tcpServerThread);
82
$thr = threads->new(\&tcpServerThread);
68
$thr->detach;
83
$thr->detach;
69
 
84
 
70
### create a connection to hardware ###
85
### create a connection to hardware ###
71
if ($devicearg) {
86
if ($devicearg) {
72
    if ($devicearg =~ m/^udp$/) {
87
    if ($devicearg =~ m/^udp$/) {
73
        ### if the hardware is an udp node ###
88
        ### if the hardware is an udp node ###
74
        &udpServerInit;
89
        &udpServerInit;
75
        $thr = threads->new(\&udpServerThread);
90
        $thr = threads->new(\&udpServerThread);
76
        $thr->detach;
91
        $thr->detach;
77
    }
92
    }
78
    ### else, the hardware is serial, check for device, this might not work in windows ###
93
    ### else, the hardware is serial, check for device, this might not work in windows ###
79
#   elsif (-e $devicearg) {
94
#   elsif (-e $devicearg) {
80
    else {
95
    else {
81
        if (!$baudarg) {
96
        if (!$baudarg) {
82
            print "For a serial device you need to specifiy baudrate, now using default 19200\n";
97
            print "For a serial device you need to specifiy baudrate, now using default 19200\n";
83
            $baudarg = 19200;
98
            $baudarg = 19200;
84
        }
99
        }
85
       
100
       
86
        eval 'use Device::SerialPort';      ### install module with aptitude install libdevice-serialport-perl
101
        eval 'use Device::SerialPort';      ### install module with aptitude install libdevice-serialport-perl
87
        if ($@) {
102
        if ($@) {
88
            eval 'use Win32::SerialPort';
103
            eval 'use Win32::SerialPort';
89
            if ($@) {
104
            if ($@) {
90
                print "Could not find Device::SerialPort or Win32::SerialPort, I quit.\n";
105
                print "Could not find Device::SerialPort or Win32::SerialPort, I quit.\n";
91
                exit 0;
106
                exit 0;
92
            } else {
107
            } else {
93
                $usingWin32Serial = 1;
108
                $usingWin32Serial = 1;
94
            }
109
            }
95
        } else {
110
        } else {
96
            $usingDeviceSerial = 1;
111
            $usingDeviceSerial = 1;
97
        }
112
        }
98
       
113
       
99
        &serialConnInit;
114
        &serialConnInit;
100
        $thr = threads->new(\&serialConnThread);
115
        $thr = threads->new(\&serialConnThread);
101
        $thr->detach;      
116
        $thr->detach;      
102
    }
117
    }
103
#   } else {
118
#   } else {
104
#       print "Argument $devicearg is not correct\n";
119
#       print "Argument $devicearg is not correct\n";
105
#       exit 0;
120
#       exit 0;
106
#   }
121
#   }
107
}
122
}
-
 
123
 
108
 
124
 
109
### loop here until user aborts with ctrl+c ###
125
### loop here until user aborts with ctrl+c ###
110
while (1) { sleep 1; }
126
while (1) { sleep 1; }
111
 
127
 
112
 
128
 
113
##################### Hardware connection to TCP HUB ############################
129
##################### Hardware connection to TCP HUB ############################
114
sub hardwareConnThread {
130
sub hardwareConnThread {
115
    ### Check for data from HUB ###
131
    ### Check for data from HUB ###
116
    while ( $newmsg = <$hwCremote> ) {
132
    while ( $newmsg = <$hwCremote> ) {
117
        ### Convert to can2serial format ### 
133
        ### Convert to can2serial format ### 
118
        &stringToc2s($newmsg, $retstring);
134
        &stringToc2s($newmsg, $retstring);
119
        if ($retstring) {
135
        if ($retstring) {
120
            #print length($retstring)."\n";
136
            #print length($retstring)."\n";
121
            #&c2sToString($retstring, $newretstring);
137
            #&c2sToString($retstring, $newretstring);
122
            #print "TO SEND: ".$newretstring."\n";
138
            #print "TO SEND: ".$newretstring."\n";
123
            #print $udpCsocket $retstring;
139
            #print $udpCsocket $retstring;
124
           
140
           
125
            ### Send data ###
141
            ### Send data ###
126
            if (length($hardwareSendFunction) > 0) {
142
            if (length($hardwareSendFunction) > 0) {
127
                &{$hardwareSendFunction}($retstring);
143
                &{$hardwareSendFunction}($retstring);
128
            }
144
            }
129
           
145
           
130
        }
146
        }
131
    }  
147
    }  
132
}
148
}
133
 
149
 
134
sub hardwareConnInit {
150
sub hardwareConnInit {
135
    print "Connecting hardware to tcpServer\n";
151
    print "Connecting hardware to tcpServer\n";
136
    $hwCremote = IO::Socket::INET->new(Proto    => "tcp", PeerAddr => "localhost", PeerPort => $hubport,)
152
    $hwCremote = IO::Socket::INET->new(Proto    => "tcp", PeerAddr => "localhost", PeerPort => $hubport,)
137
                  or die "cannot connect to $hubport port at localhost";
153
                  or die "cannot connect to $hubport port at localhost";
138
}
154
}
139
 
155
 
140
##################### Serial Connection ############################
156
##################### Serial Connection ############################
141
sub serialConnThread {
157
sub serialConnThread {
142
    $serialBuffer = "";
158
    $serialBuffer = "";
143
    while(1) {
159
    while(1) {
144
        my ($count,$saw)=$serialPort->read(1); # will read _up to_ 1 chars
160
        my ($count,$saw)=$serialPort->read(1); # will read _up to_ 1 chars
145
        if ($count > 0) {
161
        if ($count > 0) {
146
            $serialBuffer.=$saw;
162
            $serialBuffer.=$saw;
147
            serialConnProcessBuffer($serialBuffer);
163
            serialConnProcessBuffer($serialBuffer);
148
        }
164
        }
149
    }
165
    }
150
}
166
}
151
 
167
 
152
sub serialConnProcessBuffer {
168
sub serialConnProcessBuffer {
153
    my $input = $_[0];
169
    my $input = $_[0];
154
    my $output = $input;
170
    my $output = $input;
155
    my $newmsg;
171
    my $newmsg;
156
    my $retstring;
172
    my $retstring;
157
       
173
       
158
    ### Cut all leading chars that is not a start-char ###
174
    ### Cut all leading chars that is not a start-char ###
159
    for ($i = 0; $i < length($input); $i++) {
175
    for ($i = 0; $i < length($input); $i++) {
160
        if (ord(substr($input, $i, 1)) == $C2SSTARTSTR) {
176
        if (ord(substr($input, $i, 1)) == $C2SSTARTSTR) {
161
            $input = substr($input, $i);
177
            $input = substr($input, $i);
162
            $output = $input;
178
            $output = $input;
163
            #print "debug: cutting character\n";
179
            #print "debug: cutting character\n";
164
            break;
180
            break;
165
        }
181
        }
166
        if (ord(substr($input, $i, 1)) == $C2PINGSTR) {
182
        if (ord(substr($input, $i, 1)) == $C2PINGSTR) {
167
            print "Got pong from hardware\n";
183
            print "Got pong from hardware\n";
168
            $input = substr($input, $i+1);
184
            $input = substr($input, $i+1);
169
            $output = $input;
185
            $output = $input;
170
        }
186
        }
171
    }
187
    }
172
    ### Check for possible complete packets ###
188
    ### Check for possible complete packets ###
173
    for ($i = 0; $i < length($input)-16; $i++) {
189
    for ($i = 0; $i < length($input)-16; $i++) {
174
        my $newmsg = substr($input, $i, 17);
190
        my $newmsg = substr($input, $i, 17);
175
        $retstring = "";
191
        $retstring = "";
176
        &c2sToString($newmsg, $retstring);
192
        &c2sToString($newmsg, $retstring);
177
        if (length($retstring)>0) {
193
        if (length($retstring)>0) {
178
            if ($hwCremote) {
194
            if ($hwCremote) {
179
                ### Send to tcp hub ###
195
                ### Send to tcp hub ###
180
                print $hwCremote $retstring . "\n";
196
                print $hwCremote $retstring . "\n";
181
            }
197
            }
182
            #print $retstring."\n";
198
            #print $retstring."\n";
183
            $output = substr($input, $i+17);
199
            $output = substr($input, $i+17);
184
            $i+=16;
200
            $i+=16;
185
        }
201
        }
186
    }
202
    }
187
   
203
   
188
    ### Store modified buffer ###
204
    ### Store modified buffer ###
189
    $_[0] = $output;
205
    $_[0] = $output;
190
}
206
}
191
 
207
 
192
sub serialConnInit {
208
sub serialConnInit {
193
    print "Connecting to hardware over serial port\n";
209
    print "Connecting to hardware over serial port\n";
194
    $quiet=0;
210
    $quiet=0;
195
    if ($usingDeviceSerial == 1) {
211
    if ($usingDeviceSerial == 1) {
196
        $serialPort = new Device::SerialPort($devicearg, $quiet) || die "failed to open serial port, $devicearg is not valid?";
212
        $serialPort = new Device::SerialPort($devicearg, $quiet) || die "failed to open serial port, $devicearg is not valid?";
197
    } elsif ($usingWin32Serial == 1) {
213
    } elsif ($usingWin32Serial == 1) {
198
        $serialPort = new Win32::SerialPort($devicearg, $quiet) || die "failed to open serial port, $devicearg is not valid?";
214
        $serialPort = new Win32::SerialPort($devicearg, $quiet) || die "failed to open serial port, $devicearg is not valid?";
199
    }
215
    }
200
    $serialPort->databits(8)            || die "failed setting databits";
216
    $serialPort->databits(8)            || die "failed setting databits";
201
    $serialPort->baudrate($baudarg)     || die "failed setting baudrate";
217
    $serialPort->baudrate($baudarg)     || die "failed setting baudrate";
202
    $serialPort->parity("none")         || die "failed setting parity";
218
    $serialPort->parity("none")         || die "failed setting parity";
203
    $serialPort->stopbits(1)            || die "failed setting stopbits";
219
    $serialPort->stopbits(1)            || die "failed setting stopbits";
204
    $serialPort->handshake("none")      || die "failed setting handshake";
220
    $serialPort->handshake("none")      || die "failed setting handshake";
205
    $serialPort->write_settings         || die "no settings";
221
    $serialPort->write_settings         || die "no settings";
206
   
222
   
207
    $serialPort->read_char_time(0);     # don't wait for each character
223
    $serialPort->read_char_time(0);     # don't wait for each character
208
    $serialPort->read_const_time(1000); # 1 second per unfulfilled "read" call
224
    $serialPort->read_const_time(1000); # 1 second per unfulfilled "read" call
209
 
225
 
210
    print "Testing connection to hardware: ping (hardware should answer with a pong)\n";
226
    print "Testing connection to hardware: ping (hardware should answer with a pong)\n";
211
    serialConnSend(chr($C2PINGSTR));
227
    serialConnSend(chr($C2PINGSTR));
212
   
228
   
213
    ### create a connection between the hardware and the tcp-server ###
229
    ### create a connection between the hardware and the tcp-server ###
214
    &hardwareConnInit;
230
    &hardwareConnInit;
215
    $hardwareSendFunction = "serialConnSend";       ### set up callback for a 'send data' function
231
    $hardwareSendFunction = "serialConnSend";       ### set up callback for a 'send data' function
216
    $thr = threads->new(\&hardwareConnThread);
232
    $thr = threads->new(\&hardwareConnThread);
217
    $thr->detach;
233
    $thr->detach;
218
}
234
}
219
 
235
 
220
sub serialConnSend {
236
sub serialConnSend {
221
    $cnt = $serialPort->write($_[0]);
237
    $cnt = $serialPort->write($_[0]);
222
}
238
}
223
 
239
 
224
##################### UDP Connection ############################
240
##################### UDP Connection ############################
225
sub udpServerThread {
241
sub udpServerThread {
226
    $MAXLEN = 1024;
242
    $MAXLEN = 1024;
227
    my $newmsg;
243
    my $newmsg;
228
    my $retstring;
244
    my $retstring;
229
    while ($udpSsocket->recv($newmsg, $MAXLEN)) {
245
    while ($udpSsocket->recv($newmsg, $MAXLEN)) {
230
        my($udpport, $ipaddr) = sockaddr_in($udpSsocket->peername);
246
        my($udpport, $ipaddr) = sockaddr_in($udpSsocket->peername);
231
        $peer_addr = inet_ntoa($ipaddr);
247
        $peer_addr = inet_ntoa($ipaddr);
232
       
248
       
233
        ### check ipaddr to ip in commandlinearg ###
249
        ### check ipaddr to ip in commandlinearg ###
234
        if ($udpip == $peer_addr) {
250
        if ($udpip == $peer_addr) {
235
            #check len of incomming data
251
            #check len of incomming data
236
            if (length($newmsg) > 16 && length($newmsg) < 20) {
252
            if (length($newmsg) > 16 && length($newmsg) < 20) {
237
                $retstring = "";
253
                $retstring = "";
238
                &c2sToString($newmsg, $retstring);
254
                &c2sToString($newmsg, $retstring);
239
                if (length($retstring) > 0 && $hwCremote) {
255
                if (length($retstring) > 0 && $hwCremote) {
240
                    print $hwCremote $retstring . "\n";
256
                    print $hwCremote $retstring . "\n";
241
                }
257
                }
242
            }
258
            }
243
        }
259
        }
244
    }
260
    }
245
   
261
   
246
}
262
}
247
 
263
 
248
sub udpServerInit {
264
sub udpServerInit {
249
    print "Starting udpServer\n";
265
    print "Starting udpServer\n";
250
    $udpSsocket = IO::Socket::INET->new(LocalPort => $udpport, Proto => 'udp')
266
    $udpSsocket = IO::Socket::INET->new(LocalPort => $udpport, Proto => 'udp')
251
        or die "socket: $@";
267
        or die "socket: $@";
252
 
268
 
253
    $udpCsocket = IO::Socket::INET->new(PeerPort => $udpport, Proto => 'udp', PeerAddr => $udpip)
269
    $udpCsocket = IO::Socket::INET->new(PeerPort => $udpport, Proto => 'udp', PeerAddr => $udpip)
254
        or die "socket: $@";
270
        or die "socket: $@";
255
   
271
   
256
    #här ska keep-alive/start-paket skickas till ipt enligt commandline-arg
272
    #här ska keep-alive/start-paket skickas till ipt enligt commandline-arg
257
 
273
 
258
    ### create a connection between the hardware and the tcp-server ###
274
    ### create a connection between the hardware and the tcp-server ###
259
    &hardwareConnInit;
275
    &hardwareConnInit;
260
    $hardwareSendFunction = "udpServerSend";        ### set up callback for a 'send data' function
276
    $hardwareSendFunction = "udpServerSend";        ### set up callback for a 'send data' function
261
    $thr = threads->new(\&hardwareConnThread);
277
    $thr = threads->new(\&hardwareConnThread);
262
    $thr->detach;
278
    $thr->detach;
263
   
279
   
264
}
280
}
265
 
281
 
266
sub udpServerSend {
282
sub udpServerSend {
267
    print $udpCsocket $_[0];
283
    print $udpCsocket $_[0];
268
}
284
}
269
 
285
 
270
##################### TCP HUB ############################
286
##################### TCP HUB ############################
271
sub tcpServerThread {
287
sub tcpServerThread {
272
    while(@ready = $tcpSselect->can_read) {
288
    while(@ready = $tcpSselect->can_read) {
273
        for $tcpSsocket (@ready) {
289
        for $tcpSsocket (@ready) {
274
            if($tcpSsocket == $tcpSlisten) {
290
            if($tcpSsocket == $tcpSlisten) {
275
                &tcpServerConn;
291
                &tcpServerConn;
276
            } else {
292
            } else {
277
                $tcpSsocket->recv($line,$linelength);
293
                $tcpSsocket->recv($line,$linelength);
278
                if ($line eq "") {
294
                if ($line eq "") {
279
                    &tcpServerClientDis;
295
                    &tcpServerClientDis;
280
                } else {
296
                } else {
281
                    $line =~ s/\n.*//gm;    #remove newline and everything after it
297
                    $line =~ s/\n.*//gm;    #remove newline and everything after it
282
                    $line =~ s/\r.*//gm;    #remove linefeed and everything after it
298
                    $line =~ s/\r.*//gm;    #remove linefeed and everything after it
283
                    print "Got packet '".$line."' from client ".$tcpSsocket->fileno."\n";
299
                    print "Got packet '".$line."' from client ".$tcpSsocket->fileno."\n";
284
                   
300
                   
285
                    $rxerror = 0;
301
                    $rxerror = 0;
286
                    testPacket($line, 0, $rxerror);
302
                    testPacket($line, 0, $rxerror);
287
                   
303
                   
288
                    if ($rxerror == 0) {
304
                    if ($rxerror == 0) {
289
                        #Add newline to each packet
305
                        #Add newline to each packet
290
                        $line .= "\n";
306
                        $line .= "\n";
291
                                           
307
                                           
292
                        &tcpServerBroadcastExcept($line, $tcpSsocket);
308
                        &tcpServerBroadcastExcept($line, $tcpSsocket);
293
                    }
309
                    }
294
                }
310
                }
295
            }
311
            }
296
        }
312
        }
297
    }
313
    }
298
}
314
}
299
 
315
 
300
#initiate the tcp server
316
#initiate the tcp server
301
sub tcpServerInit {
317
sub tcpServerInit {
302
    $tcpSlisten = IO::Socket::INET->new(Proto => "tcp", LocalPort => $hubport, Listen => 1, Reuse => 1)
318
    $tcpSlisten = IO::Socket::INET->new(Proto => "tcp", LocalPort => $hubport, Listen => 1, Reuse => 1)
303
                or die $!;
319
                or die $!;
304
 
320
 
305
    $tcpSselect = IO::Select->new($tcpSlisten);
321
    $tcpSselect = IO::Select->new($tcpSlisten);
306
    print "Starting tcpServer\n";
322
    print "Starting tcpServer\n";
307
}
323
}
308
 
324
 
309
#a client connected
325
#a client connected
310
sub tcpServerConn {
326
sub tcpServerConn {
311
    $new = $tcpSlisten->accept;
327
    $new = $tcpSlisten->accept;
312
    $tcpSselect->add($new);
328
    $tcpSselect->add($new);
313
    print $new->fileno . ": connected\n";
329
    print $new->fileno . ": connected\n";
314
}
330
}
315
 
331
 
316
#a client disconnected
332
#a client disconnected
317
sub tcpServerClientDis {
333
sub tcpServerClientDis {
318
    print $tcpSsocket->fileno . ": disconnected\n";
334
    print $tcpSsocket->fileno . ": disconnected\n";
319
    $tcpSselect->remove($tcpSsocket);
335
    $tcpSselect->remove($tcpSsocket);
320
    $tcpSsocket->close;
336
    $tcpSsocket->close;
321
}
337
}
322
 
338
 
323
#subroutine sends data to all connected clients except for one specified 
339
#subroutine sends data to all connected clients except for one specified 
324
sub tcpServerBroadcastExcept {
340
sub tcpServerBroadcastExcept {
325
    my $first = 0;
341
    my $first = 0;
326
    my $data = $_[0];
342
    my $data = $_[0];
327
    my $exception = $_[1];
343
    my $exception = $_[1];
328
    for $eachsocket ($tcpSselect->handles) {
344
    for $eachsocket ($tcpSselect->handles) {
329
        if ($eachsocket==$tcpSlisten) {     #dont send to self
345
        if ($eachsocket==$tcpSlisten) {     #dont send to self
330
            next;
346
            next;
331
        } elsif ($eachsocket==$exception) {     #dont send to the specified exception
347
        } elsif ($eachsocket==$exception) {     #dont send to the specified exception
332
            next;
348
            next;
333
        } else {
349
        } else {
334
            if ($first==0) {
350
            if ($first==0) {
335
                $first = 1;
351
                $first = 1;
336
                print "Sending to client ".$eachsocket->fileno;
352
                print "Sending to client ".$eachsocket->fileno;
337
            } else {
353
            } else {
338
                print ", ".$eachsocket->fileno;
354
                print ", ".$eachsocket->fileno;
339
            }
355
            }
340
            $eachsocket->send($data) or do {
356
            $eachsocket->send($data) or do {
341
                &tcpServerClientDis;
357
                &tcpServerClientDis;
342
            }
358
            }
343
        }
359
        }
344
    }
360
    }
345
    if ($first==1) {
361
    if ($first==1) {
346
        print "\n";
362
        print "\n";
347
    }
363
    }
348
}
364
}
349
 
365
 
350
##################### General functions ############################
366
##################### General functions ############################
351
 
367
 
352
#this function should do a number of tests on $_[0] and print messages if packet is malformed and return 1 in $_[2]
368
#this function should do a number of tests on $_[0] and print messages if packet is malformed and return 1 in $_[2]
353
#messages can be suppressed by having $_[1] as 1
369
#messages can be suppressed by having $_[1] as 1
354
sub testPacket {
370
sub testPacket {
355
    my $input = $_[0];
371
    my $input = $_[0];
356
    my $messages = $_[1];
372
    my $messages = $_[1];
357
   
373
   
358
    #line should be parsed somewhat here, check PKT, AUT and so on
374
    #line should be parsed somewhat here, check PKT, AUT and so on
359
    $testErr = 0;
375
    $testErr = 0;
360
    if (length($input) < 16) {
376
    if (length($input) < 16) {
361
        $testErr = 1;
377
        $testErr = 1;
362
        if ($messages!=1) {print "Packet was malformed, not long enough\n";}
378
        if ($messages!=1) {print "Packet was malformed, not long enough\n";}
363
    }
379
    }
364
    if ($testErr == 0 && substr($input, 0, 4) != "PKT ") {
380
    if ($testErr == 0 && substr($input, 0, 4) != "PKT ") {
365
        $testErr = 1;
381
        $testErr = 1;
366
        if ($messages!=1) {print "Packet was malformed, should start with PKT\n";}
382
        if ($messages!=1) {print "Packet was malformed, should start with PKT\n";}
367
    }
383
    }
368
    #if (substr($line, 12, 1) != " " || substr($line, 14, 1) != " ") {
384
    #if (substr($line, 12, 1) != " " || substr($line, 14, 1) != " ") {
369
    #   $testErr = 1;
385
    #   $testErr = 1;
370
    #   print "Packet was malformed, spaces not in the correct place\n";
386
    #   print "Packet was malformed, spaces not in the correct place\n";
371
    #}
387
    #}
372
    @splitinput = split(/ +/, $input);
388
    @splitinput = split(/ +/, $input);
373
    $inputarrlen = @splitinput;
389
    $inputarrlen = @splitinput;
374
    if ($testErr == 0 && ($inputarrlen < 4 || $inputarrlen > 12)) {
390
    if ($testErr == 0 && ($inputarrlen < 4 || $inputarrlen > 12)) {
375
        $testErr = 1;
391
        $testErr = 1;
376
        if ($messages!=1) {print "Packet was malformed, to many or to few parts\n";}
392
        if ($messages!=1) {print "Packet was malformed, to many or to few parts\n";}
377
    }
393
    }
378
    if ($testErr == 0 && length($splitinput[1]) != 8) {
394
    if ($testErr == 0 && length($splitinput[1]) != 8) {
379
        $testErr = 1;
395
        $testErr = 1;
380
        if ($messages!=1) {print "Packet was malformed, id part must be 8 digits (padded with zeros)\n";}
396
        if ($messages!=1) {print "Packet was malformed, id part must be 8 digits (padded with zeros)\n";}
381
    }
397
    }
382
    if ($testErr == 0 && length($splitinput[2]) != 1) {
398
    if ($testErr == 0 && length($splitinput[2]) != 1) {
383
        $testErr = 1;
399
        $testErr = 1;
384
        if ($messages!=1) {print "Packet was malformed, ext part must be 1 digit\n";}
400
        if ($messages!=1) {print "Packet was malformed, ext part must be 1 digit\n";}
385
    }
401
    }
386
    if ($testErr == 0 && length($splitinput[3]) != 1) {
402
    if ($testErr == 0 && length($splitinput[3]) != 1) {
387
        $testErr = 1;
403
        $testErr = 1;
388
        if ($messages!=1) {print "Packet was malformed, rtr part must be 1 digit\n";}
404
        if ($messages!=1) {print "Packet was malformed, rtr part must be 1 digit\n";}
389
    }
405
    }
390
    for ($i = 4; $i < $inputarrlen; $i++) {
406
    for ($i = 4; $i < $inputarrlen; $i++) {
391
        if ($testErr == 0 && length($splitinput[$i]) != 2) {
407
        if ($testErr == 0 && length($splitinput[$i]) != 2) {
392
            $testErr = 1;
408
            $testErr = 1;
393
            if ($messages!=1) {print "Packet was malformed, data parts must be 2 digits (padded with zero)\n";}
409
            if ($messages!=1) {print "Packet was malformed, data parts must be 2 digits (padded with zero)\n";}
394
        }
410
        }
395
    }
411
    }
396
    $checkstrlen = length($input)-4;
412
    $checkstrlen = length($input)-4;
397
    $checkstr = substr($input, 4, $checkstrlen);
413
    $checkstr = substr($input, 4, $checkstrlen);
398
    if ($testErr == 0 && $checkstr !~ m/^[0-9a-fA-F ]*$/) {
414
    if ($testErr == 0 && $checkstr !~ m/^[0-9a-fA-F ]*$/) {
399
        $testErr = 1;
415
        $testErr = 1;
400
        if ($messages!=1) {print "Packet was malformed, not hex\n";}
416
        if ($messages!=1) {print "Packet was malformed, not hex\n";}
401
    }
417
    }
402
   
418
   
403
    $_[2] = $testErr;
419
    $_[2] = $testErr;
404
}
420
}
405
 
421
 
406
#this function should parse $_[0] (can2serial-data) and save in $_[1] as string
422
#this function should parse $_[0] (can2serial-data) and save in $_[1] as string
407
sub c2sToString {
423
sub c2sToString {
408
    my $input = $_[0];
424
    my $input = $_[0];
409
    my $output = "";
425
    my $output = "";
410
    #if not correct input data, then dont save anything in $_[1]
426
    #if not correct input data, then dont save anything in $_[1]
411
    if (ord(substr($input, 0, 1))==$C2SSTARTSTR && ord(substr($input, 16, 1))==$C2SENDSTR) {
427
    if (ord(substr($input, 0, 1))==$C2SSTARTSTR && ord(substr($input, 16, 1))==$C2SENDSTR) {
412
        #$output = "boundaries=ok ";
428
        #$output = "boundaries=ok ";
413
        $id = ord(substr($input, 1, 1)) + ord(substr($input, 2, 1))*256 + ord(substr($input, 3, 1))*256*256 + ord(substr($input, 4, 1))*256*256*256;
429
        $id = ord(substr($input, 1, 1)) + ord(substr($input, 2, 1))*256 + ord(substr($input, 3, 1))*256*256 + ord(substr($input, 4, 1))*256*256*256;
414
        $ext = ord(substr($input, 5, 1));
430
        $ext = ord(substr($input, 5, 1));
415
        $rtr = ord(substr($input, 6, 1));
431
        $rtr = ord(substr($input, 6, 1));
416
        $dl = ord(substr($input, 7, 1));
432
        $dl = ord(substr($input, 7, 1));
417
        if ($ext < 2 && $rtr < 2 && $dl < 9) {
433
        if ($ext < 2 && $rtr < 2 && $dl < 9) {
418
            $output .= sprintf "%08x ", $id;
434
            $output .= sprintf "%08x ", $id;
419
            $output .= $ext . " " . $rtr;
435
            $output .= $ext . " " . $rtr;
420
            for ($i = 0; $i < $dl; $i++) {
436
            for ($i = 0; $i < $dl; $i++) {
421
                $data = ord(substr($input, 8+$i, 1));
437
                $data = ord(substr($input, 8+$i, 1));
422
                $output .= sprintf " %02x", $data;
438
                $output .= sprintf " %02x", $data;
423
            }
439
            }
424
            $_[1] = "PKT ".$output;
440
            $_[1] = "PKT ".$output;
425
        } else {
441
        } else {
426
            #print "debug: incorrect ext, rtr or dl\n";
442
            #print "debug: incorrect ext, rtr or dl\n";
427
 
443
 
428
        }
444
        }
429
    } else {
445
    } else {
430
        #print "debug: incorrect boundaries\n";
446
        #print "debug: incorrect boundaries\n";
431
 
447
 
432
    }
448
    }
433
}
449
}
434
 
450
 
435
#this function should parse $_[0] (string) and save in $_[1] as can2serial-data
451
#this function should parse $_[0] (string) and save in $_[1] as can2serial-data
436
sub stringToc2s {
452
sub stringToc2s {
437
    my $input = $_[0];
453
    my $input = $_[0];
438
    my $output = "";
454
    my $output = "";
439
    #if not correct input data, then dont save anything in $_[1]
455
    #if not correct input data, then dont save anything in $_[1]
440
    if (length($input) > 15) {
456
    if (length($input) > 15) {
441
        #minor checks, the data from the tcp-server should be valid
457
        #minor checks, the data from the tcp-server should be valid
442
        @splitinput = split(/ +/, $input);
458
        @splitinput = split(/ +/, $input);
443
        $inputarrlen = @splitinput;
459
        $inputarrlen = @splitinput;
444
        if (substr($input, 0, 4) == "PKT " && substr($input, 12, 1) == " " && substr($input, 14, 1) == " " && $inputarrlen > 3 && $inputarrlen < 13) {
460
        if (substr($input, 0, 4) == "PKT " && substr($input, 12, 1) == " " && substr($input, 14, 1) == " " && $inputarrlen > 3 && $inputarrlen < 13) {
445
            $id = hex($splitinput[1]);
461
            $id = hex($splitinput[1]);
446
            $ext = hex($splitinput[2]);
462
            $ext = hex($splitinput[2]);
447
            $rtr = hex($splitinput[3]);
463
            $rtr = hex($splitinput[3]);
448
            @data = @splitinput[4..($inputarrlen-1)];
464
            @data = @splitinput[4..($inputarrlen-1)];
449
            $dl = @data;
465
            $dl = @data;
450
           
466
           
451
            $output .= chr($C2SSTARTSTR);
467
            $output .= chr($C2SSTARTSTR);
452
            $output .= chr($id & 0xff);
468
            $output .= chr($id & 0xff);
453
            $output .= chr(($id>>8) & 0xff);
469
            $output .= chr(($id>>8) & 0xff);
454
            $output .= chr(($id>>16) & 0xff);
470
            $output .= chr(($id>>16) & 0xff);
455
            $output .= chr(($id>>24) & 0xff);
471
            $output .= chr(($id>>24) & 0xff);
456
            $output .= chr($ext);
472
            $output .= chr($ext);
457
            $output .= chr($rtr);
473
            $output .= chr($rtr);
458
            $output .= chr($dl);
474
            $output .= chr($dl);
459
            for ($i = 0; $i < 8; $i++) {
475
            for ($i = 0; $i < 8; $i++) {
460
                if ($i < $dl) {
476
                if ($i < $dl) {
461
                    $output .= chr(hex($data[$i]));
477
                    $output .= chr(hex($data[$i]));
462
                } else {
478
                } else {
463
                    $output .= chr(" ");
479
                    $output .= chr(" ");
464
                }
480
                }
465
            }
481
            }
466
            $output .= chr($C2SENDSTR);
482
            $output .= chr($C2SENDSTR);
467
            $_[1] = $output;
483
            $_[1] = $output;
468
        }
484
        }
469
    }
485
    }
470
}
486
}
471
 
487