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:
2019-10-02
Revision:
11:d40adc7de05f
Parent:
10:9da863a6da3e
Child:
12:4bb088c27838

File content as of revision 11:d40adc7de05f:

#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"

Ticker nettimer;

struct netsys net1;
struct vRegData vReg1;

analogAverager voltageAvg(120,true,0.9,true,1.1);
analogMinMax voltageMinMax(120,true,0.9,true,1.1);
counterMinMax tapMinMax(0,true,-16,true,16);

bool polltick;

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

CircularBuffer<char, 1024> receiveBuffer;
CircularBuffer<char, 64> sendLength;
CircularBuffer<char, 1024> sendBuffer;
CircularBuffer<char, 16> serrxbuffer;

Thread conchkthread[2];
Thread rxtxdatathread[5];

unsigned int currenttime=0;

nsapi_error_t ret;

//Provides the deivce poll timing
void heartbeat()
{
    setTick(true);
}

void confignetdevices(EthernetInterface *eth)
{   
    net1.cltPort=setclientport;
    net1.srv_addr=setclientaddress;
    net1.cltIsActive=false;
    net1.serIsActive=false;
    net1.cltCloseConnection=false;
    net1.pollTime=0;
    net1.pollTimeout=0;
    net1.pollRequestSent=false;
    net1.pollResponseReceived=false;
    net1.srv_sock.set_blocking(true);
    net1.srv_sock.set_timeout(100);
    net1.aliveTimeout=setservertimeout;
    net1.srv.set_blocking(true);
    net1.srv.set_timeout(100);
    net1.pollEnabled=setpollenabled;
    net1.pollTimeoutCount=0;
    net1.configState=0;
    net1.pollTimeoutCount=0;
    net1.sendRetryCount=0;
    net1.messageFailCount=0;
    net1.txMessageCount=0;
    net1.rxMessageCount=0;
    net1.fmEnabled=false;
    net1.fmdEnabled=false;
    
    /* Open the server on ethernet stack */
    net1.srv.open(eth);
    net1.srvIsActive=false;
    net1.srvCloseConnection=false;
    
    /* Bind port 23 to the server */
    net1.srvPort=setserverport;
    net1.srv.bind(net1.srvPort);
    
    /* Can handle 5 simultaneous connections */
    net1.srv.listen(5);
    sport0.baud(sport0baud);
}

