Ejemplo n.º 1
0
        // this implements the server/rig part
        public static void Run()
        {
            List <MsgHeader> lCliMsg = new List <MsgHeader>();

            _serialPort.PortName  = "com" + iCom;
            _serialPort.DtrEnable = true; // GR needed
            _serialPort.Open();

            _continue = true;
            Thread serialThread = new Thread(SerialOut);

            Console.WriteLine("Starting thread SerialOut");
            serialThread.Start();

MyStart:
            oldAvg    = 0;
            startTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

            //---listen at the specified IP and port no.---
            IPAddress   localAdd = IPAddress.Parse(sIP);
            TcpListener listener = new TcpListener(localAdd, iPort);

            Console.WriteLine("Listening on ip={0}, port={1} ...", sIP, iPort);
            listener.Start();

            //---incoming client connected---
            TcpClient client = listener.AcceptTcpClient();

            Console.WriteLine("Client connected with ip={0}", client.Client.RemoteEndPoint.ToString());


            //---get the incoming data through a network stream---
            NetworkStream nwStream = client.GetStream();

            byte[] buffer      = new byte[client.ReceiveBufferSize];
            int    iSrvCounter = 0;

            while (_continue)
            {
                try
                {
                    long lNowMs = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

                    //---read incoming stream--- which might contain multiple packets in one
                    int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

                    Dictionary <int, MsgHeader> dMH = new Dictionary <int, MsgHeader>();

                    // the read data may contain multiple msgHeader elements, we process all of them in this loop
                    for (int j = 0; j < bytesRead; j += iSizeMh)
                    {
                        byte[]    bufInstance = buffer.Skip(j).Take(iSizeMh).ToArray();
                        MsgHeader aH          = (MsgHeader)InterOp.ByteArrayToStruct(bufInstance, 0, typeof(MsgHeader));

                        if (!bDisableLogging)
                        {
                            Log2("I: " + Convert.ToInt32(lNowMs - startTime) + " index unsorted=" + aH.clientCounter);
                        }

                        dMH[aH.clientCounter] = aH;
                    }

                    int firstindex = -1;
                    int index      = 0;
                    // find the newest client packet, as we reset the counter after 255, need to do a search backwards
                    foreach (KeyValuePair <int, MsgHeader> elem in dMH)
                    {
                        index = elem.Key;
                        do
                        {
                            if ((firstindex < 0) || (firstindex > index))
                            {
                                firstindex = index;
                            }

                            if (!bDisableLogging)
                            {
                                Log2("I: " + Convert.ToInt32(lNowMs - startTime) + " index=" + index + " firstindex=" + firstindex);
                            }

                            index--;
                            if (index < 0)
                            {
                                index = 255;
                            }
                        } while (dMH.ContainsKey(index));
                    }

                    index = firstindex;
                    if (!bDisableLogging)
                    {
                        Log2("I: " + Convert.ToInt32(lNowMs - startTime) + " firstindex=" + firstindex);
                    }

                    if (index < 0) // Client disconnected
                    {
                        string sMsg = "Client disconnected.";
                        Console.WriteLine("\n{0}", sMsg);
                        _serialPort.RtsEnable = false;
                        Log2(sMsg);
                        client.Close();
                        listener.Stop();
                        waveOut.Stop();
                        goto MyStart;
                    }
                    // now process all all msgHeader elements stored in the dictionary dMH
                    while (dMH.ContainsKey(index))
                    {
                        MsgHeader aH            = dMH[index];
                        int       clientCounter = (int)aH.clientCounter;
                        int       serverCounter = (int)aH.serverCounter;

                        if (!bDisableLogging)
                        {
                            Log2("Server read: " + Convert.ToInt32(lNowMs - startTime) + " " +
                                 bytesRead + " clientCounter=" + clientCounter + " bitvector=" + Convert.ToString(aH.bitVector, 2).PadLeft(16, '0') +
                                 " serverCounter=" + serverCounter + " lMQ=" + lMQ.Count() + " lNQ=" + lNQ.Count());
                        }

                        // we sent to the client the serverCounter, which we now get back
                        // we can now calulate a roundtrip time seen on the server side
                        if (dServerTime.ContainsKey(serverCounter))
                        {
                            long srvMs = dServerTime[serverCounter];
                            int  iPing = Convert.ToInt32(lNowMs - srvMs);
                            CheckPing(iPing);
                            lock (dServerTime)
                                dServerTime.Remove(serverCounter);
                        }

                        // we add the data to be send to the serial port to the queue
                        SerialSend(aH);

                        // add a new server reference number and store the milliseconds since epoch in the dictionary dServerTime
                        aH.serverCounter = Convert.ToByte(iSrvCounter);

                        if (lNQ.Count < iQueueSize - 2)
                        {
                            aH.bitVector = 2; // send queue too small
                        }
                        else if (lNQ.Count > iQueueSize + 2)
                        {
                            aH.bitVector = 3; // send queue too big
                        }
                        else
                        {
                            aH.bitVector = 1;
                        }

                        lock (dServerTime)
                            dServerTime[iSrvCounter] = lNowMs;

                        if (!bDisableLogging)
                        {
                            Log2("Server send: " + Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - startTime) +
                                 " clientCounter=" + clientCounter + " bitvector=" + Convert.ToString(aH.bitVector, 2).PadLeft(16, '0') +
                                 " serverCounter=" + serverCounter + " lMQ=" + lMQ.Count() + " lNQ=" + lNQ.Count());
                        }

                        byte[] bytesToSend = InterOp.StructToByteArray(aH);
                        //---write back the text to the client---
                        nwStream.Write(bytesToSend, 0, bytesToSend.Length);

                        if (iSrvCounter == 255)
                        {
                            iSrvCounter = 0;
                        }
                        else
                        {
                            iSrvCounter++;
                        }

                        index++;
                        if (index > 255)
                        {
                            index = 0;
                        }
                    }

                    int iWaitMs = _waitMilliSecs - Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - lNowMs);
                    if (iWaitMs < 0)
                    {
                        iWaitMs = 0;
                    }
                    Thread.Sleep(iWaitMs);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Server exception: {0}", e);
                    _serialPort.RtsEnable = false;
                    client.Close();
                    listener.Stop();
                    waveOut.Stop();
                    goto MyStart;
                }
            }
            _continue = false;
            serialThread.Join();
            _serialPort.Close();
        }
