From 3ba0bd15bb7685ff559add0844dd8382c23a647a Mon Sep 17 00:00:00 2001 From: KRKeegan Date: Fri, 5 Apr 2013 17:12:13 -0700 Subject: [PATCH 1/3] Insteon: Prevent Crash When PLM Busy but no Active Message The PLM may report a busy code 15, even when there is no active_message. Added logic to test for an active message before trying to resend it. Partial fix for issue #154 --- lib/Insteon_PLM.pm | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index 029f61923..79291774a 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -674,13 +674,18 @@ sub _parse_data { # so, slow things down if (!($nack_count)) { - my $nack_delay = ($::config_parms{Insteon_PLM_disable_throttling}) ? 0.3 : 1.0; - &::print_log("[Insteon_PLM] DEBUG3: Interface extremely busy. Resending command" - . " after delaying for $nack_delay second") if $main::Debug{insteon} >= 3; - $self->_set_timeout('xmit',$nack_delay * 1000); - $self->active_message->no_hop_increase(1); - $self->retry_active_message(); - $process_next_command = 0; + if ($self->active_message){ + my $nack_delay = ($::config_parms{Insteon_PLM_disable_throttling}) ? 0.3 : 1.0; + &::print_log("[Insteon_PLM] DEBUG3: Interface extremely busy. Resending command" + . " after delaying for $nack_delay second") if $main::Debug{insteon} >= 3; + $self->_set_timeout('xmit',$nack_delay * 1000); + $self->active_message->no_hop_increase(1); + $self->retry_active_message(); + $process_next_command = 0; + } else { + &::print_log("[Insteon_PLM] DEBUG3: Interface extremely busy." + . " No message to resend.") if $main::Debug{insteon} >= 3; + } $nack_count++; } } From 43b7c0650030277d6c525270c73094a439c101a2 Mon Sep 17 00:00:00 2001 From: KRKeegan Date: Fri, 5 Apr 2013 17:14:09 -0700 Subject: [PATCH 2/3] Insteon: Prevent Crashing if AllLink_Failure_Report Receive and No Active Message I am not clear how this could be occuring, but it was reported as a crash. Added simple logic to test for an active_message before trying to call the active message. Fixes Issue #154 --- lib/Insteon_PLM.pm | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index 79291774a..a325ccd08 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -619,19 +619,24 @@ sub _parse_data { } elsif ($parsed_prefix eq $prefix{all_link_clean_failed} and ($message_length == 12)) { #ALL-Link Cleanup Failure Report - # extract out the pertinent parts of the message for display purposes - # bytes 0-1 - group; 2-7 device address - my $failure_group = substr($message_data,0,2); - my $failure_device = substr($message_data,2,6); - - &::print_log("[Insteon_PLM] DEBUG2: Received all-link cleanup failure from device: " - . "$failure_device and group: $failure_group") if $main::Debug{insteon} >= 2; + if ($self->active_message){ + # extract out the pertinent parts of the message for display purposes + # bytes 0-1 - group; 2-7 device address + my $failure_group = substr($message_data,0,2); + my $failure_device = substr($message_data,2,6); + + &::print_log("[Insteon_PLM] DEBUG2: Received all-link cleanup failure from device: " + . "$failure_device and group: $failure_group") if $main::Debug{insteon} >= 2; - my $failed_object = &Insteon::get_object($failure_device,'01'); - my $message = new Insteon::InsteonMessage('all_link_direct_cleanup', $failed_object, - $self->active_message->command, $failure_group); - push(@{$$failed_object{command_stack}}, $message); - $failed_object->_process_command_stack(); + my $failed_object = &Insteon::get_object($failure_device,'01'); + my $message = new Insteon::InsteonMessage('all_link_direct_cleanup', $failed_object, + $self->active_message->command, $failure_group); + push(@{$$failed_object{command_stack}}, $message); + $failed_object->_process_command_stack(); + } else { + &::print_log("[Insteon_PLM] DEBUG2: Received all-link cleanup failure." + . " But there is no pending message.") if $main::Debug{insteon} >= 2; + } } elsif ($parsed_prefix eq $prefix{all_link_record} and ($message_length == 20)) From 0f2e11d94e2cb213e83a95dc7b11234afe3654ae Mon Sep 17 00:00:00 2001 From: KRKeegan Date: Sat, 6 Apr 2013 15:52:59 -0700 Subject: [PATCH 3/3] Insteon_PLM: Fix Error in Message Parser Dumping Buffer on Busy Solves issue #158 identified by Chris Dragon This will trim the leading "15" bytes from the data. If anything is left it will be placed into the message fragment to be read next time. --- lib/Insteon_PLM.pm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index a325ccd08..0b8d367ed 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -693,6 +693,13 @@ sub _parse_data { } $nack_count++; } + #Remove the leading NACK bytes and place whatever remains into fragment for next read + $parsed_data =~ s/^(15)*//; + if ($parsed_data ne ''){ + $$self{_data_fragment} .= $parsed_data; + ::print_log("[Insteon_PLM] DEBUG3: Saving parsed data fragment: " + . $parsed_data) if( $main::Debug{insteon} >= 3); + } } else {