int Lighting_Output_Decode_Lighting_Command( uint8_t * apdu, unsigned apdu_max_len, BACNET_LIGHTING_COMMAND * data) { int len = 0; int apdu_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; float real_value = 0.0; apdu_max_len = apdu_max_len; /* check for value pointers */ if (apdu_len && data) { /* Tag 0: operation */ if (!decode_is_context_tag(&apdu[apdu_len], 0)) return -1; len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_enumerated(&apdu[apdu_len], len_value_type, (uint32_t *) & data->operation); apdu_len += len; /* Tag 1: level - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); apdu_len += len; data->level = (uint8_t) real_value; /* FIXME: are we going to flag errors in decoding values here? */ } /* FIXME: finish me! */ /* Tag 2: */ } return len; }
void DecodeBlock( char cBlockNum, uint8_t * pData) { int iLen; uint32_t ulTemp; int tag_len; uint8_t tag_number; uint32_t len_value_type; BACNET_CHARACTER_STRING bsName; DATABLOCK Response; iLen = 0; if (cBlockNum >= MY_MAX_BLOCK) return; tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) return; iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp); Response.cMyByte1 = (char) ulTemp; tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) return; iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp); Response.cMyByte2 = (char) ulTemp; tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_REAL) return; iLen += decode_real(&pData[iLen], &Response.fMyReal); tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) return; iLen += decode_character_string(&pData[iLen], len_value_type, &bsName); strncpy(Response.sMyString, characterstring_value(&bsName), MY_MAX_STR); Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */ printf("Private Transfer Read Block Response\n"); printf("Data Block: %d\n", (int) cBlockNum); printf(" First Byte : %d\n", (int) Response.cMyByte1); printf(" Second Byte : %d\n", (int) Response.cMyByte2); printf(" Real : %f\n", Response.fMyReal); printf(" String : %s\n\n", Response.sMyString); }
static void ProcessPT( BACNET_PRIVATE_TRANSFER_DATA * data) { int iLen; /* Index to current location in data */ char cBlockNumber; uint32_t ulTemp; int tag_len; uint8_t tag_number; uint32_t len_value_type; BACNET_CHARACTER_STRING bsTemp; iLen = 0; /* Decode the block number */ tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* Bail out early if wrong type */ /* and signal unexpected error */ data->serviceParametersLen = 0; return; } iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp); cBlockNumber = (char) ulTemp; if (cBlockNumber < MY_MAX_BLOCK) { if (data->serviceNumber == MY_SVC_READ) { /* Read Response is an unsigned int with 0 for success or a non 0 error code For a successful read the 0 success code is followed by the block number and then the block contents which consist of 2 unsigned ints (in 0 to 255 range as they are really chars) a single precision real and a string which will be up to 32 chars + a nul */ iLen = 0; /* Signal success */ iLen += encode_application_unsigned(&IOBufferPT[iLen], MY_ERR_OK); /* Followed by the block number */ iLen += encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber); /* And Then the block contents */ iLen += encode_application_unsigned(&IOBufferPT[iLen], MyData[(int8_t) cBlockNumber].cMyByte1); iLen += encode_application_unsigned(&IOBufferPT[iLen], MyData[(int8_t) cBlockNumber].cMyByte2); iLen += encode_application_real(&IOBufferPT[iLen], MyData[(int8_t) cBlockNumber].fMyReal); characterstring_init_ansi(&bsTemp, (char *) MyData[(int8_t) cBlockNumber].sMyString); iLen += encode_application_character_string(&IOBufferPT[iLen], &bsTemp); } else { /* Write operation */ /* Write block consists of the block number followed by the block contents as described above for the read operation. The returned result is an unsigned response which is 0 for success and a non 0 error code otherwise. */ tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { data->serviceParametersLen = 0; return; } iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp); MyData[(int8_t) cBlockNumber].cMyByte1 = (char) ulTemp; tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { data->serviceParametersLen = 0; return; } iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp); MyData[(int8_t) cBlockNumber].cMyByte2 = (char) ulTemp; tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_REAL) { data->serviceParametersLen = 0; return; } iLen += decode_real(&data->serviceParameters[iLen], &MyData[(int8_t) cBlockNumber].fMyReal); tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type); iLen += tag_len; if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) { data->serviceParametersLen = 0; return; } decode_character_string(&data->serviceParameters[iLen], len_value_type, &bsTemp); /* Only copy as much as we can accept */ strncpy((char *) MyData[(int8_t) cBlockNumber].sMyString, characterstring_value(&bsTemp), MY_MAX_STR); /* Make sure it is nul terminated */ MyData[(int8_t) cBlockNumber].sMyString[MY_MAX_STR] = '\0'; /* Signal success */ iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_OK); } } else { /* Signal bad index */ iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_BAD_INDEX); } data->serviceParametersLen = iLen; data->serviceParameters = IOBufferPT; }
/** * Decodes from bytes into the lighting-command structure * * @param apdu - buffer to hold the bytes * @param apdu_max_len - number of bytes in the buffer to decode * @param value - lighting command value to place the decoded values * * @return number of bytes encoded */ int lighting_command_decode( uint8_t * apdu, unsigned apdu_max_len, BACNET_LIGHTING_COMMAND * data) { int len = 0; int apdu_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; uint32_t unsigned_value = 0; float real_value = 0.0; unused_var(apdu_max_len); /* check for value pointers */ if (apdu_max_len && data) { /* Tag 0: operation */ if (!decode_is_context_tag(&apdu[apdu_len], 0)) return BACNET_STATUS_ERROR; len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_enumerated(&apdu[apdu_len], len_value_type, &unsigned_value); if (len > 0) { data->operation = unsigned_value; } apdu_len += len; /* Tag 1: target-level - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 1)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->target_level = real_value; apdu_len += len; data->use_target_level = true; } else { data->use_target_level = false; } /* Tag 2: ramp-rate - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 2)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->ramp_rate = real_value; data->use_ramp_rate = true; } else { data->use_ramp_rate = false; } /* Tag 3: step-increment - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 3)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_real(&apdu[apdu_len], &real_value); data->step_increment = real_value; data->use_step_increment = true; } else { data->use_step_increment = false; } /* Tag 4: fade-time - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 4)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_unsigned(&apdu[apdu_len], len_value_type, &unsigned_value); data->fade_time = unsigned_value; data->use_fade_time = true; } else { data->use_fade_time = false; } /* Tag 5: priority - OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 4)) { len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; len = decode_unsigned(&apdu[apdu_len], len_value_type, &unsigned_value); data->priority = unsigned_value; data->use_priority = true; } else { data->use_priority = false; } } return len; }