diff --git a/src/facilities.c b/src/facilities.c index eefb096..9a18dc7 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -228,14 +228,18 @@ static int facilities_request(facilities_t *facilities, void* responder, uint8_t rv = facilities_request_single_message(facilities, responder, fdreq); break; - case FacilitiesDataRequest_PR_activeEvents: - rv = facilities_request_active_events(facilities, responder, fdreq); + case FacilitiesDataRequest_PR_activeEpisodes: + rv = facilities_request_active_episodes(facilities, responder, fdreq); break; case FacilitiesDataRequest_PR_attributeTypes: rv = facilities_request_attribute_types(facilities, responder, fdreq); break; + case FacilitiesDataRequest_PR_loadedProtectionZones: + rv = facilities_request_loaded_protected_zones(facilities, responder, fdreq); + break; + default: syslog_err("[facilities] unrecognized FDR type received (%d)", fdreq->present); facilities_request_result_rejected(responder); diff --git a/src/infrastructure.c b/src/infrastructure.c index 55f078a..1ac9cce 100644 --- a/src/infrastructure.c +++ b/src/infrastructure.c @@ -529,7 +529,7 @@ void* infrastructure_service(void *fc) { infrastructure->services[i] = calloc(1, sizeof(service_t)); } - uint32_t sleep4us = 5e5; + uint32_t sleep4us = 1e6; uint32_t sleep_count = 0; while (!facilities->exit) { diff --git a/src/requests.c b/src/requests.c index e2401b3..40b695d 100644 --- a/src/requests.c +++ b/src/requests.c @@ -323,55 +323,95 @@ cleanup: return rv; } -int facilities_request_active_events(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq) { +int facilities_request_active_episodes(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq) { int rv = 0; FacilitiesDataResult_t* fdres = calloc(1, sizeof(FacilitiesDataResult_t)); uint8_t* fdres_oer = NULL; - pthread_mutex_lock(&facilities->den->lock); - fdres->code = FacilitiesResultCode_accepted; fdres->result = calloc(1, sizeof(FacilitiesResult_t)); - fdres->result->present = FacilitiesResult_PR_events; + fdres->result->present = FacilitiesResult_PR_episodes; + + pthread_mutex_lock(&facilities->den->lock); + pthread_mutex_lock(&facilities->infrastructure->lock); uint16_t nae = facilities->den->n_active_events; + uint16_t nas = facilities->infrastructure->n_active_services; - switch (fdreq->choice.activeEvents) { - case EventType_active: - fdres->result->choice.events.list.count = nae; - fdres->result->choice.events.list.size = nae * sizeof(DENM_t *); - fdres->result->choice.events.list.array = malloc(nae * sizeof(DENM_t *)); - for (int i = 0, j = 0; j < nae; ++i) { - if (facilities->den->events[i]->enabled && facilities->den->events[i]->state == EVENT_ACTIVE) { - fdres->result->choice.events.list.array[j] = calloc(1, sizeof(ItsMessage_t)); - fdres->result->choice.events.list.array[j]->itsMessageType = ItsMessageType_denm; - fdres->result->choice.events.list.array[j]->data.buf = malloc(2048); - asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_DENM, NULL, facilities->den->events[i]->denm, fdres->result->choice.events.list.array[j]->data.buf, 2048); - if (enc.encoded == -1) { /* encoding shouldn't fail as all saved DENMs are structurally valid */ - syslog_err("[facilities] failed encoding DENM for FDResult (%s)", enc.failed_type->name); - fdres->result->choice.events.list.array[j]->data.size = 0; - continue; - } - fdres->result->choice.events.list.array[j]->data.size = (enc.encoded + 7) / 8; - ++j; - } - } - break; - default: - syslog_err("[facilities] unrecognized FDR event type (%ld)", fdreq->choice.activeEvents); - pthread_mutex_unlock(&facilities->den->lock); + uint16_t na = 0; - facilities_request_result_rejected(responder); - rv = 1; - goto cleanup; + for (int e = 0; e < fdreq->choice.activeEpisodes.list.count; ++e) { + switch (*fdreq->choice.activeEpisodes.list.array[e]) { + case EpisodeType_denm: + na += nae; + break; + case EpisodeType_ivim: + na += nas; + break; + } } + fdres->result->choice.episodes.list.count = na; + fdres->result->choice.episodes.list.size = na * sizeof(void *); + fdres->result->choice.episodes.list.array = malloc(na * sizeof(void *)); + + for (int e = 0, j = 0; e < fdreq->choice.activeEpisodes.list.count; ++e) { + switch (*fdreq->choice.activeEpisodes.list.array[e]) { + case EpisodeType_denm: + for (int i = 0, n = 0; n < nae; ++i) { + if (facilities->den->events[i]->enabled && facilities->den->events[i]->state == EVENT_ACTIVE) { + fdres->result->choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); + fdres->result->choice.episodes.list.array[j]->itsMessageType = ItsMessageType_denm; + fdres->result->choice.episodes.list.array[j]->data.buf = malloc(2048); + asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_DENM, NULL, facilities->den->events[i]->denm, fdres->result->choice.episodes.list.array[j]->data.buf, 2048); + if (enc.encoded == -1) { /* encoding shouldn't fail as all saved DENMs are structurally valid */ + syslog_err("[facilities] failed encoding DENM for FDResult (%s)", enc.failed_type->name); + fdres->result->choice.episodes.list.array[j]->data.size = 0; + continue; + } + fdres->result->choice.episodes.list.array[j]->data.size = (enc.encoded + 7) / 8; + ++j; + ++n; + } + } + break; + case EpisodeType_ivim: + for (int i = 0, n = 0; n < nas; ++i) { + if (facilities->infrastructure->services[i]->enabled && facilities->infrastructure->services[i]->state == SERVICE_ACTIVE) { + fdres->result->choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); + fdres->result->choice.episodes.list.array[j]->itsMessageType = ItsMessageType_ivim; + fdres->result->choice.episodes.list.array[j]->data.buf = malloc(2048); + asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_IVIM, NULL, facilities->infrastructure->services[i]->ivim, fdres->result->choice.episodes.list.array[j]->data.buf, 2048); + if (enc.encoded == -1) { /* encoding shouldn't fail as all saved DENMs are structurally valid */ + syslog_err("[facilities] failed encoding IVIM for FDResult (%s)", enc.failed_type->name); + fdres->result->choice.episodes.list.array[j]->data.size = 0; + continue; + } + fdres->result->choice.episodes.list.array[j]->data.size = (enc.encoded + 7) / 8; + ++j; + ++n; + } + } + break; + default: + syslog_err("[facilities] unrecognized FDR event type (%ld)", *fdreq->choice.activeEpisodes.list.array[0]); + pthread_mutex_unlock(&facilities->den->lock); + pthread_mutex_unlock(&facilities->infrastructure->lock); + + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; + } + } + + pthread_mutex_unlock(&facilities->den->lock); + pthread_mutex_unlock(&facilities->infrastructure->lock); + fdres_oer = malloc(32768); asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesDataResult, NULL, fdres, fdres_oer, 32768); if (enc.encoded == -1) { syslog_err("[facilities] failed encoding FDResult (%s)", enc.failed_type->name); - pthread_mutex_unlock(&facilities->den->lock); facilities_request_result_rejected(responder); rv = 1; @@ -380,8 +420,6 @@ int facilities_request_active_events(facilities_t* facilities, void* responder, zmq_send(responder, fdres_oer, enc.encoded, 0); - pthread_mutex_unlock(&facilities->den->lock); - cleanup: free(fdres_oer); ASN_STRUCT_FREE(asn_DEF_FacilitiesDataResult, fdres); @@ -435,3 +473,45 @@ cleanup: return rv; } + + +int facilities_request_loaded_protected_zones(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq) { + int rv = 0; + + FacilitiesDataResult_t* fdres = calloc(1, sizeof(FacilitiesDataResult_t)); + + fdres->code = FacilitiesResultCode_accepted; + fdres->result = calloc(1, sizeof(FacilitiesResult_t)); + fdres->result->present = FacilitiesResult_PR_protectedCommunicationZones; + + pthread_mutex_lock(&facilities->lightship->lock); + + fdres->result->choice.protectedCommunicationZones.list.count = facilities->lightship->protected_zones.pz_len; + fdres->result->choice.protectedCommunicationZones.list.size = facilities->lightship->protected_zones.pz_len * sizeof(void*); + fdres->result->choice.protectedCommunicationZones.list.array = malloc(facilities->lightship->protected_zones.pz_len * sizeof(void*)); + + uint8_t buf[256]; + for (int z = 0; z < facilities->lightship->protected_zones.pz_len; ++z) { + fdres->result->choice.protectedCommunicationZones.list.array[z] = calloc(1, sizeof(ProtectedCommunicationZone_t)); + asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_ProtectedCommunicationZone, NULL, facilities->lightship->protected_zones.pz[z], buf, 256); + uper_decode_complete(NULL, &asn_DEF_ProtectedCommunicationZone, (void**) &fdres->result->choice.protectedCommunicationZones.list.array[z], buf, (enc.encoded+7) / 8); + } + + pthread_mutex_unlock(&facilities->lightship->lock); + + uint8_t fdres_oer[1024]; + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesDataResult, NULL, fdres, fdres_oer, 1024); + if (enc.encoded == -1) { + syslog_err("[facilities] failed encoding FDResult (%s)", enc.failed_type->name); + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; + } + + zmq_send(responder, fdres_oer, enc.encoded, 0); + +cleanup: + ASN_STRUCT_FREE(asn_DEF_FacilitiesDataResult, fdres); + + return rv; +} diff --git a/src/requests.h b/src/requests.h index 36560dc..d7e4e26 100644 --- a/src/requests.h +++ b/src/requests.h @@ -8,7 +8,8 @@ int facilities_request_result_accepted(void* responder); int facilities_request_result_rejected(void* responder); int facilities_request_single_message(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq); -int facilities_request_active_events(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq); +int facilities_request_active_episodes(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq); int facilities_request_attribute_types(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq); +int facilities_request_loaded_protected_zones(facilities_t* facilities, void* responder, FacilitiesDataRequest_t* fdreq); #endif