Loading ...
Sorry, an error occurred while loading the content.

Re: [mh] Help with pack - updated Owfs_Item.pm

Expand Messages
  • Eloy Paris
    Hi Jim, I m not a pack() expert either but just a couple of comments after reading pack() s documentation in perlfunc(1)... ... Doesn t seem like you need to
    Message 1 of 4 , Apr 20, 2013
    • 0 Attachment
      Hi Jim,

      I'm not a pack() expert either but just a couple of comments after
      reading pack()'s documentation in perlfunc(1)...

      On 04/20/2013 10:00 AM, Jim Duda wrote:

      > Hello,
      >
      > I'm the author of the Owfs_Item.pm module. I have recently done a major overhaul of this module with some major enhancements.
      >
      > Use Socket_Item instead of raw socket.
      > Avoids any pauses in the misterhouse main loop.
      > Push state up to Generic_Item baseclass for best practice operation with misterhouse objects.
      > Make discover and loss of devices more robust.
      > Support dynamic removal and reattachment of OW devices.
      >
      > If anyone is using this module and is interested in testing the enhancement, watch for the pull request.
      >
      > One of the things I had to do was integrate the OWNet.pm logic into the Owfs_Item.pm baseclass to allow integration with Socket_Item.
      >
      > I'm struggling with an issue with pack which I don't understand. My pack knowledge is weak. I'm looking for some help.
      >
      > I have confirmed that the pack operation works fine outside of mh. When used inside mh, something odd happens I cannot explain.
      >
      > I will try to boil it down to two code snipets:
      >
      > sub set {
      > my ($self, $token, $value) = @_;
      > return if (!defined $self->{path});
      > my $path = $self->{path} . $token;
      > &main::print_log ("Owfs_Item::set path: $path value: $value") if $main::Debug{owfs};
      > my $path_length = length($path)+1;
      > my $value_length = length($value);
      > my $payload = pack( 'Z'.$path_length.'A'.$value_length,$path,$value ); # THIS PACK SEEMS TO WORK FINE

      Doesn't seem like you need to specify a count for the 'Z' format.
      Probably doesn't hurt, but this is what the documentation says:

      'The "a", "A", and "Z" types gobble just one value, but pack it as a
      string of length count, padding with nulls or spaces as needed.'

      > sub _ToServer {
      > my ($self, $path, $payload_length, $msg_type, $size, $offset, $payload_data) = @_ ;
      > my $f = "N6" ;
      > $f .= 'Z'.$payload_length if ( $payload_length > 0 ) ;
      > my $message = pack($f,$self->{VER},$payload_length,$msg_type,$self->{SG}|$self->{PERSIST},$size,$offset,$payload_data); #THIS PACK corrupt $payload_data

      So it seems like the format can be either "N6" or "N6Z<some number>"
      depending on whether $payload_length > 0 (and <some number> is the
      length of the payload). In both cases you have 7 elements in the list.

      In the "N6" case, the last element of the list ($payload_data) is not
      used. I'd be surprised if that is causing a problem, but have you tried
      something like:

      if ($payload_length > 0) {
      pack("N6Z$payload_length",
      $self->{VER},$payload_length,$msg_type,$self->{SG}|$self->{PERSIST},$size,$offset,$payload_data);
      } else {
      pack("N6",
      $self->{VER},$payload_length,$msg_type,$self->{SG}|$self->{PERSIST},$size,$offset);
      }

      You could even make the "N6Z$payload_length" format just "N6Z" since it
      seems like you do not need to specify a count for the Z format.

      Just a shot in the dark...

      Cheers,

      Eloy Paris.-

      > &main::print_log ( "Owfs_Item::_ToServer path: $path payload_length: $payload_length payload_data: $payload_data message: $message") if $main::Debug{owfs};
      > my $hashref = { msg_type => $msg_type, self => $self, path => $path, message => $message };
      > push @queue, $hashref;
      > my $num = scalar(@queue);
      > &main::print_log ( "Owfs_Item::_ToServer num: $num") if $main::Debug{owfs};
      > if (scalar(@queue) eq 1) {
      > &main::print_log ( "Owfs_Item::_ToServer path: $path message: $message sending socket....") if $main::Debug{owfs};
      > start $socket unless active $socket;
      > $socket->set ( $message );
      > }
      > }
      >
      > In the set method, the $payload variable is properly packed. Example:
      >
      > $path = "/somestring"
      > $value = "1"
      >
      > I can see that $payload has "/somestring" 0 "1" 0
      > In the above, I have two strings separated by null termination byte of zero.
      >
      > Something odd happens with the second pack in the _ToServer method.
      > When $payload get packed into $message, the last character of the second string between the null termination zeros gets removed.
      > If the second string between the zeros is 1 character, then I get only the two null terminated zeros with any string in between.
      >
      > Can anyone explain what might be happening with the second pack here?
      >
      > Thanks,
      >
      > Jim
      >


      ------------------------------------------------------------------------------
      Precog is a next-generation analytics platform capable of advanced
      analytics on semi-structured data. The platform includes APIs for building
      apps and a phenomenal toolset for data science. Developers can use
      our toolset for easy data analysis & visualization. Get a free account!
      http://www2.precog.com/precogplatform/slashdotnewsletter
      ________________________________________________________
      To unsubscribe from this list, go to: http://sourceforge.net/mail/?group_id=1365
    • Jim Duda
      ... Thanks for the help Eloy. After reading your comments and trying some of them, I discovered what was necessary. First I used N6Z$payload_length .
      Message 2 of 4 , Apr 21, 2013
      • 0 Attachment
        On 04/20/2013 04:44 PM, Eloy Paris wrote:
        > You could even make the "N6Z$payload_length" format just "N6Z" since it
        > seems like you do not need to specify a count for the Z format.

        Thanks for the help Eloy. After reading your comments and trying some of them, I discovered what was necessary.
        First I used "N6Z$payload_length". Second, I change the call to _ToServer to this:

        $self->_ToServer($path,length($payload)+1, $msg_write, $value_length, 0, $payload);

        All of this code was a direct port from OWNet.pm (owfs). I noticed that the _ToServer read calls had length($payload)+1
        but the writes did not. Using +1 on writes solved my problem. This might be a bug with owfs OWNet.pm too, but for some
        reason it works outside of misterhouse with direct use of OWNet.pm

        In any event, I fell comfortable with these fixes and solve my problem.

        Regards,

        Jim




        ------------------------------------------------------------------------------
        Precog is a next-generation analytics platform capable of advanced
        analytics on semi-structured data. The platform includes APIs for building
        apps and a phenomenal toolset for data science. Developers can use
        our toolset for easy data analysis & visualization. Get a free account!
        http://www2.precog.com/precogplatform/slashdotnewsletter
        ________________________________________________________
        To unsubscribe from this list, go to: http://sourceforge.net/mail/?group_id=1365
      • Eloy Paris
        ... Great, glad you got it to work. I look forward to trying the new Ofws_Item.pm. Cheers, Eloy Paris.- ... Precog is a next-generation analytics platform
        Message 3 of 4 , Apr 21, 2013
        • 0 Attachment
          On 04/21/2013 09:04 AM, Jim Duda wrote:

          > On 04/20/2013 04:44 PM, Eloy Paris wrote:
          >> You could even make the "N6Z$payload_length" format just "N6Z" since it
          >> seems like you do not need to specify a count for the Z format.
          >
          > Thanks for the help Eloy. After reading your comments and trying some of them, I discovered what was necessary.
          > First I used "N6Z$payload_length". Second, I change the call to _ToServer to this:
          >
          > $self->_ToServer($path,length($payload)+1, $msg_write, $value_length, 0, $payload);
          >
          > All of this code was a direct port from OWNet.pm (owfs). I noticed that the _ToServer read calls had length($payload)+1
          > but the writes did not. Using +1 on writes solved my problem. This might be a bug with owfs OWNet.pm too, but for some
          > reason it works outside of misterhouse with direct use of OWNet.pm
          >
          > In any event, I fell comfortable with these fixes and solve my problem.

          Great, glad you got it to work. I look forward to trying the new
          Ofws_Item.pm.

          Cheers,

          Eloy Paris.-


          ------------------------------------------------------------------------------
          Precog is a next-generation analytics platform capable of advanced
          analytics on semi-structured data. The platform includes APIs for building
          apps and a phenomenal toolset for data science. Developers can use
          our toolset for easy data analysis & visualization. Get a free account!
          http://www2.precog.com/precogplatform/slashdotnewsletter
          ________________________________________________________
          To unsubscribe from this list, go to: http://sourceforge.net/mail/?group_id=1365
        Your message has been successfully submitted and would be delivered to recipients shortly.