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
+}