Skip to content

Commit

Permalink
core: client: add network connect/disconnect callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
joelguittet committed Jun 20, 2024
1 parent 78a594e commit c3693f8
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 7 deletions.
19 changes: 15 additions & 4 deletions add-ons/src/mender-configure.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,25 +367,31 @@ mender_configure_work_function(void) {
return ret;
}

/* Request access to the network */
if (MENDER_OK != (ret = mender_client_network_connect())) {
mender_log_error("Requesting access to the network failed");
goto END;
}

#ifndef CONFIG_MENDER_CLIENT_CONFIGURE_STORAGE

/* Download configuration */
mender_keystore_t *configuration = NULL;
if (MENDER_OK != (ret = mender_api_download_configuration_data(&configuration))) {
mender_log_error("Unable to get configuration data");
goto END;
goto RELEASE;
}

/* Release previous configuration */
if (MENDER_OK != (ret = mender_utils_keystore_delete(mender_configure_keystore))) {
mender_log_error("Unable to delete device configuration");
goto END;
goto RELEASE;
}

/* Update device configuration */
if (MENDER_OK != (ret = mender_utils_keystore_copy(&mender_configure_keystore, configuration))) {
mender_log_error("Unable to update device configuration");
goto END;
goto RELEASE;
}

/* Invoke the update callback */
Expand All @@ -400,10 +406,15 @@ mender_configure_work_function(void) {
mender_log_error("Unable to publish configuration data");
}

#ifndef CONFIG_MENDER_CLIENT_CONFIGURE_STORAGE
RELEASE:

/* Release access to the network */
mender_client_network_release();

END:

#ifndef CONFIG_MENDER_CLIENT_CONFIGURE_STORAGE

/* Release memeory */
mender_utils_keystore_delete(configuration);

Expand Down
14 changes: 14 additions & 0 deletions add-ons/src/mender-inventory.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/

#include "mender-api.h"
#include "mender-client.h"
#include "mender-inventory.h"
#include "mender-log.h"
#include "mender-scheduler.h"
Expand Down Expand Up @@ -205,11 +206,24 @@ mender_inventory_work_function(void) {
return ret;
}

/* Request access to the network */
if (MENDER_OK != (ret = mender_client_network_connect())) {
mender_log_error("Requesting access to the network failed");
goto END;
}

/* Publish inventory */
if (MENDER_OK != (ret = mender_api_publish_inventory_data(mender_inventory_keystore))) {
mender_log_error("Unable to publish inventory data");
}

RELEASE:

/* Release access to the network */
mender_client_network_release();

END:

/* Release mutex used to protect access to the inventory key-store */
mender_scheduler_mutex_give(mender_inventory_mutex);

Expand Down
12 changes: 12 additions & 0 deletions add-ons/src/mender-troubleshoot.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ mender_troubleshoot_deactivate(void) {
mender_log_error("Unable to disconnect the device of the server");
}
mender_troubleshoot_handle = NULL;

/* Release access to the network */
mender_client_network_release();
}

