cipqos.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*******************************************************************************
  2. * Copyright (c) 2009/, Rockwell Automation, Inc.
  3. * All rights reserved.
  4. *
  5. ******************************************************************************/
  6. #include "cipqos.h"
  7. #include "opener_user_conf.h"
  8. #include "cipcommon.h"
  9. #include "cipmessagerouter.h"
  10. #include "ciperror.h"
  11. #include "endianconv.h"
  12. #include "cipethernetlink.h"
  13. #include "opener_api.h"
  14. #include "trace.h"
  15. #define DEFAULT_DSCP_EVENT 59U
  16. #define DEFAULT_DSCP_GENERAL 47U
  17. #define DEFAULT_DSCP_URGENT 55U
  18. #define DEFAULT_DSCP_SCHEDULED 47U
  19. #define DEFAULT_DSCP_HIGH 43U
  20. #define DEFAULT_DSCP_LOW 31U
  21. #define DEFAULT_DSCP_EXPLICIT 27U
  22. /** @brief The QoS object
  23. *
  24. * The global instance of the QoS object
  25. */
  26. CipQosObject g_qos = {
  27. .q_frames_enable = false,
  28. .dscp.event = DEFAULT_DSCP_EVENT,
  29. .dscp.general = DEFAULT_DSCP_GENERAL,
  30. .dscp.urgent = DEFAULT_DSCP_URGENT,
  31. .dscp.scheduled = DEFAULT_DSCP_SCHEDULED,
  32. .dscp.high = DEFAULT_DSCP_HIGH,
  33. .dscp.low = DEFAULT_DSCP_LOW,
  34. .dscp.explicit_msg = DEFAULT_DSCP_EXPLICIT
  35. };
  36. /** @brief Active set of DSCP data inherits its data from the QoS object on boot-up
  37. *
  38. * The QoS DSCP values can be changed from the EIP network but the changes should come
  39. * into effect only after a restart. Values are initialized with the default values.
  40. * Changes are activated via the Identity Reset function
  41. */
  42. static CipQosDscpValues s_active_dscp = {
  43. .event = DEFAULT_DSCP_EVENT,
  44. .general = DEFAULT_DSCP_GENERAL,
  45. .urgent = DEFAULT_DSCP_URGENT,
  46. .scheduled = DEFAULT_DSCP_SCHEDULED,
  47. .high = DEFAULT_DSCP_HIGH,
  48. .low = DEFAULT_DSCP_LOW,
  49. .explicit_msg = DEFAULT_DSCP_EXPLICIT
  50. };
  51. /************** Functions ****************************************/
  52. /**@brief Retrieve the given data according to CIP encoding from the
  53. * message buffer.
  54. *
  55. * Implementation of the decode function for the SetAttributeSingle CIP service for QoS
  56. * Objects.
  57. * @param data pointer to value to be written.
  58. * @param message_router_request pointer to the request where the data should be taken from
  59. * @param message_router_response pointer to the response where status should be set
  60. * @return length of taken bytes
  61. * -1 .. error
  62. */
  63. int DecodeCipQoSAttribute(void *const data,
  64. CipMessageRouterRequest *const message_router_request,
  65. CipMessageRouterResponse *const message_router_response) {
  66. const EipUint8 **const cip_message = (const EipUint8 **const )message_router_request->data;
  67. int number_of_decoded_bytes = -1;
  68. if (NULL != cip_message) {
  69. CipUsint attribute_value_received = GetUsintFromMessage((const CipOctet **const)&cip_message);
  70. if (attribute_value_received < 64U) {
  71. *(CipUsint *)data = attribute_value_received; //write value to attribute
  72. message_router_response->general_status = kCipErrorSuccess;
  73. number_of_decoded_bytes = 1;
  74. } else {
  75. message_router_response->general_status =
  76. kCipErrorInvalidAttributeValue;
  77. }
  78. } else {
  79. message_router_response->general_status = kCipErrorNotEnoughData;
  80. OPENER_TRACE_INFO("CIP QoS not enough data\n");
  81. }
  82. return number_of_decoded_bytes;
  83. }
  84. CipUsint CipQosGetDscpPriority(ConnectionObjectPriority priority) {
  85. CipUsint priority_value;
  86. switch (priority) {
  87. case kConnectionObjectPriorityLow:
  88. priority_value = s_active_dscp.low;
  89. break;
  90. case kConnectionObjectPriorityHigh:
  91. priority_value = s_active_dscp.high;
  92. break;
  93. case kConnectionObjectPriorityScheduled:
  94. priority_value = s_active_dscp.scheduled;
  95. break;
  96. case kConnectionObjectPriorityUrgent:
  97. priority_value = s_active_dscp.urgent;
  98. break;
  99. case kConnectionObjectPriorityExplicit: /* fall through */
  100. default:
  101. priority_value = s_active_dscp.explicit_msg;
  102. break;
  103. }
  104. return priority_value;
  105. }
  106. EipStatus CipQoSInit() {
  107. CipClass *qos_class = NULL;
  108. if( ( qos_class = CreateCipClass(kCipQoSClassCode,
  109. 7, /* # class attributes */
  110. 7, /* # highest class attribute number */
  111. 2, /* # class services */
  112. 8, /* # instance attributes */
  113. 8, /* # highest instance attribute number */
  114. 2, /* # instance services */
  115. 1, /* # instances */
  116. "Quality of Service",
  117. 1, /* # class revision */
  118. NULL /* # function pointer for initialization */
  119. ) ) == 0 ) {
  120. return kEipStatusError;
  121. }
  122. CipInstance *instance = GetCipInstance(qos_class, 1); /* bind attributes to the instance #1 that was created above */
  123. InsertAttribute(instance,
  124. 1,
  125. kCipUsint,
  126. EncodeCipUsint,
  127. NULL,
  128. (void *) &g_qos.q_frames_enable,
  129. kNotSetOrGetable);
  130. InsertAttribute(instance,
  131. 2,
  132. kCipUsint,
  133. EncodeCipUsint,
  134. NULL,
  135. (void *) &g_qos.dscp.event,
  136. kNotSetOrGetable);
  137. InsertAttribute(instance,
  138. 3,
  139. kCipUsint,
  140. EncodeCipUsint,
  141. NULL,
  142. (void *) &g_qos.dscp.general,
  143. kNotSetOrGetable);
  144. InsertAttribute(instance,
  145. 4,
  146. kCipUsint,
  147. EncodeCipUsint,
  148. DecodeCipQoSAttribute,
  149. (void *) &g_qos.dscp.urgent,
  150. kGetableSingle | kSetable | kNvDataFunc);
  151. InsertAttribute(instance,
  152. 5,
  153. kCipUsint,
  154. EncodeCipUsint,
  155. DecodeCipQoSAttribute,
  156. (void *) &g_qos.dscp.scheduled,
  157. kGetableSingle | kSetable | kNvDataFunc);
  158. InsertAttribute(instance,
  159. 6,
  160. kCipUsint,
  161. EncodeCipUsint,
  162. DecodeCipQoSAttribute,
  163. (void *) &g_qos.dscp.high,
  164. kGetableSingle | kSetable | kNvDataFunc);
  165. InsertAttribute(instance,
  166. 7,
  167. kCipUsint,
  168. EncodeCipUsint,
  169. DecodeCipQoSAttribute,
  170. (void *) &g_qos.dscp.low,
  171. kGetableSingle | kSetable | kNvDataFunc);
  172. InsertAttribute(instance,
  173. 8,
  174. kCipUsint,
  175. EncodeCipUsint,
  176. DecodeCipQoSAttribute,
  177. (void *) &g_qos.dscp.explicit_msg,
  178. kGetableSingle | kSetable | kNvDataFunc);
  179. InsertService(qos_class, kGetAttributeSingle, &GetAttributeSingle,
  180. "GetAttributeSingle");
  181. InsertService(qos_class, kSetAttributeSingle, &SetAttributeSingle,
  182. "SetAttributeSingle");
  183. return kEipStatusOk;
  184. }
  185. void CipQosUpdateUsedSetQosValues(void) {
  186. s_active_dscp = g_qos.dscp;
  187. }
  188. void CipQosResetAttributesToDefaultValues(void) {
  189. static const CipQosDscpValues kDefaultValues = {
  190. .event = DEFAULT_DSCP_EVENT,
  191. .general = DEFAULT_DSCP_GENERAL,
  192. .urgent = DEFAULT_DSCP_URGENT,
  193. .scheduled = DEFAULT_DSCP_SCHEDULED,
  194. .high = DEFAULT_DSCP_HIGH,
  195. .low = DEFAULT_DSCP_LOW,
  196. .explicit_msg = DEFAULT_DSCP_EXPLICIT
  197. };
  198. g_qos.q_frames_enable = false;
  199. g_qos.dscp = kDefaultValues;
  200. }