private void SendCode(byte baudotCode, ref ShiftStates shiftState) { byte[] codes = CodeManager.BaudotCodeToBaudotWithShift(baudotCode, shiftState, ref shiftState); if (EyeballCharActive) { byte[] buffer = new byte[0]; for (int i = 0; i < codes.Length; i++) { byte[] newCodes = _eyeballChar.GetPunchCodes(codes[i], shiftState); buffer = Helper.AddBytes(buffer, newCodes); } codes = buffer; } BaudotSendRecv?.Invoke(codes); if (Local) { Update?.Invoke(); return; } if (!IsConnected) { return; } if (IdleTimerMs >= 25000) { // wake up remote machine with LTRS EnqueueSend(new byte[] { CodeManager.BAU_LTRS }); EnqueueSend(new byte[] { CodeManager.BAU_LTRS }); EnqueueSend(new byte[] { CodeManager.BAU_LTRS }); if (shiftState == ShiftStates.Figs) { EnqueueSend(new byte[] { CodeManager.BAU_FIGS }); } } EnqueueSend(codes); Update?.Invoke(); }
private void DecodePacket(ItelexPacket packet) { /* * if (packet.CommandType != ItelexCommands.Ack) * { * //Logging.Instance.Log(LogTypes.Debug, TAG, nameof(DecodePacket), * // $"Recv packet {packet.CommandType} {packet.Command:X02} {packet.GetDebugData()}"); * Logging.Instance.Debug(TAG, nameof(DecodePacket), * $"Recv packet {packet.CommandType} {packet.GetDebugPacket()}"); * } * if (packet.CommandType != ItelexCommands.Heartbeat && packet.CommandType != ItelexCommands.Ack) * { * Debug.WriteLine($"Recv packet {packet.CommandType} {packet.GetDebugPacket()}"); * } */ switch ((ItelexCommands)packet.Command) { case ItelexCommands.Heartbeat: Logging.Instance.Debug(TAG, nameof(DecodePacket), $"recv heartbeat {packet.GetDebugPacket()}"); break; case ItelexCommands.DirectDial: Logging.Instance.Info(TAG, nameof(DecodePacket), $"recv direct dial cmd {packet.GetDebugPacket()}, number={packet.Data[0]}"); int directDial = packet.Data[0]; Message?.Invoke($"received direct dial cmd {directDial}"); if (directDial == _config.IncomingExtensionNumber) { ConnectInit(); } else { // not connected byte[] data = Encoding.ASCII.GetBytes("nc"); SendCmd(ItelexCommands.Reject, data); Message?.Invoke($"send reject ncc"); Disconnect(); } break; case ItelexCommands.BaudotData: if (packet.Len > 0) { Logging.Instance.AppendBinary(packet.Data, Logging.BinaryModes.Recv); string asciiStr = CodeManager.BaudotStringToAscii(packet.Data, ref _shiftState, _config.CodeSet, CodeManager.SendRecv.Recv); Logging.Instance.Debug(TAG, nameof(DecodePacket), $"recv baudot data {packet.Len} \"{CodeManager.AsciiToDebugStr(asciiStr)}\""); AddReceivedCharCount(packet.Data.Length); _lastSendRecvIdleMs = Helper.GetTicksMs(); Received?.Invoke(asciiStr); BaudotSendRecv?.Invoke(packet.Data); Update?.Invoke(); } break; case ItelexCommands.End: Logging.Instance.Info(TAG, nameof(DecodePacket), $"recv end cmd {packet.GetDebugPacket()}"); Disconnect(); break; case ItelexCommands.Reject: string reason = Encoding.ASCII.GetString(packet.Data, 0, packet.Data.Length); Logging.Instance.Info(TAG, nameof(DecodePacket), $"recv reject cmd {packet.GetDebugPacket()}, reason={reason}"); Message?.Invoke($"{LngText(LngKeys.Message_Reject)} {reason.ToUpper()} ({ReasonToString(reason).ToUpper()})"); if (CentralexState == CentralexStates.CentralexConnect && reason == "na") { CentralexState = CentralexStates.CentralexRejected; } else { Disconnect(); } break; case ItelexCommands.Ack: lock (_sendLock) { _n_ack = packet.Data[0]; _ackRecvFlag = true; _lastAckReceived = Helper.GetTicksMs(); } //Debug.WriteLine($"recv ack cmd {_n_ack} ({CharsAckCount})"); Logging.Instance.Debug(TAG, nameof(DecodePacket), $"recv ack cmd {packet.GetDebugPacket()} ack={_n_ack} ({CharsAckCount})"); Update?.Invoke(); break; case ItelexCommands.ProtocolVersion: string versionStr = ""; if (packet.Data.Length > 1) { // get version string versionStr = Encoding.ASCII.GetString(packet.Data, 1, packet.Data.Length - 1); versionStr = versionStr.TrimEnd('\x00'); // remove 00-byte suffix } Message?.Invoke($"received protocol version {packet.Data[0]:X2} '{versionStr}'"); Logging.Instance.Log(LogTypes.Info, TAG, nameof(DecodePacket), $"recv protocol version cmd {packet.GetDebugPacket()}, version={packet.Data[0]} '{versionStr}'"); if (_connectionDirection == ConnectionDirections.In) { // answer with own version SendVersionCodeCmd(); } break; case ItelexCommands.SelfTest: Logging.Instance.Log(LogTypes.Info, TAG, nameof(DecodePacket), $"recv self test cmd {packet.GetDebugPacket()}"); break; case ItelexCommands.RemoteConfig: Logging.Instance.Log(LogTypes.Info, TAG, nameof(DecodePacket), $"recv remote config cmd {packet.GetDebugPacket()}"); break; case ItelexCommands.RemoteConfirm: CentralexState = CentralexStates.CentralexConnected; break; case ItelexCommands.RemoteCall: SendAcceptCallRemoteCmd(); ConnectInit(); _connectionDirection = ConnectionDirections.In; if (_config.IncomingExtensionNumber != 0) { // set to connected and wait for direct dial command ConnectionState = ConnectionStates.TcpConnected; } else { // no direct dial command neccessary ConnectInit(); } Message?.Invoke($"{LngText(LngKeys.Message_IncomingConnection)} centralex"); Logging.Instance.Log(LogTypes.Info, TAG, nameof(Listener), $"incoming connection from centralex"); Update?.Invoke(); break; } }