cs101_master.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #include "iec_include.h"
  2. #include "platform_thread.h"
  3. struct sCS101_Master
  4. {
  5. SerialPort serialPort;
  6. struct sLinkLayerParameters linkLayerParameters;
  7. struct sCS101_AppLayerParameters alParameters;
  8. SerialTransceiverFT12 transceiver;
  9. IEC60870_LinkLayerMode linkLayerMode;
  10. LinkLayerBalanced balancedLinkLayer;
  11. LinkLayerPrimaryUnbalanced unbalancedLinkLayer;
  12. int slaveAddress; /* address of the currently selected slave (unbalanced link layer only) */
  13. CS101_ASDUReceivedHandler asduReceivedHandler;
  14. void* asduReceivedHandlerParameter;
  15. struct sCS101_Queue userDataQueue;
  16. #if (CONFIG_USE_THREADS == 1)
  17. bool isRunning;
  18. platform_thread_t* workerThread;
  19. #endif
  20. };
  21. static struct sCS101_AppLayerParameters defaultAppLayerParameters = {
  22. /* .sizeOfTypeId = */ 1,
  23. /* .sizeOfVSQ = */ 1,
  24. /* .sizeOfCOT = */ 2,
  25. /* .originatorAddress = */ 0,
  26. /* .sizeOfCA = */ 2,
  27. /* .sizeOfIOA = */ 3,
  28. /* .maxSizeOfASDU = */ 249
  29. };
  30. /********************************************
  31. * IBalancedApplicationLayer
  32. ********************************************/
  33. static Frame
  34. IBalancedApplicationLayer_GetUserData (void* parameter, Frame frame)
  35. {
  36. CS101_Master self = (CS101_Master) parameter;
  37. Frame ret = NULL;
  38. CS101_Queue_lock(&(self->userDataQueue));
  39. ret = CS101_Queue_dequeue(&(self->userDataQueue), frame);
  40. CS101_Queue_unlock(&(self->userDataQueue));
  41. return ret;
  42. }
  43. static bool
  44. IBalancedApplicationLayer_HandleReceivedData (void* parameter, uint8_t* msg, bool isBroadcast, int userDataStart, int userDataLength)
  45. {
  46. UNUSED_PARAMETER(isBroadcast);
  47. CS101_Master self = (CS101_Master) parameter;
  48. CS101_ASDU asdu = CS101_ASDU_createFromBuffer(&(self->alParameters), msg + userDataStart, userDataLength);
  49. if (self->asduReceivedHandler)
  50. self->asduReceivedHandler(self->asduReceivedHandlerParameter, 0, asdu);
  51. CS101_ASDU_destroy(asdu);
  52. return true;
  53. }
  54. static struct sIBalancedApplicationLayer cs101BalancedAppLayerInterface = {
  55. IBalancedApplicationLayer_GetUserData,
  56. IBalancedApplicationLayer_HandleReceivedData
  57. };
  58. bool
  59. CS101_Master_isChannelReady(CS101_Master self, int address)
  60. {
  61. if (self->unbalancedLinkLayer)
  62. return LinkLayerPrimaryUnbalanced_isChannelAvailable(self->unbalancedLinkLayer, address);
  63. return false;
  64. }
  65. void
  66. CS101_Master_useSlaveAddress(CS101_Master self, int address)
  67. {
  68. self->slaveAddress = address;
  69. if (self->balancedLinkLayer) {
  70. LinkLayerBalanced_setOtherStationAddress(self->balancedLinkLayer, address);
  71. }
  72. }
  73. /********************************************
  74. * END IBalancedApplicationLayer
  75. ********************************************/
  76. void
  77. CS101_Master_sendInterrogationCommand(CS101_Master self, CS101_CauseOfTransmission cot, int ca, QualifierOfInterrogation qoi)
  78. {
  79. sCS101_StaticASDU _asdu;
  80. CS101_ASDU asdu = CS101_ASDU_initializeStatic(&_asdu, &(self->alParameters), false, cot, self->alParameters.originatorAddress, ca, false, false);
  81. struct sInterrogationCommand _io;
  82. InformationObject io = (InformationObject) InterrogationCommand_create(&_io, 0, qoi);
  83. CS101_ASDU_addInformationObject(asdu, io);
  84. CS101_Master_sendASDU(self, asdu);
  85. }
  86. void
  87. CS101_Master_sendReadCommand(CS101_Master self, int ca, int ioa)
  88. {
  89. sCS101_StaticASDU _asdu;
  90. CS101_ASDU asdu = CS101_ASDU_initializeStatic(&_asdu, &(self->alParameters), false, CS101_COT_REQUEST, self->alParameters.originatorAddress, ca, false, false);
  91. struct sReadCommand _io;
  92. InformationObject io = (InformationObject) ReadCommand_create(&_io, ioa);
  93. CS101_ASDU_addInformationObject(asdu, io);
  94. CS101_Master_sendASDU(self, asdu);
  95. }
  96. void
  97. CS101_Master_sendProcessCommand(CS101_Master self, CS101_CauseOfTransmission cot, int ca, InformationObject command)
  98. {
  99. sCS101_StaticASDU _asdu;
  100. CS101_ASDU asdu = CS101_ASDU_initializeStatic(&_asdu, &(self->alParameters), false, cot, self->alParameters.originatorAddress, ca, false, false);
  101. CS101_ASDU_addInformationObject(asdu, command);
  102. CS101_Master_sendASDU(self, asdu);
  103. }
  104. void
  105. CS101_Master_sendClockSyncCommand(CS101_Master self, int ca, CP56Time2a time)
  106. {
  107. sCS101_StaticASDU _asdu;
  108. CS101_ASDU asdu = CS101_ASDU_initializeStatic(&_asdu, &(self->alParameters), false, CS101_COT_ACTIVATION, self->alParameters.originatorAddress, ca, false, false);
  109. struct sClockSynchronizationCommand _io;
  110. InformationObject io = (InformationObject) ClockSynchronizationCommand_create(&_io, 0, time);
  111. CS101_ASDU_addInformationObject(asdu, io);
  112. CS101_Master_sendASDU(self, asdu);
  113. }
  114. void
  115. CS101_Master_destroy(CS101_Master self)
  116. {
  117. if (self) {
  118. if (self->balancedLinkLayer) {
  119. LinkLayerBalanced_destroy(self->balancedLinkLayer);
  120. CS101_Queue_dispose(&(self->userDataQueue));
  121. }
  122. if (self->unbalancedLinkLayer) {
  123. LinkLayerPrimaryUnbalanced_destroy(self->unbalancedLinkLayer);
  124. }
  125. SerialTransceiverFT12_destroy(self->transceiver);
  126. GLOBAL_FREEMEM(self);
  127. }
  128. }
  129. static bool
  130. isBroadcastAddress(CS101_Master self, int address)
  131. {
  132. if (self->linkLayerParameters.addressLength == 1) {
  133. return (address == 255);
  134. }
  135. else if (self->linkLayerParameters.addressLength == 2) {
  136. return (address == 65535);
  137. }
  138. return 0;
  139. }
  140. void
  141. CS101_Master_sendASDU(CS101_Master self, CS101_ASDU asdu)
  142. {
  143. if (self->unbalancedLinkLayer) {
  144. struct sBufferFrame bufferFrame;
  145. uint8_t buffer[256];
  146. BufferFrame_initialize(&bufferFrame, buffer, 0);
  147. CS101_ASDU_encode(asdu, (Frame) &bufferFrame);
  148. if (isBroadcastAddress(self, self->slaveAddress))
  149. LinkLayerPrimaryUnbalanced_sendNoReply(self->unbalancedLinkLayer, self->slaveAddress, &bufferFrame);
  150. else
  151. LinkLayerPrimaryUnbalanced_sendConfirmed(self->unbalancedLinkLayer, self->slaveAddress, &bufferFrame);
  152. }
  153. else
  154. CS101_Queue_enqueue(&(self->userDataQueue), asdu);
  155. }
  156. /********************************************
  157. * IPrimaryApplicationLayer
  158. ********************************************/
  159. static void
  160. IPrimaryApplicationLayer_AccessDemand(void* parameter, int slaveAddress)
  161. {
  162. CS101_Master self = (CS101_Master) parameter;
  163. printf ("MASTER: Access demand for slave %i\n", slaveAddress);
  164. LinkLayerPrimaryUnbalanced_requestClass1Data(self->unbalancedLinkLayer, slaveAddress);
  165. }
  166. static void
  167. IPrimaryApplicationLayer_UserData(void* parameter, int slaveAddress, uint8_t* msg, int start, int length)
  168. {
  169. CS101_Master self = (CS101_Master) parameter;
  170. CS101_ASDU asdu = CS101_ASDU_createFromBuffer(&(self->alParameters), msg + start, length);
  171. if (self->asduReceivedHandler)
  172. self->asduReceivedHandler(self->asduReceivedHandlerParameter, slaveAddress, asdu);
  173. CS101_ASDU_destroy(asdu);
  174. }
  175. static void
  176. IPrimaryApplicationLayer_Timeout (void* parameter, int slaveAddress)
  177. {
  178. UNUSED_PARAMETER(parameter);
  179. UNUSED_PARAMETER(slaveAddress);
  180. }
  181. static struct sIPrimaryApplicationLayer cs101UnbalancedAppLayerInterface = {
  182. IPrimaryApplicationLayer_AccessDemand,
  183. IPrimaryApplicationLayer_UserData,
  184. IPrimaryApplicationLayer_Timeout
  185. };
  186. CS101_Master
  187. CS101_Master_createEx(SerialPort serialPort, const LinkLayerParameters llParameters, const CS101_AppLayerParameters alParameters, IEC60870_LinkLayerMode linkLayerMode,
  188. int queueSize)
  189. {
  190. CS101_Master self = (CS101_Master) GLOBAL_MALLOC(sizeof(struct sCS101_Master));
  191. if (self != NULL) {
  192. if (llParameters)
  193. self->linkLayerParameters = *llParameters;
  194. else {
  195. self->linkLayerParameters.addressLength = 1;
  196. self->linkLayerParameters.timeoutForAck = 200;
  197. self->linkLayerParameters.timeoutRepeat = 1000;
  198. self->linkLayerParameters.timeoutLinkState = 5000;
  199. self->linkLayerParameters.useSingleCharACK = true;
  200. }
  201. if (alParameters)
  202. self->alParameters = *alParameters;
  203. else
  204. self->alParameters = defaultAppLayerParameters;
  205. self->transceiver = SerialTransceiverFT12_create(serialPort, &(self->linkLayerParameters));
  206. self->linkLayerMode = linkLayerMode;
  207. if (linkLayerMode == IEC60870_LINK_LAYER_UNBALANCED) {
  208. self->balancedLinkLayer = NULL;
  209. self->unbalancedLinkLayer = LinkLayerPrimaryUnbalanced_create(self->transceiver,
  210. &(self->linkLayerParameters), &cs101UnbalancedAppLayerInterface, self);
  211. }
  212. else {
  213. CS101_Queue_initialize(&(self->userDataQueue), queueSize);
  214. self->unbalancedLinkLayer = NULL;
  215. self->balancedLinkLayer = LinkLayerBalanced_create(0, self->transceiver,
  216. &(self->linkLayerParameters),
  217. &cs101BalancedAppLayerInterface, self);
  218. LinkLayerBalanced_setDIR(self->balancedLinkLayer, true);
  219. }
  220. self->asduReceivedHandler = NULL;
  221. #if (CONFIG_USE_THREADS == 1)
  222. self->isRunning = false;
  223. self->workerThread = NULL;
  224. #endif
  225. }
  226. return self;
  227. }
  228. CS101_Master
  229. CS101_Master_create(SerialPort serialPort, const LinkLayerParameters llParameters, const CS101_AppLayerParameters alParameters, IEC60870_LinkLayerMode linkLayerMode)
  230. {
  231. return CS101_Master_createEx(serialPort, llParameters, alParameters, linkLayerMode, CS101_MAX_QUEUE_SIZE);
  232. }
  233. LinkLayerParameters
  234. CS101_Master_getLinkLayerParameters(CS101_Master self)
  235. {
  236. return &(self->linkLayerParameters);
  237. }
  238. void
  239. CS101_Master_setASDUReceivedHandler(CS101_Master self, CS101_ASDUReceivedHandler handler, void* parameter)
  240. {
  241. self->asduReceivedHandler = handler;
  242. self->asduReceivedHandlerParameter = parameter;
  243. }
  244. void
  245. CS101_Master_setLinkLayerStateChanged(CS101_Master self, IEC60870_LinkLayerStateChangedHandler handler, void* parameter)
  246. {
  247. if (self->linkLayerMode == IEC60870_LINK_LAYER_BALANCED) {
  248. LinkLayerBalanced_setStateChangeHandler(self->balancedLinkLayer, handler, parameter);
  249. }
  250. else {
  251. LinkLayerPrimaryUnbalanced_setStateChangeHandler(self->unbalancedLinkLayer, handler, parameter);
  252. }
  253. }
  254. void
  255. CS101_Master_setRawMessageHandler(CS101_Master self, IEC60870_RawMessageHandler handler, void* parameter)
  256. {
  257. SerialTransceiverFT12_setRawMessageHandler(self->transceiver, handler, parameter);
  258. }
  259. void
  260. CS101_Master_addSlave(CS101_Master self, int address)
  261. {
  262. if (self->unbalancedLinkLayer)
  263. LinkLayerPrimaryUnbalanced_addSlaveConnection(self->unbalancedLinkLayer, address);
  264. }
  265. void
  266. CS101_Master_pollSingleSlave(CS101_Master self, int address)
  267. {
  268. if (self->unbalancedLinkLayer) {
  269. LinkLayerPrimaryUnbalanced_requestClass2Data(self->unbalancedLinkLayer, address);
  270. }
  271. }
  272. void
  273. CS101_Master_run(CS101_Master self)
  274. {
  275. if (self->unbalancedLinkLayer) {
  276. LinkLayerPrimaryUnbalanced_run(self->unbalancedLinkLayer);
  277. }
  278. else {
  279. LinkLayerBalanced_run(self->balancedLinkLayer);
  280. }
  281. }