| 158 |
pfowler |
1 |
using System;
|
|
|
2 |
using System.Collections.Generic;
|
|
|
3 |
using System.Linq;
|
|
|
4 |
using System.Text;
|
|
|
5 |
using System.Threading.Tasks;
|
|
|
6 |
using System.IO;
|
|
|
7 |
using System.Net;
|
|
|
8 |
using System.Net.Sockets;
|
|
|
9 |
using System.Threading;
|
|
|
10 |
|
|
|
11 |
namespace nitdcscore {
|
|
|
12 |
public class DcsBios {
|
|
|
13 |
private UdpClient _udpReceiveClient = null;
|
|
|
14 |
private UdpClient _udpSendClient = null;
|
|
|
15 |
private Thread _listeningThread;
|
|
|
16 |
|
|
|
17 |
private String _receiveFromIP = "239.255.50.10";
|
|
|
18 |
private String _sendToIP = "127.0.0.1";
|
|
|
19 |
private int _receivePort = 5010;
|
|
|
20 |
private int _sendPort = 7778;
|
|
|
21 |
private IPEndPoint _ipEndPointReceiver = null;
|
|
|
22 |
private IPEndPoint _ipEndPointSender = null;
|
|
|
23 |
|
|
|
24 |
private readonly DCSProtocolParser _parser;
|
|
|
25 |
|
|
|
26 |
public DcsBios() {
|
|
|
27 |
_parser = new DCSProtocolParser();
|
|
|
28 |
}
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
public void InitUDP() {
|
|
|
32 |
try {
|
|
|
33 |
_ipEndPointReceiver = new IPEndPoint(IPAddress.Any, _receivePort);
|
|
|
34 |
_ipEndPointSender = new IPEndPoint(IPAddress.Parse(_sendToIP), _sendPort);
|
|
|
35 |
|
|
|
36 |
_udpReceiveClient = new UdpClient();
|
|
|
37 |
_udpReceiveClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
|
|
38 |
_udpReceiveClient.Client.Bind(_ipEndPointReceiver);
|
|
|
39 |
_udpReceiveClient.JoinMulticastGroup(IPAddress.Parse(_receiveFromIP));
|
|
|
40 |
|
|
|
41 |
_udpSendClient = new UdpClient();
|
|
|
42 |
_udpSendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
|
|
43 |
_udpSendClient.EnableBroadcast = true;
|
|
|
44 |
|
|
|
45 |
if (_listeningThread != null) {
|
|
|
46 |
_listeningThread.Abort();
|
|
|
47 |
}
|
|
|
48 |
|
|
|
49 |
_listeningThread = new Thread(ReceiveData);
|
|
|
50 |
_listeningThread.Start();
|
|
|
51 |
} catch (Exception e) {
|
|
|
52 |
if (_udpReceiveClient != null && _udpReceiveClient.Client.Connected) {
|
|
|
53 |
_udpReceiveClient.Close();
|
|
|
54 |
_udpReceiveClient = null;
|
|
|
55 |
}
|
|
|
56 |
if (_udpSendClient != null && _udpSendClient.Client.Connected) {
|
|
|
57 |
_udpSendClient.Close();
|
|
|
58 |
_udpSendClient = null;
|
|
|
59 |
}
|
|
|
60 |
Console.WriteLine(e.Message);
|
|
|
61 |
}
|
|
|
62 |
|
|
|
63 |
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
public void ReceiveData() {
|
|
|
67 |
try {
|
|
|
68 |
while (true) {
|
|
|
69 |
var byteData = _udpReceiveClient.Receive(ref _ipEndPointReceiver);
|
|
|
70 |
for (int i=0; i<byteData.Length; i++) {
|
|
|
71 |
_parser.ProcessByte(byteData[i]);
|
|
|
72 |
}
|
|
|
73 |
}
|
|
|
74 |
} catch (Exception e) {
|
|
|
75 |
Console.WriteLine(e.Message);
|
|
|
76 |
}
|
|
|
77 |
}
|
|
|
78 |
|
|
|
79 |
public int SendData(string data) {
|
|
|
80 |
var rslt = 0;
|
|
|
81 |
try {
|
|
|
82 |
var unicodeBytes = Encoding.Unicode.GetBytes(data);
|
|
|
83 |
var asciiBytes = new List<byte>(data.Length);
|
|
|
84 |
asciiBytes.AddRange(Encoding.Convert(Encoding.Unicode, Encoding.ASCII, unicodeBytes));
|
|
|
85 |
rslt = _udpSendClient.Send(asciiBytes.ToArray(), asciiBytes.ToArray().Length, _ipEndPointSender);
|
|
|
86 |
} catch (Exception e) {
|
|
|
87 |
Console.WriteLine(e.Message);
|
|
|
88 |
}
|
|
|
89 |
|
|
|
90 |
return rslt;
|
|
|
91 |
}
|
|
|
92 |
|
|
|
93 |
public void Shutdown() {
|
|
|
94 |
try {
|
|
|
95 |
if (_listeningThread != null) {
|
|
|
96 |
_listeningThread.Abort();
|
|
|
97 |
_listeningThread = null;
|
|
|
98 |
}
|
|
|
99 |
_udpReceiveClient.Close();
|
|
|
100 |
_udpSendClient.Close();
|
|
|
101 |
} catch (Exception e) {
|
|
|
102 |
Console.WriteLine(e.Message);
|
|
|
103 |
}
|
|
|
104 |
}
|
|
|
105 |
|
|
|
106 |
}
|
|
|
107 |
|
|
|
108 |
public enum DCSBiosStateEnum {
|
|
|
109 |
WAIT_FOR_SYNC = 0,
|
|
|
110 |
ADDRESS_LOW = 1,
|
|
|
111 |
ADDRESS_HIGH = 2,
|
|
|
112 |
COUNT_LOW = 3,
|
|
|
113 |
COUNT_HIGH = 4,
|
|
|
114 |
DATA_LOW = 5,
|
|
|
115 |
DATA_HIGH = 6,
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
|
|
|
119 |
|
|
|
120 |
internal class DCSProtocolParser {
|
|
|
121 |
private DCSBiosStateEnum _state;
|
|
|
122 |
private uint _address;
|
|
|
123 |
private uint _count;
|
|
|
124 |
private uint _data;
|
|
|
125 |
private byte _syncByteCount;
|
|
|
126 |
|
|
|
127 |
internal DCSProtocolParser() {
|
|
|
128 |
_state = DCSBiosStateEnum.WAIT_FOR_SYNC;
|
|
|
129 |
_syncByteCount = 0;
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
internal void ProcessByte(byte b) {
|
|
|
133 |
switch (_state) {
|
|
|
134 |
case DCSBiosStateEnum.WAIT_FOR_SYNC:
|
|
|
135 |
break;
|
|
|
136 |
case DCSBiosStateEnum.ADDRESS_LOW:
|
|
|
137 |
_address = b;
|
|
|
138 |
_state = DCSBiosStateEnum.ADDRESS_HIGH;
|
|
|
139 |
break;
|
|
|
140 |
case DCSBiosStateEnum.ADDRESS_HIGH:
|
|
|
141 |
_address = (uint) (b << 8) | _address;
|
|
|
142 |
_state = _address != 0x5555 ? DCSBiosStateEnum.COUNT_LOW : DCSBiosStateEnum.WAIT_FOR_SYNC;
|
|
|
143 |
break;
|
|
|
144 |
case DCSBiosStateEnum.COUNT_LOW:
|
|
|
145 |
_count = b;
|
|
|
146 |
_state = DCSBiosStateEnum.COUNT_HIGH;
|
|
|
147 |
break;
|
|
|
148 |
case DCSBiosStateEnum.COUNT_HIGH:
|
|
|
149 |
_count = (uint)(b << 8) | _count;
|
|
|
150 |
_state = DCSBiosStateEnum.DATA_LOW;
|
|
|
151 |
break;
|
|
|
152 |
case DCSBiosStateEnum.DATA_LOW:
|
|
|
153 |
_data = b;
|
|
|
154 |
_count--;
|
|
|
155 |
_state = DCSBiosStateEnum.DATA_HIGH;
|
|
|
156 |
break;
|
|
|
157 |
case DCSBiosStateEnum.DATA_HIGH:
|
|
|
158 |
_data = (uint)(b << 8) | _data;
|
|
|
159 |
_count--;
|
|
|
160 |
if (_address == 0x10fa) {
|
|
|
161 |
uint aapCdupwrValue = (_data & 0x4000) >> 14;
|
|
|
162 |
//Console.WriteLine(_address.ToString("X") + ":" + aapCdupwrValue);
|
|
|
163 |
}
|
|
|
164 |
|
|
|
165 |
_address += 2;
|
|
|
166 |
if (_count == 0)
|
|
|
167 |
_state = DCSBiosStateEnum.ADDRESS_LOW;
|
|
|
168 |
else
|
|
|
169 |
_state = DCSBiosStateEnum.DATA_LOW;
|
|
|
170 |
break;
|
|
|
171 |
}
|
|
|
172 |
if (b == 0x55)
|
|
|
173 |
_syncByteCount++;
|
|
|
174 |
else
|
|
|
175 |
_syncByteCount = 0;
|
|
|
176 |
if (_syncByteCount == 4) {
|
|
|
177 |
_state = DCSBiosStateEnum.ADDRESS_LOW;
|
|
|
178 |
_syncByteCount = 0;
|
|
|
179 |
}
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
|
|
|
183 |
|
|
|
184 |
}
|