123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082 |
- #include "iec_include.h"
- #include "link_layer.h"
- #include "lib_memory.h"
- #include "link_layer_private.h"
- typedef struct sLinkLayerSlaveConnection* LinkLayerSlaveConnection;
- typedef struct sLinkLayerSecondaryBalanced* LinkLayerSecondaryBalanced;
- typedef struct sLinkLayerPrimaryBalanced* LinkLayerPrimaryBalanced;
- typedef struct sLinkLayerSecondaryUnbalanced* LL_Sec_Unb; /* short cut definition */
- struct sLinkLayerSecondaryBalanced {
- bool expectedFcb; /* expected value of next frame count bit (FCB) */
- LinkLayer linkLayer;
- IBalancedApplicationLayer applicationLayer;
- void* appLayerParam;
- };
- typedef enum {
- PLL_IDLE,
- PLL_EXECUTE_REQUEST_STATUS_OF_LINK,
- PLL_EXECUTE_RESET_REMOTE_LINK,
- PLL_LINK_LAYERS_AVAILABLE,
- PLL_EXECUTE_SERVICE_SEND_CONFIRM,
- PLL_EXECUTE_SERVICE_REQUEST_RESPOND,
- PLL_SECONDARY_LINK_LAYER_BUSY, /* Only required in balanced link layer */
- PLL_TIMEOUT /* only required in unbalanced link layer */
- } PrimaryLinkLayerState;
- struct sLinkLayerPrimaryBalanced {
- LinkLayerState state; /* state information for user */
- PrimaryLinkLayerState primaryState; /* internal PLL state machine state */
- bool waitingForResponse;
- uint64_t lastSendTime;
- uint64_t originalSendTime;
- bool sendLinkLayerTestFunction;
- bool nextFcb;
- int otherStationAddress;
- struct sBufferFrame lastSendAsdu;
- IBalancedApplicationLayer applicationLayer;
- void* applicationLayerParam;
- uint64_t lastReceivedMsg;
- int idleTimeout; /* connection timeout in ms */
- IEC60870_LinkLayerStateChangedHandler stateChangedHandler;
- void* stateChangedHandlerParameter;
- LinkLayer linkLayer;
- };
- struct sLinkLayerSlaveConnection {
- LinkLayerPrimaryUnbalanced primaryLink;
- LinkLayerState state; /* user visible state */
- int address;
- PrimaryLinkLayerState primaryState; /* internal PLL state machine state */
- bool hasMessageToSend; /* indicates if an app layer message is ready to be sent */
- struct sBufferFrame nextMessage;
- uint8_t buffer[256];
- uint64_t lastSendTime;
- uint64_t originalSendTime;
- bool requestClass1Data;
- bool requestClass2Data;
- bool dontSendMessages;
- bool waitingForResponse;
- bool sendLinkLayerTestFunction;
- bool nextFcb;
- };
- struct sLinkLayer {
- uint8_t buffer[261]; /* 261 = maximum FT1.2 frame length */
- uint8_t userDataBuffer[255];
- int address;
- SerialTransceiverFT12 transceiver;
- LinkLayerParameters linkLayerParameters;
- bool dir; /* DIR bit to be used when messages are sent in balanced mode */
- LinkLayerSecondaryUnbalanced llSecUnbalanced;
- LinkLayerSecondaryBalanced llSecBalanced;
- LinkLayerPrimaryBalanced llPriBalanced;
- LinkLayerPrimaryUnbalanced llPriUnbalanced;
- };
- struct sLinkLayerSecondaryUnbalanced {
- /**
- * Initialized/timeout -> state = IDLE
- * received invalid message -> state = ERROR
- * received valid message/no timeout -> state = AVAILABLE
- */
- LinkLayerState state;
- bool expectedFcb; /* expected value of next frame count bit (FCB) */
- LinkLayer linkLayer;
- ISecondaryApplicationLayer applicationLayer;
- void* appLayerParam;
- LinkLayerParameters linkLayerParameters;
- uint64_t lastReceivedMsg;
- int idleTimeout; /* connection timeout in ms */
- IEC60870_LinkLayerStateChangedHandler stateChangedHandler;
- void* stateChangedHandlerParameter;
- struct sLinkLayer _linkLayer;
- };
- struct sLinkLayerPrimaryUnbalanced {
- LinkLayerSlaveConnection currentSlave;
- int currentSlaveIndex;
- bool hasNextBroadcastToSend;
- struct sBufferFrame nextBroadcastMessage;
- uint8_t buffer[256];
- IPrimaryApplicationLayer applicationLayer;
- void* applicationLayerParam;
- struct sLinkLayer _linkLayer;
- LinkLayer linkLayer;
- LinkedList slaveConnections;
- IEC60870_LinkLayerStateChangedHandler stateChangedHandler;
- void* stateChangedHandlerParameter;
- };
- struct sLinkLayerBalanced {
- LinkLayer linkLayer;
- IBalancedApplicationLayer applicationLayer;
- void* appLayerParameter;
- struct sLinkLayer _linkLayer;
- struct sLinkLayerPrimaryBalanced primaryLinkLayer;
- struct sLinkLayerSecondaryBalanced secondaryLinkLayer;
- };
- bool
- IMasterConnection_sendACT_CON(IMasterConnection self, CS101_ASDU asdu, bool negative)
- {
- return self->sendACT_CON(self, asdu, negative);
- }
- CS101_AppLayerParameters
- IMasterConnection_getApplicationLayerParameters(IMasterConnection self)
- {
- return self->getApplicationLayerParameters(self);
- }
- bool
- IMasterConnection_sendASDU(IMasterConnection self, CS101_ASDU asdu)
- {
- return self->sendASDU(self, asdu);
- }
- bool
- IMasterConnection_sendACT_TERM(IMasterConnection self, CS101_ASDU asdu)
- {
- return self->sendACT_TERM(self, asdu);
- }
- LinkLayer
- LinkLayer_init(LinkLayer self, int address, SerialTransceiverFT12 transceiver, LinkLayerParameters linkLayerParameters)
- {
- if (self == NULL)
- self = (LinkLayer) GLOBAL_MALLOC(sizeof(struct sLinkLayer));
- if (self != NULL) {
- self->address = address;
- self->transceiver = transceiver;
- self->linkLayerParameters = linkLayerParameters;
- self->dir = false;
- self->llSecUnbalanced = NULL;
- self->llSecBalanced = NULL;
- self->llPriBalanced = NULL;
- self->llPriUnbalanced = NULL;
- }
- return self;
- }
- LinkLayerPrimaryUnbalanced
- LinkLayerPrimaryUnbalanced_create(SerialTransceiverFT12 transceiver, LinkLayerParameters linkLayerParameters,
- IPrimaryApplicationLayer applicationLayer, void* applicationLayerParam)
- {
- LinkLayerPrimaryUnbalanced self = (LinkLayerPrimaryUnbalanced) GLOBAL_MALLOC(sizeof(struct sLinkLayerPrimaryUnbalanced));
- if (self) {
- self->currentSlave = NULL;
- self->currentSlaveIndex = 0;
- self->hasNextBroadcastToSend = false;
- self->applicationLayer = applicationLayer;
- self->applicationLayerParam = applicationLayerParam;
- self->linkLayer = &(self->_linkLayer);
- LinkLayer_init(self->linkLayer, 0, transceiver, linkLayerParameters);
- self->linkLayer->llPriUnbalanced = self;
- BufferFrame_initialize(&(self->nextBroadcastMessage), self->buffer, 0);
- self->slaveConnections = LinkedList_create();
- self->stateChangedHandler = NULL;
- }
- return self;
- }
- static void
- LinkLayerPrimaryBalanced_init(LinkLayerPrimaryBalanced self, LinkLayer linkLayer, IBalancedApplicationLayer applicationLayer, void* appLayerParam)
- {
- self->primaryState = PLL_IDLE;
- self->state = LL_STATE_IDLE;
- self->waitingForResponse = false;
- self->sendLinkLayerTestFunction = false;
- self->nextFcb = true;
- self->linkLayer = linkLayer;
- self->applicationLayer = applicationLayer;
- self->applicationLayerParam = appLayerParam;
- self->stateChangedHandler = NULL;
- self->idleTimeout = 5000;
- self->otherStationAddress = 0;
- }
- static void
- LinkLayerSecondaryBalanced_init(LinkLayerSecondaryBalanced self, LinkLayer linkLayer, IBalancedApplicationLayer applicationLayer, void* appLayerParam)
- {
- self->expectedFcb = true;
- self->linkLayer = linkLayer;
- self->applicationLayer = applicationLayer;
- self->appLayerParam = appLayerParam;
- }
- LinkLayerBalanced
- LinkLayerBalanced_create(
- int linkLayerAddress,
- SerialTransceiverFT12 transceiver,
- LinkLayerParameters linkLayerParameters,
- IBalancedApplicationLayer applicationLayer,
- void* applicationLayerParameter
- )
- {
- LinkLayerBalanced self = (LinkLayerBalanced) GLOBAL_MALLOC(sizeof(struct sLinkLayerBalanced));
- if (self) {
- self->linkLayer = LinkLayer_init(&(self->_linkLayer), linkLayerAddress, transceiver, linkLayerParameters);
- self->applicationLayer = applicationLayer;
- self->appLayerParameter = applicationLayerParameter;
- LinkLayerPrimaryBalanced_init(&(self->primaryLinkLayer), self->linkLayer, applicationLayer, applicationLayerParameter);
- LinkLayerSecondaryBalanced_init(&(self->secondaryLinkLayer), self->linkLayer, applicationLayer, applicationLayerParameter);
- self->linkLayer->llPriBalanced = &(self->primaryLinkLayer);
- self->linkLayer->llSecBalanced = &(self->secondaryLinkLayer);
- }
- return self;
- }
- void
- LinkLayerBalanced_setIdleTimeout(LinkLayerBalanced self, int timeoutInMs)
- {
- self->primaryLinkLayer.idleTimeout = timeoutInMs;
- }
- void
- LinkLayerBalanced_setDIR(LinkLayerBalanced self, bool dir)
- {
- self->linkLayer->dir = dir;
- }
- void
- LinkLayerBalanced_setStateChangeHandler(LinkLayerBalanced self,
- IEC60870_LinkLayerStateChangedHandler handler, void* parameter)
- {
- self->primaryLinkLayer.stateChangedHandler = handler;
- self->primaryLinkLayer.stateChangedHandlerParameter = parameter;
- }
- void
- LinkLayerPrimaryUnbalanced_setStateChangeHandler(LinkLayerPrimaryUnbalanced self,
- IEC60870_LinkLayerStateChangedHandler handler, void* parameter)
- {
- self->stateChangedHandler = handler;
- self->stateChangedHandlerParameter = parameter;
- }
- static LinkLayerSlaveConnection
- LinkLayerPrimaryUnbalanced_getSlaveConnection(LinkLayerPrimaryUnbalanced self, int slaveAddress)
- {
- LinkLayerSlaveConnection retVal = NULL;
- LinkedList element = LinkedList_getNext(self->slaveConnections);
- while (element) {
- LinkLayerSlaveConnection slaveConnection = (LinkLayerSlaveConnection) LinkedList_getData(element);
- if (slaveConnection->address == slaveAddress) {
- retVal = slaveConnection;
- break;
- }
- element = LinkedList_getNext(element);
- }
- return retVal;
- }
- static LinkLayerSlaveConnection
- LinkLayerSlaveConnection_create(LinkLayerSlaveConnection self, LinkLayerPrimaryUnbalanced primaryLink, int slaveAddress)
- {
- if (self == NULL)
- self = (LinkLayerSlaveConnection) GLOBAL_MALLOC(sizeof(struct sLinkLayerSlaveConnection));
- if (self) {
- self->primaryLink = primaryLink;
- self->address = slaveAddress;
- self->state = LL_STATE_IDLE;
- self->lastSendTime = 0;
- self->originalSendTime = 0;
- self->nextFcb = true;
- self->waitingForResponse = false;
- self->primaryState = PLL_IDLE;
- self->hasMessageToSend = false;
- self->sendLinkLayerTestFunction = false;
- self->requestClass1Data = false;
- self->requestClass2Data = false;
- BufferFrame_initialize(&(self->nextMessage), self->buffer, 0);
- }
- return self;
- }
- void
- LinkLayerPrimaryUnbalanced_addSlaveConnection(LinkLayerPrimaryUnbalanced self, int slaveAddress)
- {
- LinkLayerSlaveConnection slaveConnection = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slaveConnection == NULL) {
- LinkLayerSlaveConnection newSlave = LinkLayerSlaveConnection_create(NULL, self, slaveAddress);
- LinkedList_add(self->slaveConnections, newSlave);
- }
- }
- bool
- LinkLayerPrimaryUnbalanced_requestClass2Data(LinkLayerPrimaryUnbalanced self, int slaveAddress)
- {
- LinkLayerSlaveConnection slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slave) {
- slave->requestClass2Data = true;
- return true;
- }
- return false;
- }
- static bool
- LinkLayerSecondaryBalanced_checkFCB(LinkLayerSecondaryBalanced self, bool fcb)
- {
- if (fcb != self->expectedFcb) {
- printf ("ERROR: Frame count bit (FCB) invalid!\n");
- /* TODO change link status */
- return false;
- } else {
- self->expectedFcb = !(self->expectedFcb);
- return true;
- }
- }
- void
- LinkLayerSecondaryUnbalanced_setStateChangeHandler(LinkLayerSecondaryUnbalanced self,
- IEC60870_LinkLayerStateChangedHandler handler, void* parameter)
- {
- self->stateChangedHandler = handler;
- self->stateChangedHandlerParameter = parameter;
- }
- static void
- SendSingleCharCharacter(LinkLayer self)
- {
- uint8_t singleCharAck[] = {0xe5};
- SerialTransceiverFT12_sendMessage(self->transceiver, singleCharAck, 1);
- }
- static void
- SendFixedFrame(LinkLayer self, uint8_t fc, int address, bool prm, bool dir, bool acd /*FCB*/, bool dfc /*FCV*/)
- {
- uint8_t* buffer = self->buffer;
- int bufPos = 0;
- buffer[bufPos++] = 0x10; /* START */
- uint8_t c = fc & 0x0f;
- if (prm) c += 0x40;
- if (dir) c += 0x80;
- if (acd) c += 0x20;
- if (dfc) c += 0x10;
- buffer [bufPos++] = c;
- if (self->linkLayerParameters->addressLength > 0) {
- buffer [bufPos++] = (uint8_t) (address % 0x100);
- if (self->linkLayerParameters->addressLength > 1)
- buffer [bufPos++] = (uint8_t) ((address / 0x100) % 0x100);
- }
- uint8_t checksum = 0;
- int i;
- for (i = 1; i < bufPos; i++)
- checksum += buffer[i];
- buffer [bufPos++] = checksum;
- buffer [bufPos++] = 0x16; /* END */
- printf("Send fixed frame (fc=%i)\n", fc);
- SerialTransceiverFT12_sendMessage(self->transceiver, buffer, bufPos);
- }
- void
- LinkLayerSecondaryBalanced_handleMessage(LinkLayerSecondaryBalanced self, uint8_t fc, bool isBroadcast, bool fcb, bool fcv, uint8_t* msg, int userDataStart, int userDataLength)
- {
- if (fcv) {
- if (LinkLayerSecondaryBalanced_checkFCB(self, fcb) == false)
- return;
- }
- switch (fc) {
- case LL_FC_00_RESET_REMOTE_LINK:
- printf ("SLL - RECV FC 00 - RESET REMOTE LINK\n");
- self->expectedFcb = true;
- printf ("SLL - SEND FC 00 - ACK\n");
- if (self->linkLayer->linkLayerParameters->useSingleCharACK)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, self->linkLayer->dir, false, false);
- break;
- case LL_FC_02_TEST_FUNCTION_FOR_LINK:
- printf ("SLL - RECV FC 02 - TEST FUNCTION FOR LINK\n");
- printf ("SLL - SEND FC 00 - ACK\n");
- if (self->linkLayer->linkLayerParameters->useSingleCharACK)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, self->linkLayer->dir, false, false);
- break;
- case LL_FC_03_USER_DATA_CONFIRMED:
- printf("SLL - RECV FC 03 - USER DATA CONFIRMED\n");
- if (userDataLength > 0) {
- if (self->applicationLayer->HandleReceivedData(self->appLayerParam, msg, isBroadcast, userDataStart, userDataLength)) {
- printf ("SLL - SEND FC 00 - ACK\n");
- if (self->linkLayer->linkLayerParameters->useSingleCharACK)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, self->linkLayer->dir, false, false);
- }
- }
- break;
- case LL_FC_04_USER_DATA_NO_REPLY:
- printf ("SLL -FC 04 - USER DATA NO REPLY\n");
- if (userDataLength > 0) {
- self->applicationLayer->HandleReceivedData(self->appLayerParam, msg, isBroadcast, userDataStart, userDataLength);
- }
- break;
- case LL_FC_09_REQUEST_LINK_STATUS:
- printf ("SLL - RECV FC 09 - REQUEST LINK STATUS\n");
- printf ("SLL - SEND FC 11 - STATUS OF LINK\n");
- SendFixedFrame(self->linkLayer, LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND, self->linkLayer->address, false, self->linkLayer->dir, false, false);
- break;
- default:
- printf ("SLL - UNEXPECTED LINK LAYER MESSAGE");
- printf ("SLL - SEND FC 15 - SERVICE NOT IMPLEMENTED\n");
- SendFixedFrame(self->linkLayer, LL_FC_15_SERVICE_NOT_IMPLEMENTED, self->linkLayer->address, false, self->linkLayer->dir, false, false);
- break;
- }
- }
- void
- LinkLayerPrimaryBalanced_resetIdleTimeout(LinkLayerPrimaryBalanced self)
- {
- self->lastReceivedMsg = Hal_getTimeInMs();
- }
- static void
- llpb_setNewState(LinkLayerPrimaryBalanced self, LinkLayerState newState)
- {
- if (newState != self->state) {
- self->state = newState;
- if (self->stateChangedHandler)
- self->stateChangedHandler(self->stateChangedHandlerParameter, -1, newState);
- }
- }
- void
- LinkLayerPrimaryBalanced_handleMessage(LinkLayerPrimaryBalanced self, uint8_t fc, bool dir, bool dfc, int address, uint8_t* msg, int userDataStart, int userDataLength)
- {
- UNUSED_PARAMETER(dir);
- UNUSED_PARAMETER(address);
- UNUSED_PARAMETER(msg);
- UNUSED_PARAMETER(userDataStart);
- UNUSED_PARAMETER(userDataLength);
- PrimaryLinkLayerState primaryState = self->primaryState;
- PrimaryLinkLayerState newState = primaryState;
- self->lastReceivedMsg = Hal_getTimeInMs();
- if (dfc) {
- switch (self->primaryState) {
- case PLL_EXECUTE_REQUEST_STATUS_OF_LINK:
- case PLL_EXECUTE_RESET_REMOTE_LINK:
- newState = PLL_EXECUTE_REQUEST_STATUS_OF_LINK;
- break;
- case PLL_EXECUTE_SERVICE_SEND_CONFIRM:
- case PLL_SECONDARY_LINK_LAYER_BUSY:
- newState = PLL_SECONDARY_LINK_LAYER_BUSY;
- break;
- default:
- break;
- }
- llpb_setNewState(self, LL_STATE_BUSY);
- self->primaryState = newState;
- return;
- }
- switch (fc) {
- case LL_FC_00_ACK:
- printf ("PLL - RECV FC 00 - ACK\n");
- if (primaryState == PLL_EXECUTE_RESET_REMOTE_LINK) {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llpb_setNewState(self, LL_STATE_AVAILABLE);
- self->waitingForResponse = false;
- }
- else if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- if (self->sendLinkLayerTestFunction)
- self->sendLinkLayerTestFunction = false;
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llpb_setNewState(self, LL_STATE_AVAILABLE);
- self->waitingForResponse = false;
- }
- else if (primaryState == PLL_EXECUTE_REQUEST_STATUS_OF_LINK) {
- /* stay in state and wait for response */
- printf ("ACK (FC 00) unexpected -> expected status-of-link (FC 11)\n");
- }
- else {
- self->waitingForResponse = false;
- }
- break;
- case LL_FC_01_NACK:
- printf ("PLL - RECV FC 01 - NACK\n");
- if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- newState = PLL_SECONDARY_LINK_LAYER_BUSY;
- llpb_setNewState(self, LL_STATE_BUSY);
- }
- break;
- case LL_FC_08_RESP_USER_DATA:
- printf ("PLL - RECV FC 08 - RESP USER DATA\n");
- newState = PLL_IDLE;
- llpb_setNewState(self, LL_STATE_ERROR);
- break;
- case LL_FC_09_RESP_NACK_NO_DATA:
- printf ("PLL - RECV FC 09 - RESP NACK - NO DATA\n");
- newState = PLL_IDLE;
- llpb_setNewState(self, LL_STATE_ERROR);
- break;
- case LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND:
- printf ("PLL - RECV FC 11 - STATUS OF LINK\n");
- if (primaryState == PLL_EXECUTE_REQUEST_STATUS_OF_LINK) {
- printf ("PLL - SEND FC 00 - RESET REMOTE LINK\n");
- SendFixedFrame(self->linkLayer, LL_FC_00_RESET_REMOTE_LINK, self->otherStationAddress, true, self->linkLayer->dir, false, false);
- self->lastSendTime = Hal_getTimeInMs();
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_RESET_REMOTE_LINK;
- llpb_setNewState(self, LL_STATE_BUSY);
- }
- else { /* illegal message in this state */
- newState = PLL_IDLE;
- llpb_setNewState(self, LL_STATE_ERROR);
- }
- break;
- case LL_FC_14_SERVICE_NOT_FUNCTIONING:
- case LL_FC_15_SERVICE_NOT_IMPLEMENTED:
- printf ("PLL - link layer service not functioning/not implemented in secondary station\n");
- if (self->sendLinkLayerTestFunction)
- self->sendLinkLayerTestFunction = false;
- if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llpb_setNewState(self, LL_STATE_AVAILABLE);
- }
- break;
- default:
- printf ("UNEXPECTED SECONDARY LINK LAYER MESSAGE\n");
- break;
- }
- printf("PLL RECV - old state: %i new state %i\n", primaryState, newState);
- self->primaryState = newState;
- }
- static void
- llsc_setState(LinkLayerSlaveConnection self, LinkLayerState newState)
- {
- if (self->state != newState) {
- self->state = newState;
- if (self->primaryLink->stateChangedHandler)
- self->primaryLink->stateChangedHandler(self->primaryLink->stateChangedHandlerParameter, self->address, newState);
- }
- }
- static void
- LinkLayerSlaveConnection_HandleMessage(LinkLayerSlaveConnection self, uint8_t fc, bool acd, bool dfc, int address, uint8_t* msg, int userDataStart, int userDataLength)
- {
- IPrimaryApplicationLayer applicationLayer = self->primaryLink->applicationLayer;
- PrimaryLinkLayerState primaryState = self->primaryState;
- PrimaryLinkLayerState newState = primaryState;
- if (dfc) {
- printf ("[SLAVE %i] PLL - DFC = true!\n", self->address);
- /* stop sending ASDUs; only send Status of link requests */
- self->dontSendMessages = true;
- switch (self->primaryState) {
- case PLL_EXECUTE_REQUEST_STATUS_OF_LINK:
- case PLL_EXECUTE_RESET_REMOTE_LINK:
- newState = PLL_EXECUTE_REQUEST_STATUS_OF_LINK;
- break;
- case PLL_EXECUTE_SERVICE_SEND_CONFIRM:
- case PLL_SECONDARY_LINK_LAYER_BUSY:
- newState = PLL_SECONDARY_LINK_LAYER_BUSY;
- break;
- default:
- break;
- }
- llsc_setState(self, LL_STATE_BUSY);
- self->primaryState = newState;
- return;
- }
- else {
- /* unblock transmission of application layer messages */
- self->dontSendMessages = false;
- }
- if (acd)
- self->requestClass1Data = true;
- switch (fc) {
- case LL_FC_00_ACK:
- printf ("[SLAVE %i] PLL - received ACK\n", self->address);
- if (primaryState == PLL_EXECUTE_RESET_REMOTE_LINK) {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llsc_setState(self, LL_STATE_AVAILABLE);
- }
- else if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- if (self->sendLinkLayerTestFunction)
- self->sendLinkLayerTestFunction = false;
- else
- self->hasMessageToSend = false;
- llsc_setState(self, LL_STATE_AVAILABLE);
- newState = PLL_LINK_LAYERS_AVAILABLE;
- }
- else if (primaryState == PLL_EXECUTE_SERVICE_REQUEST_RESPOND) {
- /* single char ACK is interpreted as RESP NO DATA */
- llsc_setState(self, LL_STATE_AVAILABLE);
- newState = PLL_LINK_LAYERS_AVAILABLE;
- }
- self->waitingForResponse = false;
- break;
- case LL_FC_01_NACK:
- printf ("[SLAVE %i] PLL - received NACK\n", self->address);
- if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- llsc_setState(self, LL_STATE_BUSY);
- newState = PLL_SECONDARY_LINK_LAYER_BUSY;
- }
- self->waitingForResponse = false;
- break;
- case LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND:
- printf ("[SLAVE %i] PLL - received STATUS OF LINK\n", self->address);
- if (primaryState == PLL_EXECUTE_REQUEST_STATUS_OF_LINK) {
- printf ("[SLAVE %i] PLL - SEND RESET REMOTE LINK\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_00_RESET_REMOTE_LINK, self->address, true, false, false, false);
- self->lastSendTime = Hal_getTimeInMs();
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_RESET_REMOTE_LINK;
- llsc_setState(self, LL_STATE_BUSY);
- }
- else { /* illegal message */
- newState = PLL_IDLE;
- llsc_setState(self, LL_STATE_ERROR);
- }
- break;
- case LL_FC_08_RESP_USER_DATA:
- printf ("[SLAVE %i] PLL - received USER DATA\n", self->address);
- if (primaryState == PLL_EXECUTE_SERVICE_REQUEST_RESPOND) {
- if (applicationLayer->UserData)
- applicationLayer->UserData(self->primaryLink->applicationLayerParam, address, msg, userDataStart, userDataLength);
- self->requestClass1Data = false;
- self->requestClass2Data = false;
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llsc_setState(self, LL_STATE_AVAILABLE);
- }
- else { /* illegal message */
- newState = PLL_IDLE;
- llsc_setState(self, LL_STATE_ERROR);
- }
- self->waitingForResponse = false;
- break;
- case LL_FC_09_RESP_NACK_NO_DATA:
- printf ("[SLAVE %i] PLL - received RESP NO DATA\n", self->address);
- if (primaryState == PLL_EXECUTE_SERVICE_REQUEST_RESPOND) {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llsc_setState(self, LL_STATE_AVAILABLE);
- }
- else { /* illegal message */
- newState = PLL_IDLE;
- llsc_setState(self, LL_STATE_ERROR);
- }
- self->waitingForResponse = false;
- break;
- case LL_FC_14_SERVICE_NOT_FUNCTIONING:
- case LL_FC_15_SERVICE_NOT_IMPLEMENTED:
- printf ("[SLAVE %i] PLL - link layer service not functioning/not implemented in secondary station\n", self->address);
- if (primaryState == PLL_EXECUTE_SERVICE_SEND_CONFIRM) {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llsc_setState(self, LL_STATE_AVAILABLE);
- }
- self->waitingForResponse = false;
- break;
- default:
- printf ("[SLAVE %i] UNEXPECTED SECONDARY LINK LAYER MESSAGE\n", self->address);
- self->waitingForResponse = false;
- break;
- }
- if (acd) {
- if (applicationLayer->AccessDemand)
- applicationLayer->AccessDemand(self->primaryLink->applicationLayerParam, address);
- }
- if (primaryState != newState)
- printf("[SLAVE %i] PLL RECV: old state: %i new state: %i\n", self->address, primaryState, newState);
- self->primaryState = newState;
- }
- void
- LinkLayerPrimaryUnbalanced_handleMessage(LinkLayerPrimaryUnbalanced self, uint8_t fc, bool acd, bool dfc, int address,
- uint8_t* msg, int userDataStart, int userDataLength)
- {
- LinkLayerSlaveConnection slave = NULL;
- if (address == -1)
- slave = self->currentSlave;
- else
- slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, address);
- if (slave) {
- LinkLayerSlaveConnection_HandleMessage(slave, fc, acd, dfc, address, msg, userDataStart, userDataLength);
- }
- else {
- printf ("PLL RECV - response from unknown slave %i\n", address);
- }
- }
- static void
- HandleMessageBalancedAndPrimaryUnbalanced(void* parameter, uint8_t* msg, int msgSize)
- {
- LinkLayer self = (LinkLayer) parameter;
- int userDataLength = 0;
- int userDataStart = 0;
- uint8_t c = 0;
- int csStart = 0;
- int csIndex = 0;
- int address = 0; /* address can be ignored in balanced mode? */
- bool isSingleCharAck = false;
- if (msg[0] == 0x68) {
- if (msg[1] != msg[2]) {
- printf ("ERROR: L fields differ!\n");
- return;
- }
- userDataLength = msg[1] - self->linkLayerParameters->addressLength - 1;
- userDataStart = 5 + self->linkLayerParameters->addressLength;
- csStart = 4;
- csIndex = userDataStart + userDataLength;
- /* check if message size is reasonable */
- if (msgSize != (userDataStart + userDataLength + 2 /* CS + END */)) {
- printf ("ERROR: Invalid message length\n");
- return;
- }
- c = msg[4];
- if (self->linkLayerParameters->addressLength > 0)
- address += msg[5];
- if (self->linkLayerParameters->addressLength > 1)
- address += msg[6] * 0x100;
- } else if (msg[0] == 0x10) {
- c = msg[1];
- csStart = 1;
- csIndex = 2 + self->linkLayerParameters->addressLength;
- if (self->linkLayerParameters->addressLength > 0)
- address += msg[2];
- if (self->linkLayerParameters->addressLength > 1)
- address += msg[3] * 0x100;
- } else if (msg[0] == 0xe5) {
- isSingleCharAck = true;
- printf ("Received single char ACK\n");
- }
- else {
- printf("ERROR: Received unexpected message type!\n");
- return;
- }
- if (isSingleCharAck == false) {
- /* check checksum */
- uint8_t checksum = 0;
- int i;
- for (i = csStart; i < csIndex; i++)
- checksum += msg [i];
- if (checksum != msg [csIndex]) {
- printf ("ERROR: checksum invalid!\n");
- return;
- }
- /* parse C field bits */
- uint8_t fc = c & 0x0f;
- bool prm = ((c & 0x40) == 0x40);
- if (prm) { /* we are secondary link layer */
- bool fcb = ((c & 0x20) == 0x20);
- bool fcv = ((c & 0x10) == 0x10);
- if (self->llSecBalanced != NULL)
- LinkLayerSecondaryBalanced_handleMessage(self->llSecBalanced, fc, false, fcb, fcv, msg, userDataStart, userDataLength);
- else
- printf ("No secondary link layer available!\n");
- if (self->llPriBalanced != NULL) {
- LinkLayerPrimaryBalanced_resetIdleTimeout(self->llPriBalanced);
- }
- } else { /* we are primary link layer */
- bool dir = ((c & 0x80) == 0x80); /* DIR - direction for balanced transmission */
- bool dfc = ((c & 0x10) == 0x10); /* DFC - Data flow control */
- if (self->llPriBalanced != NULL) {
- LinkLayerPrimaryBalanced_handleMessage(self->llPriBalanced, fc, dir, dfc, address, msg, userDataStart, userDataLength);
- }
- else if (self->llPriUnbalanced != NULL) {
- bool acd = ((c & 0x20) == 0x20); /* ACD - access demand for class 1 data - for unbalanced transmission */
- LinkLayerPrimaryUnbalanced_handleMessage(self->llPriUnbalanced, fc, acd, dfc, address, msg, userDataStart, userDataLength);
- }
- else
- printf ("No primary link layer available!\n");
- }
- }
- else { /* Single byte ACK */
- if (self->llPriBalanced != NULL) {
- LinkLayerPrimaryBalanced_handleMessage(self->llPriBalanced, LL_FC_00_ACK, false, false, -1, NULL, 0, 0);
- }
- else if (self->llPriUnbalanced != NULL) {
- LinkLayerPrimaryUnbalanced_handleMessage(self->llPriUnbalanced, LL_FC_00_ACK, false, false, -1, NULL, 0, 0);
- }
- else
- printf ("No primary link layer available!\n");
- }
- }
- static void
- SendVariableLengthFrame(LinkLayer self, uint8_t fc, int address, bool prm, bool dir, bool acd, bool dfc, Frame frame)
- {
- uint8_t* buffer = self->buffer;
- int addressLength = self->linkLayerParameters->addressLength;
- buffer [0] = 0x68; /* START */
- buffer [3] = 0x68; /* START */
- uint8_t c = fc & 0x0f;
- if (prm) c+= 0x40;//0100 0000
- if (dir) c+= 0x80;//1000 0000
- if (acd) c+= 0x20;//0010 0000
- if (dfc) c+= 0x10;//0001 0000
- buffer [4] = c;
- int bufPos = 5;
- if (addressLength > 0) {
- buffer [bufPos++] = (uint8_t) (address % 0x100);
- if (addressLength > 1)
- buffer [bufPos++] = (uint8_t) ((address / 0x100) % 0x100);
- }
- uint8_t* userData = Frame_getBuffer(frame);
- int userDataLength = Frame_getMsgSize(frame);
- int l = 1 + addressLength + userDataLength;
- if (l > 255)
- return;
- buffer [1] = (uint8_t) l;
- buffer [2] = (uint8_t) l;
- int i;
- for (i = 0; i < userDataLength; i++)
- buffer [bufPos++] = userData[i];
- uint8_t checksum = 0;
- for (i = 4; i < bufPos; i++)
- checksum += buffer[i];
- buffer [bufPos++] = checksum;
- buffer [bufPos++] = 0x16; /* END */
- printf("Send variable frame (fc=%i, size=%i)\n", (int) fc, bufPos);
- SerialTransceiverFT12_sendMessage(self->transceiver, buffer, bufPos);
- }
- static int
- LinkLayer_getBroadcastAddress(LinkLayer self)
- {
- if (self->linkLayerParameters->addressLength == 1) {
- return 255;
- } else if (self->linkLayerParameters->addressLength == 2) {
- return 65535;
- }
- return 0;
- }
- static void
- LinkLayerSlaveConnection_runStateMachine(LinkLayerSlaveConnection self)
- {
- uint32_t currentTime = Hal_getTimeInMs();
- PrimaryLinkLayerState primaryState = self->primaryState;
- PrimaryLinkLayerState newState = primaryState;
- switch (primaryState) {
- case PLL_TIMEOUT:
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutLinkState)) {
- newState = PLL_IDLE;
- }
- break;
- case PLL_IDLE:
- self->originalSendTime = 0;
- self->sendLinkLayerTestFunction = false;
- printf ("[SLAVE %i] PLL - SEND FC 09 - REQUEST LINK STATUS\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_09_REQUEST_LINK_STATUS, self->address, true, false, false, false);
- self->lastSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_REQUEST_STATUS_OF_LINK;
- break;
- case PLL_EXECUTE_REQUEST_STATUS_OF_LINK:
- if (self->waitingForResponse) {
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutForAck)) {
- self->waitingForResponse = false;
- self->lastSendTime = currentTime;
- newState = PLL_TIMEOUT;
- }
- }
- else {
- printf ("[SLAVE %i] PLL - SEND FC 00 - RESET REMOTE LINK\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_00_RESET_REMOTE_LINK, self->address, true, false, false, false);
- self->lastSendTime = currentTime;
- self->waitingForResponse = true;
- self->nextFcb = true;
- newState = PLL_EXECUTE_RESET_REMOTE_LINK;
- }
- break;
- case PLL_EXECUTE_RESET_REMOTE_LINK:
- if (self->waitingForResponse) {
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutForAck)) {
- self->waitingForResponse = false;
- self->lastSendTime = currentTime;
- newState = PLL_TIMEOUT;
- llsc_setState(self, LL_STATE_ERROR);
- }
- }
- else {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llsc_setState(self, LL_STATE_AVAILABLE);
- }
- break;
- case PLL_LINK_LAYERS_AVAILABLE:
- if (self->sendLinkLayerTestFunction) {
- printf ("[SLAVE %i] PLL - FC 02 - SEND TEST LINK\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_02_TEST_FUNCTION_FOR_LINK, self->address, true, false, self->nextFcb, true);
- self->nextFcb = !(self->nextFcb);
- self->lastSendTime = currentTime;
- self->originalSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_SERVICE_REQUEST_RESPOND;
- }
- else if (self->hasMessageToSend) {
- printf ("[SLAVE %i] PLL - SEND FC 03 - USER DATA CONFIRMED\n", self->address);
- SendVariableLengthFrame(self->primaryLink->linkLayer, LL_FC_03_USER_DATA_CONFIRMED, self->address, true, false, self->nextFcb, true, (Frame) &(self->nextMessage));
- self->nextFcb = !(self->nextFcb);
- self->lastSendTime = currentTime;
- self->originalSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_SERVICE_SEND_CONFIRM;
- }
- else if (self->requestClass1Data || self->requestClass2Data) {
- if (self->requestClass1Data) {
- printf ("[SLAVE %i] PLL - SEND FC 10 - REQ UD 1\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_10_REQUEST_USER_DATA_CLASS_1, self->address, true, false, self->nextFcb, true);
- self->requestClass1Data = false;
- }
- else {
- printf ("[SLAVE %i] PLL - SEND FC 11 - REQ UD 2\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_11_REQUEST_USER_DATA_CLASS_2, self->address, true, false, self->nextFcb, true);
- self->requestClass2Data = false;
- }
- self->nextFcb = !(self->nextFcb);
- self->lastSendTime = currentTime;
- self->originalSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_SERVICE_REQUEST_RESPOND;
- }
- break;
- case PLL_EXECUTE_SERVICE_SEND_CONFIRM:
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutForAck)) {
- if (currentTime > (self->originalSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutRepeat)) {
- printf ("[SLAVE %i] TIMEOUT: ASDU not confirmed after repeated transmission\n", self->address);
- self->waitingForResponse = false;
- self->lastSendTime = currentTime;
- newState = PLL_TIMEOUT;
- llsc_setState(self, LL_STATE_ERROR);
- }
- else {
- printf ("[SLAVE %i] TIMEOUT: ASDU not confirmed\n", self->address);
- if (self->sendLinkLayerTestFunction) {
- printf ("[SLAVE %i] PLL - SEND FC 02 - RESET REMOTE LINK [REPEAT]\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_02_TEST_FUNCTION_FOR_LINK, self->address, true, false, !(self->nextFcb), true);
- }
- else {
- printf ("[SLAVE %i] PLL - SEND FC 03 - USER DATA CONFIRMED [REPEAT]\n", self->address);
- SendVariableLengthFrame(self->primaryLink->linkLayer, LL_FC_03_USER_DATA_CONFIRMED, self->address, true, false, !(self->nextFcb), true, (Frame) &(self->nextMessage));
- }
- self->lastSendTime = currentTime;
- }
- }
- break;
- case PLL_EXECUTE_SERVICE_REQUEST_RESPOND:
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutForAck)) {
- if (currentTime > (self->originalSendTime + self->primaryLink->linkLayer->linkLayerParameters->timeoutRepeat)) {
- printf ("[SLAVE %i] TIMEOUT: ASDU not confirmed after repeated transmission\n", self->address);
- newState = PLL_IDLE;
- self->requestClass1Data = false;
- self->requestClass2Data = false;
- llsc_setState(self, LL_STATE_ERROR);
- }
- else {
- printf ("[SLAVE %i] TIMEOUT: ASDU not confirmed\n", self->address);
- if (self->requestClass1Data) {
- printf ("[SLAVE %i] PLL - SEND FC 10 - REQ UD 1 [REPEAT]\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_10_REQUEST_USER_DATA_CLASS_1, self->address, true, false, !(self->nextFcb), true);
- }
- else {
- printf ("[SLAVE %i] PLL - SEND FC 11 - REQ UD 2 [REPEAT]\n", self->address);
- SendFixedFrame(self->primaryLink->linkLayer, LL_FC_11_REQUEST_USER_DATA_CLASS_2, self->address, true, false, !(self->nextFcb), true);
- }
- self->lastSendTime = currentTime;
- }
- }
- break;
- case PLL_SECONDARY_LINK_LAYER_BUSY:
- break;
- }
- if (primaryState != newState)
- printf("[SLAVE %i] PLL: old state: %i new state: %i\n", self->address, primaryState, newState);
- self->primaryState = newState;
- }
- void
- LinkLayerPrimaryUnbalanced_runStateMachine(LinkLayerPrimaryUnbalanced self)
- {
- if (self->hasNextBroadcastToSend) {
- /* send pending broadcast message */
- SendVariableLengthFrame(self->linkLayer, LL_FC_04_USER_DATA_NO_REPLY, LinkLayer_getBroadcastAddress(self->linkLayer), true, false, false, false, (Frame) &(self->nextBroadcastMessage));
- self->hasNextBroadcastToSend = false;
- }
- /* run all the link layer state machines for the registered slaves */
- if (LinkedList_size(self->slaveConnections) > 0) {
- if (self->currentSlave != NULL) {
- if (self->currentSlave->waitingForResponse == false)
- self->currentSlave = NULL;
- }
- if (self->currentSlave == NULL) {
- /* schedule next slave connection */
- self->currentSlave = (LinkLayerSlaveConnection) LinkedList_getData(LinkedList_get(self->slaveConnections, self->currentSlaveIndex));
- self->currentSlaveIndex = (self->currentSlaveIndex + 1) % LinkedList_size(self->slaveConnections);
- }
- if (self->currentSlave)
- LinkLayerSlaveConnection_runStateMachine(self->currentSlave);
- }
- }
- void
- LinkLayerPrimaryBalanced_runStateMachine(LinkLayerPrimaryBalanced self)
- {
- uint64_t currentTime = Hal_getTimeInMs();
- PrimaryLinkLayerState primaryState = self->primaryState;
- PrimaryLinkLayerState newState = primaryState;
- switch (primaryState) {
- case PLL_IDLE:
- self->originalSendTime = 0;
- self->sendLinkLayerTestFunction = false;
- SendFixedFrame(self->linkLayer, LL_FC_09_REQUEST_LINK_STATUS, self->otherStationAddress, true, self->linkLayer->dir, false, false);
- self->lastSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_REQUEST_STATUS_OF_LINK;
- break;
- case PLL_EXECUTE_REQUEST_STATUS_OF_LINK:
- if (self->waitingForResponse) {
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->linkLayer->linkLayerParameters->timeoutForAck)) {
- newState = PLL_IDLE;
- }
- }
- else {
- printf ("PLL - SEND RESET REMOTE LINK\n");
- SendFixedFrame(self->linkLayer, LL_FC_00_RESET_REMOTE_LINK, self->otherStationAddress, true, self->linkLayer->dir, false, false);
- self->lastSendTime = currentTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_RESET_REMOTE_LINK;
- }
- break;
- case PLL_EXECUTE_RESET_REMOTE_LINK:
- if (self->waitingForResponse) {
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->linkLayer->linkLayerParameters->timeoutForAck)) {
- self->waitingForResponse = false;
- newState = PLL_IDLE;
- llpb_setNewState(self, LL_STATE_ERROR);
- }
- }
- else {
- newState = PLL_LINK_LAYERS_AVAILABLE;
- llpb_setNewState(self, LL_STATE_AVAILABLE);
- }
- break;
- case PLL_LINK_LAYERS_AVAILABLE:
- if (self->lastReceivedMsg > currentTime) {
- /* last received message not plausible */
- self->lastReceivedMsg = currentTime;
- }
- if ((currentTime - self->lastReceivedMsg) > (unsigned int) self->idleTimeout) {
- printf ("PLL - Idle timeout detected. Send link layer test function\n");
- self->sendLinkLayerTestFunction = true;
- }
- if (self->sendLinkLayerTestFunction) {
- printf ("PLL - SEND TEST LINK\n");
- SendFixedFrame(self->linkLayer, LL_FC_02_TEST_FUNCTION_FOR_LINK, self->otherStationAddress, true, self->linkLayer->dir, self->nextFcb, true);
- self->nextFcb = !(self->nextFcb);
- self->lastSendTime = currentTime;
- self->originalSendTime = self->lastSendTime;
- newState = PLL_EXECUTE_SERVICE_SEND_CONFIRM;
- }
- else {
- /* provide a buffer where the application layer can encode the user data */
- Frame bufferFrame = BufferFrame_initialize(&(self->lastSendAsdu), self->linkLayer->userDataBuffer, 0);
- Frame asdu = self->applicationLayer->GetUserData(self->applicationLayerParam, bufferFrame);
- if (asdu) {
- printf ("PLL: SEND USER DATA CONFIRMED\n");
- SendVariableLengthFrame(self->linkLayer, LL_FC_03_USER_DATA_CONFIRMED, self->otherStationAddress, true, self->linkLayer->dir, self->nextFcb, true, asdu);
- self->nextFcb = !(self->nextFcb);
- self->lastSendTime = currentTime;
- self->originalSendTime = self->lastSendTime;
- self->waitingForResponse = true;
- newState = PLL_EXECUTE_SERVICE_SEND_CONFIRM;
- }
- }
- break;
- case PLL_EXECUTE_SERVICE_SEND_CONFIRM:
- if (self->lastSendTime > currentTime) {
- /* last sent time not plausible! */
- self->lastSendTime = currentTime;
- }
- if (currentTime > (self->lastSendTime + self->linkLayer->linkLayerParameters->timeoutForAck)) {
- if (currentTime > (self->originalSendTime + self->linkLayer->linkLayerParameters->timeoutRepeat)) {
- printf ("TIMEOUT: ASDU not confirmed after repeated transmission\n");
- newState = PLL_IDLE;
- llpb_setNewState(self, LL_STATE_ERROR);
- }
- else {
- printf ("TIMEOUT: ASDU not confirmed\n");
- if (self->sendLinkLayerTestFunction) {
- printf ("PLL - repeat send test function\n");
- SendFixedFrame(self->linkLayer, LL_FC_02_TEST_FUNCTION_FOR_LINK, self->otherStationAddress, true, self->linkLayer->dir, !(self->nextFcb), true);
- }
- else {
- printf ("PLL - repeat last ASDU\n");
- SendVariableLengthFrame(self->linkLayer, LL_FC_03_USER_DATA_CONFIRMED, self->otherStationAddress, true, self->linkLayer->dir, !(self->nextFcb), true, (Frame) &(self->lastSendAsdu));
- }
- self->lastSendTime = currentTime;
- }
- }
- break;
- case PLL_SECONDARY_LINK_LAYER_BUSY:
- break;
- default:
- break;
- }
- if (primaryState != newState)
- printf ("PLL - old state: %i new state: %i\n", primaryState, newState);
- self->primaryState = newState;
- }
- void
- LinkLayerBalanced_setAddress(LinkLayerBalanced self, int address)
- {
- self->linkLayer->address = address;
- }
- void
- LinkLayerSecondaryUnbalanced_setAddress(LinkLayerSecondaryUnbalanced self, int address)
- {
- self->_linkLayer.address = address;
- }
- void
- LinkLayerBalanced_run(LinkLayerBalanced self)
- {
- LinkLayer ll = self->linkLayer;
- SerialTransceiverFT12_readNextMessage(ll->transceiver, ll->buffer, HandleMessageBalancedAndPrimaryUnbalanced, (void*) ll);
- LinkLayerPrimaryBalanced_runStateMachine(&(self->primaryLinkLayer));
- }
- void
- LinkLayerPrimaryUnbalanced_run(LinkLayerPrimaryUnbalanced self)
- {
- LinkLayer ll = self->linkLayer;
- SerialTransceiverFT12_readNextMessage(ll->transceiver, ll->buffer, HandleMessageBalancedAndPrimaryUnbalanced, (void*) ll);
- LinkLayerPrimaryUnbalanced_runStateMachine(self);
- }
- static bool
- llsc_isMessageWaitingToSend(LinkLayerSlaveConnection self)
- {
- if ((self->requestClass1Data) || (self->requestClass2Data) || (self->hasMessageToSend))
- return true;
- else
- return false;
- }
- bool
- LinkLayerPrimaryUnbalanced_isChannelAvailable(LinkLayerPrimaryUnbalanced self, int slaveAddress)
- {
- LinkLayerSlaveConnection slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slave)
- return !(llsc_isMessageWaitingToSend(slave));
- return false;
- }
- void
- LinkLayerBalanced_setOtherStationAddress(LinkLayerBalanced self, int address)
- {
- self->primaryLinkLayer.otherStationAddress = address;
- }
- bool
- LinkLayerPrimaryUnbalanced_sendNoReply(LinkLayerPrimaryUnbalanced self, int slaveAddress, BufferFrame message)
- {
- if (slaveAddress == LinkLayer_getBroadcastAddress(self->linkLayer)) {
- if (self->hasNextBroadcastToSend)
- return false;
- else {
- self->nextBroadcastMessage.msgSize = message->msgSize;
- self->nextBroadcastMessage.startSize = message->startSize;
- memcpy(self->nextBroadcastMessage.buffer, message->buffer, message->msgSize);
- self->hasNextBroadcastToSend = true;
- return true;
- }
- }
- else {
- LinkLayerSlaveConnection slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slave) {
- if (slave->hasMessageToSend == false) {
- slave->nextMessage.msgSize = message->msgSize;
- slave->nextMessage.startSize = message->startSize;
- memcpy(slave->nextMessage.buffer, message->buffer, message->msgSize);
- slave->hasMessageToSend = true;
- return true;
- }
- }
- }
- return false;
- }
- bool
- LinkLayerPrimaryUnbalanced_sendConfirmed(LinkLayerPrimaryUnbalanced self, int slaveAddress, BufferFrame message)
- {
- LinkLayerSlaveConnection slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slave) {
- if (slave->hasMessageToSend == false) {
- slave->nextMessage.msgSize = message->msgSize;
- slave->nextMessage.startSize = message->startSize;
- memcpy(slave->nextMessage.buffer, message->buffer, message->msgSize);
- slave->hasMessageToSend = true;
- return true;
- }
- }
- return false;
- }
- void
- LinkLayerBalanced_destroy(LinkLayerBalanced self)
- {
- if (self) {
- GLOBAL_FREEMEM(self);
- }
- }
- void
- LinkLayerPrimaryUnbalanced_destroy(LinkLayerPrimaryUnbalanced self)
- {
- if (self) {
- if (self->slaveConnections)
- LinkedList_destroy(self->slaveConnections);
- GLOBAL_FREEMEM(self);
- }
- }
- bool
- LinkLayerPrimaryUnbalanced_requestClass1Data(LinkLayerPrimaryUnbalanced self, int slaveAddress)
- {
- LinkLayerSlaveConnection slave = LinkLayerPrimaryUnbalanced_getSlaveConnection(self, slaveAddress);
- if (slave) {
- if (llsc_isMessageWaitingToSend(slave) == false) {
- slave->requestClass1Data = true;
- return true;
- }
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- void
- LinkLayerSecondaryUnbalanced_setIdleTimeout(LinkLayerSecondaryUnbalanced self, int timeoutInMs)
- {
- self->idleTimeout = timeoutInMs;
- }
- void
- LinkLayerSecondaryUnbalanced_destroy(LL_Sec_Unb self)
- {
- if (self != NULL)
- GLOBAL_FREEMEM(self);
- }
- static bool
- checkFCB(LL_Sec_Unb self, bool fcb)
- {
- if (fcb != self->expectedFcb)
- return false;
- else {
- self->expectedFcb = !(self->expectedFcb);
- return true;
- }
- }
- static void
- llsu_setState(LL_Sec_Unb self, LinkLayerState newState)
- {
- if (self->state != newState) {
- self->state = newState;
- if (self->stateChangedHandler)
- self->stateChangedHandler(self->stateChangedHandlerParameter, -1, newState);
- }
- }
- static void
- LinkLayerSecondaryUnbalanced_handleMessage(LL_Sec_Unb self,
- uint8_t fc,
- bool isBroadcast,
- bool fcb,
- bool fcv,
- uint8_t* msg, int userDataStart, int userDataLength)
- {
- if (fcv) {
- if (checkFCB(self, fcb) == false) {
- printf("SLL - FCB check failed\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- }
- llsu_setState(self, LL_STATE_AVAILABLE);
- switch (fc) {
- case LL_FC_09_REQUEST_LINK_STATUS:
- printf("SLL - REQUEST LINK STATUS\n");
- {
- bool accessDemand = self->applicationLayer->IsClass1DataAvailable(self->appLayerParam);
- SendFixedFrame(self->linkLayer, LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND, self->linkLayer->address, false, false, accessDemand, false);
- }
- break;
- case LL_FC_00_RESET_REMOTE_LINK:
- printf("SLL - RESET REMOTE LINK\n");
- {
- self->expectedFcb = true;
- if (self->linkLayerParameters->useSingleCharACK)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, false, false, false);
- self->applicationLayer->ResetCUReceived(self->appLayerParam, false);
- }
- break;
- case LL_FC_07_RESET_FCB:
- printf("SLL - RESET FCB\n");
- {
- self->expectedFcb = true;
- if (self->linkLayerParameters->useSingleCharACK)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, false, false, false);
- self->applicationLayer->ResetCUReceived(self->appLayerParam, true);
- }
- break;
- case LL_FC_11_REQUEST_USER_DATA_CLASS_2:
- printf("SLL - REQUEST USER DATA CLASS 2\n");
- {
- /* provide a buffer where the application layer can encode the user data */
- struct sBufferFrame _bufferFrame;
- Frame bufferFrame = BufferFrame_initialize(&_bufferFrame, self->_linkLayer.userDataBuffer, 0);
- Frame asdu = self->applicationLayer->GetClass2Data(self->appLayerParam, bufferFrame);
- bool accessDemand = self->applicationLayer->IsClass1DataAvailable(self->appLayerParam);
- if (asdu != NULL) {
- SendVariableLengthFrame(self->linkLayer, LL_FC_08_RESP_USER_DATA, self->linkLayer->address, false, false, accessDemand, false, asdu);
- /* release frame buffer if required */
- if (asdu != bufferFrame)
- Frame_destroy(asdu);
- }
- else {
- if (self->linkLayerParameters->useSingleCharACK && !accessDemand)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_09_RESP_NACK_NO_DATA, self->linkLayer->address, false, false, accessDemand, false);
- }
- }
- break;
- case LL_FC_10_REQUEST_USER_DATA_CLASS_1:
- printf("SLL - REQUEST USER DATA CLASS 1\n");
- {
- /* provide a buffer where the application layer can encode the user data */
- struct sBufferFrame _bufferFrame;
- Frame bufferFrame = BufferFrame_initialize(&_bufferFrame, self->_linkLayer.userDataBuffer, 0);
- Frame asdu = self->applicationLayer->GetClass1Data(self->appLayerParam, bufferFrame);
- bool accessDemand = self->applicationLayer->IsClass1DataAvailable(self->appLayerParam);
- if (asdu != NULL) {
- SendVariableLengthFrame(self->linkLayer, LL_FC_08_RESP_USER_DATA, self->linkLayer->address, false, false, accessDemand, false, asdu);
- /* release frame buffer if required */
- if (asdu != bufferFrame)
- Frame_destroy(asdu);
- }
- else {
- if (self->linkLayerParameters->useSingleCharACK && !accessDemand)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_09_RESP_NACK_NO_DATA, self->linkLayer->address, false, false, accessDemand, false);
- }
- }
- break;
- case LL_FC_03_USER_DATA_CONFIRMED:
- printf ("SLL - USER DATA CONFIRMED\n");
- if (userDataLength > 0) {
- if (self->applicationLayer->HandleReceivedData(self->appLayerParam, msg, isBroadcast, userDataStart, userDataLength)) {
- bool accessDemand = self->applicationLayer->IsClass1DataAvailable(self->appLayerParam);
- if (self->linkLayerParameters->useSingleCharACK && !accessDemand)
- SendSingleCharCharacter(self->linkLayer);
- else
- SendFixedFrame(self->linkLayer, LL_FC_00_ACK, self->linkLayer->address, false, false, accessDemand, false);
- }
- }
- break;
- case LL_FC_04_USER_DATA_NO_REPLY:
- printf ("SLL - USER DATA NO REPLY\n");
- if (userDataLength > 0) {
- self->applicationLayer->HandleReceivedData(self->appLayerParam, msg, isBroadcast, userDataStart, userDataLength);
- }
- break;
- default:
- printf ("SLL - UNEXPECTED LINK LAYER MESSAGE\n");
- SendFixedFrame(self->linkLayer, LL_FC_15_SERVICE_NOT_IMPLEMENTED, self->linkLayer->address, false, false, false, false);
- break;
- }
- }
- LinkLayerSecondaryUnbalanced
- LinkLayerSecondaryUnbalanced_create(
- int linkLayerAddress,
- SerialTransceiverFT12 transceiver,
- LinkLayerParameters linkLayerParameters,
- ISecondaryApplicationLayer applicationLayer,
- void* applicationLayerParameter)
- {
- LL_Sec_Unb self = (LL_Sec_Unb) GLOBAL_MALLOC(sizeof(struct sLinkLayerSecondaryUnbalanced));
- if (self != NULL) {
- self->expectedFcb = true;
- self->applicationLayer = applicationLayer;
- self->appLayerParam = applicationLayerParameter;
- self->linkLayerParameters = linkLayerParameters;
- self->linkLayer = &(self->_linkLayer);
- self->state = LL_STATE_IDLE;
- self->idleTimeout = 500;
- self->stateChangedHandler = NULL;
- self->lastReceivedMsg = 0;
- LinkLayer_init(self->linkLayer, linkLayerAddress, transceiver, self->linkLayerParameters);
- self->linkLayer->llSecUnbalanced = self;
- }
- return self;
- }
- static void
- ParserHeaderSecondaryUnbalanced(void* parameter, uint8_t* msg, int msgSize)
- {
- LL_Sec_Unb self = (LL_Sec_Unb) parameter;
- self->lastReceivedMsg = Hal_getTimeInMs();
- int userDataLength = 0;
- int userDataStart = 0;
- uint8_t c;
- int csStart;
- int csIndex;
- int address = 0;
- int addressLength = self->linkLayer->linkLayerParameters->addressLength;
- if (msg [0] == 0x68) {
- if (msg [1] != msg [2]) {
- printf("ERROR: L fields differ!\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- userDataLength = (int)msg [1] - addressLength - 1;
- userDataStart = 5 +addressLength;
- csStart = 4;
- csIndex = userDataStart + userDataLength;
- /* check if message size is reasonable */
- if (msgSize != (userDataStart + userDataLength + 2 /* CS + END */)) {
- printf("ERROR: Invalid message length\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- c = msg [4];
- } else if (msg [0] == 0x10) {
- c = msg [1];
- csStart = 1;
- csIndex = 2 + addressLength;
- } else {
- printf("ERROR: Received unexpected message type in unbalanced slave mode!\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- bool isBroadcast = false;
- /* check address */
- if (addressLength > 0) {
- address = msg [csStart + 1];
- if (addressLength > 1) {
- address = msg [csStart + 2] * 0x100;
- if (address == 65535)
- isBroadcast = true;
- }
- else {
- if (address == 255)
- isBroadcast = true;
- }
- }
- int fc = c & 0x0f;
- if (isBroadcast) {
- if (fc != LL_FC_04_USER_DATA_NO_REPLY) {
- printf("ERROR: Invalid function code for broadcast message!\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- } else {
- if (address != self->linkLayer->address) {
- printf ("INFO: unknown link layer address -> ignore message\n");
- return;
- }
- }
- /* check checksum */
- uint8_t checksum = 0;
- for (int i = csStart; i < csIndex; i++)
- checksum += msg [i];
- if (checksum != msg [csIndex]) {
- printf("ERROR: checksum invalid!\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- /* parse C field bits */
- bool prm = ((c & 0x40) == 0x40);
- if (prm == false) {
- printf("ERROR: Received secondary message in unbalanced slave mode!\n");
- llsu_setState(self, LL_STATE_ERROR);
- return;
- }
- bool fcb = ((c & 0x20) == 0x20);
- bool fcv = ((c & 0x10) == 0x10);
- LinkLayerSecondaryUnbalanced_handleMessage(self, fc, isBroadcast, fcb, fcv, msg, userDataStart, userDataLength);
- }
- void
- LinkLayerSecondaryUnbalanced_run(LinkLayerSecondaryUnbalanced self)
- {
- LinkLayer ll = self->linkLayer;
- SerialTransceiverFT12_readNextMessage(ll->transceiver, ll->buffer, ParserHeaderSecondaryUnbalanced, self);
- if (self->state != LL_STATE_IDLE) {
- if ((Hal_getTimeInMs() - self->lastReceivedMsg) > (unsigned int) self->idleTimeout)
- llsu_setState(self, LL_STATE_IDLE);
- }
- }
|