Reputation: 85
Why do I get the wrong answers/values?
The correct values it should print are 1, 2175, 4
but instead I always get 1, 3, 0
?!
my $data = pack ('C*', map hex, split /\s+/, "01 00 00 00 7F 08 03 00 21 04 80 04 FF D7 FB 0C EC 01 44 00 61 1D 00 00 10 3B 00 00 FF D7 FB 0C 00 00 8C 64 00 00 EC 45");
($obj->{Version}, $obj->{res1}, $obj->{EARFCN}, $tmp1, $obj->{res2}, $tmp2)=unpack("C C3 v C C V", $data);
$obj->{band} = ($tmp1 & 0xfc) >> 2;
print "\n".$obj->{Version}; # Should print 1
print "\n".$obj->{EARFCN}; # Should print 2175
print "\n".$obj->{band}; # Should print 4. Note: this is the first 6 bits from MSB of $tmp1.
print "\n";
Upvotes: 4
Views: 194
Reputation: 385917
There's no pattern for 24-bit words. (Machines don't have such a type.) You could use either of the following snippets.
You want band
to be the most significant 6 bits of a 16-bit word (y
in yyyy yyxx xxxx xxxx
). For that, use $_ >> 10
.
(
$obj->{Version},
my $tmp0,
$obj->{EARFCN},
my $tmp1,
$obj->{res2},
my $tmp2
) = unpack("C a3 v C C V", $data);
$obj->{res1} = unpack("V", $tmp0."\x00");
$obj->{band} = $tmp1 >> 10;
or
(
my $tmp0,
$obj->{EARFCN},
my $tmp1,
$obj->{res2},
my $tmp2
) = unpack("V v C C V", $data);
$obj->{Version} = $tmp0 & 0xFF;
$obj->{res1} = $tmp0 >> 8;
$obj->{band} = $tmp1 >> 10;
Upvotes: 0
Reputation: 85
I made two mistakes.
I should have used the a3
specifier instead of using C3
. So, it should say:
unpack("C a3 v C C V", $data);
and also
$obj->{band} = ($tmp1 & 0xfc) >> 2;
is indeed 0. and not 4.
Upvotes: 1
Reputation: 86774
Debug output:
DB<1> $data = pack ('C*', map hex, split /\s+/, "01 00 00 00 7F 08 03 00 21 04 80 04 FF D7 FB 0C EC 01 44 00 61 1D 00 00 10 3B 00 00 FF D7 FB 0C 00 00 8C 64 00 00 EC 45")
DB<2> x unpack("C C3 v C C V", $data)
0 1
1 0
2 0
3 0
4 2175
5 3
6 0
7 75498529
Pattern C3
outputs three unsigned bytes, not a string of length three.
I think you want a3
instead. See Perldoc pack()
Upvotes: 2