Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 69a1de31a3132dae6c80192a82b604733d1736cb (plain) (tree)




















































































































































                                                                                                                 
/*******************************************************************************
 * Copyright (c) 2015 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     QNX Software Systems - Initial API and implementation
 *******************************************************************************/
#include "stdafx.h"

extern "C"
JNIEXPORT jlong JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_open0
(JNIEnv *env, jobject jobj, jstring portName, jint baudRate, jint byteSize, jint parity, jint stopBits)
{
	const wchar_t * cportName = (const wchar_t *) env->GetStringChars(portName, NULL);
	HANDLE handle = CreateFile(cportName,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_OVERLAPPED,
		NULL);

	if (handle != INVALID_HANDLE_VALUE) {
		DCB dcb = { 0 };

		if (!GetCommState(handle, &dcb)) {
			fprintf(stderr, "Error getting DCB: %S\n", cportName);
			return -1;
		}

		dcb.BaudRate = baudRate;
		dcb.ByteSize = (BYTE) byteSize;

		switch (parity) {
		case 0: // None
			dcb.fParity = FALSE;
			break;
		case 1: // Even
			dcb.fParity = TRUE;
			dcb.Parity = EVENPARITY;
			break;
		case 2: // Odd
			dcb.fParity = TRUE;
			dcb.Parity = ODDPARITY;
			break;
		}
		
		switch (stopBits) {
		case 0:
			dcb.StopBits = ONESTOPBIT;
			break;
		case 1:
			dcb.StopBits = TWOSTOPBITS;
			break;
		}

		if (!SetCommState(handle, &dcb)) {
			fprintf(stderr, "Error setting DCB: %S\n", cportName);
			return -1;
		}
	}

	return (jlong) handle;
}

extern "C"
JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_close0
(JNIEnv *env, jobject jobj, jlong handle)
{
	CloseHandle((HANDLE) handle);
}

extern "C"
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_read0
(JNIEnv *env, jobject jobj, jlong jhandle)
{
	OVERLAPPED olp = { 0 };

	olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (olp.hEvent == NULL) {
		fprintf(stderr, "Error creating event\n");
		fflush(stderr);
		return -1;
	}

	char buff;
	DWORD nwritten;
	HANDLE handle = (HANDLE)jhandle;

	if (!ReadFile(handle, &buff, sizeof(buff), &nwritten, &olp)) {
		if (GetLastError() != ERROR_IO_PENDING) {
			fprintf(stderr, "Error reading from port: %d\n", GetLastError());
			fflush(stderr);
			return -1;
		}
		else {
			switch (WaitForSingleObject(olp.hEvent, INFINITE)) {
			case WAIT_OBJECT_0:
				if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) {
					if (GetLastError() != ERROR_OPERATION_ABORTED) {
						fprintf(stderr, "Error waiting for read: %d\n", GetLastError());
						fflush(stderr);
					}
					return -1;
				}
				break;
			}
		}
	}

	CloseHandle(olp.hEvent);
	return buff;
}

extern "C"
JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_write0
(JNIEnv *env, jobject jobj, jlong jhandle, jint b)
{
	OVERLAPPED olp = { 0 };

	olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (olp.hEvent == NULL) {
		fprintf(stderr, "Error creating event\n");
		return;
	}

	char buff = (char) b;
	DWORD nwritten;
	HANDLE handle = (HANDLE) jhandle;

	if (!WriteFile(handle, &buff, sizeof(buff), &nwritten, &olp)) {
		if (GetLastError() != ERROR_IO_PENDING) {
			fprintf(stderr, "Error writing to port\n");
		}
		else {
			switch (WaitForSingleObject(olp.hEvent, INFINITE)) {
			case WAIT_OBJECT_0:
				if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) {
					fprintf(stderr, "Error waiting for write\n");
				}
			}
		}
	}

	CloseHandle(olp.hEvent);
}

Back to the top