Handle incoming SAEM various tolling protocols

This commit is contained in:
emanuel 2021-12-13 16:51:36 +00:00
parent 24d88ec84d
commit ea77c982ba
2 changed files with 119 additions and 12 deletions

124
src/sa.c
View File

@ -6,6 +6,8 @@
#include <itss-transport/TransportRequest.h> #include <itss-transport/TransportRequest.h>
#include <itss-security/SecurityRequest.h> #include <itss-security/SecurityRequest.h>
#include <itss-security/SecurityReply.h> #include <itss-security/SecurityReply.h>
#include <saem/per_encoder.h>
#include <tpm/TollingPaymentInfo.h>
#include <saem/SAEM.h> #include <saem/SAEM.h>
#include <syslog.h> #include <syslog.h>
@ -44,6 +46,8 @@ SAEM_CODE_R saem_check(void* fc, bulletin_t* bulletin, SAEM_t* saem) {
int index = -1; int index = -1;
for (int a = 0; a < bulletin->to_consume_len; ++a) { 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 */ /* Check existence through stationID and itsAid */
if (saem->header.stationID == bulletin->to_consume[a]->station_id && if (saem->header.stationID == bulletin->to_consume[a]->station_id &&
its_aid == bulletin->to_consume[a]->its_aid) { 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) { if (si->chOptions.extensions) {
for (int e = 0; e < si->chOptions.extensions->list.count; ++e) { for (int e = 0; e < si->chOptions.extensions->list.count; ++e) {
switch (si->chOptions.extensions->list.array[e]->present) { 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: 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); memcpy(bulletin->to_consume[bulletin->to_consume_len]->endpoint.ipv6_addr, si->chOptions.extensions->list.array[e]->choice.addressIPv6.buf, 16);
break; 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 mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) {
int rv = 0; int rv = 0;
TollingPaymentInfo_t* tpi = NULL;
asn_enc_rval_t enc;
SAEM_t* saem = calloc(1, sizeof(SAEM_t)); SAEM_t* saem = calloc(1, sizeof(SAEM_t));
/* header */ /* 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 = calloc(1, sizeof(ServiceInfoExts_t));
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.count = 2; ServiceInfoExts_t* exts = saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions;
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*));
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t)); switch (facilities->tolling.protocol) {
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->present = ServiceInfoExt_PR_addressIPv6; 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; exts->list.array[0] = calloc(1, sizeof(ServiceInfoExt_t));
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->choice.addressIPv6.buf = malloc(16); exts->list.array[0]->present = ServiceInfoExt_PR_providerServiceContext;
memcpy(saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[0]->choice.addressIPv6.buf, facilities->id.ipv6_addr, 16); 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)); exts->list.array[2] = calloc(1, sizeof(ServiceInfoExt_t));
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[1]->present = ServiceInfoExt_PR_servicePort; exts->list.array[2]->present = ServiceInfoExt_PR_applicationDataSAM;
saem->sam.body.serviceInfos->list.array[i]->chOptions.extensions->list.array[1]->choice.servicePort = 7011; 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); 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) { if (enc.encoded == -1) {
syslog_err("[facilities] [sa] failure to encode SAEM (%s)", enc.failed_type->name); syslog_err("[facilities] [sa] failure to encode SAEM (%s)", enc.failed_type->name);
rv = 1; rv = 1;
@ -163,6 +262,7 @@ int mk_saem(facilities_t* facilities, uint8_t* b_saem, uint32_t* b_saem_len) {
cleanup: cleanup:
ASN_STRUCT_FREE(asn_DEF_SAEM, saem); ASN_STRUCT_FREE(asn_DEF_SAEM, saem);
ASN_STRUCT_FREE(asn_DEF_TollingPaymentInfo, tpi);
return rv; return rv;
} }

View File

@ -15,6 +15,13 @@ typedef struct announcement {
uint16_t port; uint16_t port;
} endpoint; } endpoint;
struct {
uint8_t* context;
uint16_t context_len;
uint8_t* data;
uint16_t data_len;
} info;
uint64_t station_id; uint64_t station_id;
uint64_t timestamp; uint64_t timestamp;