mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
159 lines
5.4 KiB
C
159 lines
5.4 KiB
C
#include <pthread.h>
|
|
#include <unistd.h>
|
|
|
|
#include "heartbeat.h"
|
|
#include "common.h"
|
|
#include "config.h"
|
|
#include "session.h"
|
|
#include "cwmp_uci.h"
|
|
#include "backupSession.h"
|
|
#include "log.h"
|
|
#include "event.h"
|
|
#include "http.h"
|
|
|
|
pthread_cond_t threshold_heartbeat_session;
|
|
pthread_cond_t threasheld_retry_session;
|
|
pthread_mutex_t mutex_heartbeat;
|
|
pthread_mutex_t mutex_heartbeat_session;
|
|
bool old_heartbeat_enable = false;
|
|
int heart_beat_retry_count_session = 0;
|
|
|
|
static struct session_status heart_beat_session_status = {0};
|
|
|
|
void check_trigger_heartbeat_session()
|
|
{
|
|
if (cwmp_main.conf.heart_beat_enable && !old_heartbeat_enable)
|
|
pthread_cond_signal(&threshold_heartbeat_session);
|
|
}
|
|
|
|
int add_heart_beat_event(struct session *heartbeat_session)
|
|
{
|
|
struct event_container *event_container;
|
|
event_container = calloc(1, sizeof(struct event_container));
|
|
if (event_container == NULL) {
|
|
return -1;
|
|
}
|
|
INIT_LIST_HEAD(&(event_container->head_dm_parameter));
|
|
list_add(&(event_container->list), heartbeat_session->head_event_container.prev);
|
|
event_container->code = EVENT_IDX_14HEARTBEAT;
|
|
event_container->command_key = strdup("");
|
|
event_container->id = 1;
|
|
/*
|
|
* event_container will be freed in the destruction of the session heartbeat_session
|
|
*/
|
|
// cppcheck-suppress memleak
|
|
return 0;
|
|
}
|
|
|
|
void *thread_heartbeat_session(void *v __attribute__((unused)))
|
|
{
|
|
static struct timespec heartbeat_interval = { 0, 0 };
|
|
|
|
sleep(2);
|
|
for (;;) {
|
|
if (thread_end)
|
|
break;
|
|
|
|
if (cwmp_main.conf.heart_beat_enable) {
|
|
heartbeat_interval.tv_sec = time(NULL) + cwmp_main.conf.heartbeat_interval;
|
|
pthread_mutex_lock(&mutex_heartbeat);
|
|
pthread_cond_timedwait(&threshold_heartbeat_session, &mutex_heartbeat, &heartbeat_interval);
|
|
if (thread_end)
|
|
break;
|
|
|
|
if (cwmp_main.session_status.last_status == SESSION_FAILURE) {
|
|
CWMP_LOG(WARNING, "Not able to start HEARTBEAT Session for this period: CWMP Session is retrying");
|
|
pthread_cond_wait(&threasheld_retry_session, &mutex_heartbeat);
|
|
//continue;
|
|
}
|
|
|
|
if (thread_end)
|
|
break;
|
|
|
|
pthread_mutex_lock(&mutex_heartbeat_session);
|
|
struct session *heartbeat_session = NULL;
|
|
heartbeat_session = calloc(1, sizeof(struct session));
|
|
if (heartbeat_session == NULL) {
|
|
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
continue;
|
|
}
|
|
INIT_LIST_HEAD(&(heartbeat_session->head_event_container));
|
|
INIT_LIST_HEAD(&(heartbeat_session->head_rpc_acs));
|
|
INIT_LIST_HEAD(&(heartbeat_session->head_rpc_cpe));
|
|
struct rpc *rpc_acs;
|
|
rpc_acs = cwmp_add_session_rpc_acs_head(heartbeat_session, RPC_ACS_INFORM);
|
|
if (rpc_acs == NULL) {
|
|
cwmp_session_destructor(heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
continue;
|
|
}
|
|
if (add_heart_beat_event(heartbeat_session) != 0) {
|
|
cwmp_session_destructor(heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
continue;
|
|
}
|
|
|
|
cwmp_uci_init();
|
|
if (heart_beat_session_status.last_status == SESSION_FAILURE)
|
|
reload_networking_config();
|
|
heart_beat_session_status.last_end_time = 0;
|
|
heart_beat_session_status.last_start_time = time(NULL);
|
|
heart_beat_session_status.last_status = SESSION_RUNNING;
|
|
heart_beat_session_status.next_retry = 0;
|
|
|
|
if (file_exists(fc_cookies))
|
|
remove(fc_cookies);
|
|
|
|
CWMP_LOG(INFO, "Start HEARTBEAT session");
|
|
int error = cwmp_schedule_rpc(&cwmp_main, heartbeat_session);
|
|
CWMP_LOG(INFO, "End HEARTBEAT session");
|
|
|
|
if (thread_end) {
|
|
event_remove_all_event_container(heartbeat_session, RPC_SEND);
|
|
run_session_end_func();
|
|
cwmp_session_destructor(heartbeat_session);
|
|
cwmp_uci_exit();
|
|
pthread_mutex_unlock(&(cwmp_main.mutex_session_send));
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
// Exiting to avoid race conditions
|
|
exit(0);
|
|
}
|
|
|
|
if (error || heartbeat_session->error == CWMP_RETRY_SESSION) {
|
|
heart_beat_retry_count_session++;
|
|
reload_networking_config();
|
|
run_session_end_func();
|
|
CWMP_LOG(INFO, "Retry HEARTBEAT session, retry count = %d, retry in %ds", cwmp_main.retry_count_session, cwmp_get_retry_interval(&cwmp_main, 1));
|
|
heart_beat_session_status.last_end_time = time(NULL);
|
|
heart_beat_session_status.last_status = SESSION_FAILURE;
|
|
heart_beat_session_status.next_retry = time(NULL) + cwmp_get_retry_interval(&cwmp_main, 1);
|
|
heartbeat_interval.tv_sec = time(NULL) + cwmp_get_retry_interval(&cwmp_main, 1);
|
|
heart_beat_session_status.failure_session++;
|
|
cwmp_uci_exit();
|
|
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
continue;
|
|
}
|
|
event_remove_all_event_container(heartbeat_session, RPC_SEND);
|
|
run_session_end_func();
|
|
cwmp_session_destructor(heartbeat_session);
|
|
heart_beat_retry_count_session = 0;
|
|
heart_beat_session_status.last_end_time = time(NULL);
|
|
heart_beat_session_status.last_status = SESSION_SUCCESS;
|
|
heart_beat_session_status.next_retry = 0;
|
|
heart_beat_session_status.success_session++;
|
|
heartbeat_interval.tv_sec = time(NULL) + cwmp_main.conf.heartbeat_interval;
|
|
cwmp_uci_exit();
|
|
pthread_mutex_unlock(&mutex_heartbeat_session);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
} else {
|
|
pthread_mutex_lock(&mutex_heartbeat);
|
|
pthread_cond_wait(&threshold_heartbeat_session, &mutex_heartbeat);
|
|
pthread_mutex_unlock(&mutex_heartbeat);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|