43 #define STORAGE_FILE_NAME_LENGTH 15
51 struct file_list_entry_t {
53 struct file_list_entry_t *
next;
59 uint32_t bundle_flags;
70 #define STORAGE_COFFEE_FLAGS_LOCKED 0x1
78 static uint16_t bundles_in_storage;
81 static struct ctimer g_store_timer;
84 static uint8_t bundle_list_changed = 0;
94 #define RADIO_SAFE_STATE_ON() NETSTACK_MAC.off(0)
95 #define RADIO_SAFE_STATE_OFF() NETSTACK_MAC.on()
116 bundles_in_storage = 0;
117 bundle_list_changed = 0;
119 #if BUNDLE_STORAGE_INIT
122 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"Formatting flash");
125 RADIO_SAFE_STATE_OFF();
142 struct cfs_dir directory_iterator;
143 struct cfs_dirent directory_entry;
144 char * delimeter =
NULL;
146 struct mmem * bundleptr =
NULL;
154 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to list directory /");
155 RADIO_SAFE_STATE_OFF();
159 while(
cfs_readdir(&directory_iterator, &directory_entry) != -1 ) {
161 delimeter = strchr(directory_entry.name,
'.');
163 if( delimeter ==
NULL ) {
165 LOG(LOGD_DTN, LOG_STORE, LOGL_WRN,
"filename %s is invalid, skipping", directory_entry.name);
170 if( *(delimeter+1) !=
'b' ) {
172 LOG(LOGD_DTN, LOG_STORE, LOGL_WRN,
"filename %s is invalid, skipping", directory_entry.name);
178 bundle_number = strtoul(directory_entry.name,
NULL, 10);
186 if( entry->bundle_num == bundle_number ) {
198 if( entry ==
NULL ) {
199 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to allocate struct, cannot restore bundle");
205 entry->file_size = directory_entry.size;
209 bundles_in_storage ++;
212 RADIO_SAFE_STATE_OFF();
216 if( bundleptr ==
NULL ) {
217 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to restore bundle %lu", entry->bundle_num);
220 bundles_in_storage--;
228 entry->rec_time = bundle->rec_time;
229 entry->lifetime = bundle->lifetime;
230 entry->file_size = bundleptr->size;
231 entry->bundle_num = bundle->bundle_num;
243 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"Restored %u bundles from CFS", bundles_in_storage);
245 RADIO_SAFE_STATE_OFF();
253 uint32_t elapsed_time;
260 elapsed_time = clock_seconds() - entry->rec_time;
262 if( entry->lifetime < elapsed_time ) {
263 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"bundle lifetime expired of bundle %lu", entry->bundle_num);
278 while(bundles_in_storage > 0) {
281 if( entry ==
NULL ) {
290 bundles_in_storage = 0;
304 if( bundlemem ==
NULL ) {
308 #if BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DO_NOT_DELETE
313 #elif (BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_OLDEST || BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_YOUNGEST )
319 unsigned long comparator = 0;
320 struct file_list_entry_t * deletor =
NULL;
332 if( (entry->bundle_flags & BUNDLE_PRIORITY_MASK) > (bundle->flags & BUNDLE_PRIORITY_MASK ) ) {
336 #if BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_OLDEST
337 if( (clock_seconds() - entry->rec_time) > comparator || comparator == 0) {
338 comparator = clock_seconds() - entry->rec_time;
341 #elif BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_YOUNGEST
342 if( (clock_seconds() - entry->rec_time) < comparator || comparator == 0) {
343 comparator = clock_seconds() - entry->rec_time;
350 if( entry ==
NULL ) {
358 #elif (BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_OLDER || BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_YOUNGER )
360 struct file_list_entry_t * entry =
NULL;
379 if( (entry->bundle_flags & BUNDLE_PRIORITY_MASK) > (bundle->flags & BUNDLE_PRIORITY_MASK ) ) {
383 #if BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_OLDER
387 if( bundle->lifetime - (clock_seconds() - bundle->rec_time) >= entry->lifetime - (clock_seconds() - entry->rec_time) ) {
390 #elif BUNDLE_STORAGE_BEHAVIOUR == BUNDLE_STORAGE_BEHAVIOUR_DELETE_YOUNGER
392 if( bundle->lifetime - (clock_seconds() - bundle->rec_time) >= entry->lifetime - (clock_seconds() - entry->rec_time) ) {
399 if( entry ==
NULL ) {
408 #error No Bundle Deletion Strategy defined
429 if( bundlemem ==
NULL ) {
430 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"save_bundle with invalid pointer %p", bundlemem);
437 if( bundle ==
NULL ) {
438 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"save_bundle with invalid MMEM structure");
448 if( bundle->bundle_num == entry->bundle_num ) {
449 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"%lu is the same bundle", entry->bundle_num);
450 *bundle_number_ptr = &entry->bundle_num;
452 return entry->bundle_num;
457 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"Cannot store bundle, no room");
470 if( entry ==
NULL ) {
471 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to allocate struct, cannot store bundle");
477 memset(entry, 0,
sizeof(
struct file_list_entry_t));
480 entry->rec_time = bundle->rec_time;
481 entry->lifetime = bundle->lifetime;
482 entry->file_size = bundlemem->size;
483 entry->bundle_flags = bundle->flags;
486 entry->bundle_num = bundle->bundle_num;
491 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"file name buffer is too short");
502 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to reserve %u bytes for bundle", bundlemem->size);
505 RADIO_SAFE_STATE_OFF();
511 if( fd_write == -1 ) {
513 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to open file %s, cannot save bundle", bundle_filename);
516 RADIO_SAFE_STATE_OFF();
521 n = cfs_write(fd_write, bundle, bundlemem->size);
522 if( n != bundlemem->size ) {
523 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to write %u bytes to file %s, aborting", bundlemem->size, bundle_filename);
528 RADIO_SAFE_STATE_OFF();
535 RADIO_SAFE_STATE_OFF();
537 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"New Bundle %lu (%lu), Src %lu.%lu, Dest %lu.%lu, Seq %lu", bundle->bundle_num, entry->bundle_num, bundle->src_node, bundle->src_srv, bundle->dst_node, bundle->dst_srv, bundle->tstamp_seq);
543 bundle_list_changed = 1;
544 bundles_in_storage++;
551 *bundle_number_ptr = &entry->bundle_num;
566 struct mmem * bundlemem =
NULL;
570 LOG(LOGD_DTN, LOG_STORE, LOGL_INF,
"Deleting Bundle %lu with reason %u", bundle_number, reason);
577 if( entry->bundle_num == bundle_number ) {
582 if( entry ==
NULL ) {
583 LOG(LOGD_DTN, LOG_STORE, LOGL_WRN,
"Could not find bundle %lu on del_bundle", bundle_number);
588 if( reason != REASON_DELIVERED ) {
589 if( (entry->bundle_flags & BUNDLE_FLAG_CUST_REQ ) || (entry->bundle_flags & BUNDLE_FLAG_REP_DELETE) ){
591 if( bundlemem ==
NULL ) {
592 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to read back bundle %lu", bundle_number);
597 bundle->del_reason = reason;
599 if (bundle->src_node != dtn_node_id){
609 agent_delete_bundle(bundle_number);
617 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"file name buffer is too short");
625 RADIO_SAFE_STATE_OFF();
628 bundle_list_changed = 1;
629 bundles_in_storage--;
646 struct mmem * bundlemem =
NULL;
651 LOG(LOGD_DTN, LOG_STORE, LOGL_DBG,
"Reading Bundle %lu", bundle_number);
658 if( entry->bundle_num == bundle_number ) {
663 if( entry ==
NULL ) {
664 LOG(LOGD_DTN, LOG_STORE, LOGL_WRN,
"Could not find bundle %lu on read_bundle", bundle_number);
669 if( bundlemem ==
NULL ) {
670 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"cannot allocate memory for bundle %lu", bundle_number);
676 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to realloc enough memory");
684 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"file name buffer is too short");
693 if( fd_read == -1 ) {
695 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to open file %s, cannot read bundle", bundle_filename);
701 n = cfs_read(fd_read,
MMEM_PTR(bundlemem), bundlemem->size);
702 if( n != bundlemem->size ) {
703 LOG(LOGD_DTN, LOG_STORE, LOGL_ERR,
"unable to read %u bytes from file %s, aborting", bundlemem->size, bundle_filename);
712 RADIO_SAFE_STATE_OFF();
718 uint32_t elapsed_time = clock_seconds() - bundle->rec_time;
721 if( bundle->lifetime < elapsed_time ) {
722 bundle->lifetime = 0;
723 bundle->rec_time = clock_seconds();
725 bundle->lifetime = bundle->lifetime - elapsed_time;
726 bundle->rec_time = clock_seconds();
747 return bundles_in_storage;
773 if( entry->bundle_num == bundle_num ) {
778 if( entry ==
NULL ) {
798 if( entry->bundle_num == bundle_num ) {
803 if( entry ==
NULL ) {