cs101_asdu.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. #include "iec_include.h"
  2. typedef struct sASDUFrame* ASDUFrame;
  3. struct sASDUFrame {
  4. FrameVFT virtualFunctionTable;
  5. CS101_ASDU asdu;
  6. };
  7. static void
  8. asduFrame_destroy(Frame self)
  9. {
  10. UNUSED_PARAMETER(self);
  11. }
  12. static void
  13. asduFrame_setNextByte(Frame self, uint8_t byte)
  14. {
  15. ASDUFrame frame = (ASDUFrame) self;
  16. frame->asdu->payload[frame->asdu->payloadSize++] = byte;
  17. }
  18. static void
  19. asduFrame_appendBytes(Frame self, const uint8_t* bytes, int numberOfBytes)
  20. {
  21. ASDUFrame frame = (ASDUFrame) self;
  22. uint8_t* target = frame->asdu->payload + frame->asdu->payloadSize;
  23. int i;
  24. for (i = 0; i < numberOfBytes; i++)
  25. target[i] = bytes[i];
  26. frame->asdu->payloadSize += numberOfBytes;
  27. }
  28. static int
  29. asduFrame_getSpaceLeft(Frame self)
  30. {
  31. ASDUFrame frame = (ASDUFrame) self;
  32. return (frame->asdu->parameters->maxSizeOfASDU - frame->asdu->payloadSize - frame->asdu->asduHeaderLength);
  33. }
  34. struct sFrameVFT asduFrameVFT = {
  35. asduFrame_destroy,
  36. NULL,
  37. asduFrame_setNextByte,
  38. asduFrame_appendBytes,
  39. NULL,
  40. NULL,
  41. asduFrame_getSpaceLeft
  42. };
  43. CS101_ASDU
  44. CS101_ASDU_create(CS101_AppLayerParameters parameters, bool isSequence, CS101_CauseOfTransmission cot, int oa, int ca,
  45. bool isTest, bool isNegative)
  46. {
  47. CS101_StaticASDU self = (CS101_StaticASDU) GLOBAL_MALLOC(sizeof(sCS101_StaticASDU));
  48. if (self != NULL)
  49. CS101_ASDU_initializeStatic(self, parameters, isSequence, cot, oa, ca, isTest, isNegative);
  50. return (CS101_ASDU) self;
  51. }
  52. CS101_ASDU
  53. CS101_ASDU_clone(CS101_ASDU self, CS101_StaticASDU clone)
  54. {
  55. if (clone == NULL) {
  56. clone = (CS101_StaticASDU) GLOBAL_MALLOC(sizeof(sCS101_StaticASDU));
  57. }
  58. if (clone) {
  59. CS101_ASDU_initializeStatic(clone, self->parameters, CS101_ASDU_isSequence(self),
  60. CS101_ASDU_getCOT(self), CS101_ASDU_getOA(self), CS101_ASDU_getCA(self), CS101_ASDU_isTest(self), CS101_ASDU_isNegative(self));
  61. uint8_t* payload = CS101_ASDU_getPayload(self);
  62. int payloadSize = CS101_ASDU_getPayloadSize(self);
  63. CS101_ASDU_setTypeID((CS101_ASDU)clone, CS101_ASDU_getTypeID(self));
  64. CS101_ASDU_setNumberOfElements((CS101_ASDU)clone, CS101_ASDU_getNumberOfElements(self));
  65. CS101_ASDU_addPayload((CS101_ASDU)clone, payload, payloadSize);
  66. }
  67. return (CS101_ASDU) clone;
  68. }
  69. CS101_ASDU
  70. CS101_ASDU_initializeStatic(CS101_StaticASDU self, CS101_AppLayerParameters parameters, bool isSequence, CS101_CauseOfTransmission cot, int oa, int ca,
  71. bool isTest, bool isNegative)
  72. {
  73. int asduHeaderLength = 2 + parameters->sizeOfCOT + parameters->sizeOfCA;
  74. self->encodedData[0] = (uint8_t) 0;
  75. if (isSequence)
  76. self->encodedData[1] = 0x80;
  77. else
  78. self->encodedData[1] = 0;
  79. self->encodedData[2] = (uint8_t) (cot & 0x3f);
  80. if (isTest)
  81. self->encodedData[2] |= 0x80;
  82. if (isNegative)
  83. self->encodedData[2] |= 0x40;
  84. int caIndex;
  85. if (parameters->sizeOfCOT > 1) {
  86. self->encodedData[3] = (uint8_t) oa;
  87. caIndex = 4;
  88. }
  89. else
  90. caIndex = 3;
  91. self->encodedData[caIndex] = ca % 0x100;
  92. if (parameters->sizeOfCA > 1)
  93. self->encodedData[caIndex + 1] = ca / 0x100;
  94. self->asdu = self->encodedData;
  95. self->asduHeaderLength = asduHeaderLength;
  96. self->payload = self->encodedData + asduHeaderLength;
  97. self->payloadSize = 0;
  98. self->parameters = parameters;
  99. return (CS101_ASDU) self;
  100. }
  101. void
  102. CS101_ASDU_destroy(CS101_ASDU self)
  103. {
  104. GLOBAL_FREEMEM(self);
  105. }
  106. void
  107. CS101_ASDU_encode(CS101_ASDU self, Frame frame)
  108. {
  109. Frame_appendBytes(frame, self->asdu, self->asduHeaderLength + self->payloadSize);
  110. }
  111. CS101_ASDU
  112. CS101_ASDU_createFromBuffer(CS101_AppLayerParameters parameters, uint8_t* msg, int msgLength)
  113. {
  114. int asduHeaderLength = 2 + parameters->sizeOfCOT + parameters->sizeOfCA;
  115. if (msgLength < asduHeaderLength)
  116. return NULL;
  117. CS101_ASDU self = (CS101_ASDU) GLOBAL_MALLOC(sizeof(struct sCS101_ASDU));
  118. if (self != NULL) {
  119. self->parameters = parameters;
  120. self->asdu = msg;
  121. self->asduHeaderLength = asduHeaderLength;
  122. self->payload = msg + asduHeaderLength;
  123. self->payloadSize = msgLength - asduHeaderLength;
  124. }
  125. return self;
  126. }
  127. uint8_t*
  128. CS101_ASDU_getPayload(CS101_ASDU self)
  129. {
  130. return self->payload;
  131. }
  132. int
  133. CS101_ASDU_getPayloadSize(CS101_ASDU self)
  134. {
  135. return self->payloadSize;
  136. }
  137. bool
  138. CS101_ASDU_addPayload(CS101_ASDU self, uint8_t* buffer, int size)
  139. {
  140. if (buffer == NULL)
  141. return false;
  142. if (self->payloadSize + self->asduHeaderLength + size <= 256) {
  143. memcpy(self->payload + self->payloadSize, buffer, size);
  144. self->payloadSize += size;
  145. return true;
  146. }
  147. else
  148. return false;
  149. }
  150. static int
  151. getFirstIOA(CS101_ASDU self)
  152. {
  153. int startIndex = self->asduHeaderLength;
  154. int ioa = self->asdu[startIndex];
  155. if (self->parameters->sizeOfIOA > 1)
  156. ioa += (self->asdu [startIndex + 1] * 0x100);
  157. if (self->parameters->sizeOfIOA > 2)
  158. ioa += (self->asdu [startIndex + 2] * 0x10000);
  159. return ioa;
  160. }
  161. bool
  162. CS101_ASDU_addInformationObject(CS101_ASDU self, InformationObject io)
  163. {
  164. struct sASDUFrame asduFrame = {
  165. &asduFrameVFT,
  166. self
  167. };
  168. bool encoded = false;
  169. int numberOfElements = CS101_ASDU_getNumberOfElements(self);
  170. if (numberOfElements == 0) {
  171. self->asdu[0] = (uint8_t) InformationObject_getType(io);
  172. encoded = InformationObject_encode(io, (Frame) &asduFrame, self->parameters, false);
  173. }
  174. else if (numberOfElements < 0x7f) {
  175. /* Check if type of information object is matching ASDU type */
  176. if (self->asdu[0] == (uint8_t) InformationObject_getType(io)) {
  177. if (CS101_ASDU_isSequence(self)) {
  178. /* check that new information object has correct IOA */
  179. if (InformationObject_getObjectAddress(io) == (getFirstIOA(self) + CS101_ASDU_getNumberOfElements(self)))
  180. encoded = InformationObject_encode(io, (Frame) &asduFrame, self->parameters, true);
  181. else
  182. encoded = false;
  183. }
  184. else {
  185. encoded = InformationObject_encode(io, (Frame) &asduFrame, self->parameters, false);;
  186. }
  187. }
  188. }
  189. if (encoded)
  190. self->asdu[1]++; /* increase number of elements in VSQ */
  191. return encoded;
  192. }
  193. void
  194. CS101_ASDU_removeAllElements(CS101_ASDU self)
  195. {
  196. self->asdu[1] = (self->asdu[1] & 0x80);
  197. self->payloadSize = 0;
  198. }
  199. bool
  200. CS101_ASDU_isTest(CS101_ASDU self)
  201. {
  202. if ((self->asdu[2] & 0x80) == 0x80)
  203. return true;
  204. else
  205. return false;
  206. }
  207. void
  208. CS101_ASDU_setTest(CS101_ASDU self, bool value)
  209. {
  210. if (value)
  211. self->asdu[2] |= 0x80;
  212. else
  213. self->asdu[2] &= ~(0x80);
  214. }
  215. bool
  216. CS101_ASDU_isNegative(CS101_ASDU self)
  217. {
  218. if ((self->asdu[2] & 0x40) == 0x40)
  219. return true;
  220. else
  221. return false;
  222. }
  223. void
  224. CS101_ASDU_setNegative(CS101_ASDU self, bool value)
  225. {
  226. if (value)
  227. self->asdu[2] |= 0x40;
  228. else
  229. self->asdu[2] &= ~(0x40);
  230. }
  231. int
  232. CS101_ASDU_getOA(CS101_ASDU self)
  233. {
  234. if (self->parameters->sizeOfCOT < 2)
  235. return -1;
  236. else
  237. return (int) self->asdu[3];
  238. }
  239. CS101_CauseOfTransmission
  240. CS101_ASDU_getCOT(CS101_ASDU self)
  241. {
  242. return (CS101_CauseOfTransmission) (self->asdu[2] & 0x3f);
  243. }
  244. void
  245. CS101_ASDU_setCOT(CS101_ASDU self, CS101_CauseOfTransmission value)
  246. {
  247. uint8_t cot = self->asdu[2] & 0xc0;
  248. cot += ((int) value) & 0x3f;
  249. self->asdu[2] = cot;
  250. }
  251. int
  252. CS101_ASDU_getCA(CS101_ASDU self)
  253. {
  254. int caIndex = 2 + self->parameters->sizeOfCOT;
  255. int ca = self->asdu[caIndex];
  256. if (self->parameters->sizeOfCA > 1)
  257. ca += (self->asdu[caIndex + 1] * 0x100);
  258. return ca;
  259. }
  260. void
  261. CS101_ASDU_setCA(CS101_ASDU self, int ca)
  262. {
  263. int caIndex = 2 + self->parameters->sizeOfCOT;
  264. int setCa = ca;
  265. /* Check if CA is in range and adjust if not */
  266. if (ca < 0)
  267. setCa = 0;
  268. else {
  269. if (self->parameters->sizeOfCA == 1) {
  270. if (ca > 255)
  271. setCa = 255;
  272. }
  273. else if (self->parameters->sizeOfCA > 1) {
  274. if (ca > 65535)
  275. setCa = 65535;
  276. }
  277. }
  278. if (self->parameters->sizeOfCA == 1) {
  279. self->asdu[caIndex] = (uint8_t) setCa;
  280. }
  281. else {
  282. self->asdu[caIndex] = (uint8_t) (setCa % 0x100);
  283. self->asdu[caIndex + 1] = (uint8_t) (setCa / 0x100);
  284. }
  285. }
  286. IEC60870_5_TypeID
  287. CS101_ASDU_getTypeID(CS101_ASDU self)
  288. {
  289. return (TypeID) (self->asdu[0]);
  290. }
  291. void
  292. CS101_ASDU_setTypeID(CS101_ASDU self, IEC60870_5_TypeID typeId)
  293. {
  294. self->asdu[0] = (uint8_t) typeId;
  295. }
  296. bool
  297. CS101_ASDU_isSequence(CS101_ASDU self)
  298. {
  299. if ((self->asdu[1] & 0x80) != 0)
  300. return true;
  301. else
  302. return false;
  303. }
  304. void
  305. CS101_ASDU_setSequence(CS101_ASDU self, bool isSequence)
  306. {
  307. if (isSequence)
  308. self->asdu[1] |= 0x80;
  309. else
  310. self->asdu[1] &= 0x7f;
  311. }
  312. int
  313. CS101_ASDU_getNumberOfElements(CS101_ASDU self)
  314. {
  315. return (self->asdu[1] & 0x7f);
  316. }
  317. void
  318. CS101_ASDU_setNumberOfElements(CS101_ASDU self, int numberOfElements)
  319. {
  320. self->asdu[1] &= 0x80;
  321. self->asdu[1] |= ((uint8_t) numberOfElements) & 0x7f;
  322. }
  323. InformationObject
  324. CS101_ASDU_getElement(CS101_ASDU self, int index)
  325. {
  326. return CS101_ASDU_getElementEx(self, NULL, index);
  327. }
  328. InformationObject
  329. CS101_ASDU_getElementEx(CS101_ASDU self, InformationObject io, int index)
  330. {
  331. InformationObject retVal = NULL;
  332. int elementSize;
  333. switch (CS101_ASDU_getTypeID(self)) {
  334. case M_SP_NA_1: /* 1 */
  335. elementSize = 1;
  336. if (CS101_ASDU_isSequence(self)) {
  337. retVal = (InformationObject) SinglePointInformation_getFromBuffer((SinglePointInformation) io, self->parameters,
  338. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  339. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  340. }
  341. else
  342. retVal = (InformationObject) SinglePointInformation_getFromBuffer((SinglePointInformation) io, self->parameters,
  343. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  344. break;
  345. case M_SP_TA_1: /* 2 */
  346. elementSize = 4;
  347. if (CS101_ASDU_isSequence(self)) {
  348. retVal = (InformationObject) SinglePointWithCP24Time2a_getFromBuffer((SinglePointWithCP24Time2a) io, self->parameters,
  349. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  350. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  351. }
  352. else
  353. retVal = (InformationObject) SinglePointWithCP24Time2a_getFromBuffer((SinglePointWithCP24Time2a) io, self->parameters,
  354. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  355. break;
  356. case M_DP_NA_1: /* 3 */
  357. elementSize = 1;
  358. if (CS101_ASDU_isSequence(self)) {
  359. retVal = (InformationObject) DoublePointInformation_getFromBuffer((DoublePointInformation) io, self->parameters,
  360. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  361. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  362. }
  363. else
  364. retVal = (InformationObject) DoublePointInformation_getFromBuffer((DoublePointInformation) io, self->parameters,
  365. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  366. break;
  367. case M_DP_TA_1: /* 4 */
  368. elementSize = 4;
  369. if (CS101_ASDU_isSequence(self)) {
  370. retVal = (InformationObject) DoublePointWithCP24Time2a_getFromBuffer((DoublePointWithCP24Time2a) io, self->parameters,
  371. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  372. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  373. }
  374. else
  375. retVal = (InformationObject) DoublePointWithCP24Time2a_getFromBuffer((DoublePointWithCP24Time2a) io, self->parameters,
  376. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  377. break;
  378. case M_ST_NA_1: /* 5 */
  379. elementSize = 2;
  380. if (CS101_ASDU_isSequence(self)) {
  381. retVal = (InformationObject) StepPositionInformation_getFromBuffer((StepPositionInformation) io, self->parameters,
  382. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  383. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  384. }
  385. else
  386. retVal = (InformationObject) StepPositionInformation_getFromBuffer((StepPositionInformation) io, self->parameters,
  387. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  388. break;
  389. case M_ST_TA_1: /* 6 */
  390. elementSize = 5;
  391. if (CS101_ASDU_isSequence(self)) {
  392. retVal = (InformationObject) StepPositionWithCP24Time2a_getFromBuffer((StepPositionWithCP24Time2a) io, self->parameters,
  393. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  394. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  395. }
  396. else
  397. retVal = (InformationObject) StepPositionWithCP24Time2a_getFromBuffer((StepPositionWithCP24Time2a) io, self->parameters,
  398. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  399. break;
  400. case M_BO_NA_1: /* 7 */
  401. elementSize = 5;
  402. if (CS101_ASDU_isSequence(self)) {
  403. retVal = (InformationObject) BitString32_getFromBuffer((BitString32) io, self->parameters,
  404. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  405. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  406. }
  407. else
  408. retVal = (InformationObject) BitString32_getFromBuffer((BitString32) io, self->parameters,
  409. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  410. break;
  411. case M_BO_TA_1: /* 8 */
  412. elementSize = 8;
  413. if (CS101_ASDU_isSequence(self)) {
  414. retVal = (InformationObject) Bitstring32WithCP24Time2a_getFromBuffer((Bitstring32WithCP24Time2a) io, self->parameters,
  415. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  416. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  417. }
  418. else
  419. retVal = (InformationObject) Bitstring32WithCP24Time2a_getFromBuffer((Bitstring32WithCP24Time2a) io, self->parameters,
  420. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  421. break;
  422. case M_ME_NA_1: /* 9 */
  423. elementSize = 3;
  424. if (CS101_ASDU_isSequence(self)) {
  425. retVal = (InformationObject) MeasuredValueNormalized_getFromBuffer((MeasuredValueNormalized) io, self->parameters,
  426. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  427. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  428. }
  429. else
  430. retVal = (InformationObject) MeasuredValueNormalized_getFromBuffer((MeasuredValueNormalized) io, self->parameters,
  431. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  432. break;
  433. case M_ME_TA_1: /* 10 */
  434. elementSize = 6;
  435. if (CS101_ASDU_isSequence(self)) {
  436. retVal = (InformationObject) MeasuredValueNormalizedWithCP24Time2a_getFromBuffer((MeasuredValueNormalizedWithCP24Time2a) io, self->parameters,
  437. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  438. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  439. }
  440. else
  441. retVal = (InformationObject) MeasuredValueNormalizedWithCP24Time2a_getFromBuffer((MeasuredValueNormalizedWithCP24Time2a) io, self->parameters,
  442. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  443. break;
  444. case M_ME_NB_1: /* 11 */
  445. elementSize = 3;
  446. if (CS101_ASDU_isSequence(self)) {
  447. retVal = (InformationObject) MeasuredValueScaled_getFromBuffer((MeasuredValueScaled) io, self->parameters,
  448. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  449. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  450. }
  451. else
  452. retVal = (InformationObject) MeasuredValueScaled_getFromBuffer((MeasuredValueScaled) io, self->parameters,
  453. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  454. break;
  455. case M_ME_TB_1: /* 12 */
  456. elementSize = 6;
  457. if (CS101_ASDU_isSequence(self)) {
  458. retVal = (InformationObject) MeasuredValueScaledWithCP24Time2a_getFromBuffer((MeasuredValueScaledWithCP24Time2a) io, self->parameters,
  459. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  460. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  461. }
  462. else
  463. retVal = (InformationObject) MeasuredValueScaledWithCP24Time2a_getFromBuffer((MeasuredValueScaledWithCP24Time2a) io, self->parameters,
  464. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  465. break;
  466. case M_ME_NC_1: /* 13 */
  467. elementSize = 5;
  468. if (CS101_ASDU_isSequence(self)) {
  469. retVal = (InformationObject) MeasuredValueShort_getFromBuffer((MeasuredValueShort) io, self->parameters,
  470. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  471. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  472. }
  473. else
  474. retVal = (InformationObject) MeasuredValueShort_getFromBuffer((MeasuredValueShort) io, self->parameters,
  475. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  476. break;
  477. case M_ME_TC_1: /* 14 */
  478. elementSize = 8;
  479. if (CS101_ASDU_isSequence(self)) {
  480. retVal = (InformationObject) MeasuredValueShortWithCP24Time2a_getFromBuffer((MeasuredValueShortWithCP24Time2a) io, self->parameters,
  481. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  482. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  483. }
  484. else
  485. retVal = (InformationObject) MeasuredValueShortWithCP24Time2a_getFromBuffer((MeasuredValueShortWithCP24Time2a) io, self->parameters,
  486. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  487. break;
  488. case M_IT_NA_1: /* 15 */
  489. elementSize = 5;
  490. if (CS101_ASDU_isSequence(self)) {
  491. retVal = (InformationObject) IntegratedTotals_getFromBuffer((IntegratedTotals) io, self->parameters,
  492. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  493. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  494. }
  495. else
  496. retVal = (InformationObject) IntegratedTotals_getFromBuffer((IntegratedTotals) io, self->parameters,
  497. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  498. break;
  499. case M_IT_TA_1: /* 16 */
  500. elementSize = 8;
  501. if (CS101_ASDU_isSequence(self)) {
  502. retVal = (InformationObject) IntegratedTotalsWithCP24Time2a_getFromBuffer((IntegratedTotalsWithCP24Time2a) io, self->parameters,
  503. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  504. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  505. }
  506. else
  507. retVal = (InformationObject) IntegratedTotalsWithCP24Time2a_getFromBuffer((IntegratedTotalsWithCP24Time2a) io, self->parameters,
  508. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  509. break;
  510. case M_EP_TA_1: /* 17 */
  511. elementSize = 6;
  512. if (CS101_ASDU_isSequence(self)) {
  513. retVal = (InformationObject) EventOfProtectionEquipment_getFromBuffer((EventOfProtectionEquipment) io, self->parameters,
  514. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  515. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  516. }
  517. else
  518. retVal = (InformationObject) EventOfProtectionEquipment_getFromBuffer((EventOfProtectionEquipment) io, self->parameters,
  519. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  520. break;
  521. case M_EP_TB_1: /* 18 */
  522. elementSize = 7;
  523. if (CS101_ASDU_isSequence(self)) {
  524. retVal = (InformationObject) PackedStartEventsOfProtectionEquipment_getFromBuffer((PackedStartEventsOfProtectionEquipment) io, self->parameters,
  525. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  526. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  527. }
  528. else
  529. retVal = (InformationObject) PackedStartEventsOfProtectionEquipment_getFromBuffer((PackedStartEventsOfProtectionEquipment) io, self->parameters,
  530. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  531. break;
  532. case M_EP_TC_1: /* 19 */
  533. elementSize = 7;
  534. if (CS101_ASDU_isSequence(self)) {
  535. retVal = (InformationObject) PackedOutputCircuitInfo_getFromBuffer((PackedOutputCircuitInfo) io, self->parameters,
  536. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  537. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  538. }
  539. else
  540. retVal = (InformationObject) PackedOutputCircuitInfo_getFromBuffer((PackedOutputCircuitInfo) io, self->parameters,
  541. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  542. break;
  543. case M_PS_NA_1: /* 20 */
  544. elementSize = 5;
  545. if (CS101_ASDU_isSequence(self)) {
  546. retVal = (InformationObject) PackedSinglePointWithSCD_getFromBuffer((PackedSinglePointWithSCD) io, self->parameters,
  547. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  548. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  549. }
  550. else
  551. retVal = (InformationObject) PackedSinglePointWithSCD_getFromBuffer((PackedSinglePointWithSCD) io, self->parameters,
  552. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  553. break;
  554. case M_ME_ND_1: /* 21 */
  555. elementSize = 2;
  556. if (CS101_ASDU_isSequence(self)) {
  557. retVal = (InformationObject) MeasuredValueNormalizedWithoutQuality_getFromBuffer((MeasuredValueNormalizedWithoutQuality) io, self->parameters,
  558. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  559. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  560. }
  561. else
  562. retVal = (InformationObject) MeasuredValueNormalizedWithoutQuality_getFromBuffer((MeasuredValueNormalizedWithoutQuality) io, self->parameters,
  563. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  564. break;
  565. case M_SP_TB_1: /* 30 */
  566. elementSize = 8;
  567. if (CS101_ASDU_isSequence(self)) {
  568. retVal = (InformationObject) SinglePointWithCP56Time2a_getFromBuffer((SinglePointWithCP56Time2a) io, self->parameters,
  569. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  570. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  571. }
  572. else
  573. retVal = (InformationObject) SinglePointWithCP56Time2a_getFromBuffer((SinglePointWithCP56Time2a) io, self->parameters,
  574. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  575. break;
  576. case M_DP_TB_1: /* 31 */
  577. elementSize = 8;
  578. if (CS101_ASDU_isSequence(self)) {
  579. retVal = (InformationObject) DoublePointWithCP56Time2a_getFromBuffer((DoublePointWithCP56Time2a) io, self->parameters,
  580. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  581. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  582. }
  583. else
  584. retVal = (InformationObject) DoublePointWithCP56Time2a_getFromBuffer((DoublePointWithCP56Time2a) io, self->parameters,
  585. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  586. break;
  587. case M_ST_TB_1: /* 32 */
  588. elementSize = 9;
  589. if (CS101_ASDU_isSequence(self)) {
  590. retVal = (InformationObject) StepPositionWithCP56Time2a_getFromBuffer((StepPositionWithCP56Time2a) io, self->parameters,
  591. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  592. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  593. }
  594. else
  595. retVal = (InformationObject) StepPositionWithCP56Time2a_getFromBuffer((StepPositionWithCP56Time2a) io, self->parameters,
  596. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  597. break;
  598. case M_BO_TB_1: /* 33 */
  599. elementSize = 12;
  600. if (CS101_ASDU_isSequence(self)) {
  601. retVal = (InformationObject) Bitstring32WithCP56Time2a_getFromBuffer((Bitstring32WithCP56Time2a) io, self->parameters,
  602. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  603. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  604. }
  605. else
  606. retVal = (InformationObject) Bitstring32WithCP56Time2a_getFromBuffer((Bitstring32WithCP56Time2a) io, self->parameters,
  607. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  608. break;
  609. case M_ME_TD_1: /* 34 */
  610. elementSize = 10;
  611. if (CS101_ASDU_isSequence(self)) {
  612. retVal = (InformationObject) MeasuredValueNormalizedWithCP56Time2a_getFromBuffer((MeasuredValueNormalizedWithCP56Time2a) io, self->parameters,
  613. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  614. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  615. }
  616. else
  617. retVal = (InformationObject) MeasuredValueNormalizedWithCP56Time2a_getFromBuffer((MeasuredValueNormalizedWithCP56Time2a) io, self->parameters,
  618. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  619. break;
  620. case M_ME_TE_1: /* 35 */
  621. elementSize = 10;
  622. if (CS101_ASDU_isSequence(self)) {
  623. retVal = (InformationObject) MeasuredValueScaledWithCP56Time2a_getFromBuffer((MeasuredValueScaledWithCP56Time2a) io, self->parameters,
  624. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  625. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  626. }
  627. else
  628. retVal = (InformationObject) MeasuredValueScaledWithCP56Time2a_getFromBuffer((MeasuredValueScaledWithCP56Time2a) io, self->parameters,
  629. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  630. break;
  631. case M_ME_TF_1: /* 36 */
  632. elementSize = 12;
  633. if (CS101_ASDU_isSequence(self)) {
  634. retVal = (InformationObject) MeasuredValueShortWithCP56Time2a_getFromBuffer((MeasuredValueShortWithCP56Time2a) io, self->parameters,
  635. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  636. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  637. }
  638. else
  639. retVal = (InformationObject) MeasuredValueShortWithCP56Time2a_getFromBuffer((MeasuredValueShortWithCP56Time2a) io, self->parameters,
  640. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  641. break;
  642. case M_IT_TB_1: /* 37 */
  643. elementSize = 12;
  644. if (CS101_ASDU_isSequence(self)) {
  645. retVal = (InformationObject) IntegratedTotalsWithCP56Time2a_getFromBuffer((IntegratedTotalsWithCP56Time2a) io, self->parameters,
  646. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  647. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  648. }
  649. else
  650. retVal = (InformationObject) IntegratedTotalsWithCP56Time2a_getFromBuffer((IntegratedTotalsWithCP56Time2a) io, self->parameters,
  651. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  652. break;
  653. case M_EP_TD_1: /* 38 */
  654. elementSize = 10;
  655. if (CS101_ASDU_isSequence(self)) {
  656. retVal = (InformationObject) EventOfProtectionEquipmentWithCP56Time2a_getFromBuffer((EventOfProtectionEquipmentWithCP56Time2a) io, self->parameters,
  657. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  658. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  659. }
  660. else
  661. retVal = (InformationObject) EventOfProtectionEquipmentWithCP56Time2a_getFromBuffer((EventOfProtectionEquipmentWithCP56Time2a) io, self->parameters,
  662. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  663. break;
  664. case M_EP_TE_1: /* 39 */
  665. elementSize = 11;
  666. if (CS101_ASDU_isSequence(self)) {
  667. retVal = (InformationObject) PackedStartEventsOfProtectionEquipmentWithCP56Time2a_getFromBuffer((PackedStartEventsOfProtectionEquipmentWithCP56Time2a) io, self->parameters,
  668. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  669. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  670. }
  671. else
  672. retVal = (InformationObject) PackedStartEventsOfProtectionEquipmentWithCP56Time2a_getFromBuffer((PackedStartEventsOfProtectionEquipmentWithCP56Time2a) io, self->parameters,
  673. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  674. break;
  675. case M_EP_TF_1: /* 40 */
  676. elementSize = 11;
  677. if (CS101_ASDU_isSequence(self)) {
  678. retVal = (InformationObject) PackedOutputCircuitInfoWithCP56Time2a_getFromBuffer((PackedOutputCircuitInfoWithCP56Time2a) io, self->parameters,
  679. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  680. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  681. }
  682. else
  683. retVal = (InformationObject) PackedOutputCircuitInfoWithCP56Time2a_getFromBuffer((PackedOutputCircuitInfoWithCP56Time2a) io, self->parameters,
  684. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  685. break;
  686. /* 41 - 44 reserved */
  687. case C_SC_NA_1: /* 45 */
  688. elementSize = self->parameters->sizeOfIOA + 1;
  689. retVal = (InformationObject) SingleCommand_getFromBuffer((SingleCommand) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  690. break;
  691. case C_DC_NA_1: /* 46 */
  692. elementSize = self->parameters->sizeOfIOA + 1;
  693. retVal = (InformationObject) DoubleCommand_getFromBuffer((DoubleCommand) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  694. break;
  695. case C_RC_NA_1: /* 47 */
  696. elementSize = self->parameters->sizeOfIOA + 1;
  697. retVal = (InformationObject) StepCommand_getFromBuffer((StepCommand) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  698. break;
  699. case C_SE_NA_1: /* 48 - Set-point command, normalized value */
  700. elementSize = self->parameters->sizeOfIOA + 3;
  701. retVal = (InformationObject) SetpointCommandNormalized_getFromBuffer((SetpointCommandNormalized) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  702. break;
  703. case C_SE_NB_1: /* 49 - Set-point command, scaled value */
  704. elementSize = self->parameters->sizeOfIOA + 3;
  705. retVal = (InformationObject) SetpointCommandScaled_getFromBuffer((SetpointCommandScaled) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  706. break;
  707. case C_SE_NC_1: /* 50 - Set-point command, short floating point number */
  708. elementSize = self->parameters->sizeOfIOA + 5;
  709. retVal = (InformationObject) SetpointCommandShort_getFromBuffer((SetpointCommandShort) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  710. break;
  711. case C_BO_NA_1: /* 51 - Bitstring command */
  712. elementSize = self->parameters->sizeOfIOA + 4;
  713. retVal = (InformationObject) Bitstring32Command_getFromBuffer((Bitstring32Command) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  714. break;
  715. /* 52 - 57 reserved */
  716. case C_SC_TA_1: /* 58 - Single command with CP56Time2a */
  717. elementSize = self->parameters->sizeOfIOA + 8;
  718. retVal = (InformationObject) SingleCommandWithCP56Time2a_getFromBuffer((SingleCommandWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  719. break;
  720. case C_DC_TA_1: /* 59 - Double command with CP56Time2a */
  721. elementSize = self->parameters->sizeOfIOA + 8;
  722. retVal = (InformationObject) DoubleCommandWithCP56Time2a_getFromBuffer((DoubleCommandWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  723. break;
  724. case C_RC_TA_1: /* 60 - Step command with CP56Time2a */
  725. elementSize = self->parameters->sizeOfIOA + 8;
  726. retVal = (InformationObject) StepCommandWithCP56Time2a_getFromBuffer((StepCommandWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  727. break;
  728. case C_SE_TA_1: /* 61 - Setpoint command, normalized value with CP56Time2a */
  729. elementSize = self->parameters->sizeOfIOA + 10;
  730. retVal = (InformationObject) SetpointCommandNormalizedWithCP56Time2a_getFromBuffer((SetpointCommandNormalizedWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  731. break;
  732. case C_SE_TB_1: /* 62 - Setpoint command, scaled value with CP56Time2a */
  733. elementSize = self->parameters->sizeOfIOA + 10;
  734. retVal = (InformationObject) SetpointCommandScaledWithCP56Time2a_getFromBuffer((SetpointCommandScaledWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  735. break;
  736. case C_SE_TC_1: /* 63 - Setpoint command, short value with CP56Time2a */
  737. elementSize = self->parameters->sizeOfIOA + 12;
  738. retVal = (InformationObject) SetpointCommandShortWithCP56Time2a_getFromBuffer((SetpointCommandShortWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  739. break;
  740. case C_BO_TA_1: /* 64 - Bitstring command with CP56Time2a */
  741. elementSize = self->parameters->sizeOfIOA + 11;
  742. retVal = (InformationObject) Bitstring32CommandWithCP56Time2a_getFromBuffer((Bitstring32CommandWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  743. break;
  744. case M_EI_NA_1: /* 70 - End of Initialization */
  745. retVal = (InformationObject) EndOfInitialization_getFromBuffer((EndOfInitialization) io, self->parameters, self->payload, self->payloadSize, 0);
  746. break;
  747. case C_IC_NA_1: /* 100 - Interrogation command */
  748. retVal = (InformationObject) InterrogationCommand_getFromBuffer((InterrogationCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  749. break;
  750. case C_CI_NA_1: /* 101 - Counter interrogation command */
  751. retVal = (InformationObject) CounterInterrogationCommand_getFromBuffer((CounterInterrogationCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  752. break;
  753. case C_RD_NA_1: /* 102 - Read command */
  754. retVal = (InformationObject) ReadCommand_getFromBuffer((ReadCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  755. break;
  756. case C_CS_NA_1: /* 103 - Clock synchronization command */
  757. retVal = (InformationObject) ClockSynchronizationCommand_getFromBuffer((ClockSynchronizationCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  758. break;
  759. case C_TS_NA_1: /* 104 - Test command */
  760. retVal = (InformationObject) TestCommand_getFromBuffer((TestCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  761. break;
  762. case C_RP_NA_1: /* 105 - Reset process command */
  763. retVal = (InformationObject) ResetProcessCommand_getFromBuffer((ResetProcessCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  764. break;
  765. case C_CD_NA_1: /* 106 - Delay acquisition command */
  766. retVal = (InformationObject) DelayAcquisitionCommand_getFromBuffer((DelayAcquisitionCommand) io, self->parameters, self->payload, self->payloadSize, 0);
  767. break;
  768. case C_TS_TA_1: /* 107 - Test command with time */
  769. retVal = (InformationObject) TestCommandWithCP56Time2a_getFromBuffer((TestCommandWithCP56Time2a) io, self->parameters, self->payload, self->payloadSize, 0);
  770. break;
  771. case P_ME_NA_1: /* 110 - Parameter of measured values, normalized value */
  772. elementSize = self->parameters->sizeOfIOA + 3;
  773. retVal = (InformationObject) ParameterNormalizedValue_getFromBuffer((ParameterNormalizedValue) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  774. break;
  775. case P_ME_NB_1: /* 111 - Parameter of measured values, scaled value */
  776. elementSize = self->parameters->sizeOfIOA + 3;
  777. retVal = (InformationObject) ParameterScaledValue_getFromBuffer((ParameterScaledValue) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  778. break;
  779. case P_ME_NC_1: /* 112 - Parameter of measured values, short floating point number */
  780. elementSize = self->parameters->sizeOfIOA + 5;
  781. retVal = (InformationObject) ParameterFloatValue_getFromBuffer((ParameterFloatValue) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  782. break;
  783. case P_AC_NA_1: /* 113 - Parameter for activation */
  784. elementSize = self->parameters->sizeOfIOA + 1;
  785. retVal = (InformationObject) ParameterActivation_getFromBuffer((ParameterActivation) io, self->parameters, self->payload, self->payloadSize, index * elementSize);
  786. break;
  787. case F_FR_NA_1: /* 120 - File ready */
  788. retVal = (InformationObject) FileReady_getFromBuffer((FileReady) io, self->parameters, self->payload, self->payloadSize, 0);
  789. break;
  790. case F_SR_NA_1: /* 121 - Section ready */
  791. retVal = (InformationObject) SectionReady_getFromBuffer((SectionReady) io, self->parameters, self->payload, self->payloadSize, 0);
  792. break;
  793. case F_SC_NA_1: /* 122 - Call/Select directory/file/section */
  794. retVal = (InformationObject) FileCallOrSelect_getFromBuffer((FileCallOrSelect) io, self->parameters, self->payload, self->payloadSize, 0);
  795. break;
  796. case F_LS_NA_1: /* 123 - Last segment/section */
  797. retVal = (InformationObject) FileLastSegmentOrSection_getFromBuffer((FileLastSegmentOrSection) io, self->parameters, self->payload, self->payloadSize, 0);
  798. break;
  799. case F_AF_NA_1: /* 124 - ACK file/section */
  800. retVal = (InformationObject) FileACK_getFromBuffer((FileACK) io, self->parameters, self->payload, self->payloadSize, 0);
  801. break;
  802. case F_SG_NA_1: /* 125 - File segment */
  803. retVal = (InformationObject) FileSegment_getFromBuffer((FileSegment) io, self->parameters, self->payload, self->payloadSize, 0);
  804. break;
  805. case F_DR_TA_1: /* 126 - File directory */
  806. elementSize = 13;
  807. if (CS101_ASDU_isSequence(self)) {
  808. retVal = (InformationObject) FileDirectory_getFromBuffer((FileDirectory) io, self->parameters,
  809. self->payload, self->payloadSize, self->parameters->sizeOfIOA + (index * elementSize), true);
  810. InformationObject_setObjectAddress(retVal, InformationObject_ParseObjectAddress(self->parameters, self->payload, 0) + index);
  811. }
  812. else
  813. retVal = (InformationObject) FileDirectory_getFromBuffer((FileDirectory) io, self->parameters,
  814. self->payload, self->payloadSize, index * (self->parameters->sizeOfIOA + elementSize), false);
  815. break;
  816. case F_SC_NB_1: /* 127 - QueryLog */
  817. retVal = (InformationObject) QueryLog_getFromBuffer((QueryLog) io, self->parameters, self->payload, self->payloadSize, 0);
  818. break;
  819. default:
  820. printf("type %d not supported\n", CS101_ASDU_getTypeID(self));
  821. break;
  822. }
  823. return retVal;
  824. }
  825. const char*
  826. TypeID_toString(TypeID self)
  827. {
  828. switch (self) {
  829. case M_SP_NA_1:
  830. return "M_SP_NA_1";
  831. case M_SP_TA_1:
  832. return "M_SP_TA_1";
  833. case M_DP_NA_1:
  834. return "M_DP_NA_1";
  835. case M_DP_TA_1:
  836. return "M_DP_TA_1";
  837. case M_ST_NA_1:
  838. return "M_ST_NA_1";
  839. case M_ST_TA_1:
  840. return "M_ST_TA_1";
  841. case M_BO_NA_1:
  842. return "M_BO_NA_1";
  843. case M_BO_TA_1:
  844. return "M_BO_TA_1";
  845. case M_ME_NA_1:
  846. return "M_ME_NA_1";
  847. case M_ME_TA_1:
  848. return "M_ME_TA_1";
  849. case M_ME_NB_1:
  850. return "M_ME_NB_1";
  851. case M_ME_TB_1:
  852. return "M_ME_TB_1";
  853. case M_ME_NC_1:
  854. return "M_ME_NC_1";
  855. case M_ME_TC_1:
  856. return "M_ME_TC_1";
  857. case M_IT_NA_1:
  858. return "M_IT_NA_1";
  859. case M_IT_TA_1:
  860. return "M_IT_TA_1";
  861. case M_EP_TA_1:
  862. return "M_EP_TA_1";
  863. case M_EP_TB_1:
  864. return "M_EP_TB_1";
  865. case M_EP_TC_1:
  866. return "M_EP_TC_1";
  867. case M_PS_NA_1:
  868. return "M_PS_NA_1";
  869. case M_ME_ND_1:
  870. return "M_ME_ND_1";
  871. case M_SP_TB_1:
  872. return "M_SP_TB_1";
  873. case M_DP_TB_1:
  874. return "M_DP_TB_1";
  875. case M_ST_TB_1:
  876. return "M_ST_TB_1";
  877. case M_BO_TB_1:
  878. return "M_BO_TB_1";
  879. case M_ME_TD_1:
  880. return "M_ME_TD_1";
  881. case M_ME_TE_1:
  882. return "M_ME_TE_1";
  883. case M_ME_TF_1:
  884. return "M_ME_TF_1";
  885. case M_IT_TB_1:
  886. return "M_IT_TB_1";
  887. case M_EP_TD_1:
  888. return "M_EP_TD_1";
  889. case M_EP_TE_1:
  890. return "M_EP_TE_1";
  891. case M_EP_TF_1:
  892. return "M_EP_TF_1";
  893. case C_SC_NA_1:
  894. return "C_SC_NA_1";
  895. case C_DC_NA_1:
  896. return "C_DC_NA_1";
  897. case C_RC_NA_1:
  898. return "C_RC_NA_1";
  899. case C_SE_NA_1:
  900. return "C_SE_NA_1";
  901. case C_SE_NB_1:
  902. return "C_SE_NB_1";
  903. case C_SE_NC_1:
  904. return "C_SE_NC_1";
  905. case C_BO_NA_1:
  906. return "C_BO_NA_1";
  907. case C_SC_TA_1:
  908. return "C_SC_TA_1";
  909. case C_DC_TA_1:
  910. return "C_DC_TA_1";
  911. case C_RC_TA_1:
  912. return "C_RC_TA_1";
  913. case C_SE_TA_1:
  914. return "C_SE_TA_1";
  915. case C_SE_TB_1:
  916. return "C_SE_TB_1";
  917. case C_SE_TC_1:
  918. return "C_SE_TC_1";
  919. case C_BO_TA_1:
  920. return "C_BO_TA_1";
  921. case M_EI_NA_1:
  922. return "M_EI_NA_1";
  923. case C_IC_NA_1:
  924. return "C_IC_NA_1";
  925. case C_CI_NA_1:
  926. return "C_CI_NA_1";
  927. case C_RD_NA_1:
  928. return "C_RD_NA_1";
  929. case C_CS_NA_1:
  930. return "C_CS_NA_1";
  931. case C_TS_NA_1:
  932. return "C_TS_NA_1";
  933. case C_RP_NA_1:
  934. return "C_RP_NA_1";
  935. case C_CD_NA_1:
  936. return "C_CD_NA_1";
  937. case C_TS_TA_1:
  938. return "C_TS_TA_1";
  939. case P_ME_NA_1:
  940. return "P_ME_NA_1";
  941. case P_ME_NB_1:
  942. return "P_ME_NB_1";
  943. case P_ME_NC_1:
  944. return "P_ME_NC_1";
  945. case P_AC_NA_1:
  946. return "P_AC_NA_1";
  947. case F_FR_NA_1:
  948. return "F_FR_NA_1";
  949. case F_SR_NA_1:
  950. return "F_SR_NA_1";
  951. case F_SC_NA_1:
  952. return "F_SC_NA_1";
  953. case F_LS_NA_1:
  954. return "F_LS_NA_1";
  955. case F_AF_NA_1:
  956. return "F_AF_NA_1";
  957. case F_SG_NA_1:
  958. return "F_SG_NA_1";
  959. case F_DR_TA_1:
  960. return "F_DR_TA_1";
  961. case F_SC_NB_1:
  962. return "F_SC_NB_1";
  963. default:
  964. return "unknown";
  965. }
  966. }
  967. const char*
  968. CS101_CauseOfTransmission_toString(CS101_CauseOfTransmission self)
  969. {
  970. switch (self) {
  971. case CS101_COT_PERIODIC:
  972. return "PERIODIC";
  973. case CS101_COT_BACKGROUND_SCAN:
  974. return "BACKGROUND_SCAN";
  975. case CS101_COT_SPONTANEOUS:
  976. return "SPONTANEOUS";
  977. case CS101_COT_INITIALIZED:
  978. return "INITIALIZED";
  979. case CS101_COT_REQUEST:
  980. return "REQUEST";
  981. case CS101_COT_ACTIVATION:
  982. return "ACTIVATION";
  983. case CS101_COT_ACTIVATION_CON:
  984. return "ACTIVATION_CON";
  985. case CS101_COT_DEACTIVATION:
  986. return "DEACTIVATION";
  987. case CS101_COT_DEACTIVATION_CON:
  988. return "DEACTIVATION_CON";
  989. case CS101_COT_ACTIVATION_TERMINATION:
  990. return "ACTIVATION_TERMINATION";
  991. case CS101_COT_RETURN_INFO_REMOTE:
  992. return "RETURN_INFO_REMOTE";
  993. case CS101_COT_RETURN_INFO_LOCAL:
  994. return "RETURN_INFO_LOCAL";
  995. case CS101_COT_FILE_TRANSFER:
  996. return "FILE_TRANSFER";
  997. case CS101_COT_AUTHENTICATION:
  998. return "AUTHENTICATION";
  999. case CS101_COT_MAINTENANCE_OF_AUTH_SESSION_KEY:
  1000. return "MAINTENANCE_OF_AUTH_SESSION_KEY";
  1001. case CS101_COT_MAINTENANCE_OF_USER_ROLE_AND_UPDATE_KEY:
  1002. return "MAINTENANCE_OF_USER_ROLE_AND_UPDATE_KEY";
  1003. case CS101_COT_INTERROGATED_BY_STATION:
  1004. return "INTERROGATED_BY_STATION";
  1005. case CS101_COT_INTERROGATED_BY_GROUP_1:
  1006. return "INTERROGATED_BY_GROUP_1";
  1007. case CS101_COT_INTERROGATED_BY_GROUP_2:
  1008. return "INTERROGATED_BY_GROUP_2";
  1009. case CS101_COT_INTERROGATED_BY_GROUP_3:
  1010. return "INTERROGATED_BY_GROUP_3";
  1011. case CS101_COT_INTERROGATED_BY_GROUP_4:
  1012. return "INTERROGATED_BY_GROUP_4";
  1013. case CS101_COT_INTERROGATED_BY_GROUP_5:
  1014. return "INTERROGATED_BY_GROUP_5";
  1015. case CS101_COT_INTERROGATED_BY_GROUP_6:
  1016. return "INTERROGATED_BY_GROUP_6";
  1017. case CS101_COT_INTERROGATED_BY_GROUP_7:
  1018. return "INTERROGATED_BY_GROUP_7";
  1019. case CS101_COT_INTERROGATED_BY_GROUP_8:
  1020. return "INTERROGATED_BY_GROUP_8";
  1021. case CS101_COT_INTERROGATED_BY_GROUP_9:
  1022. return "INTERROGATED_BY_GROUP_9";
  1023. case CS101_COT_INTERROGATED_BY_GROUP_10:
  1024. return "INTERROGATED_BY_GROUP_10";
  1025. case CS101_COT_INTERROGATED_BY_GROUP_11:
  1026. return "INTERROGATED_BY_GROUP_11";
  1027. case CS101_COT_INTERROGATED_BY_GROUP_12:
  1028. return "INTERROGATED_BY_GROUP_12";
  1029. case CS101_COT_INTERROGATED_BY_GROUP_13:
  1030. return "INTERROGATED_BY_GROUP_13";
  1031. case CS101_COT_INTERROGATED_BY_GROUP_14:
  1032. return "INTERROGATED_BY_GROUP_14";
  1033. case CS101_COT_INTERROGATED_BY_GROUP_15:
  1034. return "INTERROGATED_BY_GROUP_15";
  1035. case CS101_COT_INTERROGATED_BY_GROUP_16:
  1036. return "INTERROGATED_BY_GROUP_16";
  1037. case CS101_COT_REQUESTED_BY_GENERAL_COUNTER:
  1038. return "REQUESTED_BY_GENERAL_COUNTER";
  1039. case CS101_COT_REQUESTED_BY_GROUP_1_COUNTER:
  1040. return "REQUESTED_BY_GROUP_1_COUNTER";
  1041. case CS101_COT_REQUESTED_BY_GROUP_2_COUNTER:
  1042. return "REQUESTED_BY_GROUP_2_COUNTER";
  1043. case CS101_COT_REQUESTED_BY_GROUP_3_COUNTER:
  1044. return "REQUESTED_BY_GROUP_3_COUNTER";
  1045. case CS101_COT_REQUESTED_BY_GROUP_4_COUNTER:
  1046. return "REQUESTED_BY_GROUP_4_COUNTER";
  1047. case CS101_COT_UNKNOWN_TYPE_ID:
  1048. return "UNKNOWN_TYPE_ID";
  1049. case CS101_COT_UNKNOWN_COT:
  1050. return "UNKNOWN_CAUSE_OF_TRANSMISSION";
  1051. case CS101_COT_UNKNOWN_CA:
  1052. return "UNKNOWN_COMMON_ADDRESS_OF_ASDU";
  1053. case CS101_COT_UNKNOWN_IOA:
  1054. return "UNKNOWN_INFORMATION_OBJECT_ADDRESS";
  1055. default:
  1056. return "UNKNOWN_COT";
  1057. }
  1058. }