/* Release session ID */
Expand Down Expand Up @@ -511,6 +514,12 @@ mender_troubleshoot_healthcheck_work_function(void) {

} else {

/* Request access to the network */
if (MENDER_OK != (ret = mender_client_network_connect())) {
mender_log_error("Requesting access to the network failed");
goto END;
}

/* Connect the device to the server */
if (MENDER_OK != (ret = mender_api_troubleshoot_connect(&mender_troubleshoot_data_received_callback, &mender_troubleshoot_handle))) {
mender_log_error("Unable to connect the device to the server");
Expand Down Expand Up @@ -541,6 +550,9 @@ mender_troubleshoot_healthcheck_work_function(void) {
mender_log_error("Unable to disconnect the device of the server");
}
mender_troubleshoot_handle = NULL;

/* Release access to the network */
mender_client_network_release();
}

/* Release session ID */
Expand Down
97 changes: 95 additions & 2 deletions core/src/mender-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ typedef enum {
*/
static mender_client_state_t mender_client_state = MENDER_CLIENT_STATE_INITIALIZATION;

/**
* @brief Counter and mutex for the management of network connect/release callbacks
*/
static uint8_t mender_client_network_count = 0;
static void * mender_client_network_mutex = NULL;

/**
* @brief Deployment data (ID, artifact name and payload types), used to report deployment status after rebooting
*/
Expand Down Expand Up @@ -291,6 +297,12 @@ mender_client_init(mender_client_config_t *config, mender_client_callbacks_t *ca
goto END;
}

/* Create network management mutex */
if (MENDER_OK != (ret = mender_scheduler_mutex_create(&mender_client_network_mutex))) {
mender_log_error("Unable to create network management mutex");
return ret;
}

/* Create artifact types management mutex */
if (MENDER_OK != (ret = mender_scheduler_mutex_create(&mender_client_artifact_types_mutex))) {
mender_log_error("Unable to create artifact types management mutex");
Expand Down Expand Up @@ -490,6 +502,74 @@ mender_client_execute(void) {
return ret;
}

mender_err_t
mender_client_network_connect(void) {

mender_err_t ret;

/* Take mutex used to protect access to the network management counter */
if (MENDER_OK != (ret = mender_scheduler_mutex_take(mender_client_network_mutex, -1))) {
mender_log_error("Unable to take mutex");
return ret;
}

/* Check the network management counter value */
if (0 == mender_client_network_count) {

/* Request network access */
if (NULL != mender_client_callbacks.network_connect) {
if (MENDER_OK != (ret = mender_client_callbacks.network_connect())) {
mender_log_error("Unable to connect network");
goto END;
}
}
}

/* Increment network management counter */
mender_client_network_count++;

END:

/* Release mutex used to protect access to the network management counter */
mender_scheduler_mutex_give(mender_client_network_mutex);

return ret;
}

mender_err_t
mender_client_network_release(void) {

mender_err_t ret;

/* Take mutex used to protect access to the network management counter */
if (MENDER_OK != (ret = mender_scheduler_mutex_take(mender_client_network_mutex, -1))) {
mender_log_error("Unable to take mutex");
return ret;
}

/* Decrement network management counter */
mender_client_network_count--;

/* Check the network management counter value */
if (0 == mender_client_network_count) {

/* Release network access */
if (NULL != mender_client_callbacks.network_release) {
if (MENDER_OK != (ret = mender_client_callbacks.network_release())) {
mender_log_error("Unable to release network");
goto END;
}
}
}

END:

/* Release mutex used to protect access to the network management counter */
mender_scheduler_mutex_give(mender_client_network_mutex);

return ret;
}

mender_err_t
mender_client_exit(void) {

Expand Down Expand Up @@ -533,6 +613,10 @@ mender_client_exit(void) {
mender_client_config.tenant_token = NULL;
mender_client_config.authentication_poll_interval = 0;
mender_client_config.update_poll_interval = 0;
mender_client_network_count = 0;
mender_scheduler_mutex_give(mender_client_network_mutex);
mender_scheduler_mutex_delete(mender_client_network_mutex);
mender_client_network_mutex = NULL;
if (NULL != mender_client_deployment_data) {
cJSON_Delete(mender_client_deployment_data);
mender_client_deployment_data = NULL;
Expand Down Expand Up @@ -574,16 +658,20 @@ mender_client_work_function(void) {
/* Update client state */
mender_client_state = MENDER_CLIENT_STATE_AUTHENTICATION;
}
/* Request access to the network */
if (MENDER_OK != (ret = mender_client_network_connect())) {
goto END;
}
/* Intentional pass-through */
if (MENDER_CLIENT_STATE_AUTHENTICATION == mender_client_state) {
/* Perform authentication with the server */
if (MENDER_DONE != (ret = mender_client_authentication_work_function())) {
goto END;
goto RELEASE;
}
/* Update work period */
if (MENDER_OK != (ret = mender_scheduler_work_set_period(mender_client_work_handle, mender_client_config.update_poll_interval))) {
mender_log_error("Unable to set work period");
goto END;
goto RELEASE;
}
/* Update client state */
mender_client_state = MENDER_CLIENT_STATE_AUTHENTICATED;
Expand All @@ -594,6 +682,11 @@ mender_client_work_function(void) {
ret = mender_client_update_work_function();
}

RELEASE:

/* Release access to the network */
mender_client_network_release();

END:

return ret;
Expand Down
14 changes: 14 additions & 0 deletions include/mender-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ typedef struct {
* @brief Mender client callbacks
*/
typedef struct {
mender_err_t (*network_connect)(void); /**< Invoked when mender-client requests access to the network */
mender_err_t (*network_release)(void); /**< Invoked when mender-client releases access to the network */
mender_err_t (*authentication_success)(void); /**< Invoked when authentication with the mender server succeeded */
mender_err_t (*authentication_failure)(void); /**< Invoked when authentication with the mender server failed */
mender_err_t (*deployment_status)(mender_deployment_status_t, char *); /**< Invoked on transition changes to inform of the new deployment status */
Expand Down Expand Up @@ -116,6 +118,18 @@ mender_err_t mender_client_deactivate(void);
*/
mender_err_t mender_client_execute(void);

/**
* @brief Function to be called from add-ons to request network access
* @return MENDER_OK if network is connected following the request, error code otherwise
*/
mender_err_t mender_client_network_connect(void);

/**
* @brief Function to be called from add-ons to release network access
* @return MENDER_OK if network is released following the request, error code otherwise
*/
mender_err_t mender_client_network_release(void);

/**
* @brief Release mender client
* @return MENDER_OK if the function succeeds, error code otherwise
Expand Down
36 changes: 35 additions & 1 deletion tests/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,38 @@ static const struct option mender_client_options[] = { { "help", 0, NULL, 'h' },
static pthread_mutex_t mender_client_events_mutex;
static pthread_cond_t mender_client_events_cond;

/**
* @brief Network connnect callback
* @return MENDER_OK if network is connected following the request, error code otherwise
*/
static mender_err_t
network_connect_cb(void) {

mender_log_info("Mender client connect network");

/* This callback can be used to configure network connection */
/* Note that the application can connect the network before if required */
/* This callback only indicates the mender-client requests network access now */
/* Nothing to do in this test application just return network is available */
return MENDER_OK;
}

/**
* @brief Network release callback
* @return MENDER_OK if network is released following the request, error code otherwise
*/
static mender_err_t
network_release_cb(void) {

mender_log_info("Mender client released network");

/* This callback can be used to release network connection */
/* Note that the application can keep network activated if required */
/* This callback only indicates the mender-client doesn't request network access now */
/* Nothing to do in this test application just return network is released */
return MENDER_OK;
}

/**
* @brief Authentication success callback
* @return MENDER_OK if application is marked valid and success deployment status should be reported to the server, error code otherwise
Expand Down Expand Up @@ -454,7 +486,9 @@ main(int argc, char **argv) {
.authentication_poll_interval = 0,
.update_poll_interval = 0,
.recommissioning = false };
mender_client_callbacks_t mender_client_callbacks = { .authentication_success = authentication_success_cb,
mender_client_callbacks_t mender_client_callbacks = { .network_connect = network_connect_cb,
.network_release = network_release_cb,
.authentication_success = authentication_success_cb,
.authentication_failure = authentication_failure_cb,
.deployment_status = deployment_status_cb,
.restart = restart_cb };
Expand Down

0 comments on commit c3693f8

Please sign in to comment.