Ejemplo n.º 2
0
        public static void NetSendThread()
        {
            //---create a TCPClient object at the IP and port no.---
            TcpClient     client   = new TcpClient(sIP, iPort);
            NetworkStream nwStream = client.GetStream();

            Console.WriteLine("Client connected with IP {0}", client.Client.RemoteEndPoint.ToString());

            while (_continue)
            {
                long ms1 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

                // we take over the data to send from the list lMQ into our privat list lNQ
                lock (lMQ) {
                    lock (lNQ)
                        lNQ.AddRange(lMQ);
                    lMQ.Clear();
                }

                if (lNQ.Count > 100)
                {
                    Console.WriteLine("Client has a large queue, probably the communication to the server is broken. Giving up.");
                    _continue = false;
                }

                while (lNQ.Count > 0)
                {
                    MsgHeader aHs = lNQ[0];

                    lNQ.RemoveAt(0);

                    int clientCounter = aHs.clientCounter;

                    int serverCounter;
                    // the client stores a list of reference numbers sent by the server
                    // when the client sends this back to the server, it removes it from the list as done
                    if (lSrvNos.Count > 0)
                    {
                        serverCounter = lSrvNos[0];
                        lock (lSrvNos)
                            lSrvNos.RemoveAt(0);
                    }
                    else
                    {
                        serverCounter = 0;
                        Log2("Client send: " + Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - startTime) + " Warning: No Server counter found: " + iSizeMh +
                             " clientCounter=" + clientCounter + " bitVector=" + Convert.ToString(aHs.bitVector, 2).PadLeft(16, '0') +
                             " serverCounter=" + serverCounter + " lMQ=" + lMQ.Count() + " lNQ=" + lNQ.Count());
                    }

                    aHs.serverCounter = Convert.ToByte(serverCounter);

                    if (!bDisableLogging)
                    {
                        Log2("Client send: " + Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - startTime) + " " + iSizeMh +
                             " clientCounter=" + clientCounter + " bitVector=" + Convert.ToString(aHs.bitVector, 2).PadLeft(16, '0') +
                             " serverCounter=" + serverCounter + " lMQ=" + lMQ.Count() + " lNQ=" + lNQ.Count());
                    }

                    byte[] bytesToSend = InterOp.StructToByteArray(aHs);
                    nwStream.Write(bytesToSend, 0, bytesToSend.Length);

                    //System.Console.WriteLine("client.ReceiveBufferSize={0}", client.ReceiveBufferSize);

                    byte[] buffer = new byte[client.ReceiveBufferSize];

                    //---read incoming stream--- which might contain multiple packets in one
                    int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

                    // the read data may contain multiple msgHeader elements, we process all of them in this loop
                    for (int j = 0; j < bytesRead; j += iSizeMh)
                    {
                        byte[]    bufInstance = buffer.Skip(j).Take(iSizeMh).ToArray();
                        MsgHeader aHr         = (MsgHeader)InterOp.ByteArrayToStruct(bufInstance, 0, typeof(MsgHeader));

                        clientCounter = aHr.clientCounter;
                        serverCounter = aHr.serverCounter;
                        short sBitvector = aHr.bitVector;

                        if (sBitvector > 1)
                        { // Rig instance will send a status back to the key, inform user about any problem
                            System.Console.Write('!');
                            Log2("Rig side reports problem: " + sBitvector);
                        }

                        if (!bDisableLogging)
                        {
                            Log2("Client receive: " + Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - startTime) + " " + bytesRead +
                                 " clientCounter=" + clientCounter + " bitVector=" + Convert.ToString(aHr.bitVector, 2).PadLeft(16, '0') +
                                 " serverCounter=" + serverCounter + " lMQ=" + lMQ.Count() + " lNQ=" + lNQ.Count());
                        }

                        lock (lSrvNos)
                            lSrvNos.Add(serverCounter);

                        if (dCliTimeStamps.ContainsKey(clientCounter))
                        {
                            long ms = dCliTimeStamps[clientCounter];
                            lock (dCliTimeStamps)
                                dCliTimeStamps.Remove(clientCounter);

                            int iPing = Convert.ToInt32(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - ms);
                            if (iPing > 1000)
                            {
                                System.Console.Write('!');
                                Log2("High ping, " + iPing);
                            }

                            avgPing = CheckPing(iPing);
                        }
                    }
                }

                long ms2   = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                int  delta = Convert.ToInt32(ms2 - ms1);
                int  s     = _waitMilliSecs - delta;

                if (s > 0)
                {
                    Thread.Sleep(s);
                }
            }
            client.Close();
        }
