Skip to content

Commit

Permalink
Enable multi auto_update management, fix #450
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-rabault committed Jan 3, 2024
1 parent 649161e commit 33c9a66
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 60 deletions.
4 changes: 1 addition & 3 deletions engine/IO/src/luos_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,9 +660,7 @@ error_return_t LuosIO_ConsumeMsg(const msg_t *input)
case UPDATE_PUB:
// This service need to be auto updated
TimeOD_TimeFromMsg(&time, input);
service->auto_refresh.target = input->header.source;
service->auto_refresh.time_ms = (uint16_t)TimeOD_TimeTo_ms(time);
service->auto_refresh.last_update = LuosHAL_GetSystick();
Service_AddAutoUpdateTarget(service, input->header.source, (uint16_t)TimeOD_TimeTo_ms(time));
return SUCCEED;
break;
//**************************************** bootloader section ****************************************
Expand Down
1 change: 1 addition & 0 deletions engine/core/inc/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void Service_ResetStatistics(void);
void Service_GenerateId(uint16_t base_id);
void Service_ClearId(void);
uint16_t Service_GetIndex(service_t *service);
void Service_AddAutoUpdateTarget(service_t *service, uint16_t target, uint16_t time_ms);
void Service_RmAutoUpdateTarget(uint16_t service_id);
void Service_AutoUpdateManager(void);
error_return_t Service_Deliver(phy_job_t *job);
Expand Down
24 changes: 12 additions & 12 deletions engine/core/inc/struct_luos.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,6 @@ typedef struct __attribute__((__packed__))
};
} msg_t;

/******************************************************************************
* This structure is used to manage services timed auto update
* please refer to the documentation
******************************************************************************/
typedef struct timed_update_t
{
uint32_t last_update;
uint16_t time_ms;
uint16_t target;
} timed_update_t;

/******************************************************************************
* This structure is used to manage dead target message
* Service_id or node_id can be set to 0 to ignore it.
Expand Down Expand Up @@ -217,11 +206,22 @@ typedef struct service_t
// Private Variables
uint16_t last_topic_position; /*!< Position pointer of the last topic added. */
uint16_t topic_list[MAX_LOCAL_TOPIC_NUMBER]; /*!< multicast target bank. */
timed_update_t auto_refresh; /*!< service auto refresh context. */
void *profile_context; /*!< Pointer to the profile context. */

} service_t;

/******************************************************************************
* This structure is used to manage services timed auto update
* please refer to the documentation
******************************************************************************/
typedef struct timed_update_t
{
service_t *service;
uint32_t last_update;
uint16_t time_ms;
uint16_t target;
} timed_update_t;

typedef void (*SERVICE_CB)(service_t *service, const msg_t *msg);

#endif /*__LUOS_STRUCT_H */
71 changes: 45 additions & 26 deletions engine/core/src/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ typedef struct
{
service_t list[MAX_LOCAL_SERVICE_NUMBER];
uint16_t number;
timed_update_t auto_refresh[MAX_AUTO_REFRESH_NUMBER]; /*!< service auto refresh context. */
} service_ctx_t;

/*******************************************************************************
Expand Down Expand Up @@ -107,11 +108,9 @@ void Service_ClearId(void)
{
for (uint16_t i = 0; i < service_ctx.number; i++)
{
service_ctx.list[i].id = DEFAULTID;
service_ctx.list[i].auto_refresh.target = 0;
service_ctx.list[i].auto_refresh.time_ms = 0;
service_ctx.list[i].auto_refresh.last_update = 0;
service_ctx.list[i].id = DEFAULTID;
}
memset((void *)service_ctx.auto_refresh, 0, sizeof(timed_update_t) * MAX_AUTO_REFRESH_NUMBER);
}

/******************************************************************************
Expand All @@ -125,20 +124,41 @@ uint16_t Service_GetIndex(service_t *service)
return ((uintptr_t)service - (uintptr_t)service_ctx.list) / sizeof(service_t);
}

/******************************************************************************
* @brief Remove all services auto update targetting this service_id
* @param service_id
* @return None
******************************************************************************/
void Service_AddAutoUpdateTarget(service_t *service, uint16_t target, uint16_t time_ms)
{
LUOS_ASSERT(service && (time_ms > 0) && (target != 0));
for (uint16_t i = 0; i < MAX_AUTO_REFRESH_NUMBER; i++)
{
if (service_ctx.auto_refresh[i].time_ms == 0)
{
service_ctx.auto_refresh[i].service = service;
service_ctx.auto_refresh[i].target = target;
service_ctx.auto_refresh[i].time_ms = time_ms;
service_ctx.auto_refresh[i].last_update = LuosHAL_GetSystick();
return;
}
}
// No more space for auto update
LUOS_ASSERT(0);
}

