in reply to Re^5: Win32::SerialPort, buffer overflow
in thread Win32::SerialPort, buffer overflow

Hi.

Thanks to NERDVANA and soonix and afoken. With respect to access to the RS232 serial, the module I am accessing is an OBD2 automotive module with a USB to serial chip embedded within a plastic sealed module. The handskaking on the serial port is switched off ("none" as indicated with the serial initialisation). Also, the initialisation also seems to suggest a buffering of 256 bytes in both directions.

I have tried changing the size of the write (shorted and longer) but the issue still follows how the data is written to the sub Serial_TrxRcv($parameter). I have a "yucky" work around where I avoid taking the $ccmd (command) directly from the hash, but copy to a $newcmd variable in a very specific way. This is in the following code presentation.

sub ProcessPIDs { # print "Inside ProcessPIDs \n"; # Process the input arguments my ( $nickname, $ref_nicknametocommand ) = @_; my %InSubNickNameToCommand = %{$ref_nicknametocommand}; # De-ref +rence the reference to an hash my $ccmd; $ccmd = $InSubNickNameToCommand{ $nickname }; # need E +RROR checking here !!!!!! my $newcmd ; if ($ccmd eq '0101') { $newcmd = '0101'; } elsif ($ccmd eq '0103') { $newcmd = '0103'; } elsif ($ccmd eq '0104') { $newcmd = '0104'; } elsif ($ccmd eq '0105') { $newcmd = '0105'; } elsif ($ccmd eq '0106') { $newcmd = '0106'; } elsif ($ccmd eq '0107') { $newcmd = '0107'; } elsif ($ccmd eq '010c') { $newcmd = '010c'; } elsif ($ccmd eq '010d') { $newcmd = '010d'; } elsif ($ccmd eq '010e') { $newcmd = '010e'; } elsif ($ccmd eq '010f') { $newcmd = '010f'; } elsif ($ccmd eq '0110') { $newcmd = '0110'; } elsif ($ccmd eq '0111') { $newcmd = '0111'; } elsif ($ccmd eq '0113') { $newcmd = '0113'; } elsif ($ccmd eq '0114') { $newcmd = '0114'; } elsif ($ccmd eq '0115') { $newcmd = '0115'; } elsif ($ccmd eq '011c') { $newcmd = '011c'; } elsif ($ccmd eq '0121') { $newcmd = '0121'; } elsif ($ccmd eq '012e') { $newcmd = '012e'; } elsif ($ccmd eq '012f') { $newcmd = '012f'; } elsif ($ccmd eq '013c') { $newcmd = '013c'; } elsif ($ccmd eq '0142') { $newcmd = '0142'; } elsif ($ccmd eq '0143') { $newcmd = '0143'; } elsif ($ccmd eq '0144') { $newcmd = '0144'; } elsif ($ccmd eq '0145') { $newcmd = '0145'; } elsif ($ccmd eq '0149') { $newcmd = '0149'; } elsif ($ccmd eq '014a') { $newcmd = '014a'; } elsif ($ccmd eq '014c') { $newcmd = '014c'; } else { print "Warning; failed to match $ccmd\n"; die "AMEN !\n"; } # my $newcmd = $ccmd; # this does not work print "\$ccmd; $ccmd ".length($ccmd). " \$newcmd; $newcmd ".length +($newcmd)."\n"; my $response = Serial_TrxRcv($newcmd); my $result; .... etc ...

As indicated in the code above, I could not just copy with "my $newcmd = $ccmd" but had to involve an if statement. In this circumstance the $newcmd can be passed to the sub without the buffer error occurring.

If the $newcmd is copied from a constant in the program then it works.

It's hard to known if the issue is from a very fine timing problem with the serial port treatment or related to how perl reads from a simple scaler embedded with a hash. Please consider issues ?

Regards JC....

Replies are listed 'Best First'.
Re^7: Win32::SerialPort, buffer overflow
by NERDVANA (Priest) on Nov 19, 2024 at 03:01 UTC
    That... is a truly strange workaround you have there. I can't imagine how that is different from '=', nor do I expect it to change execution speed much. Is there any chance that the difference is the 'die' that stops you from sending any other codes?

    The most relevant "gotcha" compared to what you're doing here would be if something inside Serial_TrxRcv tried checking whether you gave it a number or a string, in which case $ccmd could have picked up a "dualvar" nature (both a number and a string) which gets removed by assigning a string constant (in certain perl versions). But, you already showed us the code of Serial_TrxRcv and the first thing in there concatenates it with "\r" which will always treat it as a string.