int decode_PA_PAC_REQUEST(const unsigned char *p, size_t len, PA_PAC_REQUEST *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_boolean(p, len, &(data)->include_pac, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_PA_PAC_REQUEST(data); return e; }
int bacapp_decode_property_state( uint8_t * apdu, BACNET_PROPERTY_STATE * value) { int len = 0; uint32_t len_value_type; int section_length; uint32_t enumValue; section_length = decode_tag_number_and_value(&apdu[len], (uint8_t *) & value->tag, &len_value_type); if (-1 == section_length) { return -1; } len += section_length; switch (value->tag) { case BOOLEAN_VALUE: value->state.booleanValue = decode_boolean(len_value_type); break; case BINARY_VALUE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.binaryValue = (BACNET_BINARY_PV) enumValue; break; case EVENT_TYPE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.eventType = (BACNET_EVENT_TYPE) enumValue; break; case POLARITY: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.polarity = (BACNET_POLARITY) enumValue; break; case PROGRAM_CHANGE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programChange = (BACNET_PROGRAM_REQUEST) enumValue; break; case PROGRAM_STATE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programState = (BACNET_PROGRAM_STATE) enumValue; break; case REASON_FOR_HALT: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.programError = (BACNET_PROGRAM_ERROR) enumValue; break; case RELIABILITY: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.reliability = (BACNET_RELIABILITY) enumValue; break; case STATE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.state = (BACNET_EVENT_STATE) enumValue; break; case SYSTEM_STATUS: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.systemStatus = (BACNET_DEVICE_STATUS) enumValue; break; case UNITS: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.units = (BACNET_ENGINEERING_UNITS) enumValue; break; case UNSIGNED_VALUE: if (-1 == (section_length = decode_unsigned(&apdu[len], len_value_type, &value->state.unsignedValue))) { return -1; } break; case LIFE_SAFETY_MODE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.lifeSafetyMode = (BACNET_LIFE_SAFETY_MODE) enumValue; break; case LIFE_SAFETY_STATE: if (-1 == (section_length = decode_enumerated(&apdu[len], len_value_type, &enumValue))) { return -1; } value->state.lifeSafetyState = (BACNET_LIFE_SAFETY_STATE) enumValue; break; default: return -1; } len += section_length; return len; }
/* decode the service request only */ int arf_ack_decode_service_request( uint8_t * apdu, unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data) { int len = 0; int tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; /* check for value pointers */ if (apdu_len && data) { len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); if (tag_number != BACNET_APPLICATION_TAG_BOOLEAN) return -1; data->endOfFile = decode_boolean(len_value_type); if (decode_is_opening_tag_number(&apdu[len], 0)) { data->access = FILE_STREAM_ACCESS; /* a tag number is not extended so only one octet */ len++; /* fileStartPosition */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) return -1; len += decode_signed(&apdu[len], len_value_type, &data->type.stream.fileStartPosition); /* fileData */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) return -1; len += decode_octet_string(&apdu[len], len_value_type, &data->fileData); if (!decode_is_closing_tag_number(&apdu[len], 0)) return -1; /* a tag number is not extended so only one octet */ len++; } else if (decode_is_opening_tag_number(&apdu[len], 1)) { data->access = FILE_RECORD_ACCESS; /* a tag number is not extended so only one octet */ len++; /* fileStartRecord */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) return -1; len += decode_signed(&apdu[len], len_value_type, &data->type.record.fileStartRecord); /* returnedRecordCount */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) return -1; len += decode_unsigned(&apdu[len], len_value_type, &data->type.record.RecordCount); /* fileData */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += tag_len; if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) return -1; len += decode_octet_string(&apdu[len], len_value_type, &data->fileData); if (!decode_is_closing_tag_number(&apdu[len], 1)) return -1; /* a tag number is not extended so only one octet */ len++; } else return -1; } return len; }
void decode_cell(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, struct cc_type *type, SV *output) { unsigned char *bytes; STRLEN bytes_len; if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) != 0) { sv_setsv(output, &PL_sv_undef); return; } switch (type->type_id) { case CC_TYPE_ASCII: case CC_TYPE_CUSTOM: case CC_TYPE_BLOB: decode_blob(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_BOOLEAN: decode_boolean(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARCHAR: case CC_TYPE_TEXT: decode_utf8(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_INET: decode_inet(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_SET: case CC_TYPE_LIST: decode_list(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UUID: case CC_TYPE_TIMEUUID: decode_uuid(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_FLOAT: decode_float(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DOUBLE: decode_double(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DECIMAL: decode_decimal(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARINT: case CC_TYPE_BIGINT: case CC_TYPE_COUNTER: case CC_TYPE_TIMESTAMP: case CC_TYPE_SMALLINT: case CC_TYPE_TINYINT: case CC_TYPE_INT: decode_varint(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DATE: decode_date(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TIME: decode_time(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_MAP: decode_map(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UDT: decode_udt(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TUPLE: decode_tuple(aTHX_ bytes, bytes_len, type, output); break; default: sv_setsv(output, &PL_sv_undef); warn("Decoder doesn't yet understand type %d, returning undef instead", type->type_id); break; } }