Testing out the PPD42 Air Quality Sensor, with an MSP430 Launchpad and graphing the data with GNUplot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1610 lines
46 KiB

5 years ago
  1. /*-------------------------------------------------------------------------
  2. | rxtx is a native interface to serial ports in java.
  3. | Copyright 2002-2004 Michal Hobot MichalHobot@netscape.net
  4. | Copyright 1997-2004 by Trent Jarvi taj@parcelfarce.linux.theplanet.co.uk
  5. |
  6. | This library is free software; you can redistribute it and/or
  7. | modify it under the terms of the GNU Library General Public
  8. | License as published by the Free Software Foundation; either
  9. | version 2 of the License, or (at your option) any later version.
  10. |
  11. | This library is distributed in the hope that it will be useful,
  12. | but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. | Library General Public License for more details.
  15. |
  16. | You should have received a copy of the GNU Library General Public
  17. | License along with this library; if not, write to the Free
  18. | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. --------------------------------------------------------------------------*/
  20. #include "StdAfx.h"
  21. #include "rxtxHelpers.h"
  22. /*
  23. Initialize
  24. accept: none
  25. perform: Initialize the native library
  26. return: none
  27. exceptions: none
  28. comments:
  29. * Class: gnu_io_RXTXPort
  30. * Method: Initialize
  31. * Signature: ()V
  32. */
  33. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_Initialize(JNIEnv *env, jclass cls)
  34. {
  35. }
  36. /*
  37. open
  38. accept: The device to open. ie "COM1:"
  39. perform: open the device
  40. return: handle
  41. exceptions: IOExcepiton
  42. comments: Very often people complain about not being able to get past
  43. this function and it turns out to be permissions on the
  44. device file or bios has the device disabled.
  45. * Class: gnu_io_RXTXPort
  46. * Method: open
  47. * Signature: (Ljava/lang/String{ })I
  48. */
  49. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_open(JNIEnv *env, jobject jobj, jstring name)
  50. {
  51. DCB PortDCB;
  52. COMMTIMEOUTS CommTimeouts;
  53. LPCWSTR lpMsgBuf;
  54. EventInfoStruct *EventInfo;
  55. DWORD dwErr;
  56. LPCWSTR wszName = env->GetStringChars(name, NULL);
  57. HANDLE hPort = CreateFileW(wszName, // Pointer to the name of the port
  58. GENERIC_READ | GENERIC_WRITE,// Access (read-write) mode
  59. 0, // Share mode
  60. NULL, // Pointer to the security attribute
  61. OPEN_EXISTING,// How to open the serial port
  62. 0, // Port attributes
  63. NULL); // Handle to port with attribute to copy
  64. // If it fails to open the port, return FALSE.
  65. if ( hPort == INVALID_HANDLE_VALUE )
  66. { // Could not open the port.
  67. CreateErrorMsg(GetLastError(), lpMsgBuf);
  68. throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - CreateFile", lpMsgBuf );
  69. // Free the buffers.
  70. ReleaseErrorMsg(lpMsgBuf);
  71. env->ReleaseStringChars(name, wszName);
  72. return (jint)INVALID_HANDLE_VALUE;
  73. }
  74. PortDCB.DCBlength = sizeof (DCB);
  75. // Get the default port setting information.
  76. GetCommState(hPort, &PortDCB);
  77. // Change the DCB structure settings.
  78. PortDCB.fBinary = TRUE; // Binary mode; no EOF check
  79. PortDCB.fParity = TRUE; // Enable parity checking
  80. PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
  81. PortDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;// DTR flow control type
  82. PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
  83. PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
  84. PortDCB.fErrorChar = FALSE; // Disable error replacement
  85. PortDCB.fNull = FALSE; // Disable null stripping
  86. PortDCB.fRtsControl = RTS_CONTROL_ENABLE;// RTS flow control
  87. PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error
  88. // Configure the port according to the specifications of the DCB structure.
  89. if (!SetCommState(hPort, &PortDCB))
  90. { // Could not set comm port state
  91. CreateErrorMsg(GetLastError(), lpMsgBuf);
  92. throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - SetCommState", lpMsgBuf);
  93. // Free the buffers.
  94. ReleaseErrorMsg(lpMsgBuf);
  95. env->ReleaseStringChars(name, wszName);
  96. return (jint)INVALID_HANDLE_VALUE;
  97. }
  98. // Retrieve the time-out parameters for all read and write operations
  99. // on the port.
  100. GetCommTimeouts(hPort, &CommTimeouts);
  101. // Change the COMMTIMEOUTS structure settings.
  102. CommTimeouts.ReadIntervalTimeout = 0;
  103. CommTimeouts.ReadTotalTimeoutMultiplier = 0;
  104. CommTimeouts.ReadTotalTimeoutConstant = MAXDWORD;
  105. CommTimeouts.WriteTotalTimeoutMultiplier = 10;
  106. CommTimeouts.WriteTotalTimeoutConstant = 1000;
  107. // Set the time-out parameters for all read and write operations
  108. // on the port.
  109. if (!SetCommTimeouts(hPort, &CommTimeouts))
  110. { // Unable to set the time-out parameters
  111. CreateErrorMsg(GetLastError(), lpMsgBuf);
  112. throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - SetCommTimeouts", lpMsgBuf);
  113. // Free the buffers.
  114. ReleaseErrorMsg(lpMsgBuf);
  115. env->ReleaseStringChars(name, wszName);
  116. return (jint)INVALID_HANDLE_VALUE;
  117. }
  118. // SETRTS: Sends the RTS (request-to-send) signal.
  119. EscapeCommFunction(hPort, SETRTS);
  120. if(dwErr = InitialiseEventInfoStruct(hPort, &EventInfo))
  121. { // Unable to set up EventInfo structure for event processing
  122. CreateErrorMsg(dwErr, lpMsgBuf);
  123. throw_java_exceptionW(env, IO_EXCEPTION, L"open - InitialiseEventInfoStruct", lpMsgBuf);
  124. // Free the buffers.
  125. ReleaseErrorMsg(lpMsgBuf);
  126. env->ReleaseStringChars(name, wszName);
  127. return (jint)INVALID_HANDLE_VALUE;
  128. }
  129. jclass cls = env->GetObjectClass(jobj);
  130. jfieldID jfEis = env->GetFieldID(cls, "eis", "I");
  131. if( !jfEis ) {
  132. IF_DEBUG
  133. (
  134. env->ExceptionDescribe();
  135. )
  136. env->ExceptionClear();
  137. // Free the buffers.
  138. env->ReleaseStringChars(name, wszName);
  139. return (jint)INVALID_HANDLE_VALUE;
  140. }
  141. env->SetIntField(jobj, jfEis, (jint)EventInfo);
  142. env->ReleaseStringChars(name, wszName);
  143. // Returning HANDLE (which is a pointer) as file descriptor... Anyway, 32 bits are 32 bits
  144. return (jint)hPort;
  145. }
  146. /*
  147. nativeSetSerialPortParams
  148. accept: speed, data bits, stop bits, parity
  149. perform: set the serial port parameters
  150. return: void
  151. exceptions: UnsupportedCommOperationException
  152. * Class: gnu_io_RXTXPort
  153. * Method: nativeSetSerialPortParams
  154. * Signature: (IIII)V
  155. */
  156. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeSetSerialPortParams(JNIEnv *env, jobject jobj, jint speed, jint dataBits, jint stopBits, jint parity)
  157. {
  158. DCB PortDCB;
  159. LPCWSTR lpMsgBuf;
  160. HANDLE hPort = get_fd(env, jobj);
  161. PortDCB.DCBlength = sizeof(DCB);
  162. IF_DEBUG
  163. (
  164. printj(env, L"--- RXTXPort.nativeSetSerialPortParams(%ld, %ld, %ld, %ld) called\n", speed, dataBits, stopBits, parity);
  165. )
  166. // Get the default port setting information.
  167. if(!GetCommState(hPort, &PortDCB))
  168. { //Unable to get configuration of the serial port
  169. CreateErrorMsg(GetLastError(), lpMsgBuf);
  170. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams - GetCommState", lpMsgBuf);
  171. // Free the buffers.
  172. ReleaseErrorMsg(lpMsgBuf);
  173. return;
  174. }
  175. // Change the DCB structure settings.
  176. PortDCB.BaudRate = speed; // Current baud
  177. PortDCB.ByteSize = (BYTE)dataBits; // Number of bits/byte, 4-8
  178. PortDCB.Parity = (BYTE)parity; // 0-4=no,odd,even,mark,space
  179. switch(stopBits)
  180. {
  181. case gnu_io_RXTXPort_STOPBITS_1:
  182. PortDCB.StopBits = ONESTOPBIT;
  183. break;
  184. case gnu_io_RXTXPort_STOPBITS_2:
  185. PortDCB.StopBits = TWOSTOPBITS;
  186. break;
  187. case gnu_io_RXTXPort_STOPBITS_1_5:
  188. PortDCB.StopBits = ONE5STOPBITS;
  189. break;
  190. default:
  191. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams", L"Incorrect stopBits");
  192. }
  193. // Configure the port according to the specifications of the DCB structure.
  194. if (!SetCommState (hPort, &PortDCB))
  195. { //Unable to configure the serial port
  196. CreateErrorMsg(GetLastError(), lpMsgBuf);
  197. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams - SetCommState", lpMsgBuf);
  198. // Free the buffers.
  199. ReleaseErrorMsg(lpMsgBuf);
  200. return;
  201. }
  202. }
  203. /*
  204. setflowcontrol
  205. accept: flowmode
  206. FLOWCONTROL_NONE none
  207. FLOWCONTROL_RTSCTS_IN hardware flow control
  208. FLOWCONTROL_RTSCTS_OUT ""
  209. FLOWCONTROL_XONXOFF_IN input software flow control
  210. FLOWCONTROL_XONXOFF_OUT output software flow control
  211. perform: set flow control to flowmode
  212. return: none
  213. exceptions: UnsupportedCommOperationException
  214. comments: there is no differentiation between input and output hardware
  215. flow control
  216. * Class: gnu_io_RXTXPort
  217. * Method: setflowcontrol
  218. * Signature: (I)V
  219. */
  220. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setflowcontrol(JNIEnv *env, jobject jobj, jint flowcontrol)
  221. {
  222. DCB PortDCB;
  223. LPCWSTR lpMsgBuf;
  224. IF_DEBUG
  225. (
  226. printj(env, L"--- RXTXPort.setflowcontrol(%ld) called\n", flowcontrol);
  227. )
  228. HANDLE hPort = get_fd(env, jobj);
  229. PortDCB.DCBlength = sizeof(DCB);
  230. if(!GetCommState (hPort, &PortDCB))
  231. { //Unable to get configuration of the serial port
  232. CreateErrorMsg(GetLastError(), lpMsgBuf);
  233. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"setflowcontrol - GetCommState", lpMsgBuf);
  234. // Free the buffers.
  235. ReleaseErrorMsg(lpMsgBuf);
  236. return;
  237. }
  238. if(flowcontrol & (gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_IN | gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_OUT))
  239. PortDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
  240. else
  241. PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
  242. if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_OUT)
  243. PortDCB.fOutxCtsFlow = TRUE;
  244. else
  245. PortDCB.fOutxCtsFlow = FALSE;
  246. if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_XONXOFF_IN)
  247. PortDCB.fInX = TRUE;
  248. else
  249. PortDCB.fInX = FALSE;
  250. if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_XONXOFF_OUT)
  251. PortDCB.fOutX = TRUE;
  252. else
  253. PortDCB.fOutX = FALSE;
  254. // Configure the port according to the specifications of the DCB structure.
  255. if (!SetCommState (hPort, &PortDCB))
  256. { // Could not set params
  257. CreateErrorMsg(GetLastError(), lpMsgBuf);
  258. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"setflowcontrol - SetCommState", lpMsgBuf);
  259. // Free the buffers.
  260. ReleaseErrorMsg(lpMsgBuf);
  261. return;
  262. }
  263. }
  264. /*
  265. NativegetReceiveTimeout
  266. accept: none
  267. perform: get termios.c_cc[VTIME]
  268. return: VTIME
  269. comments: see NativeEnableReceiveTimeoutThreshold
  270. * Class: gnu_io_RXTXPort
  271. * Method: NativegetReceiveTimeout
  272. * Signature: ()I
  273. */
  274. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_NativegetReceiveTimeout(JNIEnv *env, jobject jobj)
  275. {
  276. COMMTIMEOUTS CommTimeouts;
  277. LPCWSTR lpMsgBuf;
  278. HANDLE hPort = get_fd(env, jobj);
  279. IF_DEBUG
  280. (
  281. printj(env, L"--- RXTXPort.NativegetReceiveTimeout() called\n");
  282. )
  283. // Retrieve the time-out parameters for all read and write operations on the port.
  284. if (!GetCommTimeouts(hPort, &CommTimeouts))
  285. { // Unable to get the time-out parameters
  286. CreateErrorMsg(GetLastError(), lpMsgBuf);
  287. throw_java_exceptionW(env, IO_EXCEPTION, L"NativegetReceiveTimeout - GetCommTimeouts", lpMsgBuf);
  288. // Free the buffers.
  289. ReleaseErrorMsg(lpMsgBuf);
  290. return -1;
  291. }
  292. // As far as I know c_cc is byte table
  293. return CommTimeouts.ReadIntervalTimeout/100 <= 255 ? CommTimeouts.ReadIntervalTimeout / 100 : 255;
  294. }
  295. /*
  296. NativeisReceiveTimeoutEnabled
  297. accept: none
  298. perform: determine if VTIME is none 0
  299. return: JNI_TRUE if VTIME > 0 else JNI_FALSE
  300. comments: see NativeEnableReceiveTimeoutThreshold
  301. * Class: gnu_io_RXTXPort
  302. * Method: NativeisReceiveTimeoutEnabled
  303. * Signature: ()Z
  304. */
  305. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_NativeisReceiveTimeoutEnabled(JNIEnv *env, jobject jobj)
  306. {
  307. COMMTIMEOUTS CommTimeouts;
  308. LPCWSTR lpMsgBuf;
  309. HANDLE hPort = get_fd(env, jobj);
  310. IF_DEBUG
  311. (
  312. printj(env, L"--- RXTXPort.NativeisReceiveTimeoutEnabled() called\n");
  313. )
  314. // Retrieve the time-out parameters for all read and write operations
  315. // on the port.
  316. if (!GetCommTimeouts(hPort, &CommTimeouts))
  317. { // Unable to get the time-out parameters
  318. CreateErrorMsg(GetLastError(), lpMsgBuf);
  319. throw_java_exceptionW(env, IO_EXCEPTION, L"NativeisReceiveTimeoutEnabled - GetCommTimeouts", lpMsgBuf);
  320. // Free the buffers.
  321. ReleaseErrorMsg(lpMsgBuf);
  322. return -1;
  323. }
  324. return CommTimeouts.ReadIntervalTimeout || CommTimeouts.ReadTotalTimeoutConstant || CommTimeouts.ReadTotalTimeoutMultiplier ? JNI_TRUE : JNI_FALSE;
  325. }
  326. /*
  327. NativeEnableReceiveTimeoutThreshold
  328. accept: int threshold, int vtime,int buffer
  329. perform: Set c_cc->VMIN to threshold and c_cc=>VTIME to vtime
  330. return: void
  331. exceptions: IOException
  332. comments: This is actually all handled in read with select in
  333. canonical input mode.
  334. * Class: gnu_io_RXTXPort
  335. * Method: NativeEnableReceiveTimeoutThreshold
  336. * Signature: (III)V
  337. */
  338. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_NativeEnableReceiveTimeoutThreshold(JNIEnv *env, jobject jobj, jint time, jint threshold, jint InputBuffer)
  339. {
  340. COMMTIMEOUTS CommTimeouts;
  341. LPCWSTR lpMsgBuf;
  342. HANDLE hPort = get_fd(env, jobj);
  343. IF_DEBUG
  344. (
  345. printj(env, L"--- RXTXPort.NativeEnableReceiveTimeoutThreshold(%ld, %ld) called\n", time, threshold);
  346. )
  347. // Retrieve the time-out parameters for all read and write operations
  348. // on the port.
  349. if (!GetCommTimeouts(hPort, &CommTimeouts))
  350. { // Unable to get the time-out parameters
  351. CreateErrorMsg(GetLastError(), lpMsgBuf);
  352. throw_java_exceptionW(env, IO_EXCEPTION, L"NativeEnableReceiveTimeoutThreshold - GetCommTimeouts", lpMsgBuf);
  353. // Free the buffers.
  354. ReleaseErrorMsg(lpMsgBuf);
  355. return;
  356. }
  357. /* ------ from javax.comm.CommPort javadoc -------------------------------------------------------------
  358. | Threshold | Timeout |Read Buffer Size | Read Behaviour
  359. |State |Value |State |Value| |
  360. |disabled| - |disabled| - | n bytes | block until any data is available
  361. |enabled |m bytes|disabled| - | n bytes | block until min(m,n) bytes are available
  362. |disabled| - |enabled |x ms | n bytes | block for x ms or until any data is available
  363. |enabled |m bytes|enabled |x ms | n bytes | block for x ms or until min(m,n) bytes are available
  364. --------------------------------------------------------------------------------------------------------
  365. Enabling the Timeout OR Threshold with a value a zero is a special case.
  366. This causes the underlying driver to poll for incoming data instead being event driven.
  367. Otherwise, the behaviour is identical to having both the Timeout and Threshold disabled.
  368. */
  369. // Following is based on my understanding of timeout parameters meaning.
  370. // Not completely precise (threshold?!)
  371. if(time == 0)
  372. { // polling mode - return if no data
  373. CommTimeouts.ReadIntervalTimeout = MAXDWORD;
  374. CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
  375. CommTimeouts.ReadTotalTimeoutConstant = 1;
  376. }
  377. else if(time == -1)
  378. { // disable timeout
  379. CommTimeouts.ReadIntervalTimeout = 0;
  380. CommTimeouts.ReadTotalTimeoutMultiplier = 0;
  381. CommTimeouts.ReadTotalTimeoutConstant = 0;
  382. }
  383. else
  384. { // set timeout
  385. CommTimeouts.ReadIntervalTimeout = 0;
  386. CommTimeouts.ReadTotalTimeoutMultiplier = 0;
  387. CommTimeouts.ReadTotalTimeoutConstant = time;
  388. }
  389. // Set the time-out parameters for all read and write operations
  390. // on the port.
  391. if (!SetCommTimeouts (hPort, &CommTimeouts))
  392. { // Unable to set the time-out parameters
  393. CreateErrorMsg(GetLastError(), lpMsgBuf);
  394. throw_java_exceptionW(env, IO_EXCEPTION, L"NativeEnableReceiveTimeoutThreshold - SetCommTimeouts", lpMsgBuf);
  395. // Free the buffers.
  396. ReleaseErrorMsg(lpMsgBuf);
  397. return;
  398. }
  399. }
  400. /*
  401. isDTR
  402. accept: none
  403. perform: check status of DTR
  404. return: true if TIOCM_DTR is set
  405. false if TIOCM_DTR is not set
  406. exceptions: none
  407. comments: DTR stands for Data Terminal Ready
  408. * Class: gnu_io_RXTXPort
  409. * Method: isDTR
  410. * Signature: ()Z
  411. */
  412. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isDTR(JNIEnv *env, jobject jobj)
  413. {
  414. DCB PortDCB;
  415. HANDLE hPort = get_fd(env, jobj);
  416. PortDCB.DCBlength = sizeof(DCB);
  417. // Get the default port setting information.
  418. if(!GetCommState(hPort, &PortDCB))
  419. {
  420. GetLastError();
  421. return JNI_FALSE;
  422. }
  423. // This is not completely correct: I assume that nobody's playing with
  424. // manually setting/resetting DTR. Instead, DTR is in handshake mode (ON unless
  425. // port closed) or disable mode (OFF).
  426. // So, don't use EscapeCommFunction(SETDTR/CLRDTR) in this library!
  427. return PortDCB.fDtrControl != DTR_CONTROL_DISABLE ? JNI_TRUE : JNI_FALSE;
  428. }
  429. /*
  430. setDTR
  431. accept: new DTR state
  432. perform: if state is true, TIOCM_DTR is set
  433. if state is false, TIOCM_DTR is unset
  434. return: none
  435. exceptions: none
  436. comments: DTR stands for Data Terminal Ready
  437. * Class: gnu_io_RXTXPort
  438. * Method: setDTR
  439. * Signature: (Z)V
  440. */
  441. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setDTR(JNIEnv *env, jobject jobj, jboolean state)
  442. {
  443. DCB PortDCB;
  444. HANDLE hPort = get_fd(env, jobj);
  445. PortDCB.DCBlength = sizeof(DCB);
  446. // Don't use EscapeCommFunction(SETDTR/CLRDTR) in this library!
  447. // Get the default port setting information.
  448. if(!GetCommState (hPort, &PortDCB))
  449. { //Unable to get configuration of the serial port
  450. GetLastError();
  451. return;
  452. }
  453. if(state == JNI_TRUE)
  454. PortDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;
  455. else
  456. PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
  457. // Configure the port according to the specifications of the DCB structure.
  458. if (!SetCommState (hPort, &PortDCB))
  459. { //Unable to configure the serial port
  460. GetLastError();
  461. return;
  462. }
  463. }
  464. /*
  465. setRTS
  466. accept: state flag to set/unset.
  467. perform: depends on the state flag
  468. if true TIOCM_RTS is set
  469. if false TIOCM_RTS is unset
  470. return: none
  471. exceptions: none
  472. comments: tcsetattr with c_cflag CRTS_IFLOW
  473. * Class: gnu_io_RXTXPort
  474. * Method: setRTS
  475. * Signature: (Z)V
  476. */
  477. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setRTS(JNIEnv *env, jobject jobj, jboolean state)
  478. {
  479. HANDLE hPort = get_fd(env, jobj);
  480. // EscapeCommFunction will fail if there's RTS/CTS flowcontrol. If it is incorrect,
  481. // we could turn flowcontrol off when getting to this function
  482. if(state == JNI_TRUE)
  483. EscapeCommFunction(hPort, SETRTS);
  484. else
  485. EscapeCommFunction(hPort, CLRRTS);
  486. }
  487. /*
  488. setDSR
  489. accept: state flag to set/unset.
  490. perform: depends on the state flag
  491. if true TIOCM_DSR is set
  492. if false TIOCM_DSR is unset
  493. return: none
  494. exceptions: none
  495. comments: tcsetattr with c_cflag CRTS_IFLOW
  496. * Class: gnu_io_RXTXPort
  497. * Method: setDSR
  498. * Signature: (Z)V
  499. */
  500. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setDSR(JNIEnv *env, jobject jobj, jboolean state)
  501. {
  502. DCB PortDCB;
  503. HANDLE hPort = get_fd(env, jobj);
  504. PortDCB.DCBlength = sizeof(DCB);
  505. // Get the default port setting information.
  506. if(!GetCommState (hPort, &PortDCB))
  507. { //Unable to get configuration of the serial port
  508. GetLastError();
  509. return;
  510. }
  511. // Change the DCB structure settings.
  512. if(state != JNI_FALSE)
  513. PortDCB.fOutxDsrFlow = TRUE;
  514. else
  515. PortDCB.fOutxDsrFlow = FALSE;
  516. // Configure the port according to the specifications of the DCB
  517. // structure.
  518. if (!SetCommState (hPort, &PortDCB))
  519. { //Unable to configure the serial port
  520. GetLastError();
  521. return;
  522. }
  523. }
  524. /*
  525. isCTS
  526. accept: none
  527. perform: check status of CTS
  528. return: true if TIOCM_CTS is set
  529. false if TIOCM_CTS is not set
  530. exceptions: none
  531. comments: CTS stands for Clear To Send.
  532. * Class: gnu_io_RXTXPort
  533. * Method: isCTS
  534. * Signature: ()Z
  535. */
  536. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isCTS(JNIEnv *env, jobject jobj)
  537. {
  538. DWORD ModemStat;
  539. HANDLE hPort = get_fd(env, jobj);
  540. if(!GetCommModemStatus(hPort, &ModemStat))
  541. return JNI_FALSE;
  542. return ModemStat|MS_CTS_ON ? JNI_TRUE : JNI_FALSE;
  543. }
  544. /*
  545. isDSR
  546. accept: none
  547. perform: check status of DSR
  548. return: true if TIOCM_DSR is set
  549. false if TIOCM_DSR is not set
  550. exceptions: none
  551. comments: DSR stands for Data Set Ready
  552. * Class: gnu_io_RXTXPort
  553. * Method: isDSR
  554. * Signature: ()Z
  555. */
  556. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isDSR(JNIEnv *env, jobject jobj)
  557. {
  558. DWORD ModemStat;
  559. HANDLE hPort = get_fd(env, jobj);
  560. if(!GetCommModemStatus(hPort, &ModemStat))
  561. return JNI_FALSE;
  562. return ModemStat|MS_DSR_ON ? JNI_TRUE : JNI_FALSE;
  563. }
  564. /*
  565. isCD
  566. accept: none
  567. perform: check status of CD
  568. return: true if TIOCM_CD is set
  569. false if TIOCM_CD is not set
  570. exceptions: none
  571. comments: CD stands for Carrier Detect
  572. The following comment has been made...
  573. "well, it works, there might ofcourse be a bug, but making DCD
  574. permanently on fixed it for me so I don't care"
  575. * Class: gnu_io_RXTXPort
  576. * Method: isCD
  577. * Signature: ()Z
  578. */
  579. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isCD(JNIEnv *env, jobject jobj)
  580. {
  581. DWORD ModemStat;
  582. HANDLE hPort = get_fd(env, jobj);
  583. if(!GetCommModemStatus(hPort, &ModemStat))
  584. return JNI_FALSE;
  585. return ModemStat|MS_RLSD_ON ? JNI_TRUE : JNI_FALSE;
  586. }
  587. /*
  588. isRI
  589. accept: none
  590. perform: check status of RI
  591. return: true if TIOCM_RI is set
  592. false if TIOCM_RI is not set
  593. exceptions: none
  594. comments: RI stands for Ring Indicator
  595. * Class: gnu_io_RXTXPort
  596. * Method: isRI
  597. * Signature: ()Z
  598. */
  599. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isRI(JNIEnv *env, jobject jobj)
  600. {
  601. DWORD ModemStat;
  602. HANDLE hPort = get_fd(env, jobj);
  603. if(!GetCommModemStatus(hPort, &ModemStat))
  604. return JNI_FALSE;
  605. return ModemStat|MS_RING_ON ? JNI_TRUE : JNI_FALSE;
  606. }
  607. /*
  608. isRTS
  609. accept: none
  610. perform: check status of RTS
  611. return: true if TIOCM_RTS is set
  612. false if TIOCM_RTS is not set
  613. exceptions: none
  614. comments: tcgetattr with c_cflag CRTS_IFLOW
  615. * Class: gnu_io_RXTXPort
  616. * Method: isRTS
  617. * Signature: ()Z
  618. */
  619. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isRTS(JNIEnv *env, jobject jobj)
  620. {
  621. DCB PortDCB;
  622. HANDLE hPort = get_fd(env, jobj);
  623. PortDCB.DCBlength = sizeof(DCB);
  624. if(!GetCommState (hPort, &PortDCB))
  625. { //Unable to get configuration of the serial port
  626. GetLastError();
  627. return JNI_FALSE;
  628. }
  629. if(PortDCB.fRtsControl == RTS_CONTROL_DISABLE)
  630. return JNI_FALSE;
  631. if(PortDCB.fRtsControl == RTS_CONTROL_ENABLE)
  632. return JNI_TRUE;
  633. if(PortDCB.fRtsControl == RTS_CONTROL_HANDSHAKE)
  634. {
  635. //MessageBox(NULL, L"Undefined condition: isRTS() but control is RTS_CONTROL_HANDSHAKE\r\nReturning FALSE", L"Warning", MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
  636. printj(env, L"Undefined condition: isRTS() but control is RTS_CONTROL_HANDSHAKE. Returning FALSE\n");
  637. return JNI_FALSE;
  638. }
  639. return JNI_FALSE;
  640. }
  641. /*
  642. sendBreak
  643. accept: duration in milliseconds.
  644. perform: send break for actual time. not less than 0.25 seconds.
  645. exceptions: none
  646. comments: not very precise
  647. * Class: gnu_io_RXTXPort
  648. * Method: sendBreak
  649. * Signature: (I)V
  650. */
  651. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_sendBreak(JNIEnv *env, jobject jobj, jint duration)
  652. {
  653. HANDLE hPort = get_fd(env, jobj);
  654. SetCommBreak(hPort);
  655. Sleep(duration);
  656. ClearCommBreak(hPort);
  657. }
  658. /*
  659. writeByte
  660. accept: byte to write (passed as int)
  661. perform: write a single byte to the port
  662. return: none
  663. exceptions: IOException
  664. * Class: gnu_io_RXTXPort
  665. * Method: writeByte
  666. * Signature: (IZ)V
  667. */
  668. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_writeByte(JNIEnv *env, jobject jobj, jint b, jboolean i)
  669. {
  670. DWORD dwNumBytesWritten;
  671. LPCWSTR lpMsgBuf;
  672. HANDLE hPort = get_fd(env, jobj);
  673. BYTE bb = (BYTE)b;
  674. do {
  675. if (!WriteFile(hPort, // Port handle
  676. &bb, // Pointer to the data to write
  677. 1, // Number of bytes to write
  678. &dwNumBytesWritten, // Pointer to the number of bytes written
  679. NULL)) // Must be NULL for Windows CE
  680. { // WriteFile failed. Report error.
  681. CreateErrorMsg(GetLastError(), lpMsgBuf);
  682. throw_java_exceptionW(env, IO_EXCEPTION, L"writeByte - WriteFile", lpMsgBuf );
  683. // Free the buffers.
  684. ReleaseErrorMsg(lpMsgBuf);
  685. return;
  686. }
  687. } while(dwNumBytesWritten == 0);
  688. }
  689. /*
  690. writeArray
  691. accept: jbarray: bytes used for writing
  692. off: offset in array to start writing
  693. len: Number of bytes to write
  694. perform: write length bytes of jbarray
  695. return: none
  696. exceptions: IOException
  697. * Class: gnu_io_RXTXPort
  698. * Method: writeArray
  699. * Signature: ([BIIZ)V
  700. */
  701. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_writeArray(JNIEnv *env, jobject jobj, jbyteArray b, jint off, jint len, jboolean i)
  702. {
  703. LPCWSTR lpMsgBuf;
  704. DWORD dwNumBytesWritten;
  705. jint total=0;
  706. HANDLE hPort = get_fd(env, jobj);
  707. jbyte *body = env->GetByteArrayElements(b, NULL);
  708. do {
  709. IF_DEBUG
  710. (
  711. printj(env, L"--- writeArray - %d bytes to write\n", len-total);
  712. )
  713. if (!WriteFile(hPort, // Port handle
  714. body+total+off, // Pointer to the data to write
  715. len-total, // Number of bytes to write
  716. &dwNumBytesWritten, // Pointer to the number of bytes written
  717. NULL)) // Must be NULL for Windows CE
  718. { // WriteFile failed. Report error.
  719. CreateErrorMsg(GetLastError(), lpMsgBuf);
  720. throw_java_exceptionW(env, IO_EXCEPTION, L"writeArray - WriteFile", lpMsgBuf );
  721. // Free the buffers.
  722. ReleaseErrorMsg(lpMsgBuf);
  723. env->ReleaseByteArrayElements(b, body, JNI_ABORT);
  724. return;
  725. }
  726. total += dwNumBytesWritten;
  727. } while( total < len );
  728. env->ReleaseByteArrayElements(b, body, JNI_ABORT);
  729. }
  730. /*
  731. nativeDrain
  732. accept: none
  733. perform: wait until all data is transmitted
  734. return: none
  735. exceptions: IOException
  736. comments: java.io.OutputStream.flush() is equivalent to tcdrain,
  737. not tcflush, which throws away unsent bytes
  738. count logic added to avoid infinite loops when EINTR is
  739. true... Thread.yeild() was suggested.
  740. * Class: gnu_io_RXTXPort
  741. * Method: nativeDrain
  742. * Signature: ()V
  743. */
  744. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeDrain(JNIEnv *env, jobject jobj, jboolean i)
  745. {
  746. //COMSTAT Stat;
  747. //DWORD dwErrors;
  748. HANDLE hPort = get_fd(env, jobj);
  749. IF_DEBUG
  750. (
  751. printj(env, L"--- RXTXPort.nativeDrain() called\n");
  752. )
  753. /*
  754. if(!FlushFileBuffers(hPort))
  755. {
  756. IF_DEBUG
  757. (
  758. printj(env, L"!!! FlushFileBuffers() error %ld\n", GetLastError());
  759. )
  760. return JNI_FALSE;
  761. }
  762. */
  763. // Alternative implementation:
  764. /*
  765. do
  766. {
  767. if(!ClearCommError(hPort, &dwErrors, &Stat))
  768. {
  769. GetLastError();
  770. return;
  771. }
  772. Sleep(10);
  773. } while(Stat.cbOutQue > 0);*/
  774. return JNI_FALSE;
  775. }
  776. /*
  777. nativeavailable
  778. accept: none
  779. perform: find out the number of bytes available for reading
  780. return: available bytes
  781. -1 on error
  782. exceptions: none /// should be IOException
  783. * Class: gnu_io_RXTXPort
  784. * Method: nativeavailable
  785. * Signature: ()I
  786. */
  787. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeavailable(JNIEnv *env, jobject jobj)
  788. {
  789. DWORD dwErrors;
  790. COMSTAT Stat;
  791. LPCWSTR lpMsgBuf;
  792. HANDLE hPort = get_fd(env, jobj);
  793. IF_DEBUG
  794. (
  795. printj(env, L"--- RXTXPort.nativeavailable() called");
  796. )
  797. if(!ClearCommError(hPort, &dwErrors, &Stat))
  798. {
  799. CreateErrorMsg(GetLastError(), lpMsgBuf);
  800. throw_java_exceptionW(env, IO_EXCEPTION, L"nativeavailable - ClearCommError", lpMsgBuf );
  801. // Free the buffers.
  802. ReleaseErrorMsg(lpMsgBuf);
  803. return -1;
  804. }
  805. IF_DEBUG
  806. (
  807. printj(env, L" - returning %ld\n", Stat.cbInQue);
  808. )
  809. return Stat.cbInQue;
  810. }
  811. /*
  812. readByte
  813. accept: none
  814. perform: Read a single byte from the port
  815. return: The byte read
  816. exceptions: IOException
  817. * Class: gnu_io_RXTXPort
  818. * Method: readByte
  819. * Signature: ()I
  820. */
  821. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_readByte(JNIEnv *env, jobject jobj)
  822. {
  823. BYTE bb;
  824. DWORD dwNumBytesRead;
  825. LPCWSTR lpMsgBuf;
  826. HANDLE hPort = get_fd(env, jobj);
  827. if (!ReadFile(hPort, &bb, 1, &dwNumBytesRead, NULL))
  828. { // ReadFile failed. Report error.
  829. CreateErrorMsg(GetLastError(), lpMsgBuf);
  830. throw_java_exceptionW(env, IO_EXCEPTION, L"readByte - ReadFile", lpMsgBuf);
  831. // Free the buffers.
  832. ReleaseErrorMsg(lpMsgBuf);
  833. return -1;
  834. }
  835. return dwNumBytesRead > 0 ? bb : -1;
  836. }
  837. /*
  838. readArray
  839. accept: offset (offset to start storing data in the jbarray) and
  840. Length (bytes to read)
  841. perform: read bytes from the port into a byte array
  842. return: bytes read on success
  843. 0 on read timeout
  844. exceptions: IOException
  845. comments: throws ArrayIndexOutOfBoundsException if asked to
  846. read more than SSIZE_MAX bytes
  847. * Class: gnu_io_RXTXPort
  848. * Method: readArray
  849. * Signature: ([BII)I
  850. */
  851. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_readArray(JNIEnv *env, jobject jobj, jbyteArray b, jint off, jint len)
  852. {
  853. LPCWSTR lpMsgBuf;
  854. DWORD dwNumBytesRead, dwTotalRead = 0;
  855. jint threshold;
  856. HANDLE hPort = get_fd(env, jobj);
  857. if(len < 0)
  858. {
  859. throw_java_exceptionW(env, ARRAY_INDEX_OUT_OF_BOUNDS, L"readArray", L"Negative number of character to read");
  860. return -1;
  861. }
  862. jbyte *body = env->GetByteArrayElements(b, NULL);
  863. threshold = get_java_int_var(env, jobj, "threshold");
  864. do
  865. {
  866. if (!ReadFile(hPort, (unsigned char *)(body+off), len, &dwNumBytesRead, NULL))
  867. { // ReadFile failed. Report error.
  868. CreateErrorMsg(GetLastError(), lpMsgBuf);
  869. throw_java_exceptionW(env, IO_EXCEPTION, L"readArray - WriteFile", lpMsgBuf );
  870. // Free the buffers.
  871. ReleaseErrorMsg(lpMsgBuf);
  872. env->ReleaseByteArrayElements(b, body, JNI_ABORT);
  873. return -1;
  874. }
  875. dwTotalRead += dwNumBytesRead;
  876. } while(dwNumBytesRead > 0 && threshold != 0 && dwTotalRead <= (DWORD)len && dwTotalRead < (DWORD)threshold);
  877. env->ReleaseByteArrayElements(b, body, 0);
  878. return dwTotalRead;
  879. }
  880. /*
  881. eventLoop
  882. accept: none
  883. perform: periodically check for SerialPortEvents
  884. return: none
  885. exceptions: none
  886. comments: please keep this function clean.
  887. * Class: gnu_io_RXTXPort
  888. * Method: eventLoop
  889. * Signature: ()V
  890. */
  891. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_eventLoop(JNIEnv *env, jobject jobj)
  892. {
  893. jfieldID jfMonitorThreadCloseLock, jfMonitorThreadLock, jfMonThreadisInterrupted;
  894. jmethodID jmSendEvent;
  895. HANDLE hCommEventThread;
  896. DWORD dwThreadID, dwWaitResult, dwEvent;
  897. int RetVal;
  898. HANDLE hPort = get_fd(env, jobj);
  899. EventInfoStruct *EventInfo = get_eis(env, jobj);
  900. IF_DEBUG
  901. (
  902. printj(env, L"--- RXTXPort.eventLoop() start\n");
  903. )
  904. jclass cls = env->GetObjectClass(jobj);
  905. // Get pointers to some Java variables and methods:
  906. if( !(jfMonitorThreadLock = env->GetFieldID(cls, "MonitorThreadLock", "Z")) ||
  907. !(jfMonThreadisInterrupted = env->GetFieldID(cls, "monThreadisInterrupted", "Z")) ||
  908. !(jfMonitorThreadCloseLock = env->GetFieldID(cls, "MonitorThreadCloseLock", "Z")) ||
  909. !(jmSendEvent = env->GetMethodID(cls, "sendEvent", "(IZ)Z"))
  910. )
  911. {
  912. IF_DEBUG
  913. (
  914. env->ExceptionDescribe();
  915. )
  916. env->ExceptionClear();
  917. return;
  918. }
  919. hCommEventThread = CreateThread(NULL, 0, CommEventThread, (LPVOID)EventInfo, 0, &dwThreadID);
  920. if(hCommEventThread == NULL)
  921. {
  922. LPCWSTR lpMsgBuf;
  923. CreateErrorMsg(GetLastError(), lpMsgBuf);
  924. printj(env, L"!!! eventLoop - CreateThread() error: %s\n", lpMsgBuf);
  925. ReleaseErrorMsg(lpMsgBuf);
  926. return;
  927. }
  928. CloseHandle(hCommEventThread);
  929. do
  930. {
  931. if(env->GetBooleanField(jobj, jfMonThreadisInterrupted) == JNI_TRUE)
  932. {
  933. IF_DEBUG
  934. (
  935. printj(env, L"--- RXTXPort.eventLoop() interrupted - exiting\n");
  936. )
  937. CloseHandle(EventInfo->eventHandle);
  938. env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
  939. return;
  940. }
  941. if(EventInfo->eventThreadReady)
  942. { // Thread is ready to work - pass signal to Java
  943. IF_DEBUG
  944. (
  945. printj(env, L"--- RXTXPort.eventLoop() - EventThread is ready\n");
  946. )
  947. env->SetBooleanField(jobj, jfMonitorThreadLock, JNI_FALSE);
  948. EventInfo->eventThreadReady = false;
  949. }
  950. if((dwWaitResult = WaitForSingleObject(EventInfo->eventHandle, 250)) == WAIT_FAILED)
  951. {
  952. IF_DEBUG
  953. (
  954. LPCWSTR lpMsgBuf;
  955. CreateErrorMsg(GetLastError(), lpMsgBuf);
  956. printj(env, L"!!! eventLoop - WaitForSingleObject() error: %s\n", lpMsgBuf);
  957. ReleaseErrorMsg(lpMsgBuf);
  958. )
  959. CloseHandle(EventInfo->eventHandle);
  960. env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
  961. return;
  962. }
  963. if(dwWaitResult == WAIT_OBJECT_0)
  964. {
  965. dwEvent = EventInfo->event;
  966. // Clearing event - event thread will continue
  967. EventInfo->event = 0;
  968. // Send events to Java
  969. if(RetVal = SendEvents(env, jobj, dwEvent, EventInfo, jmSendEvent))
  970. {
  971. IF_DEBUG
  972. (
  973. printj(env, L"!!! eventLoop - SendEvents() result: %d\n", RetVal);
  974. )
  975. CloseHandle(EventInfo->eventHandle);
  976. env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
  977. return;
  978. }
  979. }
  980. else
  981. {
  982. IF_DEBUG
  983. (
  984. //printj(env, L"--- eventLoop() looping\n");
  985. MessageBeep(MB_OK);
  986. )
  987. }
  988. } while(TRUE);
  989. }
  990. /*
  991. interruptEventLoop
  992. accept: nothing
  993. perform: sets monThreadisInterrupted
  994. return: nothing
  995. exceptions: none
  996. comments: real monitoring thread will stay until port is closed
  997. * Class: gnu_io_RXTXPort
  998. * Method: interruptEventLoop
  999. * Signature: ()V
  1000. */
  1001. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_interruptEventLoop(JNIEnv *env, jobject jobj)
  1002. {
  1003. jfieldID jfid;
  1004. HANDLE hPort = get_fd(env, jobj);
  1005. jclass cls = env->GetObjectClass(jobj);
  1006. jfid = env->GetFieldID(cls, "monThreadisInterrupted", "Z");
  1007. env->SetBooleanField(jobj, jfid, JNI_TRUE);
  1008. }
  1009. /*
  1010. nativeSetEventFlag
  1011. accept: fd for finding the struct, event to flag, flag.
  1012. perform: toggle the flag
  1013. return: none
  1014. exceptions: none
  1015. comments: all the logic used to be done in Java but its too noisy
  1016. * Class: gnu_io_RXTXPort
  1017. * Method: nativeSetEventFlag
  1018. * Signature: (IIZ)V
  1019. */
  1020. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeSetEventFlag(JNIEnv *env, jobject jobj, jint fd, jint event, jboolean flag)
  1021. {
  1022. DWORD dwErr, NewFlag;
  1023. EventInfoStruct *EventInfo = get_eis(env, jobj);
  1024. HANDLE hPort = (HANDLE)fd;
  1025. IF_DEBUG
  1026. (
  1027. printj(env, L"--- nativeSetEventFlag(%ld, %d) called\n", event, (int)flag);
  1028. )
  1029. switch(event)
  1030. {
  1031. case SPE_DATA_AVAILABLE:
  1032. NewFlag = EV_RXCHAR;
  1033. break;
  1034. case SPE_OUTPUT_BUFFER_EMPTY:
  1035. NewFlag = EV_TXEMPTY;
  1036. break;
  1037. case SPE_CTS:
  1038. NewFlag = EV_CTS;
  1039. break;
  1040. case SPE_DSR:
  1041. NewFlag = EV_DSR;
  1042. break;
  1043. case SPE_RI:
  1044. NewFlag = EV_RING;
  1045. break;
  1046. case SPE_CD:
  1047. NewFlag = EV_RLSD;
  1048. break;
  1049. case SPE_OE:
  1050. case SPE_PE:
  1051. case SPE_FE:
  1052. NewFlag = EV_ERR;
  1053. break;
  1054. case SPE_BI:
  1055. NewFlag = EV_BREAK;
  1056. break;
  1057. }
  1058. if(flag == JNI_TRUE)
  1059. EventInfo->ef = EventInfo->ef | NewFlag;
  1060. else
  1061. EventInfo->ef = EventInfo->ef & ~NewFlag;
  1062. if(!SetCommMask(hPort, EventInfo->ef))
  1063. {
  1064. dwErr = GetLastError();
  1065. IF_DEBUG
  1066. (
  1067. LPCWSTR lpMsgBuf;
  1068. CreateErrorMsg(dwErr, lpMsgBuf);
  1069. printj(env, L"!!! nativeSetEventFlag - SetCommMask() error: %ld %s\n", dwErr, lpMsgBuf );
  1070. ReleaseErrorMsg(lpMsgBuf);
  1071. )
  1072. return;
  1073. }
  1074. }
  1075. /*
  1076. nativeClose
  1077. accept: none
  1078. perform: get the fd from the java end and close it
  1079. return: none
  1080. exceptions: none
  1081. * Class: gnu_io_RXTXPort
  1082. * Method: nativeClose
  1083. * Signature: (Ljava/lang/String{ })V
  1084. */
  1085. JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeClose(JNIEnv *env, jobject jobj, jstring name)
  1086. {
  1087. HANDLE hPort = get_fd(env, jobj);
  1088. IF_DEBUG
  1089. (
  1090. LPCWSTR wszName = env->GetStringChars(name, NULL);
  1091. printj(env, L"--- RXTXPort.nativeClose(%s) called\n", wszName);
  1092. env->ReleaseStringChars(name, wszName);
  1093. )
  1094. if (!CloseHandle(hPort))
  1095. {
  1096. GetLastError();
  1097. return;
  1098. }
  1099. }
  1100. /*
  1101. nativeGetParityErrorChar
  1102. accept: -
  1103. perform: check the ParityErrorChar
  1104. return: The ParityErrorChar as an jbyte.
  1105. exceptions: UnsupportedCommOperationException if not implemented
  1106. comments: It appears the Parity char is usually \0. The windows
  1107. API allows for this to be changed. I cant find may
  1108. examples of this being done. Maybe for a reason.
  1109. Use a direct call to the termios file until we find a
  1110. solution.
  1111. * Class: gnu_io_RXTXPort
  1112. * Method: nativeGetParityErrorChar
  1113. * Signature: ()I
  1114. */
  1115. JNIEXPORT jbyte JNICALL Java_gnu_io_RXTXPort_nativeGetParityErrorChar(JNIEnv *env, jobject jobj)
  1116. {
  1117. DCB PortDCB;
  1118. LPCWSTR lpMsgBuf;
  1119. HANDLE hPort = get_fd(env, jobj);
  1120. PortDCB.DCBlength = sizeof(DCB);
  1121. IF_DEBUG
  1122. (
  1123. printj(env, L"--- RXTXPort.nativeGetParityErrorChar() called\n");
  1124. )
  1125. // Get port setting information.
  1126. if(!GetCommState(hPort, &PortDCB))
  1127. { //Unable to get configuration of the serial port
  1128. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1129. IF_DEBUG
  1130. (
  1131. printj(env, L"!!! nativeGetParityErrorChar - GetCommState() error: %s\n", lpMsgBuf);
  1132. )
  1133. ReleaseErrorMsg(lpMsgBuf);
  1134. return -1;
  1135. }
  1136. return (jbyte)PortDCB.ErrorChar;
  1137. }
  1138. /*
  1139. nativeSetParityErrorChar
  1140. accept: the ParityArrorCharacter as an int.
  1141. perform: Set the ParityErrorChar
  1142. return: JNI_TRUE on success
  1143. exceptions: UnsupportedCommOperationException if not implemented
  1144. comments: It appears the Parity char is usually \0. The windows
  1145. API allows for this to be changed. I cant find may
  1146. examples of this being done. Maybe for a reason.
  1147. Use a direct call to the termios file until we find a
  1148. solution.
  1149. * Class: gnu_io_RXTXPort
  1150. * Method: nativeSetParityErrorChar
  1151. * Signature: (B)Z
  1152. */
  1153. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetParityErrorChar(JNIEnv *env, jobject jobj, jbyte b)
  1154. {
  1155. DCB PortDCB;
  1156. LPCWSTR lpMsgBuf;
  1157. HANDLE hPort = get_fd(env, jobj);
  1158. PortDCB.DCBlength = sizeof(DCB);
  1159. IF_DEBUG
  1160. (
  1161. printj(env, L"--- RXTXPort.nativeSetParityErrorChar(%#x) called\n", (int)b);
  1162. )
  1163. // Get port setting information.
  1164. if(!GetCommState(hPort, &PortDCB))
  1165. { //Unable to get configuration of the serial port
  1166. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1167. IF_DEBUG
  1168. (
  1169. printj(env, L"!!! nativeSetParityErrorChar - GetCommState() error: %s\n", lpMsgBuf);
  1170. )
  1171. ReleaseErrorMsg(lpMsgBuf);
  1172. return JNI_FALSE;
  1173. }
  1174. if(b != 0)
  1175. {
  1176. PortDCB.fErrorChar = TRUE;
  1177. PortDCB.fParity = TRUE;
  1178. PortDCB.ErrorChar = b;
  1179. }
  1180. else
  1181. {
  1182. PortDCB.fErrorChar = FALSE;
  1183. PortDCB.fParity = FALSE;
  1184. PortDCB.ErrorChar = 0;
  1185. }
  1186. if (!SetCommState(hPort, &PortDCB))
  1187. {
  1188. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1189. IF_DEBUG
  1190. (
  1191. printj(env, L"!!! nativeSetParityErrorChar - SetCommState() error: %s\n", lpMsgBuf);
  1192. )
  1193. ReleaseErrorMsg(lpMsgBuf);
  1194. return JNI_FALSE;
  1195. }
  1196. return JNI_TRUE;
  1197. }
  1198. /*
  1199. nativeGetEndOfInputChar
  1200. accept: -
  1201. perform: check the EndOf InputChar
  1202. return: the EndOfInputChar as an jbyte. -1 on error
  1203. exceptions: UnsupportedCommOperationException if not implemented
  1204. comments:
  1205. * Class: gnu_io_RXTXPort
  1206. * Method: nativeGetEndOfInputChar
  1207. * Signature: ()I
  1208. */
  1209. JNIEXPORT jbyte JNICALL Java_gnu_io_RXTXPort_nativeGetEndOfInputChar(JNIEnv *env, jobject jobj)
  1210. {
  1211. DCB PortDCB;
  1212. LPCWSTR lpMsgBuf;
  1213. HANDLE hPort = get_fd(env, jobj);
  1214. PortDCB.DCBlength = sizeof(DCB);
  1215. IF_DEBUG
  1216. (
  1217. printj(env, L"--- RXTXPort.nativeGetEndOfInputChar() called\n");
  1218. )
  1219. // Get port setting information.
  1220. if(!GetCommState(hPort, &PortDCB))
  1221. { //Unable to get configuration of the serial port
  1222. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1223. IF_DEBUG
  1224. (
  1225. printj(env, L"!!! nativeGetEndOfInputChar - GetCommState() error: %s\n", lpMsgBuf);
  1226. )
  1227. ReleaseErrorMsg(lpMsgBuf);
  1228. return -1;
  1229. }
  1230. return (jbyte)PortDCB.EofChar;
  1231. }
  1232. /*
  1233. nativeSetEndOfInputChar
  1234. accept: The EndOfInputChar as an int
  1235. perform: set the EndOfInputChar
  1236. return: JNI_TRUE on success
  1237. exceptions: UnsupportedCommOperationException if not implemented
  1238. comments: This may cause troubles on Windows.
  1239. Lets give it a shot and see what happens.
  1240. See termios.c for the windows bits.
  1241. EofChar = val;
  1242. fBinary = false; //winapi docs say always use true. ?
  1243. * Class: gnu_io_RXTXPort
  1244. * Method: nativeSetEndOfInputChar
  1245. * Signature: (B)Z
  1246. */
  1247. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetEndOfInputChar(JNIEnv *env, jobject jobj, jbyte b)
  1248. {
  1249. DCB PortDCB;
  1250. LPCWSTR lpMsgBuf;
  1251. HANDLE hPort = get_fd(env, jobj);
  1252. PortDCB.DCBlength = sizeof(DCB);
  1253. IF_DEBUG
  1254. (
  1255. printj(env, L"--- RXTXPort.nativeSetEndOfInputChar(%#x) called\n", (int)b);
  1256. )
  1257. // Get port setting information.
  1258. if(!GetCommState(hPort, &PortDCB))
  1259. { //Unable to get configuration of the serial port
  1260. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1261. IF_DEBUG
  1262. (
  1263. printj(env, L"!!! nativeSetEndOfInputChar - GetCommState() error: %s\n", lpMsgBuf);
  1264. )
  1265. ReleaseErrorMsg(lpMsgBuf);
  1266. return JNI_FALSE;
  1267. }
  1268. if( b != 0)
  1269. {
  1270. PortDCB.fBinary = FALSE;
  1271. PortDCB.EofChar = b;
  1272. }
  1273. else
  1274. {
  1275. PortDCB.fBinary = TRUE;
  1276. PortDCB.EofChar = 0;
  1277. }
  1278. if (!SetCommState(hPort, &PortDCB))
  1279. {
  1280. CreateErrorMsg(GetLastError(), lpMsgBuf);
  1281. IF_DEBUG
  1282. (
  1283. printj(env, L"!!! nativeSetEndOfInputChar - SetCommState() error: %s\n", lpMsgBuf);
  1284. )
  1285. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetEndOfInputChar", lpMsgBuf);
  1286. ReleaseErrorMsg(lpMsgBuf);
  1287. return JNI_FALSE;
  1288. }
  1289. return JNI_TRUE;
  1290. }
  1291. /*
  1292. * Class: gnu_io_RXTXPort
  1293. * Method: nativeSetUartType
  1294. * Signature: (Ljava/lang/String{ }Z)Z
  1295. */
  1296. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetUartType(JNIEnv *env, jobject jobj, jstring type, jboolean test)
  1297. {
  1298. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetUartType", L"Operation not implemented");
  1299. return JNI_FALSE;
  1300. }
  1301. /*
  1302. * Class: gnu_io_RXTXPort
  1303. * Method: nativeGetUartType
  1304. * Signature: ()Ljava/lang/String{ }
  1305. */
  1306. JNIEXPORT jstring JNICALL Java_gnu_io_RXTXPort_nativeGetUartType(JNIEnv *env, jobject jobj)
  1307. {
  1308. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetUartType", L"Operation not implemented");
  1309. return env->NewStringUTF("Unknown");
  1310. }
  1311. /*
  1312. * Class: gnu_io_RXTXPort
  1313. * Method: nativeSetBaudBase
  1314. * Signature: (I)Z
  1315. */
  1316. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetBaudBase(JNIEnv *env, jobject jobj, jint baudBase)
  1317. {
  1318. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetBaudBase", L"Operation not implemented");
  1319. return JNI_FALSE;
  1320. }
  1321. /*
  1322. * Class: gnu_io_RXTXPort
  1323. * Method: nativeGetBaudBase
  1324. * Signature: ()I
  1325. */
  1326. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeGetBaudBase(JNIEnv *env, jobject jobj)
  1327. {
  1328. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetBaudBase", L"Operation not implemented");
  1329. return -1;
  1330. }
  1331. /*
  1332. * Class: gnu_io_RXTXPort
  1333. * Method: nativeSetDivisor
  1334. * Signature: (I)Z
  1335. */
  1336. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetDivisor(JNIEnv *env, jobject jobj, jint divisor)
  1337. {
  1338. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetDivisor", L"Operation not implemented");
  1339. return JNI_FALSE;
  1340. }
  1341. /*
  1342. * Class: gnu_io_RXTXPort
  1343. * Method: nativeGetDivisor
  1344. * Signature: ()I
  1345. */
  1346. JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeGetDivisor(JNIEnv *env, jobject jobj)
  1347. {
  1348. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetDivisor", L"Operation not implemented");
  1349. return -1;
  1350. }
  1351. /*
  1352. * Class: gnu_io_RXTXPort
  1353. * Method: nativeSetLowLatency
  1354. * Signature: ()Z
  1355. */
  1356. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetLowLatency(JNIEnv *env, jobject jobj)
  1357. {
  1358. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetLowLatency", L"Operation not implemented");
  1359. return JNI_FALSE;
  1360. }
  1361. /*
  1362. * Class: gnu_io_RXTXPort
  1363. * Method: nativeGetLowLatency
  1364. * Signature: ()Z
  1365. */
  1366. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeGetLowLatency(JNIEnv *env, jobject jobj)
  1367. {
  1368. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetLowLatency", L"Operation not implemented");
  1369. return JNI_FALSE;
  1370. }
  1371. /*
  1372. * Class: gnu_io_RXTXPort
  1373. * Method: nativeSetCallOutHangup
  1374. * Signature: (Z)Z
  1375. */
  1376. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetCallOutHangup(JNIEnv *env, jobject jobj, jboolean noHup)
  1377. {
  1378. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetCallOutHangup", L"Operation not implemented");
  1379. return JNI_FALSE;
  1380. }
  1381. /*
  1382. * Class: gnu_io_RXTXPort
  1383. * Method: nativeGetCallOutHangup
  1384. * Signature: ()Z
  1385. */
  1386. JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeGetCallOutHangup(JNIEnv *env, jobject jobj)
  1387. {
  1388. throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetCallOutHangup", L"Operation not implemented");
  1389. return JNI_FALSE;
  1390. }