CNavFilter_T.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 #include "TestUtil.hpp"
40 #include "NavFilterMgr.hpp"
41 #include "CNavFilterData.hpp"
42 #include "CNavCookFilter.hpp"
44 #include "CNavEmptyFilter.hpp"
45 #include "CNavParityFilter.hpp"
46 #include "CNavTOWFilter.hpp"
47 #include "CommonTime.hpp"
48 #include "GPSWeekSecond.hpp"
49 #include "NavFilter.hpp"
50 #include "StringUtils.hpp"
51 #include "TimeString.hpp"
52 #include "TimeSystem.hpp"
53 
54 using namespace std;
55 using namespace gnsstk;
56 
57 
59 {
60 public:
61  CNavFilter_T();
62  ~CNavFilter_T();
63 
64  unsigned loadData();
65 
67  unsigned noFilterTest();
69  unsigned testCNavCook();
71  unsigned testCNavParity();
73  unsigned testCNavEmpty();
75  unsigned testCNavTOW();
77  unsigned testCNavCombined();
79  unsigned testCNavCrossSource();
80 
81  // This is a list of the PackedNavBit messages that are created from the
82  // static strings contained in the loadData( ) method.
83  list<PackedNavBits*> messageList;
84 
85  // This is a parallel list of CNavFilterData objects created from
86  // the PackedNavBit objects. These are all believed to be valid.
87  list<CNavFilterData> cNavList;
88 };
89 
90 //-------------------------------------------------------------------
93 {
94  // In the case of this test. This method doesn't have to do anything.
95 }
96 
97 
100 {
101  for (auto& mli : messageList)
102  {
103  delete mli;
104  }
105 }
106 
107 
108 //-------------------------------------------------------------------
109 unsigned CNavFilter_T ::
111 {
112  static const int MSG_COUNT_CNAV = 12;
113  string sv63_CNAV[] =
114  {
115  "365,12/31/2015,00:00:00,1877,345600,1,63,10, 0x8B04A708, 0x10EAA60A, 0x6A49007A, 0x2E3FFDAE, 0x42EEB000, 0x81B983C7, 0x9A881433, 0x89C04F25, 0xB9F60DD4, 0xED600000",
116  "365,12/31/2015,00:00:12,1877,345612,1,63,11, 0x8B04B708, 0x22490999, 0x6E1AC9D0, 0xF0CB205F, 0xFFEE3FFA, 0xBFFC9FF7, 0x94201BB3, 0x6022E5FF, 0x8B9802D4, 0xA5600000",
117  "365,12/31/2015,00:00:24,1877,345624,1,63,30, 0x8B05E708, 0x320A6A79, 0x240214AC, 0x80084000, 0x0B0FFB7E, 0x5019E0D4, 0x0DFFFF02, 0x39F1FF11, 0x5500081A, 0x33500000",
118  "365,12/31/2015,00:00:36,1877,345636,1,63,33, 0x8B061708, 0x420A6A79, 0x240214AC, 0x80084001, 0xFFCE0000, 0x02298EE7, 0x5539D988, 0x80000000, 0x00000486, 0xBF400000",
119  "365,12/31/2015,02:00:00,1877,352800,1,63,10, 0x8B04A72D, 0x90EAA60A, 0x6A550077, 0x2A400140, 0xF2F62FFF, 0xC4FC3082, 0x7A701435, 0xE9084F1E, 0xA9CA02EF, 0x1B800000",
120  "365,12/31/2015,02:00:12,1877,352812,1,63,11, 0x8B04B72D, 0xA2550999, 0x22EA09D0, 0xF0770055, 0x8FA57FED, 0xA007DFF6, 0x9B001BF7, 0xA0224CFF, 0x7D980CAA, 0xA4200000",
121  "365,12/31/2015,02:00:24,1877,352824,1,63,30, 0x8B05E72D, 0xB20A6A79, 0x54021520, 0x80084000, 0x0B0FFB7E, 0x5019E0D4, 0x0DFFFF02, 0x39F1FF11, 0x55000016, 0xEC400000",
122  "365,12/31/2015,02:00:36,1877,352836,1,63,33, 0x8B06172D, 0xC20A6A79, 0x54021520, 0x80084001, 0xFFCE0000, 0x02298EE7, 0x5539D988, 0x80000000, 0x00000C8A, 0x60500000",
123  "365,12/31/2015,04:00:00,1877,360000,1,63,10, 0x8B04A753, 0x10EAA60A, 0x6A610078, 0xE17FFE9C, 0xA30F7800, 0x64BEDD4C, 0xDBB81434, 0x9B6C4F13, 0x67480568, 0xC7C00000",
124  "365,12/31/2015,04:00:12,1877,360012,1,63,11, 0x8B04B753, 0x22610998, 0xD6B2C9D0, 0xEF01800F, 0xFF5EE007, 0xA00B3FF5, 0xEA001B8B, 0xE022CCFF, 0x755807EB, 0xB3300000",
125  "365,12/31/2015,04:00:24,1877,360024,1,63,30, 0x8B05E753, 0x320A6A79, 0x84021595, 0x00084000, 0x0B0FFB7E, 0x5019E0D4, 0x0DFFFF02, 0x39F1FF11, 0x55000411, 0xB1F00000",
126  "365,12/31/2015,04:00:36,1877,360036,1,63,33, 0x8B061753, 0x420A6A79, 0x84021595, 0x00084001, 0xFFCE0000, 0x02298EE7, 0x5539D988, 0x80000000, 0x0000088D, 0x3DE00000"
127  };
128  static const string sv50_CNAV[] =
129  {
130  "365,12/31/2015,00:00:00,1877,345600,5,50,10, 0x8B14A708, 0x10EAA605, 0xEA4900F8, 0x87BFFFCF, 0xE33EE000, 0x0DD1110C, 0x796012CA, 0x8EB84F34, 0xC1F0049B, 0x24900000",
131  "365,12/31/2015,00:00:12,1877,345612,5,50,11, 0x8B14B708, 0x22491E9A, 0xBFDBC9A2, 0xACF8E007, 0xC0DE000E, 0xC002C003, 0x510016F7, 0x4028AB00, 0x2FF00D9E, 0x66400000",
132  "365,12/31/2015,00:00:24,1877,345624,5,50,30, 0x8B15E708, 0x3205E5F9, 0x25D6111F, 0x801FB001, 0xE90FFC83, 0x1E001000, 0x0DFFFF02, 0x39F1FF11, 0x55000952, 0x83B00000",
133  "365,12/31/2015,00:00:36,1877,345636,5,50,33, 0x8B161708, 0x4205E5F9, 0x25D6111F, 0x801FB001, 0xFFCE0000, 0x022979C7, 0x5539D988, 0x80000000, 0x00000F0F, 0x80A00000",
134  "365,12/31/2015,02:00:00,1877,352800,5,50,10, 0x8B14A72D, 0x90EAA605, 0xEA5500F1, 0x10800003, 0x134AF000, 0x16E3BDCD, 0x7D8012C9, 0x8F304F2A, 0xDF9A0CA4, 0xD5A00000",
135  "365,12/31/2015,02:00:12,1877,352812,5,50,11, 0x8B14B72D, 0xA2551E9A, 0x72C749A2, 0xAE352013, 0x70829FFF, 0xFFF80002, 0xEE80181B, 0x0026F400, 0x28580984, 0x56000000",
136  "365,12/31/2015,02:00:24,1877,352824,5,50,30, 0x8B15E72D, 0xB205E5F9, 0x55D612DD, 0x001FB001, 0xE90FFC83, 0x1E001000, 0x0DFFFF02, 0x39F1FF11, 0x550008B6, 0x7E600000",
137  "365,12/31/2015,02:00:36,1877,352836,5,50,33, 0x8B16172D, 0xC205E5F9, 0x55D612DD, 0x001FB001, 0xFFCE0000, 0x022979C7, 0x5539D988, 0x80000000, 0x00000EEB, 0x7D700000",
138  "365,12/31/2015,04:00:00,1877,360000,5,50,10, 0x8B14A753, 0x10EAA605, 0xEA6100F8, 0x27400088, 0x334447FF, 0xE2966A43, 0x63D812C8, 0xAE484F33, 0xD3FC0C2A, 0x5C400000",
139  "365,12/31/2015,04:00:12,1877,360012,5,50,11, 0x8B14B753, 0x22611E9A, 0x24C149A2, 0xAF354020, 0x8088FFF9, 0xFFFB4001, 0xF5601886, 0x6026A800, 0x1A800B07, 0xF9800000",
140  "365,12/31/2015,04:00:24,1877,360024,5,50,30, 0x8B15E753, 0x3205E5F9, 0x85D6149A, 0x801FA801, 0xE90FFC83, 0x1E001000, 0x0DFFFF02, 0x39F1FF11, 0x55000781, 0x8FB00000",
141  "365,12/31/2015,04:00:36,1877,360036,5,50,33, 0x8B161753, 0x4205E5F9, 0x85D6149A, 0x801FA801, 0xFFCE0000, 0x022979C7, 0x5539D988, 0x80000000, 0x000001DC, 0x8CA00000"
142  };
143 
144  ObsID oidCNAV(ObservationType::NavMsg, CarrierBand::L2, TrackingCode::L2CML);
145  for (int i1=0; i1<MSG_COUNT_CNAV; i1++)
146  {
147  vector<string> words;
148  for (int i2=0; i2<2; i2++)
149  {
150  words.clear();
151  if (i2==0)
152  words = StringUtils::split(sv63_CNAV[i1],',');
153  else
154  words = StringUtils::split(sv50_CNAV[i1],',');
155 
156  int gpsWeek = StringUtils::asInt(words[3]);
157  double sow = StringUtils::asInt(words[4]);
158  CommonTime ct = GPSWeekSecond(gpsWeek, sow, TimeSystem::GPS);
159 
160  int prn = StringUtils::asInt(words[5]);
161  SatID sid(prn, SatelliteSystem::GPS);
162 
163  string rxString = "unk";
164 
165  PackedNavBits* pnb = new PackedNavBits(sid,oidCNAV,rxString,ct);
166 
167  // Load the raw data
168  // Words 0-8 have 32 bits.
169  // Word 9 has 12 bits and they'll be "left-justified"
170  // in the sense that the string will look like 0xXXX00000;
171  // that is to say, 12 bits plus 20 bits of zero padding.
172  int offset = 8;
173  for (int i=0; i<10; i++)
174  {
175  int ndx = i + offset;
176  string hexStr = StringUtils::strip(words[ndx]);
177  string::size_type n = hexStr.find("x");
178  hexStr = hexStr.substr(n+1);
179  unsigned long bits = StringUtils::x2uint(hexStr);
180  if (i<9) pnb->addUnsignedLong(bits,32,1);
181  else
182  {
183  bits >>= 20;
184  pnb->addUnsignedLong(bits,12,1);
185  }
186  }
187  pnb->trimsize();
188 
189  messageList.push_back(pnb);
190 
191  CNavFilterData cnavFilt(pnb);
192  cNavList.push_back(cnavFilt);
193  } // end i2
194  } // end i1
195 
196  return 0;
197 }
198 
199 //-------------------------------------------------------------------
200 unsigned CNavFilter_T ::
202 {
203  TUDEF("CNav NoFilter", "validate");
204 
205  NavFilterMgr mgr;
206  unsigned long count = 0;
207 
208  list<CNavFilterData>::iterator it;
209  for (it=cNavList.begin(); it!=cNavList.end(); it++)
210  {
211  CNavFilterData& fd = *it;
213  // We could do an assert for each record but that would be
214  // stupid. Just compare the final counts.
215  count += l.size();
216  }
217  int expected = cNavList.size();
218  TUASSERTE(unsigned long, expected, count);
219  TURETURN();
220 }
221 
222 //-------------------------------------------------------------------
223 // this should be executed before any other filter tests are used as
224 // it will upright all the data in memory.
225 unsigned CNavFilter_T ::
227 {
228  TUDEF("CNavCookFilter", "validate");
229 
230  NavFilterMgr mgr;
231  unsigned long count = 0;
232  CNavCookFilter filtCook;
233 
234  mgr.addFilter(&filtCook);
235 
236  list<CNavFilterData>::iterator it;
237  for (it=cNavList.begin(); it!=cNavList.end(); it++)
238  {
239  CNavFilterData& fd = *it;
241  // We could do an assert for each record but that would be
242  // stupid. Just compare the final counts.
243  count += l.size();
244  }
245  int expected = cNavList.size();
246  TUASSERTE(unsigned long, expected, count);
247 
248  // The preceding simply proves that valid data passes
249  // through the filter. It doesn't verify that inverted
250  // data is set upright. To address that, take a valid
251  // message, invert it, cook it, then see that the result
252  // is correct.
253  count = 0;
254  for (it=cNavList.begin(); it!=cNavList.end(); it++)
255  {
256  CNavFilterData& fd = *it;
257  PackedNavBits* pnbInvert = fd.pnb->clone();
258  pnbInvert->invert();
259  CNavFilterData fdInvert(pnbInvert);
260  gnsstk::NavFilter::NavMsgList l = mgr.validate(&fdInvert);
261 
262  if (fd.pnb->match(*(fdInvert.pnb)))
263  {
264  count++;
265  }
266  delete pnbInvert;
267  }
268  TUASSERTE(unsigned long, expected, count);
269  TURETURN();
270 }
271 
272 //-------------------------------------------------------------------
273 unsigned CNavFilter_T ::
275 {
276  TUDEF("CNavParityFilter", "validate");
277 
278  NavFilterMgr mgr;
279  unsigned long rejectCount = 0;
280  unsigned long acceptCount = 0;
281  CNavParityFilter filtParity;
282 
283  mgr.addFilter(&filtParity);
284 
285  // Test with valid data
286  list<CNavFilterData>::iterator it;
287  for (it=cNavList.begin(); it!=cNavList.end(); it++)
288  {
289  CNavFilterData& fd = *it;
291  gnsstk::NavFilter::NavMsgList::const_iterator nmli;
292 
293  acceptCount += l.size();
294  rejectCount += filtParity.rejected.size();
295  }
296  int expected = cNavList.size();
297  TUASSERTE(unsigned long, expected, acceptCount);
298  TUASSERTE(unsigned long, 0, rejectCount);
299 
300  // Clone a valid message, modify the CRC, and
301  // verify that the filter rejects the data.
302  acceptCount = 0;
303  rejectCount = 0;
304  list<PackedNavBits*>::iterator it2 = messageList.begin();
305  PackedNavBits* p = *it2;
306  PackedNavBits* pnb = p->clone();
307  unsigned long zeroes = 0x00000000;
308  pnb->insertUnsignedLong(zeroes,276,24);
309  CNavFilterData fd(pnb);
311  acceptCount = l.size();
312  rejectCount = filtParity.rejected.size();
313  TUASSERTE(unsigned long, 0, acceptCount);
314  TUASSERTE(unsigned long, 1, rejectCount);
315  delete pnb;
316  TURETURN();
317 }
318 
319 //-------------------------------------------------------------------
320 unsigned CNavFilter_T ::
322 {
323  TUDEF("CNavEmptyFilter", "validate");
324 
325  NavFilterMgr mgr;
326  unsigned long rejectCount = 0;
327  unsigned long acceptCount = 0;
328  CNavEmptyFilter filtEmpty;
329 
330  mgr.addFilter(&filtEmpty);
331 
332  list<CNavFilterData>::iterator it;
333  for (it=cNavList.begin(); it!=cNavList.end(); it++)
334  {
335  CNavFilterData& fd = *it;
337  acceptCount += l.size();
338  rejectCount += filtEmpty.rejected.size();
339  }
340  int expected = cNavList.size();
341  TUASSERTE(unsigned long, expected, acceptCount);
342  TUASSERTE(unsigned long, 0, rejectCount);
343 
344  // Now test an empty message. Create an empty message
345  // by cloning the first message in the list (which is
346  // known to be valid), then zeroing out the "payload".
347  // Since CNavFilterData does not pay attention to
348  // whether the CRC is good or bad, we don't need to
349  // worry about that.
350  // The goal is to retain bits 1-38 and bits 277-300
351  // for a valid message while zeroing out bits 39-276.
352  acceptCount = 0;
353  rejectCount = 0;
354  CNavFilterData fd;
355  list<PackedNavBits*>::iterator it2 = messageList.begin();
356  PackedNavBits* p = *it2;
357  PackedNavBits* pnbEmptyMsg = p->clone();
358 
359  unsigned long bits_1_32 = p->asUnsignedLong(0,32,1);
360  unsigned long bits_33_38 = p->asUnsignedLong(32,6,1);
361  unsigned long bits_277_300 = p->asUnsignedLong(276,24,1);
362  unsigned long alternating = 0xAAAAAAAA;
363 
364 /*
365  Actually, the 1/0 pattern is default navigation message data.
366  While it may be default, its not "empty"
367 
368  pnbEmptyMsg->reset_num_bits();
369  pnbEmptyMsg->addUnsignedLong(bits_1_32,32,1);
370  pnbEmptyMsg->addUnsignedLong(bits_33_38,6,1);
371  unsigned long alternating26 = alternating >> 6;
372  pnbEmptyMsg->addUnsignedLong(alternating26,26,1); // bits 39- 64
373  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 65- 96
374  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 97-128
375  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 129-160
376  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 161-192
377  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 193-224
378  pnbEmptyMsg->addUnsignedLong(alternating,32,1); // bits 225-256
379  unsigned long alternating20 = alternating >> 12;
380  pnbEmptyMsg->addUnsignedLong(alternating20,20,1); // bits 257-276
381  pnbEmptyMsg->addUnsignedLong(bits_277_300,24,1);
382 
383  pnbEmptyMsg->trimsize();
384  CNavFilterData fdEmpty(pnbEmptyMsg);
385  gnsstk::NavFilter::NavMsgList l = mgr.validate(&fdEmpty);
386  acceptCount += l.size();
387  rejectCount += filtEmpty.rejected.size();
388 */
389  delete pnbEmptyMsg;
390 
391  // Now build a message with zeroes in the payload
392  PackedNavBits* pnbZeroMsg = p->clone();
393  unsigned long allZero = 0x00000000;
394  pnbZeroMsg->reset_num_bits();
395  pnbZeroMsg->addUnsignedLong(bits_1_32,32,1);
396  pnbZeroMsg->addUnsignedLong(bits_33_38,6,1);
397  pnbZeroMsg->addUnsignedLong(allZero,26,1); // bits 39- 64
398  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 65- 96
399  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 97-128
400  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 129-160
401  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 161-192
402  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 193-224
403  pnbZeroMsg->addUnsignedLong(allZero,32,1); // bits 225-256
404  pnbZeroMsg->addUnsignedLong(allZero,20,1); // bits 257-276
405  pnbZeroMsg->addUnsignedLong(bits_277_300,24,1);
406 
407  pnbZeroMsg->trimsize();
408 
409  CNavFilterData fdZero(pnbZeroMsg);
410  gnsstk::NavFilter::NavMsgList l = mgr.validate(&fdZero);
411  acceptCount += l.size();
412  rejectCount += filtEmpty.rejected.size();
413  delete pnbZeroMsg;
414 
415  // Now build a 0/1 message (since the IS isn't totally
416  // specific on whether its 1/0 or 0/1)
417  unsigned long alt01 = 0x55555555;
418  int startBit = 39 - 1; // Bit 39 (1 based) == Bit 38 (0 based)
419  int nBitsPerWord = 32;
420  int endBit = 277;
421  int lastPossibleStartBit = endBit - nBitsPerWord;
422  PackedNavBits* pnb01Msg = p->clone();
423  while (startBit < lastPossibleStartBit)
424  {
425  pnb01Msg->insertUnsignedLong(alt01,startBit,32);
426  startBit += 32;
427  }
428  int lastNBits = endBit - startBit;
429  alt01 >>= (32 - lastNBits);
430  pnb01Msg->insertUnsignedLong(alt01,startBit,lastNBits);
431 
432  CNavFilterData fd01Msg(pnb01Msg);
433  l = mgr.validate(&fd01Msg);
434  acceptCount += l.size();
435  rejectCount += filtEmpty.rejected.size();
436  delete pnb01Msg;
437 
438  TUASSERTE(unsigned long, 0, acceptCount);
439  TUASSERTE(unsigned long, 2, rejectCount);
440  TURETURN();
441 }
442 
443 //-------------------------------------------------------------------
444 unsigned CNavFilter_T ::
446 {
447  TUDEF("CNavTOWFilter", "validate");
448 
449  NavFilterMgr mgr;
450  unsigned long rejectCount = 0;
451  unsigned long acceptCount = 0;
452  CNavTOWFilter filtTOW;
453 
454  mgr.addFilter(&filtTOW);
455 
456  list<CNavFilterData>::iterator it;
457  for (it=cNavList.begin(); it!=cNavList.end(); it++)
458  {
459  CNavFilterData& fd = *it;
461  rejectCount += filtTOW.rejected.size();
462  acceptCount += l.size();
463  }
464  int expected = cNavList.size();
465  TUASSERTE(unsigned long, expected, acceptCount);
466  TUASSERTE(unsigned long, 0, rejectCount);
467 
468  // --- NOW GENERATE SOME INVALID MESSAGES AND VERIFY THAT
469  // --- THEY ARE REJECTED
470  // Modify a message to have an invalid TOW count.
471  acceptCount = 0;
472  rejectCount = 0;
473  CNavFilterData fd;
474  list<PackedNavBits*>::iterator it2 = messageList.begin();
475  PackedNavBits* p = *it2;
476 
477  // Message with invalid too large) TOW
478  PackedNavBits* pnbBadTOWMsg = p->clone();
479  unsigned long badTOW = 604800;
480  pnbBadTOWMsg->insertUnsignedLong(badTOW, 20, 17, 6);
481 
482  // Message with invalid preamble
483  PackedNavBits* pnbBadPreamble = p->clone();
484  unsigned long badPre = 0;
485  pnbBadPreamble->insertUnsignedLong(badPre, 0, 8);
486 
487  acceptCount = 0;
488  rejectCount = 0;
489  CNavFilterData fdBadTOW(pnbBadTOWMsg);
490  gnsstk::NavFilter::NavMsgList l = mgr.validate(&fdBadTOW);
491  rejectCount += filtTOW.rejected.size();
492  acceptCount += l.size();
493 
494  CNavFilterData fdBadPreamble(pnbBadPreamble);
495  l = mgr.validate(&fdBadPreamble);
496  rejectCount += filtTOW.rejected.size();
497  acceptCount += l.size();
498 
499  // Bad Message Type tests
500  // Test the invalid MT immediately above/below the valid ranges.
501  unsigned long badMT[] = { 9, 16, 29, 40};
502  int badMTCount = 4;
503  PackedNavBits* pnbBadMT = p->clone();
504  for (int i=0; i<badMTCount; i++)
505  {
506  pnbBadMT->insertUnsignedLong(badMT[i], 14, 6);
507  CNavFilterData fdBadMT(pnbBadMT);
508  l = mgr.validate(&fdBadMT);
509  rejectCount += filtTOW.rejected.size();
510  acceptCount += l.size();
511  }
512  delete pnbBadMT;
513  delete pnbBadTOWMsg;
514  delete pnbBadPreamble;
515 
516  unsigned long expReject = 2 + badMTCount;
517  TUASSERTE(unsigned long, 0, acceptCount);
518  TUASSERTE(unsigned long, expReject, rejectCount);
519 
520  TURETURN();
521 }
522 
523 //-------------------------------------------------------------------
524 unsigned CNavFilter_T ::
526 {
527  TUDEF("CNavFilter-Combined", "validate");
528 
529  NavFilterMgr mgr;
530  unsigned long rejectCount = 0;
531  CNavParityFilter filtParity;
532  CNavEmptyFilter filtEmpty;
533  CNavTOWFilter filtTOW;
534 
535  mgr.addFilter(&filtParity);
536  mgr.addFilter(&filtEmpty);
537  mgr.addFilter(&filtTOW);
538 
539  list<CNavFilterData>::iterator it;
540  for (it=cNavList.begin(); it!=cNavList.end(); it++)
541  {
542  CNavFilterData& fd = *it;
544  // if l is empty, the subframe was rejected..
545  rejectCount += l.empty();
546  }
547  int expected = cNavList.size();
548  TUASSERTE(unsigned long, 0, rejectCount);
549  TURETURN();
550 }
551 
552 //-------------------------------------------------------------------
553 unsigned CNavFilter_T ::
555 {
556  TUDEF("CNavCrossSource", "validate");
557 
558  NavFilterMgr mgr;
559  unsigned long acceptCount = 0;
560  unsigned long rejectCount = 0;
561  unsigned long expReject = 0;
562  CNavCookFilter filtCook;
563  CNavParityFilter filtParity;
564  CNavEmptyFilter filtEmpty;
565  CNavTOWFilter filtTOW;
566  CNavCrossSourceFilter filtXSource;
567 
568  //mgr.addFilter(&filtCook);
569  mgr.addFilter(&filtParity);
570  mgr.addFilter(&filtEmpty);
571  mgr.addFilter(&filtTOW);
572  mgr.addFilter(&filtXSource);
573 
574  // This is a bit different than the earlier tests. The list will
575  // be empty until the epoch changes, then (if successful) it
576  // will contain a list of the accepted messages.
577 
578  // For the first test, simply submit each message TWICE, thus
579  // simulating the same message being received from different
580  // sources.
581  unsigned short cnt = 0;
583  NavFilterMgr::FilterSet::const_iterator fsi;
584  NavFilter::NavMsgList::const_iterator nmli;
585  list<CNavFilterData>::iterator it;
586 
587  // DEBUG: Dump of list of the CNavList pointers for comparison
588  //cout << " Here are the CNavList pointer values: " << endl;
589  //for (it=cNavList.begin(); it!=cNavList.end(); it++)
590  //{
591  // CNavFilterData& fd = *it;
592  // cout << " ptr: " << &fd << endl;
593  //}
594 
595  for (it=cNavList.begin(); it!=cNavList.end(); it++)
596  {
597  CNavFilterData& fd = *it;
598  for (int n=0; n<2; n++)
599  {
600  l = mgr.validate(&fd);
601 
602  // At change of epoch, l.size() will be noo-zero
603  acceptCount += l.size();
604 
605  // Count any rejects
606  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
607  {
608  for (nmli=(*fsi)->rejected.begin();
609  nmli!=(*fsi)->rejected.end();nmli++)
610  {
611  CNavFilterData* fd = dynamic_cast<CNavFilterData*>(*nmli);
612  rejectCount++;
613  // Should NOT be any rejected data in this test. Even if there IS,
614  // we do not want to delete the data as the deletion will "orphan"
615  // a pointer in CNavList that is going to be reused.
616  //delete fd;
617  }
618  }
619  cnt++;
620  }
621  }
622  l = mgr.finalize();
623  acceptCount += l.size();
624  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
625  {
626  for (nmli=(*fsi)->rejected.begin();
627  nmli!=(*fsi)->rejected.end();nmli++)
628  {
629  CNavFilterData* fd = dynamic_cast<CNavFilterData*>(*nmli);
630  rejectCount++;
631  //delete fd;
632  }
633  }
634 
635  // Mulitply because we submitted each message twice.
636  int expected = cNavList.size() * 2;
637  TUASSERTE(unsigned long, expected, acceptCount);
638  TUASSERTE(unsigned long, 0, rejectCount);
639 
640  // DEBUG TEST - To Understand filter operation
641  //cout << "Dump of filtXSource after all is finalized" << endl;
642  //filtXSource.dump(std::cout);
643 
644  // For the third test, submit each message TWICE,
645  // then create a clone with
646  // 1. a different station ID,
647  // 2. a different receiver ID,
648  // 3. a different, but still relevant, tracking code.
649  // (e.g L2CM and L2CML)
650  // All three messages should be accepted.
651  cnt = 0;
652  acceptCount = 0;
653  rejectCount = 0;
654  for (it=cNavList.begin(); it!=cNavList.end(); it++)
655  {
656  CNavFilterData& fd = *it;
657  for (int n=0; n<3; n++)
658  {
659  // Zero out the CRC. NOTE: In doing so,
660  // we are modifying the input data. If we want to add any
661  // tests below that re-use these data, we'll need to modify thiat
662  // to create a clone (and delete it when rejected).
663  if (n==2)
664  {
665  fd.stationID = "unk2";
666  fd.rxID = "unk2";
667  fd.code = TrackingCode::L2CM;
668  fd.pnb->setRxID("unk2");
669  ObsID oid2(ObservationType::NavMsg, CarrierBand::L2, TrackingCode::L2CM);
670  fd.pnb->setObsID(oid2);
671  }
672 
673  l = mgr.validate(&fd);
674 
675  // At change of epoch, l.size() will be noo-zero
676  acceptCount += l.size();
677 
678  // Count any rejects
679  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
680  {
681  for (nmli=(*fsi)->rejected.begin();
682  nmli!=(*fsi)->rejected.end();nmli++)
683  {
684  CNavFilterData* fd = dynamic_cast<CNavFilterData*>(*nmli);
685  rejectCount++;
686  // If we later create "flawed clones" of the original data,
687  // we would delete them here.
688  //delete fd;
689  }
690  }
691  cnt++;
692  }
693  }
694  l = mgr.finalize();
695  acceptCount += l.size();
696  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
697  {
698  for (nmli=(*fsi)->rejected.begin();
699  nmli!=(*fsi)->rejected.end();nmli++)
700  {
701  CNavFilterData* fd = dynamic_cast<CNavFilterData*>(*nmli);
702  rejectCount++;
703  //delete fd;
704  }
705  }
706 
707  // DEBUG TEST - To Understand filter operation
708  //cout << "Dump of filtXSource after all is finalized" << endl;
709  //filtXSource.dump(std::cout);
710 
711  // Mulitply because we submitted each message three times.
712  expected = cNavList.size() * 3;
713  expReject = 0;
714  TUASSERTE(unsigned long, expected, acceptCount);
715  TUASSERTE(unsigned long, expReject, rejectCount);
716 
717  // For the third test, submit each message TWICE,
718  // then create a clone, zero-out the CRC, and submit
719  // the message a third time. The third message should
720  // be rejected, but there should still be two accepted messages.
721  //
722  // NOTE:
723  unsigned long zeroes = 0x00000000;
724  cnt = 0;
725  acceptCount = 0;
726  rejectCount = 0;
727  for (it=cNavList.begin(); it!=cNavList.end(); it++)
728  {
729  CNavFilterData& fd = *it;
730  for (int n=0; n<3; n++)
731  {
732  // Zero out the CRC. NOTE: In doing so,
733  // we are modifying the input data. If we want to add any
734  // tests below that re-use these data, we'll need to modify thiat
735  // to create a clone (and delete it when rejected).
736  if (n==2)
737  {
738  fd.pnb->insertUnsignedLong(zeroes, 276, 24);
739  }
740 
741  l = mgr.validate(&fd);
742 
743  // At change of epoch, l.size() will be noo-zero
744  acceptCount += l.size();
745 
746  // Count any rejects
747  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
748  {
749  for (nmli=(*fsi)->rejected.begin();
750  nmli!=(*fsi)->rejected.end();nmli++)
751  {
752  CNavFilterData* fdp = dynamic_cast<CNavFilterData*>(*nmli);
753  rejectCount++;
754 
755  // Avoid this step because we don't want to delete the
756  // objects on cNavList, even though we're modifying them.
757  //delete fdp;
758  }
759  }
760  cnt++;
761  }
762  }
763  l = mgr.finalize();
764  acceptCount += l.size();
765  for (fsi=mgr.rejected.begin(); fsi!=mgr.rejected.end(); fsi++)
766  {
767  for (nmli=(*fsi)->rejected.begin();
768  nmli!=(*fsi)->rejected.end();nmli++)
769  {
770  CNavFilterData* fd = dynamic_cast<CNavFilterData*>(*nmli);
771  rejectCount++;
772  //delete fd;
773  }
774  }
775 
776  // Mulitply because we (successfully) submitted each message twice.
777  expected = cNavList.size() * 2;
778  expReject = cNavList.size();
779  TUASSERTE(unsigned long, expected, acceptCount);
780  TUASSERTE(unsigned long, expReject, rejectCount);
781 
782  TURETURN();
783 }
784 
785 //-------------------------------------------------------------------
786 int main()
787 {
788  unsigned errorTotal = 0;
789 
790  CNavFilter_T testClass;
791 
792  errorTotal += testClass.loadData();
793  errorTotal += testClass.noFilterTest();
794  errorTotal += testClass.testCNavCook();
795  errorTotal += testClass.testCNavParity();
796  errorTotal += testClass.testCNavEmpty();
797  errorTotal += testClass.testCNavTOW();
798  errorTotal += testClass.testCNavCombined();
799  errorTotal += testClass.testCNavCrossSource();
800 
801  cout << "Total Failures for " << __FILE__ << ": " << errorTotal << endl;
802 
803  return errorTotal; // Return the total number of errors
804 }
CNavFilter_T::testCNavEmpty
unsigned testCNavEmpty()
Test the LNAV empty subframe filter.
Definition: CNavFilter_T.cpp:321
CNavFilter_T
Definition: CNavFilter_T.cpp:58
TimeSystem.hpp
CNavFilter_T::testCNavTOW
unsigned testCNavTOW()
Test the TLM and HOW filter.
Definition: CNavFilter_T.cpp:445
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
CNavParityFilter.hpp
gnsstk::PackedNavBits::setRxID
void setRxID(const std::string rxString)
Definition: PackedNavBits.cpp:197
CNavFilter_T::testCNavCook
unsigned testCNavCook()
Cook the subframes.
Definition: CNavFilter_T.cpp:226
gnsstk::PackedNavBits::match
bool match(const PackedNavBits &right, const short startBit=0, const short endBit=-1, const unsigned flagBits=mmALL) const
Definition: PackedNavBits.cpp:1079
gnsstk::PackedNavBits::reset_num_bits
void reset_num_bits(const int new_bits_used=0)
Definition: PackedNavBits.cpp:932
gnsstk::NavFilterMgr::rejected
FilterSet rejected
Definition: NavFilterMgr.hpp:233
CNavFilter_T::~CNavFilter_T
~CNavFilter_T()
Definition: CNavFilter_T.cpp:99
CNavFilter_T::testCNavCrossSource
unsigned testCNavCrossSource()
Test the combination of cook,parity, empty, TOW, and cross-source filters.
Definition: CNavFilter_T.cpp:554
StringUtils.hpp
gnsstk::PackedNavBits::asUnsignedLong
unsigned long asUnsignedLong(const int startBit, const int numBits, const int scale) const
Definition: PackedNavBits.cpp:265
gnsstk::PackedNavBits::invert
void invert()
Definition: PackedNavBits.cpp:841
TUASSERTE
#define TUASSERTE(TYPE, EXP, GOT)
Definition: TestUtil.hpp:81
main
int main()
Definition: CNavFilter_T.cpp:786
CNavFilter_T::CNavFilter_T
CNavFilter_T()
Definition: CNavFilter_T.cpp:92
gnsstk::CNavTOWFilter
Definition: CNavTOWFilter.hpp:56
CNavFilter_T::testCNavCombined
unsigned testCNavCombined()
Test the combination of parity, empty and TOW filters.
Definition: CNavFilter_T.cpp:525
gnsstk::SatID
Definition: SatID.hpp:89
gnsstk::NavFilterMgr::finalize
virtual NavFilter::NavMsgList finalize()
Definition: NavFilterMgr.cpp:78
gnsstk::NavFilter::rejected
NavMsgList rejected
Definition: NavFilter.hpp:137
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
NavFilter.hpp
gnsstk::StringUtils::split
std::vector< std::string > split(const std::string &str, const char delimiter=' ')
Definition: StringUtils.hpp:2275
gnsstk::GPSWeekSecond
Definition: GPSWeekSecond.hpp:56
gnsstk::NavFilterMgr
Definition: NavFilterMgr.hpp:170
gnsstk::StringUtils::words
std::string words(const std::string &s, const std::string::size_type firstWord=0, const std::string::size_type numWords=std::string::npos, const char delimiter=' ')
Definition: StringUtils.hpp:2199
gnsstk::StringUtils::x2uint
unsigned int x2uint(const std::string &s)
Definition: StringUtils.hpp:1773
gnsstk::CNavParityFilter
Definition: CNavParityFilter.hpp:53
CNavCrossSourceFilter.hpp
gnsstk::PackedNavBits::setObsID
void setObsID(const ObsID &obsIDArg)
Definition: PackedNavBits.cpp:185
CNavFilter_T::testCNavParity
unsigned testCNavParity()
Test the LNAV parity filter.
Definition: CNavFilter_T.cpp:274
TestUtil.hpp
gnsstk::NavFilterMgr::addFilter
void addFilter(NavFilter *filt)
Definition: NavFilterMgr.cpp:50
gnsstk::PackedNavBits::insertUnsignedLong
void insertUnsignedLong(const unsigned long value, const int startBit, const int numBits, const int scale=1)
Definition: PackedNavBits.cpp:889
TURETURN
#define TURETURN()
Definition: TestUtil.hpp:232
gnsstk::PackedNavBits::trimsize
void trimsize()
Definition: PackedNavBits.cpp:938
NavFilterMgr.hpp
gnsstk::ObsID
Definition: ObsID.hpp:82
gnsstk::CNavFilterData
Definition: CNavFilterData.hpp:48
CNavTOWFilter.hpp
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::CNavCrossSourceFilter
Definition: CNavCrossSourceFilter.hpp:57
CNavEmptyFilter.hpp
TUDEF
#define TUDEF(CLASS, METHOD)
Definition: TestUtil.hpp:56
CNavFilterData.hpp
CNavCookFilter.hpp
CNavFilter_T::messageList
list< PackedNavBits * > messageList
Definition: CNavFilter_T.cpp:83
gnsstk::PackedNavBits::clone
PackedNavBits * clone() const
Definition: PackedNavBits.cpp:174
gnsstk::CNavEmptyFilter
Definition: CNavEmptyFilter.hpp:55
gnsstk::NavFilterKey::stationID
std::string stationID
site/station identifier for data source
Definition: NavFilterKey.hpp:76
GPSWeekSecond.hpp
CNavFilter_T::noFilterTest
unsigned noFilterTest()
Test to make sure that with no filters, no data is removed.
Definition: CNavFilter_T.cpp:201
CommonTime.hpp
std
Definition: Angle.hpp:142
gnsstk::NavFilterMgr::validate
NavFilter::NavMsgList validate(NavFilterKey *msgBits)
Definition: NavFilterMgr.cpp:57
gnsstk::NavFilterKey::code
gnsstk::TrackingCode code
ranging code of navigation message
Definition: NavFilterKey.hpp:80
gnsstk::StringUtils::strip
std::string & strip(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1482
CNavFilter_T::cNavList
list< CNavFilterData > cNavList
Definition: CNavFilter_T.cpp:87
gnsstk::NavFilter::NavMsgList
std::list< NavFilterKey * > NavMsgList
Definition: NavFilter.hpp:58
CNavFilter_T::loadData
unsigned loadData()
Definition: CNavFilter_T.cpp:110
gnsstk::PackedNavBits::addUnsignedLong
void addUnsignedLong(const unsigned long value, const int numBits, const int scale)
Definition: PackedNavBits.cpp:613
gnsstk::PackedNavBits
Definition: PackedNavBits.hpp:70
gnsstk::CNavFilterData::pnb
PackedNavBits * pnb
Definition: CNavFilterData.hpp:57
L2
gnsstk::Matrix< double > L2
Definition: Matrix_LUDecomp_T.cpp:46
gnsstk::NavFilterKey::rxID
std::string rxID
receiver identifier for data source
Definition: NavFilterKey.hpp:77
TimeString.hpp
gnsstk::CNavCookFilter
Definition: CNavCookFilter.hpp:54


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:38