diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5ca74dd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "prereservation-id.h": "c", + "constr_sequence.h": "c", + "array": "c", + "string_view": "c", + "initializer_list": "c", + "nativeenumerated.h": "c", + "asn_application.h": "c" + } +} \ No newline at end of file diff --git a/src/evm.c b/src/evm.c index 6e0887a..fd60e25 100644 --- a/src/evm.c +++ b/src/evm.c @@ -1,27 +1,26 @@ #include "evm.h" -#include "facilities.h" -#include +#include +#include #include #include -#include - -#include -#include -#include -#include -#include -#include -#include - +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -static UTF8String_t *create_utf8_from_string(const char* string, size_t length) { +#include "facilities.h" + +static UTF8String_t *create_utf8_from_string(const char *string, size_t length) { UTF8String_t *utf8_string = calloc(1, sizeof(UTF8String_t)); utf8_string->buf = calloc(length, sizeof(uint8_t)); utf8_string->size = length; @@ -29,16 +28,13 @@ static UTF8String_t *create_utf8_from_string(const char* string, size_t length) return utf8_string; } - -static UTF8String_t *create_empty_utf8_string() -{ +static UTF8String_t *create_empty_utf8_string() { UTF8String_t *utf8_string = calloc(1, sizeof(UTF8String_t)); utf8_string->size = 0; return utf8_string; } -static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) -{ +static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) { int rv = 0; int shm_fd, shm_valid = 0; @@ -51,7 +47,7 @@ static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) uint64_t now = itss_time_get(); - evcsnm->evcsn.poiHeader.poiType = 1; // set to "EV charging station POI ID = 1" + evcsnm->evcsn.poiHeader.poiType = 1; // set to "EV charging station POI ID = 1" asn_ulong2INTEGER(&evcsnm->evcsn.poiHeader.timeStamp, now); evcsnm->evcsn.poiHeader.relayCapable = 1; @@ -74,8 +70,8 @@ static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) cs0->accessibility = *create_utf8_from_string("Free Access", strlen("Free Access")); cs0->pricing = *create_utf8_from_string(".15 €/kWh", strlen(".15 €/kWh")); cs0->openingDaysHours = *create_utf8_from_string("Always", strlen("Always")); - const char* booking_url = "ccam.av.it.pt"; - cs0->bookingContactInfo = create_utf8_from_string(booking_url, strlen(booking_url)); + const char *booking_url = "ccam.av.it.pt"; + cs0->bookingContactInfo = create_utf8_from_string(booking_url, strlen(booking_url)); cs0->chargingSpotsAvailable.list.array = calloc(1, sizeof(void *)); cs0->chargingSpotsAvailable.list.count = 1; cs0->chargingSpotsAvailable.list.size = sizeof(void *) * 1; @@ -95,8 +91,7 @@ static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) cs_elem0->parkingPlacesData->list.count = 2; cs_elem0->parkingPlacesData->list.size = sizeof(void *) * 2; // As requested onnly 2 parking places are available - for (int parckingPlaceIndex = 0; parckingPlaceIndex < 2; parckingPlaceIndex++) - { + for (int parckingPlaceIndex = 0; parckingPlaceIndex < 2; parckingPlaceIndex++) { cs_elem0->parkingPlacesData->list.array[parckingPlaceIndex] = calloc(1, sizeof(struct SpotAvailability)); struct SpotAvailability *spot = cs_elem0->parkingPlacesData->list.array[parckingPlaceIndex]; spot->maxWaitingTimeMinutes = 0; @@ -108,8 +103,7 @@ static int mk_evcsnm(uint8_t *evcsnm_oer, uint32_t *evcsnm_len) // } asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_EvcsnPdu, NULL, evcsnm, evcsnm_oer, 512); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("[ca] failed encoding evcsnm (%s)", enc.failed_type->name); rv = 1; goto cleanup; @@ -121,29 +115,155 @@ cleanup: return rv; } -int evcsnm_check(EvcsnPdu_t *evcsnm) -{ +static int pre_reservation_id = 0; + +int evrsrm_recv(EV_RSR_t *evrsr_request) { + int rv = 0; + TransportRequest_t *tr = calloc(1, sizeof(TransportRequest_t)); + tr->present = TransportRequest_PR_packet; + TransportPacketRequest_t *tpr = &tr->choice.packet; + tpr->present = TransportPacketRequest_PR_btp; + BTPPacketRequest_t *bpr = &tpr->choice.btp; + + bpr->btpType = BTPType_btpB; + + bpr->gn.destinationAddress.buf = malloc(6); + for (int i = 0; i < 6; ++i) { + bpr->gn.destinationAddress.buf[i] = 0xff; + } + bpr->gn.destinationAddress.size = 6; + + bpr->gn.packetTransportType = PacketTransportType_shb; + + bpr->destinationPort = Port_cam; + + bpr->gn.trafficClass = 2; + + bpr->data.buf = malloc(512); + + // Fill header for FacilitiesIndication and FacilitiesMessageIndication structs + + bpr->gn.securityProfile.sign = true; + + FacilitiesIndication_t *fi = calloc(1, sizeof(FacilitiesIndication_t)); + fi->present = FacilitiesIndication_PR_message; + FacilitiesMessageIndication_t *fmi = &fi->choice.message; + fmi->itsMessageType = ItsMessageType_evrsr; + fmi->data.buf = malloc(512); + + uint8_t tr_oer[1024]; + uint8_t fi_oer[1024]; + tr_oer[0] = 4; // Facilities + fi_oer[0] = 4; + if (!evrsr_request->messageBody.present == EV_RSR_MessageBody_PR_preReservationRequestMessage || + !evrsr_request->messageBody.present == EV_RSR_MessageBody_PR_reservationRequestMessage) { + return 1; + } + int evrsr_response; + if (evrsr_request->messageBody.present == EV_RSR_MessageBody_PR_preReservationRequestMessage) + evrsr_response = evrsrm_pre_reservation_response(evrsr_request, bpr->data.buf, (uint32_t *)&bpr->data.size); + // else if (evrsr_request->messageBody.present == EV_RSR_MessageBody_PR_reservationRequestMessage) + // evrsr_response = evrsrm_reservation_response(evrsr_request); + if (evrsr_response != 0) { + rv = 1; + goto cleanup; + } + memcpy(fmi->data.buf, bpr->data.buf, bpr->data.size); + fmi->data.size = bpr->data.size; + + // Check if inside PZ + bpr->gn.communicationProfile = 0; + if (facilities.station_type != 15) bpr->gn.communicationProfile = 1; + + uint32_t id = itss_id(bpr->data.buf, bpr->data.size); + bpr->id = id; + fmi->id = id; + + asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, tr_oer + 1, 1024); + if (enc.encoded == -1) { + log_error("[ca] failed encoding facilities indication (%s)", enc.failed_type->name); + rv = 1; + goto cleanup; + } + + tr->choice.packet.choice.btp.data.size = (enc.encoded + 7) / 8; + + enc = uper_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, tr_oer, 1024); + if (enc.encoded == -1) { + log_error("[ev] failed encoding transport request (%s)", enc.failed_type->name); + rv = 1; + goto cleanup; + } + + asn_enc_rval_t enc_fdi = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, fi_oer + 1, 1023); + if (enc_fdi.encoded == -1) { + log_error("[ev] encoding FI for cam failed"); + rv = 1; + goto cleanup; + } + itss_queue_send(facilities.tx_queue, tr_oer, enc.encoded + 1, ITSS_TRANSPORT, id, "TR.packet.btp"); + + itss_queue_send(facilities.tx_queue, fi_oer, enc_fdi.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); + +cleanup: + log_debug("[ev] evrsrm_recv done"); + return rv; +} + +static int evrsrm_pre_reservation_response(EV_RSR_t *evrsr_request, uint8_t *evrsrm_oer, uint32_t *evrsrm_len) { + if (!evrsr_request->messageBody.present == EV_RSR_MessageBody_PR_preReservationRequestMessage) + return 1; + + EV_RSR_t *evrsr_response = calloc(1, sizeof(EV_RSR_t)); + evrsr_response->header.protocolVersion = 1; + evrsr_response->header.messageID = 1; + pthread_mutex_lock(&facilities.id.lock); + evrsr_response->header.stationID = facilities.id.station_id; + pthread_mutex_unlock(&facilities.id.lock); + evrsr_response->messageBody.present = EV_RSR_MessageBody_PR_preReservationResponseMessage; + + PreReservationResponseMessage_t response = evrsr_response->messageBody.choice.preReservationResponseMessage; + char *pre_reservation_id = calloc(1, sizeof(char) * 10); + sprintf(pre_reservation_id, "%d", pre_reservation_id); + response.preReservation_ID = *create_utf8_from_string(pre_reservation_id, strlen(pre_reservation_id)); + + response.availabilityStatus = 0; + + response.supportedPaymentTypes.buf = calloc(1, sizeof(uint8_t)); + response.supportedPaymentTypes.bits_unused = 0; + response.supportedPaymentTypes.size = 1; + response.supportedPaymentTypes.buf[0] = 0x00; + + response.preReservationExpirationTime = 0; + + pre_reservation_id++; + + asn_enc_rval_t enc = uper_encode_to_buffer(&asn_DEF_EV_RSR, NULL, evrsr_response, evrsrm_oer, 512); + if (enc.encoded == -1) { + log_error("[ca] failed encoding evrsrm (%s)", enc.failed_type->name); + return 1; + } + *evrsrm_len = (enc.encoded + 7) / 8; return 0; } - -int evrsrm_check(EV_RSR_t *evrsrm) -{ +int evcsnm_check(EvcsnPdu_t *evcsnm) { return 0; } -enum EVM_CHECK_R check_evcsnm(BTPPacketIndication_t *bpi, EvcsnPdu_t *evcsnm, uint8_t *ssp, uint32_t ssp_len) -{ +int evrsrm_check(EV_RSR_t *evrsrm) { return 0; } -enum EVM_CHECK_R check_evrsrm(BTPPacketIndication_t *bpi, EV_RSR_t *evrsrm, uint8_t *ssp, uint32_t ssp_len) -{ +enum EVM_CHECK_R check_evcsnm(BTPPacketIndication_t *bpi, EvcsnPdu_t *evcsnm, uint8_t *ssp, uint32_t ssp_len) { return 0; } -void *evcsn_service() -{ +enum EVM_CHECK_R check_evrsrm(BTPPacketIndication_t *bpi, EV_RSR_t *evrsrm, uint8_t *ssp, uint32_t ssp_len) { + return 0; +} + +void *evcsn_service() { int rv = 0; TransportRequest_t *tr = calloc(1, sizeof(TransportRequest_t)); @@ -155,8 +275,7 @@ void *evcsn_service() bpr->btpType = BTPType_btpB; bpr->gn.destinationAddress.buf = malloc(6); - for (int i = 0; i < 6; ++i) - { + for (int i = 0; i < 6; ++i) { bpr->gn.destinationAddress.buf[i] = 0xff; } bpr->gn.destinationAddress.size = 6; @@ -181,16 +300,13 @@ void *evcsn_service() uint8_t tr_oer[1024]; uint8_t fi_oer[1024]; - tr_oer[0] = 4; // Facilities + tr_oer[0] = 4; // Facilities fi_oer[0] = 4; - while (!facilities.exit) - { + while (!facilities.exit) { usleep(1000 * 1000); - if (facilities.evm_args.activate) - { + if (facilities.evm_args.activate) { rv = mk_evcsnm(bpr->data.buf, (uint32_t *)&bpr->data.size); - if (rv) - { + if (rv) { continue; } memcpy(fmi->data.buf, bpr->data.buf, bpr->data.size); @@ -201,15 +317,13 @@ void *evcsn_service() fmi->id = id; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, tr_oer + 1, 1023); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("encoding TR for evcsnm failed"); continue; } asn_enc_rval_t enc_fdi = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, fi_oer + 1, 1023); - if (enc_fdi.encoded == -1) - { + if (enc_fdi.encoded == -1) { log_error("encoding FI for evcsnm failed"); continue; } @@ -219,16 +333,14 @@ void *evcsn_service() itss_queue_send(facilities.tx_queue, fi_oer, enc_fdi.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); // Logging - if (facilities.logging.dbms) - { + if (facilities.logging.dbms) { pthread_mutex_lock(&facilities.id.lock); uint32_t station_id = facilities.id.station_id; pthread_mutex_unlock(&facilities.id.lock); itss_db_add(facilities.logging.dbms, station_id, bpr->id, true, messageID_evcsn, NULL, bpr->data.buf, bpr->data.size); } - if (facilities.logging.recorder) - { + if (facilities.logging.recorder) { uint16_t buffer_len = 2048; uint8_t buffer[buffer_len]; int e = itss_management_record_packet_sdu( @@ -240,8 +352,7 @@ void *evcsn_service() itss_time_get(), ITSS_FACILITIES, true); - if (e != -1) - { + if (e != -1) { itss_queue_send(facilities.tx_queue, buffer, e, ITSS_MANAGEMENT, id, "MReq.packet.set"); } } diff --git a/src/evm.h b/src/evm.h index 89e6f88..414988a 100644 --- a/src/evm.h +++ b/src/evm.h @@ -33,6 +33,24 @@ enum EVM_CHECK_R check_evrsrm(BTPPacketIndication_t *bpi, EV_RSR_t *evrsrm, uint */ void* evcsn_service(); +/** + * @brief Creates a EVCSNM response and sends it + * @param evcsnm_request The EVCSNM request + * + * @return 0 on success, 1 otherwise + */ +int evrsrm_recv(EV_RSR_t *evrsr_request); + + +/** + * @brief Creates a pre reservation response. + * @param evrsr_request The reservation request + * + * @return The reservation response or NULL if the request isn't a Pre reservation request + */ + +static int evrsrm_pre_reservation_response(EV_RSR_t *evrsr_request, uint8_t *evrsrm_oer, uint32_t *evrsrm_len); + /** * Analyses a evm * @param evm The evm to be analyzed diff --git a/src/facilities.c b/src/facilities.c index d0a7d77..a2855ba 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -1,53 +1,50 @@ #include "facilities.h" -#include "cam.h" -#include "config.h" -#include "denm.h" -#include "infrastructure.h" -#include "indications.h" -#include "requests.h" -#include "cpm.h" -#include "saem.h" -#include "tpm.h" -#include "vcm.h" -#include "evm.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include - -#include -#include -#include -#include -#include -#include - +#include +#include #include #include #include -#include -#include +#include +#include +#include +#include +#include +#include + +#include "cam.h" +#include "config.h" +#include "cpm.h" +#include "denm.h" +#include "evm.h" +#include "indications.h" +#include "infrastructure.h" +#include "requests.h" +#include "saem.h" +#include "tpm.h" +#include "vcm.h" facilities_t facilities = {0}; -static int transport_indication(void *responder, void **security_socket, uint8_t *msg, uint32_t msg_len) -{ +static int transport_indication(void *responder, void **security_socket, uint8_t *msg, uint32_t msg_len) { int rv = 0; uint8_t code = 0; bool handled_msg = false; @@ -62,8 +59,7 @@ static int transport_indication(void *responder, void **security_socket, uint8_t TransportIndication_t *ti = calloc(1, sizeof(TransportIndication_t)); asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_TransportIndication, (void **)&ti, msg, msg_len); - if (dec.code) - { + if (dec.code) { log_error("<- invalid TI received"); rv = 1; code = 1; @@ -73,21 +69,20 @@ static int transport_indication(void *responder, void **security_socket, uint8_t itss_0send(responder, &code, 1); - switch (ti->present) - { - case TransportIndication_PR_packet: - break; - case TransportIndication_PR_data: - transport_data_indication(&ti->choice.data, security_socket); - goto cleanup; - default: - log_debug("<- unrecognized TI.choice received"); - rv = 1; - goto cleanup; + switch (ti->present) { + case TransportIndication_PR_packet: + break; + case TransportIndication_PR_data: + transport_data_indication(&ti->choice.data, security_socket); + goto cleanup; + default: + log_debug("<- unrecognized TI.choice received"); + rv = 1; + goto cleanup; } - TransportPacketIndication_t *tpi = &ti->choice.packet; // TODO - // + TransportPacketIndication_t *tpi = &ti->choice.packet; // TODO + // bool fwd = false; @@ -99,375 +94,350 @@ static int transport_indication(void *responder, void **security_socket, uint8_t uint8_t *packet = NULL; uint16_t packet_len = 0; - switch (tpi->present) - { - case TransportPacketIndication_PR_btp: - id = tpi->choice.btp.id; - log_debug("<- TI.packet.btp | id:%08x size:%dB", (uint32_t)id, msg_len); - // Parse message - switch (tpi->choice.btp.destinationPort) - { - case Port_cam: - its_msg_descriptor = &asn_DEF_CAM; - its_msg = calloc(1, sizeof(CAM_t)); - its_msg_type = messageID_cam; - handled_msg = true; - break; + switch (tpi->present) { + case TransportPacketIndication_PR_btp: + id = tpi->choice.btp.id; + log_debug("<- TI.packet.btp | id:%08x size:%dB", (uint32_t)id, msg_len); + // Parse message + switch (tpi->choice.btp.destinationPort) { + case Port_cam: + its_msg_descriptor = &asn_DEF_CAM; + its_msg = calloc(1, sizeof(CAM_t)); + its_msg_type = messageID_cam; + handled_msg = true; + break; - case Port_denm: - its_msg_descriptor = &asn_DEF_DENM; - its_msg = calloc(1, sizeof(DENM_t)); - its_msg_type = messageID_denm; - handled_msg = true; - break; + case Port_denm: + its_msg_descriptor = &asn_DEF_DENM; + its_msg = calloc(1, sizeof(DENM_t)); + its_msg_type = messageID_denm; + handled_msg = true; + break; - case Port_ivim: - its_msg_descriptor = &asn_DEF_IVIM; - its_msg = calloc(1, sizeof(IVIM_t)); - its_msg_type = messageID_ivim; - handled_msg = true; - break; + case Port_ivim: + its_msg_descriptor = &asn_DEF_IVIM; + its_msg = calloc(1, sizeof(IVIM_t)); + its_msg_type = messageID_ivim; + handled_msg = true; + break; - case Port_cpm: - its_msg_descriptor = &asn_DEF_CPM; - its_msg = calloc(1, sizeof(CPM_t)); - its_msg_type = 14; - handled_msg = true; - break; + case Port_cpm: + its_msg_descriptor = &asn_DEF_CPM; + its_msg = calloc(1, sizeof(CPM_t)); + its_msg_type = 14; + handled_msg = true; + break; - case Port_saem: - its_msg_descriptor = &asn_DEF_SAEM; - its_msg = calloc(1, sizeof(SAEM_t)); - its_msg_type = messageID_saem; - handled_msg = true; - break; + case Port_saem: + its_msg_descriptor = &asn_DEF_SAEM; + its_msg = calloc(1, sizeof(SAEM_t)); + its_msg_type = messageID_saem; + handled_msg = true; + break; - case 7011: /* tolling */ - its_msg_descriptor = &asn_DEF_TPM; - its_msg = calloc(1, sizeof(TPM_t)); - its_msg_type = 117; - handled_msg = true; - break; + case 7011: /* tolling */ + its_msg_descriptor = &asn_DEF_TPM; + its_msg = calloc(1, sizeof(TPM_t)); + its_msg_type = 117; + handled_msg = true; + break; - case 2043: /* maneuvers */ - its_msg_descriptor = &asn_DEF_VCM; - its_msg = calloc(1, sizeof(VCM_t)); - its_msg_type = 43; - handled_msg = true; - break; + case 2043: /* maneuvers */ + its_msg_descriptor = &asn_DEF_VCM; + its_msg = calloc(1, sizeof(VCM_t)); + its_msg_type = 43; + handled_msg = true; + break; - case 2044: /* VERCOe */ - its_msg_descriptor = &asn_DEF_VERCOe; - its_msg = calloc(1, sizeof(VERCOe_t)); - its_msg_type = 44; - handled_msg = true; - fwd = true; - break; + case 2044: /* VERCOe */ + its_msg_descriptor = &asn_DEF_VERCOe; + its_msg = calloc(1, sizeof(VERCOe_t)); + its_msg_type = 44; + handled_msg = true; + fwd = true; + break; - case Port_poi: /* EVCSNM */ - its_msg_descriptor = &asn_DEF_EvcsnPdu; - its_msg = calloc(1, sizeof(EvcsnPdu_t)); - its_msg_type = messageID_evcsn; - handled_msg = true; - fwd = true; - break; - - case Port_evrsr: /* EVRSRM */ - its_msg_descriptor = &asn_DEF_EV_RSR; - its_msg = calloc(1, sizeof(EV_RSR_t)); - its_msg_type = messageID_evcsn; - handled_msg = true; - fwd = true; - break; + case Port_poi: /* EVCSNM */ + its_msg_descriptor = &asn_DEF_EvcsnPdu; + its_msg = calloc(1, sizeof(EvcsnPdu_t)); + its_msg_type = messageID_evcsn; + handled_msg = true; + fwd = true; + break; - default: - log_debug("messsage with unhandled BTP port received (%lld), ignoring", tpi->choice.btp.destinationPort); - goto cleanup; - } + case Port_evrsr: /* EVRSRM */ + its_msg_descriptor = &asn_DEF_EV_RSR; + its_msg = calloc(1, sizeof(EV_RSR_t)); + its_msg_type = messageID_evcsn; + handled_msg = true; + fwd = true; + break; - packet = tpi->choice.btp.data.buf; - packet_len = tpi->choice.btp.data.size; - - dec = uper_decode_complete(NULL, its_msg_descriptor, (void **)&its_msg, tpi->choice.btp.data.buf, tpi->choice.btp.data.size); - if (dec.code) - { - log_debug("<- invalid %s received", its_msg_descriptor->name); - rv = 1; - goto cleanup; - } - - // Get permisisons - uint8_t *ssp = NULL; - uint16_t ssp_len; - if (tpi->choice.btp.gn.securityPermissions) - { - ssp = tpi->choice.btp.gn.securityPermissions->ssp.buf; - ssp_len = tpi->choice.btp.gn.securityPermissions->ssp.size; - } - - // Get neighbour certificate ID - uint8_t *neighbour_cert = tpi->choice.btp.gn.securityNeighbour ? tpi->choice.btp.gn.securityNeighbour->buf : NULL; - - // Manage message - switch (tpi->choice.btp.destinationPort) - { - case Port_cam: - switch (check_cam(&tpi->choice.btp, its_msg, ssp, ssp_len)) - { - case CAM_OK: - fwd = true; - break; - case CAM_INVALID: - case CAM_BAD_PERMISSIONS: - default: - break; - } - break; - - case Port_denm:; -#ifdef DEBUG - uint8_t *xml_denm = malloc(32768); - asn_enc_rval_t rve = xer_encode_to_buffer(xml_denm, 32768, 0x02, &asn_DEF_DENM, its_msg); - log_debug("DENM XER %d: %.*s", (int)rve.encoded, (int)rve.encoded, xml_denm); - free(xml_denm); -#endif - switch (event_manage(its_msg, &id, ssp, ssp_len)) - { - case EVENT_NEW: - case EVENT_CANCELLATION: - case EVENT_NEGATION: - case EVENT_UPDATE: - case EVENT_NUMBER_EXCEEDED: - fwd = true; - break; - case EVENT_INVALID: - case EVENT_PASSED: - case EVENT_REPEATED: - case EVENT_BAD_PERMISSIONS: - break; - } - break; - - case Port_ivim: - switch (service_eval(SERVICE_IVI, its_msg, &id, ssp, ssp_len)) - { - case SERVICE_NEW: - case SERVICE_CANCELLATION: - case SERVICE_NEGATION: - case SERVICE_UPDATE: - case SERVICE_NUMBER_EXCEEDED: - fwd = true; - break; - case SERVICE_INVALID: - case SERVICE_REPEATED: - case SERVICE_PASSED: - case SERVICE_BAD_PERMISSIONS: - default: - break; - } - break; - - case Port_saem: - switch (saem_check(its_msg, neighbour_cert)) - { - case SAEM_NEW: - fwd = true; - break; - default: - break; - } - break; - - case 7011: - if (facilities.tolling.enabled) - { - tpm_recv(its_msg, security_socket, neighbour_cert, NULL); - fwd = true; - } - break; - - case 2043: - if (facilities.coordination.active) - { - vcm_check(its_msg); - } - fwd = true; - break; - case Port_poi: - if (facilities.evm_args.activate) - { - evcsnm_check(its_msg); - } - fwd = true; - break; - - case Port_evrsr: - if (facilities.evm_args.activate) - { - evrsrm_check(its_msg); - } - fwd = true; - default: - break; - } - break; - - case TransportPacketIndication_PR_tcp: - id = tpi->choice.tcp.id; - packet = tpi->choice.tcp.data.buf; - packet_len = tpi->choice.tcp.data.size; - log_debug("<- TI.packet.tcp | id:%ld size:%dB", id, msg_len); - - sreq = calloc(1, sizeof(SecurityRequest_t)); - sreq->present = SecurityRequest_PR_tlsRecv; - sreq->choice.tlsRecv.data.size = tpi->choice.tcp.data.size; - sreq->choice.tlsRecv.data.buf = malloc(tpi->choice.tcp.data.size); - memcpy(sreq->choice.tlsRecv.data.buf, tpi->choice.tcp.data.buf, tpi->choice.tcp.data.size); - - pthread_mutex_lock(&facilities.tolling.lock); - tlsc_t *tlsc = tolling_tlsc_get(tpi->choice.tcp.sourceAddress->buf, 7011); - if (tlsc) - { - id = tlsc->id; - } - else - { - tlsc = tolling_tlsc_new(tpi->choice.tcp.sourceAddress->buf, 7011); - id = tlsc->id; - } - ++tlsc->nmsg; - pthread_mutex_unlock(&facilities.tolling.lock); - sreq->choice.tlsSend.connId = id; - - uint8_t b_tx[2048], b_rx[2048]; - b_tx[0] = 4; - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, b_tx + 1, 2047); - - log_debug("->[security] SecurityRequest.tlsRecv (%ldB)", enc.encoded + 1); - itss_0send(*security_socket, b_tx, enc.encoded + 1); - int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); - log_debug("<-[security] SecurityReply.tlsRecv (%dB)", rl); - - if (oer_decode(NULL, &asn_DEF_SecurityReply, (void **)&srep, b_rx, rl).code) - { - log_error("SecurityReply.tlsRecv decode failure"); - rv = 1; - goto cleanup; - } - - if (srep->returnCode == SecurityReplyReturnCode_rejected) - { - log_error("SecurityReply.tlsRecv rejected"); - - SecurityRequest_t *sREQ = calloc(1, sizeof(SecurityRequest_t)); - sREQ->present = SecurityRequest_PR_tlsShutdown; - sREQ->choice.tlsShutdown.connId = id; - b_tx[0] = 4; - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sREQ, b_tx + 1, 2047); - log_debug("->[security] SecurityRequest.tlsShutdown (%ldB)", enc.encoded + 1); - itss_0send(*security_socket, b_tx, enc.encoded + 1); - int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); - log_debug("<-[security] SecurityReply.tlsShutdown (%dB)", rl); - - rv = 1; - goto cleanup; - } - - log_debug("[tolling] tls n-msg:%d state:%d", tlsc->nmsg, tlsc->state); - - // Forward to [transport] - if (srep->data->choice.tlsRecv.state != 1) - { - tr = calloc(1, sizeof(TransportRequest_t)); - tr->present = TransportRequest_PR_packet; - tr->choice.packet.present = TransportPacketRequest_PR_tcp; - TCPPacketRequest_t *tpr = &tr->choice.packet.choice.tcp; - tpr->data.size = srep->data->choice.tlsRecv.data.size; - tpr->data.buf = malloc(srep->data->choice.tlsRecv.data.size); - memcpy(tpr->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - - tpr->sourcePort = tpi->choice.tcp.destinationPort; - tpr->destinationPort = tpi->choice.tcp.sourcePort; - - tpr->destinationAddress = calloc(1, sizeof(OCTET_STRING_t)); - tpr->destinationAddress->buf = malloc(16); - tpr->destinationAddress->size = 16; - memcpy(tpr->destinationAddress->buf, tpi->choice.tcp.sourceAddress->buf, 16); - tpr->destinationPort = 7011; - tpr->sourcePort = 7011; - - if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_GN || - (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS && tlsc->nmsg < 2)) - { - tpr->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t)); - tpr->gn->packetTransportType = PacketTransportType_shb; - tpr->gn->destinationAddress.buf = calloc(1, 6); - tpr->gn->destinationAddress.size = 6; + default: + log_debug("messsage with unhandled BTP port received (%lld), ignoring", tpi->choice.btp.destinationPort); + goto cleanup; } - tpr->id = itss_id(tpr->data.buf, tpr->data.size); + packet = tpi->choice.btp.data.buf; + packet_len = tpi->choice.btp.data.size; - buf[0] = 4; - enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, buf + 1, buf_len - 1); - if (enc.encoded == -1) - { - log_error("TransportRequest encoding fail"); + dec = uper_decode_complete(NULL, its_msg_descriptor, (void **)&its_msg, tpi->choice.btp.data.buf, tpi->choice.btp.data.size); + if (dec.code) { + log_debug("<- invalid %s received", its_msg_descriptor->name); rv = 1; goto cleanup; } - itss_queue_send(facilities.tx_queue, buf, enc.encoded + 1, ITSS_TRANSPORT, tpr->id, "TR.packet.tcp"); - } - else - { + // Get permisisons + uint8_t *ssp = NULL; + uint16_t ssp_len; + if (tpi->choice.btp.gn.securityPermissions) { + ssp = tpi->choice.btp.gn.securityPermissions->ssp.buf; + ssp_len = tpi->choice.btp.gn.securityPermissions->ssp.size; + } - if (facilities.tolling.enabled && srep->data->choice.tlsRecv.data.size) - { - dec = uper_decode_complete(NULL, &asn_DEF_TPM, (void **)&its_msg, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - if (dec.code) - { - log_debug("<- invalid TPM received"); + // Get neighbour certificate ID + uint8_t *neighbour_cert = tpi->choice.btp.gn.securityNeighbour ? tpi->choice.btp.gn.securityNeighbour->buf : NULL; + + // Manage message + switch (tpi->choice.btp.destinationPort) { + case Port_cam: + switch (check_cam(&tpi->choice.btp, its_msg, ssp, ssp_len)) { + case CAM_OK: + fwd = true; + break; + case CAM_INVALID: + case CAM_BAD_PERMISSIONS: + default: + break; + } + break; + + case Port_denm:; +#ifdef DEBUG + uint8_t *xml_denm = malloc(32768); + asn_enc_rval_t rve = xer_encode_to_buffer(xml_denm, 32768, 0x02, &asn_DEF_DENM, its_msg); + log_debug("DENM XER %d: %.*s", (int)rve.encoded, (int)rve.encoded, xml_denm); + free(xml_denm); +#endif + switch (event_manage(its_msg, &id, ssp, ssp_len)) { + case EVENT_NEW: + case EVENT_CANCELLATION: + case EVENT_NEGATION: + case EVENT_UPDATE: + case EVENT_NUMBER_EXCEEDED: + fwd = true; + break; + case EVENT_INVALID: + case EVENT_PASSED: + case EVENT_REPEATED: + case EVENT_BAD_PERMISSIONS: + break; + } + break; + + case Port_ivim: + switch (service_eval(SERVICE_IVI, its_msg, &id, ssp, ssp_len)) { + case SERVICE_NEW: + case SERVICE_CANCELLATION: + case SERVICE_NEGATION: + case SERVICE_UPDATE: + case SERVICE_NUMBER_EXCEEDED: + fwd = true; + break; + case SERVICE_INVALID: + case SERVICE_REPEATED: + case SERVICE_PASSED: + case SERVICE_BAD_PERMISSIONS: + default: + break; + } + break; + + case Port_saem: + switch (saem_check(its_msg, neighbour_cert)) { + case SAEM_NEW: + fwd = true; + break; + default: + break; + } + break; + + case 7011: + if (facilities.tolling.enabled) { + tpm_recv(its_msg, security_socket, neighbour_cert, NULL); + fwd = true; + } + break; + + case 2043: + if (facilities.coordination.active) { + vcm_check(its_msg); + } + fwd = true; + break; + case Port_poi: + if (facilities.evm_args.activate) { + evcsnm_check(its_msg); + fwd = true; + } + break; + + case Port_evrsr: + if (facilities.evm_args.activate) { + evrsrm_check(its_msg); + fwd = true; + EV_RSR_t *evrsr_request = (EV_RSR_t *)its_msg; + evrsrm_recv(evrsr_request); + + } + default: + break; + } + break; + + case TransportPacketIndication_PR_tcp: + id = tpi->choice.tcp.id; + packet = tpi->choice.tcp.data.buf; + packet_len = tpi->choice.tcp.data.size; + log_debug("<- TI.packet.tcp | id:%ld size:%dB", id, msg_len); + + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_tlsRecv; + sreq->choice.tlsRecv.data.size = tpi->choice.tcp.data.size; + sreq->choice.tlsRecv.data.buf = malloc(tpi->choice.tcp.data.size); + memcpy(sreq->choice.tlsRecv.data.buf, tpi->choice.tcp.data.buf, tpi->choice.tcp.data.size); + + pthread_mutex_lock(&facilities.tolling.lock); + tlsc_t *tlsc = tolling_tlsc_get(tpi->choice.tcp.sourceAddress->buf, 7011); + if (tlsc) { + id = tlsc->id; + } else { + tlsc = tolling_tlsc_new(tpi->choice.tcp.sourceAddress->buf, 7011); + id = tlsc->id; + } + ++tlsc->nmsg; + pthread_mutex_unlock(&facilities.tolling.lock); + sreq->choice.tlsSend.connId = id; + + uint8_t b_tx[2048], b_rx[2048]; + b_tx[0] = 4; + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, b_tx + 1, 2047); + + log_debug("->[security] SecurityRequest.tlsRecv (%ldB)", enc.encoded + 1); + itss_0send(*security_socket, b_tx, enc.encoded + 1); + int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); + log_debug("<-[security] SecurityReply.tlsRecv (%dB)", rl); + + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void **)&srep, b_rx, rl).code) { + log_error("SecurityReply.tlsRecv decode failure"); + rv = 1; + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + log_error("SecurityReply.tlsRecv rejected"); + + SecurityRequest_t *sREQ = calloc(1, sizeof(SecurityRequest_t)); + sREQ->present = SecurityRequest_PR_tlsShutdown; + sREQ->choice.tlsShutdown.connId = id; + b_tx[0] = 4; + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sREQ, b_tx + 1, 2047); + log_debug("->[security] SecurityRequest.tlsShutdown (%ldB)", enc.encoded + 1); + itss_0send(*security_socket, b_tx, enc.encoded + 1); + int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); + log_debug("<-[security] SecurityReply.tlsShutdown (%dB)", rl); + + rv = 1; + goto cleanup; + } + + log_debug("[tolling] tls n-msg:%d state:%d", tlsc->nmsg, tlsc->state); + + // Forward to [transport] + if (srep->data->choice.tlsRecv.state != 1) { + tr = calloc(1, sizeof(TransportRequest_t)); + tr->present = TransportRequest_PR_packet; + tr->choice.packet.present = TransportPacketRequest_PR_tcp; + TCPPacketRequest_t *tpr = &tr->choice.packet.choice.tcp; + tpr->data.size = srep->data->choice.tlsRecv.data.size; + tpr->data.buf = malloc(srep->data->choice.tlsRecv.data.size); + memcpy(tpr->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + + tpr->sourcePort = tpi->choice.tcp.destinationPort; + tpr->destinationPort = tpi->choice.tcp.sourcePort; + + tpr->destinationAddress = calloc(1, sizeof(OCTET_STRING_t)); + tpr->destinationAddress->buf = malloc(16); + tpr->destinationAddress->size = 16; + memcpy(tpr->destinationAddress->buf, tpi->choice.tcp.sourceAddress->buf, 16); + tpr->destinationPort = 7011; + tpr->sourcePort = 7011; + + if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_GN || + (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS && tlsc->nmsg < 2)) { + tpr->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t)); + tpr->gn->packetTransportType = PacketTransportType_shb; + tpr->gn->destinationAddress.buf = calloc(1, 6); + tpr->gn->destinationAddress.size = 6; + } + + tpr->id = itss_id(tpr->data.buf, tpr->data.size); + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, buf + 1, buf_len - 1); + if (enc.encoded == -1) { + log_error("TransportRequest encoding fail"); rv = 1; goto cleanup; } - if (!dec.code) - { - tpm_recv(its_msg, security_socket, NULL, tpi->choice.tcp.sourceAddress->buf); - // Fwd to [applications] - fi = calloc(1, sizeof(FacilitiesIndication_t)); - fi->present = FacilitiesIndication_PR_message; - FacilitiesMessageIndication_t *fmi = &fi->choice.message; + itss_queue_send(facilities.tx_queue, buf, enc.encoded + 1, ITSS_TRANSPORT, tpr->id, "TR.packet.tcp"); + } else { + if (facilities.tolling.enabled && srep->data->choice.tlsRecv.data.size) { + dec = uper_decode_complete(NULL, &asn_DEF_TPM, (void **)&its_msg, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + if (dec.code) { + log_debug("<- invalid TPM received"); + rv = 1; + goto cleanup; + } + if (!dec.code) { + tpm_recv(its_msg, security_socket, NULL, tpi->choice.tcp.sourceAddress->buf); - fmi->id = id; + // Fwd to [applications] + fi = calloc(1, sizeof(FacilitiesIndication_t)); + fi->present = FacilitiesIndication_PR_message; + FacilitiesMessageIndication_t *fmi = &fi->choice.message; - fmi->itsMessageType = 7011; + fmi->id = id; - fmi->data.size = srep->data->choice.tlsRecv.data.size; - fmi->data.buf = malloc(srep->data->choice.tlsRecv.data.size); - memcpy(fmi->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + fmi->itsMessageType = 7011; - uint8_t buffer[ITSS_SDU_MAX_LEN]; - buffer[0] = 4; // Facilities - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); + fmi->data.size = srep->data->choice.tlsRecv.data.size; + fmi->data.buf = malloc(srep->data->choice.tlsRecv.data.size); + memcpy(fmi->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); + uint8_t buffer[ITSS_SDU_MAX_LEN]; + buffer[0] = 4; // Facilities + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); + + itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); + } } } - } - break; - case TransportPacketIndication_PR_udp: - id = tpi->choice.udp.id; - log_debug("<- TI.packet.udp | id:%ld size:%dB", id, msg_len); - break; + break; + case TransportPacketIndication_PR_udp: + id = tpi->choice.udp.id; + log_debug("<- TI.packet.udp | id:%ld size:%dB", id, msg_len); + break; - default: - break; + default: + break; } // Forward to [applications] - if (fwd) - { + if (fwd) { fi = calloc(1, sizeof(FacilitiesIndication_t)); fi->present = FacilitiesIndication_PR_message; FacilitiesMessageIndication_t *fmi = &fi->choice.message; @@ -481,22 +451,20 @@ static int transport_indication(void *responder, void **security_socket, uint8_t memcpy(fmi->data.buf, tpi->choice.btp.data.buf, tpi->choice.btp.data.size); uint8_t buffer[ITSS_SDU_MAX_LEN]; - buffer[0] = 4; // Facilities + buffer[0] = 4; // Facilities asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); } // Logging - if (facilities.logging.dbms) - { + if (facilities.logging.dbms) { pthread_mutex_lock(&facilities.id.lock); uint32_t station_id = facilities.id.station_id; pthread_mutex_unlock(&facilities.id.lock); itss_db_add(facilities.logging.dbms, station_id, id, false, its_msg_type, NULL, packet, packet_len); } - if (facilities.logging.recorder) - { + if (facilities.logging.recorder) { int e = itss_management_record_packet_sdu( buf, buf_len, @@ -506,15 +474,13 @@ static int transport_indication(void *responder, void **security_socket, uint8_t itss_time_get(), ITSS_FACILITIES, false); - if (e != -1) - { + if (e != -1) { itss_queue_send(facilities.tx_queue, buf, e, ITSS_MANAGEMENT, tpi->choice.btp.id, "MReq.packet.set"); } } cleanup: - if (handled_msg && tpi->choice.btp.destinationPort != Port_denm && tpi->choice.btp.destinationPort != Port_ivim) - { + if (handled_msg && tpi->choice.btp.destinationPort != Port_denm && tpi->choice.btp.destinationPort != Port_ivim) { ASN_STRUCT_FREE(*its_msg_descriptor, its_msg); } ASN_STRUCT_FREE(asn_DEF_TransportIndication, ti); @@ -526,59 +492,55 @@ cleanup: return rv; } -static int facilities_request(void *responder, uint8_t *msg, uint32_t msg_len) -{ +static int facilities_request(void *responder, uint8_t *msg, uint32_t msg_len) { int rv = 0; FacilitiesRequest_t *fr = calloc(1, sizeof(FacilitiesRequest_t)); asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_FacilitiesRequest, (void **)&fr, msg, msg_len); - if (dec.code) - { + if (dec.code) { log_error("<- invalid FR received"); facilities_request_result_rejected(responder); rv = 1; goto cleanup; } - switch (fr->present) - { - case FacilitiesRequest_PR_message: - rv = facilities_request_single_message(responder, &fr->choice.message); - break; - - case FacilitiesRequest_PR_data: - switch (fr->choice.data.present) - { - case FacilitiesDataRequest_PR_activeEpisodes: - rv = facilities_request_active_episodes(responder, fr); + switch (fr->present) { + case FacilitiesRequest_PR_message: + rv = facilities_request_single_message(responder, &fr->choice.message); break; - case FacilitiesDataRequest_PR_attributeTypes: - rv = facilities_request_attribute_types(responder, fr); - break; + case FacilitiesRequest_PR_data: + switch (fr->choice.data.present) { + case FacilitiesDataRequest_PR_activeEpisodes: + rv = facilities_request_active_episodes(responder, fr); + break; - case FacilitiesDataRequest_PR_loadedProtectionZones: - rv = facilities_request_loaded_protected_zones(responder, fr); - break; + case FacilitiesDataRequest_PR_attributeTypes: + rv = facilities_request_attribute_types(responder, fr); + break; - case FacilitiesDataRequest_PR_chainInfoSet: - rv = facilities_request_chaininfo_set(responder, &fr->choice.data.choice.chainInfoSet); + case FacilitiesDataRequest_PR_loadedProtectionZones: + rv = facilities_request_loaded_protected_zones(responder, fr); + break; + + case FacilitiesDataRequest_PR_chainInfoSet: + rv = facilities_request_chaininfo_set(responder, &fr->choice.data.choice.chainInfoSet); + break; + + default: + log_error("<- unrecognized FDR type received (%d)", fr->choice.data.present); + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; + } break; default: - log_error("<- unrecognized FDR type received (%d)", fr->choice.data.present); + log_error("<- unrecognized FR type received (%d)", fr->present); facilities_request_result_rejected(responder); rv = 1; goto cleanup; - } - break; - - default: - log_error("<- unrecognized FR type received (%d)", fr->present); - facilities_request_result_rejected(responder); - rv = 1; - goto cleanup; } cleanup: @@ -587,8 +549,7 @@ cleanup: return rv; } -static int security_indication(void *responder_secured, uint8_t *msg, uint32_t msg_len) -{ +static int security_indication(void *responder_secured, uint8_t *msg, uint32_t msg_len) { int rv = 0; SecurityIndication_t *si = calloc(1, sizeof(SecurityIndication_t)); @@ -599,16 +560,14 @@ static int security_indication(void *responder_secured, uint8_t *msg, uint32_t m asn_enc_rval_t enc; asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityIndication, (void **)&si, msg, msg_len); - if (dec.code) - { + if (dec.code) { log_error("<- invalid SIndication received"); rv = 1; goto cleanup; } pthread_mutex_lock(&facilities.id.change.lock); - if (facilities.id.change.stage == ID_CHANGE_BLOCKED) - { + if (facilities.id.change.stage == ID_CHANGE_BLOCKED) { pthread_mutex_unlock(&facilities.id.change.lock); log_debug("identity change is currently blocked"); rv = 1; @@ -617,8 +576,7 @@ static int security_indication(void *responder_secured, uint8_t *msg, uint32_t m if (facilities.id.change.stage == ID_CHANGE_PREPARE && si->choice.idChangeEvent.command != SecurityIdChangeEventType_commit && - si->choice.idChangeEvent.command != SecurityIdChangeEventType_abort) - { + si->choice.idChangeEvent.command != SecurityIdChangeEventType_abort) { pthread_mutex_unlock(&facilities.id.change.lock); log_debug("current identity change state is prepare, but received identity change command is not commit nor abort"); rv = 1; @@ -627,69 +585,65 @@ static int security_indication(void *responder_secured, uint8_t *msg, uint32_t m bool id_changed = false; - switch (si->choice.idChangeEvent.command) - { - case SecurityIdChangeEventType_prepare: + switch (si->choice.idChangeEvent.command) { + case SecurityIdChangeEventType_prepare: - facilities.id.change.stage = ID_CHANGE_PREPARE; + facilities.id.change.stage = ID_CHANGE_PREPARE; - pthread_mutex_lock(&facilities.id.lock); - pthread_mutex_lock(&facilities.lightship.lock); - break; + pthread_mutex_lock(&facilities.id.lock); + pthread_mutex_lock(&facilities.lightship.lock); + break; - case SecurityIdChangeEventType_commit:; - facilities.id.change.stage = ID_CHANGE_COMMIT; + case SecurityIdChangeEventType_commit:; + facilities.id.change.stage = ID_CHANGE_COMMIT; - // Reset lightship - for (int i = 0; i < facilities.lightship.path_history_len; ++i) - { - free(facilities.lightship.path_history[i]); - } - facilities.lightship.path_history_len = 0; - - facilities.lightship.t_last_cam = 0; - facilities.lightship.t_last_cam_lfc = 0; - facilities.lightship.next_cam_max = 0; - facilities.lightship.next_cam_min = 0; - - pthread_mutex_unlock(&facilities.lightship.lock); - - // Change Station ID - for (int i = 0; i < si->choice.idChangeEvent.ids.list.count; ++i) - { - switch (si->choice.idChangeEvent.ids.list.array[i]->present) - { - case SecurityId_PR_stationId: - facilities.id.station_id = si->choice.idChangeEvent.ids.list.array[i]->choice.stationId; - break; - case SecurityId_PR_ipv6Address: - memcpy(facilities.id.ipv6_addr, si->choice.idChangeEvent.ids.list.array[i]->choice.ipv6Address.buf, 16); - break; - default: - break; + // Reset lightship + for (int i = 0; i < facilities.lightship.path_history_len; ++i) { + free(facilities.lightship.path_history[i]); } - } + facilities.lightship.path_history_len = 0; - facilities.id.change.stage = ID_CHANGE_INACTIVE; + facilities.lightship.t_last_cam = 0; + facilities.lightship.t_last_cam_lfc = 0; + facilities.lightship.next_cam_max = 0; + facilities.lightship.next_cam_min = 0; - pthread_mutex_unlock(&facilities.id.lock); + pthread_mutex_unlock(&facilities.lightship.lock); - id_changed = true; + // Change Station ID + for (int i = 0; i < si->choice.idChangeEvent.ids.list.count; ++i) { + switch (si->choice.idChangeEvent.ids.list.array[i]->present) { + case SecurityId_PR_stationId: + facilities.id.station_id = si->choice.idChangeEvent.ids.list.array[i]->choice.stationId; + break; + case SecurityId_PR_ipv6Address: + memcpy(facilities.id.ipv6_addr, si->choice.idChangeEvent.ids.list.array[i]->choice.ipv6Address.buf, 16); + break; + default: + break; + } + } - break; + facilities.id.change.stage = ID_CHANGE_INACTIVE; - case SecurityIdChangeEventType_abort: - pthread_mutex_unlock(&facilities.id.lock); - pthread_mutex_unlock(&facilities.lightship.lock); + pthread_mutex_unlock(&facilities.id.lock); - facilities.id.change.stage = ID_CHANGE_INACTIVE; - break; + id_changed = true; - default: - pthread_mutex_unlock(&facilities.id.change.lock); - log_error("[networking]<- unhandled idChangeEvent command type"); - rv = 1; - goto cleanup; + break; + + case SecurityIdChangeEventType_abort: + pthread_mutex_unlock(&facilities.id.lock); + pthread_mutex_unlock(&facilities.lightship.lock); + + facilities.id.change.stage = ID_CHANGE_INACTIVE; + break; + + default: + pthread_mutex_unlock(&facilities.id.change.lock); + log_error("[networking]<- unhandled idChangeEvent command type"); + rv = 1; + goto cleanup; } sr->present = SecurityResponse_PR_idChangeEvent; @@ -700,8 +654,7 @@ static int security_indication(void *responder_secured, uint8_t *msg, uint32_t m pthread_mutex_unlock(&facilities.id.change.lock); cleanup: - if (rv) - { + if (rv) { sr->present = SecurityResponse_PR_idChangeEvent; sr->choice.idChangeEvent.returnCode = 1; enc = oer_encode_to_buffer(&asn_DEF_SecurityResponse, NULL, sr, buffer, 64); @@ -715,8 +668,7 @@ cleanup: return rv; } -static int networking_indication(void *responder, uint8_t *msg, uint32_t msg_len) -{ +static int networking_indication(void *responder, uint8_t *msg, uint32_t msg_len) { int rv = 0; uint8_t code = 0; @@ -724,8 +676,7 @@ static int networking_indication(void *responder, uint8_t *msg, uint32_t msg_len NetworkingIndication_t *ni = calloc(1, sizeof(NetworkingIndication_t)); asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_NetworkingIndication, (void **)&ni, msg, msg_len); - if (dec.code) - { + if (dec.code) { rv = 1; code = 1; itss_0send(responder, &code, 1); @@ -733,15 +684,12 @@ static int networking_indication(void *responder, uint8_t *msg, uint32_t msg_len } itss_0send(responder, &code, 1); - if (ni->present != NetworkingIndication_PR_data) - { + if (ni->present != NetworkingIndication_PR_data) { goto cleanup; } if (ni->choice.data.mobileNeighbour && - *ni->choice.data.mobileNeighbour) - { - + *ni->choice.data.mobileNeighbour) { pthread_mutex_lock(&facilities.lightship.lock); facilities.lightship.t_last_vehicle = itss_time_get(); facilities.lightship.is_vehicle_near = true; @@ -754,8 +702,7 @@ cleanup: return rv; } -static int management_indication(void *responder, uint8_t *msg, uint32_t msg_len) -{ +static int management_indication(void *responder, uint8_t *msg, uint32_t msg_len) { int rv = 0; uint8_t code = 0; @@ -763,8 +710,7 @@ static int management_indication(void *responder, uint8_t *msg, uint32_t msg_len ManagementIndication_t *mi = calloc(1, sizeof(ManagementIndication_t)); asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_ManagementIndication, (void **)&mi, msg, msg_len); - if (dec.code) - { + if (dec.code) { rv = 1; code = 1; itss_0send(responder, &code, 1); @@ -772,8 +718,7 @@ static int management_indication(void *responder, uint8_t *msg, uint32_t msg_len } itss_0send(responder, &code, 1); - if (mi->present == ManagementIndication_PR_attributes) - { + if (mi->present == ManagementIndication_PR_attributes) { itss_space_lock(); epv.space.latitude = mi->choice.attributes.coordinates.latitude; epv.space.latitude_conf = mi->choice.attributes.coordinates.latitudeConfidence; @@ -789,11 +734,9 @@ static int management_indication(void *responder, uint8_t *msg, uint32_t msg_len itss_space_unlock(); itss_trajectory_lock(); - if (mi->choice.attributes.trajectory) - { + if (mi->choice.attributes.trajectory) { epv.trajectory.len = mi->choice.attributes.trajectory->list.count; - for (int i = 0; i < mi->choice.attributes.trajectory->list.count; ++i) - { + for (int i = 0; i < mi->choice.attributes.trajectory->list.count; ++i) { epv.trajectory.path[i].latitude = mi->choice.attributes.trajectory->list.array[i]->latitude; epv.trajectory.path[i].longitude = mi->choice.attributes.trajectory->list.array[i]->longitude; asn_INTEGER2ulong(&mi->choice.attributes.trajectory->list.array[i]->timestamp, (unsigned long long *)&epv.trajectory.path[i].timestamp); @@ -812,8 +755,7 @@ cleanup: return rv; } -void *tx() -{ +void *tx() { int rv = 0; itss_queue_t *queue = facilities.tx_queue; @@ -825,15 +767,12 @@ void *tx() itss_queue_t *stream = itss_queue_new(); - while (!facilities.exit) - { + while (!facilities.exit) { pthread_mutex_lock(&queue->lock); - while (!queue->len && !facilities.exit) - { + while (!queue->len && !facilities.exit) { pthread_cond_wait(&queue->trigger, &queue->lock); } - for (int i = 0; i < queue->len; ++i) - { + for (int i = 0; i < queue->len; ++i) { memcpy(stream->packet[i], queue->packet[i], queue->packet_len[i]); stream->packet_len[i] = queue->packet_len[i]; stream->destination[i] = queue->destination[i]; @@ -845,41 +784,36 @@ void *tx() queue->len = 0; pthread_mutex_unlock(&queue->lock); - for (int i = 0; i < stream->len; ++i) - { - switch (stream->destination[i]) - { - case ITSS_TRANSPORT: - log_debug("-> %s ->[transport] | id:%08x size:%dB", - stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); - itss_0send(transport_socket, stream->packet[i], stream->packet_len[i]); - rv = itss_0recv_rt(&transport_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); - if (rv == -1) - { - log_error("-> %s ->[transport] | id:%08x size:%dB ", + for (int i = 0; i < stream->len; ++i) { + switch (stream->destination[i]) { + case ITSS_TRANSPORT: + log_debug("-> %s ->[transport] | id:%08x size:%dB", stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); - } - break; - case ITSS_APPLICATIONS: - log_debug("-> %s ->[applications] | id:%08x size:%dB", - stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); - itss_0send(applications_socket, stream->packet[i], stream->packet_len[i]); - rv = itss_0recv_rt(&applications_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); - if (rv == -1) - { - log_error("-> %s ->[applications] | id:%08x size:%dB ", + itss_0send(transport_socket, stream->packet[i], stream->packet_len[i]); + rv = itss_0recv_rt(&transport_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); + if (rv == -1) { + log_error("-> %s ->[transport] | id:%08x size:%dB ", + stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); + } + break; + case ITSS_APPLICATIONS: + log_debug("-> %s ->[applications] | id:%08x size:%dB", stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); - } - break; - case ITSS_MANAGEMENT: - itss_0send(management_socket, stream->packet[i], stream->packet_len[i]); - rv = itss_0recv_rt(&management_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); - if (rv == -1) - { - log_error("-> %s ->[management] | id:%08x size:%dB ", - stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); - } - break; + itss_0send(applications_socket, stream->packet[i], stream->packet_len[i]); + rv = itss_0recv_rt(&applications_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); + if (rv == -1) { + log_error("-> %s ->[applications] | id:%08x size:%dB ", + stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); + } + break; + case ITSS_MANAGEMENT: + itss_0send(management_socket, stream->packet[i], stream->packet_len[i]); + rv = itss_0recv_rt(&management_socket, &code, 1, stream->packet[i], stream->packet_len[i], 1000); + if (rv == -1) { + log_error("-> %s ->[management] | id:%08x size:%dB ", + stream->info_msg[i], (uint32_t)stream->id[i], stream->packet_len[i]); + } + break; } } } @@ -891,8 +825,7 @@ void *tx() return NULL; } -static void sigh(int signum) -{ +static void sigh(int signum) { facilities.exit = true; uint8_t code = 0; void *socket = itss_0connect(ZMQ_INTERNAL_ADDR, ZMQ_PAIR); @@ -900,8 +833,7 @@ static void sigh(int signum) itss_0close(socket); } -int main() -{ +int main() { signal(SIGTERM, sigh); signal(SIGINT, sigh); signal(SIGKILL, sigh); @@ -914,8 +846,7 @@ int main() bulletin_init(); void *security_socket = NULL; - if (facilities_config()) - { + if (facilities_config()) { goto cleanup; } @@ -944,8 +875,7 @@ int main() tolling_init(facilities.station_type); // VC - if (facilities.coordination.active) - { + if (facilities.coordination.active) { coordination_init(); pthread_create(&facilities.vc_service, NULL, vc_service, NULL); } @@ -963,89 +893,77 @@ int main() int32_t rl; - while (!facilities.exit) - { + while (!facilities.exit) { itss_0poll(facilities.zmq.responders, facilities.zmq.n_responders, -1); - for (int i = 0; i < facilities.zmq.n_responders; ++i) - { - if (facilities.zmq.responders[i].revents) - { + for (int i = 0; i < facilities.zmq.n_responders; ++i) { + if (facilities.zmq.responders[i].revents) { rl = itss_0recv(facilities.zmq.responders[i].socket, buffer, ITSS_SDU_MAX_LEN); - switch (buffer[0]) - { /* source */ + switch (buffer[0]) { /* source */ - case ITSS_INTERNAL: - break; + case ITSS_INTERNAL: + break; - case ITSS_NETWORKING: - networking_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); - break; - - case ITSS_TRANSPORT: - in_idchange = true; - pthread_mutex_lock(&facilities.id.change.lock); - if (facilities.id.change.stage == ID_CHANGE_INACTIVE) - { - in_idchange = false; - facilities.id.change.stage = ID_CHANGE_BLOCKED; - } - pthread_mutex_unlock(&facilities.id.change.lock); - - if (!in_idchange) - { - transport_indication(facilities.zmq.responders[i].socket, &security_socket, buffer + 1, rl); + case ITSS_NETWORKING: + networking_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); + break; + case ITSS_TRANSPORT: + in_idchange = true; pthread_mutex_lock(&facilities.id.change.lock); - facilities.id.change.stage = ID_CHANGE_INACTIVE; + if (facilities.id.change.stage == ID_CHANGE_INACTIVE) { + in_idchange = false; + facilities.id.change.stage = ID_CHANGE_BLOCKED; + } pthread_mutex_unlock(&facilities.id.change.lock); - } - else - { + + if (!in_idchange) { + transport_indication(facilities.zmq.responders[i].socket, &security_socket, buffer + 1, rl); + + pthread_mutex_lock(&facilities.id.change.lock); + facilities.id.change.stage = ID_CHANGE_INACTIVE; + pthread_mutex_unlock(&facilities.id.change.lock); + } else { + code = 1; + itss_0send(facilities.zmq.responders[i].socket, &code, 1); + } + break; + + case ITSS_APPLICATIONS: + in_idchange = true; + pthread_mutex_lock(&facilities.id.change.lock); + if (facilities.id.change.stage == ID_CHANGE_INACTIVE) { + in_idchange = false; + facilities.id.change.stage = ID_CHANGE_BLOCKED; + } + pthread_mutex_unlock(&facilities.id.change.lock); + + if (!in_idchange) { + facilities_request(facilities.zmq.responders[i].socket, buffer + 1, rl); + + pthread_mutex_lock(&facilities.id.change.lock); + facilities.id.change.stage = ID_CHANGE_INACTIVE; + pthread_mutex_unlock(&facilities.id.change.lock); + } else { + code = 1; + itss_0send(facilities.zmq.responders[i].socket, &code, 1); + } + + break; + + case ITSS_MANAGEMENT: + management_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); + break; + + case ITSS_SECURITY: + security_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); + break; + + default: + log_debug("<- unrecognized service"); code = 1; itss_0send(facilities.zmq.responders[i].socket, &code, 1); - } - break; - - case ITSS_APPLICATIONS: - in_idchange = true; - pthread_mutex_lock(&facilities.id.change.lock); - if (facilities.id.change.stage == ID_CHANGE_INACTIVE) - { - in_idchange = false; - facilities.id.change.stage = ID_CHANGE_BLOCKED; - } - pthread_mutex_unlock(&facilities.id.change.lock); - - if (!in_idchange) - { - facilities_request(facilities.zmq.responders[i].socket, buffer + 1, rl); - - pthread_mutex_lock(&facilities.id.change.lock); - facilities.id.change.stage = ID_CHANGE_INACTIVE; - pthread_mutex_unlock(&facilities.id.change.lock); - } - else - { - code = 1; - itss_0send(facilities.zmq.responders[i].socket, &code, 1); - } - - break; - - case ITSS_MANAGEMENT: - management_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); - break; - - case ITSS_SECURITY: - security_indication(facilities.zmq.responders[i].socket, buffer + 1, rl); - break; - - default: - log_debug("<- unrecognized service"); - code = 1; - itss_0send(facilities.zmq.responders[i].socket, &code, 1); - continue; + continue; } } } @@ -1066,8 +984,7 @@ cleanup: pthread_join(facilities.vc_service, NULL); itss_0close(security_socket); - for (int i = 0; i < facilities.zmq.n_responders; ++i) - { + for (int i = 0; i < facilities.zmq.n_responders; ++i) { itss_0close(facilities.zmq.responders[i].socket); } itss_0destroy(); diff --git a/src/requests.c b/src/requests.c index a012275..e3ff66a 100644 --- a/src/requests.c +++ b/src/requests.c @@ -1,26 +1,23 @@ -#include "facilities.h" -#include "cam.h" -#include "denm.h" -#include "infrastructure.h" #include "requests.h" -#include "cpm.h" -#include "evm.h" +#include #include #include - -#include -#include #include - -#include -#include #include +#include #include #include +#include -int facilities_request_result_accepted(void *responder) -{ +#include "cam.h" +#include "cpm.h" +#include "denm.h" +#include "evm.h" +#include "facilities.h" +#include "infrastructure.h" + +int facilities_request_result_accepted(void *responder) { int rv = 0; FacilitiesReply_t *fr = calloc(1, sizeof(FacilitiesReply_t)); @@ -34,8 +31,7 @@ int facilities_request_result_accepted(void *responder) return rv; } -int facilities_request_result_rejected(void *responder) -{ +int facilities_request_result_rejected(void *responder) { int rv = 0; FacilitiesReply_t *fr = calloc(1, sizeof(FacilitiesReply_t)); @@ -49,8 +45,7 @@ int facilities_request_result_rejected(void *responder) return rv; } -int facilities_request_single_message(void *responder, FacilitiesMessageRequest_t *frm) -{ +int facilities_request_single_message(void *responder, FacilitiesMessageRequest_t *frm) { int rv = 0; TransportRequest_t *tr = calloc(1, sizeof(TransportRequest_t)); @@ -68,68 +63,66 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ uint32_t transmission_interval = 0; uint64_t transmission_start = 0; - switch (frm->itsMessageType) - { - case ItsMessageType_cam: - its_msg_def = &asn_DEF_CAM; - its_msg = calloc(1, sizeof(CAM_t)); - bpr->destinationPort = Port_cam; - bpr->gn.packetTransportType = PacketTransportType_shb; - bpr->gn.trafficClass = 1; + switch (frm->itsMessageType) { + case ItsMessageType_cam: + its_msg_def = &asn_DEF_CAM; + its_msg = calloc(1, sizeof(CAM_t)); + bpr->destinationPort = Port_cam; + bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->gn.trafficClass = 1; - break; - case ItsMessageType_denm: - its_msg_def = &asn_DEF_DENM; - its_msg = calloc(1, sizeof(DENM_t)); - bpr->destinationPort = Port_denm; - bpr->gn.packetTransportType = PacketTransportType_gbc; - bpr->gn.trafficClass = 2; + break; + case ItsMessageType_denm: + its_msg_def = &asn_DEF_DENM; + its_msg = calloc(1, sizeof(DENM_t)); + bpr->destinationPort = Port_denm; + bpr->gn.packetTransportType = PacketTransportType_gbc; + bpr->gn.trafficClass = 2; - break; - case ItsMessageType_ivim: - its_msg_def = &asn_DEF_IVIM; - its_msg = calloc(1, sizeof(IVIM_t)); - bpr->destinationPort = Port_ivim; - bpr->gn.packetTransportType = PacketTransportType_shb; - bpr->gn.trafficClass = 1; + break; + case ItsMessageType_ivim: + its_msg_def = &asn_DEF_IVIM; + its_msg = calloc(1, sizeof(IVIM_t)); + bpr->destinationPort = Port_ivim; + bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->gn.trafficClass = 1; - break; + break; - case ItsMessageType_cpm: - its_msg_def = &asn_DEF_CPM; - its_msg = calloc(1, sizeof(CPM_t)); - bpr->destinationPort = Port_cpm; - bpr->gn.packetTransportType = PacketTransportType_shb; - bpr->gn.trafficClass = 2; + case ItsMessageType_cpm: + its_msg_def = &asn_DEF_CPM; + its_msg = calloc(1, sizeof(CPM_t)); + bpr->destinationPort = Port_cpm; + bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->gn.trafficClass = 2; - break; + break; - case 2044: // VERCOe - its_msg_def = &asn_DEF_VERCOe; - its_msg = calloc(1, sizeof(VERCOe_t)); - bpr->destinationPort = 2044; - bpr->gn.packetTransportType = PacketTransportType_shb; - bpr->gn.trafficClass = 2; - break; + case 2044: // VERCOe + its_msg_def = &asn_DEF_VERCOe; + its_msg = calloc(1, sizeof(VERCOe_t)); + bpr->destinationPort = 2044; + bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->gn.trafficClass = 2; + break; - case ItsMessageType_evrsr: - its_msg_def = &asn_DEF_EV_RSR; - its_msg = calloc(1, sizeof(EV_RSR_t)); - bpr->destinationPort = Port_evrsr; - bpr->gn.packetTransportType = PacketTransportType_shb; - bpr->gn.trafficClass = 1; - break; + case ItsMessageType_evrsr: + its_msg_def = &asn_DEF_EV_RSR; + its_msg = calloc(1, sizeof(EV_RSR_t)); + bpr->destinationPort = Port_evrsr; + bpr->gn.packetTransportType = PacketTransportType_shb; + bpr->gn.trafficClass = 1; + break; - default: - log_error("unrecognized FR message type (%lld)", frm->itsMessageType); - facilities_request_result_rejected(responder); - rv = 1; - goto cleanup; + default: + log_error("unrecognized FR message type (%lld)", frm->itsMessageType); + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; } asn_dec_rval_t dec = uper_decode_complete(NULL, its_msg_def, (void **)&its_msg, frm->data.buf, frm->data.size); - if (dec.code) - { + if (dec.code) { log_debug("invalid FR %s received", its_msg_def->name); facilities_request_result_rejected(responder); rv = 1; @@ -137,20 +130,16 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ } uint64_t id = 0; - if (!frm->id) - { + if (!frm->id) { id = itss_id(frm->data.buf, frm->data.size); - } - else if (*frm->id == 0) - { + } else if (*frm->id == 0) { id = itss_id(frm->data.buf, frm->data.size); } bool is_update = false; int managed_msg = false; - if (frm->itsMessageType == ItsMessageType_denm) - { + if (frm->itsMessageType == ItsMessageType_denm) { managed_msg = true; uint8_t event_type = event_manage(its_msg, &id, NULL, 0); @@ -159,36 +148,27 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ if (event_type != EVENT_NEW && event_type != EVENT_UPDATE && event_type != EVENT_CANCELLATION && - event_type != EVENT_NEGATION) - { - + event_type != EVENT_NEGATION) { fwd = false; } if (event_type == EVENT_UPDATE || event_type == EVENT_CANCELLATION || - event_type == EVENT_NEGATION) - { - + event_type == EVENT_NEGATION) { is_update = true; } - if (fwd) - { + if (fwd) { // set stationID pthread_mutex_lock(&facilities.id.lock); ((DENM_t *)its_msg)->header.stationID = facilities.id.station_id; pthread_mutex_unlock(&facilities.id.lock); // Set only one trace - if (facilities.station_type != 15) - { + if (facilities.station_type != 15) { pthread_mutex_lock(&facilities.lightship.lock); - if (facilities.lightship.path_history_len > 0) - { - - if (!((DENM_t *)its_msg)->denm.location) - { + if (facilities.lightship.path_history_len > 0) { + if (!((DENM_t *)its_msg)->denm.location) { ((DENM_t *)its_msg)->denm.location = calloc(1, sizeof(LocationContainer_t)); } ((DENM_t *)its_msg)->denm.location->traces.list.count = 1; @@ -207,30 +187,21 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ ph->list.array[0] = calloc(1, sizeof(PathPoint_t)); itss_space_lock(); - if (path_history[0]->alt != AltitudeValue_unavailable && epv.space.altitude != AltitudeValue_unavailable) - { + if (path_history[0]->alt != AltitudeValue_unavailable && epv.space.altitude != AltitudeValue_unavailable) { ph->list.array[0]->pathPosition.deltaAltitude = path_history[0]->alt - epv.space.altitude; - } - else - { + } else { ph->list.array[0]->pathPosition.deltaAltitude = DeltaAltitude_unavailable; } - if (path_history[0]->lat != Latitude_unavailable && epv.space.latitude != Latitude_unavailable) - { + if (path_history[0]->lat != Latitude_unavailable && epv.space.latitude != Latitude_unavailable) { ph->list.array[0]->pathPosition.deltaLatitude = path_history[0]->lat - epv.space.latitude; - } - else - { + } else { ph->list.array[0]->pathPosition.deltaLatitude = DeltaLatitude_unavailable; } - if (path_history[0]->lon != Longitude_unavailable && epv.space.longitude != Longitude_unavailable) - { + if (path_history[0]->lon != Longitude_unavailable && epv.space.longitude != Longitude_unavailable) { ph->list.array[0]->pathPosition.deltaLongitude = path_history[0]->lon - epv.space.longitude; - } - else - { + } else { ph->list.array[0]->pathPosition.deltaLongitude = DeltaLongitude_unavailable; } itss_space_unlock(); @@ -238,34 +209,24 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ ph->list.array[0]->pathDeltaTime = calloc(1, sizeof(PathDeltaTime_t)); *ph->list.array[0]->pathDeltaTime = (itss_time_get() - path_history[0]->ts) / 10; - for (int i = 1; i < path_history_len; ++i) - { + for (int i = 1; i < path_history_len; ++i) { ph->list.array[i] = calloc(1, sizeof(PathPoint_t)); - if (path_history[i]->alt != AltitudeValue_unavailable && path_history[i - 1]->alt != AltitudeValue_unavailable) - { + if (path_history[i]->alt != AltitudeValue_unavailable && path_history[i - 1]->alt != AltitudeValue_unavailable) { ph->list.array[i]->pathPosition.deltaAltitude = path_history[i]->alt - path_history[i - 1]->alt; - } - else - { + } else { ph->list.array[i]->pathPosition.deltaAltitude = DeltaAltitude_unavailable; } - if (path_history[i]->lat != Latitude_unavailable && path_history[i - 1]->lat != Latitude_unavailable) - { + if (path_history[i]->lat != Latitude_unavailable && path_history[i - 1]->lat != Latitude_unavailable) { ph->list.array[i]->pathPosition.deltaLatitude = path_history[i]->lat - path_history[i - 1]->lat; - } - else - { + } else { ph->list.array[i]->pathPosition.deltaLatitude = DeltaLatitude_unavailable; } - if (path_history[i]->lon != Longitude_unavailable && path_history[i - 1]->lon != Longitude_unavailable) - { + if (path_history[i]->lon != Longitude_unavailable && path_history[i - 1]->lon != Longitude_unavailable) { ph->list.array[i]->pathPosition.deltaLongitude = path_history[i]->lon - path_history[i - 1]->lon; - } - else - { + } else { ph->list.array[i]->pathPosition.deltaLongitude = DeltaLongitude_unavailable; } @@ -277,23 +238,17 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ } // get, set retransmission, duration - if (((DENM_t *)its_msg)->denm.management.transmissionInterval) - { + if (((DENM_t *)its_msg)->denm.management.transmissionInterval) { transmission_interval = *((uint32_t *)((DENM_t *)its_msg)->denm.management.transmissionInterval); - if (((DENM_t *)its_msg)->denm.management.validityDuration) - { + if (((DENM_t *)its_msg)->denm.management.validityDuration) { transmission_duration = *((uint32_t *)((DENM_t *)its_msg)->denm.management.validityDuration) * 1000; - } - else - { + } else { transmission_duration = 600 * 1000; } } } - } - else if (frm->itsMessageType == ItsMessageType_ivim) - { + } else if (frm->itsMessageType == ItsMessageType_ivim) { managed_msg = true; uint8_t service_type = service_eval(SERVICE_IVI, its_msg, &id, NULL, 0); @@ -301,39 +256,28 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ if (service_type != SERVICE_NEW && service_type != SERVICE_UPDATE && service_type != SERVICE_CANCELLATION && - service_type != SERVICE_NEGATION) - { - + service_type != SERVICE_NEGATION) { fwd = false; } if (service_type == SERVICE_UPDATE || service_type == SERVICE_CANCELLATION || - service_type == SERVICE_NEGATION) - { - + service_type == SERVICE_NEGATION) { is_update = true; } - if (fwd) - { + if (fwd) { uint64_t valid_to, valid_from; - if (!((IVIM_t *)its_msg)->ivi.mandatory.validFrom) - { + if (!((IVIM_t *)its_msg)->ivi.mandatory.validFrom) { valid_from = itss_time_get(); - } - else - { + } else { asn_INTEGER2ulong((INTEGER_t *)((IVIM_t *)its_msg)->ivi.mandatory.validFrom, (unsigned long long *)&valid_from); } - if (!((IVIM_t *)its_msg)->ivi.mandatory.validTo) - { + if (!((IVIM_t *)its_msg)->ivi.mandatory.validTo) { valid_to = valid_from + facilities.infrastructure.default_service_duration; - } - else - { + } else { asn_INTEGER2ulong((INTEGER_t *)((IVIM_t *)its_msg)->ivi.mandatory.validTo, (unsigned long long *)&valid_to); } @@ -341,12 +285,10 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ transmission_interval = facilities.infrastructure.replay_interval; transmission_duration = valid_to - valid_from; } - } - else if (frm->itsMessageType == ItsMessageType_evrsr) { + } else if (frm->itsMessageType == ItsMessageType_evrsr) { managed_msg = true; } - if (!facilities.replay) - { + if (!facilities.replay) { transmission_interval = 0; transmission_duration = 0; } @@ -355,16 +297,14 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ facilities_request_result_accepted(responder); // Forward message to [transport] - if (fwd) - { + if (fwd) { bpr->btpType = BTPType_btpB; bpr->id = id; bpr->data.buf = malloc(2048); asn_enc_rval_t enc = uper_encode_to_buffer(its_msg_def, NULL, its_msg, bpr->data.buf, 2048); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding ITS message into UPER (%s)", enc.failed_type->name); rv = 1; goto cleanup; @@ -376,26 +316,22 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ bpr->gn.destinationAddress.buf[i] = 0xff; bpr->gn.destinationAddress.size = 6; - if (transmission_start) - { + if (transmission_start) { bpr->gn.repetitionStart = malloc(sizeof(long)); *bpr->gn.repetitionStart = transmission_start; } - if (transmission_interval) - { + if (transmission_interval) { bpr->gn.repetitionInterval = malloc(sizeof(long)); *bpr->gn.repetitionInterval = transmission_interval; } - if (transmission_duration) - { + if (transmission_duration) { bpr->gn.maximumRepetitionTime = malloc(sizeof(long)); *bpr->gn.maximumRepetitionTime = transmission_duration; } - if (is_update) - { + if (is_update) { bpr->gn.isUpdate = malloc(sizeof(long)); *bpr->gn.isUpdate = 1; } @@ -403,10 +339,9 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ bpr->gn.securityProfile.sign = true; uint8_t tr_oer[2048]; - tr_oer[0] = 4; // [facilities] service id + tr_oer[0] = 4; // [facilities] service id enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, tr_oer + 1, 2047); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding TR (%s)", enc.failed_type->name); rv = 1; goto cleanup; @@ -416,8 +351,7 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ } // Logging - if (facilities.logging.recorder) - { + if (facilities.logging.recorder) { uint16_t buffer_len = 2048; uint8_t buffer[buffer_len]; int e = itss_management_record_packet_sdu( @@ -429,8 +363,7 @@ int facilities_request_single_message(void *responder, FacilitiesMessageRequest_ itss_time_get(), ITSS_FACILITIES, true); - if (e != -1) - { + if (e != -1) { itss_queue_send(facilities.tx_queue, buffer, e, ITSS_MANAGEMENT, id, "MReq.packet.set"); } } @@ -443,8 +376,7 @@ cleanup: return rv; } -int facilities_request_active_episodes(void *responder, FacilitiesRequest_t *freq) -{ +int facilities_request_active_episodes(void *responder, FacilitiesRequest_t *freq) { int rv = 0; FacilitiesReply_t *frep = calloc(1, sizeof(FacilitiesReply_t)); @@ -461,16 +393,14 @@ int facilities_request_active_episodes(void *responder, FacilitiesRequest_t *fre uint16_t na = 0; - for (int e = 0; e < freq->choice.data.choice.activeEpisodes.list.count; ++e) - { - switch (*freq->choice.data.choice.activeEpisodes.list.array[e]) - { - case EpisodeType_denm: - na += nae; - break; - case EpisodeType_ivim: - na += nas; - break; + for (int e = 0; e < freq->choice.data.choice.activeEpisodes.list.count; ++e) { + switch (*freq->choice.data.choice.activeEpisodes.list.array[e]) { + case EpisodeType_denm: + na += nae; + break; + case EpisodeType_ivim: + na += nas; + break; } } @@ -478,60 +408,52 @@ int facilities_request_active_episodes(void *responder, FacilitiesRequest_t *fre frep->choice.data.choice.episodes.list.size = na * sizeof(void *); frep->choice.data.choice.episodes.list.array = malloc(na * sizeof(void *)); - for (int e = 0, j = 0; e < freq->choice.data.choice.activeEpisodes.list.count; ++e) - { - switch (*freq->choice.data.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) - { - frep->choice.data.choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); - frep->choice.data.choice.episodes.list.array[j]->itsMessageType = ItsMessageType_denm; - frep->choice.data.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, frep->choice.data.choice.episodes.list.array[j]->data.buf, 2048); - if (enc.encoded == -1) - { /* encoding shouldn't fail as all saved DENMs are structurally valid */ - log_error("failed encoding DENM for FDResult (%s)", enc.failed_type->name); - frep->choice.data.choice.episodes.list.array[j]->data.size = 0; - continue; + for (int e = 0, j = 0; e < freq->choice.data.choice.activeEpisodes.list.count; ++e) { + switch (*freq->choice.data.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) { + frep->choice.data.choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); + frep->choice.data.choice.episodes.list.array[j]->itsMessageType = ItsMessageType_denm; + frep->choice.data.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, frep->choice.data.choice.episodes.list.array[j]->data.buf, 2048); + if (enc.encoded == -1) { /* encoding shouldn't fail as all saved DENMs are structurally valid */ + log_error("failed encoding DENM for FDResult (%s)", enc.failed_type->name); + frep->choice.data.choice.episodes.list.array[j]->data.size = 0; + continue; + } + frep->choice.data.choice.episodes.list.array[j]->data.size = (enc.encoded + 7) / 8; + ++j; + ++n; } - frep->choice.data.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) - { - frep->choice.data.choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); - frep->choice.data.choice.episodes.list.array[j]->itsMessageType = ItsMessageType_ivim; - frep->choice.data.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, frep->choice.data.choice.episodes.list.array[j]->data.buf, 2048); - if (enc.encoded == -1) - { /* encoding shouldn't fail as all saved DENMs are structurally valid */ - log_error("failed encoding IVIM for FDResult (%s)", enc.failed_type->name); - frep->choice.data.choice.episodes.list.array[j]->data.size = 0; - continue; + 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) { + frep->choice.data.choice.episodes.list.array[j] = calloc(1, sizeof(ItsMessage_t)); + frep->choice.data.choice.episodes.list.array[j]->itsMessageType = ItsMessageType_ivim; + frep->choice.data.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, frep->choice.data.choice.episodes.list.array[j]->data.buf, 2048); + if (enc.encoded == -1) { /* encoding shouldn't fail as all saved DENMs are structurally valid */ + log_error("failed encoding IVIM for FDResult (%s)", enc.failed_type->name); + frep->choice.data.choice.episodes.list.array[j]->data.size = 0; + continue; + } + frep->choice.data.choice.episodes.list.array[j]->data.size = (enc.encoded + 7) / 8; + ++j; + ++n; } - frep->choice.data.choice.episodes.list.array[j]->data.size = (enc.encoded + 7) / 8; - ++j; - ++n; } - } - break; - default: - log_error("unrecognized FR event type (%lld)", *freq->choice.data.choice.activeEpisodes.list.array[e]); - pthread_mutex_unlock(&facilities.den.lock); - pthread_mutex_unlock(&facilities.infrastructure.lock); + break; + default: + log_error("unrecognized FR event type (%lld)", *freq->choice.data.choice.activeEpisodes.list.array[e]); + pthread_mutex_unlock(&facilities.den.lock); + pthread_mutex_unlock(&facilities.infrastructure.lock); - facilities_request_result_rejected(responder); - rv = 1; - goto cleanup; + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; } } @@ -540,8 +462,7 @@ int facilities_request_active_episodes(void *responder, FacilitiesRequest_t *fre frep_oer = malloc(32768); asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesReply, NULL, frep, frep_oer, 32768); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding FReply (%s)", enc.failed_type->name); facilities_request_result_rejected(responder); @@ -558,8 +479,7 @@ cleanup: return rv; } -int facilities_request_attribute_types(void *responder, FacilitiesRequest_t *freq) -{ +int facilities_request_attribute_types(void *responder, FacilitiesRequest_t *freq) { int rv = 0; FacilitiesReply_t *frep = calloc(1, sizeof(FacilitiesReply_t)); @@ -570,30 +490,27 @@ int facilities_request_attribute_types(void *responder, FacilitiesRequest_t *fre frep->choice.data.choice.attributes.list.count = nra; frep->choice.data.choice.attributes.list.size = sizeof(void *) * nra; frep->choice.data.choice.attributes.list.array = malloc(sizeof(void *) * nra); - for (int j = 0; j < nra; ++j) - { - switch (*freq->choice.data.choice.attributeTypes.list.array[j]) - { - case FacilitiesAttributeType_stationId: - frep->choice.data.choice.attributes.list.array[j] = calloc(1, sizeof(FacilitiesAttribute_t)); - frep->choice.data.choice.attributes.list.array[j]->data.size = 8; - frep->choice.data.choice.attributes.list.array[j]->data.buf = malloc(8); - pthread_mutex_lock(&facilities.id.lock); - *((uint64_t *)frep->choice.data.choice.attributes.list.array[j]->data.buf) = facilities.id.station_id; - pthread_mutex_unlock(&facilities.id.lock); - break; + for (int j = 0; j < nra; ++j) { + switch (*freq->choice.data.choice.attributeTypes.list.array[j]) { + case FacilitiesAttributeType_stationId: + frep->choice.data.choice.attributes.list.array[j] = calloc(1, sizeof(FacilitiesAttribute_t)); + frep->choice.data.choice.attributes.list.array[j]->data.size = 8; + frep->choice.data.choice.attributes.list.array[j]->data.buf = malloc(8); + pthread_mutex_lock(&facilities.id.lock); + *((uint64_t *)frep->choice.data.choice.attributes.list.array[j]->data.buf) = facilities.id.station_id; + pthread_mutex_unlock(&facilities.id.lock); + break; - default: - log_debug("unrecognized FR attribute type request"); - facilities_request_result_rejected(responder); - rv = 1; - goto cleanup; + default: + log_debug("unrecognized FR attribute type request"); + facilities_request_result_rejected(responder); + rv = 1; + goto cleanup; } } uint8_t frep_oer[256]; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesReply, NULL, frep, frep_oer, 256); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding FReply (%s)", enc.failed_type->name); facilities_request_result_rejected(responder); rv = 1; @@ -608,8 +525,7 @@ cleanup: return rv; } -int facilities_request_loaded_protected_zones(void *responder, FacilitiesRequest_t *freq) -{ +int facilities_request_loaded_protected_zones(void *responder, FacilitiesRequest_t *freq) { int rv = 0; FacilitiesReply_t *frep = calloc(1, sizeof(FacilitiesReply_t)); @@ -624,8 +540,7 @@ int facilities_request_loaded_protected_zones(void *responder, FacilitiesRequest frep->choice.data.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) - { + for (int z = 0; z < facilities.lightship.protected_zones.pz_len; ++z) { frep->choice.data.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 **)&frep->choice.data.choice.protectedCommunicationZones.list.array[z], buf, (enc.encoded + 7) / 8); @@ -635,8 +550,7 @@ int facilities_request_loaded_protected_zones(void *responder, FacilitiesRequest uint8_t frep_oer[1024]; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesReply, NULL, frep, frep_oer, 1024); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding FDResult (%s)", enc.failed_type->name); facilities_request_result_rejected(responder); rv = 1; @@ -651,14 +565,12 @@ cleanup: return rv; } -int facilities_request_chaininfo_set(void *responder, ChainInformationSet_t *cis) -{ +int facilities_request_chaininfo_set(void *responder, ChainInformationSet_t *cis) { int rv = 0; pthread_mutex_lock(&facilities.coordination.lock); facilities.coordination.chain.id = cis->idSet; - for (int i = 0; i < cis->linkSet.list.count; ++i) - { + for (int i = 0; i < cis->linkSet.list.count; ++i) { memcpy( facilities.coordination.chain.links[i], cis->linkSet.list.array[i]->buf, @@ -675,8 +587,7 @@ int facilities_request_chaininfo_set(void *responder, ChainInformationSet_t *cis uint8_t frep_oer[1024]; asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesReply, NULL, frep, frep_oer, 1024); - if (enc.encoded == -1) - { + if (enc.encoded == -1) { log_error("failed encoding FDResult (%s)", enc.failed_type->name); facilities_request_result_rejected(responder); rv = 1;