mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-01 15:35:46 +03:00
new option encoding function
This commit is contained in:
1 parent
d7af1a6223
commit
c45cf23a61
3 files changed
+153
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ */
|
||||
Reference in new issue
Block a user