void dataprocess(netsys *net2)
{
    int txc;
    char cchar;
    char cbuf[256];
    unsigned int clen=0;
    unsigned int cbc;
    float4byte valpack;
    short2byte timepack;
    
    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
        if (net2->pollRequestSent)
        {
            if (clen>0)
            {
                net2->pollResponseReceived=true;
            }
        }
        //Check to see if bulk data and reports being sent from device due to serial command
        if (net2->devMsgOpenRx)
        {
            sport0.write(cbuf,clen);
            clen=0;
        }
        //Check to see if at least 4 characters have been received
        else if (clen>3)
        {
            //Cycle through received data to search for a command
            for (cbc=0;cbc<clen-3;cbc++)
            {
                //Check to see if serial commands are currently being received
                if (net2->serIsActive==true)
                {
                    //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);
                        net2->devMsgOpenRx=true;
                        net2->devMsgReq=0;
                        clen=0;
                        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);
                        net2->devMsgOpenRx=true;
                        net2->devMsgReq=0;
                        clen=0;
                        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);
                        net2->devMsgPos=1;
                        clen=0;
                        break;
                    }
                    //If relay sends mask character increment command pointer to send \r\n
                    if (cbuf[cbc]==0x2a)
                    {
                        sport0.write(cbuf,clen);
                        net2->devMsgPos=2;
                        clen=0;
                        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);
                        net2->devMsgPos=4;
                        clen=0;
                        break;
                    }
                    //If relay in level 0 increment command pointer to access command
                    if ((cbuf[cbc]==0x3d))
                    {
                        sport0.write(cbuf,clen);
                        net2->devMsgPos=0;
                        clen=0;
                        break;
                    }
                }
                //Check fast message conficuration
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC0))
                {
                    sport0.write(cbuf,clen);
                    net2->configState=1;
                    clen=0;
                    break;
                }
                //Check fast meter configuration
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC1))
                {
                    sport0.write(cbuf,clen);
                    //Ensure Analog channl count is correct
                    if (vReg1.numAnalog!=cbuf[6])
                    {
                        #ifdef netmsgdebug
                        printf("\r\nFast Meter Analog Channel Count Off\r\n");
                        #endif
                        clen=0;
                        break;
                    }
                    //Ensure Digital register count is correct
                    if (vReg1.numDigital!=cbuf[8])
                    {
                        #ifdef netmsgdebug
                        printf("\r\nFast Meter Digital Channel Count Off\r\n");
                        #endif
                        clen=0;
                        break;
                    }
                    char anum=16;
                    char nxc;
                    //Verify Analog names are correct
                    for (txc=0;txc<vReg1.numAnalog;txc++)
                    {
                        for (nxc=0;nxc<6;nxc++)
                        {
                            if(vReg1.analogs[txc].analogName[nxc]!=cbuf[anum+nxc])
                            {
                                #ifdef netmsgdebug
                                printf("\r\nPoint %d Failed\r\n",txc);
                                #endif
                                break;
                            }
                        }
                        anum = anum + 11;
                    }
                    net2->configState=3;
                    net2->fmEnabled=true;
                    clen=0;
                    break;
                }
                //Receive data
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xD1))
                {
                    char anum=cbc+4;
                    for (txc=0;txc<vReg1.numAnalog;txc++)
                    {
                        valpack.bytes[3]=cbuf[anum];
                        valpack.bytes[2]=cbuf[anum+1];
                        valpack.bytes[1]=cbuf[anum+2];
                        valpack.bytes[0]=cbuf[anum+3];
                        vReg1.analogs[txc].analog1Value = valpack.cmdflt;
                        anum = anum + 4;
                        printf("%.2f\r\n",vReg1.analogs[txc].analog1Value);
                    }
                    vReg1.timeStamp.month=cbuf[anum];
                    vReg1.timeStamp.day=cbuf[anum+1];
                    vReg1.timeStamp.year=cbuf[anum+2];
                    vReg1.timeStamp.hour=cbuf[anum+3];
                    vReg1.timeStamp.min=cbuf[anum+4];
                    vReg1.timeStamp.sec=cbuf[anum+5];
                    timepack.bytes[1]=cbuf[anum+6];
                    timepack.bytes[0]=cbuf[anum+7];
                    vReg1.timeStamp.msec=timepack.cmdshort;
                    printf("%d/%d/%d %d:%d:%d.%d\r\n",vReg1.timeStamp.month,vReg1.timeStamp.day,vReg1.timeStamp.year,vReg1.timeStamp.hour,vReg1.timeStamp.min,vReg1.timeStamp.sec,vReg1.timeStamp.msec);
                    anum=anum+8;
                    for (txc=0;txc<vReg1.numDigital;txc++)
                    {
                        vReg1.digitalTargets[txc]=cbuf[anum+txc];
                    }
                    clen=0;
                    tapMinMax.putVal(vReg1.analogs[7].analog1Value);
                    voltageMinMax.putVal(vReg1.analogs[9].analog1Value);
                    voltageAvg.putVal(vReg1.analogs[9].analog1Value);
                    break;
                }
                //Check fast demand meter configuration
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xC2))
                {
                    sport0.write(cbuf,clen);
                    //Ensure Analog channl count is correct
                    if (vReg1.numDemAnalog!=cbuf[6])
                    {
                        #ifdef netmsgdebug
                        printf("\r\nDemand Analog Channel Count Off\r\n");
                        #endif
                        clen=0;
                        break;
                    }
                    char anum=18;
                    char nxc;
                    //Verify Analog names are correct
                    for (txc=0;txc<vReg1.numDemAnalog;txc++)
                    {
                        for (nxc=0;nxc<6;nxc++)
                        {
                            if(vReg1.analogs[txc+vReg1.numAnalog].analogName[nxc]!=cbuf[anum+nxc])
                            {
                                #ifdef netmsgdebug
                                printf("\r\nPoint %d Failed\r\n",txc);
                                #endif
                                break;
                            }
                        }
                        anum = anum + 11;
                    }
                    net2->configState=9;
                    net2->fmdEnabled=true;
                    clen=0;
                    break;
                }
                //Receive demand data
                if ((cbuf[cbc]==0xA5) && (cbuf[cbc+1]==0xD2))
                {
                    char anum=cbc+4;
                    for (txc=0;txc<vReg1.numDemAnalog;txc++)
                    {
                        valpack.bytes[3]=cbuf[anum];
                        valpack.bytes[2]=cbuf[anum+1];
                        valpack.bytes[1]=cbuf[anum+2];
                        valpack.bytes[0]=cbuf[anum+3];
                        vReg1.analogs[txc].analog1Value = valpack.cmdflt;
                        anum = anum + 4;
                        //printf("%.2f\r\n",vReg1.analogs[txc].analog1Value);
                    }
                    vReg1.demTimeStamp.month=cbuf[anum];
                    vReg1.demTimeStamp.day=cbuf[anum+1];
                    vReg1.demTimeStamp.year=cbuf[anum+2];
                    vReg1.demTimeStamp.hour=cbuf[anum+3];
                    vReg1.demTimeStamp.min=cbuf[anum+4];
                    vReg1.demTimeStamp.sec=cbuf[anum+5];
                    timepack.bytes[1]=cbuf[anum+6];
                    timepack.bytes[0]=cbuf[anum+7];
                    vReg1.demTimeStamp.msec=timepack.cmdshort;
                    sport0.printf("%d/%d/%d %d:%d:%d.%d\r\n",vReg1.demTimeStamp.month,vReg1.demTimeStamp.day,vReg1.demTimeStamp.year,vReg1.demTimeStamp.hour,vReg1.demTimeStamp.min,vReg1.demTimeStamp.sec,vReg1.demTimeStamp.msec);
                    vReg1.calculated[0].analog1Value=voltageMinMax.getMin();
                    vReg1.calculated[1].analog1Value=voltageAvg.getAvg();
                    vReg1.calculated[2].analog1Value=voltageMinMax.getMax();
                    vReg1.calculated[3].analog1Value=tapMinMax.getMin();
                    vReg1.calculated[4].analog1Value=tapMinMax.getMax();
                    sport0.printf("%.2f\r\n",vReg1.calculated[0].analog1Value);
                    sport0.printf("%.2f\r\n",vReg1.calculated[1].analog1Value);
                    sport0.printf("%.2f\r\n",vReg1.calculated[2].analog1Value);
                    sport0.printf("%.2f\r\n",vReg1.calculated[3].analog1Value);
                    sport0.printf("%.2f\r\n",vReg1.calculated[4].analog1Value);
                    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 (net2->cltIsActive)
        {
            //Attempt to connect to server
            while (net2->sendState==3)
            {
                //delay connect attempt if previous attempt unsuccessful
                if (net2->connectRetry == true)
                {
                    wait_ms(100);
                }
                //Attempt to connectg
                ret = net2->srv_sock.connect(net2->srv_addr,net2->cltPort);
                //If connect successful proceed to send data
                if (ret==0)
                {
                    net2->connectRetry = false;
                    #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->connectRetry = false;
                    net2->sendState=4;
                }
                //If connect attempt failed on other error attempt reconnect
                else
                {
                    net2->connectRetry = true;
                    net2->sendRetryCount++;
                    #ifdef netmsgdebug
                    printf("Connect Attempt Failed, Code: %d\r\n",ret);
                    #endif
                    //If connect attempt failed exceeds 3 then end attempt
                    if (net2->sendRetryCount>3)
                    {
                        #ifdef netmsgdebug
                        printf("Communication Failed, Closing\r\n");
                        #endif
                        net2->connectRetry = false;
                        net2->sendRetryCount = 0;
                        net2->messageFailCount++;
                        net2->cltCloseConnection=true;
                        net2->sendState=0;
                        net2->sendTime=0;
                    }
                }
            }
            //Attempt to send data
            while (net2->sendState==4)
            {
                //Delay send data attempt if previous attempt failed
                if (net2->sendRetry == true)
                {
                    wait_ms(100);
                }
                //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)
                {
                    #ifdef netmsgdebug
                    printf("Send Result %d\r\n",ret);
                    #endif
                    net2->sendRetry = false;
                    net2->txMessageCount++;
                    net2->sendState=5;
                    net2->sendTime=0;
                }
                //If send attempt failed attempt to re-send data
                else
                {
                    net2->sendRetry = true;
                    net2->sendRetryCount++;
                    #ifdef netmsgdebug
                    printf("Send Attempt Failed, Code: %d\r\n",ret);
                    #endif
                    //If send attempt failed exceeds 3 then end attempt
                    if (net2->sendRetryCount>3)
                    {
                        #ifdef netmsgdebug
                        printf("Communication Failed, Closing\r\n");
                        #endif
                        net2->sendRetry = false;
                        net2->sendRetryCount = 0;
                        net2->messageFailCount++;
                        net2->cltCloseConnection=true;
                        net2->sendState=0;
                        net2->sendTime=0;
                    }
                }
            }
        }
    }
}

