Commit b9823816 authored by garciay's avatar garciay
Browse files

Try to fix CAM/DENM enc/dec:

1. CAM: Encoding done but unexpected PER result
2. DENM not working
parent 44130428
Loading
Loading
Loading
Loading
+27 −17
Original line number Original line Diff line number Diff line
#include "Asn1cEncDec.hh"
#include "Asn1cEncDec.hh"
#include "loggers.hh"


// basic types
// basic types
void        titan2asn1c(const INTEGER& t, long& a)
void        titan2asn1c(const INTEGER& t, long& a)
@@ -109,11 +110,13 @@ extern "C" int asn1c_collect_encoded_data(const void *buffer, size_t size, void
	unsigned char* ptr;
	unsigned char* ptr;
	size_t s = size;
	size_t s = size;
	TTCN_Buffer * tb = (TTCN_Buffer *)application_specific_key;
	TTCN_Buffer * tb = (TTCN_Buffer *)application_specific_key;
	tb->get_end(ptr, s);
  tb->put_s(size, (unsigned char *)buffer);
  loggers::get_instance().log_to_hexa("asn1c_collect_encoded_data: Encoding=", *tb);
	/*tb->get_end(ptr, s);
	if(s >= size){
	if(s >= size){
		memcpy(ptr, buffer, size);
		memcpy(ptr, buffer, size);
		tb->increase_length(size);
		tb->increase_length(size);
	}
    }*/
	return 0;
	return 0;
}
}


@@ -122,50 +125,57 @@ extern "C" int asn1c_collect_encoded_data(const void *buffer, size_t size, void
#include <per_encoder.h>
#include <per_encoder.h>
#include <per_decoder.h>
#include <per_decoder.h>


int asn1c_per2ber(asn_TYPE_descriptor_t &td, const TTCN_Buffer & per, TTCN_Buffer & ber )
int asn1c_per2ber(asn_TYPE_descriptor_t &td, const TTCN_Buffer & per, TTCN_Buffer & ber, void** ctx )
{
{
	void * obj = NULL;
	//void** obj = ctx;
	int rc = -1;
	int rc = -1;
	asn_dec_rval_t rc_d;
	asn_dec_rval_t rc_d;


	rc_d = uper_decode_complete(NULL, 
	rc_d = uper_decode_complete(NULL, 
				    &td, &obj, 
				    &td, ctx, 
				    per.get_read_data(), per.get_read_len());
				    per.get_read_data(), per.get_read_len());


	if(rc_d.code == RC_OK){
	if(rc_d.code == RC_OK){
		asn_enc_rval_t rc_e;
		asn_enc_rval_t rc_e;
		ber.clear();
		ber.clear();
		rc_e = der_encode(&td,
		rc_e = der_encode(&td,
			obj, 
			ctx, 
			asn1c_collect_encoded_data,
			asn1c_collect_encoded_data,
			&ber);
			&ber);
		rc = rc_e.encoded;
		rc = rc_e.encoded;
	}
	}
	if(obj) {
	/*if(obj) {
		ASN_STRUCT_FREE(td, obj);
		ASN_STRUCT_FREE(td, obj);
	}
    }*/
	return rc;
	return rc;
}
}


int asn1c_ber2per(asn_TYPE_descriptor_t &td, const TTCN_Buffer & ber, TTCN_Buffer & per )
int asn1c_ber2per(asn_TYPE_descriptor_t &td, const TTCN_Buffer & ber, TTCN_Buffer & per, void** ctx )
{
{
	void * obj = NULL;
	//void** obj = ctx;
	int rc = -1;
	int rc = -1;
	asn_dec_rval_t rc_d;
	asn_dec_rval_t rc_d;
	rc_d = ber_decode( NULL, &td,
	rc_d = ber_decode( NULL, &td,
			   &obj,
			   ctx,
			   ber.get_read_data(), ber.get_read_len());
			   ber.get_data(), ber.get_len());
	if(rc_d.code == RC_OK){
	if(rc_d.code == RC_OK){
    loggers::get_instance().log("asn1c_ber2per: BER decoding succeed");
		asn_enc_rval_t rc_e;
		asn_enc_rval_t rc_e;
		per.clear();
		//per.clear();
		rc_e = uper_encode(&td,
		rc_e = uper_encode(&td,
			obj, 
		  ctx, 
			asn1c_collect_encoded_data,
			asn1c_collect_encoded_data,
			&per);
			&per);
		rc = rc_e.encoded;
		rc = rc_e.encoded;
    if(rc < 0) {
      loggers::get_instance().warning("asn1c_ber2per: PER encoding failed");
    }
    }
	if(obj) {
	} else {
		ASN_STRUCT_FREE(td, obj);
    loggers::get_instance().warning("asn1c_ber2per: BER decoding failed");
    //    td.free_struct(&td, *ctx, 0);
  }
  }
	/*if(obj) {
		ASN_STRUCT_FREE(td, obj);
    }*/
	return rc;
	return rc;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -79,8 +79,8 @@ TS asn1c2titan_seq(const TA& a)
	return t;
	return t;
}
}


int asn1c_per2ber(asn_TYPE_descriptor_t &td, const TTCN_Buffer & per, TTCN_Buffer & ber );
int asn1c_per2ber(asn_TYPE_descriptor_t &td, const TTCN_Buffer & per, TTCN_Buffer & ber, void** ctx );
int asn1c_ber2per(asn_TYPE_descriptor_t &td, const TTCN_Buffer & ber, TTCN_Buffer & per );
int asn1c_ber2per(asn_TYPE_descriptor_t &td, const TTCN_Buffer & ber, TTCN_Buffer & per, void** ctx );




#endif
#endif
+92 −20
Original line number Original line Diff line number Diff line
@@ -386,30 +386,101 @@ int CAMCodec::decode (const OCTETSTRING& data, CAM__PDU__Descriptions::CAM& cam,
	return rc;
	return rc;
}
}


int CAMPDUCodec::encode (const CAM__PDU__Descriptions::CAM& cam, BITSTRING& data)
extern "C" int asn1c_collect_cam_encoded_data(const void *buffer, size_t size, void *application_specific_key)
{
{
	// use asn1c to encode CAM message
	TTCN_Buffer * tb = (TTCN_Buffer *)application_specific_key;
	CAM_t _cam;
  tb->put_s(size, (unsigned char *)buffer);
	asn_enc_rval_t encbits;
	return 0;
	TTCN_Buffer buf;
}


	titan2asn1c(cam, _cam);
int CAMPDUCodec::encode (const CAM__PDU__Descriptions::CAM& p_cam, BITSTRING& p_data)
{
  loggers::get_instance().log_msg(">>> CAMPDUCodec::encode: ", p_cam);
  
  
	encbits = uper_encode(
  int rc = -1;
		&asn_DEF_CAM, /* Type descriptor */
  // Encode as BER
		&_cam,        /* Structure to be encoded */
  // Encode message in BER (CER variant, but can be any)
		asn1c_collect_encoded_data,
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
		&buf);
  TTCN_Buffer ber_buf;
	if(encbits.encoded > 0) {
  p_cam.encode(CAM__PDU__Descriptions::CAM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
		data = BITSTRING(encbits.encoded, buf.get_data());
  loggers::get_instance().log_to_hexa("CAMPDUCodec::encode: BER encoding=", ber_buf);
		return 1;

  // 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();
    } else {
      loggers::get_instance().warning("CAMPDUCodec::encode: BER to PER encoding failure");
    }
    }
	return 0;
  } else {
    loggers::get_instance().warning("CAMPDUCodec::encode: Failed to fill CAM_t data structure");
  }
  }
  free(cam_t);
  
  
int CAMPDUCodec::decode (const BITSTRING& data, CAM__PDU__Descriptions::CAM& cam)
  loggers::get_instance().log("<<< CAMPDUCodec::encode: %d", rc);
  return rc;
}

int CAMPDUCodec::decode (const BITSTRING& p_data, CAM__PDU__Descriptions::CAM& p_cam)
{
{
	CAM_t * p_cam = NULL;
  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));
  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;
    } else {
      loggers::get_instance().warning("CAMPDUCodec::decode: PER to BER encoding failure");
    }
  } else {
    loggers::get_instance().warning("CAMPDUCodec::decode: Failed to fill CAM_t data structure");
  }
  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;
  }
  delete [] cam_t;
  
  loggers::get_instance().log("<<< CAMPDUCodec::decode: %d", rc);
  return rc;*/
  /*	CAM_t * p_cam = NULL;
	asn_dec_rval_t rc;
	asn_dec_rval_t rc;
	asn_codec_ctx_s ctx;
	asn_codec_ctx_s ctx;
	ctx.max_stack_size = 0;
	ctx.max_stack_size = 0;
@@ -429,4 +500,5 @@ int CAMPDUCodec::decode (const BITSTRING& data, CAM__PDU__Descriptions::CAM& cam
	}
	}


	return (rc.code == RC_OK);
	return (rc.code == RC_OK);
  */
}
}
+73 −8
Original line number Original line Diff line number Diff line
@@ -33,33 +33,73 @@ int DENMCodec::decode (const OCTETSTRING& p_data, DENM__PDU__Descriptions::DENM&
  return rc;
  return rc;
}
}


extern "C" int asn1c_collect_denm_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 DENMPDUCodec::encode (const DENM__PDU__Descriptions::DENM& p_denm, BITSTRING& p_data)
int DENMPDUCodec::encode (const DENM__PDU__Descriptions::DENM& p_denm, BITSTRING& p_data)
{
{
  loggers::get_instance().log_msg(">>> DENMPDUCodec::encode: ", p_denm);
  loggers::get_instance().log_msg(">>> DENMPDUCodec::encode: ", p_denm);
  
  
  int rc = -1;
  // 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_denm.encode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
  loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: BER encoding=", ber_buf);

  // Fill DENM_t structure
  DENM_t* denm_t = (DENM_t*)calloc(1, sizeof(DENM_t));
  asn_dec_rval_t rval = ber_decode(0, &asn_DEF_DENM, (void **)&denm_t, ber_buf.get_data(), ber_buf.get_len());
  if (rval.code == RC_OK) {
    loggers::get_instance().log("DENMPDUCodec::encode: DENM_t datat strucrue filled: StationID=%lld", denm_t->header.stationID);
    // Recode DENM_t in PER
    TTCN_Buffer per_buf;
    asn_enc_rval_t erv = uper_encode(&asn_DEF_DENM, (void**)denm_t, asn1c_collect_denm_encoded_data, &per_buf);
    if (erv.encoded >= 0) {
      loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: PER encoding=", per_buf);
      p_data = oct2bit(OCTETSTRING(per_buf.get_len(), per_buf.get_data()));
      rc = p_data.lengthof();
    } else {
      loggers::get_instance().warning("DENMPDUCodec::encode: BER to PER encoding failure");
    }
  } else {
    loggers::get_instance().warning("DENMPDUCodec::encode: Failed to fill DENM_t data structure");
  }
  free(denm_t);
  
  loggers::get_instance().log("<<< DENMPDUCodec::encode: %d", rc);
  return rc;
  /*  loggers::get_instance().log_msg(">>> DENMPDUCodec::encode: ", p_denm);
  
  int rc = -1;
  int rc = -1;
  // Encode as BER
  // Encode as BER
  // Encode message in BER (CER variant, but can be any)
  // Encode message in BER (CER variant, but can be any)
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
  TTCN_Buffer ber_buf;
  TTCN_Buffer ber_buf;
  ber_buf.clear();
  ber_buf.clear();
  p_denm.encode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_CER);
  p_denm.encode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
  ber_buf.rewind();
  ber_buf.rewind();
  loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: BER encoding=", ber_buf);
  loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: BER encoding=", ber_buf);


  // Recode p_data as PER
  // Recode p_data as PER
  TTCN_Buffer per_buf;
  TTCN_Buffer per_buf;
  if (asn1c_ber2per(asn_DEF_DENM, ber_buf, per_buf)) {
  DENM_t* denm_t = (DENM_t*)(new unsigned char[sizeof(DENM_t)]);
  if (asn1c_ber2per(asn_DEF_DENM, ber_buf, per_buf, (void**)&denm_t)) {
    loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: PER encoding=", per_buf);
    loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: PER encoding=", per_buf);
    per_buf.rewind();
    p_data = oct2bit(OCTETSTRING(per_buf.get_len(), per_buf.get_data()));
    rc = per_buf.get_len() * 8;
    rc = p_data.lengthof();
    p_data = BITSTRING(rc, per_buf.get_data());
  } else {
  } else {
    loggers::get_instance().warning("DENMPDUCodec::encode: BER to PER encoding failure");
    loggers::get_instance().warning("DENMPDUCodec::encode: BER to PER encoding failure");
  }
  }
  delete [] denm_t;
  
  
  loggers::get_instance().log("<<< DENMPDUCodec::encode: %d", rc);
  loggers::get_instance().log("<<< DENMPDUCodec::encode: %d", rc);
  return rc;
  return rc;*/
}
}


