Bläddra i källkod

Service SetAttributeList added

micsat 4 år sedan
förälder
incheckning
c52ff3e252
2 ändrade filer med 96 tillägg och 1 borttagningar
  1. 77 0
      source/src/cip/cipcommon.c
  2. 19 1
      source/src/cip/cipcommon.h

+ 77 - 0
source/src/cip/cipcommon.c

@@ -28,6 +28,7 @@
 #include "appcontype.h"
 #include "cipepath.h"
 #include "stdlib.h"
+#include "ciptypes.h"
 
 /* private functions*/
 void EncodeEPath(CipEpath *epath, ENIPMessage *message);
@@ -905,6 +906,82 @@ EipStatus GetAttributeList(CipInstance *instance,
 	return kEipStatusOkSend;
 }
 
+EipStatus SetAttributeList(CipInstance *instance,
+		CipMessageRouterRequest *message_router_request,
+		CipMessageRouterResponse *message_router_response,
+		const struct sockaddr *originator_address,
+		const int encapsulation_session) {
+
+	InitializeENIPMessage(&message_router_response->message);
+	message_router_response->reply_service = (0x80
+			| message_router_request->service);
+	message_router_response->general_status = kCipErrorSuccess;
+	message_router_response->size_of_additional_status = 0;
+
+	CipUint attribute_count_request = GetUintFromMessage(
+			&message_router_request->data);
+
+	if (0 != attribute_count_request) {
+
+		EipUint16 attribute_number = 0;
+		CipAttributeStruct *attribute = NULL;
+
+		AddIntToMessage(attribute_count_request,
+				&message_router_response->message); // number of attributes in the response
+
+		for (size_t j = 0; j < attribute_count_request; j++) {
+
+			attribute_number = GetUintFromMessage(
+					&message_router_request->data);
+			attribute = GetCipAttribute(instance, attribute_number);
+
+			AddIntToMessage(attribute_number,
+					&message_router_response->message); // Attribute-ID
+
+			if (NULL != attribute) {
+
+				uint8_t set_bit_mask =
+						(instance->cip_class->set_bit_mask[CalculateIndex(
+								attribute_number)]);
+				if (0 != (set_bit_mask & (1 << (attribute_number % 8)))) { //check if attribute is settable
+					AddSintToMessage(kCipErrorSuccess,
+							&message_router_response->message); // Attribute status
+					AddSintToMessage(0, &message_router_response->message); // Reserved, shall be 0
+					attribute->decode(attribute->data, message_router_request,
+							message_router_response); // write data to attribute
+				} else {
+					AddSintToMessage(kCipErrorAttributeNotSetable,
+							&message_router_response->message); // Attribute status
+					AddSintToMessage(0, &message_router_response->message); // Reserved, shall be 0
+
+					//move request message pointer
+					int attribute_data_length = GetCipDataTypeLength(
+							attribute->type, message_router_request->data);
+					if (0 != attribute_data_length) {
+						message_router_request->data += attribute_data_length;
+						message_router_response->general_status =
+								kCipErrorAttributeListError;
+					} else {
+						message_router_response->general_status =
+								kCipErrorPartialTransfer;
+						return kEipStatusOkSend;
+					}
+				}
+			} else {
+				AddSintToMessage(kCipErrorAttributeNotSupported,
+						&message_router_response->message); // status
+				AddSintToMessage(0, &message_router_response->message); // Reserved, shall be 0
+				message_router_response->general_status =
+						kCipErrorAttributeListError;
+			}
+		}
+	} else {
+		message_router_response->general_status = kCipErrorAttributeListError;
+	}
+
+	return kEipStatusOkSend;
+}
+
 void EncodeEPath(CipEpath *epath, ENIPMessage *message) {
   unsigned int length = epath->path_size;
   size_t start_length = message->used_message_length;

+ 19 - 1
source/src/cip/cipcommon.h

@@ -65,7 +65,7 @@ void GenerateSetAttributeSingleHeader(
 /** @brief Generic implementation of the SetAttributeSingle CIP service
  *
  *  Modifies an attribute value if the requested object has
- *  the appropriate attribute implemented and if the attribute is setable.
+ *  the appropriate attribute implemented and if the attribute is settable.
  *
  * @param instance pointer to instance.
  * @param message_router_request pointer to request.
@@ -119,6 +119,24 @@ EipStatus GetAttributeList(CipInstance *instance,
                           const struct sockaddr *originator_address,
                           const int encapsulation_session);
 
+/** @brief Generic implementation of the SetAttributeList CIP service
+ *
+ * Sets the values of selected attributes of the specified object class
+ * or instance.
+ * @param instance pointer to object instance with data.
+ * @param message_router_request pointer to MR request.
+ * @param message_router_response pointer to MR response.
+ * @param originator_address address struct of the originator as received
+ * @param encapsulation_session associated encapsulation session of the explicit message
+ * @return length of data stream >0 .. success
+ *              0 .. no reply to send
+ */
+EipStatus SetAttributeList(CipInstance *instance,
+                          CipMessageRouterRequest *message_router_request,
+                          CipMessageRouterResponse *message_router_response,
+                          const struct sockaddr *originator_address,
+                          const int encapsulation_session);
+
 /** @brief Decodes padded EPath
  *  @param epath EPath object to the receiving element
  *  @param message pointer to the message to decode