/******************************************************************************
* @brief Remove all services auto update targetting this service_id
* @param service_id
* @return None
******************************************************************************/
void Service_RmAutoUpdateTarget(uint16_t service_id)
{
for (uint16_t i = 0; i < service_ctx.number; i++)
for (uint16_t i = 0; i < MAX_AUTO_REFRESH_NUMBER; i++)
{
if (service_ctx.list[i].auto_refresh.target == service_id)
if (service_ctx.auto_refresh[i].target == service_id)
{
service_ctx.list[i].auto_refresh.target = 0;
service_ctx.list[i].auto_refresh.time_ms = 0;
service_ctx.list[i].auto_refresh.last_update = 0;
memset((void *)&service_ctx.auto_refresh[i], 0, sizeof(timed_update_t));
}
}
}
Expand All @@ -150,45 +170,44 @@ void Service_RmAutoUpdateTarget(uint16_t service_id)
******************************************************************************/
void Service_AutoUpdateManager(void)
{
// Check all services timed_update_t contexts
for (uint16_t i = 0; i < service_ctx.number; i++)
// Check all timed_update_t
for (uint16_t i = 0; i < MAX_AUTO_REFRESH_NUMBER; i++)
{
// check if services have an actual ID. If not, we are in detection mode and should reset the auto refresh
if (service_ctx.list[i].id == DEFAULTID)
// Check if detection is OK
if (Node_GetState() != DETECTION_OK)
{
// this service have not been detected or is in detection mode. remove auto_refresh parameters
service_ctx.list[i].auto_refresh.target = 0;
service_ctx.list[i].auto_refresh.time_ms = 0;
service_ctx.list[i].auto_refresh.last_update = 0;
// We have not been detected or we are in detection mode. remove auto_refresh parameters
memset((void *)&service_ctx.auto_refresh[i], 0, sizeof(timed_update_t));
}
else
{
// check if there is a timed update setted and if it's time to update it.
if (service_ctx.list[i].auto_refresh.time_ms)
if (service_ctx.auto_refresh[i].time_ms)
{
if ((LuosHAL_GetSystick() - service_ctx.list[i].auto_refresh.last_update) >= service_ctx.list[i].auto_refresh.time_ms)
if ((LuosHAL_GetSystick() - service_ctx.auto_refresh[i].last_update) >= service_ctx.auto_refresh[i].time_ms)
{
// This service need to send an update
// Create a fake message for it from the service asking for update
msg_t updt_msg;
LUOS_ASSERT(service_ctx.auto_refresh[i].service);
updt_msg.header.config = BASE_PROTOCOL;
updt_msg.header.target = service_ctx.list[i].id;
updt_msg.header.source = service_ctx.list[i].auto_refresh.target;
updt_msg.header.target_mode = SERVICEIDACK;
updt_msg.header.target = service_ctx.auto_refresh[i].service->id;
updt_msg.header.source = service_ctx.auto_refresh[i].target;
updt_msg.header.target_mode = NODEIDACK;
updt_msg.header.cmd = GET_CMD;
updt_msg.header.size = 0;
if ((service_ctx.list[i].service_cb != 0))
if ((service_ctx.auto_refresh[i].service->service_cb != 0))
{
service_ctx.list[i].service_cb(&service_ctx.list[i], &updt_msg);
service_ctx.auto_refresh[i].service->service_cb(service_ctx.auto_refresh[i].service, &updt_msg);
}
else
{
if (Node_GetState() == DETECTION_OK)
{
Luos_SendMsg(&service_ctx.list[i], &updt_msg);
Luos_SendMsg(service_ctx.auto_refresh[i].service, &updt_msg);
}
}
service_ctx.list[i].auto_refresh.last_update = LuosHAL_GetSystick();
service_ctx.auto_refresh[i].last_update = LuosHAL_GetSystick();
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions engine/engine_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#define MAX_LOCAL_SERVICE_NUMBER 5 // The maximum number of local services
#endif

#ifndef MAX_AUTO_REFRESH_NUMBER
#define MAX_AUTO_REFRESH_NUMBER MAX_LOCAL_SERVICE_NUMBER // The maximum number of auto refresh in the node
#endif

#ifndef MAX_SERVICE_NUMBER
#define MAX_SERVICE_NUMBER 20 // The maximum number of services in the complete architecture
#endif
Expand Down
84 changes: 73 additions & 11 deletions test/tests_core/test_service/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,20 +211,80 @@ void unittest_Service_GetIndex(void)
}
}

void unittest_Service_AddAutoUpdateTarget(void)
{
NEW_TEST_CASE("Test Service_AddAutoUpdateTarget assert conditions");
{
TRY
{
Service_AddAutoUpdateTarget(NULL, 1, 10);
}
TEST_ASSERT_TRUE(IS_ASSERT());
END_TRY;

TRY
{
Service_AddAutoUpdateTarget(&service_ctx.list[0], 0, 10);
}
TEST_ASSERT_TRUE(IS_ASSERT());
END_TRY;

TRY
{
Service_AddAutoUpdateTarget(&service_ctx.list[0], 1, 0);
}
TEST_ASSERT_TRUE(IS_ASSERT());
END_TRY;
}
NEW_TEST_CASE("Test Service_AddAutoUpdateTarget");
{
TRY
{
Service_AddAutoUpdateTarget(&service_ctx.list[0], 2, 20);
TEST_ASSERT_EQUAL(2, service_ctx.auto_refresh[0].target);
TEST_ASSERT_EQUAL(20, service_ctx.auto_refresh[0].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[0], service_ctx.auto_refresh[0].service);
Service_AddAutoUpdateTarget(&service_ctx.list[0], 3, 10);
TEST_ASSERT_EQUAL(2, service_ctx.auto_refresh[0].target);
TEST_ASSERT_EQUAL(20, service_ctx.auto_refresh[0].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[0], service_ctx.auto_refresh[0].service);
TEST_ASSERT_EQUAL(3, service_ctx.auto_refresh[1].target);
TEST_ASSERT_EQUAL(10, service_ctx.auto_refresh[1].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[0], service_ctx.auto_refresh[1].service);
Service_AddAutoUpdateTarget(&service_ctx.list[1], 1, 5);
TEST_ASSERT_EQUAL(2, service_ctx.auto_refresh[0].target);
TEST_ASSERT_EQUAL(20, service_ctx.auto_refresh[0].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[0], service_ctx.auto_refresh[0].service);
TEST_ASSERT_EQUAL(3, service_ctx.auto_refresh[1].target);
TEST_ASSERT_EQUAL(10, service_ctx.auto_refresh[1].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[0], service_ctx.auto_refresh[1].service);
TEST_ASSERT_EQUAL(1, service_ctx.auto_refresh[2].target);
TEST_ASSERT_EQUAL(5, service_ctx.auto_refresh[2].time_ms);
TEST_ASSERT_EQUAL(&service_ctx.list[1], service_ctx.auto_refresh[2].service);
}
CATCH
{
TEST_ASSERT_TRUE(false);
}
END_TRY;
}
}

void unittest_Service_RmAutoUpdateTarget(void)
{
NEW_TEST_CASE("Test Service_RmAutoUpdateTarget");
{
TRY
{
service_ctx.number = 10;
service_ctx.list[2].auto_refresh.target = 2;
service_ctx.list[2].auto_refresh.time_ms = 20;
service_ctx.list[2].auto_refresh.last_update = 30;
service_ctx.number = 10;
service_ctx.auto_refresh[0].service = &service_ctx.list[0];
service_ctx.auto_refresh[0].target = 2;
service_ctx.auto_refresh[0].time_ms = 20;
service_ctx.auto_refresh[0].last_update = 30;
Service_RmAutoUpdateTarget(2);
TEST_ASSERT_EQUAL(0, service_ctx.list[2].auto_refresh.target);
TEST_ASSERT_EQUAL(0, service_ctx.list[2].auto_refresh.time_ms);
TEST_ASSERT_EQUAL(0, service_ctx.list[2].auto_refresh.last_update);
TEST_ASSERT_EQUAL(0, service_ctx.auto_refresh[0].target);
TEST_ASSERT_EQUAL(0, service_ctx.auto_refresh[0].time_ms);
TEST_ASSERT_EQUAL(0, service_ctx.auto_refresh[0].last_update);
}
CATCH
{
Expand All @@ -243,11 +303,12 @@ void unittest_Service_AutoUpdateManager(void)
// Init default scenario context
Init_Context();
Luos_Loop();
service_ctx.list[2].auto_refresh.target = 1;
service_ctx.list[2].auto_refresh.time_ms = 10;
service_ctx.list[2].auto_refresh.last_update = 30;
service_ctx.auto_refresh[0].service = default_sc.App_3.app;
service_ctx.auto_refresh[0].target = 1;
service_ctx.auto_refresh[0].time_ms = 10;
service_ctx.auto_refresh[0].last_update = 30;
Service_AutoUpdateManager();
TEST_ASSERT_NOT_EQUAL(30, service_ctx.list[2].auto_refresh.last_update);
TEST_ASSERT_NOT_EQUAL(30, service_ctx.auto_refresh[0].last_update);
TEST_ASSERT_EQUAL(GET_CMD, default_sc.App_3.last_rx_msg.header.cmd);
TEST_ASSERT_EQUAL(1, default_sc.App_3.last_rx_msg.header.source);
TEST_ASSERT_EQUAL(3, default_sc.App_3.last_rx_msg.header.target);
Expand Down Expand Up @@ -534,6 +595,7 @@ int main(int argc, char **argv)
UNIT_TEST_RUN(unittest_Service_GenerateId);
UNIT_TEST_RUN(unittest_Service_ClearId);
UNIT_TEST_RUN(unittest_Service_GetIndex);
UNIT_TEST_RUN(unittest_Service_AddAutoUpdateTarget);
UNIT_TEST_RUN(unittest_Service_RmAutoUpdateTarget);
UNIT_TEST_RUN(unittest_Service_AutoUpdateManager);
UNIT_TEST_RUN(unittest_Service_GetConcerned);
Expand Down
17 changes: 9 additions & 8 deletions test/tests_io/test_luos_io/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,12 +723,13 @@ void unittest_luosIO_ConsumeMsg()
Luos_handled_job = NULL;
Robus_handled_job = NULL;

Node_Get()->node_id = 1;
service_ctx.number = 2;
service_ctx.list[0].id = 1;
service_ctx.list[0].auto_refresh.target = 0;
service_ctx.list[0].auto_refresh.time_ms = 0;
service_ctx.list[0].auto_refresh.last_update = 0;
Node_Get()->node_id = 1;
service_ctx.number = 2;
service_ctx.list[0].id = 1;
service_ctx.auto_refresh[0].service = &service_ctx.list[0];
service_ctx.auto_refresh[0].target = 0;
service_ctx.auto_refresh[0].time_ms = 0;
service_ctx.auto_refresh[0].last_update = 0;
// Generate the filters
Service_GenerateId(1);

Expand All @@ -742,8 +743,8 @@ void unittest_luosIO_ConsumeMsg()

// Check received message content
TEST_ASSERT_EQUAL(SUCCEED, ret_val);
TEST_ASSERT_EQUAL(1, service_ctx.list[0].auto_refresh.target);
TEST_ASSERT_EQUAL((uint16_t)TimeOD_TimeTo_ms(time), service_ctx.list[0].auto_refresh.time_ms);
TEST_ASSERT_EQUAL(1, service_ctx.auto_refresh[0].target);
TEST_ASSERT_EQUAL((uint16_t)TimeOD_TimeTo_ms(time), service_ctx.auto_refresh[0].time_ms);
}
CATCH
{
Expand Down

0 comments on commit 33c9a66

Please sign in to comment.