Contiki 2.5
delivery.c
Go to the documentation of this file.
1 /**
2  * \addtogroup bprocess
3  * @{
4  */
5 
6 /**
7  * \file
8  *
9  * \author Georg von Zengen <vonzeng@ibr.cs.tu-bs.de>
10  * \author Wolf-Bastian Poettner <poettner@ibr.cs.tu-bs.de>
11  */
12 
13 #include <stdint.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #include "lib/list.h"
19 #include "process.h"
20 #include "logging.h"
21 
22 #include "bundle.h"
23 #include "api.h"
24 #include "registration.h"
25 #include "statusreport.h"
26 #include "sdnv.h"
27 #include "agent.h"
28 #include "custody.h"
29 #include "statistics.h"
30 #include "storage.h"
31 
32 #include "delivery.h"
33 
34 void delivery_unblock_service(struct mmem * bundlemem) {
35  struct registration * n = NULL;
36  struct bundle_t * bundle = NULL;
37 
38  if( bundlemem == NULL ) {
39  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_ERR, "invalid MMEM pointer");
40  return;
41  }
42 
43  bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
44  if( bundle == NULL ) {
45  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_ERR, "invalid bundle");
46  bundle_decrement(bundlemem);
47  return;
48  }
49 
50  // Unlock the bundle so that it can be deleted
51  BUNDLE_STORAGE.unlock_bundle(bundle->bundle_num);
52 
53  // Let's see, what service registrations we have
54  for(n = list_head(reg_list);
55  n != NULL;
56  n = list_item_next(n)) {
57 
58  if(n->app_id == bundle->dst_srv) {
59  if(n->status == APP_ACTIVE) {
60  if( n->busy ) {
61  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_DBG, "unblocking service");
62  n->busy = 0;
63  return;
64  }
65  }
66  }
67  }
68 
69  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_ERR, "No Service found to unblock");
70 }
71 
72 /**
73  * \brief Delivers bundle to a local service
74  * \param bundlemem Pointer to the MMEM bundle representation
75  * \returns <0 on error >=0 on success
76  */
77 int delivery_deliver_bundle(struct mmem *bundlemem) {
78  struct registration * n = NULL;
79  struct bundle_t * bundle = NULL;
80  int delivered = 0;
81  int busy = 0;
82 
83  if( bundlemem == NULL ) {
84  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_ERR, "invalid MMEM pointer");
85  return DELIVERY_STATE_ERROR;
86  }
87 
88  bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
89  if( bundle == NULL ) {
90  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_ERR, "invalid bundle");
91  bundle_decrement(bundlemem);
92  return DELIVERY_STATE_ERROR;
93  }
94 
95  // Let's see, what service registrations we have
96  for(n = list_head(reg_list);
97  n != NULL;
98  n = list_item_next(n)) {
99 
100  if(n->app_id == bundle->dst_srv &&
101  n->node_id == bundle->dst_node ) {
102  if(n->status == APP_ACTIVE) {
103  if( !n->busy ) {
104  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_DBG, "Service found, delivering...");
105 
106  // Mark service as busy to prevent further bundle deliveries
107  n->busy = 1;
108 
109  // Lock the bundle so it will not be deleted in the meantime
110  BUNDLE_STORAGE.lock_bundle(bundle->bundle_num);
111 
112  // Post the event to the respective service
113  process_post(n->application_process, submit_data_to_application_event, bundlemem);
114 
115  delivered = 1;
116 
117  // We deliver only to the first service in line - multiple registrations are not supported
118  break;
119  } else {
120  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_DBG, "Service is busy");
121  busy = 1;
122  }
123  } else
124  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_DBG, "Service is inactive");
125  }
126  }
127 
128  if( !delivered && busy ) {
129  // if we did not find a registration, deallocate the memory
130  bundle_decrement(bundlemem);
131  // Return error code
132  return DELIVERY_STATE_BUSY;
133  }
134 
135  if( !delivered ) {
136  // if we did not find a registration, deallocate the memory
137  bundle_decrement(bundlemem);
138 
139  // Return error code
140  return DELIVERY_STATE_ERROR;
141  }
142 
143  // Notify statistics
145 
146  // And report to custody
147  if (bundle->flags & BUNDLE_FLAG_CUST_REQ) {
148  CUSTODY.report(bundlemem, 128);
149  }
150 
151  // Possibly send status report
152  if( bundle->flags & BUNDLE_FLAG_REP_DELIV ) {
153  STATUSREPORT.send(bundlemem, NODE_DELIVERED_BUNDLE, NO_ADDITIONAL_INFORMATION);
154  }
155 
156 #if DEBUG_H
157  uint16_t time = clock_time();
158  time -= bundle->debug_time;
159  LOG(LOGD_DTN, LOG_BUNDLE, LOGL_DBG, "time needed to process bundle for Delivery: %i", time);
160 #endif
161 
162  return DELIVERY_STATE_WAIT_FOR_APP;
163 }
164 /** @} */