Applications DENM support

This commit is contained in:
emanuel 2020-10-20 20:12:28 +01:00
parent 96605b5c3a
commit 7136fe195c
4 changed files with 81 additions and 16 deletions

View File

@ -202,7 +202,7 @@ void *ca_service(void *fc) {
continue; continue;
} }
syslog_debug("[facilities] -> [transport] BDR (%ldB)", enc.encoded); syslog_debug("[facilities] -> [transport] BDR (%ldB)", enc.encoded);
zmq_send(facilities->transport_socket, bdr_oer, enc.encoded, 0); zmq_send(facilities->transport_socket, bdr_oer, enc.encoded+1, 0);
zmq_recv(facilities->transport_socket, &code, 1, 0); zmq_recv(facilities->transport_socket, &code, 1, 0);
sleep(1); sleep(1);
} }

View File

@ -256,8 +256,8 @@ static int event_update(den_t *den, DENM_t *denm) {
else return 0; // Event updated else return 0; // Event updated
} }
void event_manage(den_t *den, DENM_t *denm) { int event_manage(den_t *den, DENM_t *denm) {
int rv; int rv = 0;
switch (event_check(den, denm)) { switch (event_check(den, denm)) {
case EVENT_NEW: case EVENT_NEW:
rv = event_add(den, denm); rv = event_add(den, denm);
@ -311,6 +311,7 @@ void event_manage(den_t *den, DENM_t *denm) {
ASN_STRUCT_FREE(asn_DEF_DENM, denm); ASN_STRUCT_FREE(asn_DEF_DENM, denm);
break; break;
} }
return rv;
} }
void* den_service(void *fc) { void* den_service(void *fc) {
@ -363,7 +364,6 @@ void* den_service(void *fc) {
} }
} }
} }
} }
syslog_debug("[facilities] [den] events :: [ %d active | %d cancelled | %d negated ]", den->no_active_events, den->no_cancelled_events, den->no_negated_events); syslog_debug("[facilities] [den] events :: [ %d active | %d cancelled | %d negated ]", den->no_active_events, den->no_cancelled_events, den->no_negated_events);

View File

