Contiki 2.5
custody_basic.c
Go to the documentation of this file.
1 /**
2  * \addtogroup custody
3  * @{
4  */
5 
6 /**
7  * \defgroup custody_basic basic custody module
8  * @{
9  */
10 
11 /**
12  * \file
13  * \brief implementation of a basic custody module
14  * \author Georg von Zengen <vonzeng@ibr.cs.tu-bs.de>
15  */
16 
17 #include <string.h>
18 
19 #include "memb.h"
20 #include "list.h"
21 #include "mmem.h"
22 
23 #include "bundle.h"
24 #include "storage.h"
25 #include "routing.h"
26 #include "sdnv.h"
27 #include "agent.h"
28 #include "statusreport.h"
29 
30 #include "custody.h"
31 
32 #define RETRANSMIT 1000
33 #define MAX_CUST 10
34 
35 struct cust_t {
36  struct cust *next;
37  uint32_t bundle_num;
38  uint32_t src_node;
39  uint32_t timestamp;
40  uint32_t frag_offset;
41  uint32_t seq_num;
42  uint16_t retransmit_in;
43 };
44 
45 
46 #if 0
47 LIST(cust_list);
48 MEMB(cust_mem, struct cust_t, MAX_CUST);
49 
50 static struct ctimer b_cust_timer;
51 
52 static uint8_t cust_cnt;
53 static uint16_t time;
54 #endif
55 
56 void retransmit();
57 void custody_basic_init(void)
58 {
59 #if 0
60  memb_init(&cust_mem);
61  list_init(cust_list);
62  time=5;
63  cust_cnt=0;
64  ctimer_set(&b_cust_timer,CLOCK_SECOND*time,&retransmit,NULL);
65  return;
66 }
67 
68 void retransmit(){
69  //search bundle to be retransmitted in cust_list
70  struct cust_t *cust;
71  uint16_t mintime=0xFFFF;
72  for(cust = list_head(cust_list); cust != NULL; cust= list_item_next(cust)){
73  //reduce all retransmit times
74  if(cust->retransmit_in - time <=0){
75  //retransmit bundle
76  ROUTING.del_bundle(cust->bundle_num);
77  if(!ROUTING.new_bundle(cust->bundle_num)){
78  return;
79  }
80  //set retransmit time
81  cust->retransmit_in = RETRANSMIT;
82 
83  }else{
84  cust->retransmit_in -= time;
85  if (cust->retransmit_in < mintime){
86  mintime=cust->retransmit_in;
87  }
88  }
89  }
90  ctimer_set(&b_cust_timer,CLOCK_SECOND*mintime,retransmit,NULL);
91 #endif
92 }
93 
94 /* XXX FIXME: Custody not implemented yet!
95 uint8_t b_cust_release(struct bundle_t *bundle)
96 {
97  struct cust_t *cust;
98  uint8_t offset=0;
99  uint8_t cust_sig= *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]) & 32;
100  uint8_t frag = *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]) & 1;
101  offset++;
102  uint8_t status= *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
103  offset++;
104  uint32_t frag_offset, frag_len;
105  uint8_t len;
106  if(!cust_sig){
107  offset++;
108  }
109  if (frag){
110  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
111  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &frag_offset);
112  offset +=len;
113  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
114  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &frag_len);
115  offset +=len;
116  }else{
117  frag_offset=0;
118  }
119 
120  uint32_t acc_time;
121  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
122  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &acc_time);
123  offset +=len;
124 
125  uint32_t timestamp;
126  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
127  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &timestamp);
128  offset +=len;
129 
130  uint32_t seq_num;
131  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
132  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &seq_num);
133  offset +=len;
134 
135  uint32_t src_node;
136  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
137  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &src_node);
138  offset +=len;
139 
140 
141 
142  uint8_t inlist=0;
143 
144 
145  // search custody
146  for(cust = list_head(cust_list); cust != NULL; cust= list_item_next(cust)){
147 // PRINTF("B_CUST: searching...\n");
148  printf("B_CUST: %lu==%lu %lu==%lu %lu==%lu %lu==%lu\n", cust->src_node, src_node ,cust->seq_num ,seq_num ,cust->timestamp ,timestamp ,cust->frag_offset ,frag_offset);
149  if( cust->src_node == src_node && cust->seq_num == seq_num && cust->timestamp == timestamp && cust->frag_offset == frag_offset){
150 // PRINTF("B_CUST: found bundle\n");
151  inlist=1;
152  break;
153  }
154  }
155  if (inlist){
156  printf("B_CUST: release %u\n",cust->bundle_num);
157  // delete in storage
158  BUNDLE_STORAGE.del_bundle(cust->bundle_num,0xff);
159  // delete in list
160  list_remove(cust_list,cust);
161  // free memb
162  memb_free(&cust_mem, cust);
163 
164  if (cust_cnt>0){
165  cust_cnt--;
166  }
167  }
168  // delete_bundle
169  PRINTF("B_CUST: delete bundle %p %p\n", bundle,bundle->mem);
170  delete_bundle(bundle);
171 
172 
173  return 0;
174 }
175 
176 uint8_t b_cust_restransmit(struct bundle_t *bundle)
177 {
178  PRINTF("B_CUST: retransmit\n");
179  struct cust_t *cust;
180  uint8_t offset=0;
181  uint8_t frag = *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]) & 1;
182  offset++;
183  uint8_t status= *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
184  offset++;
185  uint32_t frag_offset, frag_len;
186  uint8_t len;
187 
188  if (frag){
189  PRINTF("B_CUST: fragment\n");
190  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
191  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &frag_offset);
192  offset +=len;
193  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
194  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &frag_len);
195  offset +=len;
196  }else{
197  frag_offset=0;
198  }
199 
200  uint32_t acc_time;
201  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
202  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &acc_time);
203  offset +=len;
204 
205  uint32_t timestamp;
206  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
207  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &timestamp);
208  offset +=len;
209 
210  uint32_t seq_num;
211  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
212  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &seq_num);
213  offset +=len;
214 
215  uint32_t src_node;
216  len = sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset);
217  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + offset, len, &src_node);
218  offset +=len;
219 
220 
221 
222  uint8_t inlist=0;
223 
224 
225  // search custody
226  for(cust = list_head(cust_list); cust != NULL; cust= list_item_next(cust)){
227  if( cust->src_node == src_node && cust->seq_num == seq_num && cust->timestamp == timestamp && cust->frag_offset == frag_offset){
228  inlist=1;
229  break;
230  }
231  }
232  if( inlist){
233  ROUTING.del_bundle(cust->bundle_num);
234  if(!ROUTING.new_bundle(cust->bundle_num)){
235  return 0;
236  }
237  PRINTF("B_CUST: bundle num %u\n",cust->bundle_num);
238  cust->retransmit_in = RETRANSMIT;
239  }
240  // delete_bundle
241  delete_bundle(bundle);
242 
243 
244  return 0;
245 }
246 
247 
248 uint8_t b_cust_report(struct bundle_t *bundle, uint8_t status){
249  PRINTF("B_CUST: send report\n");
250  //send deleted to custodian
251  struct mmem report;
252  uint8_t size=3;
253  uint8_t type=32;
254  uint32_t len;
255  if (bundle->flags &1){
256  type +=1;
257  size += bundle->offset_tab[FRAG_OFFSET][STATE];
258  uint8_t off=0;
259  uint8_t f_len,d_len;
260  while( *((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET] + off) != 0){
261  f_len=sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1);
262  d_len=sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1+f_len);
263  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1+f_len+d_len , d_len , &len);
264  off+=f_len + d_len + len;
265  }
266  f_len=sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1+off);
267  d_len=sdnv_len((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1+f_len+off);
268  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[DATA][OFFSET]+1+f_len+d_len+off , d_len , &len);
269  size+=len;
270  }
271 
272  size += bundle->offset_tab[TIME_STAMP][STATE];
273  size += bundle->offset_tab[TIME_STAMP_SEQ_NR][STATE];
274  size += bundle->offset_tab[SRC_NODE][STATE];
275  size += bundle->offset_tab[SRC_SERV][STATE];
276  if (!mmem_alloc(&report,size)){
277  PRINTF("B_CUST: OOOPS\n");
278  return 0;
279  }
280  *(uint8_t*) report.ptr = type;
281  *(((uint8_t*) report.ptr)+1)= status;
282  uint8_t offset=2;
283  if( bundle->flags & 1){
284  memcpy(((uint8_t*) report.ptr) + offset, bundle->mem.ptr + bundle->offset_tab[FRAG_OFFSET][OFFSET],bundle->offset_tab[TIME_STAMP][STATE]);
285  offset+= bundle->offset_tab[FRAG_OFFSET][STATE];
286  struct mmem sdnv;
287  uint8_t sdnv_len= sdnv_encoding_len(len);
288  if(mmem_alloc(&sdnv,sdnv_len)){
289  sdnv_encode(len, (uint8_t*) sdnv.ptr, sdnv_len);
290  memcpy(((uint8_t*) report.ptr) + offset , sdnv.ptr , sdnv_len);
291  offset+= sdnv_len;
292  mmem_free(&sdnv);
293  }else{
294  PRINTF("B_CUST: OOOPS1\n");
295  return 0;
296  }
297  }
298  *(((uint8_t*) report.ptr)+offset)= 0;
299  offset+=1;
300  memcpy(((uint8_t*) report.ptr) + offset, bundle->mem.ptr + bundle->offset_tab[TIME_STAMP][OFFSET],bundle->offset_tab[TIME_STAMP][STATE]);
301  offset+= bundle->offset_tab[TIME_STAMP][STATE];
302  memcpy(((uint8_t*) report.ptr) + offset, bundle->mem.ptr + bundle->offset_tab[TIME_STAMP_SEQ_NR][OFFSET], bundle->offset_tab[TIME_STAMP_SEQ_NR][STATE]);
303  offset+= bundle->offset_tab[TIME_STAMP_SEQ_NR][STATE];
304  memcpy(((uint8_t*) report.ptr) + offset, bundle->mem.ptr + bundle->offset_tab[SRC_NODE][OFFSET], bundle->offset_tab[SRC_NODE][STATE]);
305  offset+= bundle->offset_tab[SRC_NODE][STATE];
306  memcpy(((uint8_t*) report.ptr) + offset, bundle->mem.ptr + bundle->offset_tab[SRC_SERV][OFFSET], bundle->offset_tab[SRC_SERV][STATE]);
307 
308  struct bundle_t rep_bundle;
309  create_bundle(&rep_bundle);
310  uint32_t tmp;
311  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[CUST_NODE][OFFSET],bundle->offset_tab[CUST_NODE][STATE],&tmp);
312  set_attr(&rep_bundle, DEST_NODE, &tmp);
313  sdnv_decode((uint8_t*)bundle->mem.ptr + bundle->offset_tab[CUST_SERV][OFFSET],bundle->offset_tab[CUST_SERV][STATE],&tmp);
314  set_attr(&rep_bundle, DEST_SERV, &tmp);
315  set_attr(&rep_bundle, SRC_NODE, &dtn_node_id);
316  tmp=2;
317  set_attr(&rep_bundle, FLAGS, &tmp);
318  tmp=0;
319  set_attr(&rep_bundle, SRC_SERV, &tmp);
320  set_attr(&rep_bundle, REP_NODE, &tmp);
321  set_attr(&rep_bundle, REP_SERV, &tmp);
322  set_attr(&rep_bundle, CUST_NODE, &tmp);
323  set_attr(&rep_bundle, CUST_SERV, &tmp);
324  set_attr(&rep_bundle, TIME_STAMP, &tmp);
325  set_attr(&rep_bundle,TIME_STAMP_SEQ_NR,&dtn_seq_nr);
326  dtn_seq_nr++;
327  tmp=3000;
328  set_attr(&rep_bundle, LIFE_TIME, &tmp);
329  unsigned int old_size = rep_bundle.mem.size;
330  if(mmem_realloc(&rep_bundle.mem, rep_bundle.mem.size + report.size)){
331  memcpy((char *)rep_bundle.mem.ptr+ old_size, report.ptr, report.size);
332  mmem_free(&report);
333  }else{
334  PRINTF("B_CUST: OOOOPPS2\n");
335  mmem_free(&report);
336  mmem_free(&rep_bundle.mem);
337  }
338  //printf("B_CUST: len %u\n",
339 #if DEBUG
340  uint8_t i;
341  PRINTF("B_CUST: %u ::",rep_bundle.mem.size);
342  for(i=0;i<rep_bundle.mem.size; i++){
343  PRINTF("%x:",*((uint8_t *)rep_bundle.mem.ptr+i));
344  }
345  PRINTF("\n");
346 #endif
347  rep_bundle.size = rep_bundle.mem.size;
348  int32_t saved=BUNDLE_STORAGE.save_bundle(&rep_bundle);
349  if (saved >=0){
350  uint16_t *saved_as_num = memb_alloc(saved_as_mem);
351  *saved_as_num = (uint16_t)saved;
352  delete_bundle(&rep_bundle);
353  process_post(&agent_process,dtn_bundle_in_storage_event, saved_as_num);
354  printf("B_CUST: %u \n",*saved_as_num);
355  return 1;
356  }else{
357  delete_bundle(&rep_bundle);
358  return 0;
359  }
360 
361  //delete in list
362  //if(!(status & 128)&&(status & 4))
363  // list_remove(cust_list,cust);
364  // free memb
365  // memb_free(&cust_mem, cust);
366  //}
367 }
368 
369 
370 int32_t b_cust_decide(struct bundle_t *bundle)
371 {
372  PRINTF("B_CUST: decide %u\n",cust_cnt);
373  uint8_t free=BUNDLE_STORAGE.free_space(bundle);
374  uint32_t src, cust_node;
375  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[SRC_NODE][OFFSET],bundle->offset_tab[SRC_NODE][STATE],&src);
376 
377  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[CUST_NODE][OFFSET],bundle->offset_tab[CUST_NODE][STATE],&cust_node);
378  if (free > 0 && cust_cnt < MAX_CUST && (src!= dtn_node_id || cust_node == dtn_node_id)){
379  bundle->custody=1;
380  uint32_t tmp;
381  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[CUST_NODE][OFFSET],bundle->offset_tab[CUST_NODE][STATE],&tmp);
382  set_attr(bundle,CUST_NODE,&dtn_node_id);
383  int32_t saved= BUNDLE_STORAGE.save_bundle(bundle);
384  if (saved>=0){
385  printf("B_CUST: acc %u\n", ((uint16_t)saved));
386  struct cust_t *cust;
387  cust = memb_alloc(&cust_mem);
388  cust->frag_offset=0;
389  cust->bundle_num= (uint16_t) saved;
390  PRINTF("B_CUST: cust->bundle_num= %u\n",cust->bundle_num);
391  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[SRC_NODE][OFFSET] , bundle->offset_tab[SRC_NODE][STATE] , &cust->src_node);
392  PRINTF("B_CUST: cust->src_node= %lu\n",cust->src_node);
393  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[TIME_STAMP][OFFSET] , bundle->offset_tab[TIME_STAMP][STATE] , &cust->timestamp);
394  PRINTF("B_CUST: cust->timestamp %lu\n",cust->timestamp);
395  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[TIME_STAMP_SEQ_NR][OFFSET] , bundle->offset_tab[TIME_STAMP_SEQ_NR][STATE] , &cust->seq_num);
396  PRINTF("B_CUST: cust->seq_num %lu\n",cust->seq_num);
397  struct cust_t *t_cust;
398  for(t_cust = list_head(cust_list); t_cust != NULL; t_cust= list_item_next(t_cust)){
399  if (cust->bundle_num == t_cust->bundle_num){
400  // printf("B_CUST: allready custodian\n");
401  return saved;
402  }
403  }
404  if (bundle->flags & 1){
405  sdnv_decode(bundle->mem.ptr + bundle->offset_tab[FRAG_OFFSET][OFFSET] , bundle->offset_tab[FRAG_OFFSET][STATE] , &cust->frag_offset);
406  }else{
407  cust->frag_offset=0;
408  }
409  cust->retransmit_in=RETRANSMIT;
410  //save saved to list
411  list_add(cust_list, cust);
412  cust_cnt++;
413  if (cust->src_node != dtn_node_id){
414  printf("B_CUST: %lu != %lu\n",cust->src_node,dtn_node_id);
415  set_attr(bundle,CUST_NODE,&tmp);
416  STATUS_REPORT.send(bundle, 2,0);
417  }
418  }
419 
420  return saved;
421  }else{
422  printf("B_CUST: cust_cnt > MAX_CUST %u %u\n",cust_cnt,free);
423  return -1;
424  }
425 }
426 void b_cust_del_from_list(uint16_t bundle_num)
427 {
428  struct cust_t *t_cust;
429  for(t_cust = list_head(cust_list); t_cust != NULL; t_cust= list_item_next(t_cust)){
430  if (bundle_num == t_cust->bundle_num){
431  list_remove(cust_list,t_cust);
432  // free memb
433  memb_free(&cust_mem, t_cust);
434  if (cust_cnt>0){
435  cust_cnt--;
436  }
437  }
438  }
439 }
440 */
441 
442 uint8_t custody_basic_release(struct mmem *bundlemem)
443 {
444  return 0;
445 }
446 uint8_t custody_basic_retransmit(struct mmem *bundlemem)
447 {
448  return 0;
449 }
450 uint8_t custody_basic_report(struct mmem *bundlemem, uint8_t status)
451 {
452  return 0;
453 }
454 uint8_t custody_basic_decide(struct mmem *bundlemem, uint32_t * bundle_number)
455 {
456  return 0;
457 }
458 void custody_basic_delete_from_list(uint32_t bundle_num)
459 {
460  return;
461 }
462 
463 const struct custody_driver custody_basic ={
464  "B_CUSTODY",
465  custody_basic_init,
466  custody_basic_release,
467  custody_basic_report,
468  custody_basic_decide,
469  custody_basic_retransmit,
470  custody_basic_delete_from_list,
471 };
472 /** @} */
473 /** @} */