DENMCodec.cc 3.64 KB
Newer Older
garciay's avatar
garciay committed
#include "LibItsDenm_TestSystem.hh"

#include "DENMCodec.hh"

filatov's avatar
filatov committed
#include "asn1/asn_application.h" // from asn1c
garciay's avatar
garciay committed
#include "loggers.hh"

int DENMCodec::encode (const DENM__PDU__Descriptions::DENM& p_denm, OCTETSTRING& p_data)
{
  loggers::get_instance().log_msg(">>> DENMCodec::encode: ", p_denm);
  
  BITSTRING b;
  int rc = asnCodec.encode(p_denm, b);
filatov's avatar
filatov committed
  if(rc > 0){
garciay's avatar
garciay committed
    p_data = bit2oct(b);
  }
  loggers::get_instance().log("<<< DENMCodec::encode: %d", rc);
  return rc;
}

int DENMCodec::decode (const OCTETSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm, Params* params)
{
  loggers::get_instance().log(">>> DENMCodec::decode");
  
  int rc = asnCodec.decode(oct2bit(p_data), p_denm);
filatov's avatar
filatov committed
  if(rc > 0) {
garciay's avatar
garciay committed
    // TODO: fill other Indication fields
  }
  
  loggers::get_instance().log("<<< DENMCodec::decode: %d", rc);
  return rc;
}

filatov's avatar
filatov committed
extern "C" {
    extern asn_TYPE_descriptor_t asn_DEF_DENM;
    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;
    }
garciay's avatar
garciay committed
int DENMPDUCodec::encode (const DENM__PDU__Descriptions::DENM& p_denm, BITSTRING& p_data)
{
  loggers::get_instance().log_msg(">>> DENMPDUCodec::encode: ", p_denm);
  
garciay's avatar
garciay committed
  int rc = -1;
filatov's avatar
filatov committed
  TTCN_Buffer buf;

garciay's avatar
garciay committed
  // 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);
filatov's avatar
filatov committed
  p_denm.encode(DENM__PDU__Descriptions::DENM_descr_, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
  loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: BER encoding=", buf);
filatov's avatar
filatov committed
  // Decode BER
  void *ptr = NULL;
  asn_dec_rval_t rc_d;
  rc_d = asn_decode(NULL, ATS_BER, &asn_DEF_DENM, &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_DENM, ptr,
			asn1c_collect_encoded_data, &buf);
    if(rc_e.encoded >= 0) {
      rc = rc_e.encoded;
      p_data = p_data + oct2bit(OCTETSTRING(buf.get_len(), buf.get_data()));
garciay's avatar
garciay committed
    } else {
filatov's avatar
filatov committed
      if(rc_e.failed_type)
        loggers::get_instance().warning("DENMPDUCodec: PER encoding failed on %s", rc_e.failed_type->name);
      else
        loggers::get_instance().warning("DENMPDUCodec: PER encoding failed");
garciay's avatar
garciay committed
    }
  } else {
filatov's avatar
filatov committed
    loggers::get_instance().warning("DENMPDUCodec: BER decoding failed");
garciay's avatar
garciay committed
  }
filatov's avatar
filatov committed
  if(ptr){
    ASN_STRUCT_FREE(asn_DEF_DENM, ptr);
garciay's avatar
garciay committed
  }
filatov's avatar
filatov committed
  return rc;
garciay's avatar
garciay committed
}

int DENMPDUCodec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm)
{
garciay's avatar
garciay committed
  loggers::get_instance().log(">>> DENMPDUCodec::decode");
garciay's avatar
garciay committed
  int rc = -1;
filatov's avatar
filatov committed
  void * ptr = NULL;
  // Decode UPER
garciay's avatar
garciay committed
  OCTETSTRING os = bit2oct(p_data);
filatov's avatar
filatov committed
  asn_dec_rval_t rc_d = asn_decode(NULL, ATS_UNALIGNED_BASIC_PER, &asn_DEF_DENM, &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;
    rc_e = asn_encode(NULL, ATS_DER, &asn_DEF_DENM, ptr, asn1c_collect_encoded_data, &buf);
    if (rc_e.encoded >= 0) {
      loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: DER encoding=", buf);
      p_denm.decode(DENM__PDU__Descriptions::DENM_descr_, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
      rc = buf.get_len();
      loggers::get_instance().log("<<< DENMPDUCodec::decode: %d bits", rc);
garciay's avatar
garciay committed
    } else {
filatov's avatar
filatov committed
      loggers::get_instance().warning("DENMPDUCodec::decode: BER encoding failure");
garciay's avatar
garciay committed
    }
  } else {
filatov's avatar
filatov committed
    loggers::get_instance().warning("DENMPDUCodec::decode: PER decoding failed");
garciay's avatar
garciay committed
  }
filatov's avatar
filatov committed
  if(ptr){
    ASN_STRUCT_FREE(asn_DEF_DENM, ptr);
garciay's avatar
garciay committed
  }
  return rc;
}