Well, I will take a stab at this. I fed my coding addiction by messing with your example. I ran it through perltidy because I had a hard time reading it. After reading it and seeing how simple it was I rewrote some of it for my own edification.

Your post is way too in depth. I don't really have time to care about CDMA. I generally simplify problems by looking at the data coming in and going out, getting munged, or whatever. You have a stream of packets. Each packet has a timestamp and data members, not all of which you will use. You only want to compare data from packets with timestamps close to each other, right? (This is an important fact you weren't specific about). Namely you want to compare c2i data from 108A/finger/multilink packets with rxAgc0-rxAgc1 data from 1069 packets. Yum.

You can either do some awkward logic where each time you see a 1069 packet you backtrack to compare it with every old 108A packet and vice versa if you see a 1069 packet. You would also have to remember to discard old packets.

Or you could just create an array of data which you map from your original stream of raw packets. To conserve memory this array contains only the data you need. The advantage over the stream is that you can go backwards and forwards so the logic is also much easier.

Stream in. Data out. Poke around the data, do some calculations. Discard data. Spit out the calculations.

## Initializes some variables and starts a software. my $nff = new NffInterface; my $logid = $nff->loadLog($inputFile); ## Picks an index in the log my $fid1 = $nff->createFilter($logid, {type => "logcode", logcode => 0 +x1069}); my $fid2 = $nff->createFilter($logid, {type => "logcode", logcode => 0 +x108A}); ## Creates an array of multiple filters on order of the particular log +Id. my $view = $nff->createView([ $fid1, $fid2 ]); my @hist; ## Iterates on filter indices and gets the next log in the view array. while((my $log = $nff->getNextLogFromView($view)) != -1){ my $code = getLogCode($log); printf "%X\n", $code; if($code == 0x108A){ # use == for numbers my $fngpkt = parse108A($log); # fngpkt instead of obj1 my $slen = $fngpkt->{numF}; for(my $i = 0; $i < $slen; $i++){ my $sum = 0; my $sec = $fngpkt->{sectors}{$i}; my $flen = $sec->{numFingers}; for(my $j = 0; $j < $flen; $j++){ $sum += $sec->{$j}{c2i}; } ## collects the sum for each SECTOR... ## note that c2i history entries have 2 elements print "c2i sum = $sum\n"; push @hist, [ $fngpkt->{timestamp}, $sum ]; } }elsif($code == 0x1069){ my $logpkt = parse1069($log); # logpkt (or something) instead +of obj2 ## agc entries have 3 elements push @hist, [ $logpkt->{timestamp}, $logpkt->{0}{rxAgc0}, $logpkt->{1}{rxAgc0} ]; } } ## Now we have a history of the data we care about... calcstuff(\@hist); sub isc2i { my ($elt) = @_; return @$elt == 2; } sub isagc { my ($elt) = @_; return @$elt == 3; } sub recentagcs { my ($hist, $idx) = @_; my $pivot = $hist->[$idx]; my @fnd; # search backwards my $i = $idx - 1; while($i >= 0){ my $x = $hist->[$i--]; unless(freshentry($pivot, $x)){ last } if(isagc($x)){ unshift @fnd, $hist; } } # search forwards $i = $idx + 1; while($i <= $#$hist){ my $x = $hist->[$i++]; unless(freshentry($pivot, $x)){ last } if(isagc($x)){ push @fnd, $hist; } } return \@fnd; } my $FRESHMS = 50; sub freshentry { my ($l, $r) = @_; # timestamps are the first elem return (abs($l->[0] - $r->[0]) <= $FRESHMS); } sub calcstuff { my ($hist) = @_; for my $i (0 .. $#$hist){ my $log = $hist->[$i]; if(isc2i($log)){ my $agcs = recentagcs($hist, $i); for my $agc (@$agcs){ ## ... etc ... } } } }

Of course, I can't test this to see if it works. Hopefully you get the idea and adapt it to your needs. Or you've probably moved on after a day and won't see this.

Regarding the parsing of the raw packets, you can specify little endianness by using the '<' (less-than) character. You can specify a repeat count with a number. Yay fun example: perl -e 'print pack(q{s<2}, 0x0A0D, 0x0A0D)'; (prints "\x0D\x0A\x0D\x0A" aka "\n\n" in windows). Parenthesis create sub-groups. So your parse1069 unpack template could be: a12 (C s<6)2. I think so anyways, pack is tricky... Yes you said you didn't want to change it but it's not much work and there's nothing more productive than deleting lines of code ;-). Consider using a module like Convert::Binary::C.

You also might want to consider using arrayrefs instead of hashrefs which have weird entries that help them pretend to be arrays. Consider:

{ 'count' => 2, '0' => 'wtf', '1' => '?' } vs [ 'wtf', '?' ]


In reply to Re: A CDMA problem by juster
in thread A CDMA problem by Fighter2

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.