Subversion Repositories HomeAutomation

Rev

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

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