mirror of
https://gitlab.com/d3tn/ud3tn.git
synced 2026-08-13 12:33:27 +02:00
Since we store the offsets, this became unnecessary. Fixes a warning in new versions of GCC. Signed-off-by: Felix Walter <felix.walter@d3tn.com>
125 lines
4 KiB
C
125 lines
4 KiB
C
// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
|
|
#include "bundle6/sdnv.h"
|
|
#include "bundle6/bundle6.h"
|
|
#include "bundle6/serializer.h"
|
|
|
|
#include "ud3tn/result.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#define write_bytes(success_var, bytes, data) do { \
|
|
if ((success_var) && write(cla_obj, data, bytes) != UD3TN_OK) \
|
|
(success_var) = false; \
|
|
} while (0)
|
|
#define serialize_u16(success_var, buffer, value) do { \
|
|
__typeof__(buffer) *_buffer = &(buffer); \
|
|
write_bytes(success_var, sdnv_write_u16(*_buffer, value), *_buffer); \
|
|
} while (0)
|
|
#define serialize_u32(success_var, buffer, value) do { \
|
|
__typeof__(buffer) *_buffer = &(buffer); \
|
|
write_bytes(success_var, sdnv_write_u32(*_buffer, value), *_buffer); \
|
|
} while (0)
|
|
#define serialize_u64(success_var, buffer, value) do { \
|
|
__typeof__(buffer) *_buffer = &(buffer); \
|
|
write_bytes(success_var, sdnv_write_u64(*_buffer, value), *_buffer); \
|
|
} while (0)
|
|
|
|
enum ud3tn_result bundle6_serialize(
|
|
struct bundle *bundle,
|
|
enum ud3tn_result (*write)(void *cla_obj, const void *, const size_t),
|
|
void *cla_obj)
|
|
{
|
|
uint8_t buffer[MAX_SDNV_SIZE];
|
|
|
|
// Serialize dict
|
|
struct bundle6_dict_descriptor *dict_desc = bundle6_calculate_dict(
|
|
bundle
|
|
);
|
|
|
|
if (dict_desc == NULL)
|
|
return UD3TN_FAIL;
|
|
|
|
char *dict = malloc(dict_desc->dict_length_bytes);
|
|
|
|
if (dict == NULL) {
|
|
bundle6_free_dict_descriptor(dict_desc);
|
|
return UD3TN_FAIL;
|
|
}
|
|
|
|
bundle6_serialize_dictionary(dict, dict_desc);
|
|
|
|
// Indicates whether the serialization process can continue
|
|
bool ok = true;
|
|
|
|
/* Write version field */
|
|
write_bytes(ok, 1, &(bundle->protocol_version));
|
|
/* Write SDNV values up to dictionary length */
|
|
serialize_u64(ok, buffer, bundle->proc_flags);
|
|
serialize_u64(ok, buffer, bundle->primary_block_length);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->destination_eid_info.dict_scheme_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->destination_eid_info.dict_ssp_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->source_eid_info.dict_scheme_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->source_eid_info.dict_ssp_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->report_to_eid_info.dict_scheme_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->report_to_eid_info.dict_ssp_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->custodian_eid_info.dict_scheme_offset);
|
|
serialize_u16(ok, buffer,
|
|
dict_desc->custodian_eid_info.dict_ssp_offset);
|
|
serialize_u64(ok, buffer, bundle->creation_timestamp_ms / 1000);
|
|
serialize_u64(ok, buffer, bundle->sequence_number);
|
|
serialize_u64(ok, buffer, bundle->lifetime_ms / 1000);
|
|
serialize_u16(ok, buffer, dict_desc->dict_length_bytes);
|
|
/* Write dictionary byte array */
|
|
write_bytes(ok, dict_desc->dict_length_bytes, dict);
|
|
/* Write remaining SDNV values */
|
|
if (HAS_FLAG(bundle->proc_flags, BUNDLE_FLAG_IS_FRAGMENT)) {
|
|
serialize_u64(ok, buffer, bundle->fragment_offset);
|
|
serialize_u64(ok, buffer, bundle->total_adu_length);
|
|
}
|
|
|
|
/* Serialize bundle blocks */
|
|
struct bundle_block_list *cur_entry = bundle->blocks;
|
|
struct eid_list *cur_ref;
|
|
|
|
while (ok && cur_entry != NULL) {
|
|
write_bytes(ok, 1, &cur_entry->data->type);
|
|
serialize_u64(ok, buffer, cur_entry->data->flags);
|
|
if (HAS_FLAG(cur_entry->data->flags,
|
|
BUNDLE_V6_BLOCK_FLAG_HAS_EID_REF_FIELD)
|
|
) {
|
|
// Determine the count of refs
|
|
int eid_ref_cnt = 0;
|
|
|
|
for (cur_ref = cur_entry->data->eid_refs; cur_ref;
|
|
cur_ref = cur_ref->next, eid_ref_cnt++)
|
|
;
|
|
serialize_u16(ok, buffer, eid_ref_cnt);
|
|
// Write out the refs
|
|
for (int c = 0; c < eid_ref_cnt; c++) {
|
|
struct bundle6_eid_info eid_info =
|
|
dict_desc->eid_references[c];
|
|
serialize_u16(ok, buffer,
|
|
eid_info.dict_scheme_offset);
|
|
serialize_u16(ok, buffer,
|
|
eid_info.dict_ssp_offset);
|
|
}
|
|
}
|
|
serialize_u64(ok, buffer, cur_entry->data->length);
|
|
write_bytes(ok, cur_entry->data->length, cur_entry->data->data);
|
|
cur_entry = cur_entry->next;
|
|
}
|
|
|
|
free(dict);
|
|
bundle6_free_dict_descriptor(dict_desc);
|
|
return ok ? UD3TN_OK : UD3TN_FAIL;
|
|
}
|