Commit 65591f7c authored by Yann Garcia's avatar Yann Garcia
Browse files

Add support of unzip BFK AT download

parent 44b7441b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ $$(foreach I, $$(includes), $$(eval all_includes += $$(if $$(filter /%, $$(I)),
$$(foreach M, $$(modules),  $$(eval $$(call IncludeModule, $$(if $$(filter /%, $$(M)), $$(TOPDIR)$$(M), $(1)/$$(M)))))
endef

all_includes := $(TTCN3_DIR)/include $(TTCN3_DIR)/src /usr/include/jsoncpp /usr/include/libxml2
all_includes := $(TTCN3_DIR)/include $(TTCN3_DIR)/src /usr/include/jsoncpp /usr/include/libxml2 /usr/include/libzip
defines  += TITAN_RUNTIME_2 _NO_SOFTLINKS_ $(ATS) AS_USE_SSL _GNU_SOURCE
libs     += $(TTCN3_DIR)/lib/libttcn3-rt2-parallel.a -lstdc++fs

@@ -50,7 +50,7 @@ defines += LINUX
libs += -lpcap -lrt -lpthread
endif

libs += -lssl -lcrypto -lxml2 -ljsoncpp
libs += -lssl -lcrypto -lxml2 -ljsoncpp -lzip

$(eval $(call IncludeModule, $(TOPDIR)/ttcn/$(ATS)))

+17 −8
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include "loggers.hh"

#include "http_etsi_ieee1609dot2_codec.hh"
#include "http_etsi_ieee1609dot2dot1_codec.hh"

bool http_codec_its::encode_body_binary(const LibHttp__BinaryMessageBodyTypes::BinaryBody &p_binary_body, OCTETSTRING &p_encoding_buffer, const std::string &p_content_type) {
  loggers::get_instance().log(">>> http_codec_its::encode_body_binary");
@@ -54,6 +55,7 @@ bool http_codec_its::decode_body_binary(const OCTETSTRING &p_data, LibHttp__Bina
          processed = true;
          }
          }*/
      if ((p_data[0].get_octet() != 0x50) || (p_data[1].get_octet() != 0x4B) || (p_data[2].get_octet() != 0x03) || (p_data[3].get_octet() != 0x04)) { // Not a Zip file header      http_etsi_ieee1609dot2_codec *codec = new http_etsi_ieee1609dot2_codec();
        loggers::get_instance().log("http_codec_its::decode_body_binary: Call '%s'", it->first.c_str());
        http_etsi_ieee1609dot2_codec *codec = new http_etsi_ieee1609dot2_codec();
        if (p_data[0].get_octet() != 0x80) {
@@ -66,6 +68,12 @@ bool http_codec_its::decode_body_binary(const OCTETSTRING &p_data, LibHttp__Bina
          }
        }
        delete codec;
      } else {
        http_etsi_ieee1609dot2dot1_codec codec;
        if (codec.decode(p_data, p_binary_body.bfk__zip__file()) == 0) {
          processed                   = true;
        }
      }
    }
    if (!processed) {
      loggers::get_instance().warning("http_codec_its::decode_body_binary: Unsupported HTTP codec, use raw field as default");
@@ -76,5 +84,6 @@ bool http_codec_its::decode_body_binary(const OCTETSTRING &p_data, LibHttp__Bina
    p_binary_body.raw()           = p_data;
  }

  loggers::get_instance().log_msg("<<< http_codec_its::decode_body_binary: p_binary_body=", p_binary_body);
  return true;
}
+112 −0
Original line number Diff line number Diff line
#include <zip.h>

#include "http_etsi_ieee1609dot2dot1_codec.hh"

#include "LibHttp_BinaryMessageBodyTypes.hh"

#include "loggers.hh"

int http_etsi_ieee1609dot2dot1_codec::decode(const OCTETSTRING &p_data, LibHttp__BinaryMessageBodyTypes::BfkZipFile &p_bfk_zip_file, params *p_params) {
  loggers::get_instance().log(">>> http_etsi_ieee1609dot2dot1_codec::decode: Butterfly AT download response corresponding to a ZIP file: Version: %02x.%02x", p_data[4].get_octet(), p_data[5].get_octet());
  loggers::get_instance().log(">>> http_etsi_ieee1609dot2dot1_codec::decode: Butterfly AT download response corresponding to a ZIP file: Compression method: %02x.%02x", p_data[8].get_octet(), p_data[9].get_octet());
  // Unzip header file
  p_bfk_zip_file.identifier() = substr(p_data, 0, 4);
  p_bfk_zip_file.version() = substr(p_data, 4, 2);
  p_bfk_zip_file.flags() = substr(p_data, 6, 2);
  p_bfk_zip_file.compression() = substr(p_data, 8, 2);
  p_bfk_zip_file.content().raw() = substr(p_data, 10, p_data.lengthof() - 10 - 1);

  zip_error_t error;
  zip_source_t *src = nullptr;
  zip_stat_t zst;
  zip_t *za = nullptr;
  int ret_code = -1;
  LibHttp__BinaryMessageBodyTypes::BfkZipFileContent_signed__messages signed_messages;
  ::zip_error_init(&error);
  if ((src = ::zip_source_buffer_create(static_cast<const unsigned char*>(p_data), p_data.lengthof(), 1, &error)) == nullptr) {
    loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: ::zip_source_buffer_create failure: %s", ::zip_error_strerror(&error));
    ::zip_error_fini(&error);
    return -1;
  }
  if (::zip_source_stat(src, &zst) < 0) {
    loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: ::zip_source_stat failure: %s\n", ::zip_error_strerror(::zip_source_error(src)));
    goto decode_cleanup;
  }
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.valid: %08x", zst.valid);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.valid: %p", zst.name);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.size: %ld", zst.size);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec: decode: mtime: %u", (unsigned int)zst.mtime);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.comp_size: %ld", zst.comp_size);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.crc: %04x", zst.crc);
  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: zst.encryption_method: %02x", zst.encryption_method);

  if (::zip_source_open(src) < 0) {
    loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: ::zip_source_open failure: %s", ::zip_error_strerror(::zip_source_error(src)));
    goto decode_cleanup;
  }
  
  if ((za = ::zip_open_from_source(src, 0, &error)) == NULL) {
    loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: Can't open zip from source: %s\n", ::zip_error_strerror(&error));
    goto decode_cleanup;
  }
  ::zip_error_fini(&error);

  loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec:: Number of entries: %d", ::zip_get_num_entries(za, 0));
  signed_messages.set_size(::zip_get_num_entries(za, 0));
  for (int i = 0; i < ::zip_get_num_entries(za, 0); i++) {
    loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: Processing entry #%d", i);
    struct zip_stat sb;
    if (::zip_stat_index(za, i, 0, &sb) == 0) {
      loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode:==================");
      loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: Name: [%s], ", sb.name);
      loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: Size: [%llu], ", sb.size);
      loggers::get_instance().log("http_etsi_ieee1609dot2dot1_codec::decode: mtime: [%u]", (unsigned int)sb.mtime);
      struct zip_file *zf = ::zip_fopen_index(za, i, 0);
      if (zf == nullptr) {
        loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: ::zip_fopen_index failure");
        goto decode_cleanup;
      }
      unsigned char* buffer = (unsigned char*)new unsigned char*[sb.size];
      size_t len = ::zip_fread(zf, buffer, sb.size);
      if (len < 0) {
        loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: ::zip_fread failure");
        delete [] buffer;
        ::zip_fclose(zf);
        goto decode_cleanup;
      }
      OCTETSTRING os;
      loggers::get_instance().log_to_hexa("http_etsi_ieee1609dot2dot1_codec::decode: content:", buffer, sb.size);
      if (*buffer == 0x81) { // Remove 0x81
        os = OCTETSTRING(sb.size - 1, buffer + 1);
      } else {
        os = OCTETSTRING(sb.size, buffer);
      }
      loggers::get_instance().log_to_hexa("http_etsi_ieee1609dot2dot1_codec::decode: content:", os);
      Ieee1609Dot2::Ieee1609Dot2Data ieee1609Dot2Data;
      if (_codec.decode(os, ieee1609Dot2Data, p_params) == -1) {
        loggers::get_instance().error("http_etsi_ieee1609dot2dot1_codec::decode: Failed to decode ieee1609Dot2Data");
        delete [] buffer;
        ::zip_fclose(zf);
        goto decode_cleanup;
      }
      signed_messages[i] = ieee1609Dot2Data;
      delete [] buffer;
      ::zip_fclose(zf);
    }
  } // End of 'for' statement
  loggers::get_instance().log_msg("http_etsi_ieee1609dot2dot1_codec::decode: After loop: signed_messages=", signed_messages);
  //::zip_source_keep(src);
  // Close the archive
  //::zip_close(za);
  // Close the source
  p_bfk_zip_file.content().signed__messages() = signed_messages;
  ret_code = 0; // Everythig goes well
