Blockwise options added
diff --git a/src/CoAP_EncDec.cc b/src/CoAP_EncDec.cc
index ccc4884..dd5066f 100644
--- a/src/CoAP_EncDec.cc
+++ b/src/CoAP_EncDec.cc
@@ -7,6 +7,8 @@
*
* Contributors:
* Mate Kovacs - initial implementation and initial documentation
+* Antal Wu-Hen Chang
+* Naum Spaseski
******************************************************************************/
//
// File: CoAP_EncDec.cc
@@ -22,6 +24,9 @@
int getIntegerLength(const long long int value, int mode);
void encodeInteger(TTCN_Buffer &stream, const long long int option, const int length);
long long int decodeInteger(OCTETSTRING const &str, const int position, const int length);
+int getBlockLengthForNum(const long long int num);
+void encodeBlock(TTCN_Buffer &stream, const BlockOption option, const int length);
+void decodeBlock(BlockOption& block, OCTETSTRING const &str, const int position, const int length);
INTEGER
f__CoAP__dec(OCTETSTRING const &str, CoAP__Message &msg)
@@ -122,6 +127,9 @@
case 5:
msg.msg().options()()[count_of_options].if__none__match() = OCTETSTRING(0, 0);
break;
+ case 6:
+ msg.msg().options()()[count_of_options].observe().set_long_long_val(decodeInteger(str, position, length));
+ break;
case 7:
msg.msg().options()()[count_of_options].uri__port().set_long_long_val(decodeInteger(str, position, length));
break;
@@ -146,6 +154,12 @@
case 20:
msg.msg().options()()[count_of_options].location__query().decode_utf8(length, &str_ptr[position]);
break;
+ case 23: // Block2 RFC 7959
+ decodeBlock(msg.msg().options()()[count_of_options].block2(), str, position, length);
+ break;
+ case 27: // Block1 RFC 7959
+ decodeBlock(msg.msg().options()()[count_of_options].block1(), str, position, length);
+ break;
case 35:
msg.msg().options()()[count_of_options].proxy__uri().decode_utf8(length, &str_ptr[position]);
break;
@@ -344,6 +358,9 @@
case CoAP__Options::ALT_if__none__match:
stream.put_os(msg.msg().options()()[optionOrder[i]].if__none__match());
break;
+ case CoAP__Options::ALT_observe:
+ encodeInteger(stream, msg.msg().options()()[optionOrder[i]].observe(), length);
+ break;
case CoAP__Options::ALT_uri__port:
encodeInteger(stream, msg.msg().options()()[optionOrder[i]].uri__port(), length);
break;
@@ -368,6 +385,12 @@
case CoAP__Options::ALT_location__query:
msg.msg().options()()[optionOrder[i]].location__query().encode_utf8(stream, false);
break;
+ case CoAP__Options::ALT_block1:
+ encodeBlock(stream, msg.msg().options()()[optionOrder[i]].block1(), length);
+ break;
+ case CoAP__Options::ALT_block2:
+ encodeBlock(stream, msg.msg().options()()[optionOrder[i]].block2(), length);
+ break;
case CoAP__Options::ALT_proxy__uri:
msg.msg().options()()[optionOrder[i]].proxy__uri().encode_utf8(stream, false);
break;
@@ -420,6 +443,9 @@
case CoAP__Options::ALT_if__none__match:
return 5;
break;
+ case CoAP__Options::ALT_observe:
+ return 6;
+ break;
case CoAP__Options::ALT_uri__port:
return 7;
break;
@@ -444,6 +470,12 @@
case CoAP__Options::ALT_location__query:
return 20;
break;
+ case CoAP__Options::ALT_block1: // RFC 7959
+ return 27;
+ break;
+ case CoAP__Options::ALT_block2: // RFC 7959
+ return 23;
+ break;
case CoAP__Options::ALT_proxy__uri:
return 35;
break;
@@ -477,6 +509,9 @@
case CoAP__Options::ALT_if__none__match:
return option.if__none__match().lengthof();
break;
+ case CoAP__Options::ALT_observe:
+ return getIntegerLength(option.observe().get_long_long_val(), 3);
+ break;
case CoAP__Options::ALT_uri__port:
return getIntegerLength(option.uri__port().get_long_long_val(), 2);
break;
@@ -501,6 +536,12 @@
case CoAP__Options::ALT_location__query:
return option.location__query().lengthof();
break;
+ case CoAP__Options::ALT_block1:
+ return getBlockLengthForNum(option.block1().num().get_long_long_val());
+ break;
+ case CoAP__Options::ALT_block2:
+ return getBlockLengthForNum(option.block2().num().get_long_long_val());
+ break;
case CoAP__Options::ALT_proxy__uri:
return option.proxy__uri().lengthof();
break;
@@ -556,4 +597,67 @@
return value;
}
+// RFC 7959
+int getBlockLengthForNum(const long long int num) {
+ if (num < 0 || num > 1048575)
+ TTCN_error("CoAP: Error at getBlockLengthForNum: num must larger than 0 and smaller than 1048576!");
+
+ if (num <= 15) { // 2^4-1
+ return 1;
+ }
+ else if (num <= 1023) { // 2^10-1
+ return 2;
+ }
+ else if (num <= 1048575) { // 2^20-1
+ return 3;
+ }
+ return 0;
+}
+
+// RFC 7959
+void encodeBlock(TTCN_Buffer &stream, const BlockOption option, const int length) {
+
+ unsigned char chr;
+
+ long long int num_val = option.num().get_long_long_val();
+
+ char szx;
+ szx = option.szx().get_long_long_val() & 0x07; // szx_val & 00000111b
+
+ char m;
+ if ((bool) option.m())
+ m = 0x08; // 00001000b
+ else
+ m = 0x00; // 00000000b
+
+ char num;
+ for(int i = length-1; i > 0; i--){
+ num = (num_val >> (8 * i - 4)) & 0xff;
+ stream.put_c(num);
+ }
+ num = (num_val << 4) & 0xf0; // num_val & 11110000b
+
+ chr = num | m | szx;
+ stream.put_c(chr);
+}
+
+void decodeBlock(BlockOption& block, OCTETSTRING const &str, const int position, const int length) {
+
+ int num = 0;
+ for(int i = 0; i < length-1; i++) {
+ num += (str[position+i].get_octet() << (8 * (length-i-1) - 4));
+ }
+ num += (str[position+length-1].get_octet() >> 4) & 0x0f;
+
+ int szx = 0;
+ szx = str[position+length-1].get_octet() & 0x07;
+
+ int m = 0;
+ m = str[position+length-1].get_octet() & 0x08;
+
+ block.num() = INTEGER(num);
+ block.szx() = INTEGER(szx);
+ block.m() = BOOLEAN(m > 0);
+}
+
}
diff --git a/src/CoAP_Types.ttcn b/src/CoAP_Types.ttcn
index 42bd3e2..5a6f08b 100644
--- a/src/CoAP_Types.ttcn
+++ b/src/CoAP_Types.ttcn
@@ -7,6 +7,8 @@
*
* Contributors:
* Mate Kovacs - initial implementation and initial documentation
+* Antal Wu-Hen Chang
+* Naum Spaseski
******************************************************************************/
//
// File: CoAP_Types.ttcn
@@ -84,6 +86,13 @@
integer option_code,
octetstring option_value
}
+
+ type record BlockOption
+ {
+ integer num (0..1048575),
+ boolean m,
+ integer szx (0..7)
+ }
type union CoAP_Options
{
@@ -91,6 +100,7 @@
UCHAR1_255 uri_host,
OCT1_8 etag,
OCT0 if_none_match,
+ integer observe,
integer uri_port,
UCHAR0_255 location_path,
UCHAR0_255 uri_path,
@@ -99,13 +109,16 @@
UCHAR0_255 uri_query,
integer accept,
UCHAR0_255 location_query,
+ BlockOption block1,
+ BlockOption block2,
UCHAR1_1034 proxy_uri,
UCHAR1_255 proxy_scheme,
integer size1,
UnknownOption unknown_option
}
- type record of CoAP_Options CoAP_OptionsList;
+ // FIXME: EANTWUH: Option order is not strict: record -> set
+ type set of CoAP_Options CoAP_OptionsList;
type record CoAP_ReqResp
{
@@ -121,4 +134,4 @@
octetstring raw_message
}
-}
\ No newline at end of file
+}