Commit 0d89f1d1 authored by Denis Filatov's avatar Denis Filatov
Browse files

Merge branch 'STF525' of https://forge.etsi.org/gitlab/ITS/ITS into STF525

parents f8693810 ade618da
Copyright 2019 ETSI
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
......@@ -37,7 +37,28 @@ The ETSI ITS protocols project builds and tests regularly on the following platf
- Linux (Ubuntu)
Note: The [OpenSSL](https://www.openssl.org) version > 1.x is also required.
Note: The [OpenSSL](https://www.openssl.org) version > 1.1.x is also required.
### How to do it?
They are two different methods:
- Using [Vagrant](https://www.vagrantup.com/)
- Using [Docker](https://www.docker.com/)
How to choose one of these methods is depending of your host system.
NOTE: In all case, if you want to setup an continuous integration process (e.g. Jenkins), Docker is the best choice.
#### The host system is Windows
The both methods require a virtual machine. You can use either VirtualBox or WMware.
In this case, the easiest way is to use Vagrant.
#### The host system is Linux
Vagrant requires a virtual machine. You can use either VirtualBox or WMware.
Docker does not need a virtual machine, so it is the more efficant way.
### Using Vagrant
......@@ -45,14 +66,14 @@ Pre-requisites on your host machine:
- Install [Virtualbox](https://www.virtualbox.org/manual/ch01.html)
- Install [Vagrant](https://www.vagrantup.com/intro/getting-started/)
- Install Vagrant plugin vagrant-vbguest
- Credentials to access [ETSI forge](https://oldforge.etsi.org/!/#)
- Set the environment variable USERNAME to your ETSI OEL account user name
- Set the environment variable PASSWORD to your ETSI OEL account password
- Credentials to access [ETSI forge](https://forge.etsi.org/gitlab/users/sign_in)
- Set the environment variable USERNAME to your ETSI EOL account user name
- Set the environment variable PASSWORD to your ETSI EOL account password
Procedure:
- On your host machine, open a command line session (PuTTY, DOS window...)
- From the ETSI ITS protocols project, clone the Vagrant folder
- In the file Vagrantfilem, odify the tag config.vm.provision replacing <username> & <password> strings by your ETSI credentials
- In the file Vagrantfile, modify the tag config.vm.provision replacing <username> & <password> strings by your ETSI credentials
- In the Vagrant folder, execute the following commands:
```sh
......@@ -85,13 +106,21 @@ NOTE The user password is vagrant.
### Using Docker
Pre-requisites on your host machine:
- Install Virtualbox
- Install Virtualbox (For Windows host only)
- Install Docker
Procedure for a Windows host machine:
- On your host machine, open a the Docker Quickstart Terminal
- On your host machine, clone the ETSI ITS protocols project. NOTE that only Docker folder and .jenkins.sh script file are required
- From the ETSI ITS protocols project root directory, execute the following commands:
- On your host machine, open a the Docker Quickstart Terminal and change to a working folder such as ./temp/docker_its
Procedure for a Linux host machine:
- On your host machine, open a terminal and change to a working folder such as $HOME/temp/docker_its
On your host machine, download the following items from ETSI ITS protocols project:
- The docker folder
- The .jenkins.sh script file (hidden file) and add the execution rights on it
- Check the rights of the script files and the folders
From the your current directory, execute the following commands:
```sh
$ ./.jenkins.sh
......@@ -190,7 +219,7 @@ The procedures below illustrate how to run the CAM test suite. The same procedur
Pre-requisites:
- Your machine is installed followimg one of the installation method describes in the previous clause
- Your machine is installed following one of the installation method describes in the previous clause
- Refer to the ETSI TS 103 099 for the description of the Test System architecture and configuration
- Your are logged as 'etsi' or 'vagrant' user
......@@ -198,7 +227,7 @@ Procedure using Eclipse TITAN:
- Start eclipse using a new workspace, (e.g. with the name workspace_titan)
- Download and follow the steps to install Eclipse plugins for TITAN, accessible [here]{https://www.eclipse.org/downloads/download.php?file=/titan/Eclipse_installationguide.pdf}
- Open the workspace_titan
- Create a new TITAN project (e.g. Its_autoInterop)
- Create a new TITAN project (e.g. STF525_Its)
<TODO>
Procedure in TITAN command line:
......@@ -224,58 +253,44 @@ $ ../bin/run-all.bash
- The log files are located in ../logs folder. You can edit them using any editor or using the Eclipse TITAN log plugins
## How to generate ITS test certificates
## Rebuild Wireshark with support of ETSI ITS Protocols
The Test System includes a tool, asn1cert, to generate ITS test certificates used for Conformance Testing.
This tool is located in the folder '~/dev/STF525_Its/tools/itscertgen/'.
A specific version of Wireshark, based on official version 2.6.x, is available [here](https://github.com/YannGarcia/wireshark-for-ITS.git).
Note: These certificates can not be used in a true architectures, there are present only for testing and/or debug purposes.
The following Pre-requisites applies to build it:
- Your machine is installed followimg one of the installation method describes in the previous clause
- Your are logged as 'etsi' or 'vagrant' user
The following procedure applies to build it:
- Open a SSH session (PuTTY...)
- Change to the directory ~/frameworks
- Execute the following comands to clone the project and switch to the branck
### Build the tool 'asn1cert'
```sh
$ git clone https://github.com/YannGarcia/wireshark-for-ITS.git wireshark-for-ITS
$ git checkout ITS_Protocol_Support
...
```
To build the tool, run the 'make' command in each of the following folders:
- cshared
- cxml
- checker
- asn1certgen
- Create a folder ~/frameworks/wireshark-build
- Change to this folder
- Generate makefiles executing the following command
```sh
$ cmake ../wireshark-for-ITS
...
```
### Generate the certificates
- Add specific compiler options to the file epan/dissectors/CMakeFiles/dissectors.dir/flags.make:
- Find the variable C_FLAGS
- Remove the flag : "-Wunused-const-variable"
- Build Wireshark/tshark executing the following command
After that change to the folder '~/dev/STF525_Its/data/v3' and execute 'make command.
The certificates will be located in the folder '~/dev/STF525_Its/data/v3/certificates'.
```sh
$ make
```
- After the build, binaries are located in ~/frameworks/wireshark-build/run folder
- To distinguish this version of Wireshark from the others, a development tag 'ETSI ITS Protocols' is displayed on the GUI version
- You have to provide also the following link to indicate the location of the new built plugins
### Modify or create new certificates
```sh
$ sudo ln -sf /home/vagrant/frameworks/wireshark-build/run/plugins/2.9 /usr/local/lib/wireshark/plugins/2.9
```
The folder '~/dev/STF525_Its/data/v3/profiles' contains an XML file for each certificate to be generated.
This XML file describes the certificate content (e.g. CERT_IUT_A_RCA.xml describes the root certificate for all CERT_IUT_A certificates).
By modifying these files, you can change create new certificate with different geographical area, different validity periods or different SSPs.
To re-generates the certificates, refer to the previous clause.
## Wireshark with support of ETSI ITS Protocols
The official version of Wireshark, supporting ETSI ITS Protocols, is available [here](https://www.wireshark.org/download.html).
Some sample capture files are available [here](https://wiki.wireshark.org/SampleCaptures).
The following instructions enable the verify signature in real time.
Note: The verify signature can be done only if the certificate in include in the message
- In the Wireshak menu Edit/Preferences, select Protocols in the list on the left
- Search for 'ETSI ITS GeoNetworking' protocol
- Check the option 'Attempt to verify signatures
- Click on OK to validate your choice
## How to Report a Bug
......
......@@ -12,6 +12,7 @@ ASN_FILES = CAM/CAM.asn \
DENM/DENM.asn \
IS/ETSI_TS_103301/IVIM_PDU_Descriptions.asn \
IS/ETSI_TS_103301/MAPEM_PDU_Descriptions.asn \
IS/ETSI_TS_103301/RTCM_PDU_Descriptions.asn \
IS/ETSI_TS_103301/SPATEM_PDU_Descriptions.asn \
IS/ETSI_TS_103301/SREM_PDU_Descriptions.asn \
IS/ETSI_TS_103301/SSEM_PDU_Descriptions.asn \
......@@ -38,7 +39,7 @@ ASN_FILES = CAM/CAM.asn \
# PDUs
PDU = CAM DENM MAPEM SPATEM SREM SSEM IVIM EtsiTs103097Data EtsiTs103097Certificate EtsiTs102941Data
PDU = CAM DENM MAPEM SPATEM SREM SSEM IVIM RTCMEM EtsiTs103097Data EtsiTs103097Certificate EtsiTs102941Data
#patches
PATCHES = PsidGroupPermissions.c.diff
......
......@@ -8,6 +8,7 @@
#include "etsi_ts102941_types_authorization_inner_response.hh"
#include "etsi_ts102941_types_authorization_shared_at_request.hh"
#include "etsi_ts102941_types_authorization_validation_request.hh"
#include "etsi_ts102941_types_authorization_validation_response.hh"
#include "etsi_ts102941_base_types_public_keys.hh"
#include "ieee_1609dot2_base_types_public_encryption_key.hh"
#include "ieee_1609dot2_base_types_public_verification_key.hh"
......@@ -230,7 +231,34 @@ namespace LibItsPki__EncdecDeclarations {
return 0;
}
BITSTRING fx__enc__PublicKeys(EtsiTs102941BaseTypes::PublicKeys const& p_public_keys) {
BITSTRING fx__enc__AuthorizationValidationResponse(EtsiTs102941TypesAuthorizationValidation::AuthorizationValidationResponse const& p_shared_at) {
loggers::get_instance().log_msg(">>> fx__enc__AuthorizationValidationResponse: ", p_shared_at);
etsi_ts102941_types_authorization_validation_response codec;
OCTETSTRING os;
if (codec.encode(p_shared_at, os) == -1) {
loggers::get_instance().warning("fx__enc__AuthorizationValidationResponse: -1 result code was returned");
return int2bit(0, 1);
}
return oct2bit(os);
}
INTEGER fx__dec__AuthorizationValidationResponse(BITSTRING& b, EtsiTs102941TypesAuthorizationValidation::AuthorizationValidationResponse& p_shared_at) {
loggers::get_instance().log_msg(">>> fx__dec__AuthorizationValidationResponse: ", b);
etsi_ts102941_types_authorization_validation_response codec;
OCTETSTRING is = bit2oct(b);
if (codec.decode(is, p_shared_at) == -1) {
loggers::get_instance().warning("fx__dec__AuthorizationValidationResponse: -1 result code was returned");
return -1;
}
loggers::get_instance().log_msg("<<< fx__dec__AuthorizationValidationResponse: ", p_shared_at);
return 0;
}
BITSTRING fx__enc__PublicKeys(EtsiTs102941BaseTypes::PublicKeys const& p_public_keys) {
loggers::get_instance().log_msg(">>> fx__enc__PublicKeys: ", p_public_keys);
etsi_ts102941_base_types_public_keys codec;
......
......@@ -587,7 +587,8 @@ namespace LibItsSecurity__Functions
* \return The HMAC value resized to 16-byte
*/
OCTETSTRING fx__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) {
loggers::get_instance().log(">>> fx__hmac__sha256");
loggers::get_instance().log_msg(">>> fx__hmac__sha256: p__k=", p__k);
loggers::get_instance().log_msg(">>> fx__hmac__sha256: p__m=", p__m);
hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm
OCTETSTRING t;
......@@ -595,8 +596,8 @@ namespace LibItsSecurity__Functions
loggers::get_instance().warning("fx__hmac__sha256: Failed to generate HMAC");
return OCTETSTRING(0, nullptr);
}
loggers::get_instance().log_msg("fx__hmac__sha256: HMAC: ", t);
loggers::get_instance().log_msg("<<< fx__hmac__sha256: HMAC: ", t);
return t;
}
......@@ -1183,7 +1184,7 @@ namespace LibItsSecurity__Functions
return TRUE;
}
BOOLEAN fx__store__certificate(const CHARSTRING& p__cert__id, const OCTETSTRING& p__cert, const OCTETSTRING& p__private__key, const OCTETSTRING& p__public__key__x, const OCTETSTRING& p__public__key__y, const OCTETSTRING& p__public__key__compressed, const INTEGER& p__public__key__compressed__mode, const OCTETSTRING& p__hash, const OCTETSTRING& p__hashid8, const OCTETSTRING& p__issuer, const OCTETSTRING_template& p__private__enc__key, const OCTETSTRING_template& p__public__enc__key__x, const OCTETSTRING_template& p__public__enc__key__y, const OCTETSTRING_template& p__public__enc__compressed__key, const INTEGER_template& p__public__enc__key__compressed__mode) {
BOOLEAN fx__store__certificate(const CHARSTRING& p__cert__id, const OCTETSTRING& p__cert, const OCTETSTRING& p__private__key, const OCTETSTRING& p__public__key__x, const OCTETSTRING& p__public__key__y, const OCTETSTRING& p__public__key__compressed, const INTEGER& p__public__key__compressed__mode, const OCTETSTRING& p__hash, const OCTETSTRING& p__hash__256, const OCTETSTRING& p__hashid8, const OCTETSTRING& p__issuer, const OCTETSTRING_template& p__private__enc__key, const OCTETSTRING_template& p__public__enc__key__x, const OCTETSTRING_template& p__public__enc__key__y, const OCTETSTRING_template& p__public__enc__compressed__key, const INTEGER_template& p__public__enc__key__compressed__mode) {
loggers::get_instance().log(">>> fx__store__certificate: '%s'", static_cast<const char*>(p__cert__id));
int result;
......@@ -1191,9 +1192,9 @@ namespace LibItsSecurity__Functions
const OCTETSTRING private_enc_key = p__private__enc__key.valueof();
const OCTETSTRING public_enc_key_x = p__public__enc__key__x.valueof();
const OCTETSTRING public_enc_key_y = p__public__enc__key__y.valueof();
result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hashid8, p__issuer, p__private__enc__key.valueof(), p__public__enc__key__x.valueof(), p__public__enc__key__y.valueof(), p__public__enc__compressed__key.valueof(), p__public__enc__key__compressed__mode.valueof());
result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hash__256, p__hashid8, p__issuer, p__private__enc__key.valueof(), p__public__enc__key__x.valueof(), p__public__enc__key__y.valueof(), p__public__enc__compressed__key.valueof(), p__public__enc__key__compressed__mode.valueof());
} else {
result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hashid8, p__issuer, OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), INTEGER(-1));
result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hash, p__hash__256, p__hashid8, p__issuer, OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), OCTETSTRING(0, nullptr), INTEGER(-1));
}
return (result == 0);
......@@ -1293,6 +1294,25 @@ namespace LibItsSecurity__Functions
return TRUE;
}
/**
* \brief Read the whole-hash of the certificate using SHA 256
* \param p_certificate_id the certificate identifier
* \param p_hash the expected certificate
* \return true on success, false otherwise
*/
BOOLEAN fx__readCertificateHash256(
const CHARSTRING& p__certificateId,
OCTETSTRING& p__hash
) {
loggers::get_instance().log(">>> fx__readCertificateHash256: '%s'", static_cast<const char*>(p__certificateId));
if (security_services::get_instance().read_certificate_hash_sha_256(p__certificateId, p__hash) == -1) {
return FALSE;
}
return TRUE;
}
/**
* \brief Read the private keys for the specified certificate
* \param p_certificate_id the keys identifier
......
......@@ -10,7 +10,7 @@
unsigned char commsignia_layer::_fixed_header[10] = { 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0D };
commsignia_layer::commsignia_layer(const std::string & p_type, const std::string & param) : layer(p_type), _params(), _c2p_recv{0}, _802_11p_hdr{0}, _c2p_llc_hdr{0}, _mac_src(), _eth_type() {
commsignia_layer::commsignia_layer(const std::string & p_type, const std::string & param) : layer(p_type), _params(), _mac_src(), _eth_type() {
loggers::get_instance().log(">>> commsignia_layer::commsignia_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
......@@ -31,7 +31,7 @@ commsignia_layer::commsignia_layer(const std::string & p_type, const std::string
_eth_type = converter::get_instance().hexa_to_bytes(_params[params::eth_type]);
it = _params.find(params::interface_id);
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("interface_id"), "1"));
_params.insert(std::pair<std::string, std::string>(std::string("interface_id"), "1")); // The interfce id for filtering & to send on
}
it = _params.find(std::string("power_tx"));
if (it == _params.cend()) {
......@@ -58,14 +58,14 @@ void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
buffer += int2oct(0, 1); // Injection to radio
}
buffer += int2oct(0, 1); // Fix
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Injection=", buffer);
buffer += int2oct(std::stoi(_params[params::interface_id]), 4);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Interface=", buffer);
buffer += int2oct(std::stoi(_params[std::string("data_rate")]), 2);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: data_rate=", buffer);
buffer += int2oct(7, 1); // MAC user priority
buffer += int2oct(0x80000000 & std::stoi(_params[std::string("power_tx")]), 4); // Negative number
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: PowerTx=", buffer);
// Destination MAC address
params::const_iterator it = params.find(params::mac_dst); // Find in provided parameters, params
if (it != params.cend()) {
......@@ -78,7 +78,7 @@ void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
buffer += str2oct(CHARSTRING(_params[params::mac_bc].c_str()));
}
}
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: mac_dst=", buffer);
// Source MAC address
it = params.find(params::mac_src); // Find in provided parameters, params
if (it != params.cend()) {
......@@ -91,14 +91,14 @@ void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
buffer += str2oct(CHARSTRING(_params[params::mac_src].c_str()));
}
}
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: mac_src=", buffer);
buffer += int2oct(0, 2); // Fixed
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
buffer += int2oct(data.lengthof(), 2);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: ", buffer);
buffer += data;
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Fixed=", buffer);
buffer += int2oct(data.lengthof(), 2); // Data length
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Data length=", buffer);
buffer += data; // Payload
loggers::get_instance().log_msg("commsignia_layer::send_data: ", buffer);
loggers::get_instance().log_msg("commsignia_layer::send_data: Final buffer=", buffer);
send_to_all_layers(buffer, params);
}
......@@ -106,38 +106,91 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg(">>> commsignia_layer::receive_data: ", data);
const unsigned char* p = static_cast<const unsigned char *>(data);
const unsigned char c2p_ver = (unsigned char)*p;
// Check the frame version
if (*p != 0x12) {
// Discard it, on;y use TX version
if ((c2p_ver != 0x11) && (c2p_ver != 0x17)) { // Rx G5 or LTE-V2X
// Discard it, only use G5 or LTE-V2X RX version
return;
}
const commsignia_layer::c2p_s_v1_tx_t* r = (const commsignia_layer::c2p_s_v1_tx_t*)p;
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r->s_header.u8_ver_type);
loggers::get_instance().log("commsignia_layer::receive_data: timestamp1=%08x", ntohl(r->s_header.u32_tst_sec));
loggers::get_instance().log("commsignia_layer::receive_data: timestamp2=%08x", ntohl(r->s_header.u32_tst_msec));
loggers::get_instance().log("commsignia_layer::receive_data: primary_channel=%08x", r->u8_primary_channel);
loggers::get_instance().log("commsignia_layer::receive_data: secondary_channel=%08x", r->u8_secondary_channel);
loggers::get_instance().log("commsignia_layer::receive_data: antenna=%02x", r->u8_antenna);
loggers::get_instance().log("commsignia_layer::receive_data: speed=%d", ntohs(r->u16_speed));
loggers::get_instance().log("commsignia_layer::receive_data: heading=%d", ntohs(r->u16_heading));
loggers::get_instance().log("commsignia_layer::receive_data: txp=%02x", r->s8_txp);
loggers::get_instance().log("commsignia_layer::receive_data: s8_tssi_ant_1=%d", r->s8_tssi_ant_1);
loggers::get_instance().log("commsignia_layer::receive_data: s8_tssi_ant_2=%d", r->s8_tssi_ant_2);
// Filtering on antenna index
loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r->u8_antenna, static_cast<unsigned char>(std::stoi(_params[params::interface_id])));
if (r->u8_antenna != std::stoi(_params[params::interface_id])) {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong antenna id");
// TODO return;
} // else, continue
const commsignia_layer::c2p_802_11p_hdr* h = (const commsignia_layer::c2p_802_11p_hdr*)(p + sizeof(commsignia_layer::c2p_s_v1_tx_t) - 1);
loggers::get_instance().log("commsignia_layer::receive_data: frame_ctrl=%04x", ntohs(h->frame_ctrl));
OCTETSTRING dst = OCTETSTRING(6, (const unsigned char*)&h->dst_addr);
if (c2p_ver == 0x11) { // G5
commsignia_layer::c2p_s_v1_rx_t r;
r.s_header.u8_ver_type = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r.s_header.u8_ver_type);
memcpy((void*)&r.s_header.u32_tst_sec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/r.s_header.u32_tst_sec)/*)*/;
memcpy((void*)&r.s_header.u32_tst_msec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/r.s_header.u32_tst_msec)/*)*/;
r.u8_primary_channel = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: primary_channel=%02x", r.u8_primary_channel);
r.u8_secondary_channel = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: secondary_channel=%02x", r.u8_secondary_channel);
r.u8_used_interface = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: used_interface=%02x", r.u8_used_interface);
r.u8_data_rate = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: data_rate=%02x", r.u8_data_rate);
r.u8_antenna = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: antenna=%02x", r.u8_antenna);
memcpy((void*)&r.s32_latitude, (int*)p, sizeof(int)); p += sizeof(int);
loggers::get_instance().log("commsignia_layer::receive_data: latitude=%08x", r.s32_latitude);
memcpy((void*)&r.s32_longitude, (int*)p, sizeof(int)); p += sizeof(int);
loggers::get_instance().log("commsignia_layer::receive_data: longitude=%08x", r.s32_longitude);
memcpy((void*)&r.u16_speed, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: speed=%02x", r.u16_speed); // ntohs
memcpy((void*)&r.u16_heading, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: heading=%02x", r.u16_heading);
r.s8_rssi_ant_1 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_rssi_ant_1=%02x", r.s8_rssi_ant_1);
r.s8_rssi_ant_2 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_rssi_ant_2=%02x", r.s8_rssi_ant_2);
r.s8_noise_ant_1 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_noise_ant_1=%02x", r.s8_noise_ant_1);
r.s8_noise_ant_2 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_noise_ant_2=%02x", r.s8_noise_ant_2);
memcpy((void*)&r.u16_cbr_ant_1, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: cbr_ant_1=%04x", r.u16_cbr_ant_1);
memcpy((void*)&r.u16_cbr_ant_2, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: cbr_ant_2=%04x", r.u16_cbr_ant_2);
// Filtering on antenna index
loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r.u8_antenna, static_cast<unsigned char>(std::stoi(_params[params::interface_id])));
if (r.u8_antenna != std::stoi(_params[params::interface_id])) {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong antenna id");
// TODO return;
} // else, continue
} else { // LTE-CV2X
commsignia_layer::c2p_s_v1_rx_cv2x_t r;
r.s_header.u8_ver_type = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r.s_header.u8_ver_type);
memcpy((void*)&r.s_header.u32_tst_sec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/r.s_header.u32_tst_sec)/*)*/;
memcpy((void*)&r.s_header.u32_tst_msec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/r.s_header.u32_tst_msec)/*)*/;
r.u8_socket_index = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: u8_socket_index=%02x", r.u8_socket_index);
memcpy((void*)&r.u16_ethertype, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: u16_ethertype=%04x", r.u16_ethertype);
r.s8_rssi = (signed char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_rssi=%02x", r.s8_rssi);
r.u8_datarate_500kbps = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: u8_datarate_500kbps=%02x", r.u8_datarate_500kbps);
}
commsignia_layer::c2p_802_11p_hdr h;
memcpy((void*)&h.frame_ctrl, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: frame_ctrl=%04x", h.frame_ctrl);
memcpy((void*)&h.duration, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: duration=%04x", h.duration);
memcpy((void*)&h.dst_addr, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.src_addr, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.bss_id, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.fragment_seq_num, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: fragment_seq_num=%04x", h.fragment_seq_num);
OCTETSTRING dst = OCTETSTRING(6, (const unsigned char*)&h.dst_addr);
loggers::get_instance().log_msg("commsignia_layer::receive_data: dst: ", dst);
OCTETSTRING src = OCTETSTRING(6, (const unsigned char*)&h->src_addr);
OCTETSTRING src = OCTETSTRING(6, (const unsigned char*)&h.src_addr);
loggers::get_instance().log_msg("commsignia_layer::receive_data: src: ", src);
// Filtering on source MAC address of the packet
......@@ -148,24 +201,21 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
} // else, continue
const commsignia_layer::c2p_llc_hdr* l;
int length;
if ((ntohs(h->frame_ctrl) & 0xf000) == 0x8000) {
l = (const commsignia_layer::c2p_llc_hdr*)(p + sizeof(commsignia_layer::c2p_s_v1_tx_t) - 1 + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl));
length = sizeof(commsignia_layer::c2p_s_v1_tx_t) - 1 + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl) + sizeof(commsignia_layer::c2p_llc_hdr);
if (c2p_ver == 0x11) {
if ((ntohs(h.frame_ctrl) & 0xf000) == 0x8000) {
l = (const commsignia_layer::c2p_llc_hdr*)(static_cast<const unsigned char *>(data) + sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl));
length = sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl) + sizeof(commsignia_layer::c2p_llc_hdr);
} else {
l = (const commsignia_layer::c2p_llc_hdr*)(p + sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr));
length = sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_llc_hdr);
}
loggers::get_instance().log("commsignia_layer::receive_data: dsap=%02x", l->dsap);
loggers::get_instance().log("commsignia_layer::receive_data: ssap=%02x", l->ssap);
loggers::get_instance().log("commsignia_layer::receive_data: ssap=%02x", l->ctrl);
loggers::get_instance().log("commsignia_layer::receive_data: type=%04x", l->type);
} else {
l = (const commsignia_layer::c2p_llc_hdr*)(p + sizeof(commsignia_layer::c2p_s_v1_tx_t) - 1 + sizeof(commsignia_layer::c2p_802_11p_hdr));
length = sizeof(commsignia_layer::c2p_s_v1_tx_t) - 1 + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_llc_hdr);
}
loggers::get_instance().log("commsignia_layer::receive_data: dsap=%02x", l->dsap);
loggers::get_instance().log("commsignia_layer::receive_data: ssap=%02x", l->ssap);
loggers::get_instance().log("commsignia_layer::receive_data: ssap=%02x", l->ctrl);
loggers::get_instance().log("commsignia_layer::receive_data: type=%04x", l->type);
length -= 4;
// Check ether type
//if ((_eth_type[1] == (unsigned char)((l->type & 0xff00) >> 8)) && (_eth_type[0] == (unsigned char)(l->type & 0xff))) { // Warning: Network ordered bytes
// Extract payload
......
......@@ -30,7 +30,25 @@ class commsignia_layer : public layer {
unsigned char u8_ver_type;
unsigned int u32_tst_sec;
unsigned int u32_tst_msec;
} c2p_s_header_t;
} __attribute__((__packed__)) c2p_s_header_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_primary_channel;
unsigned char u8_secondary_channel;
unsigned char u8_used_interface;
unsigned char u8_data_rate;
unsigned char u8_antenna;
int s32_latitude;
int s32_longitude;
unsigned short u16_speed;
unsigned short u16_heading;
signed char s8_rssi_ant_1;
signed char s8_rssi_ant_2;
signed char s8_noise_ant_1;
signed char s8_noise_ant_2;
unsigned short u16_cbr_ant_1;
unsigned short u16_cbr_ant_2;
} __attribute__((__packed__)) c2p_s_v1_rx_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_primary_channel;
......@@ -43,9 +61,27 @@ class commsignia_layer : public layer {
unsigned short u16_speed;
unsigned short u16_heading;
signed char s8_txp;
signed char s8_tssi_ant_1;