diff --git a/src/tpm.c b/src/tpm.c index 23cafa8..cd34e3b 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -687,6 +687,50 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tpm->tpm->referencePosition.positionConfidenceEllipse.semiMajorOrientation = 900; } + // Client management + for (int i = 0 ; i < tolling->station.rsu.clients_len; ++i) { + if (itss_time_get() > tolling->station.rsu.clients[i]->ts + TOLLING_CLIENT_LIFETIME_MS) { + free(tolling->station.rsu.clients[i]); + tolling->station.rsu.clients[i] = NULL; + for (int j = i; j < tolling->station.rsu.clients_len-1; ++j) { + tolling->station.rsu.clients[j] = tolling->station.rsu.clients[j+1]; + } + --tolling->station.rsu.clients_len; + } + } + + // Find client + toll_client_t* client = NULL; + for (int i = 0; i < tolling->station.rsu.clients_len; ++i) { + if (tolling->station.rsu.clients[i]->id == client_id) { + client = tolling->station.rsu.clients[i]; + } + } + + // Create client + if (!client) { + if (tolling->station.rsu.clients_len-1 >= TOLLING_MAX_CLIENTS) { + syslog_err("[facilities] [tolling] max clients reached"); + goto cleanup; + } + tolling->station.rsu.clients[tolling->station.rsu.clients_len] = malloc(sizeof(toll_client_t)); + client = tolling->station.rsu.clients[tolling->station.rsu.clients_len]; + client->id = client_id; + client->station_id = tpm_rx->header.stationID; + client->ts = itss_time_get(); + client->accepted = -1; + } + + uint8_t confirmation_code = TollingConfirmationCode_rejected; + if (itss_time_get() > client->ts + TOLLING_PAYMENT_MIN_PERIOD_MS || + client->accepted == -1) { + confirmation_code = TollingConfirmationCode_accepted; + client->accepted = true; + } else if (client->accepted && + itss_time_get() < client->ts + TOLLING_PAYMENT_MIN_PERIOD_MS) { + confirmation_code = TollingConfirmationCode_alreadyAccepted; + } + tpm->tpm->tollingType = calloc(1, sizeof(TollingType_t)); switch (tpm_rx->tpm->tollingType->present) { case TollingType_PR_entry: @@ -695,7 +739,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tpm->tpm->tollingType->choice.entry.choice.reply.clientId = client_id; tpm->tpm->tollingType->choice.entry.choice.reply.infoId = info_id; tpm->tpm->tollingType->choice.entry.choice.reply.transactionNonce = nonce; - tpm->tpm->tollingType->choice.entry.choice.reply.confirmationCode = TollingConfirmationCode_accepted; + tpm->tpm->tollingType->choice.entry.choice.reply.confirmationCode = confirmation_code; break; case TollingType_PR_exit: tpm->tpm->tollingType->present = TollingType_PR_exit; @@ -704,7 +748,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tpm->tpm->tollingType->choice.exit->choice.reply.clientId = client_id; tpm->tpm->tollingType->choice.exit->choice.reply.infoId = info_id; tpm->tpm->tollingType->choice.exit->choice.reply.transactionNonce = nonce; - tpm->tpm->tollingType->choice.exit->choice.reply.confirmationCode = TollingConfirmationCode_accepted; + tpm->tpm->tollingType->choice.exit->choice.reply.confirmationCode = confirmation_code; break; case TollingType_PR_single: tpm->tpm->tollingType->present = TollingType_PR_single; @@ -712,7 +756,7 @@ static void rsu_handle_recv(facilities_t* facilities, TPM_t* tpm_rx, void* secur tpm->tpm->tollingType->choice.single.choice.reply.clientId = client_id; tpm->tpm->tollingType->choice.single.choice.reply.infoId = info_id; tpm->tpm->tollingType->choice.single.choice.reply.transactionNonce = nonce; - tpm->tpm->tollingType->choice.single.choice.reply.confirmationCode = TollingConfirmationCode_accepted; + tpm->tpm->tollingType->choice.single.choice.reply.confirmationCode = confirmation_code; break; default: break; @@ -1290,6 +1334,9 @@ int tolling_init(tolling_t* tolling, void* zmq_ctx, char* security_address, uint switch (station_type) { case 15: + for (int i = 0; i < TOLLING_MAX_CLIENTS; ++i) { + tolling->station.rsu.clients[i] = NULL; + } break; default: tolling->station.obu.toll_type = -1; diff --git a/src/tpm.h b/src/tpm.h index 9ab6dab..74525eb 100644 --- a/src/tpm.h +++ b/src/tpm.h @@ -12,6 +12,8 @@ #define TOLLING_CONN_TIMEOUT_MS 10000 #define TOLLING_RT_PERIOD_MS 400 #define TOLLING_RT_TIMEOUT_MS 10000 +#define TOLLING_MAX_CLIENTS 256 +#define TOLLING_CLIENT_LIFETIME_MS 300000 typedef enum TOLLING_PROTOCOL { TOLLING_PROTOCOL_SIMPLE, @@ -41,6 +43,13 @@ typedef struct tlsc { uint16_t nmsg; } tlsc_t; +typedef struct toll_client { + uint64_t station_id; + uint64_t id; + uint64_t ts; + int8_t accepted; +} toll_client_t; + typedef struct tolling { bool enabled; pthread_mutex_t lock; @@ -63,6 +72,8 @@ typedef struct tolling { union { // RSU struct { + toll_client_t* clients[TOLLING_MAX_CLIENTS]; + uint16_t clients_len; } rsu; // OBU