#include "LibItsDenm_TestSystem.hh" #include "DENMCodec.hh" #include "Asn1cEncDec.hh" #include "DENM.h" #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); if(rc){ 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); if(rc) { // TODO: fill other Indication fields } loggers::get_instance().log("<<< DENMCodec::decode: %d", 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) { 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; // 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; ber_buf.clear(); p_denm.encode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER); ber_buf.rewind(); loggers::get_instance().log_to_hexa("DENMPDUCodec::encode: BER encoding=", ber_buf); // Recode p_data as PER TTCN_Buffer 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); 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"); } delete [] denm_t; loggers::get_instance().log("<<< DENMPDUCodec::encode: %d", rc); return rc;*/ } int DENMPDUCodec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm) { loggers::get_instance().log(">>> DENMPDUCodec::decode"); 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(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 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)); loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: PER=", per_buf); ber_buf.clear(); if (asn1c_per2ber(asn_DEF_DENM, per_buf, ber_buf, (void**)&denm_t)) { loggers::get_instance().log_to_hexa("DENMPDUCodec::decode: BER=", ber_buf); TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING); ber_buf.rewind(); p_denm.decode(DENM__PDU__Descriptions::DENM_descr_, ber_buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL); rc = ber_buf.get_len() * 8; } delete [] denm_t; */ loggers::get_instance().log("<<< DENMPDUCodec::decode: %d", rc); return rc; }