| 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]); |
| } |
| } |