diff --git a/libs/linux-x86-64/libsdx.so b/libs/linux-x86-64/libsdx.so new file mode 100644 index 0000000..52db697 Binary files /dev/null and b/libs/linux-x86-64/libsdx.so differ diff --git a/libs/linux-x86/libsdx.so b/libs/linux-x86/libsdx.so new file mode 100644 index 0000000..1f9ac3c Binary files /dev/null and b/libs/linux-x86/libsdx.so differ diff --git a/libs/win32-x86-64/sdx.dll b/libs/win32-x86-64/sdx.dll new file mode 100644 index 0000000..37980b9 Binary files /dev/null and b/libs/win32-x86-64/sdx.dll differ diff --git a/libs/win32-x86/sdx.dll b/libs/win32-x86/sdx.dll new file mode 100644 index 0000000..a311ed7 Binary files /dev/null and b/libs/win32-x86/sdx.dll differ diff --git a/src/Main.kt b/src/Main.kt index 839176a..64ce7d8 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -22,18 +22,20 @@ import kotlinx.coroutines.launch import org.tinylog.Logger import org.tinylog.provider.ProviderRegistry import oshi.util.GlobalConfig +import securedonglex.DongleChecker import web.WebApp import java.nio.file.Files import java.nio.file.Paths import kotlin.concurrent.fixedRateTimer import kotlin.io.path.absolutePathString +import kotlin.system.exitProcess lateinit var db: MariaDB lateinit var audioPlayer: AudioPlayer val StreamerOutputs: MutableMap = HashMap() lateinit var udpreceiver: UDPReceiver lateinit var tcpreceiver: TCPReceiver -const val version = "0.0.16 (25/11/2025)" +const val version = "0.0.17 (26/01/2026)" // AAS 64 channels const val max_channel = 64 @@ -97,9 +99,16 @@ fun files_preparation(){ } lateinit var config : configFile - +val sdx = DongleChecker() // Application start here fun main() { + if (!sdx.CheckDongle()){ + Logger.error { "Dongle check failed. Application will exit." } + exitProcess(1) + } + + + if (Platform.isWindows()) { // supaya OSHI bisa mendapatkan CPU usage di Windows seperti di Task Manager GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true) @@ -250,3 +259,5 @@ fun main() { } + + diff --git a/src/MainExtension01.kt b/src/MainExtension01.kt index a8f6c92..566d9d7 100644 --- a/src/MainExtension01.kt +++ b/src/MainExtension01.kt @@ -881,6 +881,9 @@ class MainExtension01 { } } + /** + * Read and process Queue_Table table for SOUNDBANK type messages. + */ fun Read_Queue_Soundbank() : Boolean{ db.queuetableDB.Get() val list = db.queuetableDB.List.filter { it.Type=="SOUNDBANK" } @@ -1031,10 +1034,6 @@ class MainExtension01 { return false } - - - - /** * Read and process Schedule_Table table. * This function is called every minute when second=00. diff --git a/src/securedonglex/DongleChecker.kt b/src/securedonglex/DongleChecker.kt new file mode 100644 index 0000000..4b4c96c --- /dev/null +++ b/src/securedonglex/DongleChecker.kt @@ -0,0 +1,62 @@ +package securedonglex + +import org.tinylog.Logger +import java.util.function.Consumer + +/** + * Class to periodically check for the presence of a security dongle. + */ +class DongleChecker { + private var isRunning = false + + /** + * Starts checking for the dongle at specified intervals. + * @param interval The interval in milliseconds between checks. Default is 1000 ms. + * @param cbMissing A callback function that is called when the dongle is missing. + */ + fun startChecking(interval: Int=1000, cbMissing: Consumer) { + isRunning = true + Thread { + while (isRunning) { + val donglePresent = CheckDongle() + if (!donglePresent) { + isRunning = false + } + Thread.sleep(interval.toLong()) + } + }.start() + cbMissing.accept(Unit) + } + + /** + * Stops the dongle checking process. + */ + fun stopChecking() { + isRunning = false + } + + /** + * Checks for the presence of the security dongle. + * @return True if the dongle is found and opened successfully, false otherwise. + */ + fun CheckDongle() : Boolean{ + try{ + val sdx = securedonglex.Instance + val found = sdx.SDX_Find() + Logger.info { "Found Dongle: $found" } + if (found>0){ + val uid = securedonglex.DWORD(253570225) + val hid = securedonglex.DWORDByReference(securedonglex.DWORD(0)) + val handle = sdx.SDX_Open(1, uid, hid) + Logger.info { "Handle: $handle" } + if (handle>=0){ + sdx.SDX_Close(handle) + return true + } + } + } catch (e: Exception){ + Logger.error(e) { "Error checking dongle: ${e.message}" } + } + return false + } +} \ No newline at end of file diff --git a/src/securedonglex/securedonglex.java b/src/securedonglex/securedonglex.java new file mode 100644 index 0000000..11bcb68 --- /dev/null +++ b/src/securedonglex/securedonglex.java @@ -0,0 +1,165 @@ +package securedonglex; + +import com.sun.jna.IntegerType; +import com.sun.jna.Library; +import com.sun.jna.ptr.ByReference; +import com.sun.jna.ptr.IntByReference; + +@SuppressWarnings("unused") +public interface securedonglex extends Library { + securedonglex Instance = (securedonglex) com.sun.jna.Native.load("sdx", securedonglex.class); + + // ========================= +// Constants from header +// ========================= + int SDX_MINOR = 16; + int HID_MODE = -1; + + + // Error codes (kept as long to safely hold unsigned 32-bit like 0xA0100001) + long SDXERR_SUCCESS = 0x00000000L; + + + long SDXERR_NO_SUCH_DEVICE = 0xA0100001L; + long SDXERR_NOT_OPENED_DEVICE = 0xA0100002L; + long SDXERR_WRONG_UID = 0xA0100003L; + long SDXERR_WRONG_INDEX = 0xA0100004L; + long SDXERR_TOO_LONG_SEED = 0xA0100005L; + long SDXERR_WRITE_PROTECT = 0xA0100006L; + long SDXERR_WRONG_START_INDEX = 0xA0100007L; + long SDXERR_INVALID_LEN = 0xA0100008L; + long SDXERR_TOO_LONG_ENCRYPTION_DATA = 0xA0100009L; + long SDXERR_GENERATE_KEY = 0xA010000AL; + long SDXERR_INVALID_KEY = 0xA010000BL; + long SDXERR_FAILED_ENCRYPTION = 0xA010000CL; + long SDXERR_FAILED_WRITE_KEY = 0xA010000DL; + long SDXERR_FAILED_DECRYPTION = 0xA010000EL; + + + long SDXERR_OPEN_DEVICE = 0xA010000FL; + long SDXERR_READ_REPORT = 0xA0100010L; + long SDXERR_WRITE_REPORT = 0xA0100011L; + long SDXERR_SETUP_DI_GET_DEVICE_INTERFACE_DETAIL = 0xA0100012L; + long SDXERR_GET_ATTRIBUTES = 0xA0100013L; + long SDXERR_GET_PREPARSED_DATA = 0xA0100014L; + long SDXERR_GETCAPS = 0xA0100015L; + long SDXERR_FREE_PREPARSED_DATA = 0xA0100016L; + long SDXERR_FLUSH_QUEUE = 0xA0100017L; + long SDXERR_SETUP_DI_CLASS_DEVS = 0xA0100018L; + long SDXERR_GET_SERIAL = 0xA0100019L; + long SDXERR_WRONG_REPORT_LENGTH = 0xA010001AL; + long SDXERR_TOO_LONG_DEVICE_DETAIL = 0xA010001BL; + + + long SDXERR_UNKNOWN_DEVICE = 0xA0100020L; + long SDXERR_VERIFY = 0xA0100021L; + long SDXERR_UNKNOWN_ERROR = 0xA010FFFFL; + + // ========================= +// "DWORD unsigned long" helper +// ========================= + + /** + * 32-bit unsigned container for DWORD. + * Use new DWORD(value) and read back with longValue(). + */ + class DWORD extends IntegerType { + public DWORD() { + this(0); + } + + public DWORD(long value) { + super(4, value, true); // 4 bytes, unsigned + } + } + + // ========================= +// Pointer helper for DWORD* +// ========================= + class DWORDByReference extends ByReference { + public DWORDByReference() { + super(4); + } + + public DWORDByReference(DWORD value) { + this(); + setValue(value); + } + + public void setValue(DWORD value) { + getPointer().setInt(0, (int) value.longValue()); + } + + public DWORD getValue() { +// interpret as unsigned int + long v = Integer.toUnsignedLong(getPointer().getInt(0)); + return new DWORD(v); + } + } + + /** + * Find SecureDongle X attached to computer + * + * @return <0 Error Code,
+ * =0 Not Found,
+ * >0 number of SecureDongle X found + */ + int SDX_Find(); + + + /** + * int SDX_Open(int mode, DWORD uid, DWORD *hid); + * uid: pass as DWORD (32-bit unsigned) + * hid: in/out pointer. Use DWORDByReference (below). + */ + int SDX_Open(int mode, DWORD uid, DWORDByReference hid); + + /** + * void SDX_Close(int handle); + */ + void SDX_Close(int handle); + + + /** + * int SDX_Read(int handle, int block_index, char *buffer512); + * Use byte[] of length >= 512. + */ + int SDX_Read(int handle, int block_index, byte[] buffer512); + + /** + * int SDX_Write(int handle, int block_index, char *buffer512); + * Use byte[] of length >= 512. + */ + int SDX_Write(int handle, int block_index, byte[] buffer512); + + + /** + * int SDX_Transform(int handle, int len, char *buffer); + * buffer is in/out. Use byte[] with capacity >= len. + * len max 32 (per header). + */ + int SDX_Transform(int handle, int len, byte[] buffer); + + /** + * int SDX_GetVersion(int handle); + */ + int SDX_GetVersion(int handle); + + + /** + * int SDX_RSAEncrypt(int handle, int startByte, char *bufferData, int *len, char *Key512); + * bufferData: plaintext in, then may be overwritten (depends on vendor). + * len: in/out. + * Key512: out 512 bytes. + */ + int SDX_RSAEncrypt(int handle, int startByte, byte[] bufferData, IntByReference len, byte[] Key512); + + + /** + * int SDX_RSADecrypt(int handle, int startIndex, char *bufferData, int *len, char *Key512); + * bufferData: out plaintext. + * len: in/out (ciphertext length in, plaintext length out). + * Key512: in 512 bytes. + */ + int SDX_RSADecrypt(int handle, int startIndex, byte[] bufferData, IntByReference len, byte[] Key512); +}