ud3tn/include/cla/cla.h
Felix Walter 1237eaa2db Remove heap-allocated Task_t
`hal_task_create` returned a reference to the new task allocated on the
heap via `malloc`. We commonly used the pattern to `free` this reference
from the new thread which, however, could result in race conditions and
other synchronization issues. We added a fix using a semaphore in the
application agent, but this would have been needed in other places (CLA,
...) as well. As we do not make use of the task reference anywhere
besides in the CLA for error handling, we can remove the heap-allocated
value altogether and replace it with an `enum ud3tn_result` to simplify
things and circumvent the named synchronization issues.

In the case of the CLA function `cla_link_init`, logic is introduced to
request the RX task to exit immediately in case the TX task cannot be
launched.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00

150 lines
4.3 KiB
C

// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
#ifndef CLA_H_INCLUDED
#define CLA_H_INCLUDED
#include "cla/cla_contact_rx_task.h"
#include "ud3tn/bundle_processor.h"
#include "ud3tn/crc.h"
#include "ud3tn/node.h"
#include "ud3tn/result.h"
#include "spp/spp_timecodes.h"
#include "platform/hal_types.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define CLA_MAX_OPTION_COUNT 10
struct cla_config {
const struct cla_vtable *vtable;
const struct bundle_agent_interface *bundle_agent_interface;
};
struct cla_link {
struct cla_config *config;
// CLA address (without the CLA identifier) related to the link
char *cla_addr;
// Semaphore for waiting until the RX task is finished
Semaphore_t rx_task_sem;
// Semaphore for waiting until the TX task is finished
Semaphore_t tx_task_sem;
struct rx_task_data rx_task_data;
// Semaphore for notifying the RX task to finish
Semaphore_t rx_task_notification;
// Timestamp of last received byte for implementing the read timeout
uint64_t last_rx_time_ms;
// Queue handing over bundles to the TX task
QueueIdentifier_t tx_queue_handle;
// Semaphore blocking the TX queue while bundles are being added
Semaphore_t tx_queue_sem;
};
struct cla_tx_queue {
QueueIdentifier_t tx_queue_handle;
Semaphore_t tx_queue_sem;
};
/*
* Global CLA Instance Management
*/
enum ud3tn_result cla_initialize_all(
const char *cla_config_str,
const struct bundle_agent_interface *bundle_agent_interface);
struct cla_config *cla_config_get(const char *cla_addr);
/*
* Private API
*/
enum ud3tn_result cla_config_init(
struct cla_config *config,
const struct bundle_agent_interface *bundle_agent_interface);
enum ud3tn_result cla_link_init(struct cla_link *link,
struct cla_config *config,
char *const cla_addr,
bool is_rx, bool is_tx);
// Wait for the link tasks to terminate and, then, delete all associated data.
void cla_link_wait_cleanup(struct cla_link *link);
// Wait for graceful termination of RX and TX task.
void cla_link_wait(struct cla_link *link);
// Delete the data associated with the cla_link.
void cla_link_cleanup(struct cla_link *link);
char *cla_get_connect_addr(const char *cla_addr, const char *cla_name);
void cla_generic_disconnect_handler(struct cla_link *link);
// Constructs the CLA address (`<cla>:<addr>`) from the connected link address.
char *cla_get_cla_addr_from_link(const struct cla_link *link);
/*
* Virtual Functions
*/
struct cla_vtable {
// Public API
/* Returns a unique identifier of the CLA as part of the CLA address */
const char *(*cla_name_get)(void);
/* Starts the TX/RX tasks and, e.g., the socket listener */
enum ud3tn_result (*cla_launch)(struct cla_config *);
/* Frees up memory and resources used by the CLA. - TODO */
// enum ud3tn_result (*cla_destroy)(struct cla_config *);
/* Obtains the max. serialized size of outgoing bundles for this CLA. */
size_t (*cla_mbs_get)(struct cla_config *);
/* Returns the transmission queue for the given node EID and address */
struct cla_tx_queue (*cla_get_tx_queue)(struct cla_config *,
const char *, const char *);
/* Initiates a scheduled contact for a given EID and CLA address */
enum ud3tn_result (*cla_start_scheduled_contact)(struct cla_config *,
const char *,
const char *);
/* Ends a scheduled contact for a given EID and CLA address */
enum ud3tn_result (*cla_end_scheduled_contact)(struct cla_config *,
const char *,
const char *);
// TX Task API
/* Initiates bundle transmission for a single bundle */
void (*cla_begin_packet)(struct cla_link *,
size_t, char *);
/* Terminates bundle transmission for a single bundle */
void (*cla_end_packet)(struct cla_link *);
/* Sends part of the serialized bundle. Can be called multiple times. */
void (*cla_send_packet_data)(struct cla_link *,
const void *,
const size_t);
// RX Task API
void (*cla_rx_task_reset_parsers)(struct cla_link *);
size_t (*cla_rx_task_forward_to_specific_parser)(struct cla_link *,
const uint8_t *,
size_t);
/* Reads a chunk of data */
enum ud3tn_result (*cla_read)(struct cla_link *, uint8_t *buffer,
size_t length, size_t *bytes_read);
/* Cleans up resources after a link broke */
void (*cla_disconnect_handler)(struct cla_link *);
};
#endif /* CLA_H_INCLUDED */