diff --git a/src/sa.c b/src/sa.c index 1c742ae..bd0221c 100644 --- a/src/sa.c +++ b/src/sa.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include @@ -44,6 +46,8 @@ SAEM_CODE_R saem_check(void* fc, bulletin_t* bulletin, SAEM_t* saem) { int index = -1; for (int a = 0; a < bulletin->to_consume_len; ++a) { + // TODO allow different services for same itsAid and stationID + /* Check existence through stationID and itsAid */ if (saem->header.stationID == bulletin->to_consume[a]->station_id && its_aid == bulletin->to_consume[a]->its_aid) { @@ -61,6 +65,24 @@ SAEM_CODE_R saem_check(void* fc, bulletin_t* bulletin, SAEM_t* saem) { if (si->chOptions.extensions) { for (int e = 0; e < si->chOptions.extensions->list.count; ++e) { switch (si->chOptions.extensions->list.array[e]->present) { + case ServiceInfoExt_PR_providerServiceContext: + bulletin->to_consume[bulletin->to_provide_len]->info.context_len = si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size; + bulletin->to_consume[bulletin->to_provide_len]->info.context = malloc(si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size); + memcpy(bulletin->to_consume[bulletin->to_provide_len]->info.context, + si->chOptions.extensions->list.array[e]->choice.providerServiceContext.buf, + si->chOptions.extensions->list.array[e]->choice.providerServiceContext.size + ); + break; + + case ServiceInfoExt_PR_applicationDataSAM: + bulletin->to_consume[bulletin->to_provide_len]->info.data_len = si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size; + bulletin->to_consume[bulletin->to_provide_len]->info.data = malloc(si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size); + memcpy(bulletin->to_consume[bulletin->to_provide_len]->info.data, + si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.buf, + si->chOptions.extensions->list.array[e]->choice.applicationDataSAM.size + ); + break; + case ServiceInfoExt_PR_addressIPv6: memcpy(bulletin->to_consume[bulletin->to_consume_len]->endpoint.ipv6_addr, si->chOptions.extensions->list.array[e]->choice.addressIPv6.buf, 16); break; @@ -110,6 +132,9 @@ void bulletin_init(bulletin_t* bulletin) { int mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) { int rv = 0; + TollingPaymentInfo_t* tpi = NULL; + asn_enc_rval_t enc; + SAEM_t* saem = calloc(1, sizeof(SAEM_t)); /* header */ @@ -134,26 +159,100 @@ int mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) { saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions = calloc(1, sizeof(ServiceInfoExts_t)); - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.count = 2; - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.size = 2 * sizeof(void*); - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array = malloc(2 * sizeof(void*)); + ServiceInfoExts_t* exts = saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions; - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t)); - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->present = ServiceInfoExt_PR_addressIPv6; + switch (facilities->tolling.protocol) { + case TOLLING_PROTOCOL_SIMPLE: + exts->list.count = 3; + exts->list.size = 3 * sizeof(void*); + exts->list.array = malloc(3 * sizeof(void*)); - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->choice.addressIPv6.size = 16; - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->choice.addressIPv6.buf = malloc(16); - memcpy(saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->choice.addressIPv6.buf, facilities->id.ipv6_addr, 16); + exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext; + char ctx_s[] = "tolling:simple"; + exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_s); + exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_s)); + memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_s, strlen(ctx_s)); + exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[1]->present = ServiceInfoExt_PR_servicePort; + exts->list.array[1]->choice.servicePort = 7011; - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t)); - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[1]->present = ServiceInfoExt_PR_servicePort; - saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[1]->choice.servicePort = 7011; + exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[2]->present = ServiceInfoExt_PR_applicationDataSAM; + exts->list.array[2]->choice.applicationDataSAM.buf = malloc(1024); + + if (tpi) ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi); + tpi = calloc(1, sizeof(TollingPaymentInfo_t)); + tpi->fiatInfos = calloc(1, sizeof(FiatInfos_t)); + tpi->fiatInfos->list.count = 1; + tpi->fiatInfos->list.size = 1 * sizeof(void*); + tpi->fiatInfos->list.array = malloc(1 * sizeof(void*)); + tpi->fiatInfos->list.array[0] = calloc(1, sizeof(FiatInfo_t)); + tpi->fiatInfos->list.array[0]->value = 350; + tpi->fiatInfos->list.array[0]->fiatId = FiatId_eur; + + enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, tpi, exts->list.array[2]->choice.applicationDataSAM.buf, 1024); + if (enc.encoded == -1) { + syslog_err("[facilities] [sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name); + rv = 1; + goto cleanup; + } + + exts->list.array[2]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8; + break; + + case TOLLING_PROTOCOL_TLS: + exts->list.count = 4; + exts->list.size = 4 * sizeof(void*); + exts->list.array = malloc(4 * sizeof(void*)); + + exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext; + char ctx_t[] = "tolling:tls"; + exts->list.array[0]->choice.providerServiceContext.size = strlen(ctx_t); + exts->list.array[0]->choice.providerServiceContext.buf = malloc(strlen(ctx_t)); + memcpy(exts->list.array[0]->choice.providerServiceContext.buf, ctx_t, strlen(ctx_t)); + + exts->list.array[1] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[1]->present = ServiceInfoExt_PR_addressIPv6; + exts->list.array[1]->choice.addressIPv6.size = 16; + exts->list.array[1]->choice.addressIPv6.buf = malloc(16); + memcpy(exts->list.array[1]->choice.addressIPv6.buf, facilities->id.ipv6_addr, 16); + + exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[2]->present = ServiceInfoExt_PR_servicePort; + exts->list.array[2]->choice.servicePort = 7011; + + exts->list.array[3] = calloc(1, sizeof(ServiceInfoExt_t)); + exts->list.array[3]->present = ServiceInfoExt_PR_applicationDataSAM; + exts->list.array[3]->choice.applicationDataSAM.buf = malloc(1024); + + if (tpi) ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi); + tpi = calloc(1, sizeof(TollingPaymentInfo_t)); + tpi->fiatInfos = calloc(1, sizeof(FiatInfos_t)); + tpi->fiatInfos->list.count = 1; + tpi->fiatInfos->list.size = 1 * sizeof(void*); + tpi->fiatInfos->list.array = malloc(1 * sizeof(void*)); + tpi->fiatInfos->list.array[0] = calloc(1, sizeof(FiatInfo_t)); + tpi->fiatInfos->list.array[0]->value = 350; + tpi->fiatInfos->list.array[0]->fiatId = FiatId_eur; + + enc = uper_encode_to_buffer(&asn_DEF_TollingPaymentInfo, NULL, tpi, exts->list.array[3]->choice.applicationDataSAM.buf, 1024); + if (enc.encoded == -1) { + syslog_err("[facilities] [sa] failure to encode TollingPaymentInfo (%s)", enc.failed_type->name); + rv = 1; + goto cleanup; + } + + exts->list.array[3]->choice.applicationDataSAM.size = (enc.encoded + 7) / 8; + break; + } } pthread_mutex_unlock(&facilities->id.lock); - asn_enc_rval_t enc = asn_encode_to_buffer(NULL, ATS_UNALIGNED_CANONICAL_PER, &asn_DEF_SAEM, saem, b_saem, *b_saem_len); + enc = asn_encode_to_buffer(NULL, ATS_UNALIGNED_CANONICAL_PER, &asn_DEF_SAEM, saem, b_saem, *b_saem_len); if (enc.encoded == -1) { syslog_err("[facilities] [sa] failure to encode SAEM (%s)", enc.failed_type->name); rv = 1; @@ -163,6 +262,7 @@ int mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) { cleanup: ASN_STRUCT_FREE(asn_DEF_SAEM, saem); + ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi); return rv; } diff --git a/src/sa.h b/src/sa.h index 41ca20f..f37169b 100644 --- a/src/sa.h +++ b/src/sa.h @@ -15,6 +15,13 @@ typedef struct announcement { uint16_t port; } endpoint; + struct { + uint8_t* context; + uint16_t context_len; + uint8_t* data; + uint16_t data_len; + } info; + uint64_t station_id; uint64_t timestamp;