decode_cleanup:

  ::zip_source_close(src);
  //::zip_source_free(src);

  loggers::get_instance().log_msg("http_etsi_ieee1609dot2dot1_codec::decode: p_bfk_zip_file=", p_bfk_zip_file);
  loggers::get_instance().log("<<< http_etsi_ieee1609dot2dot1_codec::decode: %d", ret_code);
  return ret_code;
}
+23 −0
Original line number Diff line number Diff line
#pragma once

#include "codec_gen.hh"
#include "params.hh"

#include "etsi_ts103097_data_codec.hh"

#include "params.hh"

namespace LibHttp__BinaryMessageBodyTypes {
  class BfkZipFile;
}

class http_etsi_ieee1609dot2dot1_codec : public codec_gen<LibHttp__BinaryMessageBodyTypes::BfkZipFile, LibHttp__BinaryMessageBodyTypes::BfkZipFile> {
  etsi_ts103097_data_codec _codec;

public:
  explicit http_etsi_ieee1609dot2dot1_codec() : codec_gen<LibHttp__BinaryMessageBodyTypes::BfkZipFile, LibHttp__BinaryMessageBodyTypes::BfkZipFile>(), _codec() {};
  virtual ~http_etsi_ieee1609dot2dot1_codec(){};

  virtual int encode(const LibHttp__BinaryMessageBodyTypes::BfkZipFile &p_bfk_zip_file, OCTETSTRING &p_data) { return -1; };
  virtual int decode(const OCTETSTRING &p_data, LibHttp__BinaryMessageBodyTypes::BfkZipFile &p_bfk_zip_file, params *p_params = NULL);
};
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ sources += http_etsi_ieee1609dot2_codec.cc \
           etsi_ts102941_types_authorization_validation_response.cc \
           etsi_ts102941_types_enrolment_inner_request.cc \
           etsi_ts102941_types_enrolment_inner_response.cc \
           http_etsi_ieee1609dot2dot1_codec.cc \

endif

Loading