Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLenard Nagy2018-12-03 13:24:43 +0000
committerLenard Nagy2018-12-03 13:24:43 +0000
commitcf054d1056d48e3f71e1474aa638beb66ce9f335 (patch)
treece82041c612e1ca7d331acc5e7b71d5982b15cc2
parente153e98def27ecc1892bbfe82c98c1ebd8c0dccb (diff)
downloadtitan.ProtocolModules.CoAP-cf054d1056d48e3f71e1474aa638beb66ce9f335.tar.gz
titan.ProtocolModules.CoAP-cf054d1056d48e3f71e1474aa638beb66ce9f335.tar.xz
titan.ProtocolModules.CoAP-cf054d1056d48e3f71e1474aa638beb66ce9f335.zip
Added Java implementation of CoAP encode and decode
Signed-off-by: Lenard Nagy <lenard.nagy@ericsson.com>
-rw-r--r--META-INF/MANIFEST.MF11
-rw-r--r--README.md4
-rw-r--r--user_provided/org/eclipse/titan/user_provided/CoAP__Types_externalfunctions.java571
3 files changed, 586 insertions, 0 deletions
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ba6c0da
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: titan.ProtocolModules.CoAP
+Bundle-SymbolicName: titan.ProtocolModules.CoAP; singleton:=true
+Bundle-Version: 1.0.0
+Require-Bundle: org.eclipse.titan.runtime;bundle-version="1.0.0",
+ org.antlr.runtime;bundle-version="4.3.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.titan.generated,
+ org.eclipse.titan.user_provided
diff --git a/README.md b/README.md
index eaf0f9e..f6684ba 100644
--- a/README.md
+++ b/README.md
@@ -7,3 +7,7 @@ https://projects.eclipse.org/projects/tools.titan
The source code of the TTCN-3 compiler and executor:
https://github.com/eclipse/titan.core
+
+## Contents
+/src/* : TTCN3 and C++ implementation
+/user_provided/* : Java implementation
diff --git a/user_provided/org/eclipse/titan/user_provided/CoAP__Types_externalfunctions.java b/user_provided/org/eclipse/titan/user_provided/CoAP__Types_externalfunctions.java
new file mode 100644
index 0000000..1e26668
--- /dev/null
+++ b/user_provided/org/eclipse/titan/user_provided/CoAP__Types_externalfunctions.java
@@ -0,0 +1,571 @@
+package org.eclipse.titan.user_provided;
+
+//CoAP__Types.CoAP__Message
+import org.eclipse.titan.generated.CoAP__Types.BlockOption;
+import org.eclipse.titan.generated.CoAP__Types.CoAP__Message;
+import org.eclipse.titan.generated.CoAP__Types.CoAP__Options;
+import org.eclipse.titan.runtime.core.Base_Template.template_sel;
+import org.eclipse.titan.runtime.core.TTCN_Buffer;
+import org.eclipse.titan.runtime.core.TTCN_Logger;
+import org.eclipse.titan.runtime.core.TTCN_Logger.Severity;
+import org.eclipse.titan.runtime.core.TitanCharString.CharCoding;
+import org.eclipse.titan.runtime.core.TitanOctetString;
+import org.eclipse.titan.runtime.core.TtcnError;
+
+
+public class CoAP__Types_externalfunctions {
+
+ public static int f__CoAP__enc(CoAP__Message msg, TitanOctetString v__encoded) {
+ if(TTCN_Logger.log_this_event(Severity.DEBUG_ENCDEC)){
+ TTCN_Logger.begin_event(Severity.DEBUG_ENCDEC);
+ TTCN_Logger.log_event("Encoding CoAP message: ");
+ msg.log();
+ TTCN_Logger.end_event();
+ }
+ TTCN_Buffer stream = new TTCN_Buffer();
+ int chr = 0;
+ switch(msg.get_selection()){
+ case ALT_raw__message:
+ stream.put_os(msg.get_field_raw__message());
+ stream.get_string(v__encoded);
+ return 0;
+ case ALT_msg:
+ default:
+ break;
+ }
+ //HEADER
+ //version
+ if(msg.get_field_msg().get_field_header().get_field_version().isGreaterThanOrEqual(0) && msg.get_field_msg().get_field_header().get_field_version().isLessThanOrEqual(3)){
+ chr = msg.get_field_msg().get_field_header().get_field_version().getInt() << 6;
+ }else{
+ return 1;
+ }
+ //message type
+ chr += msg.get_field_msg().get_field_header().get_field_msg__type().asInt() << 4;
+ //token length
+ if(msg.get_field_msg().get_field_token().lengthof().isGreaterThanOrEqual(0) && msg.get_field_msg().get_field_token().lengthof().isLessThanOrEqual(8)){
+ chr += msg.get_field_msg().get_field_token().lengthof().getInt();
+ }else{
+ return 1;
+ }
+
+ stream.put_c(Character.toChars(chr)[0]);
+ //code
+ if(msg.get_field_msg().get_field_header().get_field_code().get_field_class_().isGreaterThanOrEqual(0) && msg.get_field_msg().get_field_header().get_field_code().get_field_class_().isLessThanOrEqual(7)){
+ chr = msg.get_field_msg().get_field_header().get_field_code().get_field_class_().getInt() << 5;
+ }else{
+ return 1;
+ }
+ if(msg.get_field_msg().get_field_header().get_field_code().get_field_detail().isGreaterThanOrEqual(0) && msg.get_field_msg().get_field_header().get_field_code().get_field_detail().isLessThanOrEqual(31)){
+ chr += msg.get_field_msg().get_field_header().get_field_code().get_field_detail().getInt();
+ }else{
+ return 1;
+ }
+ stream.put_c(Character.toChars(chr)[0]);
+ //message ID
+ if(msg.get_field_msg().get_field_header().get_field_message__id().isGreaterThanOrEqual(0) && msg.get_field_msg().get_field_header().get_field_message__id().isLessThanOrEqual(65535)){
+ encodeInteger(stream, msg.get_field_msg().get_field_header().get_field_message__id().getInt(), 2);
+ }else{
+ return 1;
+ }
+ //TOKEN
+ stream.put_os(msg.get_field_msg().get_field_token());
+ //OPTIONS
+ if(msg.get_field_msg().get_field_options().ispresent() && msg.get_field_msg().get_field_options().get().size_of().isGreaterThan(0)){
+ int[] optionOrder = new int[msg.get_field_msg().get_field_options().get().size_of().getInt()];
+ int temp;
+ for(int i = 0; i < msg.get_field_msg().get_field_options().get().size_of().getInt(); i++){
+ optionOrder[i] = i;
+ }
+ //determine the order of options
+ for(int j = 0; j < msg.get_field_msg().get_field_options().get().size_of().getInt() - 1; j++){
+ int minOptionCode = getOptionCode(msg.get_field_msg().get_field_options().get().get_at(optionOrder[j]));
+ int minOptionIndex = j;
+ for(int i = j+1; i < msg.get_field_msg().get_field_options().get().size_of().getInt(); i++){
+ if(getOptionCode(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i])) < minOptionCode){
+ minOptionCode = getOptionCode(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]));
+ minOptionIndex = i;
+ }
+ }
+ temp = optionOrder[minOptionIndex];
+ optionOrder[minOptionIndex] = optionOrder[j];
+ optionOrder[j] = temp;
+ }
+ //encode options
+ int previousOptionCode = 0;
+ for(int i = 0; i < msg.get_field_msg().get_field_options().get().size_of().getInt(); i++){
+ int delta = getOptionCode(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i])) - previousOptionCode;
+ int length = getOptionLength(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]));
+ previousOptionCode += delta;
+ //first byte
+ if(delta >= 0 && delta <= 12){
+ chr = delta << 4;
+ }else if(delta >= 13 && delta <= 268){
+ chr = 13 << 4;
+ }else if(delta >= 269 && delta <= 65535){
+ chr = 14 << 4;
+ }else{
+ return 1;
+ }
+ if(length >= 0 && length <= 12){
+ chr += length;
+ }else if(length >= 13 && length <= 268){
+ chr += 13;
+ }else if(length >= 269 && length <= 65535){
+ chr += 14;
+ }else{
+ return 1;
+ }
+ stream.put_c(Character.toChars(chr)[0]);
+ //optional delta
+ if(delta >= 13 && delta <= 268){
+ chr = delta - 13;
+ stream.put_c(Character.toChars(chr)[0]);
+ }else if(delta >= 269 && delta <= 65535){
+ chr = (delta - 269) >> 8;
+ stream.put_c(Character.toChars(chr)[0]);
+ chr = (delta - 269) & 255;
+ stream.put_c(Character.toChars(chr)[0]);
+ }
+ //optional length
+ if(length >= 13 && length <= 268){
+ chr = length - 13;
+ stream.put_c(Character.toChars(chr)[0]);
+ }else if(length >= 269 && length <= 65535){
+ chr = (length - 269) >> 8;
+ stream.put_c(Character.toChars(chr)[0]);
+ chr = (length - 269) & 255;
+ stream.put_c(Character.toChars(chr)[0]);
+ }
+ //option value
+ if(length > 0){
+ switch(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_selection()){
+ case ALT_if__match:
+ stream.put_os(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_if__match());
+ break;
+ case ALT_uri__host:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_uri__host().encode_utf8(stream, false);
+ break;
+ case ALT_etag:
+ stream.put_os(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_etag());
+ break;
+ case ALT_if__none__match:
+ stream.put_os(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_if__none__match());
+ break;
+ case ALT_observe:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_observe().getInt(), length);
+ break;
+ case ALT_uri__port:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_uri__port().getInt(), length);
+ break;
+ case ALT_location__path:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_location__path().encode_utf8(stream, false);
+ break;
+ case ALT_uri__path:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_uri__path().encode_utf8(stream, false);
+ break;
+ case ALT_content__format:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_content__format().getInt(), length);
+ break;
+ case ALT_max__age:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_max__age().getInt(), length);
+ break;
+ case ALT_uri__query:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_uri__query().encode_utf8(stream, false);
+ break;
+ case ALT_accept:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_accept().getInt(), length);
+ break;
+ case ALT_location__query:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_location__query().encode_utf8(stream, false);
+ break;
+ case ALT_block1:
+ encodeBlock(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_block1(), length);
+ break;
+ case ALT_block2:
+ encodeBlock(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_block2(), length);
+ break;
+ case ALT_proxy__uri:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_proxy__uri().encode_utf8(stream, false);
+ break;
+ case ALT_proxy__scheme:
+ msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_proxy__scheme().encode_utf8(stream, false);
+ break;
+ case ALT_size1:
+ encodeInteger(stream, msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_size1().getInt(), length);
+ break;
+ case ALT_unknown__option:
+ stream.put_os(msg.get_field_msg().get_field_options().get().get_at(optionOrder[i]).get_field_unknown__option().get_field_option__value());
+ break;
+ case UNBOUND_VALUE:
+ default:
+ return 8;
+ }
+ }
+ }
+ }
+
+ //PAYLOAD
+ if(msg.get_field_msg().get_field_payload().ispresent()){
+ stream.put_c((char)255); //payload marker
+ stream.put_os(msg.get_field_msg().get_field_payload().get());
+ }
+
+ TTCN_Logger.begin_event(Severity.DEBUG_ENCDEC);
+ TTCN_Logger.log_event("Encoded CoAP message: ");
+ stream.log();
+ TTCN_Logger.end_event();
+
+ v__encoded.operator_assign(new TitanOctetString(stream.get_data()));
+
+ return 0;
+ }
+ public static int f__CoAP__dec(TitanOctetString v__enc, CoAP__Message v__dec) {
+ if(TTCN_Logger.log_this_event(Severity.DEBUG_ENCDEC)){
+ TTCN_Logger.begin_event(Severity.DEBUG_ENCDEC);
+ TTCN_Logger.log_event("Decoding CoAP message: ");
+ v__enc.log();
+ TTCN_Logger.end_event();
+ }
+ if(v__enc.lengthof().isGreaterThanOrEqual(4)){
+ int chr;
+ int position = 0;
+ int token_length = 0;
+ int actual_option_code = 0;
+ int count_of_options = 0;
+ boolean payload_marker = false;
+ //version, message type and token length
+ chr = v__enc.getValue()[0];
+ v__dec.get_field_msg().get_field_header().get_field_version().operator_assign(chr >> 6);
+ v__dec.get_field_msg().get_field_header().get_field_msg__type().operator_assign((chr >> 4) & 3);
+ token_length = chr & 15;
+ //code
+ chr = v__enc.getValue()[1];
+ v__dec.get_field_msg().get_field_header().get_field_code().get_field_class_().operator_assign((chr >> 5) & 7);
+ v__dec.get_field_msg().get_field_header().get_field_code().get_field_detail().operator_assign(chr & 31);
+ //message ID
+ v__dec.get_field_msg().get_field_header().get_field_message__id().operator_assign(v__enc.getValue()[2] * 256 + v__enc.getValue()[3]);
+ if(v__enc.lengthof().isGreaterThan(4) && v__dec.get_field_msg().get_field_header().get_field_code().get_field_class_().operator_equals(0) && v__dec.get_field_msg().get_field_header().get_field_code().get_field_detail().operator_equals(0)) {
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }
+ position = 4;
+ //token
+ if(token_length > 0){
+ if(v__enc.lengthof().isGreaterThanOrEqual(position + token_length)) {
+ v__dec.get_field_msg().get_field_token().operator_assign(new TitanOctetString(v__enc.getValue()[position]));
+ position += token_length;
+ }else{
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }
+ }else{
+ v__dec.get_field_msg().get_field_token().operator_assign(new TitanOctetString(""));
+ }
+ //options
+ v__dec.get_field_msg().get_field_options().operator_assign(template_sel.OMIT_VALUE);
+ if(v__enc.lengthof().isGreaterThan(4)) {
+ while(!payload_marker && v__enc.lengthof().isGreaterThan(position)) {
+ int delta = v__enc.get_nibble(position) >> 4;
+ int length = v__enc.get_nibble(position) & 15;
+ if(delta == 15 && length != 15){
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }
+ position++;
+ if(delta == 15 && length == 15){
+ payload_marker = true;
+ }else{
+ //optional delta
+ if(delta == 13){
+ delta = v__enc.get_nibble(position) + 13;
+ position++;
+ }else if(delta == 14){
+ delta = (v__enc.get_nibble(position) << 8) + v__enc.get_nibble(position+1) + 269;
+ position += 2;
+ }
+ //optional length
+ if(length == 13){
+ length = v__enc.get_nibble(position) + 13;
+ position++;
+ }else if(length == 14){
+ length = (v__enc.get_nibble(position) << 8) + v__enc.get_nibble(position + 1) + 269;
+ position += 2;
+ }else if(length == 15){
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1; //void function cannot return
+ }
+ //value
+ actual_option_code += delta;
+ switch(actual_option_code){
+ case 1:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_if__match().operator_assign(new TitanOctetString(v__enc.get_nibble(position)));
+ break;
+ case 3:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_uri__host().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 4:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_etag().operator_assign(new TitanOctetString(v__enc.get_nibble(position)));
+ break;
+ case 5:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_if__none__match().operator_assign(new TitanOctetString(""));
+ break;
+ case 6:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_observe().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ case 7:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_uri__port().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ case 8:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_location__path().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 11:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_uri__path().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 12:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_content__format().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ case 14:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_max__age().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ case 15:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_uri__query().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 17:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_accept().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ case 20:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_location__query().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 23: // Block2 RFC 7959
+ decodeBlock(v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_block2(), v__enc, position, length);
+ break;
+ case 27: // Block1 RFC 7959
+ decodeBlock(v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_block1(), v__enc, position, length);
+ break;
+ case 35:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_proxy__uri().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 39:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_proxy__scheme().decode_utf8(new char[] {v__enc.get_nibble(position)}, CharCoding.UTF_8, false);
+ break;
+ case 60:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_size1().operator_assign(decodeInteger(v__enc, position, length));
+ break;
+ default:
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_unknown__option().get_field_option__code().operator_assign(actual_option_code);
+ v__dec.get_field_msg().get_field_options().get().get_at(count_of_options).get_field_unknown__option().get_field_option__value().operator_assign(new TitanOctetString(v__enc.get_nibble(position)));
+ break;
+ }
+ position += length;
+ count_of_options++;
+ }
+ }
+ }
+ //payload
+ if(v__enc.lengthof().isGreaterThan(position)) {
+ v__dec.get_field_msg().get_field_payload().operator_assign(new TitanOctetString(v__enc.get_nibble(position)));
+ if(v__dec.get_field_msg().get_field_payload().get().lengthof().operator_equals(0)) {
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }
+ } else {
+ if(payload_marker){
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }else{
+ v__dec.get_field_msg().get_field_payload().operator_assign(template_sel.OMIT_VALUE);
+ }
+ }
+ } else{
+ v__dec.get_field_raw__message().operator_assign(v__enc);
+ return 1;
+ }
+ if(TTCN_Logger.log_this_event(Severity.DEBUG_ENCDEC)){
+ TTCN_Logger.begin_event(Severity.DEBUG_ENCDEC);
+ TTCN_Logger.log_event("Decoded CoAP message: ");
+ v__enc.log();
+ TTCN_Logger.end_event();
+ }
+ return 0;
+ }
+
+ private static int decodeInteger(TitanOctetString str, int position, int length) {
+ int value = 0;
+ for(int i = 0; i < length; i++) {
+ value += (str.get_nibble(position + i) << (8 * (length-i-1)));
+ }
+
+ return value;
+ }
+
+ private static void decodeBlock(BlockOption block, TitanOctetString str, int position, int length) {
+ int num = 0;
+ for(int i = 0; i < length-1; i++) {
+ num += (str.get_nibble(position + i) << (8 * (length-i-1) - 4));
+ }
+ num += (str.get_nibble(position + length-1) >> 4) & 0x0f;
+ int szx = 0;
+ szx = str.get_nibble(position + length - 1) & 0x07;
+ int m = 0;
+ m = str.get_nibble(position+length - 1) & 0x08;
+ block.get_field_num().operator_assign(num);
+ block.get_field_szx().operator_assign(szx);
+ block.get_field_m().operator_assign(intToBoolean(m));
+ }
+ private static boolean intToBoolean(int value) {
+ return value > 0 ? true : false;
+ }
+
+ private static void encodeInteger(TTCN_Buffer stream, final int option, final int length){
+ int chr;
+ for(int i = length-1; i > 0; i--){
+ chr = (option >> (8 * i)) & 255;
+ stream.put_c(Character.toChars(chr)[0]);
+ }
+ chr = option & 255;
+ stream.put_c(Character.toChars(chr)[0]);
+ }
+
+ private static int getOptionCode(CoAP__Options option){
+ switch(option.get_selection()){
+ case ALT_if__match:
+ return 1;
+ case ALT_uri__host:
+ return 3;
+ case ALT_etag:
+ return 4;
+ case ALT_if__none__match:
+ return 5;
+ case ALT_observe:
+ return 6;
+ case ALT_uri__port:
+ return 7;
+ case ALT_location__path:
+ return 8;
+ case ALT_uri__path:
+ return 11;
+ case ALT_content__format:
+ return 12;
+ case ALT_max__age:
+ return 14;
+ case ALT_uri__query:
+ return 15;
+ case ALT_accept:
+ return 17;
+ case ALT_location__query:
+ return 20;
+ case ALT_block1: // RFC 7959
+ return 27;
+ case ALT_block2: // RFC 7959
+ return 23;
+ case ALT_proxy__uri:
+ return 35;
+ case ALT_proxy__scheme:
+ return 39;
+ case ALT_size1:
+ return 60;
+ case ALT_unknown__option:
+ return option.get_field_unknown__option().get_field_option__code().getInt();
+ case UNBOUND_VALUE:
+ default:
+ throw new TtcnError("CoAP: Error at getOptionCode!");
+ }
+ }
+ private static int getOptionLength(CoAP__Options option){
+ switch(option.get_selection()){
+ case ALT_if__match:
+ return option.get_field_if__match().lengthof().getInt();
+ case ALT_uri__host:
+ return option.get_field_uri__host().lengthof().getInt();
+ case ALT_etag:
+ return option.get_field_etag().lengthof().getInt();
+ case ALT_if__none__match:
+ return option.get_field_if__none__match().lengthof().getInt();
+ case ALT_observe:
+ return getIntegerLength(option.get_field_observe().getLong(), 3);
+ case ALT_uri__port:
+ return getIntegerLength(option.get_field_uri__port().getLong(), 2);
+ case ALT_location__path:
+ return option.get_field_location__path().lengthof().getInt();
+ case ALT_uri__path:
+ return option.get_field_uri__path().lengthof().getInt();
+ case ALT_content__format:
+ return getIntegerLength(option.get_field_content__format().getLong(), 2);
+ case ALT_max__age:
+ return getIntegerLength(option.get_field_max__age().getLong(), 4);
+ case ALT_uri__query:
+ return option.get_field_uri__query().lengthof().getInt();
+ case ALT_accept:
+ return getIntegerLength(option.get_field_accept().getLong(), 2);
+ case ALT_location__query:
+ return option.get_field_location__query().lengthof().getInt();
+ case ALT_block1:
+ return getBlockLengthForNum(option.get_field_block1().get_field_num().getLong());
+ case ALT_block2:
+ return getBlockLengthForNum(option.get_field_block2().get_field_num().getLong());
+ case ALT_proxy__uri:
+ return option.get_field_proxy__uri().lengthof().getInt();
+ case ALT_proxy__scheme:
+ return option.get_field_proxy__scheme().lengthof().getInt();
+ case ALT_size1:
+ return getIntegerLength(option.get_field_size1().getLong(), 4);
+ case ALT_unknown__option:
+ return option.get_field_unknown__option().get_field_option__value().lengthof().getInt();
+ case UNBOUND_VALUE:
+ default:
+ throw new TtcnError("CoAP: Error at getOptionLength!");
+ }
+ }
+ private static int getIntegerLength(final long value, int mode){
+ if(value == 0){
+ return 0;
+ }else if(value / 269.0 == 0){
+ return 1;
+ }else if(value / 65805.0 == 0){
+ return 2;
+ }else if(mode == 4 && value / 16777485.0 == 0){
+ return 3;
+ }else if(mode == 4 && value / 4294967296L == 0){
+ return 4;
+ }else{
+ throw new TtcnError("CoAP: Error at getIntegerLength!");
+ }
+ }
+
+ // RFC 7959
+ private static int getBlockLengthForNum(final long num) {
+ if (num < 0 || num > 1048575)
+ throw new TtcnError("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
+ private static void encodeBlock(TTCN_Buffer stream, final BlockOption option, final int length) {
+ int chr;
+ int num_val = option.get_field_num().getInt();
+ int szx;
+ szx = option.get_field_szx().getInt() & 0x07; // szx_val & 00000111b
+ char m;
+ if (option.get_field_m().getValue())
+ m = 0x08; // 00001000b
+ else
+ m = 0x00; // 00000000b
+ int num;
+ for(int i = length-1; i > 0; i--){
+ num = (num_val >> (8 * i - 4)) & 0xff;
+ stream.put_c(Character.toChars(num)[0]);
+ }
+ num = (num_val << 4) & 0xf0; // num_val & 11110000b
+ chr = num | m | szx;
+ stream.put_c(Character.toChars(chr)[0]);
+ }
+} \ No newline at end of file

Back to the top