BSL v0.0.0
AMMOS Bundle Protocol Security Library (BSL)
Loading...
Searching...
No Matches
bsl_mock_bpa.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 The Johns Hopkins University Applied Physics
3 * Laboratory LLC.
4 *
5 * This file is part of the Bundle Protocol Security Library (BSL).
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * This work was performed for the Jet Propulsion Laboratory, California
18 * Institute of Technology, sponsored by the United States Government under
19 * the prime contract 80NM0018D0004 between the Caltech and NASA under
20 * subcontract 1700763.
21 */
22
27#include <BPSecLib_Public.h>
28#include <BPSecLib_Private.h>
29#include <assert.h>
30#include "bsl_mock_bpa.h"
31#include "bsl_mock_bpa_eid.h"
32#include "bsl_mock_bpa_eidpat.h"
33#include "bsl_mock_bpa_encode.h"
34#include "bsl_mock_bpa_decode.h"
35
36int MockBPA_Bundle_Deinit(MockBPA_Bundle_t *bundle)
37{
38 assert(bundle != NULL);
39 BSL_HostEID_Deinit(&bundle->primary_block.src_node_id);
40 BSL_HostEID_Deinit(&bundle->primary_block.dest_eid);
41 BSL_HostEID_Deinit(&bundle->primary_block.report_to_eid);
42 for (size_t i = 0; i < bundle->block_count; i++)
43 {
44 free(bundle->blocks[i].btsd);
45 memset(&bundle->blocks[i], 0, sizeof(bundle->blocks[i]));
46 }
47 if (bundle->primary_block.cbor)
48 {
49 free(bundle->primary_block.cbor);
50 }
51 memset(bundle, 0, sizeof(*bundle));
52 return 0;
53}
54
55int MockBPA_GetBundleMetadata(const BSL_BundleRef_t *bundle_ref, BSL_PrimaryBlock_t *result_primary_block)
56{
57 if (!bundle_ref || !result_primary_block || !bundle_ref->data)
58 {
59 return -1;
60 }
61
62 MockBPA_Bundle_t *bundle = bundle_ref->data;
63 memset(result_primary_block, 0, sizeof(*result_primary_block));
64 result_primary_block->block_count = bundle->block_count;
65 result_primary_block->field_version = bundle->primary_block.version;
66 result_primary_block->field_flags = bundle->primary_block.flags;
67 result_primary_block->field_crc_type = bundle->primary_block.crc_type;
68 result_primary_block->field_dest_eid = bundle->primary_block.dest_eid;
69 result_primary_block->field_src_node_id = bundle->primary_block.src_node_id;
70 result_primary_block->field_report_to_eid = bundle->primary_block.report_to_eid;
71 result_primary_block->field_bundle_creation_time = bundle->primary_block.timestamp.bundle_creation_time;
72 result_primary_block->field_seq_num = bundle->primary_block.timestamp.seq_num;
73 result_primary_block->field_lifetime = bundle->primary_block.lifetime;
74 result_primary_block->field_frag_offset = bundle->primary_block.frag_offset;
75 result_primary_block->field_adu_length = bundle->primary_block.adu_length;
76 result_primary_block->cbor = bundle->primary_block.cbor;
77 result_primary_block->cbor_len = bundle->primary_block.cbor_len;
78
79 return 0;
80}
81
82int MockBPA_GetBlockNums(const BSL_BundleRef_t *bundle_ref, size_t block_id_array_capacity,
83 uint64_t block_id_array_result[block_id_array_capacity], size_t *result_count)
84{
85 if (!bundle_ref || !bundle_ref->data || block_id_array_capacity == 0 || !block_id_array_result || !result_count)
86 {
87 return -1;
88 }
89
90 *result_count = 0;
91 MockBPA_Bundle_t *bundle = bundle_ref->data;
92 for (size_t i = 0; i < bundle->block_count; i++)
93 {
94 block_id_array_result[i] = bundle->blocks[i].blk_num;
95 }
96 *result_count = bundle->block_count;
97 return 0;
98}
99
100int MockBPA_GetBlockMetadata(const BSL_BundleRef_t *bundle_ref, uint64_t block_num,
101 BSL_CanonicalBlock_t *result_canonical_block)
102{
103 if (!bundle_ref || !result_canonical_block || !bundle_ref->data)
104 {
105 return -1;
106 }
107
108 memset(result_canonical_block, 0, sizeof(*result_canonical_block));
109
110 MockBPA_Bundle_t *bundle = bundle_ref->data;
111 MockBPA_CanonicalBlock_t *found_block = NULL;
112 for (size_t i = 0; i < bundle->block_count; i++)
113 {
114 if (bundle->blocks[i].blk_num == block_num)
115 {
116 found_block = &bundle->blocks[i];
117 }
118 }
119
120 if (found_block == NULL)
121 {
122 return -3;
123 }
124
125 result_canonical_block->block_num = found_block->blk_num;
126 result_canonical_block->flags = found_block->flags;
127 result_canonical_block->crc = found_block->crc_type;
128 result_canonical_block->type_code = found_block->blk_type;
129 result_canonical_block->btsd = found_block->btsd;
130 result_canonical_block->btsd_len = found_block->btsd_len;
131 return 0;
132}
133
134int MockBPA_ReallocBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t bytesize)
135{
136 if (!bundle_ref || !bundle_ref->data || block_num == 0 || bytesize == 0)
137 {
138 return -1;
139 }
140
141 MockBPA_Bundle_t *bundle = bundle_ref->data;
142 MockBPA_CanonicalBlock_t *found_block = NULL;
143 for (size_t found_index = 0; found_index < bundle->block_count; found_index++)
144 {
145 if (bundle->blocks[found_index].blk_num == block_num)
146 {
147 found_block = &bundle->blocks[found_index];
148 }
149 }
150
151 if (found_block == NULL)
152 {
153 return -2;
154 }
155
156 if (found_block->btsd == NULL)
157 {
158 found_block->btsd = calloc(1, bytesize);
159 found_block->btsd_len = bytesize;
160 }
161 else
162 {
163 found_block->btsd = realloc(found_block->btsd, bytesize);
164 found_block->btsd_len = bytesize;
165 }
166
167 // Return -9 if malloc/realloc faile. Return 0 for success.
168 return (found_block->btsd == NULL) ? -9 : 0;
169}
170
171int MockBPA_CreateBlock(BSL_BundleRef_t *bundle_ref, uint64_t block_type_code, uint64_t *result_block_num)
172{
173 if (!bundle_ref || !bundle_ref->data || !result_block_num)
174 {
175 return -1;
176 }
177
178 *result_block_num = 0;
179 MockBPA_Bundle_t *bundle = bundle_ref->data;
180 if (bundle->block_count >= MockBPA_BUNDLE_MAXBLOCKS)
181 {
182 return -2;
183 }
184
185 uint64_t max_id = 0;
186 for (size_t i = 0; i < bundle->block_count; i++)
187 {
188 max_id = bundle->blocks[i].blk_num >= max_id ? bundle->blocks[i].blk_num : max_id;
189 }
190
191 MockBPA_CanonicalBlock_t *new_block = &bundle->blocks[bundle->block_count++];
192 memset(new_block, 0, sizeof(*new_block));
193 new_block->blk_num = max_id + 1;
194 new_block->blk_type = block_type_code;
195 new_block->crc_type = 0;
196 new_block->flags = block_type_code == 12 ? 1 : 0; // BCB should have a flag of 1
197 new_block->btsd = NULL;
198 new_block->btsd_len = 0;
199 *result_block_num = new_block->blk_num;
200 return 0;
201}
202
203int MockBPA_RemoveBlock(BSL_BundleRef_t *bundle_ref, uint64_t block_num)
204{
205 if (!bundle_ref || !bundle_ref->data)
206 {
207 return -1;
208 }
209
210 MockBPA_Bundle_t *bundle = bundle_ref->data;
211 MockBPA_CanonicalBlock_t *found_block = NULL;
212 size_t found_index = 0;
213 for (found_index = 0; found_index < bundle->block_count; found_index++)
214 {
215 if (bundle->blocks[found_index].blk_num == block_num)
216 {
217 found_block = &bundle->blocks[found_index];
218 break;
219 }
220 }
221
222 if (found_block == NULL)
223 {
224 return -2;
225 }
226
227 // Deinit and clear the target block for removal
228 if (found_block->btsd != NULL)
229 {
230 free(found_block->btsd);
231 }
232 memset(found_block, 0, sizeof(*found_block));
233
234 if (bundle->block_count > 1)
235 {
236 for (size_t dst_index = found_index; dst_index < bundle->block_count - 1; dst_index++)
237 {
238 printf("Shifting block[%lu] (id=%lu, type=%lu) left", dst_index + 1, bundle->blocks[dst_index + 1].blk_num,
239 bundle->blocks[dst_index + 1].blk_type);
240 memcpy(&bundle->blocks[dst_index], &bundle->blocks[dst_index + 1], sizeof(MockBPA_CanonicalBlock_t));
241 memset(&bundle->blocks[dst_index + 1], 0, sizeof(MockBPA_CanonicalBlock_t));
242 }
243 }
244
245 bundle->block_count--;
246 return 0;
247}
248
250{
251 uint8_t *state = BSL_MALLOC(999);
252
254 .user_data = state,
255 // New-style callbacks
256 .get_host_eid_fn = MockBPA_GetEid,
257 .bundle_metadata_fn = MockBPA_GetBundleMetadata,
258 .block_metadata_fn = MockBPA_GetBlockMetadata,
259 .bundle_get_block_ids = MockBPA_GetBlockNums,
260 .block_create_fn = MockBPA_CreateBlock,
261 .block_remove_fn = MockBPA_RemoveBlock,
262 .block_realloc_btsd_fn = MockBPA_ReallocBTSD,
263
264 // Old-style callbacks
265 .eid_init = MockBPA_EID_Init,
266 .eid_deinit = MockBPA_EID_Deinit,
267 // .get_secsrc = mock_bpa_get_secsrc,
268 .eid_to_cbor = (int (*)(void *, const BSL_HostEID_t *))bsl_mock_encode_eid,
269 .eid_from_cbor = (int (*)(void *, BSL_HostEID_t *))bsl_mock_decode_eid,
270 .eid_from_text = mock_bpa_eid_from_text,
271 // .eid_to_text = mock_bpa_eid_to_text,
272 .eidpat_init = mock_bpa_eidpat_init,
273 .eidpat_deinit = mock_bpa_eidpat_deinit,
274 .eidpat_from_text = mock_bpa_eidpat_from_text,
275 .eidpat_match = mock_bpa_eidpat_match,
276 };
277 return BSL_HostDescriptors_Set(bpa);
278}
279
281{
284 if (bpa.user_data != NULL)
285 {
286 BSL_FREE(bpa.user_data);
287 }
288
289 BSL_HostDescriptors_t nullbpa = { 0 };
291}
Single entry-point include file for all of the BPSec Lib (BSL) frontend API.
Single entry-point include file for all of the "Public" BPSec Lib (BSL) frontend API.
int BSL_HostDescriptors_Set(BSL_HostDescriptors_t desc)
Set the BPA descriptor (callbacks) for this process.
void BSL_HostDescriptors_Get(BSL_HostDescriptors_t *desc)
Copy the BPA descriptor for this process.
void BSL_HostEID_Deinit(BSL_HostEID_t *eid)
De-initialize an abstract EID.
void bsl_mock_bpa_deinit(void)
Clean up the mock BPA for the current process.
int bsl_mock_bpa_init(void)
Register this mock BPA for the current process.
Declarations for Agent initialization.
int bsl_mock_decode_eid(QCBORDecodeContext *dec, BSL_HostEID_t *eid)
Encode a single EID.
Declarations for bundle and block decoding.
void MockBPA_EID_Deinit(void *user_data, BSL_HostEID_t *eid)
Interface for BSL_HostDescriptors_t::eid_deinit.
int MockBPA_EID_Init(void *user_data, BSL_HostEID_t *eid)
Interface for BSL_HostDescriptors_t::eid_init.
int mock_bpa_eid_from_text(BSL_HostEID_t *eid, const char *text, void *user_data)
Interface for BSL_HostDescriptors_t::eid_from_text.
Declarations for EID handling.
Declarations for EID Pattern handling.
int bsl_mock_encode_eid(QCBOREncodeContext *enc, const BSL_HostEID_t *eid)
Encode a single EID.
Declarations for bundle and block encoding.
Reference to a Bundle owned and stored in the host BPA.
void * data
Opaque pointer, not used by the BSL.
Structure containing parsed Canonical Block fields.
uint64_t flags
CBOR-decoded flags field.
uint64_t block_num
CBOR-decoded block number (should always be > 0)
void * btsd
Pointer to BTSD owned by the host BPA.
size_t btsd_len
Length in bytes of the BTSD pointer.
uint64_t crc
CBOR-decoded block CRC.
uint64_t type_code
CBOR-decoded block type code (should be > 0)
Dynamic BPA descriptor.
void * user_data
User data pointer for callbacks.
Opaque pointer to BPA-specific Endpoint ID storage.
Contains Bundle Primary Block fields and metadata.
uint64_t field_bundle_creation_time
CBOR-decoded bundle creation time.
uint64_t field_adu_length
CBOR-decoded field of ADU length.
uint64_t field_seq_num
CBOR-decoded sequence number.
size_t block_count
Helpful count of total canonical blocks in bundle, not a field of the header.
uint64_t field_lifetime
CBOR-decoded lifetime.
BSL_HostEID_t field_src_node_id
Source in host BPA's internal representation of an EID.
uint64_t field_frag_offset
CBOR-decoded fragment offset (warning, may not be implemented yet).
uint64_t field_crc_type
CBOR-decoded field of Primary Block CRC type.
BSL_HostEID_t field_report_to_eid
Report-to EID in host BPA's internal representation of an EID.
uint64_t field_flags
CBOR-decoded field of bundle processing control flags.
uint64_t field_version
CBOR-decoded field of Primary Block BP version.
BSL_HostEID_t field_dest_eid
Destination in host BPA's internal representation of an EID.