Commit 8eed389f authored by filatov's avatar filatov
Browse files

CAM and DENM codec using Asn1c

parent e691e238
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -20,11 +20,44 @@ public:
  virtual int decode(const OCTETSTRING& data, TPDUDec& msg, Params* params = NULL) = 0;
};

template<typename TPDU> class PERCodec
struct asn_TYPE_descriptor_s;
class ASN1Recode
{
protected:
  int ber2per (const asn_TYPE_descriptor_s & td, TTCN_Buffer & buf);
  int per2ber (const asn_TYPE_descriptor_s & td, TTCN_Buffer & buf);
  int recode  (const asn_TYPE_descriptor_s & td, int from, int to, TTCN_Buffer & buf);
};

template<typename TPDU> class PERCodec : public ASN1Recode
{
public:
  virtual int encode(const TPDU& msg, BITSTRING& bits) = 0;
  virtual int decode(const BITSTRING& bits, TPDU& msg) = 0;
protected:
  int _decode (const TTCN_Typedescriptor_t& ttcn, const asn_TYPE_descriptor_s & td, const BITSTRING& p_data, TPDU& msg) {
    TTCN_Buffer buf(bit2oct(p_data));
    TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
    int rc = per2ber (td, buf);
    if (rc > 0) {
      msg.decode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
      rc = buf.get_len();
    }
    return rc;
  }
  int _encode (const TTCN_Typedescriptor_t& ttcn, const asn_TYPE_descriptor_s & td, const TPDU& msg, BITSTRING& p_data) {
    int rc = -1;
    TTCN_Buffer buf;
    TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
    msg.encode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
    if (buf.get_len() > 0) {
      rc = ber2per (td, buf);
      if (rc > 0) {
        p_data = p_data + oct2bit(OCTETSTRING(buf.get_len(), buf.get_data()));
      }
    }
    return rc;
  }
};

#endif
+76 −456
Original line number Diff line number Diff line
#include "LibItsCam_TestSystem.hh"

#include "CAMCodec.hh"
#include "Asn1cEncDec.hh"

//asn1s
#include "asn1/CAM.h" // from asn1c
#include "asn1/CoopAwareness.h"
#include "asn1/BasicContainer.h"
#include "ITS_ContainerCodec.hh"
#include "asn1/asn_application.h" // from asn1c

#include "loggers.hh"

void titan2asn1c(const CAM__PDU__Descriptions::BasicContainer& t, BasicContainer_t& a)
{
	titan2asn1c(t.stationType(), a.stationType);
	titan2asn1c(t.referencePosition(), a.referencePosition);
}