@ -54,9 +54,9 @@ enum EVENT_CHECK_RESULT {
* Does all the checks to a DENM and adds it to the database. *Don't* free the DENM struct after calling this function * Does all the checks to a DENM and adds it to the database. *Don't* free the DENM struct after calling this function
* @param den the DEN service struct * @param den the DEN service struct
* @param denm the DENM to evaluate * @param denm the DENM to evaluate
* @return none * @return 0 if event OK, 1 if event NOK
*/ */
void event_manage(den_t *den, DENM_t *denm); int event_manage(den_t *den, DENM_t *denm);
void* den_service(void *fc); void* den_service(void *fc);

View File

@ -17,6 +17,7 @@
#include <zmq.h> #include <zmq.h>
#include <unistd.h> #include <unistd.h>
#include <syslog.h> #include <syslog.h>
#include <stdbool.h>
#define syslog_info(msg, ...) syslog(LOG_INFO, msg, ##__VA_ARGS__) #define syslog_info(msg, ...) syslog(LOG_INFO, msg, ##__VA_ARGS__)
#define syslog_emerg(msg, ...) syslog(LOG_EMERG, "%s:%d [" msg "]", __func__, __LINE__, ##__VA_ARGS__) #define syslog_emerg(msg, ...) syslog(LOG_EMERG, "%s:%d [" msg "]", __func__, __LINE__, ##__VA_ARGS__)
@ -99,7 +100,7 @@ static int transport_indication(facilities_t *facilities, uint8_t *msg, uint32_t
buffer[0] = 4; // Facilities buffer[0] = 4; // Facilities
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesDataIndication, NULL, fdi, buffer+1, 511); asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesDataIndication, NULL, fdi, buffer+1, 511);
syslog_debug("[facilities] -> [app] FDI (%ldB)", enc.encoded); syslog_debug("[facilities] -> [app] FDI (%ldB)", enc.encoded);
zmq_send(facilities->app_socket, buffer, enc.encoded, 0); zmq_send(facilities->app_socket, buffer, enc.encoded+1, 0);
zmq_recv(facilities->app_socket, &code, 1, 0); zmq_recv(facilities->app_socket, &code, 1, 0);
cleanup: cleanup:
@ -118,6 +119,7 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
FacilitiesDataRequest_t *fdreq = calloc(1, sizeof(FacilitiesDataRequest_t)); FacilitiesDataRequest_t *fdreq = calloc(1, sizeof(FacilitiesDataRequest_t));
FacilitiesDataResult_t *fdres = calloc(1, sizeof(FacilitiesDataResult_t)); FacilitiesDataResult_t *fdres = calloc(1, sizeof(FacilitiesDataResult_t));
BTPDataRequest_t *bdr = calloc(1, sizeof(BTPDataRequest_t));
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_FacilitiesDataRequest, (void**) &fdreq, msg, msg_len); asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_FacilitiesDataRequest, (void**) &fdreq, msg, msg_len);
if (dec.code) { if (dec.code) {
@ -129,6 +131,58 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
switch (fdreq->present) { switch (fdreq->present) {
case FacilitiesDataRequest_PR_singleMessage: case FacilitiesDataRequest_PR_singleMessage:
;
bool fwd = true;
switch (fdreq->choice.singleMessage.itssMessageType) {
case ItssMessageType_denm:
;
DENM_t *denm = calloc(1, sizeof(DENM_t));
dec = uper_decode_complete(NULL, &asn_DEF_DENM, (void**) &denm, fdreq->choice.singleMessage.data.buf, fdreq->choice.singleMessage.data.size);
if (dec.code) {
syslog_debug("[facilities] invalid FDRequest DENM received");
rv = 1;
ASN_STRUCT_FREE(asn_DEF_DENM, denm);
goto cleanup;
}
bdr->destinationPort = Port_denm;
if (event_manage(facilities->den, denm)) {
fwd = false;
}
break;
default:
syslog_err("[facilities] unrecognized FDRequest message type (%ld)", fdreq->choice.singleMessage.itssMessageType);
rv = 1;
goto cleanup;
}
// Forward message to [transport]
if (fwd) {
bdr->btpType = BTPType_btpB;
bdr->data.buf = malloc(fdreq->choice.singleMessage.data.size);
memcpy(bdr->data.buf, fdreq->choice.singleMessage.data.buf, fdreq->choice.singleMessage.data.size);
bdr->data.size = fdreq->choice.singleMessage.data.size;
bdr->destinationAddress.buf = malloc(6);
for (int i = 0; i < 6; ++i) bdr->destinationAddress.buf[i] = 0xff;
bdr->destinationAddress.size = 6;
bdr->packetTransportType = PacketTransportType_gbc;
bdr->trafficClass = 1;
// Encode ITS message into OER
uint8_t bdr_oer[384];
bdr_oer[0] = 4; // [facilities] service id
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_BTPDataRequest, NULL, bdr, bdr_oer + 1, 383);
if (enc.encoded == -1) {
syslog_err("[facilities] failed encoding BDR (%s)", enc.failed_type->name);
rv = 1;
goto cleanup;
}
zmq_send(facilities->transport_socket, bdr_oer, enc.encoded+1, 0);
zmq_recv(facilities->transport_socket, &code, 1, 0);
}
break; break;
case FacilitiesDataRequest_PR_activeEvents: case FacilitiesDataRequest_PR_activeEvents:
pthread_mutex_lock(&facilities->den->lock); pthread_mutex_lock(&facilities->den->lock);
@ -136,18 +190,22 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
fdres->code = ResultCode_accepted; fdres->code = ResultCode_accepted;
fdres->events = calloc(1, sizeof(Events_t)); fdres->events = calloc(1, sizeof(Events_t));
uint16_t nae = facilities->den->no_active_events;
switch (fdreq->choice.activeEvents) { switch (fdreq->choice.activeEvents) {
case EventType_active: case EventType_active:
fdres->events->list.count = facilities->den->no_active_events; fdres->events = calloc(1, sizeof(Events_t));
fdres->events->list.size = facilities->den->no_active_events * sizeof(DENM_t *); fdres->events->list.count = nae;
fdres->events->list.array = malloc(facilities->den->no_active_events * sizeof(DENM_t *)); fdres->events->list.size = nae * sizeof(DENM_t *);
for (int i = 0, j = 0; i < facilities->den->no_active_events; ++i) { fdres->events->list.array = malloc(nae * sizeof(DENM_t *));
for (int i = 0, j = 0; j < nae; ++i) {
if (facilities->den->events[i]->state == EVENT_ACTIVE) { if (facilities->den->events[i]->state == EVENT_ACTIVE) {
fdres->events->list.array[j] = calloc(1, sizeof(ItssMessage_t));
fdres->events->list.array[j]->itssMessageType = ItssMessageType_denm; fdres->events->list.array[j]->itssMessageType = ItssMessageType_denm;
fdres->events->list.array[j]->data.buf = malloc(512); fdres->events->list.array[j]->data.buf = malloc(512);
asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_DENM, NULL, facilities->den->events[i]->denm, fdres->events->list.array[j]->data.buf, 512); asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_DENM, NULL, facilities->den->events[i]->denm, fdres->events->list.array[j]->data.buf, 512);
if (enc.encoded == -1) { if (enc.encoded == -1) {
syslog_err("[facilities] failed encoding DENM for FDResult"); syslog_err("[facilities] failed encoding DENM for FDResult (%s)", enc.failed_type->name);
continue; continue;
} }
fdres->events->list.array[j]->data.size = (enc.encoded + 7) / 8; fdres->events->list.array[j]->data.size = (enc.encoded + 7) / 8;
@ -156,15 +214,15 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
} }
break; break;
default: default:
syslog_err("[facilities] unrecognized FDR event type"); syslog_err("[facilities] unrecognized FDR event type (%ld)", fdreq->choice.activeEvents);
pthread_mutex_unlock(&facilities->den->lock); pthread_mutex_unlock(&facilities->den->lock);
rv = 1; rv = 1;
goto cleanup; goto cleanup;
} }
fdres_oer = malloc(4096); fdres_oer = malloc(4096);
asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_DENM, NULL, fdres, fdres_oer, 4096); asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesDataResult, NULL, fdres, fdres_oer, 4096);
if (enc.encoded == -1) { if (enc.encoded == -1) {
syslog_err("[facilities] failed encoding FDResult"); syslog_err("[facilities] failed encoding FDResult (%s)", enc.failed_type->name);
pthread_mutex_unlock(&facilities->den->lock); pthread_mutex_unlock(&facilities->den->lock);
rv = 1; rv = 1;
goto cleanup; goto cleanup;
@ -175,7 +233,7 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
pthread_mutex_unlock(&facilities->den->lock); pthread_mutex_unlock(&facilities->den->lock);
break; break;
default: default:
syslog_err("[facilities] unrecognized FDR type received"); syslog_err("[facilities] unrecognized FDR type received (%d)", fdreq->present);
rv = 1; rv = 1;
goto cleanup; goto cleanup;
} }
@ -190,6 +248,7 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m
free(fdres_oer); free(fdres_oer);
ASN_STRUCT_FREE(asn_DEF_FacilitiesDataResult, fdres); ASN_STRUCT_FREE(asn_DEF_FacilitiesDataResult, fdres);
ASN_STRUCT_FREE(asn_DEF_FacilitiesDataRequest, fdreq); ASN_STRUCT_FREE(asn_DEF_FacilitiesDataRequest, fdreq);
ASN_STRUCT_FREE(asn_DEF_BTPDataRequest, bdr);
return rv; return rv;
} }
@ -223,16 +282,22 @@ int main() {
syslog_info("[facilities] listening"); syslog_info("[facilities] listening");
while (!facilities.exit) { while (!facilities.exit) {
memset(buffer, 0x00, 512);
zmq_recv(facilities.responder, buffer, 512, 0); zmq_recv(facilities.responder, buffer, 512, 0);
printf("NEW MESSAGE buffer[0] %d \n", buffer[0]);
switch (buffer[0]) { switch (buffer[0]) {
case 3: case 3:
code = transport_indication(&facilities, buffer+1, 511); code = transport_indication(&facilities, buffer+1, 511);
break; break;
case 5: case 5:
code = facilities_request(&facilities, buffer+1, 511); code = facilities_request(&facilities, buffer+1, 511);
break;
default: default:
syslog_debug("[facilities] unrecognized service"); syslog_debug("[facilities] unrecognized service");
code = 1;
zmq_send(facilities.responder, &code, 1, 0);
continue; continue;
} }
} }