diff --git a/src/cam.c b/src/cam.c index 5371bc3..89fc8a7 100644 --- a/src/cam.c +++ b/src/cam.c @@ -202,7 +202,7 @@ void *ca_service(void *fc) { continue; } 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); sleep(1); } diff --git a/src/denm.c b/src/denm.c index 6dee2e6..23c76a3 100644 --- a/src/denm.c +++ b/src/denm.c @@ -256,8 +256,8 @@ static int event_update(den_t *den, DENM_t *denm) { else return 0; // Event updated } -void event_manage(den_t *den, DENM_t *denm) { - int rv; +int event_manage(den_t *den, DENM_t *denm) { + int rv = 0; switch (event_check(den, denm)) { case EVENT_NEW: 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); break; } + return rv; } 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); diff --git a/src/denm.h b/src/denm.h index 66b5c09..3397517 100644 --- a/src/denm.h +++ b/src/denm.h @@ -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 * @param den the DEN service struct * @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); diff --git a/src/facilities.c b/src/facilities.c index 03bf1a6..d51d16f 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -17,6 +17,7 @@ #include #include #include +#include #define syslog_info(msg, ...) syslog(LOG_INFO, msg, ##__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 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); - 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); 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)); 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); if (dec.code) { @@ -129,6 +131,58 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m switch (fdreq->present) { 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; case FacilitiesDataRequest_PR_activeEvents: 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->events = calloc(1, sizeof(Events_t)); + uint16_t nae = facilities->den->no_active_events; + switch (fdreq->choice.activeEvents) { case EventType_active: - fdres->events->list.count = facilities->den->no_active_events; - fdres->events->list.size = facilities->den->no_active_events * sizeof(DENM_t *); - fdres->events->list.array = malloc(facilities->den->no_active_events * sizeof(DENM_t *)); - for (int i = 0, j = 0; i < facilities->den->no_active_events; ++i) { + fdres->events = calloc(1, sizeof(Events_t)); + fdres->events->list.count = nae; + fdres->events->list.size = nae * sizeof(DENM_t *); + 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) { + fdres->events->list.array[j] = calloc(1, sizeof(ItssMessage_t)); fdres->events->list.array[j]->itssMessageType = ItssMessageType_denm; 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); 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; } 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; 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); rv = 1; goto cleanup; } 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) { - syslog_err("[facilities] failed encoding FDResult"); + syslog_err("[facilities] failed encoding FDResult (%s)", enc.failed_type->name); pthread_mutex_unlock(&facilities->den->lock); rv = 1; 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); break; default: - syslog_err("[facilities] unrecognized FDR type received"); + syslog_err("[facilities] unrecognized FDR type received (%d)", fdreq->present); rv = 1; goto cleanup; } @@ -190,6 +248,7 @@ static int facilities_request(facilities_t *facilities, uint8_t *msg, uint32_t m free(fdres_oer); ASN_STRUCT_FREE(asn_DEF_FacilitiesDataResult, fdres); ASN_STRUCT_FREE(asn_DEF_FacilitiesDataRequest, fdreq); + ASN_STRUCT_FREE(asn_DEF_BTPDataRequest, bdr); return rv; } @@ -223,16 +282,22 @@ int main() { syslog_info("[facilities] listening"); while (!facilities.exit) { + memset(buffer, 0x00, 512); zmq_recv(facilities.responder, buffer, 512, 0); + printf("NEW MESSAGE buffer[0] %d \n", buffer[0]); + switch (buffer[0]) { case 3: code = transport_indication(&facilities, buffer+1, 511); break; case 5: code = facilities_request(&facilities, buffer+1, 511); + break; default: syslog_debug("[facilities] unrecognized service"); + code = 1; + zmq_send(facilities.responder, &code, 1, 0); continue; } }