CAM__PDU__Descriptions::BasicContainer asn1c2titan(const BasicContainer_t& a)
{
	return CAM__PDU__Descriptions::BasicContainer(
		asn1c2titan(a.stationType),
		asn1c2titan(a.referencePosition)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::BasicVehicleContainerHighFrequency& t, BasicVehicleContainerHighFrequency_t& a)
{
	titan2asn1c(t.heading(), a.heading);
	titan2asn1c(t.speed(), a.speed);
	titan2asn1c(t.driveDirection(), a.driveDirection);
	titan2asn1c(t.vehicleLength(), a.vehicleLength);
	titan2asn1c(t.vehicleWidth(), a.vehicleWidth);
	titan2asn1c(t.longitudinalAcceleration(), a.longitudinalAcceleration);
	titan2asn1c(t.curvature(), a.curvature);
	titan2asn1c(t.curvatureCalculationMode(), a.curvatureCalculationMode);
	titan2asn1c(t.yawRate(), a.yawRate);
	titan2asn1c_opt(t.accelerationControl(), a.accelerationControl);
	titan2asn1c_opt(t.lanePosition(), a.lanePosition);
	titan2asn1c_opt(t.steeringWheelAngle(), a.steeringWheelAngle);
	titan2asn1c_opt(t.lateralAcceleration(), a.lateralAcceleration);
	titan2asn1c_opt(t.verticalAcceleration(), a.verticalAcceleration);
	titan2asn1c_opt(t.performanceClass(), a.performanceClass);
	titan2asn1c_opt(t.cenDsrcTollingZone(), a.cenDsrcTollingZone);
}

CAM__PDU__Descriptions::BasicVehicleContainerHighFrequency asn1c2titan(const BasicVehicleContainerHighFrequency&a)
{
	return CAM__PDU__Descriptions::BasicVehicleContainerHighFrequency(
		asn1c2titan(a.heading),
		asn1c2titan(a.speed),
		asn1c2titan<ITS__Container::DriveDirection>(a.driveDirection),
		asn1c2titan(a.vehicleLength),
		asn1c2titan(a.vehicleWidth),
		asn1c2titan(a.longitudinalAcceleration),
		asn1c2titan(a.curvature),
		asn1c2titan<ITS__Container::CurvatureCalculationMode>(a.curvatureCalculationMode),
		asn1c2titan(a.yawRate),
		asn1c2titan_opt<BITSTRING>(a.accelerationControl),
		asn1c2titan_opt<INTEGER>(a.lanePosition),
		asn1c2titan_opt<ITS__Container::SteeringWheelAngle>(a.steeringWheelAngle),
		asn1c2titan_opt<ITS__Container::LateralAcceleration>(a.lateralAcceleration),
		asn1c2titan_opt<ITS__Container::VerticalAcceleration>(a.verticalAcceleration),
		asn1c2titan_opt<INTEGER>(a.performanceClass),
		asn1c2titan_opt<ITS__Container::CenDsrcTollingZone>(a.cenDsrcTollingZone)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::RSUContainerHighFrequency& t, RSUContainerHighFrequency_t& a)
{
	titan2asn1c_opt(t.protectedCommunicationZonesRSU(), a.protectedCommunicationZonesRSU);
}

CAM__PDU__Descriptions::RSUContainerHighFrequency asn1c2titan(const RSUContainerHighFrequency_t&a)
{
	return CAM__PDU__Descriptions::RSUContainerHighFrequency(
		asn1c2titan_opt<ITS__Container::ProtectedCommunicationZonesRSU>(a.protectedCommunicationZonesRSU)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::HighFrequencyContainer&t, HighFrequencyContainer_t& a)
{
	switch (t.get_selection()){
	case CAM__PDU__Descriptions::HighFrequencyContainer::ALT_basicVehicleContainerHighFrequency:
		a.present = HighFrequencyContainer_PR_basicVehicleContainerHighFrequency;
		titan2asn1c(t.basicVehicleContainerHighFrequency(), a.choice.basicVehicleContainerHighFrequency);
		break;
	case CAM__PDU__Descriptions::HighFrequencyContainer::ALT_rsuContainerHighFrequency:
		a.present = HighFrequencyContainer_PR_rsuContainerHighFrequency;
		titan2asn1c(t.rsuContainerHighFrequency(), a.choice.rsuContainerHighFrequency);
		break;
	default:
		a.present = HighFrequencyContainer_PR_NOTHING;
	}
}

const CAM__PDU__Descriptions::HighFrequencyContainer asn1c2titan(const HighFrequencyContainer_t& a)
{
	CAM__PDU__Descriptions::HighFrequencyContainer t;
	switch (a.present){
	case HighFrequencyContainer_PR_basicVehicleContainerHighFrequency:
		t.basicVehicleContainerHighFrequency() = asn1c2titan(a.choice.basicVehicleContainerHighFrequency);
		break;
	case HighFrequencyContainer_PR_rsuContainerHighFrequency:
		t.rsuContainerHighFrequency() = asn1c2titan(a.choice.rsuContainerHighFrequency);
		break;
	default:
		break;
	}
	return t;
}

void titan2asn1c(const CAM__PDU__Descriptions::BasicVehicleContainerLowFrequency&t, BasicVehicleContainerLowFrequency_t& a)
{
	titan2asn1c(t.vehicleRole(), a.vehicleRole);
	titan2asn1c(t.exteriorLights(), a.exteriorLights);
	titan2asn1c(t.pathHistory(), a.pathHistory);
}

CAM__PDU__Descriptions::BasicVehicleContainerLowFrequency asn1c2titan(const BasicVehicleContainerLowFrequency_t& a)
{
	return CAM__PDU__Descriptions::BasicVehicleContainerLowFrequency(
		asn1c2titan<ITS__Container::VehicleRole>(a.vehicleRole),
		asn1c2titan(a.exteriorLights),
		asn1c2titan(a.pathHistory)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::LowFrequencyContainer&t, LowFrequencyContainer_t& a)
{
	switch (t.get_selection()){
	case CAM__PDU__Descriptions::LowFrequencyContainer::ALT_basicVehicleContainerLowFrequency:
		a.present = LowFrequencyContainer_PR_basicVehicleContainerLowFrequency;
		titan2asn1c(t.basicVehicleContainerLowFrequency(), a.choice.basicVehicleContainerLowFrequency);
		break;
	default:
		a.present = LowFrequencyContainer_PR_NOTHING;
		break;
	}
}

CAM__PDU__Descriptions::LowFrequencyContainer asn1c2titan(const LowFrequencyContainer_t& a)
{
	CAM__PDU__Descriptions::LowFrequencyContainer t;
	switch (a.present){
	case LowFrequencyContainer_PR_basicVehicleContainerLowFrequency:
		t.basicVehicleContainerLowFrequency() = asn1c2titan(a.choice.basicVehicleContainerLowFrequency);
		break;
	default:
		break;
	}
	return t;
}

void titan2asn1c(const CAM__PDU__Descriptions::PublicTransportContainer& t, PublicTransportContainer_t& a)
{
	titan2asn1c(t.embarkationStatus(), a.embarkationStatus);
	titan2asn1c_opt(t.ptActivation(), a.ptActivation);
}
CAM__PDU__Descriptions::PublicTransportContainer asn1c2titan(const PublicTransportContainer_t& a)
{
	return CAM__PDU__Descriptions::PublicTransportContainer(
		asn1c2titan<BOOLEAN>(a.embarkationStatus),
		asn1c2titan_opt<ITS__Container::PtActivation>(a.ptActivation)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::SpecialTransportContainer& t, SpecialTransportContainer_t& a)
{
	titan2asn1c(t.specialTransportType(), a.specialTransportType);
	titan2asn1c(t.lightBarSirenInUse(), a.lightBarSirenInUse);
}
CAM__PDU__Descriptions::SpecialTransportContainer asn1c2titan(const SpecialTransportContainer_t& a)
{
	return CAM__PDU__Descriptions::SpecialTransportContainer(
		asn1c2titan(a.specialTransportType),
		asn1c2titan(a.lightBarSirenInUse)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::DangerousGoodsContainer& t, DangerousGoodsContainer_t& a)
{
	titan2asn1c(t.dangerousGoodsBasic(), a.dangerousGoodsBasic);
}

CAM__PDU__Descriptions::DangerousGoodsContainer asn1c2titan(const DangerousGoodsContainer_t& a)
{
	return CAM__PDU__Descriptions::DangerousGoodsContainer(asn1c2titan<ITS__Container::DangerousGoodsBasic>(a.dangerousGoodsBasic));
}

void titan2asn1c(const CAM__PDU__Descriptions::RoadWorksContainerBasic& t, RoadWorksContainerBasic_t& a)
{
	titan2asn1c_opt(t.roadworksSubCauseCode(), a.roadworksSubCauseCode);
	titan2asn1c(t.lightBarSirenInUse(), a.lightBarSirenInUse);
	titan2asn1c_opt(t.closedLanes(), a.closedLanes);
}

CAM__PDU__Descriptions::RoadWorksContainerBasic asn1c2titan(const RoadWorksContainerBasic_t& a)
{
	return CAM__PDU__Descriptions::RoadWorksContainerBasic(
		asn1c2titan_opt<INTEGER>(a.roadworksSubCauseCode),
		asn1c2titan(a.lightBarSirenInUse),
		asn1c2titan_opt<ITS__Container::ClosedLanes>(a.closedLanes)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::RescueContainer& t, RescueContainer_t& a)
{
	titan2asn1c(t.lightBarSirenInUse(), a.lightBarSirenInUse);
}

CAM__PDU__Descriptions::RescueContainer asn1c2titan(const RescueContainer_t& a)
{
	return CAM__PDU__Descriptions::RescueContainer(
		asn1c2titan(a.lightBarSirenInUse)
	);
}

void titan2asn1c(const CAM__PDU__Descriptions::EmergencyContainer& t, EmergencyContainer_t& a)
{
	titan2asn1c(t.lightBarSirenInUse(), a.lightBarSirenInUse);
	titan2asn1c_opt(t.incidentIndication(), a.incidentIndication);
	titan2asn1c_opt(t.emergencyPriority(), a.emergencyPriority);
}
CAM__PDU__Descriptions::EmergencyContainer asn1c2titan(const EmergencyContainer_t& a)
{
	return CAM__PDU__Descriptions::EmergencyContainer(
		asn1c2titan(a.lightBarSirenInUse),
		asn1c2titan_opt<ITS__Container::CauseCode>(a.incidentIndication),
		asn1c2titan_opt<BITSTRING>(a.emergencyPriority)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::SafetyCarContainer& t, SafetyCarContainer_t& a)
{
	titan2asn1c(t.lightBarSirenInUse(), a.lightBarSirenInUse);
	titan2asn1c_opt(t.incidentIndication(), a.incidentIndication);
	titan2asn1c_opt(t.trafficRule(), a.trafficRule);
	titan2asn1c_opt(t.speedLimit(), a.speedLimit);
}
CAM__PDU__Descriptions::SafetyCarContainer asn1c2titan(const SafetyCarContainer_t& a)
{
	return CAM__PDU__Descriptions::SafetyCarContainer(
		asn1c2titan(a.lightBarSirenInUse),
		asn1c2titan_opt<ITS__Container::CauseCode>(a.incidentIndication),
		asn1c2titan_opt<ITS__Container::TrafficRule>(a.trafficRule),
		asn1c2titan_opt<INTEGER>(a.speedLimit)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::SpecialVehicleContainer& t, SpecialVehicleContainer_t& a)
{
	switch (t.get_selection()){
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_publicTransportContainer:
		a.present = SpecialVehicleContainer_PR_publicTransportContainer;
		titan2asn1c(t.publicTransportContainer(), a.choice.publicTransportContainer);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_specialTransportContainer:
		a.present = SpecialVehicleContainer_PR_specialTransportContainer;
		titan2asn1c(t.specialTransportContainer(), a.choice.specialTransportContainer);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_dangerousGoodsContainer:
		a.present = SpecialVehicleContainer_PR_dangerousGoodsContainer;
		titan2asn1c(t.dangerousGoodsContainer(), a.choice.dangerousGoodsContainer);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_roadWorksContainerBasic:
		a.present = SpecialVehicleContainer_PR_roadWorksContainerBasic;
		titan2asn1c(t.roadWorksContainerBasic(), a.choice.roadWorksContainerBasic);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_rescueContainer:
		a.present = SpecialVehicleContainer_PR_rescueContainer;
		titan2asn1c(t.rescueContainer(), a.choice.rescueContainer);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_emergencyContainer:
		a.present = SpecialVehicleContainer_PR_emergencyContainer;
		titan2asn1c(t.emergencyContainer(), a.choice.emergencyContainer);
		break;
	case CAM__PDU__Descriptions::SpecialVehicleContainer::ALT_safetyCarContainer:
		a.present = SpecialVehicleContainer_PR_safetyCarContainer;
		titan2asn1c(t.safetyCarContainer(), a.choice.safetyCarContainer);
		break;
	default:
		a.present = SpecialVehicleContainer_PR_NOTHING;
	}

}
CAM__PDU__Descriptions::SpecialVehicleContainer asn1c2titan(const SpecialVehicleContainer& a){
	CAM__PDU__Descriptions::SpecialVehicleContainer t;
	switch (a.present){
	case SpecialVehicleContainer_PR_publicTransportContainer:
		t.publicTransportContainer() = asn1c2titan(a.choice.publicTransportContainer);
		break;
	case SpecialVehicleContainer_PR_specialTransportContainer:
		t.specialTransportContainer() = asn1c2titan(a.choice.specialTransportContainer);
		break;
	case SpecialVehicleContainer_PR_dangerousGoodsContainer:
		t.dangerousGoodsContainer() = asn1c2titan(a.choice.dangerousGoodsContainer);
		break;
	case SpecialVehicleContainer_PR_roadWorksContainerBasic:
		t.roadWorksContainerBasic() = asn1c2titan(a.choice.roadWorksContainerBasic);
		break;
	case SpecialVehicleContainer_PR_rescueContainer:
		t.rescueContainer() = asn1c2titan(a.choice.rescueContainer);
		break;
	case SpecialVehicleContainer_PR_emergencyContainer:
		t.emergencyContainer() = asn1c2titan(a.choice.emergencyContainer);
		break;
	case SpecialVehicleContainer_PR_safetyCarContainer:
		t.safetyCarContainer() = asn1c2titan(a.choice.safetyCarContainer);
		break;
	default:
		break;
	}
	return t;
}

void titan2asn1c(const CAM__PDU__Descriptions::CamParameters& t, CamParameters_t& a)
{
	titan2asn1c(t.basicContainer(), a.basicContainer);
	titan2asn1c(t.highFrequencyContainer(), a.highFrequencyContainer);
	titan2asn1c_opt(t.lowFrequencyContainer(), a.lowFrequencyContainer);
	titan2asn1c_opt(t.specialVehicleContainer(), a.specialVehicleContainer);
}

CAM__PDU__Descriptions::CamParameters asn1c2titan(const CamParameters_t& a)
{
	return CAM__PDU__Descriptions::CamParameters(
		asn1c2titan(a.basicContainer),
		asn1c2titan(a.highFrequencyContainer),
		asn1c2titan_opt<CAM__PDU__Descriptions::LowFrequencyContainer>(a.lowFrequencyContainer),
		asn1c2titan_opt<CAM__PDU__Descriptions::SpecialVehicleContainer>(a.specialVehicleContainer)
		);
}

void titan2asn1c(const CAM__PDU__Descriptions::CoopAwareness& t, CoopAwareness_t& a)
{
	titan2asn1c(t.generationDeltaTime(), a.generationDeltaTime);
	titan2asn1c(t.camParameters(), a.camParameters);
}

CAM__PDU__Descriptions::CoopAwareness asn1c2titan(const CoopAwareness_t& a)
{
	return CAM__PDU__Descriptions::CoopAwareness(
		asn1c2titan(a.generationDeltaTime),
		asn1c2titan(a.camParameters)
		);
}


static void titan2asn1c(const CAM__PDU__Descriptions::CAM& cam, CAM_t& _cam)
{
	titan2asn1c(cam.header(), _cam.header);
	titan2asn1c(cam.cam(), _cam.cam);
}

static CAM__PDU__Descriptions::CAM asn1c2titan(const CAM_t& a)
{
	return CAM__PDU__Descriptions::CAM(
		asn1c2titan(a.header),
		asn1c2titan(a.cam)
		);
}

int CAMCodec::encode (const CAM__PDU__Descriptions::CAM& cam, OCTETSTRING& data)
{
  loggers::get_instance().log(">>> CAMCodec::encode");
@@ -386,12 +29,31 @@ int CAMCodec::decode (const OCTETSTRING& data, CAM__PDU__Descriptions::CAM& cam,
  return rc;
}

extern "C" int asn1c_collect_cam_encoded_data(const void *buffer, size_t size, void *application_specific_key)
extern "C" {
  extern asn_TYPE_descriptor_t asn_DEF_CAM;
}

int CAMPDUCodec::encode (const CAM__PDU__Descriptions::CAM& p_cam, BITSTRING& p_data)
{
  return _encode(CAM__PDU__Descriptions::CAM_descr_, asn_DEF_CAM, p_cam, p_data);
}

int CAMPDUCodec::decode (const BITSTRING& p_data, CAM__PDU__Descriptions::CAM& p_cam)
{
  return _decode(CAM__PDU__Descriptions::CAM_descr_, asn_DEF_CAM, p_data, p_cam);
}
/*


extern "C" {
    extern asn_TYPE_descriptor_t asn_DEF_CAM;
    static int asn1c_collect_encoded_data(const void *buffer, size_t size, void *application_specific_key)
    {
      TTCN_Buffer * tb = (TTCN_Buffer *)application_specific_key;
      tb->put_s(size, (unsigned char *)buffer);
      return 0;
    }
}

int CAMPDUCodec::encode (const CAM__PDU__Descriptions::CAM& p_cam, BITSTRING& p_data)
{
@@ -401,104 +63,62 @@ int CAMPDUCodec::encode (const CAM__PDU__Descriptions::CAM& p_cam, BITSTRING& p_
  // Encode as BER
  // Encode message in BER (CER variant, but can be any)
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
  TTCN_Buffer ber_buf;
  p_cam.encode(CAM__PDU__Descriptions::CAM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
  loggers::get_instance().log_to_hexa("CAMPDUCodec::encode: BER encoding=", ber_buf);

  // Fill CAM_t structure
  CAM_t* cam_t = (CAM_t*)calloc(1, sizeof(CAM_t));
  asn_dec_rval_t rval = ber_decode(0, &asn_DEF_CAM, (void **)&cam_t, ber_buf.get_data(), ber_buf.get_len());
  if (rval.code == RC_OK) {
    loggers::get_instance().log("CAMPDUCodec::encode: CAM_t datat strucrue filled: StationID=%lld", cam_t->header.stationID);
    // Recode CAM_t in PER
    TTCN_Buffer per_buf;
    asn_enc_rval_t erv = uper_encode(&asn_DEF_CAM, (void**)cam_t, asn1c_collect_cam_encoded_data, &per_buf);
    if (erv.encoded >= 0) {
      loggers::get_instance().log_to_hexa("CAMPDUCodec::encode: PER encoding=", per_buf);
      p_data = oct2bit(OCTETSTRING(per_buf.get_len(), per_buf.get_data()));
      rc = p_data.lengthof();
  TTCN_Buffer buf;
  p_cam.encode(CAM__PDU__Descriptions::CAM_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
  loggers::get_instance().log_to_hexa("CAMPDUCodec::encode: BER encoding=", buf);

  // Decode BER
  void * ptr = NULL;
  asn_dec_rval_t rc_d;
  rc_d = asn_decode(NULL, ATS_BER, &asn_DEF_CAM, &ptr, buf.get_data(), buf.get_len());
  if(rc_d.code == RC_OK){
	// Encode as PER
    asn_enc_rval_t rc_e;
    buf.clear();
    rc_e = asn_encode(NULL, ATS_UNALIGNED_CANONICAL_PER, &asn_DEF_CAM, ptr,
			asn1c_collect_encoded_data, &buf);
    if(rc_e.encoded < 0) {
      loggers::get_instance().warning("CAMPDUCodec: PER encoding failed");
    }else{
      loggers::get_instance().warning("CAMPDUCodec::encode: BER to PER encoding failure");
      rc = rc_e.encoded * 8;
      p_data = p_data + oct2bit(OCTETSTRING(buf.get_len(), buf.get_data()));
    }
  } else {
    loggers::get_instance().warning("CAMPDUCodec::encode: Failed to fill CAM_t data structure");
    loggers::get_instance().warning("CAMPDUCodec: BER decoding failed");
  }
  if(ptr){
    ASN_STRUCT_FREE(asn_DEF_CAM, ptr);
  }
  free(cam_t);
  
  loggers::get_instance().log("<<< CAMPDUCodec::encode: %d", rc);
  return rc;
}

int CAMPDUCodec::decode (const BITSTRING& p_data, CAM__PDU__Descriptions::CAM& p_cam)
{
  loggers::get_instance().log(">>> CAMPDUCodec::decode");

  int rc = -1;
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
  // Fill CAM_t structure
  CAM_t* cam_t = (CAM_t*)calloc(1, sizeof(CAM_t));
  void * ptr = NULL;
  // Decode UPER
  OCTETSTRING os = bit2oct(p_data);
  asn_dec_rval_t rval = uper_decode_complete(NULL, &asn_DEF_CAM, (void **)&cam_t, static_cast<const unsigned char*>(os), os.lengthof());
  if (rval.code == RC_OK) {
    loggers::get_instance().log("CAMPDUCodec::decode: CAM_t datat strucrue filled: StationID=%lld", cam_t->header.stationID);
    // Recode CAM_t in BER/DER
    TTCN_Buffer ber_buf;
    asn_enc_rval_t erv = der_encode(&asn_DEF_CAM, (void**)cam_t, asn1c_collect_cam_encoded_data, &ber_buf);
    if (erv.encoded >= 0) {
      loggers::get_instance().log_to_hexa("CAMPDUCodec::decode: PER encoding=", ber_buf);
      p_cam.decode(CAM__PDU__Descriptions::CAM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
      rc = ber_buf.get_len() * 8;
  asn_dec_rval_t rc_d = asn_decode(NULL, ATS_UNALIGNED_BASIC_PER, &asn_DEF_CAM, &ptr, static_cast<const unsigned char*>(os), os.lengthof());
  if(rc_d.code == RC_OK) {
    // Encode BER
    TTCN_Buffer buf;
    asn_enc_rval_t rc_e = asn_encode(NULL, ATS_DER, &asn_DEF_CAM, ptr,
    		asn1c_collect_encoded_data, &buf);
    if (rc_e.encoded >= 0) {
      loggers::get_instance().log_to_hexa("CAMPDUCodec::decode: PER encoding=", buf);
      p_cam.decode(CAM__PDU__Descriptions::CAM_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
      rc = buf.get_len() * 8;
      loggers::get_instance().log("<<< CAMPDUCodec::decode: %d bits", rc);
    } else {
      loggers::get_instance().warning("CAMPDUCodec::decode: PER to BER encoding failure");
        loggers::get_instance().warning("CAMPDUCodec::decode: BER encoding failure");
    }
  } else {
    loggers::get_instance().warning("CAMPDUCodec::decode: Failed to fill CAM_t data structure");
    loggers::get_instance().warning("CAMPDUCodec::decode: PER");
  }
  free(cam_t);

  loggers::get_instance().log("<<< CAMPDUCodec::decode: %d", rc);
  return rc;

  
  /*  loggers::get_instance().log(">>> CAMPDUCodec::decode");

  int rc = -1;
  // Recode p_data to ber
  TTCN_Buffer per_buf, ber_buf;
  CAM_t* cam_t = (CAM_t*)(new unsigned char[sizeof(CAM_t)]);
  per_buf = TTCN_Buffer(bit2oct(p_data));
  loggers::get_instance().log_to_hexa("CAMPDUCodec::decode: PER=", per_buf);
  ber_buf.clear();
  if (asn1c_per2ber(asn_DEF_CAM, per_buf, ber_buf, (void**)&cam_t)) {
    loggers::get_instance().log_to_hexa("CAMPDUCodec::decode: BER=", ber_buf);
    TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
    ber_buf.rewind();
    cam.decode(CAM__PDU__Descriptions::CAM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
    rc = ber_buf.get_len() * 8;
  if(ptr){
    ASN_STRUCT_FREE(asn_DEF_CAM, ptr);
  }
  delete [] cam_t;
  
  loggers::get_instance().log("<<< CAMPDUCodec::decode: %d", rc);
  return rc;*/
  /*	CAM_t * p_cam = NULL;
	asn_dec_rval_t rc;
	asn_codec_ctx_s ctx;
	ctx.max_stack_size = 0;

	rc = uper_decode_complete(&ctx,
		&asn_DEF_CAM,
		(void**)&p_cam,
		(const unsigned char*)data,
		(data.lengthof()+7)/8);

	if (rc.code == RC_OK){
		cam = asn1c2titan(*p_cam);
	}

	if(p_cam){
		ASN_STRUCT_FREE(asn_DEF_CAM, p_cam);
  return rc;
}

	return (rc.code == RC_OK);
*/
 No newline at end of file
}
+53 −90

File changed.

Preview size limit exceeded, changes collapsed.