1. Overview 2. Build with Make 3. Application Design 4. Application Programming Interface 5. Storage Service
Note #1 - Bundle Protocol Version 6 Note #2 - Library Development Guidelines Note #3 - Configuration Parameter Trades Note #4 - Bundle Flow Analysis for Intermittent Communication
The Bundle Protocol library (bplib) implements a subset of the RFC5050 Bundle Protocol and targets embedded space flight applications. The library uses the concept of a bundle channel to manage the process of encapsulating application data in bundles, and extracting application data out of bundles. A channel specifies how the bundles are created (e.g. primary header block fields), and how bundles are processed (e.g. payloads extracted from payload block). Bplib contains no threads and relies entirely on the calling application for its execution context and implements a thread-safe blocking I/O model where requested operations will either block according to the provided timeout, or return an error code immediately if the operation cannot be performed.
Bplib assumes the availability of a persistent queued storage system for managing the rate buffering that must occur between data and bundle processing. This storage system is provided at run-time by the application, which can either use its own or can use one of the included storage services. In addition to the storage service, bplib needs an operating system interface provided at compile-time. By default a POSIX compliant operating systems interface is built with the included makefile - see below for further instructions on changing the operating system interface.
-
To build the static and shared libraries, the only prerequisites are the make build system and a compiler toolchain (by default gcc).
-
Tailoring the build to provide unique system prerequisites is accomplished by providing a custom configuration makefile. See
posix.mk
as an example. If your custom file is called{my_config_makefile}
then the following commands would be used:make CONFIG={my_config_makefile}
sudo make CONFIG={my_config_makefile} install
-
To build the optional Lua extension used for unit testing (and useful for any user implemented Lua applications), then you need to have Lua installed on your system. Given the various versions and configurations Lua can be found in for different systems, the default behavior of the makefile is to look for Lua 5.3 in
/opt/lua5.3
which assumes you've downloaded and installed Lua yourself. This can be accomplished via the followings steps:- Download Lua 5.3 from
www.lua.org
tar -xvzf lua-5.3.X.tar.gz
where X is whatever the latest stable version of Lau 5.3 is.cd lua-5.3.X
make MYCFLAGS="-fpic" linux
sudo make install INSTALL_TOP=/opt/lua5.3
alias bplua="LUA_CPATH=/opt/lua5.3/lib/lua/5.3/?.so LUA_PATH=/opt/lua5.3/lib/lua/5.3/?.lua /opt/lua5.3/bin/lua"
- Download Lua 5.3 from
-
If you want to use a different Lua installation, you must run the Makefile found in
binding/lua
directly. From the command line: thePREFIX
variable can be set to the installed version of Lua you want to use (e.g. /usr), and theLIBDIR
variable can be set to where the bplib.so extension module should be installed (e.g. /usr/lib64/lua/5.1). Managing multiple Lua distributions on a single system can be a little tricky - the biggest problem being that as of 5.3 there is still a global search path for shared objects and Lua files that is independent of the location of the binary Lua interpreter. To get around this problem you can either set thepackage.cpath
andpackage.path
variables within your Lua scripts or you can alias the call to start the Lua interpreter with the paths called out in the command (as shown above).
To build only the static and shared libraries (which is recommended), use the following commands:
make
sudo make install
To build everything, including the language bindings and example application, go to repository root directory and execute the following commands:
make dev
sudo make install-dev
The dev target of the makefile produces the following binaries:
build/libbp.so.<version>
- shared librarybuild/libbp.a
- static librarybindings/lua/build/bplib.so
- lua extension moduleapp/build/bpsend
- example application that sends bundlesapp/build/bprecv
- example program that receives bundles
And performs the following installations:
/usr/local/lib
: bplib libraries/usr/local/inc
: bplib includes/usr/local/lib/lua/5.3
: lua extensions and helper scripts/opt/bpio/bin
: example application binaries
Additional make commands are as follows:
make clean
will remove all generated files and directoriesmake testmem
will call valgrind for detecting memory leaksmake testcpu
will call valgrind/callgrind for detecting cpu bottlenecksmake testheap
will call valgrind/massif for detecting sources of memory bloatmake testcov
will generate a line coverage report (if built and run with gcov, which is enabled by default)
On CentOS you may need to create a file with the conf extension in /etc/ld.so.conf.d that contains the line '/usr/local/lib'.
sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf
sudo ldconfig
Special Note: In order to be compatible with other implementations of the Bundle Protocol, bplib uses a global custody ID by default. To use bplib with per channel custody IDs that optimize aggregate acknowledgements, define BPLIB_GLOBAL_CUSTODY_ID
to false when compiling the code (e.g. make USER_COPT="-DBPLIB_GLOBAL_CUSTODY_ID=false"
).
For those that learn better through examples, an example application is provided in the apps
directory. This example program is not intended to be complete, but provides a quick way to see how to use the library. After building and installing bplib on your system, you can do a simple test to see if the application will run by doing the following:
cd apps
make
./test_run.sh
This will create two windows, the first executing the bprecv program, and the second executing the bpsend program. Any line you type in the bpsend window is bundled and sent over UDP to the bprecv program. Custody transfer is employed and the bpsend program will keep track of the number of messages it has sent vs. the number of messages that have been acknowledged.
To manually run the unit test suite:
lua5.3 binding/lua/test/test_runner.lua
To run a specific unit test using one of the test targets provided in the makefile:
- make test{mem|cpu|heap|cov} testcase=binding/lua/test/ut_{test}.lua
Note that getting the lua extension to compile for your specific linux distribution can be difficult as they often come with different versions and named in different ways. Please see the prerequisites section above and the makefile in bindline/lua
for hints to how to get your version of Lua working with this library.
The default posix.mk
configuration makefile is for development and builds additional C unit tests, code coverage profiling, stack protector, and uses minimum compiler optimizations. When releasing the code, the library should be built with release.mk
as follows:
make CONFIG=release.mk
Bplib is written in "vanilla C" and is intended to be linked in as either a shared or static library into an application with an API for reading/writing application data and reading/writing bundles.
Conceptually, the library is meant to exist inside a board support package for an operating system and be presented to the application as a service. In such a design only the interface for reading/writing data would be provided to the application, and the interface for reading/writing bundles would be kept inside the board support package. This use case would look a lot like a typical socket application where a bundle channel (socket) is opened, data is read/written, and then at some later time the channel is closed. Underneath, the operating system would take care of sending and receiving bundles.
In order to support bplib being used directly by the application, both the data and the bundle interfaces are provided in the API. In these cases, the application is also responsible for sending and receiving the bundles.
An example application design that manages both the data and bundle interfaces could look as follows:
- A bundle reader thread that receives bundles from a convergence layer and calls bplib to process them
- A data writer thread that accepts application data from bplib
- A bundle writer thread that loads bundles from bplib and sends bundles over a convergence layer
- A data reader thread that stores application data to bplib
The stream of bundles received by the application is handled by the bundle reader and data writer threads. The bundle reader uses the bplib_process
function to pass bundles read from the convergence layer into the library. If those bundles contain payload data bound for the application, that data is pulled out of the bundles and queued in storage until the data writer thread calls the bplib_accept
function to dequeue the data out of storage and write it to the application.
Conversely, the stream of bundles sent by the application is handled by the data reader and bundler writer threads. The data reader thread calls bplib_store
to pass data from the application into the library to be bundled. Those bundles are queued in storage until the bundle writer threads calls the bplib_load
function to dequeue them out of storage and write them to the convergence layer.
Function | Purpose |
---|---|
bplib_init | Initialize the BP library - called once at program start |
bplib_open | Open a channel - provides handle to channel for future channel operations |
bplib_close | Close a channel |
bplib_flush | Flush active bundles on a channel |
bplib_config | Change and retrieve channel settings |
bplib_latchstats | Read out bundle statistics for a channel |
bplib_store | Create a bundle from application data and queue in storage for transmission |
bplib_load | Retrieve the next available bundle from storage to transmit |
bplib_process | Process a bundle for data extraction, custody acceptance, and/or forwarding |
bplib_accept | Retrieve the next available data payload from a received bundle |
bplib_ackbundle | Release bundle memory pointer for reuse (needed after bplib_load) |
bplib_ackpayload | Release payload memory pointer for reuse (needed after bplib_accept) |
bplib_routeinfo | Parse bundle and return routing information |
bplib_display | Parse bundle and log a break-down of the bundle elements |
bplib_eid2ipn | Utility function to translate an EID string into node and service numbers |
bplib_ipn2eid | Utility function to translate node and service numbers into an EID string |
bplib_attrinit | Utility to initialize a channel attribute structure with default values. Useful if the calling application only wants to change a few attributes without setting them all. |
Note: functions that operate on a channel are thread-safe with other functions that operate on channels, but they are not thread-safe with the open and close functions. A channel can only be closed when no other operations are being performed on it.
void bplib_init (void)
Initializes the BP library. This must be called before any other call to the library is made. It calls the operating system layer initialization routine.
bp_desc_t* bplib_open (bp_route_t route, bp_store_t store, bp_attr_t* attributes)
Opens a bundle channel that uses the provided endpoint IDs, storage service, and attributes.
This function returns a channel handle that is used for all future operations on the channel. The open and close calls are mutex'ed against other open and close calls, but once a channel is created, operations on that channel are only mutex'ed against other operations on the same channel. A channel persists until it is closed.
route
- a set of endpoing IDs defining the source, destination, and report to endpoints
-
local node: The {node} number of the ipn:{node}.{service} endpoint ID used for the source and custody endpoints of bundles generated on the channel.
-
local service: The {service} number of the ipn:{node}.{service} endpoint ID used for the source and custody enpoints of bundles generated on the channel.
-
destination node: The {node} number of the ipn:{node}.{service} endpoint ID used for the destination enpoint of bundles generated on the channel.
-
destination service: The {service} number of the ipn:{node}.{service} endpoint ID used for the destination enpoint of bundles generated on the channel.
-
report to node: The {node} number of the ipn:{node}.{service} endpoint ID used for the report to enpoint of bundles generated on the channel.
-
report to service: The {service} number of the ipn:{node}.{service} endpoint ID used for the report to enpoint of bundles generated on the channel.
store
- a set of callbacks that provide access to the desired storage service. See Storage Service section for more details.
attributes
- set of characteristics and settings for the channel that trade memory usage and performance
-
lifetime: Bundle generation parameter - the number of seconds since its creation that the bundle is valid. Once the lifetime of a bundle expires, the bundle can be deleted by the bundle agent.
-
request_custody: Bundle generation parameter - if set then the bundle request custody transfer and includes a CTEB extension block.
-
admin_record: Bundle generation parameter - if set then the bundle is set as an administrative record. The library handles this setting automatically for Aggregate Custody Signals that it generates; but if the user wants to create their own administrative record, then this attribute provides that option.
-
integrity_check: Bundle generation parameter - if set then the bundle includes a BIB extension block.
-
allow_fragmentation: Bundle generation parameter - if set then any generated or forwarded bundles on the channel will be fragmented if the size of the bundle exceeds the max_length attribute of the channel; if not set, then any bundle generated or forwarded that exceeds the max_length will be dropped.
-
cipher_suite: Bundle generation parameter - provides the CRC type used inside the BIB extension block. If the integrity_check attribute is not set, then this setting is ignored. If the integrity_check attribute is set and this attribute is set to BP_BIB_NONE, then a BIB is included but the cipher result length is zero (this provide unambigous indication that no integrity check is included). Currently supported cipher suites are: BP_BIB_CRC16_X25, and BP_BIB_CRC32_CASTAGNOLI.
-
timeout: The number of seconds the library waits before re-loading an unacknowledged bundle.
-
max_length: The maximum size in bytes that a bundle can be, both on receipt and on transmission.
-
cid_reuse: The library's behavior when a bundle times-out - if set, bundles that are retransmitted use the original Custody ID of the bundle when it was originally sent; if not set, then a new Custody ID is used when the bundle is retransmitted. Re-using the Custody ID bounds the size of the Aggregrate Custody Signal coming back (worse-case gaps). Using a new Custody ID makes the average size of the Aggregate Custody Signal smaller.
-
dacs_rate: The maximum number of seconds to wait before an Aggregate Custody Signal which has accumulated acknowledgments is sent. Every time a call to
bplib_load
is made, the code checks to see if there is an Aggregate Custody Signal which exists in memory but has not been sent for at least dacs_rate seconds. -
protocol_version: Which version of the bundle protocol to use; currently the library only supports version 6.
-
retransmit_order: The order in which bundles that have timed-out are retransmitted. There are currently two retransmission orders supported: BP_RETX_OLDEST_BUNDLE, and BP_RETX_SMALLEST_CID.
-
active_table_size: The number of unacknowledged bundles to keep track of. The larger this number, the more bundles can be sent before a "wrap" occurs (see BP_OPT_WRAP_RESPONSE). But every unacknowledged bundle consumes 8 bytes of CPU memory making this attribute the primary driver for a channel's memory usage.
-
max_fills_per_dacs: The maximum number of fills in the Aggregate Custody Signal. An Aggregate Custody Signal is sent when the maximum fills are reached or the dacs_rate period has expired (see BP_OPT_DACS_RATE).
-
max_gaps_per_dacs: The maximum number of Custody ID gaps a channel can keep track up when receiving bundles requesting custody transfer. If this gap limit is reached, the Aggregate Custody Signal is sent and a new one immediately begins to accumulate acknowledgments.
-
recover_storage: Instructs the storage service to attempt to recover the bundles and payloads assocaited with a previous channel with the same local node and service.
-
storage_service_parm: A pass through to the storage service
create
function.
returns
- pointer to a channel descriptor. On error, NULL is returned.
void bplib_close (bp_desc_t* desc)
Closes the specified bundle channel and releases all run-time resources associated with it; this does not include the bundles stored in the storage service; nor does it include bundles that have been transmitted but not yet acknowledged (active bundles). The close call is not mutex'ed against other channel operations - it is the caller's responsibility that the close call is made non-concurrently with any other library function call on that channel.
desc
- a descriptor for which channel to close
int bplib_flush (bp_desc_t* desc)
Flushes all active bundles on a channel; this treats each bundle that has been transmitted but not yet acknowledged as if it was immediately acknowledged. This function is separate from the bplib_close function because it is possible that a storage service supports resuming where it left off after a channel is closed. In such a case, closing the channel would occur without flushing the data since the next time the channel was opened, the data that had not yet been relinquished would resume being sent.
channel
- a descriptor for which channel to flush
int bplib_config (bp_desc_t* desc, int mode, int opt, void* val, int len)
Configures or retrieves an attribute on a channel.
desc
- a descriptor for which channel to configure or retrieve attribute
mode
- whether to read or write the attribute
-
BP_OPT_MODE_READ: the attribute is read and placed into the memory localtion pointed to by val
-
BP_OPT_MODE_WRITE: the attribute is written with the value stored at the memory location pointed to by val
opt
- the attribute to perform the operation on, as described in the table below. The different attributes that can be changed or read are further described in the Open Channel section.
Option | Units | Default | Description |
---|---|---|---|
BP_OPT_LIFETIME | int | 0 | Amount of time in seconds added to creation time specifying duration of time bundle is considered valid, 0: infinite |
BP_OPT_REQUEST_CUSTODY | int | 1 | Sets whether transmitted bundles request custody transfer, 0: false, 1: true |
BP_OPT_ADMIN_RECORD | int | 0 | Sets whether generated bundles are administrative records, 0: false, 1: true |
BP_OPT_INTEGRITY_CHECK | int | 1 | Sets whether transmitted bundles include a BIB extension block, 0: false, 1: true |
BP_OPT_ALLOW_FRAGMENTATION | int | 1 | Sets whether transmitted bundles are allowed to be fragmented, 0: false, 1: true |
BP_OPT_CIPHER_SUITE | int | BP_BIB_CRC16_X25 | The type of Cyclic Redundancy Check used in the BIB extension block - BP_BIB_NONE, BP_BIB_CRC16_X25, BP_BIB_CRC32_CASTAGNOLI |
BP_OPT_TIMEOUT | int | 10 | Amount of time in seconds to wait for positive acknowledgment of transmitted bundles before retransmitting, 0: infinite |
BP_OPT_MAX_LENGTH | int | 4096 | Maximum length of the transmitetd bundles |
BP_WRAP_BLOCK, BP_WRAP_DROP | |||
BP_OPT_CID_REUSE | int | 0 | Sets whether retransmitted bundles reuse their original custody ID, 0: false, 1: true |
BP_OPT_DACS_RATE | int | 5 | Sets minimum rate of ACS generation |
NOTE: transmitted bundles include both bundles generated on the channel from local data that is stored, as well as bundles that are received and forwarded by the channel.
val
- the value set or returned
len
- the length in bytes of the memory pointed to by val
returns
- return code.
int bplib_latchstats (bp_desc_t* desc, bp_stats_t* stats)
Retrieve channel statistics populated in the structure pointed to by stats.
desc
- a descriptor for channel to retrieve statistics on
stats
- pointer to the statistics structure to be populated
-
lost: number of deleted bundles due to: storage failure, and memory copy failure
-
expired: number of deleted bundles due to their lifetime expiring
-
unrecognized: number of bundles that were attempted to be processed but either could not be parsed or were of an unsupported type
-
transmitted_bundles: number of bundles returned by the
bplib_load
function for the first time (does not include retransmissions) -
transmitted_dacs: number of dacs returned by the
bplib_load
function -
retransmitted_bundles: number of bundles returned by the
bplib_load
function because the bundle timed-out and is being resent -
delivered_payloads: number of bundle payloads delivered to the application via the
bplib_accept
function -
received_bundles: number of bundles destined for the local node that were successfully processed by the
bplib_process
function; the payload was successfully stored by the storage service and is awaiting acceptance -
forwarded_bundles: number of bundles destined for the another node that were successfully processed by the
bplib_process
function; this does not indicated that the forwarded bundle was transmitted, only that it was successfully stored by the storage service and is awaiting transmission. -
received_dacs: number of DACS destined for the local node that were successfully processed by the
bplib_process
function; this only counts the DACS bundles received by the local node, not the bundles acknowledged by the DACS - that is represented in the acknowledged_bundles statistic. -
stored_bundles: number of data bundles currently in storage
-
stored_payloads: number of payloads currently in storage
-
stored_dacs: number of aggregate custody signal bundles currently in storage
-
acknowledged_bundles: number of locally stored bundles positively acknowleged and deleted due to a custody signal acknowledgment
-
active_bundles: number of bundles that have been loaded for which no acknowledgment has been received
int bplib_store (bp_desc_t* desc, void* payload, int size, int timeout, uint32_t* flags)
Initiates sending the data pointed to by payload as a bundle. The data will be encapsulated in a bundle (or many bundles if the channel allows fragmentation and the payload exceeds the maximum bundle length) and queued in storage for later retrieval and transmission.
desc
- a descriptor for channel to create bundle on
payload
- pointer to data to be bundled
size
- size of payload in bytes
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
flags
- flags that provide additional information on the result of the store operation (see flags). The flags variable is not initialized inside the function, so any value it has prior to the function call will be retained.
returns
- size of bundle created in bytes, or return code on error.
int bplib_load (bp_desc_t* desc, void** bundle, int* size, int timeout, uint32_t* flags)
Reads the next bundle from storage to be sent by the application over the convergence layer. From the perspective of the library, once a bundle is loaded to the application, it is as good as sent. Any failure of the application to send the bundle is treated no differently that a failure downstream in the bundle reaching its destination. On the other hand, the memory containing the bundle returned by the library is kept valid until the bplib_ackbundle
function is called, which must be called once for every returned bundle. So while subsequent calls to bplib_load
will continue to provide the next bundle the library determines should be sent, the application is free to hold onto the bundle buffer and keep trying to send it until it acknowledges the bundle to the library.
desc
- a descriptor for channel to retrieve bundle from
bundle
- pointer to a bundle buffer pointer; on success, the library will populate this pointer with the address of a buffer containing the bundle that is loaded.
size
- pointer to a variable holding the size in bytes of the bundle buffer being returned, populated on success.
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
flags
- flags that provide additional information on the result of the load operation (see flags). The flags variable is not initialized inside the function, so any value it has prior to the function call will be retained.
returns
- the bundle reference, the size of the bundle, and return code
int bplib_process (bp_desc_t* desc, void* bundle, int size, int timeout, uint32_t* flags)
Processes the provided bundle.
There are three types of bundles processed by this function: (1) If the bundle is an aggregate custody signal, then any acknowledged bundles will be freed from storage. (2) If the bundle is destined for the local node, then the payload data will be extracted and queued for retrieval by the application; and if custody is requested, then the current aggregate custody signal will be updated and queued for transmission if necessary. (3) If the bundle is not destined for the local node, then the bundle will be queued for transmission as a forwarded bundle; and if custody is requested, then the current aggregate custody signal will be updated and queued for transmission if necessary.
desc
- a descriptor for channel to process bundle on
bundle
- pointer to a bundle
size
- size of the bundle in bytes
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
flags
- flags that provide additional information on the result of the process operation (see flags). The flags variable is not initialized inside the function, so any value it has prior to the function call will be retained.
returns
- return code.
int bplib_accept (bp_desc_t* desc, void** payload, int* size, int timeout, uint32_t* flags)
Returns the next available bundle payload (from bundles that have been received and processed via the bplib_process
function) to the application. The memory containing the payload returned by the library is kept valid until the bplib_ackpayload
function is called, which must be called once for every returned payload. So while subsequent calls to bplib_accept
will continue to provide the next payload the library determines should be accepted, the payload will not be deleted from the library's storage service until it is acknowledged by the application.
desc
- a descriptor for channel to accept payload from
payload
- pointer to a payload buffer pointer; on success, the library will populate this pointer with the address of a buffer containing the payload that is accepted.
size
- pointer to a variable holding the size in bytes of the payload buffer being returned, populated on success.
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
flags
- flags that provide additional information on the result of the accept operation (see flags). The flags variable is not initialized inside the function, so any value it has prior to the function call will be retained.
returns
- the payload reference, the size of the payload, and return code
int bplib_ackbundle (bp_desc_t* desc, void* bundle)
Informs the library that the memory and storage used for the payload can be freed. The memory will be immediately freed, the storage will be freed immediately only if the bundle is not requesting custody transfer (otherwise, if the bundle is requesting custody transfer, then the ACS acknowledgment frees the storage). This must be called at some point after every bundle that is loaded.
desc
- a descriptor for channel to acknowlwedge bundle
bundle
- pointer to the bundle buffer to be acknowledged
returns
- return code
int bplib_ackpayload (bp_desc_t* desc, void* payload)
Informs the library that the memory and storage used for the payload can be freed. This must be called at some point after every payload that is accepted.
desc
- a descriptor for channel to acknowlwedge payload
payload
- pointer to the payload buffer to be acknowledged
returns
- return code
int bplib_routeinfo (void* bundle, int size, bp_route_t* route)
Parses the provided bundle and supplies its endpoint ID node and service numbers. Used to route a received bundle to the appropriate channel by looking up its destination endpoint ID prior to making other library calls that require a channel identifier.
bundle
- pointer to a buffer of memory containing a properly formatted bundle
size
- size of the bundle
route
- pointer to a route structure that is populated by the function (see Open Channel for more details on the structure contents).
returns
- return code
int bplib_display (void* bundle, int size, uint32_t* flags)
Parses the provided bundle (transversing the primary block, extension blocks, and payload block), and logs debug information about the bundle.
bundle
- pointer to a buffer of memory containing a properly formatted bundle
size
- size of the bundle
flags
- flags that provide additional information on the result of the accept operation (see flags). The flags variable is not initialized inside the function, so any value it has prior to the function call will be retained.
returns
- return code
int bplib_eid2ipn (const char* eid, int len, bp_ipn_t* node, bp_ipn_t* service)
Convert a enpoint ID string into the IPN node and service numbers
eid
- string containing the endpoint ID
len
- length of the eid string
node
- pointer to variable that will be populated with the node number
service
- pointer to the variable that will be populated with the service number
int bplib_ipn2eid (char* eid, int len, bp_ipn_t node, bp_ipn_t service)
Convert an IPN node and service number to an enpoint ID string
eid
- pointer to a buffer that will be populated with the endpoint ID string
len
- length of the eid buffer
node
- node number used to populate the endpoint ID string
service
- service number used to populate the endpoint ID string
int bplib_attrinit (bp_attr_t* attr)
Initialize an attribute structure with the library default values. This is useful when creating a channel where only a few attributes need to be changed.
attr
- pointer to attributes structure populated by the function (see Open Channel for more details on the attributes structure contents).
Code | Value | Description |
---|---|---|
BP_SUCCESS | 0 | Operation successfully performed |
BP_ERROR | -1 | Generic error occurred; further information provided in flags to determine root cause |
BP_TIMEOUT | -2 | A timeout occurred when a blocking operation was performed |
Flag | Value | Description |
---|---|---|
BP_FLAG_DIAGNOSTIC | 0x00000000 | No event issued - diagnostic message only |
BP_FLAG_NONCOMPLIANT | 0x00000001 | Valid bundle but the library was not able to comply with the standard |
BP_FLAG_INCOMPLETE | 0x00000002 | At least one block in bundle was not recognized |
BP_FLAG_UNRELIABLE_TIME | 0x00000004 | The time returned by the O.S. preceded the January 2000 epoch, or went backwards |
BP_FLAG_DROPPED | 0x00000008 | A bundle was dropped because a required extension block could not be processed |
BP_FLAG_FAILED_INTEGRITY_CHECK | 0x00000010 | A bundle with a BIB failed the integrity check on the payload |
BP_FLAG_BUNDLE_TOO_LARGE | 0x00000020 | The size of a bundle exceeds the capacity allowed by library |
BP_FLAG_ROUTE_NEEDED | 0x00000040 | A bundle needs to be routed before transmission |
BP_FLAG_STORE_FAILURE | 0x00000080 | Storage service failed to deliver data |
BP_FLAG_UNKNOWN_CID | 0x00000100 | An ACS bundle acknowledged a CID for which no bundle was found |
BP_FLAG_SDNV_OVERFLOW | 0x00000200 | The local variable used to read/write and the value was of insufficient width |
BP_FLAG_SDNV_INCOMPLETE | 0x00000400 | There was insufficient room in block to read/write value |
BP_FLAG_ACTIVE_TABLE_WRAP | 0x00000800 | The active table wrapped; see BP_OPT_WRAP_RESPONSE |
BP_FLAG_DUPLICATES | 0x00001000 | The custody ID was already acknowledged |
BP_FLAG_CUSTODY_FULL | 0x00002000 | An aggregate custody signal was generated due the number of custody ID gaps exceeded the maximum allowed |
BP_FLAG_UNKNOWNREC | 0x00004000 | A bundle contained unknown administrative record |
BP_FLAG_INVALID_CIPHER_SUITEID | 0x00008000 | An invalid cipher suite ID was found in a BIB |
BP_FLAG_INVALID_BIB_RESULT_TYPE | 0x00010000 | An invalid result type was found in a BIB |
BP_FLAG_INVALID_BIB_TARGET_TYPE | 0x00020000 | An invalid target type was found in a BIB |
BP_FLAG_FAILED_TO_PARSE | 0x00040000 | Unable to parse a bundle due to internal inconsistencies in bundle |
BP_FLAG_API_ERROR | 0x00080000 | Calling program incorrectly used a library function, e.g. passing in invalid parameter |
The application is responsible for providing the storage service to the library at run-time through call-backs passed to the bplib_open
function.
int create (int type, bp_ipn_t node, bp_ipn_t service, bool recover, void* parm)
Creates a storage service.
type
- the type of bundle being stored, will be one of the following (defined in bplib.h): BP_STORE_DATA_TYPE, BP_STORE_DACS_TYPE, BP_STORE_PAYLOAD_TYPE
node
- the {node} number of the ipn:{node}.{service} endpoint ID used for the source of bundles generated on the channel
service
- the {service} number of the ipn:{node}.{service} endpoint ID used for the source of bundles generated on the channel
recover
- true: attempt to recover bundles from existing storage that matches the type, node, and service; false: do not recover any bundles. Note that a storage service does not need to provide a recovery capability, in which case this parameter is ignored and bundles are never recovered.
parm
- service specific parameters pass through library to this function. See the storage_service_parm of the attributes structure passed to the bplib_open
function.
returns
- handle for storage service used in subsequence calls.
int destroy (bp_handle_t h)
Destroys a storage service. This does not mean that the data stored in the service is freed - that is service specific.
handle
- handle to the storage service
returns
- return code
int enqueue (bp_handle_t h, void* data1, int data1_size, void* data2, int data2_size, int timeout)
Stores the pointed to data into the storage service.
handle
- handle to the storage service
data1
- pointer to first block of memory to store. This must be concatenated with data2 by the function into one continuous block of data.
data1_size
- size of first block of memory to store.
data2
- pointer to second block of memory to store. This must be concatenated with data1 by the function into one continuous block of data.
data2_size
- size of the second block of memory to store.
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
returns
- return code
int dequeue (bp_handle_t h, void** data, int* size, bp_sid_t* sid, int timeout)
Retrieves the oldest data block stored in the storage service that has not yet been dequeued, and returns a Storage ID that can be used to retrieve the data block in the future.
handle
- handle to the storage service
data
- the pointer that will be updated to point to the retrieved block of memory. This function returns the data block via a pointer and performs no copy. The data is still owned by the storage service and is only valid until the next dequeue or relinquish call.
size
- size of data block being retrieved.
sid
- pointer to a Storage ID variable populated by the function. The sid variable is used in future storage service functions to identify the retrieved data block.
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
returns
- return code
int retrieve (bp_handle_t h, void** data, int* size, bp_sid_t sid, int timeout)
Retrieves the data block stored in the storage service identified by the Storage ID sid parameter.
handle
- handle to the storage service
data
- the pointer that will be updated to point to the retrieved block of memory. This function returns the data block via a pointer and performs no copy. The data is still owned by the storage service and is only valid until the next dequeue or relinquish call.
size
- size of data block being retrieved.
sid
- the Storage ID that identifies which data block to retrieve from the storage service
timeout
- 0: check, -1: pend, 1 and above: timeout in milliseconds
returns
- return code
int release (bp_handle_t h, bp_sid_t sid)
Releases any in-memory resources associated with the dequeueing or retrieval of a bundle.
handle
- handle to the storage service
sid
- the Storage ID that identifies the data block for which memory resources are released.
returns
- return code
int relinquish (bp_handle_t h, bp_sid_t sid)
Deletes the stored data block identified by the Storage ID sid parameter.
handle
- handle to the storage service
sid
- the Storage ID that identifies which data block to delete from storage
returns
- return code
int getcount (bp_handle_t h)
Returns the number of data blocks currently stored in the storage service.
handle
- handle to the storage service
returns
- number of data blocks
The storage service call-backs must have the following characteristics:
enqueue
,dequeue
,retrieve
, andrelinquish
are expected to be thread safe against each other.create
anddestroy
do not need to be thread safe against each other or any other function call - the application is responsible for calling them when it can complete atomically with respect to any other storage service call- The memory returned by the dequeue and retrieve function is valid until the release function call. Every dequeue and retrieve issued by the library will be followed by a release.
- The Storage ID (SID) returned by the storage service cannot be zero since that is marked as a VACANT SID