######### sub new { ######### my $class = shift; my $self = {}; bless ($self,$class); my %fragArgs = %{ $_[0] }; # dereference the hashref of message fragment parameters die "no message ID!" unless defined $fragArgs{msgID} ; die "no frag seq!" unless defined $fragArgs{fragSeq} ; die "no morefrag flag!" unless defined $fragArgs{moreFrags} ; die "no frag data !" unless defined fragArgs{fragData} ; &setUpLogging; # Declare the constant field lengths for the pack statement # to package the msg data into a fragment my $fmtMsgID = 'H4';# 16 bits Msg ID 4 hex digits my $fmtFragSeq = 'b7';# 7 bits Frag Seq my $fmtMoreFrags = 'b'; # 1 bit More Frags flag my $fmtFlagUnitIDPresent = 'b'; # 1 bit Unit ID Present my $fmtFlagCRCPresent = 'b'; # 1 bit CRC Present my $fmtFlagsUnused = 'b6'; # 6 bits Unused my $fmtfragLen = 'H2'; # 8 bits Frag Length #my $fmtFragData is 'variable'; my $fmtUnitID = 'A8'; # if present, unit ID is 8 chars my $fmtFragCRC = 'H4'; # if present, CRC is a 16 bit word # create the fragment packing format according to the data length and flags my $fragFormat = $fmtMsgID . $fmtFragSeq . $fmtMoreFrags . $fmtFlagUnitIDPresent . $fmtFlagCRCPresent . $fmtFlagsUnused . $fmtfragLen . 'A' . (length $fragArgs{fragData} ) . ($fragArgs{unitID} ? $fmtUnitID : '') . ($fragArgs{doCRC} ? $fmtFragCRC: '') ; #pack the individual bits of the first message hash according to the pack-format. # include Unit ID and/or CRC data if they are declared for this message. DEBUG "packing message frag using format $fragFormat"; my $wrappedFrag = pack $fragFormat, $fragArgs{msgID}, $fragArgs{fragSeq}, $fragArgs{moreFrags}, ($fragArgs{unitID}? 1 : 0 ), # set UnitIDPresent bit if given ($fragArgs{CRC} ? 1 : 0 ) , # set CRCPresent bit if given 0, # 0 for the unused bits length $fragArgs{fragData}, $fragArgs{fragData}, ($fragArgs{unitID} ? $fragArgs{unitID} :''), # include unit ID if it was given ($fragArgs{doCRC} ? &doCRC($fragArgs{fragData}) :''); $Data::Dumper::Sortkeys = $Data::Dumper::Terse = $Data::Dumper::Indent = 1; print Dumper(\%fragArgs) . "gives:\n". Dumper($wrappedFrag); return $wrappedFrag; } ############# sub unwrap { ############# #given a msg fragment in packed binary return a message hash my $class = shift; my $self = {}; bless ($self,$class); my $wrappedFrag = $_[0] ; my %msgFrag = (); die "no message frag!" unless defined $wrappedFrag; &setUpLogging; # Declare the constant field lengths for the unpack statement # to extract the msg data from a fragment my $fmtMsgID = 'H4';# 16 bits Msg ID my $fmtFragSeq = 'b7';# 7 bits Frag Seq my $fmtMoreFrags = 'b'; # 1 bit More Frags flag my $fmtFlagUnitIDPresent = 'b'; # 1 bit Unit ID Present my $fmtFlagCRCPresent = 'b'; # 1 bit CRC Present my $fmtFlagsUnused = 'b6'; # 6 bits Unused my $fmtfragLen = 'H2'; # 8 bits Frag Length #my $fmtFragData is 'variable'; my $fmtUnitID = 'A8'; # if present, unit ID is 8 chars my $fmtFragCRC = 'H4'; # if present, CRC is a 16 bit word # We will have to take the frag apart in a number of bites. # 1. Msg ID, Frag Seq, More Frags flag, Unit ID Present, CRC Present, Frag Length. my $fragFormat = $fmtMsgID . $fmtFragSeq . $fmtMoreFrags . $fmtFlagUnitIDPresent . $fmtFlagCRCPresent . $fmtFlagsUnused . $fmtfragLen ; DEBUG "unpacking message frag using format $fragFormat"; ($msgFrag{msgID}, $msgFrag{fragSeq}, $msgFrag{moreFrags}, $msgFrag{unitID}, $msgFrag{CRC}, my $junk, #for the unused flagbits my $fragLength) = unpack $fragFormat, $wrappedFrag; $Data::Dumper::Sortkeys = $Data::Dumper::Terse = $Data::Dumper::Indent = 1; print "unpack got \n" . Dumper(\%msgFrag) . "from:\n". Dumper($wrappedFrag); # further code to be added ... return %msgFrag; }