//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 (net2->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)
            {
                net2->aliveTime=0;
                for (rxc = 0;rxc<rxlen;rxc++)
                {
                    receiveBuffer.push(rxbuf[rxc]);
                }
                #ifdef netmsgdebug
                printf("Client Received Data\r\n");
                #endif
                //Increment received message counter
                net2->rxMessageCount++;
            }
        }
    }
}

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

//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++)
            {
                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;
            //printf("%d\r\n",rxlen);
            //printf("%d\r\n",rxindex);
            //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];
                    //printf("%08x\r\n",cmdpack.cmdint);
                    //Search for the Min/Max command
                    if (cmdpack.cmdint==0x4d45544d)
                    {
                        #ifdef netmsgdebug
                        printf("MIN MAX METERING\r\n");
                        #endif
                        net2->devMsgReq=1;
                        net2->devMsgPos=2;
                        rxindex=0;
                    }
                    //Search for the Tap Report Command
                    if (cmdpack.cmdint==0x54415052)
                    {
                        #ifdef netmsgdebug
                        printf("TAP REPORT\r\n");
                        #endif
                        net2->devMsgReq=2;
                        net2->devMsgPos=2;
                        rxindex=0;
                    }
                }
                //If no command found set cursor location to zero
                if (rxindex>0)
                {
                    #ifdef netmsgdebug
                    printf("Serial Command Not Found");
                    #endif
                    rxindex=0;
                }
            }
        }
    }
}

