Created
June 26, 2025 03:17
-
-
Save ilomon10/616026ac915911e799aa522bd38aa54c to your computer and use it in GitHub Desktop.
quectel ril library client
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// qlril_gnss_client.ts | |
// OOP wrapper for Quectel QLRIL GNSS one-shot NMEA location in Deno | |
export interface Location { | |
latitude: number; | |
longitude: number; | |
} | |
const symbols: Record<string, Deno.ForeignFunction> = { | |
QLRIL_Init: { parameters: ["pointer"], result: "i32" }, | |
QLRIL_Exit: { parameters: ["pointer"], result: "i32" }, | |
QLRIL_GNSS_CLIENT_OPEN: { parameters: ["pointer"], result: "i32" }, | |
QLRIL_GNSS_CLIENT_CLOSE: { parameters: ["pointer"], result: "i32" }, | |
QLRIL_GNSS_NEMA_TYPE: { parameters: ["pointer", "i32"], result: "i32" }, | |
QLRIL_GNSS_NEMA_GetLocation: { | |
parameters: [ | |
"pointer", // handle | |
"pointer", // int* longitude | |
"pointer", // int* latitude | |
"i32", // timeout seconds | |
], | |
result: "i32", | |
}, | |
}; | |
export class QlrilGnssClient { | |
private lib: Deno.DynamicLibrary<typeof symbols>; | |
private handleBuf: BigUint64Array; | |
private handlePtr: Deno.PointerValue; | |
private closed = false; | |
constructor(soPath: string = "libql_ril.so") { | |
this.lib = Deno.dlopen(soPath, symbols); | |
this.handleBuf = new BigUint64Array(1); | |
this.handlePtr = Deno.UnsafePointer.of(this.handleBuf); | |
} | |
async init(): Promise<void> { | |
const rc = this.lib.symbols.QLRIL_Init(this.handlePtr); | |
if (rc !== 0) { | |
throw new Error(`QLRIL_Init failed: ${rc}`); | |
} | |
} | |
async openClient(nmeaMode: number = 1): Promise<void> { | |
let rc = this.lib.symbols.QLRIL_GNSS_CLIENT_OPEN(this.handlePtr); | |
if (rc !== 0) throw new Error(`GNSS_CLIENT_OPEN failed: ${rc}`); | |
rc = this.lib.symbols.QLRIL_GNSS_NEMA_TYPE(this.handlePtr, nmeaMode); | |
if (rc !== 0) console.warn(`NEMA_TYPE returned warning code: ${rc}`); | |
} | |
async getOneShotLocation(timeoutSec: number = 90): Promise<Location> { | |
// allocate buffers | |
const lonBuf = new Int32Array(1); | |
const latBuf = new Int32Array(1); | |
const lonPtr = Deno.UnsafePointer.of(lonBuf); | |
const latPtr = Deno.UnsafePointer.of(latBuf); | |
const rc = this.lib.symbols.QLRIL_GNSS_NEMA_GetLocation( | |
this.handlePtr, | |
lonPtr, | |
latPtr, | |
timeoutSec | |
); | |
if (rc !== 0) { | |
throw new Error(`NEMA_GetLocation failed: ${rc}`); | |
} | |
// scale by 1e-6 | |
return { | |
longitude: lonBuf[0] / 1e6, | |
latitude: latBuf[0] / 1e6, | |
}; | |
} | |
async close(): Promise<void> { | |
if (this.closed) return; | |
this.lib.symbols.QLRIL_GNSS_CLIENT_CLOSE(this.handlePtr); | |
this.lib.symbols.QLRIL_Exit(this.handlePtr); | |
this.lib.close(); | |
this.closed = true; | |
} | |
} | |
// example usage | |
if (import.meta.main) { | |
(async () => { | |
const client = new QlrilGnssClient(); | |
try { | |
await client.init(); | |
await client.openClient(); | |
console.log("๐ Acquiring one-shot NMEA location..."); | |
const loc = await client.getOneShotLocation(90); | |
console.log( | |
`๐ Latitude: ${loc.latitude.toFixed( | |
6 | |
)}, Longitude: ${loc.longitude.toFixed(6)}` | |
); | |
} catch (err) { | |
console.error(err); | |
} finally { | |
await client.close(); | |
} | |
})(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment