diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cec9c3d..451396c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,10 @@ -name: Build Binarys +name: Build Binaries on: push: + branches: + - dev + - testing paths: - 'cpp/**' - '.github/workflows/build.yml' diff --git a/cpp/include/serial.h b/cpp/include/serial.h index 6eded48..1aa75da 100644 --- a/cpp/include/serial.h +++ b/cpp/include/serial.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include "status_codes.h" @@ -22,17 +23,18 @@ extern void (*writeCallback)(int bytes); extern "C" { #endif - MODULE_API void serialOpen( + MODULE_API auto serialOpen( void* port, const int baudrate, const int dataBits, const int parity = 0, const int stopBits = 0 - ); + ) -> int64_t; - MODULE_API void serialClose(); + MODULE_API void serialClose(int64_t pointer); MODULE_API auto serialRead( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, @@ -40,6 +42,7 @@ extern "C" { ) -> int; MODULE_API auto serialReadUntil( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, @@ -48,6 +51,7 @@ extern "C" { ) -> int; MODULE_API auto serialWrite( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, diff --git a/cpp/src/serial_unix.cpp b/cpp/src/serial_unix.cpp index 7fca11b..f364fcd 100644 --- a/cpp/src/serial_unix.cpp +++ b/cpp/src/serial_unix.cpp @@ -9,21 +9,23 @@ #include #include +namespace { int hSerialPort; termios2 tty; std::string data; +} void (*errorCallback)(int errorCode); void (*readCallback)(int bytes); void (*writeCallback)(int bytes); -void serialOpen( +auto serialOpen( void* port, const int baudrate, const int dataBits, const int parity, const int stopBits -) { +) -> int64_t { char *portName = static_cast(port); // Open new serial connection hSerialPort = open(portName, O_RDWR); @@ -31,13 +33,13 @@ void serialOpen( // Error if open fails if(hSerialPort == -1){ errorCallback(status(StatusCodes::INVALID_HANDLE_ERROR)); - return; + return -1; } // Get the current com configuration if(ioctl(hSerialPort, TCGETS2, &tty) == -1){ errorCallback(status(StatusCodes::GET_STATE_ERROR)); - return; + return -1; } tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common) @@ -114,13 +116,13 @@ void serialOpen( // Save tty settings, also checking for error if (ioctl(hSerialPort, TCSETS2, &tty) == -1){ errorCallback(status(StatusCodes::SET_STATE_ERROR)); - return; + return -1; } - return; + return 0; } -void serialClose() { +void serialClose(int64_t pointer) { // Error if close fails if (close(hSerialPort) == -1) { errorCallback(status(StatusCodes::CLOSE_HANDLE_ERROR)); @@ -131,6 +133,7 @@ void serialClose() { } auto serialRead( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, @@ -166,6 +169,7 @@ auto serialRead( } auto serialReadUntil( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, @@ -200,6 +204,7 @@ auto serialReadUntil( } auto serialWrite( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, diff --git a/cpp/src/serial_windows.cpp b/cpp/src/serial_windows.cpp index 1044cbb..e39028e 100644 --- a/cpp/src/serial_windows.cpp +++ b/cpp/src/serial_windows.cpp @@ -1,25 +1,26 @@ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) #include - #include "serial.h" - -HANDLE hSerialPort; +namespace { DCB dcbSerialParams = {0}; COMMTIMEOUTS timeouts = {0}; std::string data; +} void (*errorCallback)(int errorCode); void (*readCallback)(int bytes); void (*writeCallback)(int bytes); -void serialOpen( +auto serialOpen( void* port, const int baudrate, const int dataBits, const int parity, const int stopBits -) { +) -> int64_t { + + HANDLE hSerialPort; char *portName = static_cast(port); @@ -38,7 +39,7 @@ void serialOpen( // Error if open fails if (hSerialPort == INVALID_HANDLE_VALUE) { errorCallback(status(StatusCodes::INVALID_HANDLE_ERROR)); - return; + return -1; } // Error if configuration get fails @@ -46,12 +47,12 @@ void serialOpen( // Error if close fails if (!CloseHandle(hSerialPort)) { errorCallback(status(StatusCodes::CLOSE_HANDLE_ERROR)); - return; + return -1; } errorCallback(status(StatusCodes::GET_STATE_ERROR)); - return; + return -1; } dcbSerialParams.BaudRate = baudrate; @@ -64,11 +65,11 @@ void serialOpen( // Error if close fails if (!CloseHandle(hSerialPort)) { errorCallback(status(StatusCodes::CLOSE_HANDLE_ERROR)); - return; + return -1; } errorCallback(status(StatusCodes::SET_STATE_ERROR)); - return; + return -1; } timeouts.ReadIntervalTimeout = 50; @@ -82,15 +83,18 @@ void serialOpen( // Error if close fails if (!CloseHandle(hSerialPort)) { errorCallback(status(StatusCodes::CLOSE_HANDLE_ERROR)); - return; + return -1; } errorCallback(status(StatusCodes::SET_TIMEOUT_ERROR)); - return; + return -1; } + return int64_t(hSerialPort); } -void serialClose() { +void serialClose(int64_t pointer) { + HANDLE hSerialPort = reinterpret_cast(pointer); + // Error if handle is invalid if (hSerialPort == INVALID_HANDLE_VALUE) { errorCallback(status(StatusCodes::INVALID_HANDLE_ERROR)); @@ -105,11 +109,14 @@ void serialClose() { } auto serialRead( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, const int multiplier ) -> int { + HANDLE hSerialPort = reinterpret_cast(pointer); + // Error if handle is invalid if (hSerialPort == INVALID_HANDLE_VALUE) { errorCallback(status(StatusCodes::INVALID_HANDLE_ERROR)); @@ -117,7 +124,7 @@ auto serialRead( } timeouts.ReadIntervalTimeout = timeout; - timeouts.ReadTotalTimeoutConstant = timeout; + timeouts.ReadTotalTimeoutConstant = multiplier; timeouts.ReadTotalTimeoutMultiplier = multiplier; // Error if timeout set fails @@ -139,12 +146,15 @@ auto serialRead( } auto serialReadUntil( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, const int multiplier, void* searchString ) -> int { + HANDLE hSerialPort = reinterpret_cast(pointer); + // Error if handle is invalid if (hSerialPort == INVALID_HANDLE_VALUE) { errorCallback(status(StatusCodes::INVALID_HANDLE_ERROR)); @@ -152,7 +162,7 @@ auto serialReadUntil( } timeouts.ReadIntervalTimeout = timeout; - timeouts.ReadTotalTimeoutConstant = timeout; + timeouts.ReadTotalTimeoutConstant = multiplier; timeouts.ReadTotalTimeoutMultiplier = multiplier; // Error if timeout set fails @@ -187,11 +197,13 @@ auto serialReadUntil( } auto serialWrite( + int64_t pointer, void* buffer, const int bufferSize, const int timeout, const int multiplier ) -> int { + HANDLE hSerialPort = reinterpret_cast(pointer); DWORD bytesWritten = 0; diff --git a/links.md b/links.md new file mode 100644 index 0000000..e10687f --- /dev/null +++ b/links.md @@ -0,0 +1,6 @@ +- [Communications Functions](https://learn.microsoft.com/en-us/windows/win32/devio/communications-functions) +- [CreateFileA function](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea) +- [CloseHandle function](https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle) +- [ReadFile function](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile) +- [WriteFile function](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile) +- [PurgeComm function](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm) diff --git a/mod.ts b/mod.ts index 57749b1..7a304bd 100644 --- a/mod.ts +++ b/mod.ts @@ -1,6 +1,6 @@ -export { Serial } from './lib/Serial.ts'; -export { baudrates } from './lib/constants/baudrates.ts'; -export { dataBits } from './lib/constants/data_bits.ts'; -export { parity } from './lib/constants/parity.ts'; -export { stopBits } from './lib/constants/stop_bits.ts'; -export { statusCodes } from './lib/constants/status_codes.ts'; +export { Serial } from './ts/Serial.ts'; +export { baudrates } from './ts/constants/baudrates.ts'; +export { dataBits } from './ts/constants/data_bits.ts'; +export { parity } from './ts/constants/parity.ts'; +export { stopBits } from './ts/constants/stop_bits.ts'; +export { statusCodes } from './ts/constants/status_codes.ts'; diff --git a/schnittstelle.drawio b/schnittstelle.drawio new file mode 100644 index 0000000..b668eed --- /dev/null +++ b/schnittstelle.drawio @@ -0,0 +1,951 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..f491174 --- /dev/null +++ b/test.ts @@ -0,0 +1,43 @@ +import * as serialLink from "./mod.ts"; + +const serial1 = new serialLink.Serial(); +const serial2 = new serialLink.Serial(); + +let port1 = ''; +let port2 = ''; + +while(!port1 && !port2) { + const availablePorts = serial1.getPortsInfo(); + + console.log('serial properties (available ports):', availablePorts); + + port1 = prompt('Port1 to connect:') || ''; + port2 = prompt('Port2 to connect:') || ''; +} + +serial1.open(port1, 9600); +serial2.open(port2, 9600); + +const textToSend1 = prompt('Text1 to send:') || ''; +const textToSend2 = prompt('Text2 to send:') || ''; + +const dataToSend1 = new TextEncoder().encode(textToSend1); +const dataToSend2 = new TextEncoder().encode(textToSend2); + +console.log('serial1.write():', serial1.write(dataToSend1, dataToSend1.length, 10, 10)); +console.log('writing1:', textToSend1); + +console.log('serial2.write():', serial2.write(dataToSend2, dataToSend2.length, 10, 10)); +console.log('writing2:', textToSend2); + +const dataToRead1 = new Uint8Array(20); +const dataToRead2 = new Uint8Array(20); + +console.log('serial1.read()', serial1.read(dataToRead1, dataToRead1.length, 10, 10)); +console.log('reading1:', new TextDecoder().decode(dataToRead1)); + +console.log('serial2.read()', serial2.read(dataToRead2, dataToRead2.length, 10, 10)); +console.log('reading2:', new TextDecoder().decode(dataToRead2)); + +serial1.close(); +serial2.close(); diff --git a/ts/Serial.ts b/ts/Serial.ts index 8bb631a..2f4e7e6 100644 --- a/ts/Serial.ts +++ b/ts/Serial.ts @@ -10,11 +10,12 @@ import { SerialFunctions } from "./interfaces/serial_functions.d.ts"; import { SerialOptions } from "./interfaces/serial_options.d.ts"; import { loadBinaryForOS } from "./load_binary_for_os.ts"; -const pathToBinariesDirectory = './lib/bin'; +const pathToBinariesDirectory = './ts/bin'; export class Serial { private _isOpen : boolean; private _dl : SerialFunctions; + private handle! : number | bigint; /** * Create a new instance of a serial connection. @@ -54,7 +55,7 @@ export class Serial { baudrate : Baudrate, serialOptions? : SerialOptions ) : void { - this._dl.open( + this.handle = this._dl.open( encode(port + '\0'), baudrate, serialOptions?.dataBits || dataBits.EIGHT, @@ -62,6 +63,9 @@ export class Serial { serialOptions?.stopBits || stopBits.ONE ); + console.log(this.handle); + + this._isOpen = true; } @@ -69,7 +73,7 @@ export class Serial { * Closes the serial connection. */ close() { - this._dl.close(); + this._dl.close(this.handle); this._isOpen = false; } @@ -88,7 +92,10 @@ export class Serial { timeout = 0, multiplier = 10 ) : number { + console.log('read from handle:', this.handle); + const result = this._dl.read( + this.handle, buffer, bytes, timeout, @@ -117,6 +124,7 @@ export class Serial { searchString = '', ) : number { const result = this._dl.readUntil( + this.handle, buffer, bytes, timeout, @@ -142,7 +150,11 @@ export class Serial { timeout = 0, multiplier = 10 ) : number { + + console.log('write to handle:', this.handle); + const result = this._dl.write( + this.handle, buffer, bytes, timeout, diff --git a/ts/bin/linux.so b/ts/bin/linux.so index f78d8af..74202dc 100644 Binary files a/ts/bin/linux.so and b/ts/bin/linux.so differ diff --git a/ts/bin/windows.dll b/ts/bin/windows.dll index 593c541..28c09d0 100644 Binary files a/ts/bin/windows.dll and b/ts/bin/windows.dll differ diff --git a/ts/interfaces/serial_functions.d.ts b/ts/interfaces/serial_functions.d.ts index 890b9c4..bdf5d6c 100644 --- a/ts/interfaces/serial_functions.d.ts +++ b/ts/interfaces/serial_functions.d.ts @@ -10,15 +10,17 @@ export interface SerialFunctions { dataBits : DataBits, parity : Parity, stopBits : StopBits - ) => void, - close : () => void, + ) => number | bigint, + close : (handle : number | bigint) => void, read : ( + handle : number | bigint, buffer : Uint8Array, bufferSize : number, timeout : number, multiplier : number ) => number, readUntil : ( + handle : number | bigint, buffer : Uint8Array, bufferSize : number, timeout : number, @@ -26,6 +28,7 @@ export interface SerialFunctions { searchString : Uint8Array ) => number, write : ( + handle : number | bigint, buffer : Uint8Array, bufferSize : number, timeout : number, diff --git a/ts/register_serial_functions.ts b/ts/register_serial_functions.ts index 94e6351..ba28af5 100644 --- a/ts/register_serial_functions.ts +++ b/ts/register_serial_functions.ts @@ -20,15 +20,18 @@ export function registerSerialFunctions( 'i32' ], // Status code - result: 'void' + result: 'i64' }, 'serialClose': { - parameters: [], + parameters: [ + 'i64' + ], // Status code result: 'i32' }, 'serialRead': { parameters: [ + 'i64', // Buffer 'buffer', // Buffer Size @@ -43,6 +46,7 @@ export function registerSerialFunctions( }, 'serialReadUntil': { parameters: [ + 'i64', // Buffer 'buffer', // Buffer Size @@ -59,6 +63,7 @@ export function registerSerialFunctions( }, 'serialWrite': { parameters: [ + 'i64', // Buffer 'buffer', // Buffer Size