//Checks for a Ethernet to Serial connection
void conchk(netsys *net2)
{
    TCPServer *server=&(net2->srv);
    TCPSocket *client_socket=&(net2->clt_sock);
    SocketAddress *client_address=&(net2->clt_addr);
    
    while(1)
    {
        //Wait for someone to connect
        while (server->accept(client_socket, client_address) < 0)
        {
            //printf("Connection Failed.\r\n");
        }
        #ifdef netmsgdebug
        printf("Server Port %d\r\n", net2->srvPort);
        printf("accept %s:%d\r\n", client_address->get_ip_address(), client_address->get_port());
        #endif
        net2->aliveTime=0;
        net2->srvIsActive=true;
    }
}

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

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 Ethernet to Serial Connection Thread */
    conchkthread[0].start(callback(conchk,&net1));
    /* Setup polltick Ticker */
    nettimer.attach_us(heartbeat,10000);
    /* Setup Ethernet to Serial transmit data Thread */
    rxtxdatathread[0].start(callback(datansrx,&net1));
    rxtxdatathread[1].start(callback(datancrx,&net1));
    /* Setup Ethernet to Serial receive data Thread */
    rxtxdatathread[2].start(callback(datasrx,&net1));
    rxtxdatathread[3].start(callback(datantx,&net1));
    rxtxdatathread[4].start(callback(dataprocess,&net1));
    
    unsigned int txc;
    unsigned int sxc;
    
    while (true) {
        
        polltick=getTick();
        
        if (polltick)
        {
            setTick(false);
            incTime();
            currenttime=getTime();
            net1.pollTime++;
            net1.fmPollTime++;
            net1.fmdPollTime++;
            net1.sendTime++;
            if (net1.srvIsActive)
            {
                net1.aliveTime++;
                if (net1.aliveTime>net1.aliveTimeout)
                {
                    #ifdef netmsgdebug
                    printf("Closed\r\n");
                    #endif
                    net1.clt_sock.close();
                    net1.srvIsActive=false;
                    net1.srvCloseConnection=false;
                }
                
            }
            if (net1.pollEnabled)
            {
                if (net1.pollTime >= setpollinterval)
                {
                    if ((net1.sendState==0)||(net1.sendState==5))
                    {
                        if (net1.devMsgReq>0)
                        {
                            net1.serTimeoutCount=0;
                            sendLength.push(serCmdSeq[2][net1.devMsgPos]);
                            for (txc=0;txc<serCmdSeq[2][net1.devMsgPos];txc++)
                            {
                                sendBuffer.push(serCmd[serCmdSeq[net1.devMsgReq-1][net1.devMsgPos]][txc]);
                            }
                            if (net1.serIsActive==false)
                            {
                                net1.serIsActive=true;
                            }
                        }
                        else
                        {
                            if (net1.configState<9)
                            {
                                sendCmd(net1.configState);
                                if (net1.sendState==0)
                                {
                                    net1.sendState=1;
                                    net1.pollRequestSent=true;
                                }
                            }
                        }
                        
                    }
                    net1.pollTime=0;
                }
                if (net1.fmPollTime >= setfmpollinterval)
                {
                    if (net1.serIsActive==false)
                    {
                        if ((net1.sendState==0)||(net1.sendState==5))
                        {
                            {
                                if (net1.fmEnabled)
                                {
                                    sendCmd(2);
                                    if (net1.sendState==0)
                                    {
                                        net1.sendState=1;
                                        net1.pollRequestSent=true;
                                    }
                                }
                            }
                        }
                        if (net1.fmPollTime>setfmpollinterval)
                        {
                            net1.fmPollTime=net1.fmPollTime-setfmpollinterval;
                        }
                        else
                        {
                            net1.fmPollTime=0;
                        }
                    }
                }
                if (net1.fmdPollTime >= setfmdemandpollinterval)
                {
                    if (net1.serIsActive==false)
                    {
                        if ((net1.sendState==0)||(net1.sendState==5))
                        {
                            {
                                if (net1.fmdEnabled)
                                {
                                    sendCmd(4);
                                    if (net1.sendState==0)
                                    {
                                        net1.sendState=1;
                                        net1.pollRequestSent=true;
                                    }
                                }
                            }
                        }
                        if (net1.fmdPollTime>setfmdemandpollinterval)
                        {
                            net1.fmdPollTime=net1.fmdPollTime-setfmdemandpollinterval;
                        }
                        else
                        {
                            net1.fmdPollTime=0;
                        }
                    }
                }
                if ((net1.sendState==5) || (net1.serIsActive))
                {
                    net1.pollTimeout++;
                    if (net1.pollTimeout==setpolltimeout)
                    {
                        if (net1.pollRequestSent)
                        {
                            #ifdef netmsgdebug
                            printf("Poll Request Sent\r\n");
                            #endif
                            if (net1.pollResponseReceived==false)
                            {
                                #ifdef netmsgdebug
                                printf("Poll Response Not Received\r\n");
                                #endif
                            }
                            else
                            {
                                #ifdef netmsgdebug
                                printf("Poll Response Received\r\n");
                                #endif
                            }
                            net1.pollRequestSent=false;
                            net1.pollResponseReceived=false;
                            if (net1.serIsActive==false)
                            {
                                net1.cltCloseConnection=true;
                                net1.sendState=0;
                            }
                        }
                        if (net1.serIsActive)
                        {
                            if ((net1.serTimeoutCount==sertimeoutperiods) || (net1.devMsgReq==0))
                            {
                                net1.devMsgOpenRx=false;
                                net1.cltCloseConnection=true;
                                net1.devMsgReq=0;
                                net1.serIsActive=false;
                                net1.sendState=0;
                            }
                            else
                            {
                                net1.pollTimeout=0;
                                net1.serTimeoutCount++;
                                #ifdef netmsgdebug
                                printf("Serial Active Timeout Count: %d\r\n",net1.serTimeoutCount);
                                #endif
                            }
                        }
                    }
                }
                else
                {
                    net1.pollTimeout=0;
                }
            }
            if (net1.sendTime == 10)
            {
                switch (net1.sendState)
                {
                    case 1:
                        if (!sendLength.empty())
                        {
                            sendLength.pop(net1.sendLen);
                            for (sxc=0;sxc<net1.sendLen;sxc++)
                            {
                                sendBuffer.pop(net1.sendString[sxc]);
                            }
                        }
                        else
                        {
                            net1.sendState=0;
                        }
                        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
                            {
                                net1.attachRetry = true;
                                net1.sendRetryCount=0;
                                net1.sendState=2;
                                net1.sendTime=0;
                                break;
                            }
                        }
                        net1.sendState=3;
                        net1.sendTime=11;
                        net1.cltIsActive=true;
                        break;
                    case 2:
                        ret=net1.srv_sock.open(&eth);
                        #ifdef netmsgdebug
                        printf("Socket%d\r\n",ret);
                        #endif
                        if (ret < 0)
                        {
                            net1.attachRetry = true;
                            net1.sendRetryCount++;
                            net1.sendTime=0;
                            #ifdef netmsgdebug
                            printf("Attach Attempt Failed, Code: %d\r\n",ret);
                            #endif
                            if (net1.sendRetryCount>3)
                            {
                                #ifdef netmsgdebug
                                printf("Communication Failed, Closing\r\n");
                                #endif
                                net1.attachRetry = false;
                                net1.sendRetryCount = 0;
                                net1.messageFailCount++;
                                net1.sendState=0;
                                net1.sendTime=0;
                            }
                            break;
                        }
                        net1.sendState=0;
                        net1.attachRetry = false;
                        net1.sendTime=11;
                        net1.cltIsActive=true;
                        break;
                    default:
                        net1.sendTime=0;
                        if (!sendLength.empty())
                        {
                            if (net1.sendState==5)
                            {
                                
                                sendLength.pop(net1.sendLen);
                                for (sxc=0;sxc<net1.sendLen;sxc++)
                                {
                                    sendBuffer.pop(net1.sendString[sxc]);
                                }
                                net1.sendState=4;
                            }
                            else
                            {
                                net1.sendState=1;
                            }
                        }
                        break;
                }
            }
        }
        if (net1.cltCloseConnection==true)
        {
            #ifdef netmsgdebug
            printf("Client Socket Closed\r\n");
            #endif
            net1.srv_sock.close();
            net1.cltIsActive=false;
            net1.cltCloseConnection=false;
            net1.sendState=0;
        }
    }
}