Преглед изворни кода

SetAttributeSingleAdded, decode functions added

micsat пре 5 година
родитељ
комит
f062c78605
4 измењених фајлова са 318 додато и 2 уклоњено
  1. 234 1
      source/src/cip/cipcommon.c
  2. 25 0
      source/src/cip/cipcommon.h
  3. 5 0
      source/src/cip/ciptypes.h
  4. 54 1
      source/src/opener_api.h

+ 234 - 1
source/src/cip/cipcommon.c

@@ -325,6 +325,7 @@ void InsertAttribute(CipInstance *const instance,
                      const EipUint16 attribute_number,
                      const EipUint8 cip_type,
                      CipAttributeEncodeInMessage encode_function,
+					 //CipAttributeDecodeInMessage decode_function, //TODO: add decode
                      void *const data,
                      const EipByte cip_flags) {
 
@@ -672,7 +673,239 @@ void EncodeCipEthernetLinkPhyisicalAddress(const void *const data,
   outgoing_message->used_message_length += 6;
 }
 
-int DecodeData(const EipUint8 cip_data_type,
+void GenerateSetAttributeSingleHeader( //TODO: update
+  const CipMessageRouterRequest *const message_router_request,
+  CipMessageRouterResponse *const message_router_response) {
+  InitializeENIPMessage(&message_router_response->message);
+  message_router_response->reply_service =
+    (0x80 | message_router_request->service);
+  message_router_response->general_status = kCipErrorAttributeNotSupported;
+  message_router_response->size_of_additional_status = 0;
+}
+
+EipStatus SetAttributeSingle(CipInstance *RESTRICT const instance,
+                             CipMessageRouterRequest *const message_router_request,
+                             CipMessageRouterResponse *const message_router_response,
+                             const struct sockaddr *originator_address,
+                             const int encapsulation_session) {
+
+  CipAttributeStruct *attribute = GetCipAttribute(instance,
+                                                  message_router_request->request_path.attribute_number);
+
+  GenerateSetAttributeSingleHeader(message_router_request,
+                                   message_router_response);
+
+  EipUint16 attribute_number =
+    message_router_request->request_path.attribute_number;
+
+  /* Mask for filtering set-ability */
+  if ( (NULL != attribute) && (NULL != attribute->data) ) {
+    uint8_t set_bit_mask =
+      (instance->cip_class->set_bit_mask[CalculateIndex(
+                                                  attribute_number)
+       ]);
+    if (0 != (set_bit_mask & (1 << (attribute_number % 8) ) ) ) {    //TODO: check if attribute setable, check correct bit mask
+      OPENER_TRACE_INFO("setAttribute %d\n", attribute_number);
+
+      //TODO: check data length ?
+
+      /* Call the PreSetCallback if enabled for this attribute and the class provides one. */
+      if ( (attribute->attribute_flags & kPreSetFunc) &&
+           NULL != instance->cip_class->PreSetCallback ) {
+        instance->cip_class->PreSetCallback(instance,
+                                            attribute,
+                                            message_router_request->service);
+      }
+
+      OPENER_ASSERT(NULL != attribute);
+      attribute->decode(attribute->data, &message_router_response->message);
+      message_router_response->general_status = kCipErrorSuccess;
+
+      /* Call the PostSetCallback if enabled for this attribute and the class provides one. */
+      if ( (attribute->attribute_flags & kPostSetFunc) &&
+           NULL != instance->cip_class->PostSetCallback ) {
+        instance->cip_class->PostSetCallback(instance,
+                                             attribute,
+                                             message_router_request->service);
+      }
+    }
+  }
+
+  return kEipStatusOkSend;
+}
+
+
+int DecodeCipBool(const CipBool *const data, const EipUint8 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	*(EipUint8*) (data) = **cip_message;
+	++(*cip_message);
+	number_of_decoded_bytes = 1;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipByte(const CipByte *const data,
+			const EipUint8 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+		(*(EipUint8*) (data)) = GetByteFromMessage(cip_message);
+		number_of_decoded_bytes = 1;
+		return number_of_decoded_bytes;
+}
+
+int DecodeCipWord(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint16*) (data)) = GetWordFromMessage(cip_message);
+	number_of_decoded_bytes = 2;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipDword(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint32*) (data)) = GetDintFromMessage(cip_message);
+	number_of_decoded_bytes = 4;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipLword(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint64*) (data)) = GetLintFromMessage(cip_message);
+	number_of_decoded_bytes = 8;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipUsint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint8*) (data)) = GetUsintFromMessage(cip_message);
+	number_of_decoded_bytes = 1;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipUint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint16*) (data)) = GetUintFromMessage(cip_message);
+	number_of_decoded_bytes = 2;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipUdint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint32*) (data)) = GetUdintFromMessage(cip_message);
+	number_of_decoded_bytes = 4;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipUlint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint64*) (data)) = GetLintFromMessage(cip_message);
+	number_of_decoded_bytes = 8;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipSint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint8*) (data)) = GetSintFromMessage(cip_message);
+	number_of_decoded_bytes = 1;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipInt(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint16*) (data)) = GetIntFromMessage(cip_message);
+	number_of_decoded_bytes = 2;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipDint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint32*) (data)) = GetDintFromMessage(cip_message);
+	number_of_decoded_bytes = 4;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipLint(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint64*) (data)) = GetLintFromMessage(cip_message);
+	number_of_decoded_bytes = 8;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipReal(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint32 *) (data) ) = GetDintFromMessage(cip_message);
+	number_of_decoded_bytes = 4;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipLreal(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	(*(EipUint64*) (data)) = GetLintFromMessage(cip_message);
+	number_of_decoded_bytes = 8;
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipString(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	CipString *string = (CipString*) data;
+	string->length = GetIntFromMessage(cip_message);
+	memcpy(string->string, *cip_message, string->length);
+	*cip_message += string->length;
+
+	number_of_decoded_bytes = string->length + 2; /* we have a two byte length field */
+	if (number_of_decoded_bytes & 0x01) {
+		/* we have an odd byte count */
+		++(*cip_message);
+		number_of_decoded_bytes++;
+	}
+	return number_of_decoded_bytes;
+}
+
+int DecodeCipShortString(const CipByte *const data,
+		const EipUint16 **const cip_message) {
+
+	int number_of_decoded_bytes = -1;
+	CipShortString *short_string = (CipShortString*) data;
+
+	short_string->length = **cip_message;
+	++(*cip_message);
+
+	memcpy(short_string->string, *cip_message, short_string->length);
+	*cip_message += short_string->length;
+
+	number_of_decoded_bytes = short_string->length + 1;
+	return number_of_decoded_bytes;
+}
+
+
+int DecodeData(const EipUint8 cip_data_type,  //TODO: replace with Decode functions, see above
                void *const cip_data,
                const EipUint8 **const cip_message) {
   int number_of_decoded_bytes = -1;

+ 25 - 0
source/src/cip/cipcommon.h

@@ -58,6 +58,31 @@ EipStatus GetAttributeSingle(
   const struct sockaddr *originator_address,
   const int encapsulation_session);
 
+void GenerateSetAttributeSingleHeader(
+  const CipMessageRouterRequest *const message_router_request,
+  CipMessageRouterResponse *const message_router_response);
+
+/** @brief Generic implementation of the SetAttributeSingle CIP service
+ *
+ * TODO: add description
+ *
+ * @param instance pointer to instance.
+ * @param message_router_request pointer to request.
+ * @param message_router_response pointer to response.
+ * @param originator_address address struct of the originator as received
+ * @param encapsulation_session associated encapsulation session of the explicit message
+ * @return status  >0 .. success
+ *          -1 .. requested attribute not set //TODO: check if correct
+ */
+EipStatus SetAttributeSingle(
+  CipInstance *RESTRICT const instance,
+  CipMessageRouterRequest *const
+  message_router_request,
+  CipMessageRouterResponse *const
+  message_router_response,
+  const struct sockaddr *originator_address,
+  const int encapsulation_session);
+
 /** @brief Generic implementation of the GetAttributeAll CIP service
  *
  * Copy all attributes from Object into the global message buffer.

+ 5 - 0
source/src/cip/ciptypes.h

@@ -276,12 +276,17 @@ typedef struct {
 typedef void (*CipAttributeEncodeInMessage)(const void *const data,
                                             ENIPMessage *const outgoing_message);
 
+/** @brief self-describing data decoding for CIP types */
+typedef void (*CipAttributeDecodeInMessage)(const void *const data,
+                                            ENIPMessage *const incoming_message); //TODO: chek if correct
+
 /** @brief Structure to describe a single CIP attribute of an object
  */
 typedef struct {
   EipUint16 attribute_number; /**< The attribute number of this attribute. */
   EipUint8 type;  /**< The @ref CipDataType of this attribute. */
   CipAttributeEncodeInMessage encode; /**< Self-describing its data encoding */
+  CipAttributeDecodeInMessage decode; /**< Self-describing its data decoding */
   CIPAttributeFlag attribute_flags; /**< See @ref CIPAttributeFlag declaration for valid values. */
   void *data;
 } CipAttributeStruct;

+ 54 - 1
source/src/opener_api.h

@@ -224,6 +224,7 @@ CipInstance *AddCipInstance(CipClass *RESTRICT const cip_class_to_add_instance,
  *  @param attribute_number Number of attribute to be inserted.
  *  @param cip_data_type Type of attribute to be inserted.
  *  @param encode_function Function pointer to the encoding function
+ *  @param decode_function Function pointer to the decoding function
  *  @param cip_data Pointer to data of attribute.
  *  @param cip_flags Flags to indicate set-ability and get-ability of attribute.
  */
@@ -231,6 +232,7 @@ void InsertAttribute(CipInstance *const instance,
                      const EipUint16 attribute_number,
                      const EipUint8 cip_type,
                      CipAttributeEncodeInMessage encode_function,
+					 //CipAttributeDecodeInMessage decode_function, //TODO: add decode
                      void *const data,
                      const EipByte cip_flags);
 
@@ -379,10 +381,61 @@ void EncodeCipEthernetLinkPhyisicalAddress(const void *const data,
  *  @return length of taken bytes
  *          -1 .. error
  */
-int DecodeData(const EipUint8 cip_data_type,
+int DecodeData(const EipUint8 cip_data_type,  //TODO: replace with decode functions, see below
                void *const cip_data,
                const EipUint8 **const cip_message);
 
+int DecodeCipBool(const CipBool *const data,
+					const EipUint8 **const cip_message);
+
+int DecodeCipByte(const CipByte *const data,
+			const EipUint8 **const cip_message);
+
+int DecodeCipWord(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipDword(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipLword(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipUsint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipUint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipUdint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipUlint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipSint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipInt(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipDint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipLint(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipReal(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipLreal(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipString(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
+int DecodeCipShortString(const CipByte *const data,
+		const EipUint16 **const cip_message);
+
 /** @ingroup CIP_API
  * @brief Create an instance of an assembly object
  *