sampleapplication.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*******************************************************************************
  2. * Copyright (c) 2012, Rockwell Automation, Inc.
  3. * All rights reserved.
  4. *
  5. ******************************************************************************/
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <stdbool.h>
  9. #include "opener_api.h"
  10. #include "appcontype.h"
  11. #include "trace.h"
  12. #include "cipidentity.h"
  13. #include "ciptcpipinterface.h"
  14. #include "cipqos.h"
  15. #include "nvdata.h"
  16. #if defined(OPENER_ETHLINK_CNTRS_ENABLE) && 0 != OPENER_ETHLINK_CNTRS_ENABLE
  17. #include "cipethernetlink.h"
  18. #include "ethlinkcbs.h"
  19. #endif
  20. #define DEMO_APP_INPUT_ASSEMBLY_NUM 100 //0x064
  21. #define DEMO_APP_OUTPUT_ASSEMBLY_NUM 150 //0x096
  22. #define DEMO_APP_CONFIG_ASSEMBLY_NUM 151 //0x097
  23. #define DEMO_APP_HEARTBEAT_INPUT_ONLY_ASSEMBLY_NUM 152 //0x098
  24. #define DEMO_APP_HEARTBEAT_LISTEN_ONLY_ASSEMBLY_NUM 153 //0x099
  25. #define DEMO_APP_EXPLICT_ASSEMBLY_NUM 154 //0x09A
  26. /* global variables for demo application (4 assembly data fields) ************/
  27. EipUint8 g_assembly_data064[32]; /* Input */
  28. EipUint8 g_assembly_data096[32]; /* Output */
  29. EipUint8 g_assembly_data097[10]; /* Config */
  30. EipUint8 g_assembly_data09A[32]; /* Explicit */
  31. /* local functions */
  32. /* global functions called by the stack */
  33. EipStatus ApplicationInitialization(void) {
  34. /* create 3 assembly object instances*/
  35. /*INPUT*/
  36. CreateAssemblyObject( DEMO_APP_INPUT_ASSEMBLY_NUM, g_assembly_data064,
  37. sizeof(g_assembly_data064) );
  38. /*OUTPUT*/
  39. CreateAssemblyObject( DEMO_APP_OUTPUT_ASSEMBLY_NUM, g_assembly_data096,
  40. sizeof(g_assembly_data096) );
  41. /*CONFIG*/
  42. CreateAssemblyObject( DEMO_APP_CONFIG_ASSEMBLY_NUM, g_assembly_data097,
  43. sizeof(g_assembly_data097) );
  44. /*Heart-beat output assembly for Input only connections */
  45. CreateAssemblyObject(DEMO_APP_HEARTBEAT_INPUT_ONLY_ASSEMBLY_NUM, NULL, 0);
  46. /*Heart-beat output assembly for Listen only connections */
  47. CreateAssemblyObject(DEMO_APP_HEARTBEAT_LISTEN_ONLY_ASSEMBLY_NUM, NULL, 0);
  48. /* assembly for explicit messaging */
  49. CreateAssemblyObject( DEMO_APP_EXPLICT_ASSEMBLY_NUM, g_assembly_data09A,
  50. sizeof(g_assembly_data09A) );
  51. ConfigureExclusiveOwnerConnectionPoint(0, DEMO_APP_OUTPUT_ASSEMBLY_NUM,
  52. DEMO_APP_INPUT_ASSEMBLY_NUM,
  53. DEMO_APP_CONFIG_ASSEMBLY_NUM);
  54. ConfigureInputOnlyConnectionPoint(0,
  55. DEMO_APP_HEARTBEAT_INPUT_ONLY_ASSEMBLY_NUM,
  56. DEMO_APP_INPUT_ASSEMBLY_NUM,
  57. DEMO_APP_CONFIG_ASSEMBLY_NUM);
  58. ConfigureListenOnlyConnectionPoint(0,
  59. DEMO_APP_HEARTBEAT_LISTEN_ONLY_ASSEMBLY_NUM,
  60. DEMO_APP_INPUT_ASSEMBLY_NUM,
  61. DEMO_APP_CONFIG_ASSEMBLY_NUM);
  62. /* For NV data support connect callback functions for each object class with
  63. * NV data.
  64. */
  65. InsertGetSetCallback(GetCipClass(kCipQoSClassCode), NvQosSetCallback,
  66. kNvDataFunc);
  67. InsertGetSetCallback(GetCipClass(kCipTcpIpInterfaceClassCode),
  68. NvTcpipSetCallback,
  69. kNvDataFunc);
  70. #if defined(OPENER_ETHLINK_CNTRS_ENABLE) && 0 != OPENER_ETHLINK_CNTRS_ENABLE
  71. /* For the Ethernet Interface & Media Counters connect a PreGetCallback and
  72. * a PostGetCallback.
  73. * The PreGetCallback is used to fetch the counters from the hardware.
  74. * The PostGetCallback is utilized by the GetAndClear service to clear
  75. * the hardware counters after the current data have been transmitted.
  76. */
  77. {
  78. CipClass *p_eth_link_class = GetCipClass(kCipEthernetLinkClassCode);
  79. InsertGetSetCallback(p_eth_link_class,
  80. EthLnkPreGetCallback,
  81. kPreGetFunc);
  82. InsertGetSetCallback(p_eth_link_class,
  83. EthLnkPostGetCallback,
  84. kPostGetFunc);
  85. /* Specify the attributes for which the callback should be executed. */
  86. for (int idx = 0; idx < OPENER_ETHLINK_INSTANCE_CNT; ++idx)
  87. {
  88. CipAttributeStruct *p_eth_link_attr;
  89. CipInstance *p_eth_link_inst =
  90. GetCipInstance(p_eth_link_class, idx + 1);
  91. OPENER_ASSERT(p_eth_link_inst);
  92. /* Interface counters attribute */
  93. p_eth_link_attr = GetCipAttribute(p_eth_link_inst, 4);
  94. p_eth_link_attr->attribute_flags |= (kPreGetFunc | kPostGetFunc);
  95. /* Media counters attribute */
  96. p_eth_link_attr = GetCipAttribute(p_eth_link_inst, 5);
  97. p_eth_link_attr->attribute_flags |= (kPreGetFunc | kPostGetFunc);
  98. }
  99. }
  100. #endif
  101. return kEipStatusOk;
  102. }
  103. void HandleApplication(void) {
  104. /* check if application needs to trigger an connection */
  105. }
  106. void CheckIoConnectionEvent(unsigned int output_assembly_id,
  107. unsigned int input_assembly_id,
  108. IoConnectionEvent io_connection_event) {
  109. /* maintain a correct output state according to the connection state*/
  110. (void) output_assembly_id; /* suppress compiler warning */
  111. (void) input_assembly_id; /* suppress compiler warning */
  112. (void) io_connection_event; /* suppress compiler warning */
  113. }
  114. EipStatus AfterAssemblyDataReceived(CipInstance *instance) {
  115. EipStatus status = kEipStatusOk;
  116. /*handle the data received e.g., update outputs of the device */
  117. switch (instance->instance_number) {
  118. case DEMO_APP_OUTPUT_ASSEMBLY_NUM:
  119. /* Data for the output assembly has been received.
  120. * Mirror it to the inputs */
  121. memcpy( &g_assembly_data064[0], &g_assembly_data096[0],
  122. sizeof(g_assembly_data064) );
  123. break;
  124. case DEMO_APP_EXPLICT_ASSEMBLY_NUM:
  125. /* do something interesting with the new data from
  126. * the explicit set-data-attribute message */
  127. break;
  128. case DEMO_APP_CONFIG_ASSEMBLY_NUM:
  129. /* Add here code to handle configuration data and check if it is ok
  130. * The demo application does not handle config data.
  131. * However in order to pass the test we accept any data given.
  132. * EIP_ERROR
  133. */
  134. status = kEipStatusOk;
  135. break;
  136. default:
  137. OPENER_TRACE_INFO(
  138. "Unknown assembly instance ind AfterAssemblyDataReceived");
  139. break;
  140. }
  141. return status;
  142. }
  143. EipBool8 BeforeAssemblyDataSend(CipInstance *pa_pstInstance) {
  144. /*update data to be sent e.g., read inputs of the device */
  145. /*In this sample app we mirror the data from out to inputs on data receive
  146. * therefore we need nothing to do here. Just return true to inform that
  147. * the data is new.
  148. */
  149. if (pa_pstInstance->instance_number == DEMO_APP_EXPLICT_ASSEMBLY_NUM) {
  150. /* do something interesting with the existing data
  151. * for the explicit get-data-attribute message */
  152. }
  153. return true;
  154. }
  155. EipStatus ResetDevice(void) {
  156. /* add reset code here*/
  157. CloseAllConnections();
  158. CipQosUpdateUsedSetQosValues();
  159. return kEipStatusOk;
  160. }
  161. EipStatus ResetDeviceToInitialConfiguration(void) {
  162. /*rest the parameters */
  163. g_tcpip.encapsulation_inactivity_timeout = 120;
  164. CipQosResetAttributesToDefaultValues();
  165. /*than perform device reset*/
  166. ResetDevice();
  167. return kEipStatusOk;
  168. }
  169. void *
  170. CipCalloc(size_t number_of_elements,
  171. size_t size_of_element) {
  172. return calloc(number_of_elements, size_of_element);
  173. }
  174. void CipFree(void *data) {
  175. free(data);
  176. }
  177. void RunIdleChanged(EipUint32 run_idle_value) {
  178. OPENER_TRACE_INFO("Run/Idle handler triggered\n");
  179. if( (0x0001 & run_idle_value) == 1 ) {
  180. CipIdentitySetExtendedDeviceStatus(kAtLeastOneIoConnectionInRunMode);
  181. } else {
  182. CipIdentitySetExtendedDeviceStatus(
  183. kAtLeastOneIoConnectionEstablishedAllInIdleMode);
  184. }
  185. (void) run_idle_value;
  186. }