Ejemplo n.º 3
0
        // we send the dit and dahs via the serial port, pin7 to the rig
        // between the rig and the serial port there is an optocoupler to have galvanic separation of the serial port and the rig
        public static void SerialOut()
        {
            Console.WriteLine("Thread SerialOut");

            bool bLastPin7 = false;
            bool bPin7;

            while (_continue)
            {
                // we take over the data to be sent from the list lMQ into our private list lNQ
                lock (lMQ)
                {
                    lock (lNQ)
                    {
                        lNQ.AddRange(lMQ);
                        lMQ.Clear();
                    }
                }

                if (lNQ.Count == 0)
                {
                    Thread.Sleep(_waitMilliSecs);
                    continue;
                }

                if (lNQ.Count < iQueueSize - 2)
                {
                    System.Console.Write('*');
                    Log2("lNQ queue too small, " + lNQ.Count);
                }
                else if (lNQ.Count > iQueueSize + 2)
                {
                    System.Console.Write('!');
                    Log2("lNQ queue too large, " + lNQ.Count);
                }
                else if (lMQ.Count > 5)
                {
                    System.Console.Write('!');
                    Log2("lMQ queue too large, " + lMQ.Count);
                }

                // we are delaying the replay to wipe out small delays on the network between key and rig
                // in case that the bitVector is zero, and the queue is smaller than 5, we delay a bit
                // bLast16AllZero = lNQ[lNQ.Count - 1].bitVector == 0;
                // if (bLast16AllZero && lNQ.Count < iQueueSize) {
                //    Thread.Sleep(_waitMilliSecs); // we will wait here additional 10ms
                //    continue;
                //}

                MsgHeader aHs = lNQ[0];

                // the bitVector contains 16 bits which we replay in this loop to the output pin, pin7
                for (int i = 0; i < 16; i++)
                {
                    bPin7 = (aHs.bitVector & (1 << i)) != 0;

                    if (!bLastPin7 && bPin7)
                    {
                        _serialPort.RtsEnable = true;

                        bLastPin7 = bPin7;
                        if (bStartAudio)
                        {
                            waveOut.Play();
                        }
                        Morse.ToOn();
                    }
                    else if (bLastPin7 && !bPin7)
                    {
                        _serialPort.RtsEnable = false;

                        if (bStartAudio)
                        {
                            waveOut.Stop();
                        }

                        Morse.ToOff();

                        bLastPin7 = bPin7;
                    }
                    else if (!bPin7)
                    {
                        Morse.IsOff();
                    }

                    //int iWait = _waitMilliSecs - Math.Max(0, lNQ.Count - iQueueSize);
                    int iWait = _waitMilliSecs - (lNQ.Count - iQueueSize); // if queue is too small add ms, if queue is too big remove ms

                    if (iWait > 0)
                    {
                        Thread.Sleep(iWait);
                    }

                    /* Using Pin 5 = Ground and Pin 7 RTS out to generate +5, +-0 V output
                     * GR 2020-07-19 tested okay */
                }
                lock (lNQ)
                    lNQ.RemoveAt(0);
            }
            _serialPort.RtsEnable = false;
        }