Contiki 2.5
sdnv.c
Go to the documentation of this file.
1  /**
2  * \addtogroup sdnv SDNV Functions
3  *
4  * @{
5  */
6 
7 /**
8  * \file
9  * \brief implementation of SDNV functions
10  * \author Georg von Zengen (vonzeng@ibr.cs.tu-bs.de)
11  */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdint.h>
16 
17 #include "logging.h"
18 
19 #include "agent.h"
20 
21 /** maximum sdnv length */
22 #define MAX_LENGTH 8
23 
24 int sdnv_encode(uint32_t val, uint8_t* bp, size_t len)
25 {
26  size_t val_len = 0;
27  uint32_t tmp = val;
28 
29  do {
30  tmp = tmp >> 7;
31  val_len++;
32  } while (tmp != 0);
33 
34 
35  if (len < val_len) {
36  return -1;
37  }
38 
39  bp += val_len;
40  uint8_t high_bit = 0; // for the last octet
41  do {
42  --bp;
43  *bp = (uint8_t)(high_bit | (val & 0x7f));
44  high_bit = (1 << 7); // for all but the last octet
45  val = val >> 7;
46  } while (val != 0);
47 
48  return val_len;
49 }
50 
51 size_t sdnv_encoding_len(uint32_t val)
52 {
53  size_t val_len = 0;
54 // printf("val %lu ptr %p\n ",val,&val);
55  do {
56  val = val >> 7;
57  val_len++;
58  } while (val != 0);
59 
60  return val_len;
61 }
62 
63 int sdnv_decode(const uint8_t* bp, size_t len, uint32_t* val)
64 {
65  LOG(LOGD_DTN, LOG_SDNV, LOGL_DBG, "sdnv_decode");
66  const uint8_t* start = bp;
67  if (!val) {
68  LOG(LOGD_DTN, LOG_SDNV, LOGL_ERR, "SDNV: NULL pointer");
69  return -1;
70  }
71  size_t val_len = 0;
72  *val = 0;
73  do {
74  LOG(LOGD_DTN, LOG_SDNV, LOGL_DBG, "SDNV: len: %u", len);
75  if (len == 0){
76  LOG(LOGD_DTN, LOG_SDNV, LOGL_ERR, "SDNV: buffer too short");
77  return -1; // buffer too short
78  }
79  *val = (*val << 7) | (*bp & 0x7f);
80  ++val_len;
81 
82  if ((*bp & (1 << 7)) == 0){
83  break; // all done;
84  }
85 
86  ++bp;
87  --len;
88  } while (1);
89 
90  if ((val_len > MAX_LENGTH) || ((val_len == MAX_LENGTH) && (*start != 0x81))){
91  LOG(LOGD_DTN, LOG_SDNV, LOGL_ERR, "SDNV: val_len >= %u", MAX_LENGTH);
92  return -1;
93  }
94 
95  LOG(LOGD_DTN, LOG_SDNV, LOGL_DBG, "SDNV: val: %lu", *val);
96  return val_len;
97 }
98 
99 size_t sdnv_len(const uint8_t* bp)
100 {
101  size_t val_len = 1;
102  for ( ; *bp++ & 0x80; ++val_len )
103  ;
104  return val_len;
105 }
106 /** @} */
107 
108 
109