int DENMPDUCodec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm)
int DENMPDUCodec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm)
@@ -67,19 +107,44 @@ int DENMPDUCodec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM
  loggers::get_instance().log(">>> DENMPDUCodec::decode");
  loggers::get_instance().log(">>> DENMPDUCodec::decode");


  int rc = -1;
  int rc = -1;
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
  // Fill DENM_t structure
  DENM_t* denm_t = (DENM_t*)calloc(1, sizeof(DENM_t));
  OCTETSTRING os = bit2oct(p_data);
  asn_dec_rval_t rval = uper_decode_complete(NULL, &asn_DEF_DENM, (void **)&denm_t, static_cast<const unsigned char*>(os), os.lengthof());
  if (rval.code == RC_OK) {
    loggers::get_instance().log("DENMPDUCodec::decode: DENM_t datat strucrue filled: StationID=%lld", denm_t->header.stationID);
    // Recode DENM_t in BER/DER
    TTCN_Buffer ber_buf;
    asn_enc_rval_t erv = der_encode(&asn_DEF_DENM, (void**)denm_t, asn1c_collect_denm_encoded_data, &ber_buf);
    if (erv.encoded >= 0) {
      loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: PER encoding=", ber_buf);
      p_denm.decode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
      rc = ber_buf.get_len() * 8;
    } else {
      loggers::get_instance().warning("DENMPDUCodec::decode: PER to BER encoding failure");
    }
  } else {
    loggers::get_instance().warning("DENMPDUCodec::decode: Failed to fill DENM_t data structure");
  }
  free(denm_t);
  
  /*int rc = -1;
  // Recode p_data to ber
  // Recode p_data to ber
  TTCN_Buffer per_buf, ber_buf;
  TTCN_Buffer per_buf, ber_buf;
  DENM_t* denm_t = (DENM_t*)(new unsigned char[sizeof(DENM_t)]);
  per_buf = TTCN_Buffer(bit2oct(p_data));
  per_buf = TTCN_Buffer(bit2oct(p_data));
  loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: PER=", per_buf);
  loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: PER=", per_buf);
  ber_buf.clear();
  ber_buf.clear();
  if (asn1c_per2ber(asn_DEF_DENM, per_buf, ber_buf)) {
  if (asn1c_per2ber(asn_DEF_DENM, per_buf, ber_buf, (void**)&denm_t)) {
    loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: BER=", ber_buf);
    loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: BER=", ber_buf);
    TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
    TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
    ber_buf.rewind();
    ber_buf.rewind();
    p_denm.decode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
    p_denm.decode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
    rc = ber_buf.get_len() * 8;
    rc = ber_buf.get_len() * 8;
  }
  }
  
  delete [] denm_t;
  */
  loggers::get_instance().log("<<< DENMPDUCodec::decode: %d", rc);
  loggers::get_instance().log("<<< DENMPDUCodec::decode: %d", rc);
  return rc;
  return rc;
}
}