Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: A CDMA problem

by juster (Friar)
on Nov 16, 2011 at 22:01 UTC ( #938472=note: print w/ replies, xml ) Need Help??


in reply to A CDMA problem

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', '?' ]


Comment on Re: A CDMA problem
Select or Download Code
Re^2: A CDMA problem
by Fighter2 (Novice) on Nov 17, 2011 at 04:35 UTC
    Juster. Thank you so very much for trying out my problem. I am indeed grateful to you. I will go home and run this, and tell you what results I get. Boy, if you do like problems that challenge and stretch your mind, we have plenty, which is a continuation of this one. What you attempted was a small part of a big project. Anyways, I will keep you in loop. Thank-you much for being kind and helpful. Grateful to you. Thanks bud (:
Re^2: A CDMA problem
by Fighter2 (Novice) on Nov 17, 2011 at 19:43 UTC

    Hi juster.

    So my code compiles. and thanks for cleaning it up so nicely. I do have an error when I try to run it though.

    C:\Dropbox\PandaDBCM>perl -d logprocessTempNff.pl sample2.nff out.txt 1069 Can't use string ("980904258.881354") as a HASH ref while "strict refs +" in use at logprocessTempNff. pl line 222. C:\Dropbox\PandaDBCM>

    I think "980904258.881354" is the timestamp. It looks like it. I know it will take a few tries to make this work. but how do I fix this error I wonder. Hmm. ?

      The error is pretty straightforward. That happens when you try to use a string as a hash reference. I.e.:

      my $foo = 'bar'; $foo->{'key'} = 'value'; # or likely for my $k (values %{$foo}){ ... }

      Just look at the line number specified and back-track from there. Use Data::Dumper or Data::Dump to ensure you have the values you are expecting (like a hashref instead of a string). Print them to screen alot, etc.

      I know there is one typo where I used the wrong variable ($logpkt should be $fngpkt in one spot) and I think I might have used values() where I shouldn't have. Make sure you understand values. Make sure you understand references, read perlreftut for example.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://938472]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (12)
As of 2014-07-14 06:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (255 votes), past polls