Commit 7b5b5790 authored by garciay's avatar garciay
Browse files

Validate AtsRSUSimulator for CAM & DENM

parent c7aefb41
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -149,12 +149,13 @@ int GeoNetworkingCodec::decode_ (Base_Type& type, const TTCN_Typedescriptor_t& f
        break;
      } // End of 'switch' statement
      _dc.lifetime = base * static_cast<unsigned int>(l.multiplier());
      //loggers::get_instance().log("GeoNetworkingCodec::decode_: Lifetime calculus: %d - %s", _dc.lifetime, std::to_string(_dc.lifetime).c_str());
    } else if (std::string(type.get_descriptor()->name).compare("@LibItsGeoNetworking_TypesAndValues.TrafficClass") == 0) {
      LibItsGeoNetworking__TypesAndValues::TrafficClass& t = static_cast<LibItsGeoNetworking__TypesAndValues::TrafficClass&>(r);
      _dc.traffic_class = (t.scf().as_int() << 7) | (t.channelOffload() << 6) | (t.tcId() & 0x3f); // ETSI EN 302 636-4-1 chapter 8.7.5
    }
  } else if (std::string(type.get_descriptor()->name).compare("@IEEE1609dot2::Ieee1609Dot2Data") == 0) {
    dynamic_cast<OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data> &>(type).set_to_omit();
  } else if (std::string(type.get_descriptor()->name).compare("@IEEE1609dot2.Ieee1609Dot2Data") == 0) {
    dynamic_cast<OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data> &>(type).set_to_omit(); // TODO Add security support
  } else {
    loggers::get_instance().log("GeoNetworkingCodec::decode_ (else): processing type %s/%s - optional:%d", type.get_descriptor()->name, field_descriptor.name, type.is_optional());
    if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.nextHeader") == 0) {
@@ -352,15 +353,14 @@ int GeoNetworkingCodec::decode_extendedHeader(LibItsGeoNetworking__TypesAndValue
    decode_(u.anyHeader(), *u.anyHeader().get_descriptor(), decoding_buffer);
    break;
  case LibItsGeoNetworking__TypesAndValues::HeaderType::e__serviceAnnouncement:
    // TODO Check that Service Advertisment (ETSI TS 102 890-1) uses TSB
    decode_(u.tsbHeader(), *u.tsbHeader().get_descriptor(), decoding_buffer);
    // if (_dc.header_sub_type == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeSa::e__sa) {
    //   decode_(u.saHeader(), *u.saHeader().get_descriptor(), decoding_buffer);
    // } else if (_dc.header_sub_type == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeSa::e__saEos) {
    //   decode_(u.saEosHeader(), *u.saEosHeader().get_descriptor(), decoding_buffer);
    // } else {
    //   TTCN_error("GeoNetworkingCodec::decode_headerTST: Service Advertisement subtype not processed");
    // }
    // Check that Service Advertisment (ETSI TS 102 890-1) uses TSB
    if (_dc.header_sub_type == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeSa::e__sa) {
      decode_(u.saHeader(), *u.saHeader().get_descriptor(), decoding_buffer);
    } else if (_dc.header_sub_type == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeSa::e__saEos) {
      decode_(u.saEosHeader(), *u.saEosHeader().get_descriptor(), decoding_buffer);
    } else {
      TTCN_error("GeoNetworkingCodec::decode_headerTST: Service Advertisement subtype not processed");
    }
    break;
  default:
    TTCN_error("GeoNetworkingCodec::decode_headerTST: Not processed, _dc.header_type = %d - _dc.header_sub_type = %d", _dc.header_type, _dc.header_sub_type);
@@ -368,4 +368,3 @@ int GeoNetworkingCodec::decode_extendedHeader(LibItsGeoNetworking__TypesAndValue

  return 0;
}
+135 −16
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@

using namespace LibItsGeoNetworking__TypesAndValues;

GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(NULL), _packet(NULL), _location_table(), _pass_beacon_table(), _device_mode{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0} {
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _packet(nullptr), _ls_reply(nullptr), _location_table(), _pass_beacon_table(), _device_mode{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0} {
  loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
  
  // Setup parameters
@@ -70,6 +70,8 @@ GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::st
  }

  fill_packet(latitude, longitude, ll_address, latitude, longitude, distanceA, distanceB, angle);// TODO Check if GeoBroadcastArea lat/lon are identical to lat/lon of the Test System
  
  fill_ls_reply(latitude, longitude, ll_address);
                                                                                                                                                                                                                                                                                                                                                                                        } // End of constructor

GeoNetworkingLayer::~GeoNetworkingLayer() {
@@ -85,6 +87,9 @@ GeoNetworkingLayer::~GeoNetworkingLayer() {
  if (_packet != nullptr) {
    delete _packet;
  }
  if (_ls_reply != nullptr) {
    delete _ls_reply;
  }
} // End of destructor

void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, Params& params) {
@@ -104,7 +109,7 @@ void GeoNetworkingLayer::sendData(OCTETSTRING& data, Params& params) {
  if (_device_mode) { // Need to build a GN packet
    params.log();// TODO To be removed
    ExtendedHeader* eh = static_cast<ExtendedHeader *>(_packet->gnPacket().packet().extendedHeader().get_opt_value());
    if (eh == NULL) {
    if (eh == nullptr) {
      loggers::get_instance().error("GeoNetworkingLayer::sendData: Wrong cast");
      return;
    }
@@ -169,6 +174,40 @@ void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
        if (ex.ischosen(LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsRequestHeader)) { // Receive a LocationService/LsRequest
          sopv = &ex.lsRequestHeader().srcPosVector();
          // TODO Send LsReply if we are not in context of GN ATS in case of non GN test suite
          if (_device_mode) {
            // Update _ls_reply
            ExtendedHeader* eh = static_cast<ExtendedHeader *>(_ls_reply->gnPacket().packet().extendedHeader().get_opt_value());
            if (eh != nullptr) {
              // Update sequence number
              eh->lsReplyHeader().seqNumber() = 1 + eh->lsReplyHeader().seqNumber(); // TODO Use a common counter
              // Update destination
              eh->lsReplyHeader().dstPosVector().gnAddr() = sopv->gnAddr();
              eh->lsReplyHeader().dstPosVector().latitude() = sopv->latitude();
              eh->lsReplyHeader().dstPosVector().longitude() = sopv->longitude();
              // Update timestamp
              unsigned long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - 1072911600000L;  // TODO Add method such as its_tme() & its_time_mod()
              eh->lsReplyHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(ms));
              eh->lsReplyHeader().dstPosVector().timestamp__() = eh->lsReplyHeader().srcPosVector().timestamp__();
              
              loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: ", *_ls_reply);
              
              // send it
              // Encode GeoNetworking PDU
              OCTETSTRING os;
              _codec.encode(*_ls_reply, os);
              // Send it
              // TODO To be removed
              while (_sendData.try_lock() == FALSE) {
                // not ready yet
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
              } // End of 'while' statement
              sendToAllLayers(os, params);
              _sendData.unlock();
            } else {
              loggers::get_instance().error("GeoNetworkingLayer::sendData: Wrong cast");
              return;
            }
          }
        } else {
          sopv = &ex.lsReplyHeader().srcPosVector();
        }
@@ -192,13 +231,13 @@ void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
    
    // By default incoming beacons are filtered by the test adapter
    if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_beaconHdr)) {
      loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Pass beaconing processing", htst);
      loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Pass beaconing filtering", htst);
      if (_pass_beacon_table.empty()) { // Discard beacon
        loggers::get_instance().log("GeoNetworkingLayer::receiveData: Pass beaconing table empty, skip it");
        loggers::get_instance().log("GeoNetworkingLayer::receiveData: Pass beaconing table empty, discard it");
        return;
      } else { // Check beacon filter for StartPassBeaconing/Stop
        if (!_pass_beacon_table.has_entry(sopv->gnAddr().mid())) { // Discard beacon
          loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Not in pass beaconing table, skip it", *sopv);
          loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Not in pass beaconing table, discard it", *sopv);
          return;
        } // else, continue
      }
@@ -261,14 +300,14 @@ void GeoNetworkingLayer::start_beaconing() {
  _sa.sa_flags = SA_SIGINFO;
  _sa.sa_sigaction = timer_irq_sigalrm_handler;
  sigemptyset(&_sa.sa_mask);
  if (sigaction(_signal_id, &_sa, NULL) == -1) {
  if (sigaction(_signal_id, &_sa, nullptr) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigaction failure: %d", errno);
  }
  // Block timer signal temporarily
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Blocking signal %d\n", _signal_id);
  sigemptyset(&_mask);
  sigaddset(&_mask, _signal_id);
  if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
  if (sigprocmask(SIG_SETMASK, &_mask, nullptr) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }	
  // Create the timer 
@@ -283,19 +322,19 @@ void GeoNetworkingLayer::start_beaconing() {
  unsigned int expiry = 1000; // Default expiry time 1000ms
  Params::const_iterator i = _params.find("expiry");
  if (i != _params.cend()) {
    expiry = static_cast<unsigned int>(std::strtoul(i->second.c_str(), NULL, 10));
    expiry = static_cast<unsigned int>(std::strtoul(i->second.c_str(), nullptr, 10));
  }
  _freq_nanosecs = expiry * 1000000;
  _its.it_value.tv_sec = _freq_nanosecs / 1000000000;
  _its.it_value.tv_nsec = _freq_nanosecs % 1000000000;
  _its.it_interval.tv_sec = _its.it_value.tv_sec;
  _its.it_interval.tv_nsec = _its.it_value.tv_nsec;
  if (timer_settime(_timerid, 0, &_its, NULL) == -1) {
  if (timer_settime(_timerid, 0, &_its, nullptr) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }
  // Unlock the timer signal, so that timer notification can be delivered
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Unblocking signal %d\n", _signal_id);
  if (sigprocmask(SIG_UNBLOCK, &_mask, NULL) == -1) {
  if (sigprocmask(SIG_UNBLOCK, &_mask, nullptr) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }
} // End of start_beaconing method
@@ -319,7 +358,7 @@ void GeoNetworkingLayer::stop_beaconing() {
  loggers::get_instance().log("GeoNetworkingLayer::stop_beaconing: Blocking signal %d\n", _signal_id);
  sigemptyset(&_mask);
  sigaddset(&_mask, _signal_id);
  if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
  if (sigprocmask(SIG_SETMASK, &_mask, nullptr) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::stop_beaconing: Sigprocmask failure: %d", errno);
  }	
  timer_delete(_timerid);
@@ -330,7 +369,7 @@ void GeoNetworkingLayer::send_beacon() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::send_beacon");
  
  ExtendedHeader* eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
  if (eh == NULL) {
  if (eh == nullptr) {
    loggers::get_instance().error("GeoNetworkingLayer::send_beacon: Wrong cast");
  }
  // Update timestamp
@@ -342,8 +381,14 @@ void GeoNetworkingLayer::send_beacon() {
  _beacon->encode(*(_beacon->get_descriptor()), encoding_buffer, TTCN_EncDec::CT_RAW);
  OCTETSTRING data(encoding_buffer.get_len(), encoding_buffer.get_data());
  // Send it
  // TODO To be removed
  while (_sendData.try_lock() == FALSE) {
    // not ready yet
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  } // End of 'while' statement
  Params params(_params);
  sendData(data, params);
  sendToAllLayers(data, params);
  _sendData.unlock();
  
  //loggers::get_instance().log("<<< GeoNetworkingLayer::send_beacon");
} // End of send_beacon method
@@ -506,6 +551,81 @@ void GeoNetworkingLayer::fill_packet(const INTEGER& p_latitude, const INTEGER& p
  //loggers::get_instance().log_msg("GeoNetworkingLayer::fill_packet: packet value: ", *_packet);
} // End of fill_packet method
  
void GeoNetworkingLayer::fill_ls_reply(const INTEGER& p_latitude, const INTEGER& p_longitude, const OCTETSTRING& p_ll_address)
{
  _ls_reply = new GeoNetworkingPdu();
  HeaderTST h;
  h.lsHdr() = LsHeaderType(
                           HeaderType(HeaderType::e__locationService),
                           HeaderSubTypeLs(HeaderSubTypeLs::e__lsReply)
                           );
  ExtendedHeader eh;
  eh.lsReplyHeader() = LSReplyHeader(
                                     0,
                                     0,
                                     LongPosVector(
                                                   GN__Address(
                                                               TypeOfAddress(TypeOfAddress::e__manual), // TODO Use Params
                                                               StationType(StationType::e__passengerCar), // TODO Use Params
                                                               33,
                                                               p_ll_address
                                                               ),
                                                   0,
                                                   p_latitude,
                                                   p_longitude,
                                                   int2bit(1, 1), // PAI
                                                   0,
                                                   0
                                                   ),
                                     ShortPosVector(
                                                    GN__Address(
                                                                TypeOfAddress(TypeOfAddress::e__manual), // TODO Use Params
                                                                StationType(StationType::e__passengerCar), // TODO Use Params
                                                                33,
                                                                p_ll_address
                                                                ),
                                                    0,
                                                    p_latitude,
                                                    p_longitude
                                                    )
                                     );
  _ls_reply->basicHeader() = BasicHeader(
                                         0,
                                         BasicNextHeader(
                                                         BasicNextHeader::e__commonHeader
                                                         ),
                                         0,
                                         Lifetime(
                                                  4,
                                                  LtBase(LtBase::e__50ms)
                                                  ),
                                         5
                                         );
  _ls_reply->gnPacket().packet() = GnNonSecuredPacket(
                                                      CommonHeader(
                                                                   NextHeader(
                                                                              NextHeader::e__any
                                                                              ),
                                                                   0,
                                                                   h,
                                                                   TrafficClass(
                                                                                SCF(SCF::e__scfDisabled),
                                                                                ChannelOffload(ChannelOffload::e__choffDisabled),
                                                                                0
                                                                                ),
                                                                   int2bit(128, 8), // Mobile stationnary flag set
                                                                   0,
                                                                   5,
                                                                   0
                                                                   ),
                                                      OPTIONAL<ExtendedHeader>(eh),
                                                      OPTIONAL<GnRawPayload>()
                                                      );
  _ls_reply->gnPacket().packet().payload().set_to_omit();
  _ls_reply->gnPacket().securedMsg().set_to_omit();
  //loggers::get_instance().log_msg("GeoNetworkingLayer::fill_ls_reply: packet value: ", *_ls_reply);
} // End of fill_ls_reply method
  
void GeoNetworkingLayer::timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc) {
  //loggers::get_instance().log(">>> GeoNetworkingLayer::timer_irq_sigalrm_handler: Caught signal %d", p_signal);

@@ -513,4 +633,3 @@ void GeoNetworkingLayer::timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_si
} // End of method timer_irq_sigalrm_handler

GeoNetworkingLayerFactory GeoNetworkingLayerFactory::_f;
+25 −15
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ namespace LibItsGeoNetworking__TypesAndValues {
  class GN__Address;
}

// TODO Change pointers into smart pointers
class GeoNetworkingLayer : public TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort> {
  Params _params;
  GeoNetworkingCodec _codec;
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _beacon;
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _packet;
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _beacon;   /*!< Data structure used for beaconing */
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _packet;   /*!< Data structure used to encapsulate upper layer PDU into a GeoNetworking packet */
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _ls_reply; /*!< Data structure used to reply to an incoming LS_REQUEST */
  LocationTable _location_table;
  LocationTable _pass_beacon_table;
  bool _device_mode;
@@ -49,22 +51,30 @@ class GeoNetworkingLayer : public TLayer<LibItsGeoNetworking__TestSystem::GeoNet
  sigset_t _mask;
  struct sigaction _sa;

  /**
   * @desc Initialize a beacon object for a stand alone beaconing
  /*!
   * \brief Initialize a beacon object for a stand alone beaconing
   *        This object could be replaced in case of start_beaconing call from the Adapter Control Port
   * @param p_latitude
   * @param p_longitude
   * @param p_address
   * \param[in] p_latitude
   * \param[in] p_longitude
   * \param[in] p_address
   */ 
  void fill_beacon(INTEGER& p_latitude, INTEGER& p_longitude, OCTETSTRING& p_ll_address);
  /**
   * @desc Initialize a GeoNetworking packet to send GeoNetworking Facility messages
  /*!
   * \brief Initialize a GeoNetworking packet to send GeoNetworking Facility messages
   *        This object shall be updated before to be sent
   * @param p_latitude
   * @param p_longitude
   * @param p_address
   * \param[in] p_latitude
   * \param[in] p_longitude
   * \param[in] p_address
   */ 
  void fill_packet(const INTEGER& p_latitude, const INTEGER& p_longitude, const OCTETSTRING& p_ll_address, const INTEGER& p_geoAreaPosLatitude, const INTEGER& p_geoAreaPosLongitude, const INTEGER& p_distanceA, const INTEGER& p_distanceB, const INTEGER& p_angle = 0);  
  /*!
   * \brief Initialize an LS_REPLY GeoNetworking packet to reply to an LS_REQUEST
   *        This object shall be updated before to be sent
   * \param[in] p_latitude
   * \param[in] p_longitude
   * \param[in] p_address
   */ 
  void fill_ls_reply(const INTEGER& p_latitude, const INTEGER& p_longitude, const OCTETSTRING& p_ll_address);
  
  static void timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc);

+9 −21
Original line number Diff line number Diff line
@@ -6,42 +6,30 @@

using namespace LibItsGeoNetworking__TypesAndValues;

bool compare_octetstring::operator()(const OCTETSTRING& p_os1, const OCTETSTRING& p_os2) const
{
  if (p_os1.lengthof() > p_os2.lengthof()) {
    return false;
  } else if (p_os1.lengthof() < p_os2.lengthof()) {
    return true;
  } else {
    for (int i = 0; i < p_os1.lengthof(); i++) {
      if (p_os1[i].get_octet() < p_os2[i].get_octet()) {
        return true;
      }
    }
  }
  return false;
}

void LocationTable::add_entry(const LibItsGeoNetworking__TypesAndValues::LongPosVector& p_long_pos_vector) {
  loggers::get_instance().log_msg(">>> LocationTable::add_entry:", p_long_pos_vector);

  std::map<OCTETSTRING, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(p_long_pos_vector.gnAddr().mid());
  std::map<const std::string, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(std::string(oct2str(p_long_pos_vector.gnAddr().mid())));
  if (it == _entries_by_mids.cend()) { // Not found
    // Add it
    loggers::get_instance().log_to_hexa("LocationTable::add_entry: Create new entry: ", p_long_pos_vector.gnAddr().mid());
    std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector> lpv(new LibItsGeoNetworking__TypesAndValues::LongPosVector(p_long_pos_vector));
    _entries_by_mids.insert(std::pair<OCTETSTRING, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>(p_long_pos_vector.gnAddr().mid(), lpv));
    _entries_by_times.insert(std::pair<unsigned long, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>(static_cast<unsigned long>(p_long_pos_vector.timestamp__().get_long_long_val()), lpv));
    _entries_by_times.insert(std::pair<const unsigned long, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>(static_cast<const unsigned long>(p_long_pos_vector.timestamp__().get_long_long_val()), lpv));
    _entries_by_mids.insert(std::pair<const std::string, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>(std::string(oct2str(p_long_pos_vector.gnAddr().mid())), lpv));
  } else {
    // Remove entry from _entries_by_times.insert
    // TODO Update the timestamp
    // Add new entry in _entries_by_times.insert
  }
} // End of add_entry method

const bool LocationTable::has_entry(const OCTETSTRING& p_mid) const
{
  loggers::get_instance().log_to_hexa(">>> LocationTable::has_entry: ", p_mid);
  loggers::get_instance().log(">>> LocationTable::has_entry: l=%d", _entries_by_mids.size());
  //  loggers::get_instance().log_to_hexa(">>> LocationTable::has_entry: ", _entries_by_mids[0]);
  
  std::map<OCTETSTRING, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(p_mid);
  std::map<const std::string, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(std::string(oct2str(p_mid)));
  return (it != _entries_by_mids.cend());
}

@@ -54,7 +42,7 @@ const LibItsGeoNetworking__TypesAndValues::LongPosVector* LocationTable::get_ent
    return nullptr;
  }

  std::map<OCTETSTRING, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(p_mid);
  std::map<const std::string, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>>::const_iterator it = _entries_by_mids.find(std::string(oct2str(p_mid)));
  if (it == _entries_by_mids.cend()) { // Not found
    loggers::get_instance().warning("LocationTable::get_entry: Item not found");
    return nullptr;
+3 −8
Original line number Diff line number Diff line
@@ -10,18 +10,13 @@ namespace LibItsGeoNetworking__TypesAndValues {
  class LongPosVector;
}

struct compare_octetstring : public std::binary_function<OCTETSTRING, OCTETSTRING, bool>
{
  bool operator()(const OCTETSTRING& p_os2, const OCTETSTRING& p_os1) const;
};

class LocationTable {
  std::map<unsigned long, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector> > _entries_by_times;
  std::map<OCTETSTRING, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector>, compare_octetstring> _entries_by_mids;
  std::map<const unsigned long, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector> > _entries_by_times;
  std::map<const std::string, std::shared_ptr<LibItsGeoNetworking__TypesAndValues::LongPosVector> > _entries_by_mids;

public:
  LocationTable() : _entries_by_times(), _entries_by_mids() { };
  virtual ~LocationTable() { _entries_by_times.clear(); _entries_by_mids.clear();  }; // std::shared_ptr provides memory free process
  virtual ~LocationTable() { /*_entries_by_times.clear(); _entries_by_mids.clear();*/  }; // std::shared_ptr provides memory free process

  const bool has_entry(const OCTETSTRING& p_mid) const;
  void add_entry(const LibItsGeoNetworking__TypesAndValues::LongPosVector& p_long_pos_vector);