diff --git a/bacnet-stack/iam.c b/bacnet-stack/iam.c index b26a74ba..0ea832b5 100755 --- a/bacnet-stack/iam.c +++ b/bacnet-stack/iam.c @@ -80,50 +80,66 @@ int iam_decode_apdu( uint16_t *pVendor_id) { int len = 0; + int apdu_len = 0; // total length of the apdu, return value int object_type = 0; // should be a Device Object uint32_t object_instance = 0; uint8_t tag_number = 0; uint32_t len_value = 0; unsigned int decoded_value = 0; + // valid data? + if (!apdu) + return -1; // optional checking - most likely was already done prior to this call if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) return -1; if (apdu[1] != SERVICE_UNCONFIRMED_I_AM) return -1; // OBJECT ID - object id - len = 2; - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + apdu_len = 2; + len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); + apdu_len += len; if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) return -1; - len += decode_object_id(&apdu[len], &object_type, &object_instance); + len = decode_object_id(&apdu[apdu_len], &object_type, &object_instance); + apdu_len += len; if (object_type != OBJECT_DEVICE) return -1; - *pDevice_id = object_instance; + if (pDevice_id) + *pDevice_id = object_instance; // MAX APDU - unsigned - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); + apdu_len += len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) return -1; - len += decode_unsigned(&apdu[len], len_value, &decoded_value); - *pMax_apdu = decoded_value; + len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + apdu_len += len; + if (pMax_apdu) + *pMax_apdu = decoded_value; // Segmentation - enumerated - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); + apdu_len += len; if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) return -1; - len += decode_enumerated(&apdu[len],len_value, &decoded_value); + len = decode_enumerated(&apdu[apdu_len],len_value, &decoded_value); + apdu_len += len; if (decoded_value >= MAX_BACNET_SEGMENTATION) return -1; - *pSegmentation = decoded_value; + if (pSegmentation) + *pSegmentation = decoded_value; // Vendor ID - unsigned16 - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); + apdu_len += len; if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) return -1; - len += decode_unsigned(&apdu[len], len_value, &decoded_value); + len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + apdu_len += len; if (decoded_value > 0xFFFF) return -1; - *pVendor_id = decoded_value; + if (pVendor_id) + *pVendor_id = decoded_value; - return len; + return apdu_len; } #ifdef TEST @@ -158,15 +174,12 @@ void testIAm(Test * pTest) &test_max_apdu, &test_segmentation, &test_vendor_id); + ct_test(pTest, len != -1); ct_test(pTest, test_device_id == device_id); ct_test(pTest, test_vendor_id == vendor_id); ct_test(pTest, test_max_apdu == max_apdu); ct_test(pTest, test_segmentation == segmentation); - - // check the error conditions - - } #ifdef TEST_IAM @@ -187,5 +200,5 @@ int main(void) return 0; } -#endif /* TEST_DECODE */ +#endif /* TEST_IAM */ #endif /* TEST */