added EVCSInfo to SAEMs
This commit is contained in:
parent
948780526b
commit
dfbc7bf866
|
|
@ -13,6 +13,9 @@
|
|||
"asn_application.h": "c",
|
||||
"itspduheader.h": "c",
|
||||
"evchargingspotnotificationpoimessage.h": "c",
|
||||
"vcm.h": "c"
|
||||
"vcm.h": "c",
|
||||
"constr_sequence_of.h": "c",
|
||||
"asn_internal.h": "c",
|
||||
"bit_string.h": "c"
|
||||
}
|
||||
}
|
||||
556
src/config.c
556
src/config.c
|
|
@ -13,6 +13,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <it2s-asn/camv2/ProtectedCommunicationZone.h>
|
||||
#include <it2s-asn/tpm/TollingPaymentInfo.h>
|
||||
#include <it2s-asn/evcsnm/EVCSInfo.h>
|
||||
#include <zmq.h>
|
||||
|
||||
#include <it2s-tender/packet.h>
|
||||
|
|
@ -22,23 +23,29 @@
|
|||
#include <it2s-asn/itss-security/SecurityRequest.h>
|
||||
#include <it2s-asn/itss-security/SecurityReply.h>
|
||||
|
||||
static int fetch_target_address(char** addresses, uint16_t addresses_len) {
|
||||
static int fetch_target_address(char **addresses, uint16_t addresses_len)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
for (int i = 0; i < addresses_len; ++i) {
|
||||
char* addr = addresses[i];
|
||||
for (int i = 0; i < addresses_len; ++i)
|
||||
{
|
||||
char *addr = addresses[i];
|
||||
|
||||
// If TCP, ignore receiver addresses, e.g. tcp://*:[port]
|
||||
if (!memcmp(addr, "tcp", 3)) {
|
||||
if (!memcmp(addr, "tcp", 3))
|
||||
{
|
||||
bool found_astk = false;
|
||||
for (int j = 0; j < strlen(addr); ++j) {
|
||||
if (addr[j] == '*') {
|
||||
for (int j = 0; j < strlen(addr); ++j)
|
||||
{
|
||||
if (addr[j] == '*')
|
||||
{
|
||||
found_astk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_astk) continue;
|
||||
if (found_astk)
|
||||
continue;
|
||||
}
|
||||
|
||||
index = i;
|
||||
|
|
@ -48,24 +55,32 @@ static int fetch_target_address(char** addresses, uint16_t addresses_len) {
|
|||
return index;
|
||||
}
|
||||
|
||||
int facilities_config() {
|
||||
int facilities_config()
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
it2s_config_t* config = calloc(1, sizeof(it2s_config_t));
|
||||
it2s_config_t *config = calloc(1, sizeof(it2s_config_t));
|
||||
rv = it2s_config_read("/etc/it2s/itss.toml", config);
|
||||
if (rv) {
|
||||
if (rv)
|
||||
{
|
||||
log_error("[config] read config failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Logging - status messages
|
||||
bool use_syslog = false, use_std = false, use_file = false;
|
||||
for (int i = 0; i < config->general.logging.status_len; ++i) {
|
||||
if (!strcmp(config->general.logging.status[i], "syslog")) {
|
||||
for (int i = 0; i < config->general.logging.status_len; ++i)
|
||||
{
|
||||
if (!strcmp(config->general.logging.status[i], "syslog"))
|
||||
{
|
||||
use_syslog = true;
|
||||
} else if (!strcmp(config->general.logging.status[i], "std")) {
|
||||
}
|
||||
else if (!strcmp(config->general.logging.status[i], "std"))
|
||||
{
|
||||
use_std = true;
|
||||
} else if (!strcmp(config->general.logging.status[i], "file")) {
|
||||
}
|
||||
else if (!strcmp(config->general.logging.status[i], "file"))
|
||||
{
|
||||
use_file = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,58 +89,67 @@ int facilities_config() {
|
|||
itss_0init(&facilities.exit);
|
||||
|
||||
struct timeval time;
|
||||
gettimeofday(&time,NULL);
|
||||
gettimeofday(&time, NULL);
|
||||
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
|
||||
|
||||
facilities.zmq.responders = calloc(config->facilities.zmq.addresses_len + 1, sizeof(zmq_pollitem_t));
|
||||
facilities.zmq.n_responders = 1;
|
||||
|
||||
// Internal socket
|
||||
void* socket = itss_0bind(ZMQ_INTERNAL_ADDR, ZMQ_PAIR);
|
||||
void *socket = itss_0bind(ZMQ_INTERNAL_ADDR, ZMQ_PAIR);
|
||||
facilities.zmq.responders[0].socket = socket;
|
||||
facilities.zmq.responders[0].events = ZMQ_POLLIN;
|
||||
|
||||
for (int i = 0; i < config->facilities.zmq.addresses_len; ++i) {
|
||||
char* addr = config->facilities.zmq.addresses[i];
|
||||
for (int i = 0; i < config->facilities.zmq.addresses_len; ++i)
|
||||
{
|
||||
char *addr = config->facilities.zmq.addresses[i];
|
||||
|
||||
// IPC
|
||||
if (!memcmp(addr, "ipc", 3)) {
|
||||
|
||||
// Create dir
|
||||
if (!memcmp(addr, "ipc", 3))
|
||||
{
|
||||
|
||||
// Create dir
|
||||
int lp = 0;
|
||||
for (int j = 0; j < strlen(addr); ++j) {
|
||||
if (addr[j] == '/') lp = j;
|
||||
for (int j = 0; j < strlen(addr); ++j)
|
||||
{
|
||||
if (addr[j] == '/')
|
||||
lp = j;
|
||||
}
|
||||
|
||||
char dir[256];
|
||||
memcpy(dir, addr+6, lp-6);
|
||||
dir[lp-6] = 0;
|
||||
memcpy(dir, addr + 6, lp - 6);
|
||||
dir[lp - 6] = 0;
|
||||
|
||||
struct stat st = {0};
|
||||
if (stat(dir, &st) == -1) {
|
||||
if (stat(dir, &st) == -1)
|
||||
{
|
||||
mkdir(dir, 0777);
|
||||
}
|
||||
|
||||
// Bind
|
||||
void* socket = itss_0bind(addr, ZMQ_REP);
|
||||
void *socket = itss_0bind(addr, ZMQ_REP);
|
||||
|
||||
facilities.zmq.responders[facilities.zmq.n_responders].socket = socket;
|
||||
facilities.zmq.responders[facilities.zmq.n_responders].events = ZMQ_POLLIN;
|
||||
++facilities.zmq.n_responders;
|
||||
}
|
||||
else if (!memcmp(addr, "tcp", 3))
|
||||
{
|
||||
|
||||
} else if (!memcmp(addr, "tcp", 3)) {
|
||||
|
||||
bool found_astk = false;
|
||||
for (int j = 0; j < strlen(addr); ++j) {
|
||||
if (addr[j] == '*') {
|
||||
found_astk = true;
|
||||
bool found_astk = false;
|
||||
for (int j = 0; j < strlen(addr); ++j)
|
||||
{
|
||||
if (addr[j] == '*')
|
||||
{
|
||||
found_astk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_astk) {
|
||||
if (found_astk)
|
||||
{
|
||||
// Bind
|
||||
void* socket = itss_0bind(addr, ZMQ_REP);
|
||||
void *socket = itss_0bind(addr, ZMQ_REP);
|
||||
|
||||
facilities.zmq.responders[facilities.zmq.n_responders].socket = socket;
|
||||
facilities.zmq.responders[facilities.zmq.n_responders].events = ZMQ_POLLIN;
|
||||
|
|
@ -133,7 +157,8 @@ int facilities_config() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (facilities.zmq.n_responders <= 1) {
|
||||
if (facilities.zmq.n_responders <= 1)
|
||||
{
|
||||
log_info("[config] a valid address to listen to was not found, exiting now");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -141,10 +166,13 @@ int facilities_config() {
|
|||
|
||||
// Fetch [transport] address
|
||||
int index = fetch_target_address(config->transport.zmq.addresses, config->transport.zmq.addresses_len);
|
||||
if (index != -1) {
|
||||
facilities.zmq.transport_address = malloc(strlen(config->transport.zmq.addresses[index])+1);
|
||||
if (index != -1)
|
||||
{
|
||||
facilities.zmq.transport_address = malloc(strlen(config->transport.zmq.addresses[index]) + 1);
|
||||
strcpy(facilities.zmq.transport_address, config->transport.zmq.addresses[index]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] a valid address for [transport] was not found");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -152,10 +180,13 @@ int facilities_config() {
|
|||
|
||||
// Fetch [applications] address
|
||||
index = fetch_target_address(config->applications.zmq.addresses, config->applications.zmq.addresses_len);
|
||||
if (index != -1) {
|
||||
facilities.zmq.applications_address = malloc(strlen(config->applications.zmq.addresses[index])+1);
|
||||
if (index != -1)
|
||||
{
|
||||
facilities.zmq.applications_address = malloc(strlen(config->applications.zmq.addresses[index]) + 1);
|
||||
strcpy(facilities.zmq.applications_address, config->applications.zmq.addresses[index]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] a valid address for [applications] was not found");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -163,10 +194,13 @@ int facilities_config() {
|
|||
|
||||
// Fetch [security] address
|
||||
index = fetch_target_address(config->security.zmq.addresses, config->security.zmq.addresses_len);
|
||||
if (index != -1) {
|
||||
facilities.zmq.security_address = malloc(strlen(config->security.zmq.addresses[index])+1);
|
||||
if (index != -1)
|
||||
{
|
||||
facilities.zmq.security_address = malloc(strlen(config->security.zmq.addresses[index]) + 1);
|
||||
strcpy(facilities.zmq.security_address, config->security.zmq.addresses[index]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] a valid address for [security] was not found");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -174,10 +208,13 @@ int facilities_config() {
|
|||
|
||||
// Fetch [management] address
|
||||
index = fetch_target_address(config->management.zmq.addresses, config->management.zmq.addresses_len);
|
||||
if (index != -1) {
|
||||
facilities.zmq.management_address = malloc(strlen(config->management.zmq.addresses[index])+1);
|
||||
if (index != -1)
|
||||
{
|
||||
facilities.zmq.management_address = malloc(strlen(config->management.zmq.addresses[index]) + 1);
|
||||
strcpy(facilities.zmq.management_address, config->management.zmq.addresses[index]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] a valid address for [management] was not found");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -185,58 +222,89 @@ int facilities_config() {
|
|||
|
||||
// Values
|
||||
// General
|
||||
if (!strcmp("obu", config->general.itss_type)) {
|
||||
if (!strcmp("obu", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 5;
|
||||
} else if (!strcmp("rsu", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("rsu", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 15;
|
||||
} else if (!strcmp("unknown", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("unknown", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 0;
|
||||
} else if (!strcmp("pedestrian", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("pedestrian", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 1;
|
||||
} else if (!strcmp("cyclist", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("cyclist", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 2;
|
||||
} else if (!strcmp("moped", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("moped", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 3;
|
||||
} else if (!strcmp("motorcycle", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("motorcycle", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 4;
|
||||
} else if (!strcmp("passengerCar", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("passengerCar", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 5;
|
||||
} else if (!strcmp("bus", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("bus", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 6;
|
||||
} else if (!strcmp("lightTruck", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("lightTruck", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 7;
|
||||
} else if (!strcmp("heavyTruck", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("heavyTruck", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 8;
|
||||
} else if (!strcmp("trailer", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("trailer", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 9;
|
||||
} else if (!strcmp("specialVehicles", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("specialVehicles", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 10;
|
||||
} else if (!strcmp("tram", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("tram", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 11;
|
||||
} else if (!strcmp("roadSideUnit", config->general.itss_type)) {
|
||||
}
|
||||
else if (!strcmp("roadSideUnit", config->general.itss_type))
|
||||
{
|
||||
facilities.station_type = 15;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] unrecognized ITS-S type, running as OBU");
|
||||
facilities.station_type = 5;
|
||||
}
|
||||
|
||||
|
||||
facilities.use_security = config->security.use_security;
|
||||
|
||||
pthread_mutex_init(&facilities.id.lock, NULL);
|
||||
pthread_mutex_init(&facilities.id.change.lock, NULL);
|
||||
|
||||
facilities.id.change.random = config->security.identity.random;
|
||||
if (facilities.id.change.random) {
|
||||
if (facilities.id.change.random)
|
||||
{
|
||||
// Ask [security] for station id
|
||||
|
||||
SecurityRequest_t* sREQ = calloc(1, sizeof(SecurityRequest_t));
|
||||
SecurityReply_t* sREP = NULL;
|
||||
|
||||
SecurityRequest_t *sREQ = calloc(1, sizeof(SecurityRequest_t));
|
||||
SecurityReply_t *sREP = NULL;
|
||||
|
||||
sREQ->present = SecurityRequest_PR_ids;
|
||||
sREQ->choice.ids.list.count = 2;
|
||||
sREQ->choice.ids.list.size = 2*sizeof(void*);
|
||||
sREQ->choice.ids.list.array = malloc(2*sizeof(void*));
|
||||
sREQ->choice.ids.list.size = 2 * sizeof(void *);
|
||||
sREQ->choice.ids.list.array = malloc(2 * sizeof(void *));
|
||||
sREQ->choice.ids.list.array[0] = calloc(1, sizeof(SecurityIdType_t));
|
||||
*sREQ->choice.ids.list.array[0] = SecurityIdType_stationId;
|
||||
sREQ->choice.ids.list.array[1] = calloc(1, sizeof(SecurityIdType_t));
|
||||
|
|
@ -245,51 +313,56 @@ int facilities_config() {
|
|||
uint8_t b_tx[256], b_rx[256];
|
||||
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sREQ, b_tx, 256);
|
||||
|
||||
void* ss = itss_0connect(facilities.zmq.security_address, ZMQ_REQ);
|
||||
void *ss = itss_0connect(facilities.zmq.security_address, ZMQ_REQ);
|
||||
itss_0send(ss, b_tx, enc.encoded);
|
||||
int rl = itss_0recv_rt(&ss, b_rx, 256, b_tx, 256, -1);
|
||||
itss_0close(ss);
|
||||
if (rl == -1) {
|
||||
if (rl == -1)
|
||||
{
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void**) &sREP, b_rx, 256);
|
||||
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityReply, (void **)&sREP, b_rx, 256);
|
||||
|
||||
if (sREP->returnCode == SecurityReplyReturnCode_rejected) {
|
||||
if (sREP->returnCode == SecurityReplyReturnCode_rejected)
|
||||
{
|
||||
// TODO handle it
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sREP->data->choice.ids.list.count; ++i) {
|
||||
switch (sREP->data->choice.ids.list.array[i]->present) {
|
||||
case SecurityId_PR_stationId:
|
||||
facilities.id.station_id = sREP->data->choice.ids.list.array[i]->choice.stationId;
|
||||
break;
|
||||
case SecurityId_PR_ipv6Address:
|
||||
memcpy(facilities.id.ipv6_addr, sREP->data->choice.ids.list.array[i]->choice.ipv6Address.buf, 16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
for (int i = 0; i < sREP->data->choice.ids.list.count; ++i)
|
||||
{
|
||||
switch (sREP->data->choice.ids.list.array[i]->present)
|
||||
{
|
||||
case SecurityId_PR_stationId:
|
||||
facilities.id.station_id = sREP->data->choice.ids.list.array[i]->choice.stationId;
|
||||
break;
|
||||
case SecurityId_PR_ipv6Address:
|
||||
memcpy(facilities.id.ipv6_addr, sREP->data->choice.ids.list.array[i]->choice.ipv6Address.buf, 16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sREQ);
|
||||
ASN_STRUCT_FREE(asn_DEF_SecurityReply, sREP);
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
facilities.id.station_id = config->security.identity.station_id;
|
||||
|
||||
uint8_t src_mac[6];
|
||||
unsigned int tmp_uint[6];
|
||||
|
||||
sscanf(config->security.identity.mac_address, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
&tmp_uint[0],
|
||||
&tmp_uint[1],
|
||||
&tmp_uint[2],
|
||||
&tmp_uint[3],
|
||||
&tmp_uint[4],
|
||||
&tmp_uint[5]);
|
||||
&tmp_uint[0],
|
||||
&tmp_uint[1],
|
||||
&tmp_uint[2],
|
||||
&tmp_uint[3],
|
||||
&tmp_uint[4],
|
||||
&tmp_uint[5]);
|
||||
|
||||
src_mac[0] = (uint8_t)tmp_uint[0];
|
||||
src_mac[1] = (uint8_t)tmp_uint[1];
|
||||
|
|
@ -299,19 +372,18 @@ int facilities_config() {
|
|||
src_mac[5] = (uint8_t)tmp_uint[5];
|
||||
|
||||
memset(facilities.id.ipv6_addr, 0, 8);
|
||||
memcpy(facilities.id.ipv6_addr+8, src_mac, 3);
|
||||
memcpy(facilities.id.ipv6_addr + 8, src_mac, 3);
|
||||
facilities.id.ipv6_addr[11] = 0xff;
|
||||
facilities.id.ipv6_addr[12] = 0xfe;
|
||||
memcpy(facilities.id.ipv6_addr+13, src_mac+3, 3);
|
||||
memcpy(facilities.id.ipv6_addr + 13, src_mac + 3, 3);
|
||||
facilities.id.ipv6_addr[8] ^= 0x02;
|
||||
}
|
||||
|
||||
|
||||
// DENM
|
||||
facilities.den.n_max_events = config->facilities.denm.nmax_active_events;
|
||||
|
||||
// CAM
|
||||
facilities.lightship.active = config->facilities.cam.activate;
|
||||
facilities.lightship.active = config->facilities.cam.activate;
|
||||
facilities.lightship.vehicle_gen_min = config->facilities.cam.obu_period_min;
|
||||
facilities.lightship.vehicle_gen_max = config->facilities.cam.obu_period_max;
|
||||
facilities.lightship.rsu_gen_min = config->facilities.cam.rsu_period_min;
|
||||
|
|
@ -329,27 +401,36 @@ int facilities_config() {
|
|||
facilities.dissemination.radar_rotation = config->applications.its_center.radar_rotation;
|
||||
facilities.dissemination.tmc_connect = config->facilities.cpm.tmc_connected;
|
||||
facilities.dissemination.T_AddSensorInformation = 1000;
|
||||
int oa_start = (360-facilities.dissemination.radar_rotation) * 10 - 500;
|
||||
int oa_end = (360-facilities.dissemination.radar_rotation) * 10 + 500;
|
||||
int oa_start = (360 - facilities.dissemination.radar_rotation) * 10 - 500;
|
||||
int oa_end = (360 - facilities.dissemination.radar_rotation) * 10 + 500;
|
||||
facilities.dissemination.opening_angle_start = (oa_start + 3600) % 3600;
|
||||
facilities.dissemination.opening_angle_end = (oa_end + 3600) % 3600;
|
||||
|
||||
facilities.dissemination.int_radar = malloc(strlen(config->facilities.cpm.radar_interface)+1);
|
||||
strcpy(facilities.dissemination.int_radar,config->facilities.cpm.radar_interface);
|
||||
facilities.dissemination.ip_radar = malloc(strlen(config->facilities.cpm.radar_ip)+1);
|
||||
strcpy(facilities.dissemination.ip_radar,config->facilities.cpm.radar_ip);
|
||||
facilities.dissemination.int_radar = malloc(strlen(config->facilities.cpm.radar_interface) + 1);
|
||||
strcpy(facilities.dissemination.int_radar, config->facilities.cpm.radar_interface);
|
||||
facilities.dissemination.ip_radar = malloc(strlen(config->facilities.cpm.radar_ip) + 1);
|
||||
strcpy(facilities.dissemination.ip_radar, config->facilities.cpm.radar_ip);
|
||||
|
||||
// TPM
|
||||
facilities.tolling.enabled = config->facilities.tpm.activate;
|
||||
if (!strcmp("simple", config->facilities.tpm.protocol)) {
|
||||
if (!strcmp("simple", config->facilities.tpm.protocol))
|
||||
{
|
||||
facilities.tolling.protocol.p = TOLLING_PROTOCOL_SIMPLE;
|
||||
} else if (!strcmp("tls", config->facilities.tpm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("tls", config->facilities.tpm.protocol))
|
||||
{
|
||||
facilities.tolling.protocol.p = TOLLING_PROTOCOL_TLS;
|
||||
} else if (!strcmp("tls-gn", config->facilities.tpm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("tls-gn", config->facilities.tpm.protocol))
|
||||
{
|
||||
facilities.tolling.protocol.p = TOLLING_PROTOCOL_TLS_GN;
|
||||
} else if (!strcmp("tls-shs", config->facilities.tpm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("tls-shs", config->facilities.tpm.protocol))
|
||||
{
|
||||
facilities.tolling.protocol.p = TOLLING_PROTOCOL_TLS_SHS;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] unrecognized tolling protocol, defaulting to 'simple'");
|
||||
facilities.tolling.protocol.p = TOLLING_PROTOCOL_SIMPLE;
|
||||
}
|
||||
|
|
@ -357,37 +438,58 @@ int facilities_config() {
|
|||
|
||||
// MCM
|
||||
facilities.coordination.active = config->facilities.mcm.activate;
|
||||
if (!strcmp("vcm-RR", config->facilities.mcm.protocol)) {
|
||||
if (!strcmp("vcm-RR", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
} else if (!strcmp("vcm-RR1C", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("vcm-RR1C", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR1C;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
} else if (!strcmp("vcm-RR1Cc", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("vcm-RR1Cc", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR1C;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
} else if (!strcmp("vcm-RRAC", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("vcm-RRAC", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RRAC;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
} else if (!strcmp("vcm-RRACc", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("vcm-RRACc", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RRAC;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
} else if (!strcmp("evcm-RR-PBFT", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("evcm-RR-PBFT", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR;
|
||||
facilities.coordination.chain.enabled = false;
|
||||
} else if (!strcmp("evcm-RR1C-PBFT", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("evcm-RR1C-PBFT", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR1C;
|
||||
facilities.coordination.chain.enabled = false;
|
||||
} else if (!strcmp("evcm-RR1Cc-PBFT", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("evcm-RR1Cc-PBFT", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR1C;
|
||||
facilities.coordination.chain.enabled = false;
|
||||
} else if (!strcmp("evcm-RRAC-PBFT", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("evcm-RRAC-PBFT", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RRAC;
|
||||
facilities.coordination.chain.enabled = false;
|
||||
} else if (!strcmp("evcm-RRACc-PBFT", config->facilities.mcm.protocol)) {
|
||||
}
|
||||
else if (!strcmp("evcm-RRACc-PBFT", config->facilities.mcm.protocol))
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RRAC;
|
||||
facilities.coordination.chain.enabled = false;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
facilities.coordination.protocol = MC_PROTOCOL_VCM_RR;
|
||||
facilities.coordination.chain.enabled = true;
|
||||
}
|
||||
|
|
@ -396,12 +498,65 @@ int facilities_config() {
|
|||
|
||||
// EVCSNM
|
||||
facilities.evcsnm_args.activate = config->facilities.evcsnm.activate;
|
||||
if (facilities.station_type == 15)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
DIR *d = opendir(config->facilities.evcsnm.evcsi_path);
|
||||
struct dirent *dir;
|
||||
char file[256];
|
||||
char ti_xml[2048];
|
||||
if (d)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL && i < EVCSNM_INFOS_MAX_LENGTH)
|
||||
{
|
||||
if (dir->d_name[0] == '.')
|
||||
continue;
|
||||
sprintf(file, "%s/%s", config->facilities.evcsnm.evcsi_path, dir->d_name);
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (!fp)
|
||||
continue;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint16_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if (!size)
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
if (!fread(ti_xml, 1, size, fp))
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
EVCSInfo_t *ti = calloc(1, sizeof(EVCSInfo_t));
|
||||
|
||||
asn_dec_rval_t dec = xer_decode(NULL, &asn_DEF_EVCSInfo, (void **)&ti, ti_xml, size);
|
||||
if (!dec.code)
|
||||
{
|
||||
facilities.evcsnm_args.infos.z[i] = calloc(1, sizeof(evcs_info_t));
|
||||
facilities.evcsnm_args.infos.z[i]->asn = ti;
|
||||
++facilities.evcsnm_args.infos.length;
|
||||
++i;
|
||||
log_debug("[config] loaded evcs info | id:%lld", ti->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] failure to decode evcs info '%s'", dir->d_name);
|
||||
ASN_STRUCT_FREE(asn_DEF_EVCSInfo, ti);
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
// Replay
|
||||
facilities.replay = config->networking.replay.activate;
|
||||
|
||||
// PZ
|
||||
if (facilities.station_type == 15) {
|
||||
if (facilities.station_type == 15)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -409,45 +564,54 @@ int facilities_config() {
|
|||
struct dirent *dir;
|
||||
char file[256];
|
||||
char pz_xml[2048];
|
||||
if (d) {
|
||||
while ((dir = readdir(d)) != NULL && i < 16) {
|
||||
if (dir->d_name[0] == '.') continue;
|
||||
if (d)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL && i < 16)
|
||||
{
|
||||
if (dir->d_name[0] == '.')
|
||||
continue;
|
||||
sprintf(file, "%s/%s", config->facilities.protected_zones.path, dir->d_name);
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (!fp) continue;
|
||||
if (!fp)
|
||||
continue;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint16_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if (!size) {
|
||||
if (!size)
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
if (!fread(pz_xml, 1, size, fp)) {
|
||||
if (!fread(pz_xml, 1, size, fp))
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
|
||||
ProtectedCommunicationZone_t *zone = calloc(1, sizeof(ProtectedCommunicationZone_t));
|
||||
|
||||
asn_dec_rval_t dec = xer_decode(NULL, &asn_DEF_ProtectedCommunicationZone, (void**) &zone, pz_xml, size);
|
||||
if (!dec.code) {
|
||||
asn_dec_rval_t dec = xer_decode(NULL, &asn_DEF_ProtectedCommunicationZone, (void **)&zone, pz_xml, size);
|
||||
if (!dec.code)
|
||||
{
|
||||
facilities.lightship.protected_zones.pz[i] = zone;
|
||||
++facilities.lightship.protected_zones.pz_len;
|
||||
++i;
|
||||
log_debug("[config] loaded protection zone @ (%lld, %lld)", zone->protectedZoneLatitude, zone->protectedZoneLongitude);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] failure to decode protection zone '%s'", dir->d_name);
|
||||
ASN_STRUCT_FREE(asn_DEF_ProtectedCommunicationZone, zone);
|
||||
}
|
||||
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
|
||||
// TZ
|
||||
if (facilities.station_type == 15) {
|
||||
if (facilities.station_type == 15)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -455,42 +619,50 @@ int facilities_config() {
|
|||
struct dirent *dir;
|
||||
char file[256];
|
||||
char ti_xml[2048];
|
||||
if (d) {
|
||||
while ((dir = readdir(d)) != NULL && i < TOLLING_INFOS_MAX_LENGTH) {
|
||||
if (dir->d_name[0] == '.') continue;
|
||||
if (d)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL && i < TOLLING_INFOS_MAX_LENGTH)
|
||||
{
|
||||
if (dir->d_name[0] == '.')
|
||||
continue;
|
||||
sprintf(file, "%s/%s", config->facilities.tpm.tis_path, dir->d_name);
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (!fp) continue;
|
||||
if (!fp)
|
||||
continue;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint16_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if (!size) {
|
||||
if (!size)
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
if (!fread(ti_xml, 1, size, fp)) {
|
||||
if (!fread(ti_xml, 1, size, fp))
|
||||
{
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
|
||||
TollingPaymentInfo_t *ti = calloc(1, sizeof(TollingPaymentInfo_t));
|
||||
|
||||
asn_dec_rval_t dec = xer_decode(NULL, &asn_DEF_TollingPaymentInfo, (void**) &ti, ti_xml, size);
|
||||
if (!dec.code) {
|
||||
asn_dec_rval_t dec = xer_decode(NULL, &asn_DEF_TollingPaymentInfo, (void **)&ti, ti_xml, size);
|
||||
if (!dec.code)
|
||||
{
|
||||
facilities.tolling.infos.z[i] = calloc(1, sizeof(tolling_info_t));
|
||||
facilities.tolling.infos.z[i]->asn = ti;
|
||||
++facilities.tolling.infos.length;
|
||||
++i;
|
||||
log_debug("[config] loaded tolling info | id:%lld type:%s",
|
||||
ti->id,
|
||||
ti->tollType==TollType_entry ? "entry": ti->tollType==TollType_exit ? "exit": "single"
|
||||
);
|
||||
} else {
|
||||
log_debug("[config] loaded tolling info | id:%lld type:%s",
|
||||
ti->id,
|
||||
ti->tollType == TollType_entry ? "entry" : ti->tollType == TollType_exit ? "exit"
|
||||
: "single");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("[config] failure to decode tolling info '%s'", dir->d_name);
|
||||
ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, ti);
|
||||
}
|
||||
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
|
|
@ -498,7 +670,7 @@ int facilities_config() {
|
|||
|
||||
itss_epv_init();
|
||||
|
||||
ManagementRequest_t* mreq = calloc(1, sizeof(ManagementRequest_t));
|
||||
ManagementRequest_t *mreq = calloc(1, sizeof(ManagementRequest_t));
|
||||
mreq->present = ManagementRequest_PR_attributes;
|
||||
mreq->choice.attributes.present = ManagementRequestAttributes_PR_get;
|
||||
mreq->choice.attributes.choice.get.coordinates = 1;
|
||||
|
|
@ -511,33 +683,35 @@ int facilities_config() {
|
|||
mreq->choice.attributes.choice.get.clock = 1;
|
||||
mreq->choice.attributes.choice.get.clockOffset = 1;
|
||||
mreq->choice.attributes.choice.get.trajectory = config->facilities.mcm.activate;
|
||||
void* management_socket = itss_0connect(facilities.zmq.management_address, ZMQ_REQ);
|
||||
void *management_socket = itss_0connect(facilities.zmq.management_address, ZMQ_REQ);
|
||||
uint8_t b_tx[256], b_rx[256];
|
||||
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_ManagementRequest, NULL, mreq, b_tx, 256);
|
||||
|
||||
itss_0send(management_socket, b_tx, enc.encoded);
|
||||
int rl = itss_0recv_rt(&management_socket, b_rx, 256, b_tx, 256, -1);
|
||||
itss_0close(management_socket);
|
||||
if (rl == -1) {
|
||||
if (rl == -1)
|
||||
{
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ManagementReply_t* mrep = calloc(1, sizeof(ManagementReply_t));
|
||||
oer_decode(NULL, &asn_DEF_ManagementReply, (void**) &mrep, b_rx, 256);
|
||||
ManagementReply_t *mrep = calloc(1, sizeof(ManagementReply_t));
|
||||
oer_decode(NULL, &asn_DEF_ManagementReply, (void **)&mrep, b_rx, 256);
|
||||
long lat, lon, alt, alt_conf;
|
||||
if (mrep->returnCode == ManagementReplyReturnCode_accepted &&
|
||||
mrep->data &&
|
||||
mrep->data->choice.attributes.coordinates &&
|
||||
mrep->data->choice.attributes.altitude &&
|
||||
mrep->data->choice.attributes.heading &&
|
||||
mrep->data->choice.attributes.speed &&
|
||||
mrep->data->choice.attributes.acceleration &&
|
||||
mrep->data->choice.attributes.clockType &&
|
||||
mrep->data->choice.attributes.clock &&
|
||||
mrep->data->choice.attributes.clockOffset &&
|
||||
mrep->data->choice.attributes.gpsType &&
|
||||
(!!mrep->data->choice.attributes.trajectory == mreq->choice.attributes.choice.get.trajectory)) {
|
||||
mrep->data &&
|
||||
mrep->data->choice.attributes.coordinates &&
|
||||
mrep->data->choice.attributes.altitude &&
|
||||
mrep->data->choice.attributes.heading &&
|
||||
mrep->data->choice.attributes.speed &&
|
||||
mrep->data->choice.attributes.acceleration &&
|
||||
mrep->data->choice.attributes.clockType &&
|
||||
mrep->data->choice.attributes.clock &&
|
||||
mrep->data->choice.attributes.clockOffset &&
|
||||
mrep->data->choice.attributes.gpsType &&
|
||||
(!!mrep->data->choice.attributes.trajectory == mreq->choice.attributes.choice.get.trajectory))
|
||||
{
|
||||
epv.space.latitude = mrep->data->choice.attributes.coordinates->latitude;
|
||||
epv.space.latitude_conf = mrep->data->choice.attributes.coordinates->latitudeConfidence;
|
||||
epv.space.longitude = mrep->data->choice.attributes.coordinates->longitude;
|
||||
|
|
@ -553,18 +727,22 @@ int facilities_config() {
|
|||
epv.space.type = *mrep->data->choice.attributes.gpsType;
|
||||
epv.time.type = *mrep->data->choice.attributes.clockType;
|
||||
|
||||
asn_INTEGER2ulong(mrep->data->choice.attributes.clock, (unsigned long long*) &epv.time.clock);
|
||||
asn_INTEGER2ulong(mrep->data->choice.attributes.clockOffset,(unsigned long long*) &epv.time.offset);
|
||||
asn_INTEGER2ulong(mrep->data->choice.attributes.clock, (unsigned long long *)&epv.time.clock);
|
||||
asn_INTEGER2ulong(mrep->data->choice.attributes.clockOffset, (unsigned long long *)&epv.time.offset);
|
||||
|
||||
if (config->facilities.mcm.activate) {
|
||||
if (config->facilities.mcm.activate)
|
||||
{
|
||||
epv.trajectory.len = mrep->data->choice.attributes.trajectory->list.count;
|
||||
for (int i = 0; i < mrep->data->choice.attributes.trajectory->list.count; ++i) {
|
||||
for (int i = 0; i < mrep->data->choice.attributes.trajectory->list.count; ++i)
|
||||
{
|
||||
epv.trajectory.path[i].latitude = mrep->data->choice.attributes.trajectory->list.array[i]->latitude;
|
||||
epv.trajectory.path[i].longitude = mrep->data->choice.attributes.trajectory->list.array[i]->longitude;
|
||||
asn_INTEGER2ulong(&mrep->data->choice.attributes.trajectory->list.array[i]->timestamp, (unsigned long long*) &epv.trajectory.path[i].timestamp);
|
||||
asn_INTEGER2ulong(&mrep->data->choice.attributes.trajectory->list.array[i]->timestamp, (unsigned long long *)&epv.trajectory.path[i].timestamp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("rejected MR attribute request");
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -572,11 +750,23 @@ int facilities_config() {
|
|||
ASN_STRUCT_FREE(asn_DEF_ManagementRequest, mreq);
|
||||
ASN_STRUCT_FREE(asn_DEF_ManagementReply, mrep);
|
||||
|
||||
if (config->facilities.saem.activate) { // TODO handle various services
|
||||
if (config->facilities.saem.activate)
|
||||
{ // TODO handle various services
|
||||
facilities.bulletin.to_provide_len = 1;
|
||||
facilities.bulletin.to_provide[0] = calloc(1, sizeof(announcement_t));
|
||||
facilities.bulletin.to_provide[0]->endpoint.port = 7010 + config->facilities.saem.service_to_advertise;
|
||||
facilities.bulletin.to_provide[0]->its_aid = config->facilities.saem.service_to_advertise;
|
||||
switch (config->facilities.saem.service_to_advertise)
|
||||
{
|
||||
case SAID_ETC:
|
||||
facilities.bulletin.to_provide[0]->endpoint.port = 7011;
|
||||
break;
|
||||
case SAID_EVCSN:
|
||||
facilities.bulletin.to_provide[0]->endpoint.port = Port_poi;
|
||||
break;
|
||||
default:
|
||||
log_error("unknown service to advertise! [config.c:facilities.saem.service_to_advertise]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
facilities.vehicle.length = config->facilities.vehicle.length;
|
||||
|
|
@ -585,18 +775,19 @@ int facilities_config() {
|
|||
|
||||
// Logging
|
||||
facilities.logging.recorder = config->facilities.logging.management;
|
||||
if (config->general.logging.enabled && config->facilities.logging.dbms) {
|
||||
if (config->general.logging.enabled && config->facilities.logging.dbms)
|
||||
{
|
||||
facilities.logging.dbms = calloc(1, sizeof(itss_db_t));
|
||||
if (itss_db_init(
|
||||
facilities.logging.dbms,
|
||||
config->general.logging.database,
|
||||
config->general.logging.table_style,
|
||||
ITSS_FACILITIES,
|
||||
config->general.logging.host,
|
||||
config->general.logging.port,
|
||||
config->general.logging.username,
|
||||
config->general.logging.password
|
||||
)) {
|
||||
facilities.logging.dbms,
|
||||
config->general.logging.database,
|
||||
config->general.logging.table_style,
|
||||
ITSS_FACILITIES,
|
||||
config->general.logging.host,
|
||||
config->general.logging.port,
|
||||
config->general.logging.username,
|
||||
config->general.logging.password))
|
||||
{
|
||||
log_error("failed to initialize the database -> turning off logging");
|
||||
free(facilities.logging.dbms);
|
||||
facilities.logging.dbms = NULL;
|
||||
|
|
@ -608,4 +799,3 @@ cleanup:
|
|||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
|||
15
src/evcsnm.c
15
src/evcsnm.c
|
|
@ -220,3 +220,18 @@ void *evcsn_service()
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
evcs_info_t* evcs_info_new(EVCSInfo_t* tpi) {
|
||||
evcs_info_t* ti = calloc(1, sizeof(evcs_info_t));
|
||||
|
||||
ti->timestamp = itss_time_get();
|
||||
ti->asn = tpi;
|
||||
|
||||
return ti;
|
||||
}
|
||||
|
||||
void evcs_info_free(evcs_info_t* ti) {
|
||||
ASN_STRUCT_FREE(asn_DEF_EVCSInfo, ti->asn);
|
||||
free(ti);
|
||||
}
|
||||
|
|
|
|||
26
src/evcsnm.h
26
src/evcsnm.h
|
|
@ -7,14 +7,16 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include <it2s-asn/evcsnm/EvcsnPdu.h>
|
||||
#include <it2s-asn/evcsnm/EVCSInfo.h>
|
||||
#include <it2s-asn/itss-transport/BTPPacketIndication.h>
|
||||
|
||||
#include <it2s-tender/epv.h>
|
||||
|
||||
#define EVCSNM_INFOS_MAX_LENGTH 16 //MAX number of charging spots
|
||||
#define POS_HISTORY_MAX_LEN 24
|
||||
#define PATH_HISTORY_MAX_LEN POS_HISTORY_MAX_LEN-1
|
||||
|
||||
enum EVCSNM_CHECK_R {
|
||||
enum EVCSNM_CHECK_R
|
||||
{
|
||||
EVCSNM_OK,
|
||||
EVCSNM_INVALID,
|
||||
EVCSNM_BAD_PERMISSIONS
|
||||
|
|
@ -32,17 +34,31 @@ enum EVCSNM_CHECK_R check_evcsnm(BTPPacketIndication_t *bpi, EvcsnPdu_t *evcsnm,
|
|||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void* evcsn_service();
|
||||
void *evcsn_service();
|
||||
|
||||
/**
|
||||
* Analyses a VCM
|
||||
* @param vcm The VCM to be analyzed
|
||||
* @return 0 on success, other value otherwise
|
||||
*/
|
||||
int evcsnm_check(EvcsnPdu_t* evcsnm);
|
||||
int evcsnm_check(EvcsnPdu_t *evcsnm);
|
||||
|
||||
typedef struct evcsnm_args {
|
||||
typedef struct evcs_info {
|
||||
uint64_t timestamp;
|
||||
EVCSInfo_t* asn;
|
||||
} evcs_info_t;
|
||||
|
||||
typedef struct evcsnm_args
|
||||
{
|
||||
bool activate;
|
||||
struct
|
||||
{
|
||||
evcs_info_t *z[EVCSNM_INFOS_MAX_LENGTH];
|
||||
uint8_t length;
|
||||
} infos;
|
||||
} evcsnm_args_t;
|
||||
|
||||
evcs_info_t* evcs_info_new(EVCSInfo_t* tpi);
|
||||
void evcs_info_free(evcs_info_t* ti);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
504
src/saem.c
504
src/saem.c
|
|
@ -12,108 +12,156 @@
|
|||
#include <it2s-asn/itss-security/SecurityRequest.h>
|
||||
#include <it2s-asn/itss-security/SecurityReply.h>
|
||||
#include <it2s-asn/tpm/TollingPaymentInfo.h>
|
||||
#include <it2s-asn/evcsnm/EVCSInfo.h>
|
||||
#include <it2s-asn/saem/SAEM.h>
|
||||
#include <zmq.h>
|
||||
|
||||
|
||||
SAEM_CODE_R saem_check(SAEM_t* saem, uint8_t* neighbour) {
|
||||
SAEM_CODE_R saem_check(SAEM_t *saem, uint8_t *neighbour)
|
||||
{
|
||||
|
||||
int rv = 0;
|
||||
|
||||
bulletin_t* bulletin = &facilities.bulletin;
|
||||
bulletin_t *bulletin = &facilities.bulletin;
|
||||
|
||||
if (saem->header.messageID != messageID_saem) {
|
||||
if (saem->header.messageID != messageID_saem)
|
||||
{
|
||||
return SAEM_INVALID_HEADER_MESSAGE_ID;
|
||||
}
|
||||
|
||||
if (saem->header.protocolVersion != 1) {
|
||||
if (saem->header.protocolVersion != 1)
|
||||
{
|
||||
return SAEM_INVALID_HEADER_VERSION;
|
||||
}
|
||||
|
||||
if (bulletin->to_consume_len >= MAX_ANNOUNCEMENTS_LEN - 1) {
|
||||
if (bulletin->to_consume_len >= MAX_ANNOUNCEMENTS_LEN - 1)
|
||||
{
|
||||
return SAEM_MAX_ANNOUNCEMENTS_REACHED;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&bulletin->lock);
|
||||
|
||||
if (saem->sam.body.serviceInfos) {
|
||||
for (int i = 0; i < saem->sam.body.serviceInfos->list.count; ++i) {
|
||||
ServiceInfo_t* si = saem->sam.body.serviceInfos->list.array[i];
|
||||
if (saem->sam.body.serviceInfos)
|
||||
{
|
||||
for (int i = 0; i < saem->sam.body.serviceInfos->list.count; ++i)
|
||||
{
|
||||
ServiceInfo_t *si = saem->sam.body.serviceInfos->list.array[i];
|
||||
|
||||
uint16_t its_aid = si->serviceID;
|
||||
|
||||
bool new_announcement = false;
|
||||
|
||||
if (si->chOptions.extensions) {
|
||||
if (si->chOptions.extensions)
|
||||
{
|
||||
|
||||
for (int e = 0; e < si->chOptions.extensions->list.count; ++e) {
|
||||
switch (si->chOptions.extensions->list.array[e]->present) {
|
||||
case ServiceInfoExt_PR_providerServiceContext:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.context_len = si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.context = malloc(si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size);
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->info.context,
|
||||
si->chOptions.extensions->list.array[e]->choice.providerServiceContext.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size
|
||||
);
|
||||
break;
|
||||
for (int e = 0; e < si->chOptions.extensions->list.count; ++e)
|
||||
{
|
||||
switch (si->chOptions.extensions->list.array[e]->present)
|
||||
{
|
||||
case ServiceInfoExt_PR_providerServiceContext:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.context_len = si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.context = malloc(si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size);
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->info.context,
|
||||
si->chOptions.extensions->list.array[e]->choice.providerServiceContext.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size);
|
||||
break;
|
||||
|
||||
case ServiceInfoExt_PR_applicationDataSAM:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.data_len = si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.data = malloc(si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size);
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->info.data,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size
|
||||
);
|
||||
case ServiceInfoExt_PR_applicationDataSAM:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.data_len = si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.data = malloc(si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size);
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->info.data,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size);
|
||||
|
||||
switch (its_aid) {
|
||||
case SAID_ETC:
|
||||
if (facilities.station_type != 15 && facilities.tolling.infos.length < TOLLING_INFOS_MAX_LENGTH) {
|
||||
TollingPaymentInfo_t* tpi = NULL;
|
||||
asn_dec_rval_t dec = uper_decode_complete(
|
||||
NULL,
|
||||
&asn_DEF_TollingPaymentInfo,
|
||||
(void**) &tpi,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size
|
||||
);
|
||||
if (!dec.code) {
|
||||
switch (its_aid)
|
||||
{
|
||||
case SAID_ETC:
|
||||
if (facilities.station_type != 15 && facilities.tolling.infos.length < TOLLING_INFOS_MAX_LENGTH)
|
||||
{
|
||||
TollingPaymentInfo_t *tpi = NULL;
|
||||
asn_dec_rval_t dec = uper_decode_complete(
|
||||
NULL,
|
||||
&asn_DEF_TollingPaymentInfo,
|
||||
(void **)&tpi,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size);
|
||||
if (!dec.code)
|
||||
{
|
||||
|
||||
bool found = false;
|
||||
for (int t = 0; t < bulletin->to_consume_len; ++t) {
|
||||
if (((tolling_info_t*)bulletin->to_consume[t]->info.internal_p)->asn->id == tpi->id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
facilities.tolling.infos.z[facilities.tolling.infos.length] = tolling_info_new(tpi);
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.internal_p = facilities.tolling.infos.z[facilities.tolling.infos.length];
|
||||
++facilities.tolling.infos.length;
|
||||
new_announcement = true;
|
||||
}
|
||||
} else {
|
||||
ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi);
|
||||
bool found = false;
|
||||
for (int t = 0; t < bulletin->to_consume_len; ++t)
|
||||
{
|
||||
if (((tolling_info_t *)bulletin->to_consume[t]->info.internal_p)->asn->id == tpi->id)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SAID_EVCSN:
|
||||
// TODO
|
||||
break;
|
||||
if (!found)
|
||||
{
|
||||
facilities.tolling.infos.z[facilities.tolling.infos.length] = tolling_info_new(tpi);
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.internal_p = facilities.tolling.infos.z[facilities.tolling.infos.length];
|
||||
++facilities.tolling.infos.length;
|
||||
new_announcement = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ServiceInfoExt_PR_addressIPv6:
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->endpoint.ipv6_addr, si->chOptions.extensions->list.array[e]->choice.addressIPv6.buf, 16);
|
||||
break;
|
||||
case SAID_EVCSN:
|
||||
if (facilities.station_type != 15 && facilities.evcsnm_args.infos.length < EVCSNM_INFOS_MAX_LENGTH)
|
||||
{
|
||||
EVCSInfo_t *evcsi = NULL;
|
||||
asn_dec_rval_t dec = uper_decode_complete(
|
||||
NULL,
|
||||
&asn_DEF_EVCSInfo,
|
||||
(void **)&evcsi,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf,
|
||||
si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size);
|
||||
if (!dec.code)
|
||||
{
|
||||
|
||||
case ServiceInfoExt_PR_servicePort:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->endpoint.port = si->chOptions.extensions->list.array[e]->choice.servicePort;
|
||||
break;
|
||||
bool found = false;
|
||||
for (int t = 0; t < bulletin->to_consume_len; ++t)
|
||||
{
|
||||
if (((evcs_info_t *)bulletin->to_consume[t]->info.internal_p)->asn->id == evcsi->id)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if (!found)
|
||||
{
|
||||
facilities.evcsnm_args.infos.z[facilities.evcsnm_args.infos.length] = evcs_info_new(evcsi);
|
||||
bulletin->to_consume[bulletin->to_consume_len]->info.internal_p = facilities.evcsnm_args.infos.z[facilities.evcsnm_args.infos.length];
|
||||
++facilities.evcsnm_args.infos.length;
|
||||
new_announcement = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_EVCSInfo, evcsi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServiceInfoExt_PR_addressIPv6:
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->endpoint.ipv6_addr, si->chOptions.extensions->list.array[e]->choice.addressIPv6.buf, 16);
|
||||
break;
|
||||
|
||||
case ServiceInfoExt_PR_servicePort:
|
||||
bulletin->to_consume[bulletin->to_consume_len]->endpoint.port = si->chOptions.extensions->list.array[e]->choice.servicePort;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -121,23 +169,26 @@ SAEM_CODE_R saem_check(SAEM_t* saem, uint8_t* neighbour) {
|
|||
uint16_t ci_index = si->channelIndex;
|
||||
|
||||
// TODO channelInfos
|
||||
if (saem->sam.body.channelInfos) {
|
||||
if (saem->sam.body.channelInfos->list.count >= ci_index + 1) {
|
||||
if (saem->sam.body.channelInfos)
|
||||
{
|
||||
if (saem->sam.body.channelInfos->list.count >= ci_index + 1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (new_announcement && bulletin->to_consume_len < MAX_ANNOUNCEMENTS_LEN - 1) {
|
||||
if (new_announcement && bulletin->to_consume_len < MAX_ANNOUNCEMENTS_LEN - 1)
|
||||
{
|
||||
bulletin->to_consume[bulletin->to_consume_len]->its_aid = its_aid;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->station_id = saem->header.stationID;
|
||||
bulletin->to_consume[bulletin->to_consume_len]->timestamp = itss_time_get();
|
||||
if (neighbour) {
|
||||
if (neighbour)
|
||||
{
|
||||
bulletin->to_consume[bulletin->to_consume_len]->certificate_id = malloc(8);
|
||||
memcpy(bulletin->to_consume[bulletin->to_consume_len]->certificate_id, neighbour, 8);
|
||||
}
|
||||
++bulletin->to_consume_len;
|
||||
rv = SAEM_NEW;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,17 +197,18 @@ SAEM_CODE_R saem_check(SAEM_t* saem, uint8_t* neighbour) {
|
|||
return rv == SAEM_NEW ? SAEM_NEW : SAEM_OK;
|
||||
}
|
||||
|
||||
void bulletin_init() {
|
||||
void bulletin_init()
|
||||
{
|
||||
|
||||
bulletin_t* bulletin = &facilities.bulletin;
|
||||
bulletin_t *bulletin = &facilities.bulletin;
|
||||
|
||||
pthread_mutex_init(&bulletin->lock, NULL);
|
||||
|
||||
bulletin->to_consume_len = 0;
|
||||
for (int i = 0; i < MAX_ANNOUNCEMENTS_LEN; ++i) {
|
||||
for (int i = 0; i < MAX_ANNOUNCEMENTS_LEN; ++i)
|
||||
{
|
||||
bulletin->to_consume[i] = calloc(1, sizeof(announcement_t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -165,17 +217,18 @@ void bulletin_init() {
|
|||
* @param b_saem_len The encoded SAEM length.
|
||||
* @return 0 on success, 1 otherwise.
|
||||
*/
|
||||
static int mk_saem(uint8_t* b_saem, uint32_t* b_saem_len) {
|
||||
static int mk_saem(uint8_t *b_saem, uint32_t *b_saem_len)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
// Check tolling advertisements
|
||||
if (!facilities.tolling.infos.length /* || facilites.evcsn.infos.length */) {
|
||||
if (!facilities.tolling.infos.length && !facilities.evcsnm_args.infos.length)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
asn_enc_rval_t enc;
|
||||
|
||||
SAEM_t* saem = calloc(1, sizeof(SAEM_t));
|
||||
SAEM_t *saem = calloc(1, sizeof(SAEM_t));
|
||||
|
||||
/* header */
|
||||
saem->header.protocolVersion = 1;
|
||||
|
|
@ -188,102 +241,138 @@ static int mk_saem(uint8_t* b_saem, uint32_t* b_saem_len) {
|
|||
saem->sam.version = 0;
|
||||
|
||||
saem->sam.body.serviceInfos = calloc(1, sizeof(ServiceInfos_t));
|
||||
saem->sam.body.serviceInfos->list.count = facilities.tolling.infos.length; // + facilities.evcsn.infos.length;
|
||||
saem->sam.body.serviceInfos->list.size = facilities.tolling.infos.length * sizeof(void*); // + facilities.evcsn.infos.length * sizeof(void*);
|
||||
saem->sam.body.serviceInfos->list.array = malloc(facilities.tolling.infos.length * sizeof(void*)); // + facilities.evcsn.infos.length * sizeof(void*);
|
||||
saem->sam.body.serviceInfos->list.count = facilities.tolling.infos.length + facilities.evcsnm_args.infos.length;
|
||||
saem->sam.body.serviceInfos->list.size = (facilities.tolling.infos.length + facilities.evcsnm_args.infos.length) * sizeof(void *);
|
||||
saem->sam.body.serviceInfos->list.array = malloc((facilities.tolling.infos.length + facilities.evcsnm_args.infos.length) * sizeof(void *));
|
||||
|
||||
uint8_t buf[1024];
|
||||
int i;
|
||||
for (i = 0; i < facilities.tolling.infos.length; ++i) {
|
||||
for (i = 0; i < facilities.tolling.infos.length; ++i)
|
||||
{
|
||||
saem->sam.body.serviceInfos->list.array[i] = calloc(1, sizeof(ServiceInfo_t));
|
||||
saem->sam.body.serviceInfos->list.array[i]->serviceID = SAID_ETC;
|
||||
|
||||
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions = calloc(1, sizeof(ServiceInfoExts_t));
|
||||
|
||||
ServiceInfoExts_t* exts = saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions;
|
||||
ServiceInfoExts_t *exts = saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions;
|
||||
|
||||
switch (facilities.tolling.protocol.p) {
|
||||
case TOLLING_PROTOCOL_SIMPLE:
|
||||
exts->list.count = 3;
|
||||
exts->list.size = 3 * sizeof(void*);
|
||||
exts->list.array = malloc(3 * sizeof(void*));
|
||||
switch (facilities.tolling.protocol.p)
|
||||
{
|
||||
case TOLLING_PROTOCOL_SIMPLE:
|
||||
exts->list.count = 3;
|
||||
exts->list.size = 3 * sizeof(void *);
|
||||
exts->list.array = malloc(3 * sizeof(void *));
|
||||
|
||||
exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
|
||||
|
||||
char ctx_s[] = "tolling:simple";
|
||||
exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_s);
|
||||
exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_s));
|
||||
memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_s, strlen(ctx_s));
|
||||
exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
|
||||
|
||||
exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[1]->present = ServiceInfoExt_PR_servicePort;
|
||||
exts->list.array[1]->choice.servicePort = 7011;
|
||||
char ctx_s[] = "tolling:simple";
|
||||
exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_s);
|
||||
exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_s));
|
||||
memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_s, strlen(ctx_s));
|
||||
|
||||
exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[2]->present = ServiceInfoExt_PR_applicationDataSAM;
|
||||
exts->list.array[2]->choice.applicationDataSAM.buf = malloc(1024);
|
||||
exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[1]->present = ServiceInfoExt_PR_servicePort;
|
||||
exts->list.array[1]->choice.servicePort = 7011;
|
||||
|
||||
enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, facilities.tolling.infos.z[i]->asn, exts->list.array[2]->choice.applicationDataSAM.buf, 1024);
|
||||
if (enc.encoded == -1) {
|
||||
log_error("[sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[2]->present = ServiceInfoExt_PR_applicationDataSAM;
|
||||
exts->list.array[2]->choice.applicationDataSAM.buf = malloc(1024);
|
||||
|
||||
exts->list.array[2]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8;
|
||||
break;
|
||||
enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, facilities.tolling.infos.z[i]->asn, exts->list.array[2]->choice.applicationDataSAM.buf, 1024);
|
||||
if (enc.encoded == -1)
|
||||
{
|
||||
log_error("[sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
case TOLLING_PROTOCOL_TLS:
|
||||
case TOLLING_PROTOCOL_TLS_GN:
|
||||
case TOLLING_PROTOCOL_TLS_SHS:
|
||||
exts->list.count = 4;
|
||||
exts->list.size = 4 * sizeof(void*);
|
||||
exts->list.array = malloc(4 * sizeof(void*));
|
||||
exts->list.array[2]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8;
|
||||
break;
|
||||
|
||||
exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
|
||||
char ctx_t[] = "tolling:tls";
|
||||
exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_t);
|
||||
exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_t));
|
||||
memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_t, strlen(ctx_t));
|
||||
case TOLLING_PROTOCOL_TLS:
|
||||
case TOLLING_PROTOCOL_TLS_GN:
|
||||
case TOLLING_PROTOCOL_TLS_SHS:
|
||||
exts->list.count = 4;
|
||||
exts->list.size = 4 * sizeof(void *);
|
||||
exts->list.array = malloc(4 * sizeof(void *));
|
||||
|
||||
exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[1]->present = ServiceInfoExt_PR_addressIPv6;
|
||||
exts->list.array[1]->choice.addressIPv6.size = 16;
|
||||
exts->list.array[1]->choice.addressIPv6.buf = malloc(16);
|
||||
memcpy(exts->list.array[1]->choice.addressIPv6.buf, facilities.id.ipv6_addr, 16);
|
||||
exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
|
||||
char ctx_t[] = "tolling:tls";
|
||||
exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_t);
|
||||
exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_t));
|
||||
memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_t, strlen(ctx_t));
|
||||
|
||||
exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[2]->present = ServiceInfoExt_PR_servicePort;
|
||||
exts->list.array[2]->choice.servicePort = 7011;
|
||||
exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[1]->present = ServiceInfoExt_PR_addressIPv6;
|
||||
exts->list.array[1]->choice.addressIPv6.size = 16;
|
||||
exts->list.array[1]->choice.addressIPv6.buf = malloc(16);
|
||||
memcpy(exts->list.array[1]->choice.addressIPv6.buf, facilities.id.ipv6_addr, 16);
|
||||
|
||||
exts->list.array[3] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[3]->present = ServiceInfoExt_PR_applicationDataSAM;
|
||||
exts->list.array[3]->choice.applicationDataSAM.buf = malloc(1024);
|
||||
exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[2]->present = ServiceInfoExt_PR_servicePort;
|
||||
exts->list.array[2]->choice.servicePort = 7011;
|
||||
|
||||
enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, facilities.tolling.infos.z[i]->asn, exts->list.array[3]->choice.applicationDataSAM.buf, 1024);
|
||||
if (enc.encoded == -1) {
|
||||
log_error("[sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
exts->list.array[3] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[3]->present = ServiceInfoExt_PR_applicationDataSAM;
|
||||
exts->list.array[3]->choice.applicationDataSAM.buf = malloc(1024);
|
||||
|
||||
exts->list.array[3]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8;
|
||||
break;
|
||||
enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, facilities.tolling.infos.z[i]->asn, exts->list.array[3]->choice.applicationDataSAM.buf, 1024);
|
||||
if (enc.encoded == -1)
|
||||
{
|
||||
log_error("[sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
exts->list.array[3]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 0/* + facilities.evcsn.infos.length */; ++j) {
|
||||
saem->sam.body.serviceInfos->list.array[i+j] = calloc(1, sizeof(ServiceInfo_t));
|
||||
saem->sam.body.serviceInfos->list.array[i+j]->serviceID = SAID_EVCSN;
|
||||
// TODO
|
||||
for (int j = 0; j < facilities.evcsnm_args.infos.length; ++j)
|
||||
{
|
||||
saem->sam.body.serviceInfos->list.array[i + j] = calloc(1, sizeof(ServiceInfo_t));
|
||||
saem->sam.body.serviceInfos->list.array[i + j]->serviceID = SAID_EVCSN;
|
||||
saem->sam.body.serviceInfos->list.array[i + j]->chOptions.extensions = calloc(1, sizeof(ServiceInfoExts_t));
|
||||
|
||||
ServiceInfoExts_t *exts = saem->sam.body.serviceInfos->list.array[i + j]->chOptions.extensions;
|
||||
exts->list.count = 3;
|
||||
exts->list.size = 3 * sizeof(void *);
|
||||
exts->list.array = malloc(3 * sizeof(void *));
|
||||
|
||||
exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
|
||||
|
||||
char ctx_s[] = "evcsnm";
|
||||
exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_s);
|
||||
exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_s));
|
||||
memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_s, strlen(ctx_s));
|
||||
|
||||
exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[1]->present = ServiceInfoExt_PR_servicePort;
|
||||
exts->list.array[1]->choice.servicePort = Port_poi;
|
||||
|
||||
exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
|
||||
exts->list.array[2]->present = ServiceInfoExt_PR_applicationDataSAM;
|
||||
exts->list.array[2]->choice.applicationDataSAM.buf = malloc(1024);
|
||||
|
||||
enc = uper_encode_to_buffer(&asn_DEF_EVCSInfo, NULL, facilities.evcsnm_args.infos.z[i]->asn, exts->list.array[2]->choice.applicationDataSAM.buf, 1024);
|
||||
if (enc.encoded == -1)
|
||||
{
|
||||
log_error("[sa] failure to encode EVCSInfo (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
exts->list.array[2]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&facilities.id.lock);
|
||||
|
||||
enc = asn_encode_to_buffer(NULL, ATS_UNALIGNED_CANONICAL_PER, &asn_DEF_SAEM, saem, b_saem, *b_saem_len);
|
||||
if (enc.encoded == -1) {
|
||||
if (enc.encoded == -1)
|
||||
{
|
||||
log_error("[sa] failure to encode SAEM (%s)", enc.failed_type->name);
|
||||
rv = 1;
|
||||
goto cleanup;
|
||||
|
|
@ -292,27 +381,29 @@ static int mk_saem(uint8_t* b_saem, uint32_t* b_saem_len) {
|
|||
|
||||
cleanup:
|
||||
ASN_STRUCT_FREE(asn_DEF_SAEM, saem);
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void *sa_service() {
|
||||
void *sa_service()
|
||||
{
|
||||
|
||||
pthread_mutex_init(&facilities.bulletin.lock, NULL);
|
||||
|
||||
TransportRequest_t *tr = calloc(1, sizeof(TransportRequest_t));
|
||||
tr->present = TransportRequest_PR_packet;
|
||||
TransportPacketRequest_t* tpr = &tr->choice.packet;
|
||||
TransportPacketRequest_t *tpr = &tr->choice.packet;
|
||||
|
||||
tpr->present = TransportPacketRequest_PR_btp;
|
||||
BTPPacketRequest_t *bpr = &tpr->choice.btp;
|
||||
|
||||
bulletin_t* bulletin = &facilities.bulletin;
|
||||
bulletin_t *bulletin = &facilities.bulletin;
|
||||
|
||||
bpr->btpType = BTPType_btpB;
|
||||
|
||||
bpr->gn.destinationAddress.buf = malloc(6);
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
bpr->gn.destinationAddress.buf[i] = 0xff;
|
||||
}
|
||||
bpr->gn.destinationAddress.size = 6;
|
||||
|
|
@ -329,7 +420,7 @@ void *sa_service() {
|
|||
bpr->gn.securityProfile.sign = true;
|
||||
|
||||
int linger_ms = 0;
|
||||
void* security_socket = itss_0connect(facilities.zmq.security_address, ZMQ_REQ);
|
||||
void *security_socket = itss_0connect(facilities.zmq.security_address, ZMQ_REQ);
|
||||
|
||||
uint8_t tr_oer[1024];
|
||||
tr_oer[0] = 4; // Facilities
|
||||
|
|
@ -339,41 +430,50 @@ void *sa_service() {
|
|||
int sleep_ms = 100;
|
||||
int mk_saem_n_sleep = 0;
|
||||
|
||||
while (!facilities.exit) {
|
||||
while (!facilities.exit)
|
||||
{
|
||||
|
||||
if (bulletin->to_provide_len && sleep_ms*mk_saem_n_sleep >= 1000) {
|
||||
rv = mk_saem(bpr->data.buf, (uint32_t *) &bpr->data.size);
|
||||
if (!rv) {
|
||||
if (bulletin->to_provide_len && sleep_ms * mk_saem_n_sleep >= 1000)
|
||||
{
|
||||
rv = mk_saem(bpr->data.buf, (uint32_t *)&bpr->data.size);
|
||||
if (!rv)
|
||||
{
|
||||
|
||||
bpr->id = itss_id(bpr->data.buf, bpr->data.size);
|
||||
|
||||
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, tr_oer+1, 1023);
|
||||
if (enc.encoded == -1) {
|
||||
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, tr_oer + 1, 1023);
|
||||
if (enc.encoded == -1)
|
||||
{
|
||||
log_error("encoding TR for SAEM failed");
|
||||
continue;
|
||||
} else {
|
||||
itss_queue_send(facilities.tx_queue, tr_oer, enc.encoded+1, ITSS_TRANSPORT, bpr->id, "TR.packet.btp");
|
||||
// Logging
|
||||
if (facilities.logging.dbms) {
|
||||
}
|
||||
else
|
||||
{
|
||||
itss_queue_send(facilities.tx_queue, tr_oer, enc.encoded + 1, ITSS_TRANSPORT, bpr->id, "TR.packet.btp");
|
||||
// Logging
|
||||
if (facilities.logging.dbms)
|
||||
{
|
||||
pthread_mutex_lock(&facilities.id.lock);
|
||||
uint32_t station_id = facilities.id.station_id;
|
||||
pthread_mutex_unlock(&facilities.id.lock);
|
||||
itss_db_add(facilities.logging.dbms, station_id, bpr->id, true, messageID_saem, NULL, bpr->data.buf, bpr->data.size);
|
||||
}
|
||||
if (facilities.logging.recorder) {
|
||||
if (facilities.logging.recorder)
|
||||
{
|
||||
uint16_t buffer_len = 2048;
|
||||
uint8_t buffer[buffer_len];
|
||||
int e = itss_management_record_packet_sdu(
|
||||
buffer,
|
||||
buffer_len,
|
||||
bpr->data.buf,
|
||||
bpr->data.size,
|
||||
bpr->id,
|
||||
itss_time_get(),
|
||||
ITSS_FACILITIES,
|
||||
true);
|
||||
if (e != -1) {
|
||||
itss_queue_send(facilities.tx_queue, buffer, e, ITSS_MANAGEMENT, bpr->id, "MReq.packet.set");
|
||||
buffer,
|
||||
buffer_len,
|
||||
bpr->data.buf,
|
||||
bpr->data.size,
|
||||
bpr->id,
|
||||
itss_time_get(),
|
||||
ITSS_FACILITIES,
|
||||
true);
|
||||
if (e != -1)
|
||||
{
|
||||
itss_queue_send(facilities.tx_queue, buffer, e, ITSS_MANAGEMENT, bpr->id, "MReq.packet.set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -392,40 +492,42 @@ void *sa_service() {
|
|||
uint64_t now = itss_time_get();
|
||||
|
||||
pthread_mutex_lock(&bulletin->lock);
|
||||
for (int a = 0; a < bulletin->to_consume_len; ++a) {
|
||||
for (int a = 0; a < bulletin->to_consume_len; ++a)
|
||||
{
|
||||
|
||||
// Tolling
|
||||
if (facilities.tolling.enabled &&
|
||||
bulletin->to_consume[a]->its_aid == 1 &&
|
||||
(
|
||||
now > bulletin->to_consume[a]->t_trigger + TOLLING_PAYMENT_MIN_PERIOD_MS ||
|
||||
(facilities.tolling.protocol.p == TOLLING_PROTOCOL_SIMPLE && tpm_should_retransmit())
|
||||
) &&
|
||||
facilities.station_type != 15) {
|
||||
if (facilities.tolling.enabled &&
|
||||
bulletin->to_consume[a]->its_aid == 1 &&
|
||||
(now > bulletin->to_consume[a]->t_trigger + TOLLING_PAYMENT_MIN_PERIOD_MS ||
|
||||
(facilities.tolling.protocol.p == TOLLING_PROTOCOL_SIMPLE && tpm_should_retransmit())) &&
|
||||
facilities.station_type != 15)
|
||||
{
|
||||
|
||||
tolling_info_t* info = (tolling_info_t*) bulletin->to_consume[a]->info.internal_p;
|
||||
tolling_info_t *info = (tolling_info_t *)bulletin->to_consume[a]->info.internal_p;
|
||||
|
||||
if (!tpm_is_inside_zone(info)) {
|
||||
if (!tpm_is_inside_zone(info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (facilities.tolling.protocol.p) {
|
||||
case TOLLING_PROTOCOL_SIMPLE:
|
||||
tpm_pay(info, &security_socket, bulletin->to_consume[a]->certificate_id, NULL);
|
||||
++bulletin->to_consume[a]->n_trigger;
|
||||
bulletin->to_consume[a]->t_trigger = now;
|
||||
break;
|
||||
switch (facilities.tolling.protocol.p)
|
||||
{
|
||||
case TOLLING_PROTOCOL_SIMPLE:
|
||||
tpm_pay(info, &security_socket, bulletin->to_consume[a]->certificate_id, NULL);
|
||||
++bulletin->to_consume[a]->n_trigger;
|
||||
bulletin->to_consume[a]->t_trigger = now;
|
||||
break;
|
||||
|
||||
case TOLLING_PROTOCOL_TLS:
|
||||
case TOLLING_PROTOCOL_TLS_GN:
|
||||
case TOLLING_PROTOCOL_TLS_SHS:
|
||||
tpm_pay(info, &security_socket, NULL, bulletin->to_consume[a]->endpoint.ipv6_addr);
|
||||
++bulletin->to_consume[a]->n_trigger;
|
||||
bulletin->to_consume[a]->t_trigger = now;
|
||||
break;
|
||||
case TOLLING_PROTOCOL_TLS:
|
||||
case TOLLING_PROTOCOL_TLS_GN:
|
||||
case TOLLING_PROTOCOL_TLS_SHS:
|
||||
tpm_pay(info, &security_socket, NULL, bulletin->to_consume[a]->endpoint.ipv6_addr);
|
||||
++bulletin->to_consume[a]->n_trigger;
|
||||
bulletin->to_consume[a]->t_trigger = now;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -434,17 +536,17 @@ void *sa_service() {
|
|||
// Tolling management
|
||||
if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS ||
|
||||
facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_GN ||
|
||||
facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS) {
|
||||
facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS)
|
||||
{
|
||||
tolling_tlsc_mgmt(facilities.tx_queue, &security_socket);
|
||||
}
|
||||
|
||||
usleep(sleep_ms*1000);
|
||||
usleep(sleep_ms * 1000);
|
||||
}
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_TransportRequest, tr);
|
||||
|
||||
itss_0close(security_socket);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue