This demonstrates the process of communicating through ethernet to a SEL-2431 Voltage Regulator Control Panel using SEL Fast Message. Basic device commands and data cna be requested and displayed over a connected serial port. This is a basic version and full testing and documentation has yet to be completed.

Dependencies:   BufferedSerial analogAverager voltageRegulator netStatReg analogMinMax CounterMinMax

main.cpp

Committer:
masterkookus
Date:
2020-01-23
Revision:
19:cae910c9c06a
Parent:
18:69846c990e04

File content as of revision 19:cae910c9c06a:

#if !FEATURE_LWIP
    #error [NOT_SUPPORTED] LWIP not supported for this target
#endif

//#define netmsgdebug

#include "mbed.h"
#include "EthernetInterface.h"
#include "TCPServer.h"
#include "TCPSocket.h"
#include "BufferedSerial.h"
#include "nettime.h"
#include "netdevices.h"
#include "mydevices.h"
#include "platform/CircularBuffer.h"
#include "netDataTypes.h"
#include "selMsg.h"
#include "string.h"
#include "analogAverager.h"
#include "analogMinMax.h"
#include "counterMinMax.h"
#include "netStatusReg.h"
#include "voltageRegulator.h"

Ticker nettimer;
Timer netDevTimers[7];

struct netsys net1;
netDevStatus netStat(0,0,0,0,0,setConsFailCount);

voltageRegulator myDevice;

bool polltick;
bool sendtick;

BufferedSerial sport0(sport0tx, sport0rx, rxtxbuffer, sport0mult);    // UART2

CircularBuffer<char, rxtxbuffer> receiveBuffer;
CircularBuffer<char, 256> unSolReceiveBuffer;
CircularBuffer<char, 64> sendLength;
CircularBuffer<char, 256> sendBuffer;

Thread rxtxdatathread[4];

unsigned int currenttime=0;

nsapi_error_t ret;

//Provides the deivce poll timing
void heartbeat()
{
    setPollTick(true);
    
    //Provide Sender Task Tick
    if (netDevTimers[0].read_ms()>=100)
    {
        netDevTimers[0].reset();
        setSendTick(true);
    }
    if (netStat.bit_isset(pollEnabled))
    {
        if (netStat.bit_isset(devOnline))
        {
            //Fast Demand Poll Tick
            if (netStat.bit_isset(fmdEnabled))
            {
                if (netStat.bit_isset(fmdOnline))
                {
                    if (netDevTimers[2].read_ms()>=setfmdemandpollinterval)
                    {
                        netDevTimers[2].reset();
                        netStat.bit_toset(fmdPollReq);
                    }
                }
                else
                {
                    if (netDevTimers[2].read_ms()>=8000)
                    {
                        netDevTimers[2].reset();
                        netStat.bit_toset(fmdPollReq);
                    }
                }
            }
            //Fast Meter Poll Tick
            if (netStat.bit_isset(fmEnabled))
            {
                if (netStat.bit_isset(fmOnline))
                {
                    if (netDevTimers[3].read_ms()>=setfmpollinterval)
                    {
                        netDevTimers[3].reset();
                        netStat.bit_toset(fmPollReq);
                    }
                }
                else
                {
                    if (netDevTimers[3].read_ms()>=8000)
                    {
                        netDevTimers[3].reset();
                        netStat.bit_toset(fmPollReq);
                    }
                }
            }
            if (netStat.bit_isset(recEnabled))
            {
                if (netDevTimers[6].read_ms()>=setDataRecInterval)
                {
                    netStat.bit_toset(recDataFile);
                    netDevTimers[6].stop();
                }
            }
        }
        else
        {
            if (netDevTimers[3].read_ms()>=8000)
            {
                netDevTimers[3].reset();
                netStat.bit_toset(fmCfgReq);
            }
        }
    }
    //Fast Message Timeout
    if ((netStat.bit_isset(fmCfgInProg)) || (netStat.bit_isset(fmPollInProg)) || (netStat.bit_isset(fmdPollInProg)))
    {
        if (netDevTimers[4].read_ms()>=2000)
        {
            netDevTimers[4].stop();
            netStat.bit_toset(fmCloseConnection);
            netStat.bit_toset(fmTimeout);
        }
    }
    //Serial Message Timeout
    if (netStat.bit_isset(serPollInProg))
    {
        if (netDevTimers[5].read_ms()>=net1.serMsgTimeout)
        {
            netDevTimers[5].stop();
            netStat.bit_toset(serCloseConnection);
            netStat.bit_toset(serTimeout);
        }
    }
    
}

void sendCmd(char cmdNum)
{
    sendLength.push(2);
    for (char txc=0;txc<2;txc++)
    {
        sendBuffer.push(fmCmd[cmdNum][txc]);
    }
}

void sendSerCmd(char cmdNum, char cmdCnt)
{
    sendLength.push(cmdCnt);
    for (char txc=0;txc<cmdCnt;txc++)
    {
        sendBuffer.push(serCmd[cmdNum][txc]);
    }
}

void confignetdevices(EthernetInterface *eth)
{   
    #ifdef sportEnabled
    netStat.bit_toset(serEnabled);
    #endif
    
    #ifdef setPollEnabled
    netStat.bit_toset(pollEnabled);
    #endif
    
    #ifdef fastMeterEnabled
    netStat.bit_toset(fmEnabled);
    #endif
    
    #ifdef fastDemandEnabled
    netStat.bit_toset(fmdEnabled);
    #endif
    
    #ifdef recordDataEnabled
    netStat.bit_toset(recEnabled);
    #endif
    
    net1.cltPort=setclientport;
    net1.srv_addr=setclientaddress;
    net1.srv_sock.set_blocking(false);
    net1.srv_sock.set_timeout(100);
    net1.sendRetryCount=0;
    net1.messageFailCount=0;
    net1.serMsgTimeout=2000;
    
    /* Open the server on ethernet stack */
    net1.srv.open(eth);
    sport0.baud(sport0baud);
}

void dataprocess(netsys *net2)
{
    char cchar;
    char cbuf[rxtxbuffer];
    unsigned int clen=0;
    unsigned int cbc;
    
    while(1)
    {
        //Check to see if the Receive Buffer has anything
        /*while (!receiveBuffer.empty())
        {
            receiveBuffer.pop(cchar);
            cbuf[clen]=cchar;
            clen++;
        }*/
        //If a Poll Request has been made and data has been received set flag
        netStat.bit_sis(serPollInProg,serRespRx);
        netStat.bit_sis(fmPollInProg,fmRespRx);
        netStat.bit_sis(fmdPollInProg,fmdRespRx);
        
        //Check to see if bulk data and reports being sent from device due to serial command
        if (netStat.bit_isset(serMsgRx))
        {
            while (!receiveBuffer.empty())
            {
                receiveBuffer.pop(cchar);
                sport0.putc(cchar);
                //cbuf[clen]=cchar;
                //clen++;
            }
            /*if (clen>0)
            {
                sport0.write(cbuf,clen);
                netDevTimers[5].reset();
                clen=0;
                netStat.iedOnline(true);
            }*/
        }
        else
        {
            while (!receiveBuffer.empty())
            {
                receiveBuffer.pop(cchar);
                cbuf[clen]=cchar;
                clen++;
            }
        }
        //Check to see if at least 4 characters have been received
        if (clen>3)
        {
            //Cycle through received data to search for a command
            for (cbc=0;cbc<clen-3;cbc++)
            {
                //Check fast message configuration
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC0))
                {
                    sport0.write(cbuf,clen);
                    if (myDevice.chkCfgMsg(cbuf,clen))
                    {
                        //netStat.bit_toclear(fmCfgInProg);
                        netStat.bit_toset(devOnline);
                        clen=0;
                        netStat.iedOnline(true);
                    }
                    break;
                }
                //Check to see if serial commands are currently being received
                if (netStat.bit_isset(serPollInProg))
                {
                    //If relay acknowledges max metering command set bulk receive flag
                    if ((cbuf[cbc]==0x4d) && (cbuf[cbc+1]==0x45) && (cbuf[cbc+2]==0x54))
                    {
                        sport0.write(cbuf,clen);
                        netStat.bit_toset(serMsgRx);
                        netDevTimers[5].reset();
                        netStat.setDevMsgReq(0);
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                    //If relay acknowledges tap report command set bulk receive flag
                    if ((cbuf[cbc]==0x54) && (cbuf[cbc+1]==0x41) && (cbuf[cbc+2]==0x50))
                    {
                        sport0.write(cbuf,clen);
                        netStat.bit_toset(serMsgRx);
                        netDevTimers[5].reset();
                        netStat.setDevMsgReq(0);
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                    //If relay acknowledges level 1 login attempt increment command pointer to password
                    if ((cbuf[cbc]==0x41) && (cbuf[cbc+1]==0x43) && (cbuf[cbc+2]==0x43))
                    {
                        sport0.write(cbuf,clen);
                        netStat.setDevMsgPos(1);
                        sendSerCmd(serCmdSeq[netStat.getDevMsgReq()][netStat.getDevMsgPos()],serCmdlen[netStat.getDevMsgReq()][netStat.getDevMsgPos()]);
                        netDevTimers[5].reset();
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                    //If relay sends mask character increment command pointer to send \r\n
                    if (cbuf[cbc]==0x2a)
                    {
                        sport0.write(cbuf,clen);
                        netStat.setDevMsgPos(2);
                        sendSerCmd(serCmdSeq[netStat.getDevMsgReq()][netStat.getDevMsgPos()],serCmdlen[netStat.getDevMsgReq()][netStat.getDevMsgPos()]);
                        netDevTimers[5].reset();
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                    //If relay is in access level 1 or higher increment command pointer to desired command
                    if ((cbuf[cbc]==0x3d) && (cbuf[cbc+1]==0x3e))
                    {
                        sport0.write(cbuf,clen);
                        netStat.setDevMsgPos(4);
                        sendSerCmd(serCmdSeq[netStat.getDevMsgReq()][netStat.getDevMsgPos()],serCmdlen[netStat.getDevMsgReq()][netStat.getDevMsgPos()]);
                        netDevTimers[5].reset();
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                    //If relay in level 0 increment command pointer to access command
                    if ((cbuf[cbc]==0x3d))
                    {
                        sport0.write(cbuf,clen);
                        netStat.setDevMsgPos(0);
                        sendSerCmd(serCmdSeq[netStat.getDevMsgReq()][netStat.getDevMsgPos()],serCmdlen[netStat.getDevMsgReq()][netStat.getDevMsgPos()]);
                        netDevTimers[5].reset();
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                }
                //if (bit_isset(net2->statusReg,fmPollInProg))
                if (netStat.bit_isset(fmPollInProg))
                {
                    //Check fast meter configuration
                    if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC1))
                    {
                        sport0.write(cbuf,clen);
                        if (myDevice.chkMeterMsg(cbuf,clen))
                        {
                            netStat.bit_toset(fmOnline);
                            clen=0;
                            netStat.iedOnline(true);
                            break;
                        }
                        break;
                    }
                    //Receive data
                    if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xD1))
                    {
                        myDevice.setMeterData(cbuf, cbc,clen);
                        clen=0;
                        netStat.iedOnline(true);
                        break;
                    }
                }
                if (netStat.bit_isset(fmdPollInProg))
                {
                    //Check fast demand meter configuration
                    if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC2))
                    {
                        sport0.write(cbuf,clen);
                        if (myDevice.chkDemMeterMsg(cbuf,clen))
                        {
                            netStat.bit_toset(fmdOnline);
                            clen=0;
                            netStat.iedOnline(true);
                            break;
                        }
                        break;
                    }
                    //Receive demand data
                    if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xD2))
                    {
                        myDevice.setDemMeterData(cbuf, cbc,clen);
                        netStat.iedOnline(true);
                        break;
                    }
                }
            }
            if (clen>0)
            {
                #ifdef netmsgdebug
                printf("Command not Received\r\n");
                #endif
                clen=0;
            }
        }
    }
}

//Ethernet to Ethernet Send Data
void datantx(netsys *net2)
{
    while(1)
    {
        if (netStat.bit_isset(cltIsActive))
        {
            //Attempt to connect to server
            while (net2->sendState==3)
            {
                //Attempt to connect
                ret = net2->srv_sock.connect(net2->srv_addr,net2->cltPort);
                //If connect successful proceed to send data
                if (ret==0)
                {
                    #ifdef netmsgdebug
                    printf("Connected %d\r\n",ret);
                    #endif
                    net2->sendState=4;
                }
                //If connect attempt failed check to see if may already be connected
                else if (ret==-3015)
                {
                    #ifdef netmsgdebug
                    printf("May already be connected, attempting send.\r\n");
                    #endif
                    net2->sendState=4;
                }
                else
                {
                    #ifdef netmsgdebug
                    printf("Communication Failed, Closing\r\n");
                    #endif
                    net2->sendRetryCount = 0;
                    netStat.iedOnline(false);
                    netStat.bit_toset(cltCloseConnection);
                    net2->sendState=0;
                }
            }
            //Attempt to send data
            while (net2->sendState==4)
            {
                if (net2->sendLen>0)
                {
                    //Attempt to send data
                    ret = net2->srv_sock.send(net2->sendString,net2->sendLen);
                    //If data send successful proceed to wait for response
                    if (ret>=0)
                    {
                        net2->sendLen=0;
                        #ifdef netmsgdebug
                        printf("Send Result %d\r\n",ret);
                        #endif
                        netStat.incCount(1);
                        net2->sendState=5;
                    }
                    else
                    {
                        #ifdef netmsgdebug
                        printf("Communication Failed, Closing\r\n");
                        #endif
                        net2->sendRetryCount = 0;
                        netStat.iedOnline(false);
                        netStat.bit_toset(cltCloseConnection);
                        net2->sendState=0;
                    }
                }
                else
                {
                    net2->sendState=5;
                }
            }
        }
    }
}

//Ethernet receive data and send to aux devices (serial, etc...)
void datancrx(netsys *net2)
{
    char rxbuf[256];
    int rxlen=0;
    int rxc;
    while (1)
    {
        //If the client is active check to see if data has been received
        while (netStat.bit_isset(cltIsActive))
        {
            //Store the length of the received data
            rxlen=net2->srv_sock.recv(rxbuf, sizeof(rxbuf));
            //if there is data then push data into received buffer
            if (rxlen>0)
            {
                for (rxc = 0;rxc<rxlen;rxc++)
                {
                    receiveBuffer.push(rxbuf[rxc]);
                }
                #ifdef netmsgdebug
                printf("Client Received Data\r\n");
                #endif
                //Increment received message counter
                netStat.incCount(2);
            }
        }
    }
}

//Serial device to server
void datasrx(netsys *net2)
{
    char rxbuf[256];
    int rxlen=0;
    int rxindex=0;
    int rxc;
    bool crRx = false;
    int4byte cmdpack;
    
    while (1)
    {
        //Check to see if there is any data received by serial port and store length
        rxlen=sport0.readable();
        //If data is ready push into receive buffer
        if (rxlen>0)
        {
            for (rxc=0;rxc<rxlen;rxc++)
            {
                #ifdef netmsgdebug
                printf("Serial Data Received\r\n");
                #endif
                rxbuf[rxindex+rxc]=sport0.getc();
                //Check to see if a carriage return has been detected
                if (rxbuf[rxindex+rxc]=='\r')
                {
                    crRx=true;
                }
            }
            //Store the current cursor location in the buffer
            rxindex=rxindex+rxlen;
            //Set the received length to zero
            rxlen=0;
            //If there is data in the buffer and a carriage return has been detected search for a command
            if ((rxindex>2) && (crRx==true))
            {
                //Set the carriage return flag false
                crRx=false;
                for (rxc=0;rxc<=rxindex-3;rxc++)
                {
                    cmdpack.bytes[3]=rxbuf[rxc];
                    cmdpack.bytes[2]=rxbuf[rxc+1];
                    cmdpack.bytes[1]=rxbuf[rxc+2];
                    cmdpack.bytes[0]=rxbuf[rxc+3];
                    //Search for the Min/Max command
                    if (cmdpack.cmdint==0x4d45544d)
                    {
                        #ifdef netmsgdebug
                        printf("MIN MAX METERING\r\n");
                        #endif
                        netStat.setDevMsgReq(0);
                        netStat.setDevMsgPos(2);
                        netStat.bit_toset(serPollReq);
                        rxindex=0;
                    }
                    //Search for the Tap Report Command
                    if (cmdpack.cmdint==0x54415052)
                    {
                        #ifdef netmsgdebug
                        printf("TAP REPORT\r\n");
                        #endif
                        netStat.setDevMsgReq(1);
                        netStat.setDevMsgPos(2);
                        netStat.bit_toset(serPollReq);
                        rxindex=0;
                    }
                    //Search for the Status Command
                    if (cmdpack.cmdint==0x53544154)
                    {
                        #ifdef netmsgdebug
                        printf("STATS\r\n");
                        #endif
                        sport0.printf("\r\nStatus %08x\r\n",netStat.getStatus());
                        sport0.printf("Messages Sent: %d\r\n",netStat.getCount(1));
                        sport0.printf("Messages Received: %d\r\n",netStat.getCount(2));
                        sport0.printf("Fast Message Timeouts: %d\r\n",netStat.getCount(3));
                        sport0.printf("Serial Timeouts: %d\r\n",netStat.getCount(4));
                        sport0.printf("Messages Failed: %d\r\n\r\n",netStat.getCount(5));
                        rxindex=0;
                    }
                    //Search for the Target Command
                    if (cmdpack.cmdint==0x54415247)
                    {
                        char *dTargets;
                        #ifdef netmsgdebug
                        printf("Targets\r\n");
                        #endif
                        sport0.printf("\r\nTarget 0 %08x\r\n",dTargets[0]);
                        sport0.printf("\r\nTarget 1 %08x\r\n",dTargets[1]);
                        sport0.printf("\r\nTarget 2 %08x\r\n",dTargets[2]);
                        sport0.printf("\r\nTarget 3 %08x\r\n",dTargets[3]);
                        sport0.printf("\r\nTarget 4 %08x\r\n",dTargets[4]);
                        sport0.printf("\r\nTarget 5 %08x\r\n",dTargets[5]);
                        sport0.printf("\r\nTarget 6 %08x\r\n",dTargets[6]);
                        sport0.printf("\r\nTarget 7 %08x\r\n",dTargets[7]);
                        sport0.printf("\r\nTarget 8 %08x\r\n",dTargets[8]);
                        sport0.printf("\r\nTarget 9 %08x\r\n",dTargets[9]);
                        rxindex=0;
                    }
                }
                //If no command found set cursor location to zero
                if (rxindex>0)
                {
                    #ifdef netmsgdebug
                    printf("Serial Command Not Found");
                    #endif
                    rxindex=0;
                }
            }
        }
    }
}

int main()
{
    EthernetInterface eth;
    eth.set_network(setseveraddress,setsevermask,setsevergateway); //Use  these parameters for static IP
    eth.connect();
    
    //initVoltageRegulator(&vReg1);
    
    #ifdef netmsgdebug
    printf("The target IP address is '%s'\r\n", eth.get_ip_address());
    #endif
    confignetdevices(&eth);
    /* Setup polltick Ticker */
    nettimer.attach_us(heartbeat,10000);
    /* Setup Ethernet to Serial transmit data Thread */
    rxtxdatathread[0].start(callback(datancrx,&net1));
    /* Setup Ethernet to Serial receive data Thread */
    rxtxdatathread[1].start(callback(datasrx,&net1));
    rxtxdatathread[2].start(callback(datantx,&net1));
    rxtxdatathread[3].start(callback(dataprocess,&net1));

    unsigned int sxc;
    
    netDevTimers[0].start();
    netDevTimers[2].start();
    netDevTimers[3].start();
    netDevTimers[6].start();
    
    while (true) {
        
        polltick=getPollTick();
        
        if (polltick)
        {
            setPollTick(false);
            if (netStat.bit_isset(serCloseConnection))
            {
                #ifdef netmsgdebug
                printf("Serial Connection Closed\r\n");
                #endif
                if (netStat.bit_isset(serRespRx))
                {
                    netStat.incCount(2);
                }
                else
                {
                    netStat.incCount(4);
                }
                netStat.bit_toclear(serclose);
                netStat.bit_toset(cltCloseConnection);
            }
            if (netStat.bit_isset(fmCloseConnection))
            {
                #ifdef netmsgdebug
                printf("Fast Meter Connection Closed\r\n");
                #endif
                if ((netStat.bit_isset(fmRespRx)) || (netStat.bit_isset(fmdRespRx)))
                {
                    netStat.incCount(2);
                }
                else
                {
                    netStat.incCount(3);
                }
                netStat.bit_toclear(fmclose);
                netStat.bit_toset(cltCloseConnection);
            }
            if (netStat.bit_isset(cltCloseConnection))
            {
                sport0.printf("Status %08x\r\n",netStat.getStatus());
                #ifdef netmsgdebug
                printf("Connection Closed\r\n");
                #endif
                net1.srv_sock.close();
                net1.sendState=0;
                netStat.bit_toclear(cltclose);
            }
            
            if ((netStat.bit_isclear(serPollInProg)) && (netStat.bit_isclear(fmPollInProg)) && (netStat.bit_isclear(fmdPollInProg)))
            {
                if (netStat.bit_isset(recDataFile))
                {
                    char dataStrLen=0;
                    char dataStr[256];
                    dataStrLen=myDevice.getMeterReport(&dataStr[0]);
                    sport0.write(dataStr,dataStrLen);
                    
                    netStat.bit_toclear(recDataFile);
                    netDevTimers[6].reset();
                    netDevTimers[6].start();
                }
                if ((net1.sendState==0) || (net1.sendState==5))
                {
                    if ((netStat.bit_isset(fmdPollReq)) && (netStat.bit_isset(devOnline)))
                    {
                        if (netStat.bit_isset(fmdOnline))
                        {
                            printf("Demand Reading\r\n");
                            sendCmd(4);
                            netStat.bit_toclear(fmdPollReq);
                            netStat.bit_toset(fmdPollInProg);
                        }
                        else
                        {
                            printf("Demand Configuration\r\n");
                            sendCmd(3);
                            netStat.bit_toclear(fmdPollReq);
                            netStat.bit_toset(fmdPollInProg);
                        }
                        netDevTimers[4].reset();
                        netDevTimers[4].start();
                    }
                    else if (netStat.bit_isset(serPollReq))
                    {
                        if (netStat.bit_isset(serEnabled))
                        {
                            sendSerCmd(serCmdSeq[netStat.getDevMsgReq()][netStat.getDevMsgPos()],serCmdlen[netStat.getDevMsgReq()][netStat.getDevMsgPos()]);
                            netStat.bit_toclear(serPollReq);
                            netStat.bit_toset(serPollInProg);
                            netDevTimers[5].reset();
                            netDevTimers[5].start();
                        }
                        else
                        {
                            netStat.bit_toclear(serPollReq);
                        }
                    }
                    else if ((netStat.bit_isset(fmPollReq)) && (netStat.bit_isset(devOnline)))
                    {
                        if (netStat.bit_isset(fmOnline))
                        {
                            printf("Meter Reading\r\n");
                            sendCmd(2);
                            netStat.bit_toclear(fmPollReq);
                            netStat.bit_toset(fmPollInProg);
                        }
                        else
                        {
                            printf("Meter Configuration\r\n");
                            sendCmd(1);
                            netStat.bit_toclear(fmPollReq);
                            netStat.bit_toset(fmPollInProg);
                        }
                        netDevTimers[4].reset();
                        netDevTimers[4].start();
                    }
                }
            }
            if ((netStat.bit_isclear(devOnline)) &&  (netStat.bit_isclear(fmCfgInProg)) && (netStat.bit_isset(fmCfgReq)))
            {
                sendCmd(0);
                netStat.bit_toclear(fmCfgReq);
                netStat.bit_toset(fmCfgInProg);
                net1.sendState=1;
                netDevTimers[4].reset();
                netDevTimers[4].start();
            }
        }
        
        
        //Begin Sending Data
        sendtick=getSendTick();
        
        if (sendtick)
        {
            setSendTick(false);
            switch (net1.sendState)
            {
                case 0:
                    if (!sendLength.empty())
                    {
                        sport0.printf("Status %08x\r\n",netStat.getStatus());
                        sendLength.pop(net1.sendLen);
                        for (sxc=0;sxc<net1.sendLen;sxc++)
                        {
                            sendBuffer.pop(net1.sendString[sxc]);
                        }
                        net1.sendState=1;
                    }
                    break;
                case 1:
                    ret=net1.srv_sock.open(&eth);
                    #ifdef netmsgdebug
                    printf("Socket%d\r\n",ret);
                    #endif
                    if (ret < 0)
                    {
                        if (ret==-3003)
                        {
                            #ifdef netmsgdebug
                            printf("May already be attached, attempting connect.\r\n");
                            #endif
                        }
                        else
                        {
                            #ifdef netmsgdebug
                            printf("Communication Failed, Closing\r\n");
                            #endif
                            net1.sendRetryCount = 0;
                            netStat.iedOnline(false);
                            net1.sendState=0;
                            break;
                        }
                    }
                    net1.sendState=3;
                    netStat.bit_toset(cltIsActive);
                    break;
                case 5:
                    if (!sendLength.empty())
                    {
                        sport0.printf("Status %08x\r\n",netStat.getStatus());
                        sendLength.pop(net1.sendLen);
                        for (sxc=0;sxc<net1.sendLen;sxc++)
                        {
                            sendBuffer.pop(net1.sendString[sxc]);
                        }
                        net1.sendState=4;
                    }
                    break;
                default:
                    break;
            }
        }
    }
}