diff --git a/demo/handler/h_cov.c b/demo/handler/h_cov.c index fd4be2b..fc117b8 100644 --- a/demo/handler/h_cov.c +++ b/demo/handler/h_cov.c @@ -495,14 +495,14 @@ static bool cov_send_request( cov_subscription->invokeID = invoke_id; len = ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id, &cov_data); + sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, &cov_data); } else { goto COV_FAILED; } } else { len = ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - &cov_data); + sizeof(Handler_Transmit_Buffer) - pdu_len, &cov_data); } pdu_len += len; if (cov_subscription->flag.issueConfirmedNotifications) { diff --git a/demo/handler/s_cov.c b/demo/handler/s_cov.c index 49f1e9c..ceaae4b 100644 --- a/demo/handler/s_cov.c +++ b/demo/handler/s_cov.c @@ -44,8 +44,19 @@ /** @file s_cov.c Send a Change of Value (COV) update or a Subscribe COV request. */ +/** Encodes an Unconfirmed COV Notification. + * @ingroup DSCOV + * + * @param buffer [in,out] The buffer to build the message in for sending. + * @param buffer_len [in] Number of bytes in the buffer + * @param dest [in] Destination address + * @param npdu_data [in] Network Layer information + * @param cov_data [in] The COV update information to be encoded. + * @return Size of the message sent (bytes), or a negative value on error. + */ int ucov_notify_encode_pdu( uint8_t * buffer, + unsigned buffer_len, BACNET_ADDRESS * dest, BACNET_NPDU_DATA * npdu_data, BACNET_COV_DATA * cov_data) @@ -62,8 +73,13 @@ int ucov_notify_encode_pdu( pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); /* encode the APDU portion of the packet */ - len = ucov_notify_encode_apdu(&buffer[pdu_len], cov_data); - pdu_len += len; + len = ucov_notify_encode_apdu(&buffer[pdu_len], + buffer_len - pdu_len, cov_data); + if (len) { + pdu_len += len; + } else { + pdu_len = 0; + } return pdu_len; } @@ -72,11 +88,13 @@ int ucov_notify_encode_pdu( * @ingroup DSCOV * * @param buffer [in,out] The buffer to build the message in for sending. + * @param buffer_len [in] Number of bytes in the buffer * @param cov_data [in] The COV update information to be encoded. * @return Size of the message sent (bytes), or a negative value on error. */ int Send_UCOV_Notify( uint8_t * buffer, + unsigned buffer_len, BACNET_COV_DATA * cov_data) { int pdu_len = 0; @@ -84,7 +102,8 @@ int Send_UCOV_Notify( int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - pdu_len = ucov_notify_encode_pdu(buffer, &dest, &npdu_data, cov_data); + pdu_len = ucov_notify_encode_pdu(buffer, buffer_len, &dest, &npdu_data, + cov_data); bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); return bytes_sent; @@ -130,7 +149,7 @@ uint8_t Send_COV_Subscribe( /* encode the APDU portion of the packet */ len = cov_subscribe_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - invoke_id, cov_data); + sizeof(Handler_Transmit_Buffer)-pdu_len, invoke_id, cov_data); pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between diff --git a/demo/ucov/main.c b/demo/ucov/main.c index e3469a5..30a172d 100644 --- a/demo/ucov/main.c +++ b/demo/ucov/main.c @@ -193,7 +193,8 @@ int main( Init_Service_Handlers(); dlenv_init(); atexit(datalink_cleanup); - Send_UCOV_Notify(&Handler_Transmit_Buffer[0], &cov_data); + Send_UCOV_Notify(&Handler_Transmit_Buffer[0], + sizeof(Handler_Transmit_Buffer), &cov_data); return 0; } diff --git a/include/cov.h b/include/cov.h index f5ea3dd..6a9b6fb 100644 --- a/include/cov.h +++ b/include/cov.h @@ -58,6 +58,7 @@ extern "C" { int ucov_notify_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, BACNET_COV_DATA * data); int ucov_notify_decode_apdu( @@ -66,11 +67,13 @@ extern "C" { BACNET_COV_DATA * data); int ucov_notify_send( - uint8_t * buffer, + uint8_t * apdu, + unsigned max_apdu_len, BACNET_COV_DATA * data); int ccov_notify_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_COV_DATA * data); @@ -93,6 +96,7 @@ extern "C" { int cov_subscribe_property_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data); @@ -103,6 +107,7 @@ extern "C" { int cov_subscribe_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data); diff --git a/src/cov.c b/src/cov.c index 4f68a3b..a3a8a65 100644 --- a/src/cov.c +++ b/src/cov.c @@ -36,6 +36,8 @@ #include "bacdcode.h" #include "bacdef.h" #include "bacapp.h" +#include "memcopy.h" +/* me! */ #include "cov.h" /** @file cov.c Encode/Decode Change of Value (COV) services */ @@ -48,6 +50,7 @@ Unconfirmed COV Notification */ static int notify_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, BACNET_COV_DATA * data) { int len = 0; /* length of each encoding */ @@ -131,39 +134,53 @@ static int notify_encode_apdu( int ccov_notify_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_COV_DATA * data) { int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ + int apdu_len = BACNET_STATUS_ERROR; /* return value */ - if (apdu) { + if (apdu && data && memcopylen(0, max_apdu_len, 4)) { apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); apdu[2] = invoke_id; apdu[3] = SERVICE_CONFIRMED_COV_NOTIFICATION; apdu_len = 4; - len = notify_encode_apdu(&apdu[apdu_len], data); + len = notify_encode_apdu(&apdu[apdu_len], + max_apdu_len-apdu_len, data); + if (len < 0) { + /* return the error */ + apdu_len = len; + } else { apdu_len += len; } + } return apdu_len; } int ucov_notify_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, BACNET_COV_DATA * data) { int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ + int apdu_len = BACNET_STATUS_ERROR; /* return value */ - if (apdu && data) { + if (apdu && data && memcopylen(0, max_apdu_len, 2)) { apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; apdu[1] = SERVICE_UNCONFIRMED_COV_NOTIFICATION; /* service choice */ apdu_len = 2; - len = notify_encode_apdu(&apdu[apdu_len], data); + len = notify_encode_apdu(&apdu[apdu_len], + max_apdu_len-apdu_len, data); + if (len < 0) { + /* return the error */ + apdu_len = len; + } else { apdu_len += len; } + } return apdu_len; } @@ -341,6 +358,7 @@ SubscribeCOV-Request ::= SEQUENCE { int cov_subscribe_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data) { @@ -475,6 +493,7 @@ BACnetPropertyReference ::= SEQUENCE { int cov_subscribe_property_encode_apdu( uint8_t * apdu, + unsigned max_apdu_len, uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data) { @@ -801,6 +820,7 @@ int cov_subscribe_property_decode_apdu( return len; } +/* dummy function stubs */ void testCOVNotifyData( Test * pTest, BACNET_COV_DATA * data,