DENM permissions
This commit is contained in:
parent
e55a3782a5
commit
702e4b75cd
|
|
@ -262,7 +262,7 @@ void lightship_reset_timer(lightship_t* lightship) {
|
||||||
pthread_mutex_unlock(&lightship->lock);
|
pthread_mutex_unlock(&lightship->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_cam(void* fc, BTPDataIndication_t *bdi, CAM_t* cam) {
|
int check_cam(void* fc, BTPDataIndication_t *bdi, CAM_t* cam, ServiceSpecificPermissions_t* ssp) {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
lightship_t *lightship = ((facilities_t*) fc)->lightship;
|
lightship_t *lightship = ((facilities_t*) fc)->lightship;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ lightship_t* lightship_init();
|
||||||
int lightship_check(lightship_t *lightship);
|
int lightship_check(lightship_t *lightship);
|
||||||
void lightship_reset_timer(lightship_t *lightship);
|
void lightship_reset_timer(lightship_t *lightship);
|
||||||
|
|
||||||
int check_cam(void* fc, BTPDataIndication_t* bdi, CAM_t* cam);
|
int check_cam(void* fc, BTPDataIndication_t* bdi, CAM_t* cam, ServiceSpecificPermissions_t* ssp);
|
||||||
void* ca_service(void* fc);
|
void* ca_service(void* fc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
77
src/denm.c
77
src/denm.c
|
|
@ -14,7 +14,64 @@
|
||||||
#define syslog_debug(msg, ...)
|
#define syslog_debug(msg, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static enum EVENT_CHECK_RESULT event_check(den_t *den, DENM_t *denm) {
|
|
||||||
|
const cc_ssp_bm_t CC_SSP_BM_MAP[] = {
|
||||||
|
{"trafficCondition", 1, 0x800000},
|
||||||
|
{"accident", 2, 0x400000},
|
||||||
|
{"roadworks", 3, 0x200000},
|
||||||
|
{"adverseWeatherCondition-Adhesion", 6, 0x100000},
|
||||||
|
{"hazardousLocation-SurfaceCondition", 9, 0x080000},
|
||||||
|
{"hazardousLocation-ObstacleOnTheRoad", 10, 0x040000},
|
||||||
|
{"hazardousLocation-AnimalOnTheRoad", 11, 0x020000},
|
||||||
|
{"humanPresenceOnTheRoad", 12, 0x010000},
|
||||||
|
{"wrongWayDriving", 14, 0x008000},
|
||||||
|
{"rescueAndRecoveryWorkInProgress", 15, 0x004000},
|
||||||
|
{"adverseWeatherCondition-ExtremeWeatherCondition", 17, 0x002000},
|
||||||
|
{"adverseWeatherCondition-Visibility", 18, 0x001000},
|
||||||
|
{"adverseWeatherCondition-Precipitation", 19, 0x000800},
|
||||||
|
{"slowVehicle", 26, 0x000400},
|
||||||
|
{"dangerousEndOfQueue", 27, 0x000200},
|
||||||
|
{"vehicleBreakdown", 91, 0x000100},
|
||||||
|
{"postCrash", 92, 0x000080},
|
||||||
|
{"humanProblem", 93, 0x000040},
|
||||||
|
{"stationaryVehicle", 94, 0x000020},
|
||||||
|
{"emergencyVehicleApproaching", 95, 0x000010},
|
||||||
|
{"hazardousLocation-DangerousCurve", 96, 0x000008},
|
||||||
|
{"collisionRisk", 97, 0x000004},
|
||||||
|
{"signalViolation", 98, 0x000002},
|
||||||
|
{"dangerousSituation", 99, 0x000001},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int permissions_check(int cause_code, uint8_t* permissions, uint8_t permissions_len) {
|
||||||
|
/* DENM SSP scheme
|
||||||
|
*
|
||||||
|
* byte | description
|
||||||
|
* ---------------------------------
|
||||||
|
* 0 | SSP version control
|
||||||
|
* 1-3 | Service-specific parameter
|
||||||
|
* 3-40 | Reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (permissions_len < 4) {
|
||||||
|
syslog_debug("[facilities] [den] permissions length too small");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t perms_int = (*((uint32_t*) permissions)) >> 8;
|
||||||
|
|
||||||
|
uint32_t perm_val;
|
||||||
|
for (int i = 0; i < 24; ++i) {
|
||||||
|
if (cause_code == CC_SSP_BM_MAP[i].cause_code) {
|
||||||
|
perm_val = CC_SSP_BM_MAP[i].bitmap_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((perm_val & perms_int) == perm_val) return 1;
|
||||||
|
else return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum EVENT_CHECK_RESULT event_check(den_t *den, DENM_t *denm, ServiceSpecificPermissions_t* ssp) {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
uint64_t e_detection_time, e_reference_time;
|
uint64_t e_detection_time, e_reference_time;
|
||||||
|
|
@ -25,6 +82,20 @@ static enum EVENT_CHECK_RESULT event_check(den_t *den, DENM_t *denm) {
|
||||||
return EVENT_INVALID;
|
return EVENT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if event cause code type is permitted by the issuing ticket
|
||||||
|
if (ssp && denm->denm.situation) {
|
||||||
|
if (
|
||||||
|
!permissions_check(
|
||||||
|
denm->denm.situation->eventType.causeCode,
|
||||||
|
ssp->choice.bitmapSsp.buf,
|
||||||
|
ssp->choice.bitmapSsp.size
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return EVENT_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct timespec systemtime;
|
struct timespec systemtime;
|
||||||
clock_gettime(CLOCK_REALTIME, &systemtime);
|
clock_gettime(CLOCK_REALTIME, &systemtime);
|
||||||
long now = (long) (systemtime.tv_sec * 1000 + systemtime.tv_nsec / 1E6);
|
long now = (long) (systemtime.tv_sec * 1000 + systemtime.tv_nsec / 1E6);
|
||||||
|
|
@ -256,9 +327,9 @@ static int event_update(den_t *den, DENM_t *denm, int64_t* id) {
|
||||||
else return 0; // Event updated
|
else return 0; // Event updated
|
||||||
}
|
}
|
||||||
|
|
||||||
int event_manage(den_t *den, DENM_t *denm, int64_t* id) {
|
int event_manage(den_t *den, DENM_t *denm, int64_t* id, ServiceSpecificPermissions_t* ssp) {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
switch (rv = event_check(den, denm)) {
|
switch (rv = event_check(den, denm, ssp)) {
|
||||||
case EVENT_NEW:
|
case EVENT_NEW:
|
||||||
syslog_debug("[facilities] [den] new event received");
|
syslog_debug("[facilities] [den] new event received");
|
||||||
if (event_add(den, denm, id)) {
|
if (event_add(den, denm, id)) {
|
||||||
|
|
|
||||||
12
src/denm.h
12
src/denm.h
|
|
@ -5,6 +5,7 @@
|
||||||
#include <denmv2/DENM.h>
|
#include <denmv2/DENM.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <itss-transport/ServiceSpecificPermissions.h>
|
||||||
|
|
||||||
enum EVENT_STATE {
|
enum EVENT_STATE {
|
||||||
EVENT_ACTIVE,
|
EVENT_ACTIVE,
|
||||||
|
|
@ -49,14 +50,23 @@ enum EVENT_CHECK_RESULT {
|
||||||
EVENT_NUMBER_EXCEEDED
|
EVENT_NUMBER_EXCEEDED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct cc_ssp_bm {
|
||||||
|
const char* cause_type;
|
||||||
|
const int cause_code;
|
||||||
|
const uint32_t bitmap_val;
|
||||||
|
} cc_ssp_bm_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate a DENM event.
|
* Evaluate a DENM event.
|
||||||
* Does all the checks to a DENM and adds it to the database. *Don't* free the DENM struct after calling this function
|
* Does all the checks to a DENM and adds it to the database. *Don't* free the DENM struct after calling this function
|
||||||
* @param den the DEN service struct
|
* @param den the DEN service struct
|
||||||
* @param denm the DENM to evaluate
|
* @param denm the DENM to evaluate
|
||||||
|
* @param id message intra ITS-S identitifier
|
||||||
|
* @param ssp permissions
|
||||||
* @return 0 if event OK, 1 if event NOK
|
* @return 0 if event OK, 1 if event NOK
|
||||||
*/
|
*/
|
||||||
int event_manage(den_t* den, DENM_t* denm, int64_t* id);
|
int event_manage(den_t* den, DENM_t* denm, int64_t* id, ServiceSpecificPermissions_t* ssp);
|
||||||
|
|
||||||
void* den_service(void* fc);
|
void* den_service(void* fc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,17 @@ static int transport_indication(facilities_t *facilities, void* responder, uint8
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get permisisons
|
||||||
|
ServiceSpecificPermissions_t* ssp = NULL;
|
||||||
|
if (bdi->gnPermissions) {
|
||||||
|
ssp = &bdi->gnPermissions->ssp;
|
||||||
|
}
|
||||||
|
|
||||||
// Manage message
|
// Manage message
|
||||||
switch (bdi->destinationPort) {
|
switch (bdi->destinationPort) {
|
||||||
case Port_cam:
|
case Port_cam:
|
||||||
|
|
||||||
check_cam(facilities, bdi, its_msg);
|
check_cam(facilities, bdi, its_msg, ssp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Port_denm:
|
case Port_denm:
|
||||||
|
|
@ -96,9 +102,13 @@ static int transport_indication(facilities_t *facilities, void* responder, uint8
|
||||||
free(xml_denm);
|
free(xml_denm);
|
||||||
#endif
|
#endif
|
||||||
int64_t id = -1;
|
int64_t id = -1;
|
||||||
event_manage(facilities->den, its_msg, &id);
|
event_manage(facilities->den, its_msg, &id, ssp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Port_ivim:
|
||||||
|
service_eval(facilities->infrastructure, SERVICE_IVI, its_msg, &id, ssp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +130,9 @@ static int transport_indication(facilities_t *facilities, void* responder, uint8
|
||||||
pthread_cond_signal(&facilities->tx_queue->trigger);
|
pthread_cond_signal(&facilities->tx_queue->trigger);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (bdi->destinationPort != Port_denm) ASN_STRUCT_FREE(*its_msg_descriptor, its_msg);
|
if (bdi->destinationPort != Port_denm && bdi->destinationPort != Port_ivim) {
|
||||||
|
ASN_STRUCT_FREE(*its_msg_descriptor, its_msg);
|
||||||
|
}
|
||||||
ASN_STRUCT_FREE(asn_DEF_BTPDataIndication, bdi);
|
ASN_STRUCT_FREE(asn_DEF_BTPDataIndication, bdi);
|
||||||
ASN_STRUCT_FREE(asn_DEF_FacilitiesDataIndication, fdi);
|
ASN_STRUCT_FREE(asn_DEF_FacilitiesDataIndication, fdi);
|
||||||
|
|
||||||
|
|
@ -204,7 +216,7 @@ static int facilities_request(facilities_t *facilities, void* responder, uint8_t
|
||||||
if (fdreq->choice.singleMessage.itssMessageType == ItssMessageType_denm) {
|
if (fdreq->choice.singleMessage.itssMessageType == ItssMessageType_denm) {
|
||||||
managed_msg = true;
|
managed_msg = true;
|
||||||
|
|
||||||
uint8_t event_type = event_manage(facilities->den, its_msg, &id);
|
uint8_t event_type = event_manage(facilities->den, its_msg, &id, NULL);
|
||||||
// Do not free its_msg! event_manage takes care of the msg
|
// Do not free its_msg! event_manage takes care of the msg
|
||||||
// id will get set to another val if EVENT NEW or UPDATE or CANCELLATION or NEGATION
|
// id will get set to another val if EVENT NEW or UPDATE or CANCELLATION or NEGATION
|
||||||
if (event_type != EVENT_NEW &&
|
if (event_type != EVENT_NEW &&
|
||||||
|
|
@ -243,7 +255,7 @@ static int facilities_request(facilities_t *facilities, void* responder, uint8_t
|
||||||
} else if (fdreq->choice.singleMessage.itssMessageType == ItssMessageType_ivim) {
|
} else if (fdreq->choice.singleMessage.itssMessageType == ItssMessageType_ivim) {
|
||||||
managed_msg = true;
|
managed_msg = true;
|
||||||
|
|
||||||
uint8_t service_type = service_eval(facilities->infrastructure, SERVICE_IVI, its_msg, &id);
|
uint8_t service_type = service_eval(facilities->infrastructure, SERVICE_IVI, its_msg, &id, NULL);
|
||||||
|
|
||||||
if (service_type != SERVICE_NEW &&
|
if (service_type != SERVICE_NEW &&
|
||||||
service_type != SERVICE_UPDATE &&
|
service_type != SERVICE_UPDATE &&
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ static int service_update(infrastructure_t* infrastructure, enum SERVICE_TYPE ty
|
||||||
else return 0; // Event updated
|
else return 0; // Event updated
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SERVICE_EVAL_RESULT service_eval(infrastructure_t* infrastructure, enum SERVICE_TYPE type, void* its_msg, int64_t* id) {
|
enum SERVICE_EVAL_RESULT service_eval(infrastructure_t* infrastructure, enum SERVICE_TYPE type, void* its_msg, int64_t* id, ServiceSpecificPermissions_t* ssp) {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
switch (rv = service_check(infrastructure, type, its_msg)) {
|
switch (rv = service_check(infrastructure, type, its_msg)) {
|
||||||
case SERVICE_NEW:
|
case SERVICE_NEW:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <ivim/IVIM.h>
|
#include <ivim/IVIM.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <itss-transport/ServiceSpecificPermissions.h>
|
||||||
|
|
||||||
enum SERVICE_STATE {
|
enum SERVICE_STATE {
|
||||||
SERVICE_ACTIVE,
|
SERVICE_ACTIVE,
|
||||||
|
|
@ -61,7 +62,7 @@ enum SERVICE_EVAL_RESULT {
|
||||||
SERVICE_NUMBER_EXCEEDED
|
SERVICE_NUMBER_EXCEEDED
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SERVICE_EVAL_RESULT service_eval(infrastructure_t* infrastructure, enum SERVICE_TYPE type, void* its_msg, int64_t* id);
|
enum SERVICE_EVAL_RESULT service_eval(infrastructure_t* infrastructure, enum SERVICE_TYPE type, void* its_msg, int64_t* id, ServiceSpecificPermissions_t* ssp);
|
||||||
|
|
||||||
void* infrastructure_service(void* fc);
|
void* infrastructure_service(void* fc);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue