/*---------------------------------------------------------------------------*/ static size_t coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) { size_t written = 0; buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); if(delta > 268) { buffer[++written] = ((delta - 269) >> 8) & 0xff; buffer[++written] = (delta - 269) & 0xff; } else if(delta > 12) {
int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt) { size_t opts_len = 0; size_t i; uint8_t *p; uint16_t running_delta = 0; // build header if (*buflen < 4) return COAP_ERR_BUFFER_TOO_SMALL; buf[0] = (pkt->hdr.ver & 0x03) << 6; buf[0] |= (pkt->hdr.t & 0x03) << 4; buf[0] |= (pkt->hdr.tkl & 0x0F); buf[1] = pkt->hdr.code; buf[2] = pkt->hdr.id[0]; buf[3] = pkt->hdr.id[1]; // http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3.1 // inject options p = buf + 4; for (i=0;i<pkt->numopts;i++) { uint8_t optDelta, len, delta = 0; if (p-buf > *buflen) return COAP_ERR_BUFFER_TOO_SMALL; optDelta = pkt->opts[i].num - running_delta; coap_option_nibble(optDelta, &delta); coap_option_nibble(pkt->opts[i].buf.len, &len); *p++ = (0xFF & (delta << 4 | len)); if (delta == 13) { *p++ = (optDelta - 13); } else if (delta == 14) { *p++ = ((optDelta-269) >> 8); *p++ = (0xFF & (optDelta-269)); } if (len == 13) { *p++ = (pkt->opts[i].buf.len - 13); } else if (len == 14) { *p++ = (pkt->opts[i].buf.len >> 8); *p++ = (0xFF & (pkt->opts[i].buf.len-269)); }
/*---------------------------------------------------------------------------*/ static size_t coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) { size_t written = 0; buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); /* avoids code duplication without function overhead */ unsigned int *x = δ do { if(*x > 268) { buffer[++written] = (*x - 269) >> 8; buffer[++written] = (*x - 269); } else if(*x > 12) { buffer[++written] = (*x - 13); } } while(x != &length && (x = &length));
int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt) { size_t opts_len = 0; size_t i; uint8_t *p; uint16_t running_delta = 0; // build header if (*buflen < (4U + pkt->header.tkllen)) { return COAP_ERR_BUFFER_TOO_SMALL; } buf[0] = (pkt->header.version & 0x03) << 6; buf[0] |= (pkt->header.type & 0x03) << 4; buf[0] |= (pkt->header.tkllen & 0x0F); buf[1] = pkt->header.code; buf[2] = pkt->header.mid[0]; buf[3] = pkt->header.mid[1]; // inject token p = buf + 4; if ((pkt->header.tkllen > 0) && (pkt->header.tkllen != pkt->token.len)) { return COAP_ERR_UNSUPPORTED; } if (pkt->header.tkllen > 0) { memcpy(p, pkt->token.p, pkt->header.tkllen); } // inject options p += pkt->header.tkllen; for (i = 0; i < pkt->numopts; i++) { uint32_t optDelta; uint8_t len; uint8_t delta = 0; if (((size_t)(p - buf)) > *buflen) { return COAP_ERR_BUFFER_TOO_SMALL; } optDelta = pkt->opts[i].num - running_delta; coap_option_nibble(optDelta, &delta); coap_option_nibble((uint32_t)pkt->opts[i].val.len, &len); *p++ = (0xFF & (delta << 4 | len)); if (delta == 13) { *p++ = (optDelta - 13); } else if (delta == 14) { *p++ = ((optDelta - 269) >> 8); *p++ = (0xFF & (optDelta - 269)); } if (len == 13) { *p++ = (pkt->opts[i].val.len - 13); } else if (len == 14) { *p++ = (pkt->opts[i].val.len >> 8); *p++ = (0xFF & (pkt->opts[i].val.len - 269)); }
int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt) { size_t opts_len = 0; size_t i; uint8_t *p; uint16_t running_delta = 0; // build header if (*buflen < (4U + pkt->hdr.tkl)) return COAP_ERR_BUFFER_TOO_SMALL; buf[0] = (pkt->hdr.ver & 0x03) << 6; buf[0] |= (pkt->hdr.t & 0x03) << 4; buf[0] |= (pkt->hdr.tkl & 0x0F); buf[1] = pkt->hdr.code; buf[2] = pkt->hdr.id[0]; buf[3] = pkt->hdr.id[1]; // inject token p = buf + 4; if ((pkt->hdr.tkl > 0) && (pkt->hdr.tkl != pkt->tok.len)) return COAP_ERR_UNSUPPORTED; if (pkt->hdr.tkl > 0) memcpy(p, pkt->tok.p, pkt->hdr.tkl); // // http://tools.ietf.org/html/rfc7252#section-3.1 // inject options p += pkt->hdr.tkl; for (i=0;i<pkt->numopts;i++) { uint32_t optDelta; uint8_t len, delta = 0; if (((size_t)(p-buf)) > *buflen) return COAP_ERR_BUFFER_TOO_SMALL; optDelta = pkt->opts[i].num - running_delta; coap_option_nibble(optDelta, &delta); coap_option_nibble((uint32_t)pkt->opts[i].buf.len, &len); *p++ = (0xFF & (delta << 4 | len)); if (delta == 13) { *p++ = (optDelta - 13); } else if (delta == 14) { *p++ = ((optDelta-269) >> 8); *p++ = (0xFF & (optDelta-269)); } if (len == 13) { *p++ = (pkt->opts[i].buf.len - 13); } else if (len == 14) { *p++ = (pkt->opts[i].buf.len >> 8); *p++ = (0xFF & (pkt->opts[i].buf.len-269)); }