diff --git a/Makefile b/Makefile index 993d1d71..77ac118a 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ # ############################################################################## -## DEFINITIONS +## DEFINITIONS # bplib repository root directory ROOT := . @@ -246,7 +246,7 @@ testcov: ## STATIC ANALYSIS RULES CHECK_OPT = --enable=all --inconclusive --error-exitcode=1 -q -CHECK_OPT += --suppress=unusedFunction --suppress=missingInclude +CHECK_OPT += --suppress=unusedFunction --suppress=missingInclude CHECK_OPT += --suppress=objectIndex:common/crc.c CHECK_OPT += --suppress=redundantAssignment:v6/dacs.c CHECK_OPT += --suppress=memleak:os/cfe.c diff --git a/README.md b/README.md index 689ee531..ea31b941 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # bplib -[1. Overview](#1-overview) -[2. Build with Make](#2-build-with-make) -[3. Application Design](#3-application-design) -[4. Application Programming Interface](#4-application-programming-interface) -[5. Storage Service](#5-storage-service) - -[Note #1 - Bundle Protocol Version 6](doc/bpv6_notes.md) -[Note #2 - Library Development Guidelines](doc/dev_notes.md) -[Note #3 - Configuration Parameter Trades](doc/parm_notes.md) -[Note #4 - Bundle Flow Analysis for Intermittent Communication](doc/perf_analysis_ic.md) +[1. Overview](#1-overview) +[2. Build with Make](#2-build-with-make) +[3. Application Design](#3-application-design) +[4. Application Programming Interface](#4-application-programming-interface) +[5. Storage Service](#5-storage-service) + +[Note #1 - Bundle Protocol Version 6](doc/bpv6_notes.md) +[Note #2 - Library Development Guidelines](doc/dev_notes.md) +[Note #3 - Configuration Parameter Trades](doc/parm_notes.md) +[Note #4 - Bundle Flow Analysis for Intermittent Communication](doc/perf_analysis_ic.md) ---------------------------------------------------------------------- ## 1. Overview diff --git a/app/bpio.h b/app/bpio.h index 1c01f27c..ee281d07 100644 --- a/app/bpio.h +++ b/app/bpio.h @@ -44,9 +44,9 @@ typedef struct { bp_desc_t* bpc; char data_ip_addr[PARM_STR_SIZE]; - int data_port; + int data_port; char dacs_ip_addr[PARM_STR_SIZE]; - int dacs_port; + int dacs_port; } thread_parm_t; #endif /* __bpio_h__ */ \ No newline at end of file diff --git a/app/sock.c b/app/sock.c index a3a7d538..ce6d7f14 100644 --- a/app/sock.c +++ b/app/sock.c @@ -97,7 +97,7 @@ static int sockkeepalive(int socket_fd, int idle, int cnt, int intvl) display_error("Failed to set TCP_KEEPINTVL option on socket, %s\n", strerror(errno)); return SOCK_INVALID; } - + return 0; } @@ -115,7 +115,7 @@ static int sockreuse(int socket_fd) display_error("Failed to set SO_REUSEADDR option on socket, %s\n", strerror(errno)); return SOCK_INVALID; } - + return 0; } @@ -150,30 +150,30 @@ int sockcreate(int type, const char* ip_addr, int port, int is_server, int* bloc char portstr[SOCK_PORT_STR_LEN]; char host[SOCK_HOST_STR_LEN]; char serv[SOCK_SERV_STR_LEN]; - + /* Check Address */ if(!ip_addr) ip_addr = "0.0.0.0"; // wildcard - + /* Initialize Port */ snprintf(portstr, SOCK_PORT_STR_LEN, "%d", port); - + /* Get Destination Host */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; /* IPv4 */ hints.ai_socktype = type; status = getaddrinfo(ip_addr, portstr, &hints, &result); - if(status != 0) + if(status != 0) { display_error("Failed to get address info for %s:%d, %s\n", ip_addr, port, gai_strerror(status)); return SOCK_INVALID; } /* Try each address until we successfully connect. */ - for(rp = result; rp != NULL; rp = rp->ai_next) + for(rp = result; rp != NULL; rp = rp->ai_next) { /* Get address information */ status = getnameinfo(rp->ai_addr,rp->ai_addrlen, host, SOCK_HOST_STR_LEN, serv, SOCK_SERV_STR_LEN, NI_NUMERICHOST | NI_NUMERICSERV); - + /* Create socket */ sock = socket(rp->ai_family, rp->ai_socktype, 0); if(sock < 0) @@ -208,13 +208,13 @@ int sockcreate(int type, const char* ip_addr, int port, int is_server, int* bloc do { /* Connect Socket */ status = connect(sock, rp->ai_addr, rp->ai_addrlen); - if(status < 0) + if(status < 0) { display_error("Failed to connect socket to %s:%s... %s\n", host, serv, strerror(errno)); sleep(1); } } while(status < 0 && block && *block); - + /* Check Connection */ if(status < 0) close(sock); else break; @@ -247,7 +247,7 @@ int sockcreate(int type, const char* ip_addr, int port, int is_server, int* bloc } /* Return Client TcpSocket */ - return sock; + return sock; } /*----------------------------------------------------------------------------* @@ -258,7 +258,7 @@ int sockstream(const char* ip_addr, int port, int is_server, int* block) /* Create initial socket */ int sock = sockcreate(SOCK_STREAM, ip_addr, port, is_server, block); if(sock == SOCK_INVALID) return SOCK_INVALID; - + if(!is_server) // client { return sock; @@ -382,7 +382,7 @@ int socksend(int fd, const void* buf, int size, int timeout) if(c == 0) { c = SOCK_INVALID; - } + } else if(c < 0) { display_error("Failed (%d) to send data to ready socket [%0X]: %s\n", c, revents, strerror(errno)); diff --git a/binding/lua/lua_bplib.h b/binding/lua/lua_bplib.h index 63cf463f..e205f0be 100644 --- a/binding/lua/lua_bplib.h +++ b/binding/lua/lua_bplib.h @@ -1,13 +1,13 @@ /************************************************************************ * File: lua_bplib.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/common/rb_tree.h b/common/rb_tree.h index 6ae7828e..c4182b42 100644 --- a/common/rb_tree.h +++ b/common/rb_tree.h @@ -1,13 +1,13 @@ /************************************************************************ * File: rb_tree.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -39,9 +39,9 @@ typedef struct rb_range { typedef struct rb_node { rb_range_t range; /* The range of cids represented by the node. */ bool color; /* The color of the node where RED (True) and BLACK (False). */ - bool traversal_state; /* Tracks when a node is visited in a tree traversal. */ + bool traversal_state; /* Tracks when a node is visited in a tree traversal. */ /* The respective ancestors of the current node within the red black tree. - * Child nodes that are null are assumed to be black in color. The root node + * Child nodes that are null are assumed to be black in color. The root node * of the red black tree has a null parent. */ struct rb_node* left; struct rb_node* right; @@ -56,21 +56,21 @@ typedef struct rb_tree { rb_node_t* free_node_head; /* The memory location of the first unallocated rb_node. */ rb_node_t* free_node_tail; /* The memory location of the last unallocated rb_node. */ rb_node_t* iterator; /* The current node when using iterator functions */ - /* The starting memory address of the allocated memory for rb_nodes. + /* The starting memory address of the allocated memory for rb_nodes. * This value is tracked so that the nodes can be deallocated in a single call to free. */ - rb_node_t* node_block; + rb_node_t* node_block; } rb_tree_t; /****************************************************************************** PROTOTYPES ******************************************************************************/ -/* Red Black Tree API +/* Red Black Tree API * * NOTE: The rb_tree_t is limited by its maximum size data type, in this case a bp_val_t. * Since ranges are being stored no range will ever exceed BP_MAX_ENCODED_VALUE nor will the tree be able * to allocate more than BP_MAX_ENCODED_VALUE nodes even if the memory is available. - * + * */ int rb_tree_create (bp_val_t max_size, rb_tree_t* tree); /* Creates am empty rb_tree. */ diff --git a/common/rh_hash.c b/common/rh_hash.c index 054407ef..72d63d2d 100644 --- a/common/rh_hash.c +++ b/common/rh_hash.c @@ -119,7 +119,7 @@ int rh_hash_create(rh_hash_t** rh_hash, int size) if(size > 0) { int i; - + /* Allocate Hash Table */ (*rh_hash)->table = (rh_hash_node_t*)bplib_os_calloc(size * sizeof(rh_hash_node_t)); if((*rh_hash)->table == NULL) return BP_ERROR; diff --git a/common/rh_hash.h b/common/rh_hash.h index 7f3182cb..e443ee4e 100644 --- a/common/rh_hash.h +++ b/common/rh_hash.h @@ -1,13 +1,13 @@ /************************************************************************ * File: rh_hash.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/doc/bpv6_notes.md b/doc/bpv6_notes.md index b68e5634..30538ba8 100644 --- a/doc/bpv6_notes.md +++ b/doc/bpv6_notes.md @@ -1,242 +1,242 @@ -# Bundle Protocol Version 6 Notes - -[1. Protocol Compliance and Tailoring](#1-protocol-compliance-and-tailoring) -[2. Bundle Formats](#2-bundle-formats) - ----------------------------------------------------------------------- -## 1. Protocol Compliance and Tailoring ----------------------------------------------------------------------- - -#### 1.1 Endpoint IDs -* Compressed Bundle Header Encoding (CBHE) is used on all generated data bundles. -* The only addressing schema supported by the BP library is the "ipn" schema defined in RFC6260. -* The format of endpoint IDs as defined by this schema are "ipn:{node}.{service}" where {node} and {service} are unsigned integers encoded as SDNVs in the bundle header block. -* Constant static data structures declared in the code set the size of all endpoint IDs. All {node} numbers are 28 bits (which occupies 32 bits of bundle memory encoded as an SDNV), and all {service} numbers are 14 bits (which occupies 16 bits of bundle memory encoded as an SDNV). -* The convention used by the BP library is that {node} number identifies the endpoint application agent and the {service} number identifies a flow of data that is able to be processed by the application agent. -* All endpoints are treated as singletons and marked as such in the PCF, even for forwarded bundles. - -#### 1.2 Fixed Size SDNVs -* The BP library uses fixed sized SDNVs for all SDNV fields of generated bundles. -* Bundles that are received by the library can have any size SDNV as long as the encoded value fits within the `unsigned long` integer for the local platform the library is compiled on. - -#### 1.3 Creation Time Sequence -* The BP library does not reset the creation time sequence number, but maintains a strictly incrementing value (stepped by one for each successive bundle created) per channel. This allows receiving nodes to detect gaps in the data and allows reconstruction of the original sending order of the data. - -#### 1.4 Lifetimes -* The BP library calculates an absolute time for a bundles expiration at the time the bundle is created. -* The expiration time is checked prior to transmission and on receipt (in `bplib_load` and `bplib_process` functions). -* A value of zero has special meaning when using bplib and specifies an infinite lifetime, this is different than the protocol specification which interprets zero as an immediate expiration. In order to be compatible with other BP nodes, ULONG_MAX - 1 should be used to set the maximum lifetime (136 years on 32-bit machine). -* The lifetime setting of a bundle is the ***minimal*** amount of time the bundle will remain in the system. It is possible and likely that the bundle will exist in the system and consume storage resources longer than its lifetime as the lifetime is only checked at certain points in the code. What can be said is that a bundle with an expired lifetime will not be transmitted by the library, nor will the payload of an expired bundle be passed to the application. - -#### 1.5 Administrative Records -* The only supported administrative record type is the aggregate custody signal, all other record types are ignored. -* The report to EID for bundles generated by this library is set to the null EID. - -#### 1.6 DTN Aggregate Custody Signaling -* The BP library only supports custody transfers when DTN Aggregate Custody Signals are used. Regular RFC5050 custody signals are not supported. A custody signal bundle received by the library is ignored. -* A data bundle received by the library that is requesting custody transfer without a CTEB is dropped. -* ACS acknowledgments are delivered to the “custodian” node and service provided in the bundle. -* The rate that ACS bundles are sent is controlled via a receiver node configuration setting. The BP library has a run-time defined maximum number of fills per ACS, and a dynamically configurable setting for the longest time a partially full ACS bundle can remain in memory before it is sent. -* Only positive acknowledgements are generated (i.e. ACS bundles mark the appropriate fields indicating positive acknowledgment of custody transfer). This means that the lifetime of a bundle and the timeout setting of the sending bundle agent completely define the bundle’s retransmission behavior. - -#### 1.7 Bundle Integrity -* The BP library inserts a BIB in all data bundles it generates and all data bundles it accepts custody of for forwarding. -* Bundles received by the library are not required to have BIBs, but if they do, then the bundle is verified against the BIB prior to accepting custody (if requested) and processing the payload (if destined for the local node). - -#### 1.8 Timeouts -* Timeout processing is not fully implemented. The library keeps track of active bundles (i.e. bundles that have been sent but not acknowledged) in a circular buffer of bundle references that maintain strictly incrementing custody IDs. When the application requests a bundle to be loaded, only the oldest active bundle is checked for a timeout. -* If CID_REUSE is set, then the age of the bundle is measure against the first time it was sent; otherwise if CID_REUSE is not set, then the age of the bundle is measure against the most recent time it was sent. -* If the circular buffer wraps and the oldest active bundle has not timed out, then onboard transmission of bundles stop until the oldest bundle times out. - -#### 1.9 Class of Service -* The class of service of generated data bundles and received bundles is set to normal and otherwise completely ignored. - -#### 1.10 Fragmentation -* Custody transfer is requested per fragment. In other words, each fragment has its own CTEB. -* A fragment of a bundle that requests custody transfer, and is sent to an intermediary hop, is acknowledged and forwarded by that hop without requiring the entire original bundle to be reconstituted. Even though it is not required, there is also no assumed constraint on the fragment being further fragmented, or combined with other fragments if they are available. -* Bundle integrity via the BIB is always applied to each fragment. If the library generates fragmented bundles, it will put a BIB in each fragment. If a bundle with a BIB is received that is to be forwarded, and needs to be fragmented, then the BIB is checked upon receipt, and then that original BIB is dropped. The outgoing fragmented bundles will all have their own BIB generated by the library. This applies even when the BIB block flags indicate that the block is to be kept. - -#### 1.11 Routing -* If a BP library channel receives bundles to be forwarded then the pre-build bundle headers are marked as dirty and rebuilt when the local node generates bundles of its own to be sent. The result is a temporary loss of performance. -* When a call to the BP library returns a bundle, it will set a flag if the bundle needs to be routed to a different destination than the channel’s default destination. -* When routing bundles, the BP library will associate any bundle with a destination {node} that matches its local {node} number as being destined for itself and will then require that the {service} number matches the channel's {service} number that it is being processed on. Any bundle with a {node} that is different than its local {node} number is treated as a bundle that needs to be routed. -* A service number of 0 is considered a global service and is allowed to be passed to any channel associated with the node. - -#### 1.12 Payload Block -* The library assumes that the last block of every bundle is the payload block and stops processing the bundle when the payload block is reached. - -#### 1.13 Bundle Protocol Agent (BPA) Services -* The concept of a BPA corresponds to a bundle channel. -* There is no concept of __switchin__ between an Active and Passive state for the BPA. A registration is __commenced__ when a channel is opened, and __terminated__ when a channel is closed. -* There is no concept of __polling__ the state of the BPA as there is no concept of an Active or Passive state. -* Bundles are __transmitted__ via the `bplib_store` and `bplib_load` APIs, but __transmission__ cannot be __cancelled__. -* Bundles are __delivered__ via the `bplib_process` and `bplib_accept` APIs. - ----------------------------------------------------------------------- -## 2. Bundle Formats ----------------------------------------------------------------------- - -#### 2.1 Data Bundle -``` - ------------------------------------------------- - Data Bundle - ------------------------------------------------- - |-----------------------------------------------| - | | - | Primary Bundle Block | - | | - |-----------------------------------------------| - | | - | Custody Transfer Extension Block | - | | - |-----------------------------------------------| - | | - | Bundle Integrity Block | - | | - |-----------------------------------------------| - | | - | Bundle Payload Block | - | | - |-----------------------------------------------| -``` - -#### 2.2 DTN Aggregate Custody Signal (DACS) -``` - ------------------------------------------------- - Aggregate Custody Signal - ------------------------------------------------- - |-----------------------------------------------| - | | - | Primary Bundle Block | - | | - |-----------------------------------------------| - | | - | Bundle Integrity Block | - | | - |-----------------------------------------------| - | | - | Bundle Payload Block | - | (ACS as administrative record in payload) | - | | - |-----------------------------------------------| -``` - -#### 2.3 Primary Bundle Block: Compressed Bundle Header Encoding (CBHE) -``` - ------------------------------------------------- - Primary Bundle Block - ------------------------------------------------- - | MSB | | | LSB | - | (8 bits) | (8 bits) | (8 bits) | (8 bits) | - |-----------|-----------|-----------|-----------| 0 - | Version | Processing Control Flags | - |-----------|-----------------------------------| 4 - | Blk Len | Destination Node ... - |-----------|-----------------------|-----------| 8 - ... | Destination Service | ... - |-----------|-----------------------|-----------| 12 - ... Source Node | Source - |-----------|-----------------------|-----------| 16 - Service | Report To Node ... - |-----------|-----------------------|-----------| 20 - ... | Report To Service | ... - |-----------|-----------------------|-----------| 24 - ... Custody Node | Custody - |-----------|-----------------------|-----------| 28 - Service | Creation Timestamp Seconds - |-----------|-----------------------|-----------| 32 - ... | Timestamp - |-----------|-----------------------|-----------| 36 - Sequence | Lifetime ... - |-----------|-----------------------|-----------| 40 - ... | Dict Len | - |-----------------------------------|-----------| 44 - | Fragment Offset | - |-----------------------------------------------| 48 - | Payload Length | - |-----------------------------------------------| 52 -``` - -#### 2.4 Custody Transfer Enhancement Block (CTEB) -``` - ------------------------------------------------- - Custody Transfer Enhancement Block - ------------------------------------------------- - | MSB | | | LSB | - | (8 bits) | (8 bits) | (8 bits) | (8 bits) | - |-----------|-----------|-----------|-----------| - | | - | Primary Bundle Block | - | | - |-----------|-----------|-----------------------| - . . . . - |-----------|-----------|-----------|-----------| 0 --> Custody Transfer Enhancement Block - | 0xA | Blk Flags | Blk Len | ... - |-----------|-----------|-----------|-----------| 4 - Custody ID | ... - |-----------------------|-----------------------| 8 - | Custodian EID (ASCII character array) | - |-----------------------------------------------| Variable -``` - -#### 2.5 Bundle Integrity Block (BIB) -``` - ------------------------------------------------- - Bundle Integrity Block - ------------------------------------------------- - | MSB | | | LSB | - | (8 bits) | (8 bits) | (8 bits) | (8 bits) | - |-----------|-----------|-----------|-----------| - | | - | Primary Bundle Block | - | | - |-----------|-----------|-----------------------| - . . . . - |-----------|-----------|-----------------------| 0 --> Bundle Integrity Block - | 0xD | Blk Flags | Block Length ... - |-----------|-----------|-----------|-----------| 4 - ... | STC | SBT | - |-----------|-----------|-----------|-----------| 8 - | CSI | CSF | CL | SRT | - |-----------|-----------|-----------|-----------| 12 - | SRL | Security Result ... - |-----------|-----------|-----------|-----------| Variable - - STC: Security Target Count (hardcoded to 1) - SBT: Security Target Block Type (hardcoded to 1) - CSI: Cipher Suite ID - CSF: Cipher Suite Flags - SRC: Compound Length (number of bytes that follow) - SRT: Security Result Type (hardcoded to 5) - SRL: Security Result Length (2 if CRC16, 4 if CRC32) -``` - -#### 2.6 Aggregate Custody Signal Block -``` - ------------------------------------------------- - DTN Aggregate Custody Signal Block - ------------------------------------------------- - | MSB | | | LSB | - | (8 bits) | (8 bits) | (8 bits) | (8 bits) | - |-----------|-----------|-----------|-----------| - | | - | Primary Bundle Block | - | | - |-----------|-----------|-----------------------| - . . . . - |-----------|-----------|-----------------------| 0 --> Payload BLock - | 0x1 | Blk Flags | Block Length ... - |-----------|-----------|-----------|-----------| 4 --> Aggregate Custody Signal - ... | 0x40 | Status | - |-----------|-----------|-----------|-----------| 8 - | First Custody ID | - |-----------------------|-----------------------| Variable - | Number Valid CIDs | Number Skipped CIDs | - |-----------------------|-----------------------| - | Number VAlid CIDs | Number Skipped CIDs | - |-----------------------|-----------------------| - . . . - |-----------------------|-----------------------| - | Number Valid CIDs | Number Skipped CIDs | - |-----------------------------------------------| Variable -``` +# Bundle Protocol Version 6 Notes + +[1. Protocol Compliance and Tailoring](#1-protocol-compliance-and-tailoring) +[2. Bundle Formats](#2-bundle-formats) + +---------------------------------------------------------------------- +## 1. Protocol Compliance and Tailoring +---------------------------------------------------------------------- + +#### 1.1 Endpoint IDs +* Compressed Bundle Header Encoding (CBHE) is used on all generated data bundles. +* The only addressing schema supported by the BP library is the "ipn" schema defined in RFC6260. +* The format of endpoint IDs as defined by this schema are "ipn:{node}.{service}" where {node} and {service} are unsigned integers encoded as SDNVs in the bundle header block. +* Constant static data structures declared in the code set the size of all endpoint IDs. All {node} numbers are 28 bits (which occupies 32 bits of bundle memory encoded as an SDNV), and all {service} numbers are 14 bits (which occupies 16 bits of bundle memory encoded as an SDNV). +* The convention used by the BP library is that {node} number identifies the endpoint application agent and the {service} number identifies a flow of data that is able to be processed by the application agent. +* All endpoints are treated as singletons and marked as such in the PCF, even for forwarded bundles. + +#### 1.2 Fixed Size SDNVs +* The BP library uses fixed sized SDNVs for all SDNV fields of generated bundles. +* Bundles that are received by the library can have any size SDNV as long as the encoded value fits within the `unsigned long` integer for the local platform the library is compiled on. + +#### 1.3 Creation Time Sequence +* The BP library does not reset the creation time sequence number, but maintains a strictly incrementing value (stepped by one for each successive bundle created) per channel. This allows receiving nodes to detect gaps in the data and allows reconstruction of the original sending order of the data. + +#### 1.4 Lifetimes +* The BP library calculates an absolute time for a bundles expiration at the time the bundle is created. +* The expiration time is checked prior to transmission and on receipt (in `bplib_load` and `bplib_process` functions). +* A value of zero has special meaning when using bplib and specifies an infinite lifetime, this is different than the protocol specification which interprets zero as an immediate expiration. In order to be compatible with other BP nodes, ULONG_MAX - 1 should be used to set the maximum lifetime (136 years on 32-bit machine). +* The lifetime setting of a bundle is the ***minimal*** amount of time the bundle will remain in the system. It is possible and likely that the bundle will exist in the system and consume storage resources longer than its lifetime as the lifetime is only checked at certain points in the code. What can be said is that a bundle with an expired lifetime will not be transmitted by the library, nor will the payload of an expired bundle be passed to the application. + +#### 1.5 Administrative Records +* The only supported administrative record type is the aggregate custody signal, all other record types are ignored. +* The report to EID for bundles generated by this library is set to the null EID. + +#### 1.6 DTN Aggregate Custody Signaling +* The BP library only supports custody transfers when DTN Aggregate Custody Signals are used. Regular RFC5050 custody signals are not supported. A custody signal bundle received by the library is ignored. +* A data bundle received by the library that is requesting custody transfer without a CTEB is dropped. +* ACS acknowledgments are delivered to the “custodian” node and service provided in the bundle. +* The rate that ACS bundles are sent is controlled via a receiver node configuration setting. The BP library has a run-time defined maximum number of fills per ACS, and a dynamically configurable setting for the longest time a partially full ACS bundle can remain in memory before it is sent. +* Only positive acknowledgements are generated (i.e. ACS bundles mark the appropriate fields indicating positive acknowledgment of custody transfer). This means that the lifetime of a bundle and the timeout setting of the sending bundle agent completely define the bundle’s retransmission behavior. + +#### 1.7 Bundle Integrity +* The BP library inserts a BIB in all data bundles it generates and all data bundles it accepts custody of for forwarding. +* Bundles received by the library are not required to have BIBs, but if they do, then the bundle is verified against the BIB prior to accepting custody (if requested) and processing the payload (if destined for the local node). + +#### 1.8 Timeouts +* Timeout processing is not fully implemented. The library keeps track of active bundles (i.e. bundles that have been sent but not acknowledged) in a circular buffer of bundle references that maintain strictly incrementing custody IDs. When the application requests a bundle to be loaded, only the oldest active bundle is checked for a timeout. +* If CID_REUSE is set, then the age of the bundle is measure against the first time it was sent; otherwise if CID_REUSE is not set, then the age of the bundle is measure against the most recent time it was sent. +* If the circular buffer wraps and the oldest active bundle has not timed out, then onboard transmission of bundles stop until the oldest bundle times out. + +#### 1.9 Class of Service +* The class of service of generated data bundles and received bundles is set to normal and otherwise completely ignored. + +#### 1.10 Fragmentation +* Custody transfer is requested per fragment. In other words, each fragment has its own CTEB. +* A fragment of a bundle that requests custody transfer, and is sent to an intermediary hop, is acknowledged and forwarded by that hop without requiring the entire original bundle to be reconstituted. Even though it is not required, there is also no assumed constraint on the fragment being further fragmented, or combined with other fragments if they are available. +* Bundle integrity via the BIB is always applied to each fragment. If the library generates fragmented bundles, it will put a BIB in each fragment. If a bundle with a BIB is received that is to be forwarded, and needs to be fragmented, then the BIB is checked upon receipt, and then that original BIB is dropped. The outgoing fragmented bundles will all have their own BIB generated by the library. This applies even when the BIB block flags indicate that the block is to be kept. + +#### 1.11 Routing +* If a BP library channel receives bundles to be forwarded then the pre-build bundle headers are marked as dirty and rebuilt when the local node generates bundles of its own to be sent. The result is a temporary loss of performance. +* When a call to the BP library returns a bundle, it will set a flag if the bundle needs to be routed to a different destination than the channel’s default destination. +* When routing bundles, the BP library will associate any bundle with a destination {node} that matches its local {node} number as being destined for itself and will then require that the {service} number matches the channel's {service} number that it is being processed on. Any bundle with a {node} that is different than its local {node} number is treated as a bundle that needs to be routed. +* A service number of 0 is considered a global service and is allowed to be passed to any channel associated with the node. + +#### 1.12 Payload Block +* The library assumes that the last block of every bundle is the payload block and stops processing the bundle when the payload block is reached. + +#### 1.13 Bundle Protocol Agent (BPA) Services +* The concept of a BPA corresponds to a bundle channel. +* There is no concept of __switchin__ between an Active and Passive state for the BPA. A registration is __commenced__ when a channel is opened, and __terminated__ when a channel is closed. +* There is no concept of __polling__ the state of the BPA as there is no concept of an Active or Passive state. +* Bundles are __transmitted__ via the `bplib_store` and `bplib_load` APIs, but __transmission__ cannot be __cancelled__. +* Bundles are __delivered__ via the `bplib_process` and `bplib_accept` APIs. + +---------------------------------------------------------------------- +## 2. Bundle Formats +---------------------------------------------------------------------- + +#### 2.1 Data Bundle +``` + ------------------------------------------------- + Data Bundle + ------------------------------------------------- + |-----------------------------------------------| + | | + | Primary Bundle Block | + | | + |-----------------------------------------------| + | | + | Custody Transfer Extension Block | + | | + |-----------------------------------------------| + | | + | Bundle Integrity Block | + | | + |-----------------------------------------------| + | | + | Bundle Payload Block | + | | + |-----------------------------------------------| +``` + +#### 2.2 DTN Aggregate Custody Signal (DACS) +``` + ------------------------------------------------- + Aggregate Custody Signal + ------------------------------------------------- + |-----------------------------------------------| + | | + | Primary Bundle Block | + | | + |-----------------------------------------------| + | | + | Bundle Integrity Block | + | | + |-----------------------------------------------| + | | + | Bundle Payload Block | + | (ACS as administrative record in payload) | + | | + |-----------------------------------------------| +``` + +#### 2.3 Primary Bundle Block: Compressed Bundle Header Encoding (CBHE) +``` + ------------------------------------------------- + Primary Bundle Block + ------------------------------------------------- + | MSB | | | LSB | + | (8 bits) | (8 bits) | (8 bits) | (8 bits) | + |-----------|-----------|-----------|-----------| 0 + | Version | Processing Control Flags | + |-----------|-----------------------------------| 4 + | Blk Len | Destination Node ... + |-----------|-----------------------|-----------| 8 + ... | Destination Service | ... + |-----------|-----------------------|-----------| 12 + ... Source Node | Source + |-----------|-----------------------|-----------| 16 + Service | Report To Node ... + |-----------|-----------------------|-----------| 20 + ... | Report To Service | ... + |-----------|-----------------------|-----------| 24 + ... Custody Node | Custody + |-----------|-----------------------|-----------| 28 + Service | Creation Timestamp Seconds + |-----------|-----------------------|-----------| 32 + ... | Timestamp + |-----------|-----------------------|-----------| 36 + Sequence | Lifetime ... + |-----------|-----------------------|-----------| 40 + ... | Dict Len | + |-----------------------------------|-----------| 44 + | Fragment Offset | + |-----------------------------------------------| 48 + | Payload Length | + |-----------------------------------------------| 52 +``` + +#### 2.4 Custody Transfer Enhancement Block (CTEB) +``` + ------------------------------------------------- + Custody Transfer Enhancement Block + ------------------------------------------------- + | MSB | | | LSB | + | (8 bits) | (8 bits) | (8 bits) | (8 bits) | + |-----------|-----------|-----------|-----------| + | | + | Primary Bundle Block | + | | + |-----------|-----------|-----------------------| + . . . . + |-----------|-----------|-----------|-----------| 0 --> Custody Transfer Enhancement Block + | 0xA | Blk Flags | Blk Len | ... + |-----------|-----------|-----------|-----------| 4 + Custody ID | ... + |-----------------------|-----------------------| 8 + | Custodian EID (ASCII character array) | + |-----------------------------------------------| Variable +``` + +#### 2.5 Bundle Integrity Block (BIB) +``` + ------------------------------------------------- + Bundle Integrity Block + ------------------------------------------------- + | MSB | | | LSB | + | (8 bits) | (8 bits) | (8 bits) | (8 bits) | + |-----------|-----------|-----------|-----------| + | | + | Primary Bundle Block | + | | + |-----------|-----------|-----------------------| + . . . . + |-----------|-----------|-----------------------| 0 --> Bundle Integrity Block + | 0xD | Blk Flags | Block Length ... + |-----------|-----------|-----------|-----------| 4 + ... | STC | SBT | + |-----------|-----------|-----------|-----------| 8 + | CSI | CSF | CL | SRT | + |-----------|-----------|-----------|-----------| 12 + | SRL | Security Result ... + |-----------|-----------|-----------|-----------| Variable + + STC: Security Target Count (hardcoded to 1) + SBT: Security Target Block Type (hardcoded to 1) + CSI: Cipher Suite ID + CSF: Cipher Suite Flags + SRC: Compound Length (number of bytes that follow) + SRT: Security Result Type (hardcoded to 5) + SRL: Security Result Length (2 if CRC16, 4 if CRC32) +``` + +#### 2.6 Aggregate Custody Signal Block +``` + ------------------------------------------------- + DTN Aggregate Custody Signal Block + ------------------------------------------------- + | MSB | | | LSB | + | (8 bits) | (8 bits) | (8 bits) | (8 bits) | + |-----------|-----------|-----------|-----------| + | | + | Primary Bundle Block | + | | + |-----------|-----------|-----------------------| + . . . . + |-----------|-----------|-----------------------| 0 --> Payload BLock + | 0x1 | Blk Flags | Block Length ... + |-----------|-----------|-----------|-----------| 4 --> Aggregate Custody Signal + ... | 0x40 | Status | + |-----------|-----------|-----------|-----------| 8 + | First Custody ID | + |-----------------------|-----------------------| Variable + | Number Valid CIDs | Number Skipped CIDs | + |-----------------------|-----------------------| + | Number VAlid CIDs | Number Skipped CIDs | + |-----------------------|-----------------------| + . . . + |-----------------------|-----------------------| + | Number Valid CIDs | Number Skipped CIDs | + |-----------------------------------------------| Variable +``` diff --git a/doc/dev_notes.md b/doc/dev_notes.md index 730f000d..261ae008 100644 --- a/doc/dev_notes.md +++ b/doc/dev_notes.md @@ -1,88 +1,88 @@ -# Developer Notes - -[1. Directory Structure](#1-directory-structure) -[2. Layered Architecture](#2-layered-architecture) -[3. Customization and Extensions](#3-customization-and-extensions) -[4. Coding Rules](#4-coding-rules) - - -## 1.0 Directory Structure - -```` -bplib // library build system -|-- binding // language bindings - |-- lua // Lua scripting language - |-- test // library unit test framework -|-- common // utilities and data structures -|-- doc // documentation -|-- inc // public API headers -|-- lib // high level protocol implementation -|-- os // operating system abstractions -|-- store // storage services -|-- unittest // c-code unit tests -|-- v6 // version 6 protocol implementation -```` - -## 2.0 Layered Architecture - -```` -+-----------+ -| bplib | -+-----------+ - | - | -+-----------+ -| v6 | -+-----------+ - |________________________________________________ - || || | | -+-----------+ +-----------+ +-----------+ +-----------+ -| pri | | pay | | bib | | cteb | -+-----------+ +-----------+ +-----------+ +-----------+ - | | - +-----------+ +-----------+ - | dacs | | sdnv | - +-----------+ +-----------+ - - -+-----------+ +-----------+ +-----------+ +-----------+ -| rb_tree | | rh_hash | | cbuf | | crc | -+-----------+ +-----------+ +-----------+ +-----------+ -```` - -## 3.0 Customization and Extension - -#### Storage Service - -The storage service is provided at __run-time__ by the application. The storage service may be managed outside of the library and can contain its own application interfaces for -configuring and statusing. - -#### Operating System Abstraction - -The operating system abstraction is provided at __compile-time__ and must supply all the functions exported by "bplib_os.h". - -Inside "bplib_os.h" there are two #defines that constrain the size of the numbers that the library supports: -* BP_VAL_TYPE - the C type used to represent the largest integer value that can be used by the library. -* BP_INDEX_TYPE - the C type used to represent an index into the active table. - -## 4.0 Coding Rules - -#### Include Rules - -1. An application may only include headers from the `inc/` directory. - -2. All library modules may include "bplib.h" and "bundle_types.h". - -3. The only inclusion of "bplib_os.h" occurs in "bplib.h"; library modules must include "bplib.h" to pull in "bplib_os.h". - -4. A library module may only include headers from `common/` modules or from the modules in the layer directly below it in the architecture diagram. - -5. No functions or data may be extern'ed in a header file (except in unit tests). All functions and data types should be pushed to the smallest scope of exposure as possible (i.e. functions only called within a module should be static, typedefs and defines only used within a module's source file should be defined in the source file instead of the header). - -#### Status Rules - -1. All API functions return a return code as defined in the "bplib.h" list of return codes; and other value must be passed back through pointers. - -2. Return codes are for use by application code, flags are for use by humans. An application should never need to look at the status flags. - -3. Status flags are cumulative and should never be cleared in a library function, nor should they ever be used by a library function - they should only be set. The application is responsible for when the flags are cleared. +# Developer Notes + +[1. Directory Structure](#1-directory-structure) +[2. Layered Architecture](#2-layered-architecture) +[3. Customization and Extensions](#3-customization-and-extensions) +[4. Coding Rules](#4-coding-rules) + + +## 1.0 Directory Structure + +```` +bplib // library build system +|-- binding // language bindings + |-- lua // Lua scripting language + |-- test // library unit test framework +|-- common // utilities and data structures +|-- doc // documentation +|-- inc // public API headers +|-- lib // high level protocol implementation +|-- os // operating system abstractions +|-- store // storage services +|-- unittest // c-code unit tests +|-- v6 // version 6 protocol implementation +```` + +## 2.0 Layered Architecture + +```` ++-----------+ +| bplib | ++-----------+ + | + | ++-----------+ +| v6 | ++-----------+ + |________________________________________________ + || || | | ++-----------+ +-----------+ +-----------+ +-----------+ +| pri | | pay | | bib | | cteb | ++-----------+ +-----------+ +-----------+ +-----------+ + | | + +-----------+ +-----------+ + | dacs | | sdnv | + +-----------+ +-----------+ + + ++-----------+ +-----------+ +-----------+ +-----------+ +| rb_tree | | rh_hash | | cbuf | | crc | ++-----------+ +-----------+ +-----------+ +-----------+ +```` + +## 3.0 Customization and Extension + +#### Storage Service + +The storage service is provided at __run-time__ by the application. The storage service may be managed outside of the library and can contain its own application interfaces for +configuring and statusing. + +#### Operating System Abstraction + +The operating system abstraction is provided at __compile-time__ and must supply all the functions exported by "bplib_os.h". + +Inside "bplib_os.h" there are two #defines that constrain the size of the numbers that the library supports: +* BP_VAL_TYPE - the C type used to represent the largest integer value that can be used by the library. +* BP_INDEX_TYPE - the C type used to represent an index into the active table. + +## 4.0 Coding Rules + +#### Include Rules + +1. An application may only include headers from the `inc/` directory. + +2. All library modules may include "bplib.h" and "bundle_types.h". + +3. The only inclusion of "bplib_os.h" occurs in "bplib.h"; library modules must include "bplib.h" to pull in "bplib_os.h". + +4. A library module may only include headers from `common/` modules or from the modules in the layer directly below it in the architecture diagram. + +5. No functions or data may be extern'ed in a header file (except in unit tests). All functions and data types should be pushed to the smallest scope of exposure as possible (i.e. functions only called within a module should be static, typedefs and defines only used within a module's source file should be defined in the source file instead of the header). + +#### Status Rules + +1. All API functions return a return code as defined in the "bplib.h" list of return codes; and other value must be passed back through pointers. + +2. Return codes are for use by application code, flags are for use by humans. An application should never need to look at the status flags. + +3. Status flags are cumulative and should never be cleared in a library function, nor should they ever be used by a library function - they should only be set. The application is responsible for when the flags are cleared. diff --git a/doc/parm_notes.md b/doc/parm_notes.md index 33269d58..3c437fc1 100644 --- a/doc/parm_notes.md +++ b/doc/parm_notes.md @@ -1,13 +1,13 @@ # Parameter Configuration Notes -[1. Bundle Transmission](#1-bundle-transmission) -[2. Bundle Acknowledgment](#2-bundle-acknowledgment) -[3. Active Bundle Management](#3-active-bundle-management) +[1. Bundle Transmission](#1-bundle-transmission) +[2. Bundle Acknowledgment](#2-bundle-acknowledgment) +[3. Active Bundle Management](#3-active-bundle-management) [4. Example Configuration](#4-example-configuration) Bplib provides a set of APIs that perform the delay-tolerant networking functions of a single node within a network. So while bplib does not define the characteristics of the overall network, the configuration of the local node which uses bplib must be consistent with the characteristics of the network as a whole. For this reason, many configuration options are available in bplib. Nodes participating in different networks with different performance goals and physical constraints need to be configured differently in order to maximize the efficiency, reliability, and throughput of the overall network. -What follows is a series of explanations surrounding the key configuration parameters provided by bplib. Each explanation is a discussion of a trade between resources and desired behaviors - these notes will help you to select which behaviors you want for your network given the resource constraints of your local node. +What follows is a series of explanations surrounding the key configuration parameters provided by bplib. Each explanation is a discussion of a trade between resources and desired behaviors - these notes will help you to select which behaviors you want for your network given the resource constraints of your local node. ## 1. Bundle Transmission @@ -32,9 +32,9 @@ All bundle transmissions begin with a call to the `bplib_load` function which re - Timed-out bundles - New bundles retrieved from storage -> -> Possible Issue #1: if the outgoing link rate for bundles is too small and the timeout period too short, the library may do nothing but resend timed-out bundles. -> +> +> Possible Issue #1: if the outgoing link rate for bundles is too small and the timeout period too short, the library may do nothing but resend timed-out bundles. +> ## 2. Bundle Acknowledgment @@ -64,11 +64,11 @@ There are three things that cause a DACS bundle to be sent: In all cases, the generation of DACS bundles may produce more than one DACS bundle. The DACS bundle is limited in size by the `max_fills_per_dacs` attribute, so that when the library interrogates the state information for the bundles it has accepted custody of, it may need to generate multiple DACS bundles in order to acknowledge all the bundles. -> -> Possible Issue #2: If the DACS rate of the receiver is slower than the timeout period of the sender, then bundles will always timeout before they are acknowledged. If timed-out bundles use the same custody ID (see `CID_REUSE`) then the sending node will be throttled down to the rate of the bundle acknowledgment (i.e. if a link allows 100 bundles per second to be sent, but the receiver is only able to acknowledge 10 bundles per second, then the sender will ultimately only be able to achieve sending 10 bundles per second). If, on the other hand, timed-out bundles use new custody IDs (see `CID_REUSE`), then the acknowledged bundles will no longer reference valid custody IDs by the time they are received by the sender since the bundles will have already timed-out and been assigned new custody IDs. The effect of this misconfiguration is that no bundles will ever be acknowledged. -> +> +> Possible Issue #2: If the DACS rate of the receiver is slower than the timeout period of the sender, then bundles will always timeout before they are acknowledged. If timed-out bundles use the same custody ID (see `CID_REUSE`) then the sending node will be throttled down to the rate of the bundle acknowledgment (i.e. if a link allows 100 bundles per second to be sent, but the receiver is only able to acknowledge 10 bundles per second, then the sender will ultimately only be able to achieve sending 10 bundles per second). If, on the other hand, timed-out bundles use new custody IDs (see `CID_REUSE`), then the acknowledged bundles will no longer reference valid custody IDs by the time they are received by the sender since the bundles will have already timed-out and been assigned new custody IDs. The effect of this misconfiguration is that no bundles will ever be acknowledged. +> > Possible Issue #3: If bundles from multiple senders are received by a single bplib channel, the benefits are aggregating acknowledgments within a single DACS bundle is greatly reduced as everytime there is a transition between receiving bundles from one sender to another the library will generate a new DACS bundle and start over aggregating the acknowledgments. -> +> ## 3. Active Bundle Management @@ -94,12 +94,12 @@ An __active bundle__ is a bundle requesting custody transfer that has been sent The purpose of the active table is two-fold: (1) to determine if a bundle has timed-out and needs to be resent, (2) to translate the custody ID provided in a bundle acknowedgment into the storage ID needed to relinquish its resources in the storage service. The combined need of determining if a bundle has timed-out and which of the timed-out bundles should be sent first, along with the need to be able to randomly access a bundle given a custody ID, imposes a fundemental trade between CPU usage and RAM usage. In a system that had no constraint on CPU, a simple solution could be that every bundle in the active table is looked at each time the `bplib_load` function is called, and the bundle with the oldest transmission time that has timed-out would be returned. On the other hand, in a system with no constraint on memory, a more sophisticated solution could be maintaining a perfect hash of bundles using their custody ID, superimposed on top of a linked list of the bundles kept in transmission order. The implementation in bplib does neither, but instead provides two options via the `retransmit_order` attribute that attempt to balance both CPU and memory usage at the cost of complexity: `BP_RETX_OLDEST_BUNDLE`, and `BP_RETX_SMALLEST_CID`. - + __Oldest Bundle__ -- Behavior: +- Behavior: * When the retransmit order is set to `BP_RETX_OLDEST_BUNDLE` at channel creation, the library allocates a fixed size hash table (set via the `active_table_size` attribute) that also keeps track of the order in which the bundles were sent. * When a bundle is loaded, only the bundle with the oldest transmission time is checked for timing-out. - * On acknowledgment, the custody ID is hashed and used to directly index the bundle's stored information. + * On acknowledgment, the custody ID is hashed and used to directly index the bundle's stored information. - Disadvantages: * Linking the bundles in time order, along with managing hash collisions requires more than twice the memory needed to store the essential information listed above. * The lookup time of an acknowledged bundle is subject to the number of collisions within the hash for the bundle's custody ID. @@ -121,31 +121,31 @@ __Smallest Custody ID__ The size of the active table represents the maximum number of bundles that can be pending acknowledgment. In other words, it is the maximum number of bundles that can be currently enroute. Therefore, the size of the active table must correspond to the anticipated round-trip time of a bundle on the network between the local sender and the next custody accepting hop. -> +> > Possible Issue #4: Reusing custody IDs when retransmitting the smallest custody ID leaves the system vulnerable to a single bundle stopping the transmission of all bundles. -> +> > Possible Issue #5: Not reusing custody IDs leaves the system vulnerable to unanticipated mismatches between the DACS rate of the receiver and the timeout of the sender. -> +> ## 4. Example Configuration What follows is a notional configuration of a bplib channel which serves more to suggest the relationship between the different parameters than recommending an actual setting. __Rate Related Parameters__: - -* DACS Rate = Round Trip Time x 1.5 -* Timeout = DACS Rate x 1.5 -* Active Table Size = Timeout x Bundle Rate x 1.5 + +* DACS Rate = Round Trip Time x 1.5 +* Timeout = DACS Rate x 1.5 +* Active Table Size = Timeout x Bundle Rate x 1.5 * Max Gaps per DACS = Active Table Size __Volume Related Parameters__: - + * Lifetime = Storage Service Partition Size / Bundle Rate / 1.5 - + __Behavior Related Parameters__: - + * CID Reuse = True * Retransmit Order = Oldest Bundle diff --git a/doc/perf_analysis_ic.md b/doc/perf_analysis_ic.md index d9d59204..4e78a29c 100644 --- a/doc/perf_analysis_ic.md +++ b/doc/perf_analysis_ic.md @@ -1,8 +1,8 @@ # Performance Analysis Under Intermittent Communication -[1. Description of Analysis](#1-description-of-analysis) -[2. Case #1: Small Active Table](#2-case-1-small-active-table) -[3. Case #2: Large Active Table](#3-case-2-large-active-table) +[1. Description of Analysis](#1-description-of-analysis) +[2. Case #1: Small Active Table](#2-case-1-small-active-table) +[3. Case #2: Large Active Table](#3-case-2-large-active-table) ### 1. Description of Analysis @@ -14,7 +14,7 @@ The `binding/lua/pf_missed_contact.lua` script simulates a LEO spaceraft accumul ##### Parameters -* __Retransmit Order__: see discussion of `retransmit_order` provided in [README](../README.md) +* __Retransmit Order__: see discussion of `retransmit_order` provided in [README](../README.md) * __CID Reuse__: see discussion of `cid_reuse` provided in [README](../README.md) * __Active Table Size__: maximum number of active bundles managed by the sender * __Bundle Transmission Rate__: number of bundles sent per second during a contact @@ -50,31 +50,31 @@ The `binding/lua/pf_missed_contact.lua` script simulates a LEO spaceraft accumul ![Figure 1](analysis_ic_c1_flow.png "Bundle Flow Analysis of Intermittent Communication for Case 1") -> +> > Description: -> - During the first contact from seconds 0 to 220, no bundles were received by the receiver and as a result, no bundles were acknowledged. The "New" line (blue) shows early activity where new bundles were sent until the active table was full. After that, the "Retransmitted" line (red) begins to grow as the bundles in the active table time out. Since none of them are acknowledged, they keep timing out and no new bundles can be sent. +> - During the first contact from seconds 0 to 220, no bundles were received by the receiver and as a result, no bundles were acknowledged. The "New" line (blue) shows early activity where new bundles were sent until the active table was full. After that, the "Retransmitted" line (red) begins to grow as the bundles in the active table time out. Since none of them are acknowledged, they keep timing out and no new bundles can be sent. > - During the second contact from seconds 220 to 440, the additional bundles from the back-orbit are added and are seen to slowly drain. Retransmissions cease as new bundles and acknowledged bundles grow in lock step. Towards the end of the contact the number of bundles stored drops below the starting value. > - At the start of the second contact no new bundles are sent at first because all the bundles in the active table have timed out and will be sent first. > - The third contact continues the process started during the second contact. -> +> > Analysis: > - By the end of the third contact, there are still bundles being held over in the sender's storage. > - The active table size was small enough and the timeout large enough that all active bundles were retransmitted without additional timeouts. -> +> ##### Time Order Continuity ![Figure 1](analysis_ic_c1_smooth.png "Time Order Continuity Analysis of Intermittent Communication for Case 1") -> +> > Description: > - The order of the bundles being sent are roughly from oldest to newest -> -> Analysis: +> +> Analysis: > - The small active table size nominally bounds out-of-order bundles to the depth of the table (this does not take into account periodically lost bundles) > - The timeout is sufficiently large that under nominal transmission rates, no bundles timeout > - At the start of each pass there are perturbations in the time order, but they are constrained to be no greater than the size of the active table. After the active table clears, the bundles are in strict time order. -> +> ### 3. Case #2: Large Active Table @@ -95,24 +95,24 @@ The `binding/lua/pf_missed_contact.lua` script simulates a LEO spaceraft accumul ![Figure 1](analysis_ic_c2_flow.png "Bundle Flow Analysis of Intermittent Communication for Case 2") -> +> > Description: > - The behavior of the system is similar to case 1 with two exceptions: there are more retranmissions during the first contact, and there are slightly more new bundles during the first contact. > > Analysis: -> - The larger active table size unexpectantly makes very little difference in the number of new bundles able to be received during the missed contact. This is because by the time the sender has sent 320 bundles, at a rate of 16 bundles per second, the first bundle has timed-out. The result is that the system is being bound by the timeout and bundle transmission rate instead of the active table size. +> - The larger active table size unexpectantly makes very little difference in the number of new bundles able to be received during the missed contact. This is because by the time the sender has sent 320 bundles, at a rate of 16 bundles per second, the first bundle has timed-out. The result is that the system is being bound by the timeout and bundle transmission rate instead of the active table size. > - The only large effect the increased active table size had was that it allowed the bundles to be retransmitted at the full bundle transmission rate, since the active table was large enough to hold a full timeout's worth of bundles. > - In summary, with a large active table, there was significantly more data sent, but there was only a marginal increase in new data sent. -> +> ##### Time Order Continuity ![Figure 1](analysis_ic_c2_smooth.png "Time Order Continuity Analysis of Intermittent Communication for Case 2") -> +> > Description: > - Very similar behavior to case 1 -> -> Analysis: +> +> Analysis: > - Since the active table size was being shortcut by the timeout period, the time order continuity is largely unaffected. As the timeout setting is increased, the time ordering will show larger jumps. -> \ No newline at end of file +> \ No newline at end of file diff --git a/inc/bplib.h b/inc/bplib.h index 4b653597..78a8da55 100644 --- a/inc/bplib.h +++ b/inc/bplib.h @@ -58,7 +58,7 @@ extern "C" { #define BP_FLAG_INVALID_BIB_RESULT_TYPE 0x00010000 /* invalid result type found in BIB */ #define BP_FLAG_INVALID_BIB_TARGET_TYPE 0x00020000 /* invalid target type found in BIB */ #define BP_FLAG_FAILED_TO_PARSE 0x00040000 /* unable to parse bundle due to internal inconsistencies in bundle */ -#define BP_FLAG_API_ERROR 0x00080000 /* calling code incorrectly used library */ +#define BP_FLAG_API_ERROR 0x00080000 /* calling code incorrectly used library */ /* Handles */ #define BP_INVALID_HANDLE (-1) /* used for integers (os locks, storage services) */ diff --git a/inc/bplib_store_flash.h b/inc/bplib_store_flash.h index c885a84f..03e503d4 100644 --- a/inc/bplib_store_flash.h +++ b/inc/bplib_store_flash.h @@ -49,7 +49,7 @@ extern "C" { #endif /* - * The number of flash based storage service control structures to + * The number of flash based storage service control structures to * statically allocate */ #ifndef FLASH_MAX_STORES diff --git a/inc/bplib_store_ram.h b/inc/bplib_store_ram.h index 30e932e1..94846d25 100644 --- a/inc/bplib_store_ram.h +++ b/inc/bplib_store_ram.h @@ -1,52 +1,52 @@ -/************************************************************************ - * File: bplib_store_ram.h - * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. - * - * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that - * agreement. - * - * Maintainer(s): - * Joe-Paul Swinski, Code 582 NASA GSFC - * - *************************************************************************/ - -#ifndef _bplib_store_ram_h_ -#define _bplib_store_ram_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - INCLUDES - ******************************************************************************/ - -#include "bplib.h" - -/****************************************************************************** - PROTOTYPES - ******************************************************************************/ - -/* Application API */ -void bplib_store_ram_init (void); - -/* Service API */ -int bplib_store_ram_create (int type, bp_ipn_t node, bp_ipn_t service, bool recover, void* parm); -int bplib_store_ram_destroy (int handle); -int bplib_store_ram_enqueue (int handle, void* data1, int data1_size, void* data2, int data2_size, int timeout); -int bplib_store_ram_dequeue (int handle, bp_object_t** object, int timeout); -int bplib_store_ram_retrieve (int handle, bp_sid_t sid, bp_object_t** object, int timeout); -int bplib_store_ram_release (int handle, bp_sid_t sid); -int bplib_store_ram_relinquish (int handle, bp_sid_t sid); -int bplib_store_ram_getcount (int handle); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* _bplib_store_ram_h_ */ +/************************************************************************ + * File: bplib_store_ram.h + * + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. + * + * This software was created at NASA's Goddard Space Flight Center. + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that + * agreement. + * + * Maintainer(s): + * Joe-Paul Swinski, Code 582 NASA GSFC + * + *************************************************************************/ + +#ifndef _bplib_store_ram_h_ +#define _bplib_store_ram_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + INCLUDES + ******************************************************************************/ + +#include "bplib.h" + +/****************************************************************************** + PROTOTYPES + ******************************************************************************/ + +/* Application API */ +void bplib_store_ram_init (void); + +/* Service API */ +int bplib_store_ram_create (int type, bp_ipn_t node, bp_ipn_t service, bool recover, void* parm); +int bplib_store_ram_destroy (int handle); +int bplib_store_ram_enqueue (int handle, void* data1, int data1_size, void* data2, int data2_size, int timeout); +int bplib_store_ram_dequeue (int handle, bp_object_t** object, int timeout); +int bplib_store_ram_retrieve (int handle, bp_sid_t sid, bp_object_t** object, int timeout); +int bplib_store_ram_release (int handle, bp_sid_t sid); +int bplib_store_ram_relinquish (int handle, bp_sid_t sid); +int bplib_store_ram_getcount (int handle); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* _bplib_store_ram_h_ */ diff --git a/lib/bplib.c b/lib/bplib.c index 4aeb459a..a8691aaa 100644 --- a/lib/bplib.c +++ b/lib/bplib.c @@ -844,7 +844,7 @@ int bplib_load(bp_desc_t* desc, void** bundle, int* size, int timeout, uint32_t* } else { - /* Clear Entry in Active Table and Storage + /* Clear Entry in Active Table and Storage * - when the retrieval of the bundle failed above OR * - when the retrieved bundle has expired */ ch->active_table.remove(ch->active_table.table, active_bundle.cid, NULL); @@ -868,12 +868,12 @@ int bplib_load(bp_desc_t* desc, void** bundle, int* size, int timeout, uint32_t* status = bplib_os_waiton(ch->active_table_signal, timeout); if(status == BP_SUCCESS) { - /* Recheck Table Availability - * The conditional active_table_signal can notify that the table has space but - * another thread could claim the space before this current context is able to proceed; - * therefore the check for room in the table must be remade. Furthermore, the check - * is only made once as we don't want to stay trapped inside this function; as such - * any failed check is overwritten to be a TIMEOUT. */ + /* Recheck Table Availability + * The conditional active_table_signal can notify that the table has space but + * another thread could claim the space before this current context is able to proceed; + * therefore the check for room in the table must be remade. Furthermore, the check + * is only made once as we don't want to stay trapped inside this function; as such + * any failed check is overwritten to be a TIMEOUT. */ status = ch->active_table.available(ch->active_table.table, ch->current_active_cid); if(status != BP_SUCCESS) status = BP_TIMEOUT; } @@ -1042,7 +1042,7 @@ int bplib_process(bp_desc_t* desc, void* bundle, int size, int timeout, uint32_t status = BP_SUCCESS; } else - { + { status = bytes_read; /* Error Code */ } } diff --git a/os/cfe.c b/os/cfe.c index 52251d43..e1acd205 100644 --- a/os/cfe.c +++ b/os/cfe.c @@ -93,7 +93,7 @@ void bplib_os_init(void) /*-------------------------------------------------------------------------------------- * bplib_os_log - * - * Returns - the error code passed in (for convenience) + * Returns - the error code passed in (for convenience) *-------------------------------------------------------------------------------------*/ int bplib_os_log(const char* file, unsigned int line, uint32_t* flags, uint32_t event, const char* fmt, ...) { @@ -127,13 +127,13 @@ int bplib_os_log(const char* file, unsigned int line, uint32_t* flags, uint32_t /* Build Log Message */ msglen = snprintf(log_message, BP_MAX_LOG_ENTRY_SIZE, "%s:%u:%s", pathptr, line, formatted_string); - + /* Provide Truncation Indicator */ if(msglen > (BP_MAX_LOG_ENTRY_SIZE - 2)) { log_message[BP_MAX_LOG_ENTRY_SIZE - 2] = '#'; } - + /* Issue Log Message */ CFE_EVS_SendEvent(BP_BPLIB_INFO_EID, CFE_EVS_INFORMATION, "%s", log_message); } diff --git a/os/posix.c b/os/posix.c index c729a3c0..9bfa15d8 100644 --- a/os/posix.c +++ b/os/posix.c @@ -103,7 +103,7 @@ void bplib_os_init() /*-------------------------------------------------------------------------------------- * bplib_os_log - * - * Returns - the error code passed in (for convenience) + * Returns - the error code passed in (for convenience) *-------------------------------------------------------------------------------------*/ int bplib_os_log(const char* file, unsigned int line, uint32_t* flags, uint32_t event, const char* fmt, ...) { diff --git a/posix.mk b/posix.mk index 069601c7..7006c225 100644 --- a/posix.mk +++ b/posix.mk @@ -1,19 +1,19 @@ ############################################################################### # File: posix.mk # -# Copyright 2019 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Other Rights Reserved. +# Copyright 2019 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Other Rights Reserved. # # This software was created at NASA's Goddard Space Flight Center. -# This software is governed by the NASA Open Source Agreement and may be -# used, distributed and modified only pursuant to the terms of that +# This software is governed by the NASA Open Source Agreement and may be +# used, distributed and modified only pursuant to the terms of that # agreement. # # Maintainer(s): # Joe-Paul Swinski, Code 582 NASA GSFC # -# Note: +# Note: # See 'Makefile' in same directory for where this is included ############################################################################### @@ -33,7 +33,7 @@ BUILD_UNITTESTS=1 APP_COPT += -DUNITTESTS APP_COPT += -DBP_LOCAL_SCOPE="" # removes static designator so that local functions can be unit tested -# GNU Code Coverage # +# GNU Code Coverage # APP_COPT += -fprofile-arcs -ftest-coverage APP_LOPT += -lgcov --coverage diff --git a/release.mk b/release.mk index 595e40d0..f193dffb 100644 --- a/release.mk +++ b/release.mk @@ -1,19 +1,19 @@ ############################################################################### # File: release.mk # -# Copyright 2019 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Other Rights Reserved. +# Copyright 2019 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Other Rights Reserved. # # This software was created at NASA's Goddard Space Flight Center. -# This software is governed by the NASA Open Source Agreement and may be -# used, distributed and modified only pursuant to the terms of that +# This software is governed by the NASA Open Source Agreement and may be +# used, distributed and modified only pursuant to the terms of that # agreement. # # Maintainer(s): # Joe-Paul Swinski, Code 582 NASA GSFC # -# Note: +# Note: # See 'Makefile' in same directory for where this is included ############################################################################### diff --git a/store/flash.c b/store/flash.c index b98ed0dc..fcad4b51 100644 --- a/store/flash.c +++ b/store/flash.c @@ -101,7 +101,7 @@ static uint8_t* flash_page_buffer = NULL; /* memor /****************************************************************************** LOCAL FUNCTIONS - UTILITY ******************************************************************************/ - + /*-------------------------------------------------------------------------------------- * type2str - *-------------------------------------------------------------------------------------*/ @@ -173,16 +173,16 @@ BP_LOCAL_SCOPE int flash_page_read (bp_flash_addr_t addr, uint8_t* data, int siz * a separate buffer just to read the beginning of the object. It is the only * time in the code when this is done, and it is hardcoded to only read one page * and have the offset into the flash_page_buffer be zero. - * + * * When this occurs, we not only don't need to copy the contents out of the flash_page_buffer * since the "data" pointer already points to it, but on many architectures, calling * memcpy with overlapping address ranges causes an exception. - * + * * Note that there is no case in the code where the data buffer is pointing to a location - * in memory that overlaps with the flash_page_buffer; so the check for equivalence is + * in memory that overlaps with the flash_page_buffer; so the check for equivalence is * sufficient. - */ - if(data != flash_page_buffer) + */ + if(data != flash_page_buffer) { memcpy(data, flash_page_buffer, size); } @@ -269,7 +269,7 @@ BP_LOCAL_SCOPE int flash_free_allocate (bp_flash_index_t* block) /* Failed to Erase - Add to Failed Block List */ flash_error_count++; flash_block_list_add(&flash_fail_blocks, block_out); - bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to erase block %d when allocating it... adding as failed block\n", + bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to erase block %d when allocating it... adding as failed block\n", FLASH_DRIVER.phyblk(block_out)); } @@ -302,7 +302,7 @@ BP_LOCAL_SCOPE int flash_data_write (bp_flash_addr_t* addr, uint8_t* data, int s /* Check for Valid Address */ if(addr->block >= FLASH_DRIVER.num_blocks || addr->page >= FLASH_DRIVER.pages_per_block) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to write function: %d.%d\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to write function: %d.%d\n", FLASH_DRIVER.phyblk(addr->block), addr->page); } @@ -313,13 +313,13 @@ BP_LOCAL_SCOPE int flash_data_write (bp_flash_addr_t* addr, uint8_t* data, int s int bytes_to_copy = bytes_left < FLASH_PAGE_DATA_SIZE ? bytes_left : FLASH_PAGE_DATA_SIZE; int flash_status = flash_page_write(*addr, &data[data_index], bytes_to_copy); - /* Check if Write Failed + /* Check if Write Failed * don't set return status of function to failure * but instead count and log the error and keep going */ if(flash_status != BP_SUCCESS) { flash_error_count++; - bplog(NULL, BP_FLAG_STORE_FAILURE, "Error encountered writing data to flash address: %d.%d\n", + bplog(NULL, BP_FLAG_STORE_FAILURE, "Error encountered writing data to flash address: %d.%d\n", FLASH_DRIVER.phyblk(addr->block), addr->page); } @@ -341,7 +341,7 @@ BP_LOCAL_SCOPE int flash_data_write (bp_flash_addr_t* addr, uint8_t* data, int s } else { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next free block in middle of flash write at block: %ld\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next free block in middle of flash write at block: %ld\n", FLASH_DRIVER.phyblk(addr->block)); } } @@ -361,7 +361,7 @@ BP_LOCAL_SCOPE int flash_data_read (bp_flash_addr_t* addr, uint8_t* data, int si /* Check for Valid Address */ if(addr->block >= FLASH_DRIVER.num_blocks || addr->page >= FLASH_DRIVER.pages_per_block) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to read function: %d.%d\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to read function: %d.%d\n", FLASH_DRIVER.phyblk(addr->block), addr->page); } @@ -378,7 +378,7 @@ BP_LOCAL_SCOPE int flash_data_read (bp_flash_addr_t* addr, uint8_t* data, int si if(flash_status != BP_SUCCESS) { flash_error_count++; - bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to read data from flash address: %d.%d\n", + bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to read data from flash address: %d.%d\n", FLASH_DRIVER.phyblk(addr->block), addr->page); } @@ -393,7 +393,7 @@ BP_LOCAL_SCOPE int flash_data_read (bp_flash_addr_t* addr, uint8_t* data, int si bp_flash_index_t next_read_block = flash_blocks[addr->block].next_block; if(next_read_block == BP_FLASH_INVALID_INDEX) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next block in middle of flash read at block: %ld\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next block in middle of flash read at block: %ld\n", FLASH_DRIVER.phyblk(addr->block)); } @@ -445,8 +445,8 @@ BP_LOCAL_SCOPE int flash_object_write (flash_store_t* fs, int handle, uint8_t* d } else { - status = bplog(NULL, BP_FLAG_STORE_FAILURE, "Insufficient room in flash storage, max: %llu, available: %llu, needed: %llu\n", - (long long unsigned)fs->attributes.max_data_size, (long long unsigned)bytes_available, + status = bplog(NULL, BP_FLAG_STORE_FAILURE, "Insufficient room in flash storage, max: %llu, available: %llu, needed: %llu\n", + (long long unsigned)fs->attributes.max_data_size, (long long unsigned)bytes_available, (long long unsigned)bytes_needed); } @@ -520,7 +520,7 @@ BP_LOCAL_SCOPE int flash_object_delete (flash_store_t* fs, bp_sid_t sid) bp_flash_addr_t addr = {FLASH_GET_BLOCK((unsigned long)sid), FLASH_GET_PAGE((unsigned long)sid)}; if(addr.block >= FLASH_DRIVER.num_blocks || addr.page >= FLASH_DRIVER.pages_per_block) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to delete function: %d.%d\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Invalid address provided to delete function: %d.%d\n", FLASH_DRIVER.phyblk(addr.block), addr.page); } @@ -531,12 +531,12 @@ BP_LOCAL_SCOPE int flash_object_delete (flash_store_t* fs, bp_sid_t sid) status = flash_data_read(&hdr_addr, (uint8_t*)flash_object_hdr, sizeof(flash_object_hdr_t)); if(status != BP_SUCCESS) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Unable to read object header at %d.%d in delete function\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Unable to read object header at %d.%d in delete function\n", FLASH_DRIVER.phyblk(addr.block), addr.page); } else if(flash_object_hdr->object_hdr.sid != sid) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Attempting to delete object with invalid SID: %lu != %lu\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Attempting to delete object with invalid SID: %lu != %lu\n", (unsigned long)flash_object_hdr->object_hdr.sid, (unsigned long)sid); } @@ -561,7 +561,7 @@ BP_LOCAL_SCOPE int flash_object_delete (flash_store_t* fs, bp_sid_t sid) bp_flash_index_t next_delete_block = flash_blocks[addr.block].next_block; if((next_delete_block == BP_FLASH_INVALID_INDEX) && (bytes_left > 0)) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next block in middle of flash delete at block: %d\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed to retrieve next block in middle of flash delete at block: %d\n", FLASH_DRIVER.phyblk(addr.block)); } @@ -583,7 +583,7 @@ BP_LOCAL_SCOPE int flash_object_delete (flash_store_t* fs, bp_sid_t sid) status = flash_free_reclaim(fs->active_block); if(status != BP_SUCCESS) { - bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed (%d) to reclaim block %d as a free block\n", + bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed (%d) to reclaim block %d as a free block\n", status, FLASH_DRIVER.phyblk(fs->active_block)); } @@ -708,7 +708,7 @@ int bplib_store_flash_init (bp_flash_driver_t driver, bool sw_edac) /* Check for Success */ if(reclaimed_blocks > 0) { - bplog(NULL, BP_FLAG_DIAGNOSTIC, "Flash storage service reclaimed %d blocks, starting at block %d\n", + bplog(NULL, BP_FLAG_DIAGNOSTIC, "Flash storage service reclaimed %d blocks, starting at block %d\n", reclaimed_blocks, FLASH_DRIVER.phyblk(start_block % driver.num_blocks)); } else @@ -771,9 +771,9 @@ void bplib_store_flash_reclaim_used_blocks (bp_ipn_t node, bp_ipn_t service) for(s = 0; s < FLASH_MAX_STORES; s++) { - if( (flash_stores[s].in_use == false) && - (flash_stores[s].preserve == true) && - (flash_stores[s].node == node) && + if( (flash_stores[s].in_use == false) && + (flash_stores[s].preserve == true) && + (flash_stores[s].node == node) && (flash_stores[s].service == service) ) { flash_stores[s].in_use = true; @@ -867,29 +867,29 @@ int bplib_store_flash_create (int type, bp_ipn_t node, bp_ipn_t service, bool re bp_flash_attr_t* attr = (bp_flash_attr_t*)parm; bool in_error = false; int handle = BP_INVALID_HANDLE; - int s; + int s; if(recover) { /* Search for Existing Store */ for(s = 0; s < FLASH_MAX_STORES; s++) { - if( (flash_stores[s].preserve == true) && + if( (flash_stores[s].preserve == true) && (flash_stores[s].type == type) && - (flash_stores[s].node == node) && + (flash_stores[s].node == node) && (flash_stores[s].service == service) ) { if(!flash_stores[s].in_use) { /* Recover Bundles */ - bplog(NULL, BP_FLAG_DIAGNOSTIC, "Recovered %d %s from ipn:%d.%d in flash store\n", + bplog(NULL, BP_FLAG_DIAGNOSTIC, "Recovered %d %s from ipn:%d.%d in flash store\n", flash_stores[s].object_count, type2str(type), node, service); handle = s; } else { /* Node.Service Already In Use */ - bplog(NULL, BP_FLAG_DIAGNOSTIC, "Store of %s for ipn:%d.%d already in use!\n", + bplog(NULL, BP_FLAG_DIAGNOSTIC, "Store of %s for ipn:%d.%d already in use!\n", type2str(type), node, service); in_error = true; } @@ -989,15 +989,15 @@ int bplib_store_flash_destroy (int handle) assert(flash_stores[handle].in_use); /* If Preserving: - * Reset Active Block to Read Address - this will cause any bundles that are - * active to be lost. Since this store doesn't keep track of individual free pages, - * there is no way to reset the active address to the exact page (the active address - * only keeps track of the block for this reason). - * + * Reset Active Block to Read Address - this will cause any bundles that are + * active to be lost. Since this store doesn't keep track of individual free pages, + * there is no way to reset the active address to the exact page (the active address + * only keeps track of the block for this reason). + * * If Not Preserving: * Reclaim all blocks from the active block all the way to the end. This drains all * the blocks associated with this store from flash. */ - while( (flash_stores[handle].active_block != BP_FLASH_INVALID_INDEX) && + while( (flash_stores[handle].active_block != BP_FLASH_INVALID_INDEX) && ( (!flash_stores[handle].preserve) || (flash_stores[handle].active_block != flash_stores[handle].read_addr.block) ) ) { @@ -1008,7 +1008,7 @@ int bplib_store_flash_destroy (int handle) int status = flash_free_reclaim(flash_stores[handle].active_block); if(status != BP_SUCCESS) { - bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed (%d) to reclaim block %d as a free block\n", + bplog(NULL, BP_FLAG_STORE_FAILURE, "Failed (%d) to reclaim block %d as a free block\n", status, FLASH_DRIVER.phyblk(flash_stores[handle].active_block)); } @@ -1034,15 +1034,15 @@ int bplib_store_flash_destroy (int handle) /* Generate Status Message */ if(!flash_stores[handle].preserve) { - bplog(NULL, BP_FLAG_DIAGNOSTIC, "Deleting %d unpreserved %s from ipn:%d.%d in flash store\n", - flash_stores[handle].object_count, type2str(flash_stores[handle].type), + bplog(NULL, BP_FLAG_DIAGNOSTIC, "Deleting %d unpreserved %s from ipn:%d.%d in flash store\n", + flash_stores[handle].object_count, type2str(flash_stores[handle].type), flash_stores[handle].node, flash_stores[handle].service); } else { int active_bundles = flash_stores[handle].object_count - flash_stores[handle].inactive_count; - bplog(NULL, BP_FLAG_DIAGNOSTIC, "Deleting %d abandoned %s from ipn:%d.%d in flash store\n", - active_bundles, type2str(flash_stores[handle].type), + bplog(NULL, BP_FLAG_DIAGNOSTIC, "Deleting %d abandoned %s from ipn:%d.%d in flash store\n", + active_bundles, type2str(flash_stores[handle].type), flash_stores[handle].node, flash_stores[handle].service); } @@ -1184,7 +1184,7 @@ int bplib_store_flash_release (int handle, bp_sid_t sid) flash_object_hdr_t* flash_object_hdr = (flash_object_hdr_t*)fs->read_stage; if(flash_object_hdr->object_hdr.sid != sid) { - return bplog(NULL, BP_FLAG_STORE_FAILURE, "Object being released does not have correct SID, requested: %lu, actual: %lu\n", + return bplog(NULL, BP_FLAG_STORE_FAILURE, "Object being released does not have correct SID, requested: %lu, actual: %lu\n", (unsigned long)sid, (unsigned long)flash_object_hdr->object_hdr.sid); } else diff --git a/store/ram.c b/store/ram.c index 6c79a88d..3a7b460c 100644 --- a/store/ram.c +++ b/store/ram.c @@ -1,541 +1,541 @@ -/************************************************************************ - * File: ram.c - * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. - * - * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that - * agreement. - * - * Maintainer(s): - * Joe-Paul Swinski, Code 582 NASA GSFC - * - *************************************************************************/ - -/****************************************************************************** - * INCLUDES - ******************************************************************************/ - -#include "bplib.h" -#include "bplib_store_ram.h" - -/****************************************************************************** - * DEFINES - ******************************************************************************/ - -#define MSGQ_OKAY (0) -#define MSGQ_TIMEOUT (-1) -#define MSGQ_ERROR (-2) -#define MSGQ_FULL (-3) -#define MSGQ_MEMORY_ERROR (-4) -#define MSGQ_UNDERFLOW (-5) -#define MSGQ_INVALID_HANDLE ((msgq_t)NULL) -#define MSGQ_DEPTH_INFINITY 0 -#define MSGQ_SIZE_INFINITY 0 -#define MSGQ_STORE_STR "bplibq" -#define MSGQ_STORE_STR_SIZE 32 - -/* Configurable Options */ - -#ifndef MSGQ_MAX_STORES -#define MSGQ_MAX_STORES 60 -#endif - -#ifndef MSGQ_MAX_DEPTH -#define MSGQ_MAX_DEPTH 65536 -#endif - -#ifndef MSGQ_MAX_SIZE -#define MSGQ_MAX_SIZE MSGQ_SIZE_INFINITY -#endif - -/****************************************************************************** - * TYPEDEFS - ******************************************************************************/ - -/* queue_node_t */ -typedef struct queue_block_t { - void* data; - unsigned int size; - struct queue_block_t* next; -} queue_node_t; - -/* queue_t */ -typedef struct queue_def_t { - queue_node_t* front; /* oldest node removed (read pointer) */ - queue_node_t* rear; /* newest node added (write pointer) */ - unsigned int depth; /* maximum length of linked list */ - unsigned int len; /* current length of linked list (lazy deallocation means this includes non-active items) */ - unsigned int max_data_size; /* largest item that can be queued */ -} queue_t; - -/* message_queue_t */ -typedef struct { - queue_t queue; /* linked list */ - int ready; /* handle for mutex/conditional */ - int state; /* state of queue */ - int count; /* number of items in queue */ -} message_queue_t; - -/* message queue handle */ -typedef message_queue_t* msgq_t; - -/****************************************************************************** - * FILE DATA - ******************************************************************************/ - -static msgq_t msgq_stores[MSGQ_MAX_STORES]; - -/****************************************************************************** - * LOCAL QUEUE FUNCTIONS - ******************************************************************************/ - -/*---------------------------------------------------------------------------- - * Function: flush_queue - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE void flush_queue(queue_t* q) -{ - queue_node_t* temp; - - while(q->front) - { - temp = q->front->next; - bplib_os_free(q->front->data); - bplib_os_free(q->front); - q->front = temp; - } - q->rear = NULL; -} - -/*---------------------------------------------------------------------------- - * Function: isempty - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE int isempty(queue_t* q) -{ - if(q->front == NULL) - { - return true; - } - else - { - return false; - } -} - -/*---------------------------------------------------------------------------- - * Function: enqueue - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE int enqueue(queue_t* q, void* data, int size) -{ - /* check if queue is full */ - if((q->depth != MSGQ_DEPTH_INFINITY) && (q->len >= q->depth)) - { - return MSGQ_FULL; - } - - /* check size */ - if((size <= 0) || - ((q->max_data_size != MSGQ_SIZE_INFINITY) && - ((unsigned)size > q->max_data_size))) - { - return MSGQ_ERROR; - } - - /* create temp node */ - queue_node_t* temp = (queue_node_t*)bplib_os_calloc((int)sizeof(queue_node_t)); - if(!temp) return MSGQ_MEMORY_ERROR; - - /* construct node to be added */ - temp->data = data; - temp->size = size; - temp->next = NULL; - - /* place temp node into queue */ - if(q->rear == NULL) - { - q->rear = temp; - q->front = temp; - } - else /* q->rear != NULL */ - { - q->rear->next = temp; - q->rear = q->rear->next; - } - - q->len++; - - return MSGQ_OKAY; -} - -/*---------------------------------------------------------------------------- - * Function: dequeue - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE void* dequeue(queue_t* q, int* size) -{ - void *data; - - if(q->front) - { - /* extract */ - data = q->front->data; - if(size) *size = q->front->size; - - /* remove */ - queue_node_t* tmp = q->front; - if(q->front == q->rear) - { - q->front = q->rear = NULL; - } - else - { - q->front = q->front->next; - } - bplib_os_free(tmp); - - q->len--; - } - else - { - if(size) *size = 0; - data = NULL; - } - - return data; -} - -/****************************************************************************** - * LOCAL MSGQ FUNCTIONS - ******************************************************************************/ - -/*---------------------------------------------------------------------------- - * Function: msgq_create - * - * Notes: 1. Returns a handle to the message queue created - * 2. The depth specifies the maximum number of items that are - * allowed to be queued up. If the depth is zero, the queue - * is allowed to infinitely grow until all the memory in the - * system is consumed. - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE msgq_t msgq_create(int depth, int data_size) -{ - message_queue_t* msgQ; - int ready_lock; - - /* Create Lock */ - ready_lock = bplib_os_createlock(); - if(ready_lock == -1) - { - printf("ERROR(%d): Unable to create ready sem\n", ready_lock); - return MSGQ_INVALID_HANDLE; - } - - /* Allocate MSG Q */ - msgQ = (message_queue_t*)bplib_os_calloc(sizeof(message_queue_t)); - if(msgQ == NULL) - { - printf("ERROR, Unable to allocate message queue\n"); - return MSGQ_INVALID_HANDLE; - } - - /* Initialize MSG Q */ - msgQ->state = MSGQ_OKAY; - msgQ->queue.front = NULL; - msgQ->queue.rear = NULL; - msgQ->queue.depth = depth; - msgQ->queue.len = 0; - msgQ->queue.max_data_size = data_size; - msgQ->ready = ready_lock; - - /* Return MSG Q */ - return (msgq_t)msgQ; -} - -/*---------------------------------------------------------------------------- - * Function: msgq_delete - * - * Notes: 1. de-allocates memory associated with message queue - * 2. removes queue from system list - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE void msgq_delete(msgq_t queue_handle) -{ - message_queue_t* msgQ = (message_queue_t*)queue_handle; - if(msgQ) - { - flush_queue(&msgQ->queue); - bplib_os_destroylock(msgQ->ready); - bplib_os_free(msgQ); - } -} - -/*---------------------------------------------------------------------------- - * Function: msgq_post - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE int msgq_post(msgq_t queue_handle, void* data, int size) -{ - int post_state; - - message_queue_t* msgQ = (message_queue_t*)queue_handle; - if(msgQ == NULL) return MSGQ_ERROR; - - /* Post Data */ - bplib_os_lock(msgQ->ready); - { - post_state = enqueue(&msgQ->queue, data, size); - msgQ->state = post_state; - } - bplib_os_unlock(msgQ->ready); - - /* Trigger if Ready */ - if(post_state == MSGQ_OKAY) - { - bplib_os_signal(msgQ->ready); - } - - /* Return Status */ - return post_state; -} - -/*---------------------------------------------------------------------------- - * Function: msgq_receive - * - * Notes: returns a pointer to the data and the size of the data by - * populating the size parameter passed in by pointer - *----------------------------------------------------------------------------*/ -BP_LOCAL_SCOPE int msgq_receive(msgq_t queue_handle, void** data, int* size, int block) -{ - message_queue_t* msgQ = (message_queue_t*)queue_handle; - if(msgQ == NULL) return MSGQ_ERROR; - - int recv_state = MSGQ_OKAY; - - bplib_os_lock(msgQ->ready); - { - /* Wait for a message to be posted */ - if(block == BP_PEND) - { - while(isempty(&msgQ->queue)) - { - bplib_os_waiton(msgQ->ready, BP_PEND); - } - } - else if(block == BP_CHECK) - { - } - else /* Timed Wait */ - { - if(isempty(&msgQ->queue)) - { - int wait_status = bplib_os_waiton(msgQ->ready, block); - if(wait_status == BP_TIMEOUT) recv_state = MSGQ_TIMEOUT; - else if(wait_status == BP_ERROR) recv_state = MSGQ_ERROR; - } - } - - /* Get data from queue */ - msgQ->state = recv_state; - if(msgQ->state == MSGQ_OKAY) - { - *data = dequeue(&msgQ->queue, size); - if(*data == NULL) recv_state = MSGQ_UNDERFLOW; - } - } - bplib_os_unlock(msgQ->ready); - - /* Return Status */ - return recv_state; -} - -/****************************************************************************** - * EXPORTED FUNCTIONS - ******************************************************************************/ - -/*---------------------------------------------------------------------------- - * bplib_store_ram_init - - *----------------------------------------------------------------------------*/ -void bplib_store_ram_init (void) -{ - memset(msgq_stores, 0, sizeof(msgq_stores)); -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_create - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_create (int type, bp_ipn_t node, bp_ipn_t service, bool recover, void* parm) -{ - (void)type; - (void)node; - (void)service; - (void)recover; - (void)parm; - - int slot, i; - - /* Look for Empty Slots */ - slot = BP_INVALID_HANDLE; - for(i = 0; i < MSGQ_MAX_STORES; i++) - { - if(msgq_stores[i] == MSGQ_INVALID_HANDLE) - { - msgq_t msgq = msgq_create(MSGQ_MAX_DEPTH, MSGQ_MAX_SIZE); - if(msgq != MSGQ_INVALID_HANDLE) - { - msgq_stores[i] = msgq; - slot = i; - } - break; - } - } - - /* Return Index into List */ - return slot; -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_destroy - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_destroy (int handle) -{ - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle] != MSGQ_INVALID_HANDLE); - - msgq_delete(msgq_stores[handle]); - msgq_stores[handle] = MSGQ_INVALID_HANDLE; - - return BP_SUCCESS; -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_enqueue - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_enqueue(int handle, void* data1, int data1_size, - void* data2, int data2_size, int timeout) -{ - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle]); - assert((data1_size >= 0) && (data2_size >= 0)); - assert((data1_size + data2_size) > 0); - - int status; - int data_size = data1_size + data2_size; - int object_size = sizeof(bp_object_hdr_t) + data_size; - bp_object_t* object = (bp_object_t*)bplib_os_calloc(object_size); - - /* Check memory allocation */ - if(!object) return BP_ERROR; - - /* Populate Object */ - object->header.handle = handle; - object->header.sid = BP_SID_VACANT; - object->header.size = data_size; - memcpy(object->data, data1, data1_size); - memcpy(&object->data[data1_size], data2, data2_size); - - /* Post object */ - status = msgq_post(msgq_stores[handle], object, object_size); - if(status == MSGQ_OKAY) - { - msgq_stores[handle]->count++; - return BP_SUCCESS; - } - else if(status == MSGQ_FULL) - { - bplib_os_free(object); - bplib_os_sleep(timeout / 1000); - return BP_TIMEOUT; - } - else - { - bplib_os_free(object); - return BP_ERROR; - } -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_dequeue - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_dequeue(int handle, bp_object_t** object, int timeout) -{ - int size; - - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle]); - assert(object); - - bp_object_t* dequeued_object; - int status = msgq_receive(msgq_stores[handle], (void**)&dequeued_object, &size, timeout); - if(status == MSGQ_OKAY) - { - (void)size; /* unused */ - dequeued_object->header.sid = (unsigned long)dequeued_object; /* only update sid */ - *object = dequeued_object; - return BP_SUCCESS; - } - else if(status == MSGQ_TIMEOUT || status == MSGQ_UNDERFLOW) - { - return BP_TIMEOUT; - } - else - { - return BP_ERROR; - } -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_retrieve - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_retrieve(int handle, bp_sid_t sid, - bp_object_t** object, int timeout) -{ - (void)handle; - (void)timeout; - - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle]); - assert(object); - - *object = (bp_object_t*)sid; - - return BP_SUCCESS; -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_release - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_release (int handle, bp_sid_t sid) -{ - (void)handle; - (void)sid; - - return BP_SUCCESS; -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_relinquish - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_relinquish (int handle, bp_sid_t sid) -{ - (void)handle; - - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle]); - - bp_object_t* object = (void*)sid; - bplib_os_free(object); - msgq_stores[handle]->count--; - - return BP_SUCCESS; -} - -/*---------------------------------------------------------------------------- - * bplib_store_ram_getcount - - *----------------------------------------------------------------------------*/ -int bplib_store_ram_getcount (int handle) -{ - assert(handle >= 0 && handle < MSGQ_MAX_STORES); - assert(msgq_stores[handle]); - - return msgq_stores[handle]->count; -} +/************************************************************************ + * File: ram.c + * + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. + * + * This software was created at NASA's Goddard Space Flight Center. + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that + * agreement. + * + * Maintainer(s): + * Joe-Paul Swinski, Code 582 NASA GSFC + * + *************************************************************************/ + +/****************************************************************************** + * INCLUDES + ******************************************************************************/ + +#include "bplib.h" +#include "bplib_store_ram.h" + +/****************************************************************************** + * DEFINES + ******************************************************************************/ + +#define MSGQ_OKAY (0) +#define MSGQ_TIMEOUT (-1) +#define MSGQ_ERROR (-2) +#define MSGQ_FULL (-3) +#define MSGQ_MEMORY_ERROR (-4) +#define MSGQ_UNDERFLOW (-5) +#define MSGQ_INVALID_HANDLE ((msgq_t)NULL) +#define MSGQ_DEPTH_INFINITY 0 +#define MSGQ_SIZE_INFINITY 0 +#define MSGQ_STORE_STR "bplibq" +#define MSGQ_STORE_STR_SIZE 32 + +/* Configurable Options */ + +#ifndef MSGQ_MAX_STORES +#define MSGQ_MAX_STORES 60 +#endif + +#ifndef MSGQ_MAX_DEPTH +#define MSGQ_MAX_DEPTH 65536 +#endif + +#ifndef MSGQ_MAX_SIZE +#define MSGQ_MAX_SIZE MSGQ_SIZE_INFINITY +#endif + +/****************************************************************************** + * TYPEDEFS + ******************************************************************************/ + +/* queue_node_t */ +typedef struct queue_block_t { + void* data; + unsigned int size; + struct queue_block_t* next; +} queue_node_t; + +/* queue_t */ +typedef struct queue_def_t { + queue_node_t* front; /* oldest node removed (read pointer) */ + queue_node_t* rear; /* newest node added (write pointer) */ + unsigned int depth; /* maximum length of linked list */ + unsigned int len; /* current length of linked list (lazy deallocation means this includes non-active items) */ + unsigned int max_data_size; /* largest item that can be queued */ +} queue_t; + +/* message_queue_t */ +typedef struct { + queue_t queue; /* linked list */ + int ready; /* handle for mutex/conditional */ + int state; /* state of queue */ + int count; /* number of items in queue */ +} message_queue_t; + +/* message queue handle */ +typedef message_queue_t* msgq_t; + +/****************************************************************************** + * FILE DATA + ******************************************************************************/ + +static msgq_t msgq_stores[MSGQ_MAX_STORES]; + +/****************************************************************************** + * LOCAL QUEUE FUNCTIONS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * Function: flush_queue + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE void flush_queue(queue_t* q) +{ + queue_node_t* temp; + + while(q->front) + { + temp = q->front->next; + bplib_os_free(q->front->data); + bplib_os_free(q->front); + q->front = temp; + } + q->rear = NULL; +} + +/*---------------------------------------------------------------------------- + * Function: isempty + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE int isempty(queue_t* q) +{ + if(q->front == NULL) + { + return true; + } + else + { + return false; + } +} + +/*---------------------------------------------------------------------------- + * Function: enqueue + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE int enqueue(queue_t* q, void* data, int size) +{ + /* check if queue is full */ + if((q->depth != MSGQ_DEPTH_INFINITY) && (q->len >= q->depth)) + { + return MSGQ_FULL; + } + + /* check size */ + if((size <= 0) || + ((q->max_data_size != MSGQ_SIZE_INFINITY) && + ((unsigned)size > q->max_data_size))) + { + return MSGQ_ERROR; + } + + /* create temp node */ + queue_node_t* temp = (queue_node_t*)bplib_os_calloc((int)sizeof(queue_node_t)); + if(!temp) return MSGQ_MEMORY_ERROR; + + /* construct node to be added */ + temp->data = data; + temp->size = size; + temp->next = NULL; + + /* place temp node into queue */ + if(q->rear == NULL) + { + q->rear = temp; + q->front = temp; + } + else /* q->rear != NULL */ + { + q->rear->next = temp; + q->rear = q->rear->next; + } + + q->len++; + + return MSGQ_OKAY; +} + +/*---------------------------------------------------------------------------- + * Function: dequeue + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE void* dequeue(queue_t* q, int* size) +{ + void *data; + + if(q->front) + { + /* extract */ + data = q->front->data; + if(size) *size = q->front->size; + + /* remove */ + queue_node_t* tmp = q->front; + if(q->front == q->rear) + { + q->front = q->rear = NULL; + } + else + { + q->front = q->front->next; + } + bplib_os_free(tmp); + + q->len--; + } + else + { + if(size) *size = 0; + data = NULL; + } + + return data; +} + +/****************************************************************************** + * LOCAL MSGQ FUNCTIONS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * Function: msgq_create + * + * Notes: 1. Returns a handle to the message queue created + * 2. The depth specifies the maximum number of items that are + * allowed to be queued up. If the depth is zero, the queue + * is allowed to infinitely grow until all the memory in the + * system is consumed. + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE msgq_t msgq_create(int depth, int data_size) +{ + message_queue_t* msgQ; + int ready_lock; + + /* Create Lock */ + ready_lock = bplib_os_createlock(); + if(ready_lock == -1) + { + printf("ERROR(%d): Unable to create ready sem\n", ready_lock); + return MSGQ_INVALID_HANDLE; + } + + /* Allocate MSG Q */ + msgQ = (message_queue_t*)bplib_os_calloc(sizeof(message_queue_t)); + if(msgQ == NULL) + { + printf("ERROR, Unable to allocate message queue\n"); + return MSGQ_INVALID_HANDLE; + } + + /* Initialize MSG Q */ + msgQ->state = MSGQ_OKAY; + msgQ->queue.front = NULL; + msgQ->queue.rear = NULL; + msgQ->queue.depth = depth; + msgQ->queue.len = 0; + msgQ->queue.max_data_size = data_size; + msgQ->ready = ready_lock; + + /* Return MSG Q */ + return (msgq_t)msgQ; +} + +/*---------------------------------------------------------------------------- + * Function: msgq_delete + * + * Notes: 1. de-allocates memory associated with message queue + * 2. removes queue from system list + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE void msgq_delete(msgq_t queue_handle) +{ + message_queue_t* msgQ = (message_queue_t*)queue_handle; + if(msgQ) + { + flush_queue(&msgQ->queue); + bplib_os_destroylock(msgQ->ready); + bplib_os_free(msgQ); + } +} + +/*---------------------------------------------------------------------------- + * Function: msgq_post + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE int msgq_post(msgq_t queue_handle, void* data, int size) +{ + int post_state; + + message_queue_t* msgQ = (message_queue_t*)queue_handle; + if(msgQ == NULL) return MSGQ_ERROR; + + /* Post Data */ + bplib_os_lock(msgQ->ready); + { + post_state = enqueue(&msgQ->queue, data, size); + msgQ->state = post_state; + } + bplib_os_unlock(msgQ->ready); + + /* Trigger if Ready */ + if(post_state == MSGQ_OKAY) + { + bplib_os_signal(msgQ->ready); + } + + /* Return Status */ + return post_state; +} + +/*---------------------------------------------------------------------------- + * Function: msgq_receive + * + * Notes: returns a pointer to the data and the size of the data by + * populating the size parameter passed in by pointer + *----------------------------------------------------------------------------*/ +BP_LOCAL_SCOPE int msgq_receive(msgq_t queue_handle, void** data, int* size, int block) +{ + message_queue_t* msgQ = (message_queue_t*)queue_handle; + if(msgQ == NULL) return MSGQ_ERROR; + + int recv_state = MSGQ_OKAY; + + bplib_os_lock(msgQ->ready); + { + /* Wait for a message to be posted */ + if(block == BP_PEND) + { + while(isempty(&msgQ->queue)) + { + bplib_os_waiton(msgQ->ready, BP_PEND); + } + } + else if(block == BP_CHECK) + { + } + else /* Timed Wait */ + { + if(isempty(&msgQ->queue)) + { + int wait_status = bplib_os_waiton(msgQ->ready, block); + if(wait_status == BP_TIMEOUT) recv_state = MSGQ_TIMEOUT; + else if(wait_status == BP_ERROR) recv_state = MSGQ_ERROR; + } + } + + /* Get data from queue */ + msgQ->state = recv_state; + if(msgQ->state == MSGQ_OKAY) + { + *data = dequeue(&msgQ->queue, size); + if(*data == NULL) recv_state = MSGQ_UNDERFLOW; + } + } + bplib_os_unlock(msgQ->ready); + + /* Return Status */ + return recv_state; +} + +/****************************************************************************** + * EXPORTED FUNCTIONS + ******************************************************************************/ + +/*---------------------------------------------------------------------------- + * bplib_store_ram_init - + *----------------------------------------------------------------------------*/ +void bplib_store_ram_init (void) +{ + memset(msgq_stores, 0, sizeof(msgq_stores)); +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_create - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_create (int type, bp_ipn_t node, bp_ipn_t service, bool recover, void* parm) +{ + (void)type; + (void)node; + (void)service; + (void)recover; + (void)parm; + + int slot, i; + + /* Look for Empty Slots */ + slot = BP_INVALID_HANDLE; + for(i = 0; i < MSGQ_MAX_STORES; i++) + { + if(msgq_stores[i] == MSGQ_INVALID_HANDLE) + { + msgq_t msgq = msgq_create(MSGQ_MAX_DEPTH, MSGQ_MAX_SIZE); + if(msgq != MSGQ_INVALID_HANDLE) + { + msgq_stores[i] = msgq; + slot = i; + } + break; + } + } + + /* Return Index into List */ + return slot; +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_destroy - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_destroy (int handle) +{ + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle] != MSGQ_INVALID_HANDLE); + + msgq_delete(msgq_stores[handle]); + msgq_stores[handle] = MSGQ_INVALID_HANDLE; + + return BP_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_enqueue - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_enqueue(int handle, void* data1, int data1_size, + void* data2, int data2_size, int timeout) +{ + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle]); + assert((data1_size >= 0) && (data2_size >= 0)); + assert((data1_size + data2_size) > 0); + + int status; + int data_size = data1_size + data2_size; + int object_size = sizeof(bp_object_hdr_t) + data_size; + bp_object_t* object = (bp_object_t*)bplib_os_calloc(object_size); + + /* Check memory allocation */ + if(!object) return BP_ERROR; + + /* Populate Object */ + object->header.handle = handle; + object->header.sid = BP_SID_VACANT; + object->header.size = data_size; + memcpy(object->data, data1, data1_size); + memcpy(&object->data[data1_size], data2, data2_size); + + /* Post object */ + status = msgq_post(msgq_stores[handle], object, object_size); + if(status == MSGQ_OKAY) + { + msgq_stores[handle]->count++; + return BP_SUCCESS; + } + else if(status == MSGQ_FULL) + { + bplib_os_free(object); + bplib_os_sleep(timeout / 1000); + return BP_TIMEOUT; + } + else + { + bplib_os_free(object); + return BP_ERROR; + } +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_dequeue - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_dequeue(int handle, bp_object_t** object, int timeout) +{ + int size; + + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle]); + assert(object); + + bp_object_t* dequeued_object; + int status = msgq_receive(msgq_stores[handle], (void**)&dequeued_object, &size, timeout); + if(status == MSGQ_OKAY) + { + (void)size; /* unused */ + dequeued_object->header.sid = (unsigned long)dequeued_object; /* only update sid */ + *object = dequeued_object; + return BP_SUCCESS; + } + else if(status == MSGQ_TIMEOUT || status == MSGQ_UNDERFLOW) + { + return BP_TIMEOUT; + } + else + { + return BP_ERROR; + } +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_retrieve - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_retrieve(int handle, bp_sid_t sid, + bp_object_t** object, int timeout) +{ + (void)handle; + (void)timeout; + + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle]); + assert(object); + + *object = (bp_object_t*)sid; + + return BP_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_release - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_release (int handle, bp_sid_t sid) +{ + (void)handle; + (void)sid; + + return BP_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_relinquish - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_relinquish (int handle, bp_sid_t sid) +{ + (void)handle; + + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle]); + + bp_object_t* object = (void*)sid; + bplib_os_free(object); + msgq_stores[handle]->count--; + + return BP_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * bplib_store_ram_getcount - + *----------------------------------------------------------------------------*/ +int bplib_store_ram_getcount (int handle) +{ + assert(handle >= 0 && handle < MSGQ_MAX_STORES); + assert(msgq_stores[handle]); + + return msgq_stores[handle]->count; +} diff --git a/unittest/ut_rh_hash.c b/unittest/ut_rh_hash.c index ce4e6714..e5dcae83 100644 --- a/unittest/ut_rh_hash.c +++ b/unittest/ut_rh_hash.c @@ -776,12 +776,12 @@ static void test_8(void) { found_error = true; } - + if(!ut_assert(rh_hash_next (rh_hash, &bundle) == BP_SUCCESS && bundle.cid == cid, "Failed to get same CID %d\n", cid)) { found_error = true; } - + if(!ut_assert(rh_hash_remove(rh_hash, cid, &bundle) == BP_SUCCESS && bundle.cid == cid, "Failed to remove CID %d\n", cid)) { found_error = true; @@ -863,19 +863,19 @@ static void test_9(void) { found_error = true; } - + if(!ut_assert(rh_hash_next (rh_hash, &bundle) == BP_SUCCESS && bundle.cid == next_cid, "Failed to get same CID %d\n", next_cid)) { found_error = true; } - + /* Find Random CID to Remove */ int remove_index = bplib_os_random() % num_added; bp_val_t cid = order_of_cids[remove_index]; while(cid == BP_MAX_ENCODED_VALUE) { remove_index = (remove_index + 1) % num_added; - cid = order_of_cids[remove_index]; + cid = order_of_cids[remove_index]; } /* Remove CID */ diff --git a/v6/bib.c b/v6/bib.c index e553575d..b9f0f84a 100644 --- a/v6/bib.c +++ b/v6/bib.c @@ -175,7 +175,7 @@ int bib_read (void* block, int size, bp_blk_bib_t* bib, bool update_indices, uin if (bytes_read + 1 > size) return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "BIB block terminated prematurely: %d\n", bytes_read); bib->security_target_type = buffer[bytes_read]; - + sdnv_read(buffer, size, &bib->cipher_suite_id, &sdnvflags); sdnv_read(buffer, size, &bib->cipher_suite_flags, &sdnvflags); bytes_read = sdnv_read(buffer, size, &bib->compound_length, &sdnvflags); @@ -236,7 +236,7 @@ int bib_read (void* block, int size, bp_blk_bib_t* bib, bool update_indices, uin } else if (bib->cipher_suite_id.value == BP_BIB_CRC32_CASTAGNOLI) { - if ((bib->security_result_length.value != 4) || (bytes_read + 4 > size)) + if ((bib->security_result_length.value != 4) || (bytes_read + 4 > size)) { return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "BIB block terminated prematurely: %d\n", bytes_read); } @@ -253,7 +253,7 @@ int bib_read (void* block, int size, bp_blk_bib_t* bib, bool update_indices, uin if(sdnvflags != 0) { *flags |= sdnvflags; - return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of BIB (%08X)\n", sdnvflags); + return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of BIB (%08X)\n", sdnvflags); } else { @@ -300,7 +300,7 @@ int bib_write (void* block, int size, bp_blk_bib_t* bib, bool update_indices, ui else if (bib->cipher_suite_id.value == BP_BIB_CRC32_CASTAGNOLI) { bib->compound_length.value = 6; - bib->security_result_length.value = 4; + bib->security_result_length.value = 4; } else { @@ -320,7 +320,7 @@ int bib_write (void* block, int size, bp_blk_bib_t* bib, bool update_indices, ui if (bytes_written + 1 > size) return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Insufficient room for BIB block at: %d\n", bytes_written); buffer[bytes_written] = bib->security_target_type; - + sdnv_write(buffer, size, bib->cipher_suite_id, &sdnvflags); sdnv_write(buffer, size, bib->cipher_suite_flags, &sdnvflags); bytes_written = sdnv_write(buffer, size, bib->compound_length, &sdnvflags); diff --git a/v6/cteb.c b/v6/cteb.c index 0e5bcc5b..d53bf8c5 100644 --- a/v6/cteb.c +++ b/v6/cteb.c @@ -1,13 +1,13 @@ /************************************************************************ * File: cteb.c * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -81,7 +81,7 @@ int cteb_read (void* block, int size, bp_blk_cteb_t* cteb, bool update_indices, if(sdnvflags != 0) { *flags |= sdnvflags; - return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of CTEB (%08X)\n", sdnvflags); + return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of CTEB (%08X)\n", sdnvflags); } else { @@ -146,13 +146,13 @@ int cteb_write (void* block, int size, bp_blk_cteb_t* cteb, bool update_indices, { bplog(&sdnvflags, BP_FLAG_SDNV_OVERFLOW, "CTEB block length too large: %d\n", cteb->blklen.value); } - + /* Success Oriented Error Checking */ if(sdnvflags != 0) { *flags |= sdnvflags; - return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of CTEB (%08X)\n", sdnvflags); + return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of CTEB (%08X)\n", sdnvflags); } else { diff --git a/v6/cteb.h b/v6/cteb.h index 51aa843d..c53797b3 100644 --- a/v6/cteb.h +++ b/v6/cteb.h @@ -1,13 +1,13 @@ /************************************************************************ * File: cteb.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/dacs.c b/v6/dacs.c index 686c2c95..0e94f226 100644 --- a/v6/dacs.c +++ b/v6/dacs.c @@ -1,13 +1,13 @@ /************************************************************************ * File: dacs.c * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -35,11 +35,11 @@ * rec - buffer containing the ACS record [OUTPUT] * size - size of buffer [INPUT] * max_fills_per_dacs - the maximum number of allowable fills for each dacs - * tree - a rb_tree ptr containing the cid ranges for the bundle. The tree nodes will + * tree - a rb_tree ptr containing the cid ranges for the bundle. The tree nodes will * be deleted as they are written to the dacs. [OUTPUT] * iter - a ptr to a ptr the next rb_node in the tree to extract the fill information * and then delete. [OUTPUT] - * + * * Returns: Number of bytes processed of bundle *-------------------------------------------------------------------------------------*/ int dacs_write(uint8_t* rec, int size, int max_fills_per_dacs, rb_tree_t* tree, uint32_t* flags) @@ -47,7 +47,7 @@ int dacs_write(uint8_t* rec, int size, int max_fills_per_dacs, rb_tree_t* tree, bp_field_t cid = { 0, 2, 0 }; bp_field_t fill = { 0, 0, 0 }; uint32_t sdnvflags = 0; - + /* Write Record Information */ rec[BP_ACS_REC_TYPE_INDEX] = BP_ACS_REC_TYPE; /* record type */ rec[BP_ACS_REC_STATUS_INDEX] = BP_ACS_ACK_MASK; @@ -64,14 +64,14 @@ int dacs_write(uint8_t* rec, int size, int max_fills_per_dacs, rb_tree_t* tree, cid.value = range.value; fill.index = sdnv_write(rec, size, cid, &sdnvflags); fill.value = range.offset + 1; - fill.index = sdnv_write(rec, size, fill, &sdnvflags); + fill.index = sdnv_write(rec, size, fill, &sdnvflags); count_fills += 2; /* Traverse tree in order and write out fills to dacs. */ while (count_fills < max_fills_per_dacs && !rb_tree_is_empty(tree)) { prev_range = range; - rb_tree_get_next(tree, &range, true, false); + rb_tree_get_next(tree, &range, true, false); /* Write range of missing cid. Calculate the missing values between the current and previous node. */ @@ -80,16 +80,16 @@ int dacs_write(uint8_t* rec, int size, int max_fills_per_dacs, rb_tree_t* tree, /* Write range of received cids. */ fill.value = range.offset + 1; - fill.index = sdnv_write(rec, size, fill, &sdnvflags); - count_fills += 2; + fill.index = sdnv_write(rec, size, fill, &sdnvflags); + count_fills += 2; } /* Success Oriented Error Checking */ - if(sdnvflags != 0) + if(sdnvflags != 0) { *flags |= sdnvflags; - return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of DACS (%08X)\n", sdnvflags); - } + return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Flags raised during processing of DACS (%08X)\n", sdnvflags); + } /* Return Block Size */ return fill.index; diff --git a/v6/dacs.h b/v6/dacs.h index 6a08999a..499b31df 100644 --- a/v6/dacs.h +++ b/v6/dacs.h @@ -1,13 +1,13 @@ /************************************************************************ * File: dacs.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/pay.c b/v6/pay.c index 5b8c2c56..63af8a67 100644 --- a/v6/pay.c +++ b/v6/pay.c @@ -1,13 +1,13 @@ /************************************************************************ * File: pay.c * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/pay.h b/v6/pay.h index ea437bed..10cf309c 100644 --- a/v6/pay.h +++ b/v6/pay.h @@ -1,13 +1,13 @@ /************************************************************************ * File: pay.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/pri.c b/v6/pri.c index 707de1e4..f61d72d0 100644 --- a/v6/pri.c +++ b/v6/pri.c @@ -1,13 +1,13 @@ /************************************************************************ * File: pri.c * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -43,7 +43,7 @@ int pri_read (void* block, int size, bp_blk_pri_t* pri, bool update_indices, uin uint8_t* blkbuf = (uint8_t*)block; int bytes_read = 0; uint32_t sdnvflags = 0; - + /* Check Size */ if(size < 1) return bplog(flags, BP_FLAG_FAILED_TO_PARSE, "Invalid size of primary block: %d\n", size); diff --git a/v6/pri.h b/v6/pri.h index 2f831c7a..c2e0407e 100644 --- a/v6/pri.h +++ b/v6/pri.h @@ -1,13 +1,13 @@ /************************************************************************ * File: pri.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/sdnv.c b/v6/sdnv.c index d086805e..f86df194 100644 --- a/v6/sdnv.c +++ b/v6/sdnv.c @@ -1,13 +1,13 @@ /************************************************************************ * File: sdnv.c * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -69,10 +69,10 @@ int sdnv_read(uint8_t* block, int size, bp_field_t* sdnv, uint32_t* flags) * the encoded value could not be stored in a bp_val_t */ bplog(flags, BP_FLAG_SDNV_OVERFLOW, "Encoded value was too large to fit into local variable\n"); } - + /* OR in next byte */ sdnv->value |= (block[i] & 0x7F); - + /* Check for end of SDNV */ if((block[i] & 0x80) == 0x00) { @@ -123,7 +123,7 @@ int sdnv_write(uint8_t* block, int size, bp_field_t sdnv, uint32_t* flags) /* Set Fixed Width */ fixedwidth = sdnv.width; } - + /* Check for Truncation */ if(fixedwidth > (size - (int)sdnv.index)) { diff --git a/v6/sdnv.h b/v6/sdnv.h index 66bbad5b..d11b2ec0 100644 --- a/v6/sdnv.h +++ b/v6/sdnv.h @@ -1,13 +1,13 @@ /************************************************************************ * File: sdnv.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): diff --git a/v6/v6.c b/v6/v6.c index 1e4f5c11..895f01a8 100644 --- a/v6/v6.c +++ b/v6/v6.c @@ -383,7 +383,7 @@ int v6_send_bundle(bp_bundle_t* bundle, uint8_t* buffer, int size, bp_create_fun /* Creation time set to current system time */ pri->createsec.value = sysnow; } - + /* Set Creation Time and Sequence */ sdnv_write(data->header, BP_BUNDLE_HDR_BUF_SIZE, pri->createsec, flags); sdnv_write(data->header, BP_BUNDLE_HDR_BUF_SIZE, pri->createseq, flags); @@ -399,7 +399,7 @@ int v6_send_bundle(bp_bundle_t* bundle, uint8_t* buffer, int size, bp_create_fun data->exprtime = BP_UNKNOWN_CREATION_TIME; } else - { + { data->exprtime = pri->createsec.value + lifetime.value; if(data->exprtime < pri->createsec.value) { diff --git a/v6/v6.h b/v6/v6.h index 81cc3823..bc6fa474 100644 --- a/v6/v6.h +++ b/v6/v6.h @@ -1,13 +1,13 @@ /************************************************************************ * File: v6.h * - * Copyright 2019 United States Government as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All Other Rights Reserved. + * Copyright 2019 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Other Rights Reserved. * * This software was created at NASA's Goddard Space Flight Center. - * This software is governed by the NASA Open Source Agreement and may be - * used, distributed and modified only pursuant to the terms of that + * This software is governed by the NASA Open Source Agreement and may be + * used, distributed and modified only pursuant to the terms of that * agreement. * * Maintainer(s): @@ -53,7 +53,7 @@ #define BP_UNKNOWN_CREATION_TIME 1 /* unreliable time source */ #define BP_BEST_EFFORT_LIFETIME 1576800000 /* 50 years; ground systems using 'int' type for time have maximum of 68 years */ -/* Record Type Definitions */ +/* Record Type Definitions */ #define BP_STAT_REC_TYPE 0x10 /* Status Report */ #define BP_CS_REC_TYPE 0x20 /* Custody Signal */ #define BP_ACS_REC_TYPE 0x40 /* Aggregate Custody Signal */