2
0

SerialPort.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /* -*- Mode: Csharp; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
  2. #if NET_2_0
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. namespace System.IO.Ports
  6. {
  7. public enum Handshake
  8. {
  9. None, /* No control is used for the handshake */
  10. RequestToSend, /* Request-to-Send (RTS) hardware flow
  11. * control is used. RTS is used to signal
  12. * that data is available for
  13. * transmission. */
  14. RequestToSendXOnXOff, /* Both the Request-to-Send (RTS) hardware
  15. * control and the XON/XOFF software
  16. * controls are used. */
  17. XOnXOff /* The XON/XOFF software control protocol is
  18. * used. XOFF is a software control sent to
  19. * stop the transmission of data and the XON
  20. * control is sent to resume the
  21. * transmission. These controls are used
  22. * instead of the Request to Send (RTS) and
  23. * Clear to Send (CTS) hardware controls. */
  24. }
  25. public enum Parity
  26. {
  27. Even, /* Sets the parity bit so that the count of bits set is an even number */
  28. Mark, /* Leaves the parity bit set to 1. */
  29. None, /* No parity check occurs */
  30. Odd, /* Sets the parity bit so that the count of bits set is an odd number */
  31. Space /* Leaves the parity bit set to 0 */
  32. }
  33. public enum StopBits
  34. {
  35. One, /* One stop bit is used */
  36. OnePointFive, /* Three stop bits are used. */
  37. Two /* Two stop bits are used. */
  38. }
  39. public class SerialPort /* : Component */
  40. {
  41. public const int InfiniteTimeout = -1;
  42. bool isOpen = false;
  43. int baudRate = 9600;
  44. Parity parity = Parity.None;
  45. StopBits stopBits = StopBits.One;
  46. Handshake handshake = Handshake.None;
  47. int dataBits = 8;
  48. bool breakState = false;
  49. Stream baseStream;
  50. string newLine = "\n";
  51. string portName;
  52. int unixFd;
  53. int readTimeout = InfiniteTimeout;
  54. int writeTimeout = InfiniteTimeout;
  55. private class SerialPortStream : Stream
  56. {
  57. SerialPort port;
  58. public SerialPortStream (SerialPort port)
  59. {
  60. this.port = port;
  61. }
  62. public override bool CanRead
  63. {
  64. get {
  65. return true;
  66. }
  67. }
  68. public override bool CanSeek
  69. {
  70. get {
  71. return false;
  72. }
  73. }
  74. public override bool CanWrite
  75. {
  76. get {
  77. return true;
  78. }
  79. }
  80. public override long Length
  81. {
  82. get {
  83. return -1;
  84. }
  85. }
  86. public override long Position
  87. {
  88. get {
  89. return -1;
  90. }
  91. set {
  92. throw new InvalidOperationException ();
  93. }
  94. }
  95. public override void Flush ()
  96. {
  97. throw new NotImplementedException ();
  98. }
  99. public override int Read ([In,Out] byte[] buffer, int offset, int count)
  100. {
  101. return port.Read (buffer, offset, count);
  102. }
  103. public override long Seek (long offset, SeekOrigin origin)
  104. {
  105. throw new InvalidOperationException ();
  106. }
  107. public override void SetLength (long value)
  108. {
  109. throw new InvalidOperationException ();
  110. }
  111. public override void Write (byte[] buffer, int offset, int count)
  112. {
  113. port.Write (buffer, offset, count);
  114. }
  115. }
  116. public SerialPort ()
  117. {
  118. throw new NotImplementedException ();
  119. }
  120. /*
  121. IContainer is in 2.0?
  122. public SerialPort (IContainer container) {
  123. }
  124. */
  125. public SerialPort (string portName)
  126. {
  127. this.portName = portName;
  128. }
  129. public SerialPort (string portName, int baudRate)
  130. {
  131. this.portName = portName;
  132. this.baudRate = baudRate;
  133. }
  134. public SerialPort (string portName, int baudRate, Parity parity)
  135. {
  136. this.portName = portName;
  137. this.baudRate = baudRate;
  138. this.parity = parity;
  139. }
  140. public SerialPort (string portName, int baudRate, Parity parity, int dataBits)
  141. {
  142. this.portName = portName;
  143. this.baudRate = baudRate;
  144. this.parity = parity;
  145. this.dataBits = dataBits;
  146. }
  147. public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) {
  148. this.portName = portName;
  149. this.baudRate = baudRate;
  150. this.parity = parity;
  151. this.dataBits = dataBits;
  152. this.stopBits = stopBits;
  153. }
  154. public Stream BaseStream
  155. {
  156. get {
  157. if (!isOpen)
  158. throw new InvalidOperationException ();
  159. if (baseStream == null)
  160. baseStream = new SerialPortStream (this);
  161. return baseStream;
  162. }
  163. }
  164. [DllImport("MonoPosixHelper")]
  165. private static extern bool set_attributes (int unix_fd, int baud_rate, Parity parity, int dataBits, StopBits stopBits, Handshake handshake);
  166. public int BaudRate
  167. {
  168. get {
  169. return baudRate;
  170. }
  171. set {
  172. this.baudRate = value;
  173. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  174. }
  175. }
  176. public bool BreakState
  177. {
  178. get {
  179. return breakState;
  180. }
  181. set {
  182. if (!isOpen)
  183. throw new InvalidOperationException ();
  184. throw new NotImplementedException ();
  185. }
  186. }
  187. public int BytesToRead
  188. {
  189. get {
  190. if (!isOpen)
  191. throw new InvalidOperationException ();
  192. throw new NotImplementedException ();
  193. }
  194. }
  195. public int BytesToWrite
  196. {
  197. get {
  198. if (!isOpen)
  199. throw new InvalidOperationException ();
  200. throw new NotImplementedException ();
  201. }
  202. }
  203. public bool CDHolding
  204. {
  205. get {
  206. if (!isOpen)
  207. throw new InvalidOperationException ();
  208. throw new NotImplementedException ();
  209. }
  210. }
  211. public bool CtsHolding
  212. {
  213. get {
  214. if (!isOpen)
  215. throw new InvalidOperationException ();
  216. throw new NotImplementedException ();
  217. }
  218. }
  219. public int DataBits
  220. {
  221. get {
  222. throw new NotImplementedException ();
  223. }
  224. set {
  225. if (value < 5 || value > 8)
  226. throw new ArgumentOutOfRangeException ();
  227. dataBits = value;
  228. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  229. }
  230. }
  231. public bool DiscardNull
  232. {
  233. get {
  234. if (!isOpen)
  235. throw new InvalidOperationException ();
  236. throw new NotImplementedException ();
  237. }
  238. set {
  239. if (!isOpen)
  240. throw new InvalidOperationException ();
  241. throw new NotImplementedException ();
  242. }
  243. }
  244. public bool DsrHolding
  245. {
  246. get {
  247. if (!isOpen)
  248. throw new InvalidOperationException ();
  249. throw new NotImplementedException ();
  250. }
  251. }
  252. public bool DtrEnable
  253. {
  254. get {
  255. throw new NotImplementedException ();
  256. }
  257. }
  258. public Encoding Encoding
  259. {
  260. get {
  261. throw new NotImplementedException ();
  262. }
  263. set {
  264. throw new NotImplementedException ();
  265. }
  266. }
  267. public Handshake Handshake
  268. {
  269. get {
  270. if (!isOpen)
  271. throw new InvalidOperationException ();
  272. return handshake;
  273. }
  274. set {
  275. if (!isOpen)
  276. throw new InvalidOperationException ();
  277. handshake = value;
  278. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  279. }
  280. }
  281. public bool IsOpen
  282. {
  283. get {
  284. return isOpen;
  285. }
  286. }
  287. public string NewLine
  288. {
  289. get {
  290. return newLine;
  291. }
  292. set {
  293. newLine = value;
  294. }
  295. }
  296. public Parity Parity
  297. {
  298. get {
  299. if (!isOpen)
  300. throw new InvalidOperationException ();
  301. return parity;
  302. }
  303. set {
  304. if (!isOpen)
  305. throw new InvalidOperationException ();
  306. this.parity = value;
  307. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  308. }
  309. }
  310. public byte ParityReplace
  311. {
  312. get {
  313. throw new NotImplementedException ();
  314. }
  315. set {
  316. throw new NotImplementedException ();
  317. }
  318. }
  319. public string PortName
  320. {
  321. get {
  322. return portName;
  323. }
  324. set {
  325. throw new NotImplementedException ();
  326. }
  327. }
  328. public int ReadBufferSize
  329. {
  330. get {
  331. throw new NotImplementedException ();
  332. }
  333. set {
  334. if (value <= 0)
  335. throw new ArgumentOutOfRangeException ();
  336. throw new NotImplementedException ();
  337. }
  338. }
  339. public int ReadTimeout
  340. {
  341. get {
  342. return readTimeout;
  343. }
  344. set {
  345. if (value <= 0 && value != InfiniteTimeout)
  346. throw new ArgumentOutOfRangeException ();
  347. readTimeout = value;
  348. }
  349. }
  350. public int ReceivedBytesThreshold
  351. {
  352. get {
  353. throw new NotImplementedException ();
  354. }
  355. set {
  356. if (value <= 0)
  357. throw new ArgumentOutOfRangeException ();
  358. throw new NotImplementedException ();
  359. }
  360. }
  361. public bool RtsEnable
  362. {
  363. get {
  364. throw new NotImplementedException ();
  365. }
  366. set {
  367. throw new NotImplementedException ();
  368. }
  369. }
  370. public StopBits StopBits
  371. {
  372. get {
  373. return stopBits;
  374. }
  375. set {
  376. this.stopBits = value;
  377. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  378. }
  379. }
  380. public int WriteBufferSize
  381. {
  382. get {
  383. throw new NotImplementedException ();
  384. }
  385. set {
  386. if (value <= 0)
  387. throw new ArgumentOutOfRangeException ();
  388. throw new NotImplementedException ();
  389. }
  390. }
  391. public int WriteTimeout
  392. {
  393. get {
  394. return writeTimeout;
  395. }
  396. set {
  397. if (value <= 0 && value != InfiniteTimeout)
  398. throw new ArgumentOutOfRangeException ();
  399. writeTimeout = value;
  400. }
  401. }
  402. // methods
  403. [DllImport("MonoPosixHelper")]
  404. private static extern void close_serial (int unixFd);
  405. public void Close ()
  406. {
  407. isOpen = false;
  408. close_serial (unixFd);
  409. }
  410. [DllImport("MonoPosixHelper")]
  411. private static extern void discard_buffer (int unixFd, bool input_buffer);
  412. public void DiscardInBuffer ()
  413. {
  414. if (!isOpen)
  415. throw new InvalidOperationException ();
  416. discard_buffer (unixFd, true);
  417. }
  418. public void DiscardOutBuffer ()
  419. {
  420. if (!isOpen)
  421. throw new InvalidOperationException ();
  422. discard_buffer (unixFd, false);
  423. }
  424. [DllImport("MonoPosixHelper")]
  425. private static extern string[] list_serial_devices ();
  426. public static string[] GetPortNames()
  427. {
  428. return list_serial_devices ();
  429. }
  430. [DllImport("MonoPosixHelper")]
  431. private static extern int open_serial (string portName);
  432. public void Open ()
  433. {
  434. if (portName == null || portName.StartsWith ("\\\\"))
  435. throw new ArgumentException ();
  436. unixFd = open_serial (portName);
  437. if (unixFd == -1)
  438. throw new IOException();
  439. set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake);
  440. isOpen = true;
  441. }
  442. [DllImport("MonoPosixHelper")]
  443. private static extern int read_serial (int unixFd, byte[] buffer, int offset, int count, int timeout);
  444. public int Read (byte[] buffer, int offset, int count)
  445. {
  446. return read_serial (unixFd, buffer, offset, count, readTimeout);
  447. }
  448. public int Read (char[] buffer, int offset, int count)
  449. {
  450. throw new NotImplementedException ();
  451. }
  452. byte[] read_buffer = new byte[4096];
  453. public int ReadByte ()
  454. {
  455. if (Read (read_buffer, 0, 1) == 1)
  456. return read_buffer [0];
  457. return -1;
  458. }
  459. public int ReadChar ()
  460. {
  461. throw new NotImplementedException ();
  462. }
  463. public string ReadExisting ()
  464. {
  465. throw new NotImplementedException ();
  466. }
  467. public string ReadLine ()
  468. {
  469. return ReadTo (newLine);
  470. }
  471. public string ReadTo (string value)
  472. {
  473. throw new NotImplementedException ();
  474. }
  475. [DllImport("MonoPosixHelper")]
  476. private static extern void write_serial (int unixFd, byte[] buffer, int offset, int count, int timeout);
  477. public void Write (string str)
  478. {
  479. throw new NotImplementedException ();
  480. }
  481. public void Write (byte[] buffer, int offset, int count)
  482. {
  483. write_serial (unixFd, buffer, offset, count, writeTimeout);
  484. }
  485. public void Write (char[] buffer, int offset, int count)
  486. {
  487. throw new NotImplementedException ();
  488. }
  489. public void WriteLine (string str)
  490. {
  491. Write (str + newLine);
  492. }
  493. // events
  494. public delegate void SerialReceivedEventHandler (object sender, SerialReceivedEventArgs e);
  495. public delegate void SerialPinChangedEventHandler (object sender, SerialPinChangedEventArgs e);
  496. public delegate void SerialErrorEventHandler (object sender, SerialErrorEventArgs e);
  497. public event SerialErrorEventHandler ErrorEvent;
  498. public event SerialPinChangedEventHandler PinChangedEvent;
  499. public event SerialReceivedEventHandler ReceivedEvent;
  500. }
  501. }
  502. #endif