new option encoding function

This commit is contained in:
Olaf Bergmann committed 2012-10-25 18:18:49 +02:00
1 parent d7af1a6223
commit c45cf23a61
3 files changed
+153

No files matched your search

+5
View File
@@ -1,3 +1,8 @@
2012-10-25 Olaf Bergmann <bergmann@tzi.org>
* option.c (coap_opt_encode): new function for option encoding
with option jumps
2012-03-23 Olaf Bergmann <bergmann@tzi.org>
* examples/client.c (clear_obs): clear observation relationship after
+117
View File
@@ -15,6 +15,7 @@
#endif
#include <stdio.h>
#include <string.h>
#include "option.h"
@@ -91,3 +92,119 @@ coap_check_option(coap_pdu_t *pdu, unsigned char type,
return oi->option && oi->type == type ? oi->option : NULL;
}
size_t
coap_opt_encode(coap_opt_t *opt, size_t n, unsigned short delta,
unsigned char *val, unsigned short len) {
size_t l = 1;
size_t length = len;
unsigned int D = delta;
coap_opt_t *O = opt;
unsigned short N;
/* option length must not exceed 1034 bytes */
if (length > 1034)
return 0;
/* check for option jumps */
if (delta < 15) {
/* no option jump required, proceed with normal encoding if
sufficient space is available */
if (n < length + 1)
return 0;
goto encode;
}
if (delta < 30) { /* encode with short option jump */
/* check if sufficient storage space is available */
if (n < length + 2)
return 0;
delta -= 15;
l++; /* need one additional byte for 0xf1 */
*opt++ = 0xf1;
goto encode;
}
/* Values up to 2070 can be encoded with a single jump value
* (((0xff + 2) << 3) + 14) == 257 * 8 + 14 = 2070). For values
* below 2064, we use the last three bits from delta as the
* delta value and always encode N as (delta >> 3) - 2. Above
* 2064, N will be (delta >> 3) - 3, and
* delta = delta - ((N + 2) << 3).
*/
if (delta < 2071) { /* longer option jump */
/* check if sufficient storage space is available */
if (n < length + 2)
return 0;
N = (delta >> 3) - 2;
if (N > 255) {
N--;
delta = (delta + 8) & 0x0f;
} else
delta = (delta & 0x07);
l += 2; /* need two additional bytes for 0xf2 nn */
*opt++ = 0xf2;
*opt++ = N & 0xff;
goto encode;
}
/* longest option jump (delta <= 65535) */
/* check if sufficient storage space is available */
if (n < length + 3)
return 0;
N = (delta >> 3) - 258;
delta = (delta & 0x07);
l += 3; /* need three additional bytes for 0xf3 nn nn */
*opt++ = 0xf3;
*opt++ = (N >> 8) & 0xff;
*opt++ = N & 0xff;
encode:
{
size_t k;
printf("delta(%d) = ", D);
for (k = 0; k < l-1; ++k) {
printf("%02x ", O[k]);
}
printf("%xx\n", delta & 0x0f);
}
return 0;
if (length < 15) {
*opt++ = (delta << 4) | (length & 0x0f);
n--;
} else {
*opt = ((delta & 0x0f) << 4) | 0x0f;
opt++; n--;
length -= 15;
while (255 <= length && len < n) {
++l;
*opt++ = 0xff;
length -= 255;
n--;
}
if (len < n) {
++l;
*opt++ = length & 0xff;
n--;
} else
return 0;
}
memcpy(opt, val, len);
return l + len;
}
+31
View File
@@ -38,6 +38,20 @@ typedef unsigned char coap_opt_t;
? (*(PCHAR(opt) + 1) + 15) \
: (*PCHAR(opt) & 0x0f)))
/**
* Encodes the option delta, length and value.
*
* @param opt start of the given option
* @param n maximum length of the option
* @param delta the option delta
* @param val the value to write
* @param length option length
* @return the number of bytes that are used to encode the option length
* or @c 0 in case of error.
*/
size_t coap_opt_encode(coap_opt_t *opt, size_t n, unsigned char delta,
unsigned char *val, unsigned short len);
#define COAP_OPT_SETLENGTH(opt,val) \
if ((val) < 15) \
*PCHAR(opt) = ((*PCHAR(opt) & 0xf0) | ((val) & 0x0f)); \
@@ -217,6 +231,23 @@ coap_opt_t *coap_check_option(coap_pdu_t *pdu,
unsigned char type,
coap_opt_iterator_t *oi);
/**
* Encodes option with given @p delta into @p opt. This function returns
* the number of bytes written to @p opt or @c 0 on error. This happens
* especially when @p opt does not provide sufficient space to store
* the option value, delta, and option jumps when required.
*
* @param opt The option buffer space where @p val is written
* @param n Maximum length of @p opt.
* @param delta The option delta.
* @param val The option value to copy into @p opt.
* @param len The actual length of @p val.
* @return The number of bytes that have been written to @p opt or
* @c 0 on error. The return value will always be less than @p n.
*/
size_t coap_opt_encode(coap_opt_t *opt, size_t n, unsigned short delta,
unsigned char *val, unsigned short len);
/** @} */
#endif /* _OPTION_H_ */