diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ae11f6..52be034 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ ADD_EXECUTABLE(it2s-itss-facilities requests.c facilities.c cpm.c + sa.c ) TARGET_LINK_LIBRARIES(it2s-itss-facilities @@ -21,6 +22,7 @@ TARGET_LINK_LIBRARIES(it2s-itss-facilities -lit2s-asn-ivim -lit2s-asn-denmv2 -lit2s-asn-cpm + -lit2s-asn-saem -lit2s-tender -lm ) diff --git a/src/facilities.c b/src/facilities.c index d6b376b..e503981 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -5,6 +5,7 @@ #include "infrastructure.h" #include "requests.h" #include "cpm.h" +#include "sa.h" #include #include @@ -20,8 +21,7 @@ #include #include #include -#include -#include +#include #include #include @@ -71,22 +71,31 @@ static int transport_indication(facilities_t *facilities, void* responder, uint8 its_msg = calloc(1, sizeof(CAM_t)); handled_msg = true; break; + case Port_denm: its_msg_descriptor = &asn_DEF_DENM; its_msg = calloc(1, sizeof(DENM_t)); handled_msg = true; break; + case Port_ivim: its_msg_descriptor = &asn_DEF_IVIM; its_msg = calloc(1, sizeof(IVIM_t)); handled_msg = true; break; + case Port_cpm: its_msg_descriptor = &asn_DEF_CPM; its_msg = calloc(1, sizeof(CPM_t)); handled_msg = true; break; + case Port_saem: + its_msg_descriptor = &asn_DEF_SAEM; + its_msg = calloc(1, sizeof(SAEM_t)); + handled_msg = true; + break; + default: syslog_debug("[facilities] messsage with unhandled BTP port received, ignoring"); goto cleanup; @@ -165,6 +174,10 @@ static int transport_indication(facilities_t *facilities, void* responder, uint8 } break; + case Port_saem: + saem_check(facilities, facilities->press, its_msg); + break; + default: break; } diff --git a/src/facilities.h b/src/facilities.h index ec891a6..96a39b8 100644 --- a/src/facilities.h +++ b/src/facilities.h @@ -10,6 +10,7 @@ #include "infrastructure.h" #include "queue.h" #include "cpm.h" +#include "sa.h" #include @@ -53,6 +54,9 @@ typedef struct facilities { //CPM dissemination_t* dissemination; + // SA + press_t* press; + int station_type; bool use_security; bool replay; diff --git a/src/sa.c b/src/sa.c new file mode 100644 index 0000000..912cd2a --- /dev/null +++ b/src/sa.c @@ -0,0 +1,101 @@ +#include "sa.h" +#include "facilities.h" + +#include + +SAEM_CODE_R saem_check(void* fc, press_t* press, SAEM_t* saem) { + + facilities_t* facilities = (facilities_t*) fc; + + int rv = 0; + + if (saem->header.messageID != ItsPduHeader__messageID_saem) { + return SAEM_INVALID_HEADER_MESSAGE_ID; + } + + if (saem->header.protocolVersion != 1) { + return SAEM_INVALID_HEADER_VERSION; + } + + + 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 = 0; + switch (si->serviceID.present) { + case VarLengthNumber_PR_content: + its_aid = si->serviceID.choice.content; + break; + case VarLengthNumber_PR_extension: + // TODO + break; + default: + break; + } + + if (!its_aid) { + continue; + } + + int index = -1; + for (int a = 0; a < press->announcements_len; ++a) { + /* Check existence through stationID and itsAid */ + if (saem->header.stationID == press->announcements[a]->station_id && + its_aid == press->announcements[a]->its_aid) { + index = a; + break; + } + } + + if (index == -1) { + if (press->announcements_len + 1 < MAX_ANNOUNCEMENTS_LEN) { + press->announcements[press->announcements_len]->its_aid = its_aid; + press->announcements[press->announcements_len]->station_id = saem->header.stationID; + press->announcements[press->announcements_len]->timestamp = it2s_tender_get_clock(&facilities->epv); + index = press->announcements_len; + ++press->announcements_len; + } + } + + uint16_t ci_index = si->channelIndex; + + // TODO chOptions + for (int o = 0; o < si->chOptions.extensions->list.count; ++o) { + Extension_34P0_t* sie = (Extension_34P0_t*) si->chOptions.extensions->list.array[o]; + switch (sie->value.present) { + case Extension_34P0__value_PR_TwoDLocation: + press->announcements[index]->position.latitude = sie->value.choice.TwoDLocation.latitude; + break; + case Extension_34P0__value_PR_ThreeDLocation: + break; + case Extension_34P0__value_PR_RepeatRate: + break; + case Extension_34P0__value_PR_AdvertiserIdentifier: + break; + default: + break; + } + } + + // TODO channelInfos + if (saem->sam.body.channelInfos) { + if (saem->sam.body.channelInfos->list.count >= ci_index + 1) { + } + } + + + } + } + + return rv; +} + +void press_init(press_t* press) { + + press->announcements_len = 0; + for (int i = 0; i < MAX_ANNOUNCEMENTS_LEN; ++i) { + press->announcements[i] = calloc(1, sizeof(announcement_t)); + + } +} diff --git a/src/sa.h b/src/sa.h new file mode 100644 index 0000000..15eb919 --- /dev/null +++ b/src/sa.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#define MAX_ANNOUNCEMENTS_LEN 32 + +typedef struct announcement { + uint32_t its_aid; + uint8_t protocol_id; + uint8_t traffic_class; + + uint64_t station_id; + uint64_t timestamp; + + struct { + int32_t latitude; + int32_t longitude; + int16_t altitude; + } position; +} announcement_t; + +typedef struct press { + announcement_t* announcements[MAX_ANNOUNCEMENTS_LEN]; + uint16_t announcements_len; +} press_t; + +typedef enum SAEM_CODE { + SAEM_OK, + SAEM_INVALID_HEADER_MESSAGE_ID, + SAEM_INVALID_HEADER_VERSION +} SAEM_CODE_R; + +void press_init(press_t* press); + +SAEM_CODE_R saem_check(void* fc, press_t* press, SAEM_t* saem);