denm: Handle 2.1.1 messages
This commit is contained in:
parent
7a51c6a5b7
commit
117ed93e31
|
|
@ -36,6 +36,7 @@ TARGET_LINK_LIBRARIES(it2s-itss-facilities
|
|||
-lit2s-asn-etsi-its-v1-evrsrm
|
||||
-lit2s-asn-etsi-its-v2-cdd-2.2.1
|
||||
-lit2s-asn-etsi-its-v2-cam
|
||||
-lit2s-asn-etsi-its-v2-denm
|
||||
-lit2s-tender
|
||||
-lm
|
||||
-lrt
|
||||
|
|
|
|||
159
src/denm.c
159
src/denm.c
|
|
@ -6,6 +6,8 @@
|
|||
#include <it2s-tender/time.h>
|
||||
#include <it2s-tender/space.h>
|
||||
|
||||
#define DENM_VERSION(denm) (((EI1_ItsPduHeader_t*)(denm))->protocolVersion)
|
||||
|
||||
const cc_ssp_bm_t CC_SSP_BM_MAP[] = {
|
||||
{"trafficCondition", 1, 0x80000000},
|
||||
{"accident", 2, 0x40000000},
|
||||
|
|
@ -67,29 +69,56 @@ static int permissions_check(int cause_code, uint8_t* permissions, uint8_t permi
|
|||
|
||||
}
|
||||
|
||||
static enum EVENT_CHECK_R event_check(EI1_DENM_t *denm, uint8_t* ssp, uint32_t ssp_len) {
|
||||
static enum EVENT_CHECK_R event_check(void *denm, uint8_t* ssp, uint32_t ssp_len) {
|
||||
int rv = 0;
|
||||
|
||||
den_t* den = &facilities.den;
|
||||
|
||||
uint8_t cause_code;
|
||||
uint32_t action_id_origin_station;
|
||||
uint32_t action_id_seq_num;
|
||||
switch (DENM_VERSION(denm)) {
|
||||
case 1:
|
||||
;
|
||||
EI1_DENM_t* denm_v1 = (EI1_DENM_t*) denm;
|
||||
cause_code = denm_v1->denm.situation->eventType.causeCode;
|
||||
action_id_origin_station = denm_v1->denm.management.actionID.originatingStationID;
|
||||
action_id_seq_num = denm_v1->denm.management.actionID.sequenceNumber;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
;
|
||||
EI2_DENM_t* denm_v2 = (EI2_DENM_t*) denm;
|
||||
cause_code = denm_v2->denm.situation->eventType.ccAndScc.present - 1;
|
||||
action_id_origin_station = denm_v2->denm.management.actionId.originatingStationId;
|
||||
action_id_seq_num = denm_v2->denm.management.actionId.sequenceNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EVENT_INVALID;
|
||||
}
|
||||
|
||||
/* Common fields in version 1, 2 */
|
||||
EI2_DENM_t* denm_c = (EI2_DENM_t*) denm;
|
||||
uint64_t e_detection_time, e_reference_time;
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.referenceTime, &e_reference_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.referenceTime, &e_reference_time);
|
||||
|
||||
|
||||
if (e_detection_time > e_reference_time) {
|
||||
return EVENT_INVALID;
|
||||
}
|
||||
|
||||
// Check if event cause code type is permitted by the issuing ticket
|
||||
if (ssp && denm->denm.situation) {
|
||||
if (!permissions_check(denm->denm.situation->eventType.causeCode, ssp, ssp_len)) {
|
||||
if (ssp && denm_c->denm.situation) {
|
||||
if (!permissions_check(cause_code, ssp, ssp_len)) {
|
||||
return EVENT_BAD_PERMISSIONS;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t e_validity_duration;
|
||||
if (denm->denm.management.validityDuration != NULL) {
|
||||
e_validity_duration = *(uint32_t *) denm->denm.management.validityDuration * 1000; // validityDuration comes in seconds
|
||||
if (denm_c->denm.management.validityDuration != NULL) {
|
||||
e_validity_duration = *(uint32_t *) denm_c->denm.management.validityDuration * 1000; // validityDuration comes in seconds
|
||||
} else {
|
||||
e_validity_duration = 600 * 1000;
|
||||
}
|
||||
|
|
@ -108,8 +137,8 @@ static enum EVENT_CHECK_R event_check(EI1_DENM_t *denm, uint8_t* ssp, uint32_t s
|
|||
|
||||
for (int i = 0; i < den->n_max_events; ++i) {
|
||||
if (den->events[i]->enabled) {
|
||||
if (den->events[i]->station_id == denm->denm.management.actionID.originatingStationID &&
|
||||
den->events[i]->sn == denm->denm.management.actionID.sequenceNumber) {
|
||||
if (den->events[i]->station_id == action_id_origin_station &&
|
||||
den->events[i]->sn == action_id_seq_num) {
|
||||
|
||||
is_new = false;
|
||||
|
||||
|
|
@ -133,10 +162,10 @@ static enum EVENT_CHECK_R event_check(EI1_DENM_t *denm, uint8_t* ssp, uint32_t s
|
|||
|
||||
|
||||
if (is_update) {
|
||||
if (denm->denm.management.termination != NULL) {
|
||||
if (*denm->denm.management.termination == 0) {
|
||||
if (denm_c->denm.management.termination != NULL) {
|
||||
if (*denm_c->denm.management.termination == 0) {
|
||||
return EVENT_CANCELLATION;
|
||||
} else if (*denm->denm.management.termination == 1) {
|
||||
} else if (*denm_c->denm.management.termination == 1) {
|
||||
return EVENT_NEGATION;
|
||||
}
|
||||
}
|
||||
|
|
@ -155,18 +184,44 @@ static enum EVENT_CHECK_R event_check(EI1_DENM_t *denm, uint8_t* ssp, uint32_t s
|
|||
return EVENT_NEW;
|
||||
}
|
||||
|
||||
static int event_add(EI1_DENM_t *denm, uint64_t* id) {
|
||||
static int event_add(void *denm, uint64_t* id) {
|
||||
|
||||
den_t* den = &facilities.den;
|
||||
uint64_t now = itss_time_get();
|
||||
|
||||
uint8_t cause_code;
|
||||
uint32_t action_id_origin_station;
|
||||
uint32_t action_id_seq_num;
|
||||
switch (DENM_VERSION(denm)) {
|
||||
case 1:
|
||||
;
|
||||
EI1_DENM_t* denm_v1 = (EI1_DENM_t*) denm;
|
||||
cause_code = denm_v1->denm.situation->eventType.causeCode;
|
||||
action_id_origin_station = denm_v1->denm.management.actionID.originatingStationID;
|
||||
action_id_seq_num = denm_v1->denm.management.actionID.sequenceNumber;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
;
|
||||
EI2_DENM_t* denm_v2 = (EI2_DENM_t*) denm;
|
||||
cause_code = denm_v2->denm.situation->eventType.ccAndScc.present - 1;
|
||||
action_id_origin_station = denm_v2->denm.management.actionId.originatingStationId;
|
||||
action_id_seq_num = denm_v2->denm.management.actionId.sequenceNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EVENT_INVALID;
|
||||
}
|
||||
|
||||
/* Common fields in version 1, 2 */
|
||||
EI2_DENM_t* denm_c = (EI2_DENM_t*) denm;
|
||||
uint64_t e_detection_time, e_reference_time;
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.referenceTime, &e_reference_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.referenceTime, &e_reference_time);
|
||||
|
||||
uint32_t e_validity_duration;
|
||||
if (denm->denm.management.validityDuration != NULL) {
|
||||
e_validity_duration = *(uint32_t *) denm->denm.management.validityDuration * 1000; // validityDuration comes in seconds
|
||||
if (denm_c->denm.management.validityDuration != NULL) {
|
||||
e_validity_duration = *(uint32_t *) denm_c->denm.management.validityDuration * 1000; // validityDuration comes in seconds
|
||||
} else {
|
||||
e_validity_duration = 600 * 1000;
|
||||
}
|
||||
|
|
@ -182,10 +237,10 @@ static int event_add(EI1_DENM_t *denm, uint64_t* id) {
|
|||
}
|
||||
|
||||
uint8_t state = EVENT_ACTIVE;
|
||||
if (denm->denm.management.termination != NULL) {
|
||||
if (*(denm->denm.management.termination) == 0) {
|
||||
if (denm_c->denm.management.termination != NULL) {
|
||||
if (*(denm_c->denm.management.termination) == 0) {
|
||||
state = EVENT_CANCELLED;
|
||||
} else if (*(denm->denm.management.termination) == 1) {
|
||||
} else if (*(denm_c->denm.management.termination) == 1) {
|
||||
state = EVENT_NEGATED;
|
||||
}
|
||||
}
|
||||
|
|
@ -206,17 +261,17 @@ static int event_add(EI1_DENM_t *denm, uint64_t* id) {
|
|||
den->events[index]->id = *id;
|
||||
den->events[index]->enabled = true;
|
||||
den->events[index]->state = state;
|
||||
den->events[index]->station_id = denm->denm.management.actionID.originatingStationID;
|
||||
den->events[index]->sn = denm->denm.management.actionID.sequenceNumber;
|
||||
den->events[index]->station_id = action_id_origin_station;
|
||||
den->events[index]->sn = action_id_seq_num;
|
||||
den->events[index]->detection_time = e_detection_time;
|
||||
den->events[index]->reference_time = e_reference_time;
|
||||
den->events[index]->expiration_time = e_detection_time + e_validity_duration;
|
||||
den->events[index]->latitude = denm->denm.management.eventPosition.latitude;
|
||||
den->events[index]->longitude = denm->denm.management.eventPosition.longitude;
|
||||
den->events[index]->latitude = denm_c->denm.management.eventPosition.latitude;
|
||||
den->events[index]->longitude = denm_c->denm.management.eventPosition.longitude;
|
||||
den->events[index]->denm = denm;
|
||||
|
||||
if (denm->denm.management.actionID.sequenceNumber > den->sn) {
|
||||
den->sn = denm->denm.management.actionID.sequenceNumber;
|
||||
if (action_id_seq_num > den->sn) {
|
||||
den->sn = action_id_seq_num;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,20 +281,46 @@ static int event_add(EI1_DENM_t *denm, uint64_t* id) {
|
|||
else return 0; // Event added to db
|
||||
}
|
||||
|
||||
static int event_update(EI1_DENM_t *denm, uint64_t* id) {
|
||||
static int event_update(void *denm, uint64_t* id) {
|
||||
|
||||
den_t* den = &facilities.den;
|
||||
uint64_t now = itss_time_get();
|
||||
|
||||
uint8_t cause_code;
|
||||
uint32_t action_id_origin_station;
|
||||
uint32_t action_id_seq_num;
|
||||
switch (DENM_VERSION(denm)) {
|
||||
case 1:
|
||||
;
|
||||
EI1_DENM_t* denm_v1 = (EI1_DENM_t*) denm;
|
||||
cause_code = denm_v1->denm.situation->eventType.causeCode;
|
||||
action_id_origin_station = denm_v1->denm.management.actionID.originatingStationID;
|
||||
action_id_seq_num = denm_v1->denm.management.actionID.sequenceNumber;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
;
|
||||
EI2_DENM_t* denm_v2 = (EI2_DENM_t*) denm;
|
||||
cause_code = denm_v2->denm.situation->eventType.ccAndScc.present - 1;
|
||||
action_id_origin_station = denm_v2->denm.management.actionId.originatingStationId;
|
||||
action_id_seq_num = denm_v2->denm.management.actionId.sequenceNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EVENT_INVALID;
|
||||
}
|
||||
|
||||
/* Common fields in version 1, 2 */
|
||||
EI2_DENM_t* denm_c = (EI2_DENM_t*) denm;
|
||||
uint64_t e_detection_time, e_reference_time;
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm->denm.management.referenceTime, &e_reference_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.detectionTime, &e_detection_time);
|
||||
asn_INTEGER2ulong((INTEGER_t*) &denm_c->denm.management.referenceTime, &e_reference_time);
|
||||
|
||||
uint8_t state = EVENT_ACTIVE;
|
||||
if (denm->denm.management.termination != NULL) {
|
||||
if (*(denm->denm.management.termination) == 0) {
|
||||
if (denm_c->denm.management.termination != NULL) {
|
||||
if (*(denm_c->denm.management.termination) == 0) {
|
||||
state = EVENT_CANCELLED;
|
||||
} else if (*(denm->denm.management.termination) == 1) {
|
||||
} else if (*(denm_c->denm.management.termination) == 1) {
|
||||
state = EVENT_NEGATED;
|
||||
}
|
||||
}
|
||||
|
|
@ -249,8 +330,8 @@ static int event_update(EI1_DENM_t *denm, uint64_t* id) {
|
|||
|
||||
for (int i = 0; i < den->n_max_events; ++i) {
|
||||
if (den->events[i]->enabled) {
|
||||
if (den->events[i]->station_id == denm->denm.management.actionID.originatingStationID &&
|
||||
den->events[i]->sn == denm->denm.management.actionID.sequenceNumber) {
|
||||
if (den->events[i]->station_id == action_id_origin_station &&
|
||||
den->events[i]->sn == action_id_seq_num) {
|
||||
|
||||
index = i;
|
||||
break;
|
||||
|
|
@ -289,16 +370,16 @@ static int event_update(EI1_DENM_t *denm, uint64_t* id) {
|
|||
den->events[index]->detection_time = e_detection_time;
|
||||
den->events[index]->reference_time = e_reference_time;
|
||||
|
||||
if (denm->denm.management.validityDuration != NULL) {
|
||||
den->events[index]->expiration_time = e_detection_time + *(uint32_t *) denm->denm.management.validityDuration * 1000;
|
||||
if (denm_c->denm.management.validityDuration != NULL) {
|
||||
den->events[index]->expiration_time = e_detection_time + *(uint32_t *) denm_c->denm.management.validityDuration * 1000;
|
||||
}
|
||||
|
||||
if (state == EVENT_CANCELLED || state == EVENT_NEGATED) { // Keep terminated events for 10 mins
|
||||
den->events[index]->expiration_time = now + 600 * 1000;
|
||||
}
|
||||
|
||||
den->events[index]->latitude = denm->denm.management.eventPosition.latitude;
|
||||
den->events[index]->longitude = denm->denm.management.eventPosition.longitude;
|
||||
den->events[index]->latitude = denm_c->denm.management.eventPosition.latitude;
|
||||
den->events[index]->longitude = denm_c->denm.management.eventPosition.longitude;
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_EI1_DENM, den->events[index]->denm);
|
||||
den->events[index]->denm = denm;
|
||||
|
|
@ -310,7 +391,7 @@ static int event_update(EI1_DENM_t *denm, uint64_t* id) {
|
|||
else return 0; // Event updated
|
||||
}
|
||||
|
||||
enum EVENT_CHECK_R event_manage(EI1_DENM_t *denm, uint64_t* id, uint8_t* ssp, uint32_t ssp_len) {
|
||||
enum EVENT_CHECK_R event_manage(void *denm, uint64_t* id, uint8_t* ssp, uint32_t ssp_len) {
|
||||
int rv = 0;
|
||||
switch (rv = event_check(denm, ssp, ssp_len)) {
|
||||
case EVENT_NEW:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <it2s-asn/etsi-its-v1/denm/EI1_DENM.h>
|
||||
#include <it2s-asn/etsi-its-v2/denm/EI2_DENM.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ enum EVENT_STATE {
|
|||
|
||||
typedef struct event {
|
||||
uint64_t id;
|
||||
EI1_DENM_t *denm;
|
||||
void *denm;
|
||||
uint32_t station_id;
|
||||
uint32_t sn;
|
||||
uint64_t detection_time;
|
||||
|
|
@ -67,7 +68,7 @@ typedef struct cc_ssp_bm {
|
|||
* @param ssp permissions
|
||||
* @return 0 if event OK, 1 if event NOK
|
||||
*/
|
||||
enum EVENT_CHECK_R event_manage(EI1_DENM_t* denm, uint64_t* id, uint8_t* ssp, uint32_t ssp_len);
|
||||
enum EVENT_CHECK_R event_manage(void* denm, uint64_t* id, uint8_t* ssp, uint32_t ssp_len);
|
||||
|
||||
int den_init();
|
||||
void* den_service();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,14 @@ static int pver2mver(uint8_t pver) {
|
|||
}
|
||||
}
|
||||
|
||||
static int handled_mver(uint8_t* msg_data) {
|
||||
if (!facilities.mver.handle_all &&
|
||||
facilities.mver.defaultv != msg_data[0]) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int facilities_request_result_accepted(void *responder) {
|
||||
int rv = 0;
|
||||
|
||||
|
|
@ -685,6 +693,16 @@ static int networking_packet_indication_btp(EIS_NetworkingPacketIndication_t* np
|
|||
uint64_t id = 0;
|
||||
uint8_t pver = npi->data.buf[0];
|
||||
|
||||
// No message
|
||||
if (npi->data.size == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Is message version handled
|
||||
if (!handled_mver(npi->data.buf)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parse message
|
||||
switch (bpi->destinationPort) {
|
||||
case EIS_Port_cam:
|
||||
|
|
@ -700,9 +718,15 @@ static int networking_packet_indication_btp(EIS_NetworkingPacketIndication_t* np
|
|||
break;
|
||||
|
||||
case EIS_Port_denm:
|
||||
its_msg_descriptor = &asn_DEF_EI1_DENM;
|
||||
its_msg = calloc(1, sizeof(EI1_DENM_t));
|
||||
its_msg_type = EI1_messageID_denm;
|
||||
switch (pver) {
|
||||
/* Only DENMv2 is supported (as in 1.3.1 - 2.1.1) */
|
||||
/* Use by default CDDv2 */
|
||||
case 2:
|
||||
its_msg_descriptor = &asn_DEF_EI2_DENM;
|
||||
its_msg = calloc(1, sizeof(EI2_DENM_t));
|
||||
its_msg_type = EI2_MessageId_denm;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EIS_Port_ivim:
|
||||
|
|
|
|||
Loading…
Reference in New Issue