negative testing added
diff --git a/src/negative_testing/CoAP_EncDec.cc b/src/negative_testing/CoAP_EncDec.cc
new file mode 100644
index 0000000..6d3412d
--- /dev/null
+++ b/src/negative_testing/CoAP_EncDec.cc
@@ -0,0 +1,747 @@
+/******************************************************************************
+* Copyright (c) 2016  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*  Mate Kovacs - initial implementation and initial documentation
+*  Antal Wu-Hen Chang
+*  Naum Spaseski
+*  Bence Janos Szabo - negative testing branch 
+******************************************************************************/
+//
+//  File:               CoAP_EncDec.cc
+//  Rev:                R1A
+//  Prodnr:             CNL 113 829
+
+#include "CoAP_Types.hh"
+
+namespace CoAP__Types {
+
+int getOptionCode(CoAP__Options option);
+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)
+{
+  if(TTCN_Logger::log_this_event(TTCN_DEBUG)){
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("Decoding CoAP message: ");
+    str.log();
+    TTCN_Logger::end_event();
+  }
+
+  if(str.lengthof() >= 4){
+    const unsigned char* str_ptr = (const unsigned char*) str;
+    unsigned char chr;
+    int position = 0;
+    int token_length = 0;
+    int actual_option_code = 0;
+    int count_of_options = 0;
+    bool payload_marker = false;
+
+    //version, message type and token length
+    chr = str_ptr[0];
+    msg.msg().version() = chr >> 6;
+    msg.msg().msg__type() = (chr >> 4) & 3;
+    token_length = chr & 15;
+    msg.msg().tkl() = token_length;
+    //code
+    chr = str_ptr[1];
+    msg.msg().code().class_() = (chr >> 5) & 7;
+    msg.msg().code().detail() = chr & 31;
+    //message ID
+    msg.msg().message__id() = str_ptr[2] * 256 + str_ptr[3];
+
+    if(str.lengthof() > 4 && msg.msg().code().class_() == 0 && msg.msg().code().detail() == 0){
+	  msg.raw__message() = str;
+	  return 1;
+    }
+
+    position = 4;
+    //token
+    if(token_length > 0){
+      if(str.lengthof() >= position + token_length){
+	    msg.msg().token() = OCTETSTRING(token_length, &str_ptr[position]);
+	    position += token_length;
+      }else{
+        msg.raw__message() = str;
+	    return 1;
+	  }
+    }else{
+	  msg.msg().token() = OCTETSTRING(0, 0);
+    }
+    //options
+    msg.msg().options() = OMIT_VALUE;
+    if(str.lengthof() > 4){
+      while(!payload_marker && str.lengthof() > position){
+      int delta = str_ptr[position] >> 4;
+	    int length = str_ptr[position] & 15;
+	    if(delta == 15 && length != 15){
+	      msg.raw__message() = str;
+	      return 1;
+	    }
+        position++;
+	    if(delta == 15 && length == 15){
+	      payload_marker = true;
+	    }else{
+        msg.msg().options()()[count_of_options].option__delta() = delta;
+        msg.msg().options()()[count_of_options].option__length() = length;
+	      //optional delta
+        int opt_delta = 0;
+	      if(delta == 13){
+	        delta = str_ptr[position] + 13;
+          opt_delta = str_ptr[position];
+		    position++;
+	      }else if(delta == 14){
+          delta = (str_ptr[position] << 8) + str_ptr[position+1] + 269;
+          opt_delta = (str_ptr[position] << 8) + str_ptr[position+1];
+	        position += 2;
+	      }
+	      //optional length
+        int opt_length = 0;
+	      if(length == 13){
+		    length = str_ptr[position] + 13;
+        opt_length = str_ptr[position];
+		    position++;
+	      }else if(length == 14){
+		    length = (str_ptr[position] << 8) + str_ptr[position+1] + 269;
+        opt_length = (str_ptr[position] << 8) + str_ptr[position+1];
+		    position += 2;
+	      }else if(length == 15){
+	        msg.raw__message() = str;
+	        return 1;
+	      }
+        if (opt_delta != 0) {
+          if (opt_delta >= 0 && opt_delta <= 255) {
+            msg.msg().options()()[count_of_options].option__delta__ext()().int__bit8() = opt_delta;
+          } else if (opt_delta > 255 && opt_delta <= 65335) {
+            msg.msg().options()()[count_of_options].option__delta__ext()().int__bit16() = opt_delta;
+          }
+        } else {
+          msg.msg().options()()[count_of_options].option__delta__ext() = OMIT_VALUE;
+        }
+        if (opt_length != 0) {
+          if (opt_length >= 0 && opt_length <= 255) {
+            msg.msg().options()()[count_of_options].option__length__ext()().int__bit8() = opt_length;
+          } else if (opt_length > 255 && opt_length <= 65335) {
+            msg.msg().options()()[count_of_options].option__length__ext()().int__bit16() = opt_length;
+          }
+        } else {
+          msg.msg().options()()[count_of_options].option__length__ext() = OMIT_VALUE;
+        }
+
+	      //value
+	      actual_option_code += delta;
+	      switch(actual_option_code){
+	      case 1:
+	    	msg.msg().options()()[count_of_options].option__value().if__match() = OCTETSTRING(length, &str_ptr[position]);
+		    break;
+	      case 3:
+	    	msg.msg().options()()[count_of_options].option__value().uri__host().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 4:
+	    	msg.msg().options()()[count_of_options].option__value().etag() = OCTETSTRING(length, &str_ptr[position]);
+		    break;
+          case 5:
+            msg.msg().options()()[count_of_options].option__value().if__none__match() = OCTETSTRING(0, 0);
+		    break;
+          case 6:
+            if (length <= 1) {
+              msg.msg().options()()[count_of_options].option__value().observe().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+            } else if (length <= 2) {
+              msg.msg().options()()[count_of_options].option__value().observe().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+            } else if (length <= 3) {
+              msg.msg().options()()[count_of_options].option__value().observe().int__bit24().set_long_long_val(decodeInteger(str, position, length));
+            } else if (length <= 4) {
+              msg.msg().options()()[count_of_options].option__value().observe().int__bit32().set_long_long_val(decodeInteger(str, position, length));
+            }
+            break;
+	      case 7:
+          if (length <= 1) {
+            msg.msg().options()()[count_of_options].option__value().uri__port().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length >= 2) {
+            msg.msg().options()()[count_of_options].option__value().uri__port().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+          }
+		    break;
+	      case 8:
+	    	msg.msg().options()()[count_of_options].option__value().location__path().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 11:
+	    	msg.msg().options()()[count_of_options].option__value().uri__path().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 12:
+          if (length <= 1) {
+            msg.msg().options()()[count_of_options].option__value().content__format().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length >= 2) {
+            msg.msg().options()()[count_of_options].option__value().content__format().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+          }
+	        break;
+	      case 14:
+          if (length <= 1) {
+            msg.msg().options()()[count_of_options].option__value().max__age().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 2) {
+            msg.msg().options()()[count_of_options].option__value().max__age().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 3) {
+            msg.msg().options()()[count_of_options].option__value().max__age().int__bit24().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 4) {
+            msg.msg().options()()[count_of_options].option__value().max__age().int__bit32().set_long_long_val(decodeInteger(str, position, length));
+          }
+	        break;
+	      case 15:
+	    	msg.msg().options()()[count_of_options].option__value().uri__query().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 17:
+          if (length <= 1) {
+            msg.msg().options()()[count_of_options].option__value().accept().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length >= 2) {
+            msg.msg().options()()[count_of_options].option__value().accept().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+          }
+		    break;
+	      case 20:
+	    	msg.msg().options()()[count_of_options].option__value().location__query().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 23: // Block2 RFC 7959
+	    	decodeBlock(msg.msg().options()()[count_of_options].option__value().block2(), str, position, length);
+	    	break;
+	      case 27: // Block1 RFC 7959
+	    	decodeBlock(msg.msg().options()()[count_of_options].option__value().block1(), str, position, length);
+	    	break;
+	      case 35:
+	    	msg.msg().options()()[count_of_options].option__value().proxy__uri().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 39:
+	    	msg.msg().options()()[count_of_options].option__value().proxy__scheme().decode_utf8(length, &str_ptr[position]);
+		    break;
+	      case 60:
+          if (length <= 1) {
+            msg.msg().options()()[count_of_options].option__value().size1().int__bit8().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 2) {
+            msg.msg().options()()[count_of_options].option__value().size1().int__bit16().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 3) {
+            msg.msg().options()()[count_of_options].option__value().size1().int__bit24().set_long_long_val(decodeInteger(str, position, length));
+          } else if (length <= 4) {
+            msg.msg().options()()[count_of_options].option__value().size1().int__bit32().set_long_long_val(decodeInteger(str, position, length));
+          }
+		    break;
+	      default:
+		    msg.msg().options()()[count_of_options].option__value().unknown__option().option__code() = actual_option_code;
+		    msg.msg().options()()[count_of_options].option__value().unknown__option().option__value() = OCTETSTRING(length, &str_ptr[position]);
+		    break;
+	      }
+	      position += length;
+	      count_of_options++;
+        }
+      }
+    }
+
+    //payload
+    if(str.lengthof() > position){
+    msg.msg().payload()().payloadMarker() = OCTETSTRING(1, &str_ptr[position]-1);
+	  msg.msg().payload()().payload() = OCTETSTRING(str.lengthof() - position, &str_ptr[position]);
+	  if(msg.msg().payload()().payload().lengthof() == 0){
+	    msg.raw__message() = str;
+	    return 1;
+	  }
+    }else{
+	  if(payload_marker){
+	    msg.raw__message() = str;
+	    return 1;
+	  }else{
+	    msg.msg().payload() = OMIT_VALUE;
+	  }
+    }
+  }else{
+    msg.raw__message() = str;
+    return 1;
+  }
+
+  if(TTCN_Logger::log_this_event(TTCN_DEBUG)){
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("Decoded CoAP message: ");
+    msg.log();
+    TTCN_Logger::end_event();
+  }
+
+  return 0;
+}
+
+INTEGER
+f__CoAP__enc(CoAP__Message const &msg, OCTETSTRING &str)
+{
+  TTCN_Buffer stream;
+  unsigned char chr = 0;
+
+  if(TTCN_Logger::log_this_event(TTCN_DEBUG)){
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("Encoding CoAP message: ");
+    msg.log();
+    TTCN_Logger::end_event();
+  }
+
+  switch(msg.get_selection()){
+  case CoAP__Message::ALT_raw__message:
+	  stream.put_os(msg.raw__message());
+	  stream.get_string(str);
+	  return 0;
+	  break;
+  case CoAP__Message::ALT_msg:
+  default:
+	  break;
+  }
+
+  //HEADER
+    //version
+  if(0 <= msg.msg().version() && msg.msg().version() <= 3){
+    chr = msg.msg().version() << 6;
+  }else{
+	return 1;
+  }
+    //message type
+  chr += msg.msg().msg__type() << 4;
+    //tkl (token length)
+  chr += (int)(msg.msg().tkl());
+
+  stream.put_c(chr);
+    //code
+  if(msg.msg().code().class_() >= 0 && msg.msg().code().class_() <= 7){
+    chr = msg.msg().code().class_() << 5;
+  }else{
+	return 1;
+  }
+  if(msg.msg().code().detail() >= 0 && msg.msg().code().detail() <= 31){
+    chr += msg.msg().code().detail();
+  }else{
+	return 1;
+  }
+  stream.put_c(chr);
+    //message ID
+  if(msg.msg().message__id() >= 0 && msg.msg().message__id() <= 65535){
+    encodeInteger(stream, msg.msg().message__id(), 2);
+  }else{
+	return 1;
+  }
+
+  //TOKEN
+  stream.put_os(msg.msg().token());
+
+  //OPTIONS
+  if(msg.msg().options().ispresent() && msg.msg().options()().size_of() > 0){
+	int optionOrder[msg.msg().options()().size_of()];
+	int temp;
+	for(int i = 0; i < msg.msg().options()().size_of(); i++){
+		optionOrder[i] = i;
+	}
+
+	//determine the order of options
+	for(int j = 0; j < msg.msg().options()().size_of()-1; j++){
+      int minOptionCode = getOptionCode(msg.msg().options()()[optionOrder[j]].option__value());
+      int minOptionIndex = j;
+      for(int i = j+1; i < msg.msg().options()().size_of(); i++){
+        if(getOptionCode(msg.msg().options()()[optionOrder[i]].option__value()) < minOptionCode){
+        	minOptionCode = getOptionCode(msg.msg().options()()[optionOrder[i]].option__value());
+        	minOptionIndex = i;
+        }
+      }
+      temp = optionOrder[minOptionIndex];
+      optionOrder[minOptionIndex] = optionOrder[j];
+      optionOrder[j] = temp;
+	}
+
+	//encode options
+	int previousOptionCode = 0;
+	for(int i = 0; i < msg.msg().options()().size_of(); i++){
+      int delta = msg.msg().options()()[optionOrder[i]].option__delta();
+      int length = msg.msg().options()()[optionOrder[i]].option__length();
+
+      previousOptionCode += delta;
+      //first byte
+      if(delta >= 0 && delta <= 15){
+        chr = delta << 4;
+      } else {
+        return 1;
+      }
+      if(length >= 0 && length <= 15){
+        chr += length;
+  	  }else{
+  		  return 1;
+  	  }
+      stream.put_c(chr);
+
+      //optional delta
+      if (msg.msg().options()()[optionOrder[i]].option__delta__ext().ispresent()) {
+        switch(msg.msg().options()()[optionOrder[i]].option__delta__ext()().get_selection()) {
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit8:
+            chr = (int)(msg.msg().options()()[optionOrder[i]].option__delta__ext()().int__bit8());
+            stream.put_c(chr);
+            break;
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit16:
+            encodeInteger(stream, (int)(msg.msg().options()()[optionOrder[i]].option__delta__ext()().int__bit16()), 2);
+            break;
+          default:
+            return 1;
+        }
+      }
+      //optional length
+      if (msg.msg().options()()[optionOrder[i]].option__length__ext().ispresent()) {
+        switch(msg.msg().options()()[optionOrder[i]].option__length__ext()().get_selection()) {
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit8:
+            chr = (int)(msg.msg().options()()[optionOrder[i]].option__length__ext()().int__bit8());
+            stream.put_c(chr);
+            break;
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit16:
+            encodeInteger(stream, (int)(msg.msg().options()()[optionOrder[i]].option__length__ext()().int__bit16()), 2);
+            break;
+          default:
+           return 1;
+        }
+      }
+      //option value
+      if(length > 0){
+    	switch(msg.msg().options()()[optionOrder[i]].option__value().get_selection()){
+    	  case CoAP__Options::ALT_if__match:
+    		  stream.put_os(msg.msg().options()()[optionOrder[i]].option__value().if__match());
+    	    break;
+    	  case CoAP__Options::ALT_uri__host:
+    		  msg.msg().options()()[optionOrder[i]].option__value().uri__host().encode_utf8(stream, false);
+    	    break;
+		  case CoAP__Options::ALT_etag:
+			  stream.put_os(msg.msg().options()()[optionOrder[i]].option__value().etag());
+			  break;
+		  case CoAP__Options::ALT_if__none__match:
+			  stream.put_os(msg.msg().options()()[optionOrder[i]].option__value().if__none__match());
+			  break;
+		  case CoAP__Options::ALT_observe:
+			  switch(msg.msg().options()()[optionOrder[i]].option__value().observe().get_selection()) {
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().observe().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().observe().int__bit16(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit24:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().observe().int__bit24(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit32:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().observe().int__bit32(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_uri__port:
+        switch(msg.msg().options()()[optionOrder[i]].option__value().uri__port().get_selection()) {
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().uri__port().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().uri__port().int__bit16(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_location__path:
+			  msg.msg().options()()[optionOrder[i]].option__value().location__path().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_uri__path:
+			  msg.msg().options()()[optionOrder[i]].option__value().uri__path().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_content__format:
+        switch(msg.msg().options()()[optionOrder[i]].option__value().content__format().get_selection()) {
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().content__format().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().content__format().int__bit16(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_max__age:
+        switch(msg.msg().options()()[optionOrder[i]].option__value().max__age().get_selection()) {
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().max__age().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().max__age().int__bit16(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit24:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().max__age().int__bit24(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit32:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().max__age().int__bit32(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_uri__query:
+			  msg.msg().options()()[optionOrder[i]].option__value().uri__query().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_accept:
+        switch(msg.msg().options()()[optionOrder[i]].option__value().accept().get_selection()) {
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().accept().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__BIT16__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().accept().int__bit16(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_location__query:
+			  msg.msg().options()()[optionOrder[i]].option__value().location__query().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_block1:
+			  encodeBlock(stream, msg.msg().options()()[optionOrder[i]].option__value().block1(), length);
+			  break;
+		  case CoAP__Options::ALT_block2:
+			  encodeBlock(stream, msg.msg().options()()[optionOrder[i]].option__value().block2(), length);
+			  break;
+		  case CoAP__Options::ALT_proxy__uri:
+			  msg.msg().options()()[optionOrder[i]].option__value().proxy__uri().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_proxy__scheme:
+			  msg.msg().options()()[optionOrder[i]].option__value().proxy__scheme().encode_utf8(stream, false);
+			  break;
+		  case CoAP__Options::ALT_size1:
+        switch(msg.msg().options()()[optionOrder[i]].option__value().size1().get_selection()) {
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit8:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().size1().int__bit8(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit16:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().size1().int__bit16(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit24:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().size1().int__bit24(), length);
+            break;
+          case INT__BIT8__OR__16__OR__24__OR__32__MSB::ALT_int__bit32:
+             encodeInteger(stream, msg.msg().options()()[optionOrder[i]].option__value().size1().int__bit32(), length);
+            break;
+          default:
+            break;
+        }
+			  break;
+		  case CoAP__Options::ALT_unknown__option:
+			  stream.put_os(msg.msg().options()()[optionOrder[i]].option__value().unknown__option().option__value());
+			  break;
+		  case CoAP__Options::UNBOUND_VALUE:
+		  default:
+			return 8;
+			break;
+		}
+      }
+	}
+  }
+
+  //PAYLOAD
+  if(msg.msg().payload().ispresent()){
+    stream.put_os(msg.msg().payload()().payloadMarker()); //payload marker
+    stream.put_os(msg.msg().payload()().payload());
+  }
+
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("Encoded CoAP message: ");
+  stream.log();
+  TTCN_Logger::end_event();
+
+  stream.get_string(str);
+
+  return 0;
+}
+
+//helper functions
+int getOptionCode(CoAP__Options option){
+  switch(option.get_selection()){
+    case CoAP__Options::ALT_if__match:
+    	    return 1;
+        break;
+    case CoAP__Options::ALT_uri__host:
+        	return 3;
+        break;
+    case CoAP__Options::ALT_etag:
+        	return 4;
+        break;
+    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;
+    case CoAP__Options::ALT_location__path:
+        	return 8;
+        break;
+    case CoAP__Options::ALT_uri__path:
+        	return 11;
+        break;
+    case CoAP__Options::ALT_content__format:
+        	return 12;
+        break;
+    case CoAP__Options::ALT_max__age:
+        	return 14;
+        break;
+    case CoAP__Options::ALT_uri__query:
+        	return 15;
+        break;
+    case CoAP__Options::ALT_accept:
+        	return 17;
+        break;
+    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;
+    case CoAP__Options::ALT_proxy__scheme:
+        	return 39;
+        break;
+    case CoAP__Options::ALT_size1:
+        	return 60;
+        break;
+    case CoAP__Options::ALT_unknown__option:
+        	return option.unknown__option().option__code();
+        break;
+    case CoAP__Options::UNBOUND_VALUE:
+    default:
+    	TTCN_error("CoAP: Error at getOptionCode!");
+    	break;
+  }
+}
+
+int getIntegerLength(const long long int value, int mode){
+	if(value == 0){
+	  return 0;
+	}else if(value / 269 == 0){
+	  return 1;
+	}else if(value / 65805 == 0){
+	  return 2;
+	}else if(mode == 4 && value / 16777485 == 0){
+      return 3;
+	}else if(mode == 4 && value / 4294967296 == 0){
+	  return 4;
+	}else{
+		TTCN_error("CoAP: Error at getIntegerLength!");
+	}
+}
+
+void encodeInteger(TTCN_Buffer &stream, const long long int option, const int length){
+  unsigned char chr;
+
+  for(int i = length-1; i > 0; i--){
+	  chr = (option >> (8 * i)) & 255;
+	  stream.put_c(chr);
+  }
+  chr = option & 255;
+  stream.put_c(chr);
+}
+
+long long int decodeInteger(OCTETSTRING const &str, const int position, const int length){
+  int value = 0;
+
+  for(int i = 0; i < length; i++){
+	  value += (str[position+i].get_octet() << (8 * (length-i-1)));
+  }
+  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 = 0;
+  if (option.num().int__bit4().ispresent()) {
+      num_val = option.num().int__bit4()().get_long_long_val();
+  } else if (option.num().int__bit12().ispresent()) {
+      num_val = option.num().int__bit12()().get_long_long_val();
+  } else if (option.num().int__bit20().ispresent()) {
+      num_val = option.num().int__bit20()().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;
+
+  if (num >= 0 && num <= 15) {
+    block.num().int__bit4() = INTEGER(num);
+    block.num().int__bit12() = OMIT_VALUE;
+    block.num().int__bit20() = OMIT_VALUE;
+  } else if (num >= 16 && num <= 4095) {
+    block.num().int__bit12() = INTEGER(num);
+    block.num().int__bit4() = OMIT_VALUE;
+    block.num().int__bit20() = OMIT_VALUE;
+  } else if (num >= 4096 && num <= 1048575) {
+    block.num().int__bit20() = INTEGER(num);
+    block.num().int__bit4() = OMIT_VALUE;
+    block.num().int__bit12() = OMIT_VALUE;
+  }
+	block.szx() = INTEGER(szx);
+	block.m() = BOOLEAN(m > 0);
+}
+
+}
diff --git a/src/negative_testing/CoAP_Types.ttcn b/src/negative_testing/CoAP_Types.ttcn
new file mode 100644
index 0000000..6b32dd8
--- /dev/null
+++ b/src/negative_testing/CoAP_Types.ttcn
@@ -0,0 +1,234 @@
+/******************************************************************************
+* Copyright (c) 2016  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*  Mate Kovacs - initial implementation and initial documentation
+*  Antal Wu-Hen Chang
+*  Naum Spaseski
+*  Bence Janos Szabo - negative testing branch 
+******************************************************************************/
+//
+//  File:               CoAP_Types.ttcn
+//  Rev:                R1A
+//  Prodnr:             CNL 113 829
+
+module CoAP_Types
+{
+  external function f_CoAP_enc(in CoAP_Message msg, out octetstring str) return integer;
+  external function f_CoAP_dec(in octetstring str, out CoAP_Message msg) return integer;
+
+  external function f_CoAP_encode(in CoAP_Message msg, out octetstring str)
+  with {
+    extension "prototype(fast) encode(RAW)"
+  }
+
+  // RAW decode is not working correctly
+  external function f_CoAP_decode(in octetstring str, out CoAP_Message msg)
+  with {
+    extension "prototype(fast) decode(RAW)"
+  }
+
+
+  const Code EMPTY_MESSAGE:={ 0, 0 };
+  
+  const Code METHOD_GET:={ 0, 1 };
+  const Code METHOD_POST:={ 0, 2 };
+  const Code METHOD_PUT:={ 0, 3 };
+  const Code METHOD_DELETE:={ 0, 4 };
+
+  const Code RESPONSE_CODE_Created:={ 2, 1 };
+  const Code RESPONSE_CODE_Deleted:={ 2, 2 };
+  const Code RESPONSE_CODE_Valid:={ 2, 3 };
+  const Code RESPONSE_CODE_Changed:={ 2, 4 };
+  const Code RESPONSE_CODE_Content:={ 2, 5 };
+  
+  const Code RESPONSE_CODE_BadRequest:={ 4, 0 };
+  const Code RESPONSE_CODE_Unauthorized:={ 4, 1 };
+  const Code RESPONSE_CODE_BadOption:={ 4, 2 };
+  const Code RESPONSE_CODE_Forbidden:={ 4, 3 };
+  const Code RESPONSE_CODE_NotFound:={ 4, 4 };
+  const Code RESPONSE_CODE_MethodNotAllowed:={ 4, 5 };
+  const Code RESPONSE_CODE_NotAcceptable:={ 4, 6 };
+  const Code RESPONSE_CODE_PreconditionFailed:={ 4, 12 };
+  const Code RESPONSE_CODE_RequestEntityTooLarge:={ 4, 13 };
+  const Code RESPONSE_CODE_UnsupportedContentFormat:={ 4, 15 };
+  
+  const Code RESPONSE_CODE_InternalServerError:={ 5, 0 };
+  const Code RESPONSE_CODE_NotImplemented:={ 5, 1 };
+  const Code RESPONSE_CODE_BadGateway:={ 5, 2 };
+  const Code RESPONSE_CODE_ServiceUnavailable:={ 5, 3 };
+  const Code RESPONSE_CODE_GatewayTimeout:={ 5, 4 };
+  const Code RESPONSE_CODE_ProxyingNotSupported:={ 5, 5 };
+
+  type octetstring OCT0     length (0);
+  type octetstring OCT0_8   length(0..8);
+  type octetstring OCT1_8   length(1..8);
+  type octetstring OCT0_2   length(0..2) with { variant "" };
+  type octetstring OCT0_INF              with { variant "" };
+  type octetstring OCT1_MSB length(1)    with { variant "FIELDLENGTH(1),BITORDER(msb)" };
+  
+  type universal charstring UCHAR0_255    length(0..255);
+  type universal charstring UCHAR1_255    length(1..255);
+  type universal charstring UCHAR1_1034   length(1..1034);
+
+  type integer INT_BIT2_MSB   (0..3)          with { variant "FIELDLENGTH(2),  BITORDER(msb)" };
+  type integer INT_BIT3_MSB   (0..7)          with { variant "FIELDLENGTH(3),  BITORDER(msb)" };
+  type integer INT_BIT4_MSB   (0..15)         with { variant "FIELDLENGTH(4),  BITORDER(msb)" };
+  type integer INT_BIT4       (0..15)         with { variant "FIELDLENGTH(4),  BYTEORDER(last)" };
+  type integer INT_BIT5_MSB   (0..31)         with { variant "FIELDLENGTH(5),  BITORDER(msb)" };
+  type integer INT_BIT8_MSB   (0..255)        with { variant "FIELDLENGTH(8),  BITORDER(msb)" };
+  type integer INT_BIT12_MSB  (0..4095)       with { variant "FIELDLENGTH(12), BYTEORDER(last)" };
+  type integer INT_BIT16_MSB  (0..65335)      with { variant "FIELDLENGTH(16), BITORDER(msb)" };
+  type integer INT_BIT20_MSB  (0..1048575)    with { variant "FIELDLENGTH(20), BYTEORDER(last)" };
+  type integer INT_BIT24_MSB                  with { variant "FIELDLENGTH(24), BITORDER(msb)" };
+  type integer INT_BIT32_MSB                  with { variant "FIELDLENGTH(32), BITORDER(msb)" };
+
+  type enumerated Type
+  {
+    CONFIRMABLE(0),
+    NON_CONFIRMABLE(1),
+    ACKNOWLEDGEMENT(2),
+    RESET(3)
+  } with { variant "FIELDLENGTH(2), BITORDER(msb)" };
+  
+  type record Code
+  {
+    INT_BIT3_MSB               class,
+    INT_BIT5_MSB               detail
+  } with {
+    variant "FIELDORDER(msb)" 
+    variant (class) "BITORDERINFIELD(msb)"  
+    variant (detail) "BITORDERINFIELD(msb)"  
+  }
+  
+  type record UnknownOption
+  {
+    integer option_code,
+    octetstring option_value
+  }
+
+  type record INT_BIT_4_OR_12_OR_20_MSB {
+    INT_BIT4      int_bit4 optional,
+    INT_BIT12_MSB int_bit12 optional,
+    INT_BIT20_MSB int_bit20 optional
+  } with {
+    variant "FIELDORDER(msb)";
+  }
+  
+  type record BlockOption
+  {
+    INT_BIT_4_OR_12_OR_20_MSB num,
+    boolean m,
+    INT_BIT3_MSB szx
+  } with {
+    variant "FIELDORDER(msb)";
+    variant (num) "BITORDERINFIELD(msb)";
+    variant (m)   "BITORDERINFIELD(msb)";
+    variant (szx) "BITORDERINFIELD(msb)";
+  }
+
+  type union CoAP_Options
+  {
+    OCT0_8                         if_match,
+    UCHAR1_255                     uri_host,
+    OCT1_8                         etag,
+    OCT0                           if_none_match,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB observe,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB uri_port,
+    UCHAR0_255                     location_path,
+    UCHAR0_255                     uri_path,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB content_format,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB max_age,
+    UCHAR0_255                     uri_query,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB accept,
+    UCHAR0_255                     location_query,
+    BlockOption                    block1,
+    BlockOption	                   block2,
+    UCHAR1_1034                    proxy_uri,
+    UCHAR1_255                     proxy_scheme,
+    INT_BIT8_OR_16_OR_24_OR_32_MSB size1,
+    UnknownOption                  unknown_option
+  }
+
+   type union INT_BIT8_OR_16_OR_24_OR_32_MSB {
+    INT_BIT8_MSB   int_bit8,
+    INT_BIT16_MSB  int_bit16,
+    INT_BIT24_MSB  int_bit24,
+    INT_BIT32_MSB  int_bit32
+  } with {
+    variant (int_bit8)   "BITORDERINFIELD(msb)";
+    variant (int_bit16)  "BITORDERINFIELD(msb)";
+    variant (int_bit24)  "BITORDERINFIELD(msb)";
+    variant (int_bit32)  "BITORDERINFIELD(msb)";
+  }
+
+  // This enables fuzzing of the option_delta_ext and option_length_ext fields.
+  // For correct RAW encoding use the int_bit8 field for values from 0..255 and
+  // use the int_bit16 field for values from 256..35335
+  type union INT_BIT8_OR_BIT16_MSB {
+    INT_BIT8_MSB  int_bit8,
+    INT_BIT16_MSB int_bit16
+  } with {
+    variant (int_bit8)  "BITORDERINFIELD(msb)";
+    variant (int_bit16) "BITORDERINFIELD(msb)";
+  }
+
+  type record CoAP_OptionsExt
+  {
+    INT_BIT4_MSB  option_delta,
+    INT_BIT4_MSB  option_length,
+    INT_BIT8_OR_BIT16_MSB option_delta_ext  optional,
+    INT_BIT8_OR_BIT16_MSB option_length_ext optional,
+  CoAP_Options  option_value
+  } with {
+    variant "FIELDORDER(msb)" 
+    variant (option_delta)  "BITORDERINFIELD(msb)" 
+    variant (option_length) "BITORDERINFIELD(msb)"
+  };
+
+
+ type set of CoAP_OptionsExt CoAP_OptionsExtList with {variant "" };
+
+ type record Payload
+{
+ OCT1_MSB              payloadMarker /*('FF'O)*/, // to enable the negative testing of the marker
+ octetstring           payload length(1..infinity) 
+} with {variant "" }
+
+  type record CoAP_ReqResp
+  {
+    // header begin
+    INT_BIT2_MSB          version,
+    Type                  msg_type,
+    INT_BIT4_MSB          tkl,
+    Code                  code,
+    INT_BIT16_MSB         message_id,
+    // header end
+    OCT0_8                token,
+    CoAP_OptionsExtList   options optional,
+    Payload               payload optional
+  } with {
+    variant "FIELDORDER(msb)"
+    variant (version) "BITORDERINFIELD(msb)";
+    variant (msg_type) "BITORDERINFIELD(msb)" ;
+    variant (tkl) "BITORDERINFIELD(msb)" ;
+    variant (message_id) "BITORDERINFIELD(msb)" ;
+    variant (token) "BITORDERINFIELD(lsb)" ;//!!
+  }
+
+  type union CoAP_Message
+  {
+    CoAP_ReqResp          msg,
+    octetstring           raw_message
+  } with {
+    variant ""
+  }
+
+}
+with {
+  encode "RAW"
+}
diff --git a/src/negative_testing/README b/src/negative_testing/README
new file mode 100644
index 0000000..e73d644
--- /dev/null
+++ b/src/negative_testing/README
@@ -0,0 +1,10 @@
+The CoAP protocol module was written initially with an external codec (see http://git.eclipse.org/c/titan/titan.ProtocolModules.CoAP.git/)
+
+The reason for this was that the variable length encoding of some fields and the handling of the option fields cannot be directly handled by RAW alone; some external assistance is needed;
+A new protocol module has been written (based on the RAW codec), which can handle encoding directions. But for the decoding the external codec should be used.
+
+To enable more throughout fuzzing (negative testing) the TTCN-3 types were extended with fields that stores the length of fields of the length of payload, based on the CoAP standard. 
+
+The CoAP standard indicates that the sender should encode without leading zero bytes, but the recipient must handle leading zero bytes. The RAW encoder will produce theese leading zero bytes when the value of an option is zero. For example when the content_format is 0 then zero byte will be sent.
+
+The num field of the block1 and block2 options is a 'union' implemented as a record, because the RAW encoder cannot handle unions correctly in this case. The fields of the record are optional and only one field should be filled with value and the other fields must be set to omit. 
\ No newline at end of file