feat: Intel HDA audio driver, audio streaming syscalls, userspace Music app, fixes and improvements, rudimentary Bluetooth support
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Audio.hpp
|
||||
* Audio syscall implementations
|
||||
* Routes audio to Intel HDA or Bluetooth A2DP based on handle
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <Drivers/Audio/IntelHda.hpp>
|
||||
#include <Drivers/USB/Bluetooth/Bluetooth.hpp>
|
||||
#include <Drivers/USB/Bluetooth/A2dp.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
|
||||
namespace Montauk {
|
||||
|
||||
// Audio handle convention:
|
||||
// 0x00 - 0x0F : Intel HDA handles
|
||||
// 0x100 : Bluetooth A2DP audio output
|
||||
|
||||
static constexpr int AUDIO_HANDLE_BT = 0x100;
|
||||
|
||||
static int64_t Sys_AudioOpen(uint32_t sampleRate, uint8_t channels, uint8_t bitsPerSample) {
|
||||
// If HDA is available, use it (primary output)
|
||||
if (Drivers::Audio::IntelHda::IsInitialized()) {
|
||||
return (int64_t)Drivers::Audio::IntelHda::Open(sampleRate, channels, bitsPerSample);
|
||||
}
|
||||
|
||||
// Fallback: try Bluetooth audio if available
|
||||
if (Drivers::USB::Bluetooth::IsInitialized()) {
|
||||
auto state = Drivers::USB::Bluetooth::A2dp::GetState();
|
||||
if (state == Drivers::USB::Bluetooth::A2dp::State::Open ||
|
||||
state == Drivers::USB::Bluetooth::A2dp::State::Streaming ||
|
||||
state == Drivers::USB::Bluetooth::A2dp::State::Configured) {
|
||||
Drivers::USB::Bluetooth::A2dp::ConfigureStream(sampleRate, channels, bitsPerSample);
|
||||
Drivers::USB::Bluetooth::A2dp::StartStream();
|
||||
return AUDIO_HANDLE_BT;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int64_t Sys_AudioClose(int handle) {
|
||||
if (handle == AUDIO_HANDLE_BT) {
|
||||
Drivers::USB::Bluetooth::A2dp::StopStream();
|
||||
return 0;
|
||||
}
|
||||
Drivers::Audio::IntelHda::Close(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t Sys_AudioWrite(int handle, const uint8_t* data, uint32_t size) {
|
||||
if (handle == AUDIO_HANDLE_BT) {
|
||||
return (int64_t)Drivers::USB::Bluetooth::A2dp::WriteAudio(data, size);
|
||||
}
|
||||
return (int64_t)Drivers::Audio::IntelHda::Write(handle, data, size);
|
||||
}
|
||||
|
||||
static int64_t Sys_AudioCtl(int handle, int cmd, int value) {
|
||||
if (handle == AUDIO_HANDLE_BT) {
|
||||
switch (cmd) {
|
||||
case AUDIO_CTL_SET_VOLUME:
|
||||
Drivers::USB::Bluetooth::A2dp::SetVolume(value);
|
||||
return 0;
|
||||
case AUDIO_CTL_GET_VOLUME:
|
||||
return Drivers::USB::Bluetooth::A2dp::GetVolume();
|
||||
case AUDIO_CTL_PAUSE:
|
||||
if (value) Drivers::USB::Bluetooth::A2dp::StopStream();
|
||||
else Drivers::USB::Bluetooth::A2dp::StartStream();
|
||||
return 0;
|
||||
case AUDIO_CTL_GET_OUTPUT:
|
||||
return 1; // Bluetooth
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional control commands for audio routing
|
||||
if (cmd == AUDIO_CTL_GET_OUTPUT) return 0; // HDA
|
||||
if (cmd == AUDIO_CTL_BT_STATUS) {
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) return 0;
|
||||
return (int64_t)Drivers::USB::Bluetooth::A2dp::GetState();
|
||||
}
|
||||
|
||||
return (int64_t)Drivers::Audio::IntelHda::Control(handle, cmd, value);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* BluetoothSyscall.hpp
|
||||
* SYS_BTSCAN, SYS_BTCONNECT, SYS_BTDISCONNECT, SYS_BTLIST, SYS_BTINFO
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <Drivers/USB/Bluetooth/Bluetooth.hpp>
|
||||
#include <Drivers/USB/Bluetooth/Hci.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
|
||||
namespace Montauk {
|
||||
|
||||
static int64_t Sys_BtScan(BtScanResult* buf, int maxCount, uint32_t timeoutMs) {
|
||||
if (!buf || maxCount <= 0) return -1;
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) return -1;
|
||||
|
||||
// Use a stack buffer for kernel-side results (max 16)
|
||||
Drivers::USB::Bluetooth::Hci::InquiryDevice tmpBuf[16];
|
||||
int kMax = maxCount;
|
||||
if (kMax > 16) kMax = 16;
|
||||
|
||||
int found = Drivers::USB::Bluetooth::Scan(tmpBuf, kMax, timeoutMs);
|
||||
if (found < 0) return found;
|
||||
|
||||
// Convert kernel InquiryDevice to userspace BtScanResult
|
||||
for (int i = 0; i < found; i++) {
|
||||
memcpy(buf[i].bdAddr, tmpBuf[i].BdAddr, 6);
|
||||
buf[i]._pad[0] = 0;
|
||||
buf[i]._pad[1] = 0;
|
||||
buf[i].classOfDevice = tmpBuf[i].ClassOfDevice;
|
||||
buf[i].rssi = tmpBuf[i].Rssi;
|
||||
buf[i]._pad2[0] = 0;
|
||||
buf[i]._pad2[1] = 0;
|
||||
buf[i]._pad2[2] = 0;
|
||||
memcpy(buf[i].name, tmpBuf[i].Name, 64);
|
||||
}
|
||||
|
||||
return (int64_t)found;
|
||||
}
|
||||
|
||||
static int64_t Sys_BtConnect(const uint8_t* bdAddr) {
|
||||
if (!bdAddr) return -1;
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) return -1;
|
||||
|
||||
return (int64_t)Drivers::USB::Bluetooth::Connect(bdAddr);
|
||||
}
|
||||
|
||||
static int64_t Sys_BtDisconnect(const uint8_t* bdAddr) {
|
||||
if (!bdAddr) return -1;
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) return -1;
|
||||
|
||||
return (int64_t)Drivers::USB::Bluetooth::Disconnect(bdAddr);
|
||||
}
|
||||
|
||||
static int64_t Sys_BtList(BtDevInfo* buf, int maxCount) {
|
||||
if (!buf || maxCount <= 0) return 0;
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) return 0;
|
||||
|
||||
Drivers::USB::Bluetooth::Hci::ConnectionInfo tmpBuf[4];
|
||||
int kMax = maxCount;
|
||||
if (kMax > 4) kMax = 4;
|
||||
|
||||
int count = Drivers::USB::Bluetooth::ListConnected(tmpBuf, kMax);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
memcpy(buf[i].bdAddr, tmpBuf[i].BdAddr, 6);
|
||||
buf[i].connected = tmpBuf[i].Active ? 1 : 0;
|
||||
buf[i].encrypted = tmpBuf[i].Encrypted ? 1 : 0;
|
||||
buf[i].handle = tmpBuf[i].Handle;
|
||||
buf[i].linkType = tmpBuf[i].LinkType;
|
||||
buf[i]._pad = 0;
|
||||
}
|
||||
|
||||
return (int64_t)count;
|
||||
}
|
||||
|
||||
static int64_t Sys_BtInfo(BtAdapterInfo* buf) {
|
||||
if (!buf) return -1;
|
||||
|
||||
memset(buf, 0, sizeof(BtAdapterInfo));
|
||||
|
||||
if (!Drivers::USB::Bluetooth::IsInitialized()) {
|
||||
buf->initialized = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->initialized = 1;
|
||||
memcpy(buf->bdAddr, Drivers::USB::Bluetooth::GetBdAddr(), 6);
|
||||
buf->scanning = Drivers::USB::Bluetooth::Hci::IsInquiryActive() ? 1 : 0;
|
||||
|
||||
// Copy adapter name
|
||||
const char* name = "MontaukOS";
|
||||
int i = 0;
|
||||
for (; i < 63 && name[i]; i++) buf->name[i] = name[i];
|
||||
buf->name[i] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
+100
-22
@@ -9,13 +9,18 @@
|
||||
#include <Hal/Apic/ApicInit.hpp>
|
||||
#include <Drivers/PS2/PS2Controller.hpp>
|
||||
#include <Drivers/USB/Xhci.hpp>
|
||||
#include <Drivers/USB/UsbDevice.hpp>
|
||||
#include <Drivers/USB/Bluetooth/Bluetooth.hpp>
|
||||
#include <Drivers/Net/E1000.hpp>
|
||||
#include <Drivers/Net/E1000E.hpp>
|
||||
#include <Drivers/Graphics/IntelGPU.hpp>
|
||||
#include <Drivers/Storage/Ahci.hpp>
|
||||
#include <Drivers/Audio/IntelHda.hpp>
|
||||
#include <Pci/Pci.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
#include <Drivers/Storage/BlockDevice.hpp>
|
||||
#include <Drivers/Storage/Nvme.hpp>
|
||||
|
||||
namespace Montauk {
|
||||
|
||||
@@ -92,10 +97,12 @@ namespace Montauk {
|
||||
auto* dev = Drivers::USB::Xhci::GetDevice(slot);
|
||||
if (!dev || !dev->Active) continue;
|
||||
const char* devName = "USB Device";
|
||||
if (dev->InterfaceClass == 3) {
|
||||
if (dev->InterfaceClass == Drivers::USB::UsbDevice::CLASS_HID) {
|
||||
if (dev->InterfaceProtocol == 1) devName = "USB HID Keyboard";
|
||||
else if (dev->InterfaceProtocol == 2) devName = "USB HID Mouse";
|
||||
else devName = "USB HID Device";
|
||||
} else if (dev->InterfaceClass == Drivers::USB::UsbDevice::CLASS_WIRELESS) {
|
||||
devName = "Bluetooth Adapter";
|
||||
} else if (dev->InterfaceClass == 8) {
|
||||
devName = "USB Mass Storage";
|
||||
} else if (dev->InterfaceClass == 9) {
|
||||
@@ -129,6 +136,22 @@ namespace Montauk {
|
||||
}
|
||||
}
|
||||
|
||||
// Audio (category 9)
|
||||
if (Drivers::Audio::IntelHda::IsInitialized()) {
|
||||
uint32_t codecId = Drivers::Audio::IntelHda::GetCodecVendorId();
|
||||
char detail[48];
|
||||
int p = 0;
|
||||
p = dl_append(detail, p, "HDA Codec ", 48);
|
||||
p = dl_append_hex(detail, p, codecId >> 16, 4, 48);
|
||||
p = dl_append(detail, p, ":", 48);
|
||||
p = dl_append_hex(detail, p, codecId & 0xFFFF, 4, 48);
|
||||
add(9, "Intel HDA", detail);
|
||||
}
|
||||
|
||||
if (Drivers::USB::Bluetooth::IsInitialized()) {
|
||||
add(9, "Bluetooth Audio", "A2DP (SBC)");
|
||||
}
|
||||
|
||||
// Storage (category 7)
|
||||
if (Drivers::Storage::Ahci::IsInitialized()) {
|
||||
for (int port = 0; port < 32 && count < maxCount; port++) {
|
||||
@@ -152,6 +175,27 @@ namespace Montauk {
|
||||
}
|
||||
}
|
||||
|
||||
if (Drivers::Storage::Nvme::IsInitialized()) {
|
||||
for (int ns = 0; ns < Drivers::Storage::Nvme::GetNamespaceCount() && count < maxCount; ns++) {
|
||||
auto* nsInfo = Drivers::Storage::Nvme::GetNamespaceInfo(ns);
|
||||
if (!nsInfo || !nsInfo->Active) continue;
|
||||
uint64_t sectors = nsInfo->SectorCount;
|
||||
uint64_t sizeMB = (sectors * nsInfo->SectorSize) / (1024 * 1024);
|
||||
uint64_t sizeGB = sizeMB / 1024;
|
||||
char detail[48];
|
||||
int p = 0;
|
||||
if (sizeGB > 0) {
|
||||
p = dl_append_dec(detail, p, (int)sizeGB, 48);
|
||||
p = dl_append(detail, p, " GiB, NVMe ns ", 48);
|
||||
} else {
|
||||
p = dl_append_dec(detail, p, (int)sizeMB, 48);
|
||||
p = dl_append(detail, p, " MiB, NVMe ns ", 48);
|
||||
}
|
||||
p = dl_append_dec(detail, p, ns, 48);
|
||||
add(7, nsInfo->Model, detail);
|
||||
}
|
||||
}
|
||||
|
||||
// PCI devices (category 8)
|
||||
auto& pciDevs = Pci::GetDevices();
|
||||
for (int i = 0; i < (int)pciDevs.size() && count < maxCount; i++) {
|
||||
@@ -174,30 +218,64 @@ namespace Montauk {
|
||||
return count;
|
||||
}
|
||||
|
||||
static int Sys_DiskInfo(DiskInfo* buf, int port) {
|
||||
static int Sys_DiskInfo(DiskInfo* buf, int blockDevIndex) {
|
||||
if (buf == nullptr) return -1;
|
||||
if (!Drivers::Storage::Ahci::IsInitialized()) return -1;
|
||||
|
||||
auto* info = Drivers::Storage::Ahci::GetPortInfo(port);
|
||||
if (!info) return -1;
|
||||
auto* bdev = Drivers::Storage::GetBlockDevice(blockDevIndex);
|
||||
if (!bdev) return -1;
|
||||
|
||||
buf->port = info->PortIndex;
|
||||
buf->type = (uint8_t)info->Type;
|
||||
buf->sataGen = (uint8_t)info->SataGen;
|
||||
buf->sectorCount = info->SectorCount;
|
||||
buf->sectorSizeLog = info->SectorSizeLog;
|
||||
buf->sectorSizePhys = info->SectorSizePhys;
|
||||
buf->rpm = info->Rpm;
|
||||
buf->ncqDepth = info->NcqDepth;
|
||||
buf->supportsLba48 = info->SupportsLba48 ? 1 : 0;
|
||||
buf->supportsNcq = info->SupportsNcq ? 1 : 0;
|
||||
buf->supportsTrim = info->SupportsTrim ? 1 : 0;
|
||||
buf->supportsSmart = info->SupportsSmart ? 1 : 0;
|
||||
buf->supportsWriteCache = info->SupportsWriteCache ? 1 : 0;
|
||||
buf->supportsReadAhead = info->SupportsReadAhead ? 1 : 0;
|
||||
dl_strcpy(buf->model, info->Model, 41);
|
||||
dl_strcpy(buf->serial, info->Serial, 21);
|
||||
dl_strcpy(buf->firmware, info->Firmware, 9);
|
||||
// Zero the struct first so SATA-specific fields default to 0
|
||||
for (unsigned i = 0; i < sizeof(DiskInfo); i++)
|
||||
((uint8_t*)buf)[i] = 0;
|
||||
|
||||
buf->port = (uint8_t)blockDevIndex;
|
||||
buf->sectorCount = bdev->SectorCount;
|
||||
buf->sectorSizeLog = bdev->SectorSize;
|
||||
buf->sectorSizePhys = bdev->SectorSize;
|
||||
dl_strcpy(buf->model, bdev->Model, 41);
|
||||
|
||||
// Try to fill AHCI-specific fields if this is an AHCI device
|
||||
if (Drivers::Storage::Ahci::IsInitialized()) {
|
||||
for (int p = 0; p < 32; p++) {
|
||||
auto* info = Drivers::Storage::Ahci::GetPortInfo(p);
|
||||
if (!info) continue;
|
||||
// Match by sector count and model name
|
||||
if (info->SectorCount == bdev->SectorCount &&
|
||||
info->Model[0] == bdev->Model[0]) {
|
||||
buf->type = (uint8_t)info->Type;
|
||||
buf->sataGen = (uint8_t)info->SataGen;
|
||||
buf->sectorSizeLog = info->SectorSizeLog;
|
||||
buf->sectorSizePhys = info->SectorSizePhys;
|
||||
buf->rpm = info->Rpm;
|
||||
buf->ncqDepth = info->NcqDepth;
|
||||
buf->supportsLba48 = info->SupportsLba48 ? 1 : 0;
|
||||
buf->supportsNcq = info->SupportsNcq ? 1 : 0;
|
||||
buf->supportsTrim = info->SupportsTrim ? 1 : 0;
|
||||
buf->supportsSmart = info->SupportsSmart ? 1 : 0;
|
||||
buf->supportsWriteCache = info->SupportsWriteCache ? 1 : 0;
|
||||
buf->supportsReadAhead = info->SupportsReadAhead ? 1 : 0;
|
||||
dl_strcpy(buf->serial, info->Serial, 21);
|
||||
dl_strcpy(buf->firmware, info->Firmware, 9);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For NVMe devices: set type=3 (NVMe), rpm=1 (SSD)
|
||||
if (buf->type == 0 && Drivers::Storage::Nvme::IsInitialized()) {
|
||||
for (int ns = 0; ns < Drivers::Storage::Nvme::GetNamespaceCount(); ns++) {
|
||||
auto* nsInfo = Drivers::Storage::Nvme::GetNamespaceInfo(ns);
|
||||
if (!nsInfo) continue;
|
||||
if (nsInfo->SectorCount == bdev->SectorCount) {
|
||||
buf->type = 3; // NVMe
|
||||
buf->rpm = 1; // SSD / non-rotating
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If type is still 0, this block device is not recognized
|
||||
if (buf->type == 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "Device.hpp" // SYS_DEVLIST, SYS_DISKINFO
|
||||
#include "Storage.hpp" // SYS_PARTLIST, SYS_DISKREAD, SYS_DISKWRITE
|
||||
#include "Window.hpp" // SYS_WINCREATE, SYS_WINDESTROY, SYS_WINPRESENT, SYS_WINPOLL, SYS_WINENUM, SYS_WINMAP, SYS_WINSENDEVENT, SYS_WINRESIZE, SYS_WINSETSCALE, SYS_WINGETSCALE
|
||||
#include "Audio.hpp" // SYS_AUDIOOPEN, SYS_AUDIOCLOSE, SYS_AUDIOWRITE, SYS_AUDIOCTL
|
||||
#include "BluetoothSyscall.hpp" // SYS_BTSCAN, SYS_BTCONNECT, SYS_BTDISCONNECT, SYS_BTLIST, SYS_BTINFO
|
||||
|
||||
// Assembly entry point
|
||||
extern "C" void SyscallEntry();
|
||||
@@ -243,6 +245,24 @@ namespace Montauk {
|
||||
return (int64_t)Sys_FsMount((int)frame->arg1, (int)frame->arg2);
|
||||
case SYS_FSFORMAT:
|
||||
return (int64_t)Sys_FsFormat((const FsFormatParams*)frame->arg1);
|
||||
case SYS_AUDIOOPEN:
|
||||
return Sys_AudioOpen((uint32_t)frame->arg1, (uint8_t)frame->arg2, (uint8_t)frame->arg3);
|
||||
case SYS_AUDIOCLOSE:
|
||||
return Sys_AudioClose((int)frame->arg1);
|
||||
case SYS_AUDIOWRITE:
|
||||
return Sys_AudioWrite((int)frame->arg1, (const uint8_t*)frame->arg2, (uint32_t)frame->arg3);
|
||||
case SYS_AUDIOCTL:
|
||||
return Sys_AudioCtl((int)frame->arg1, (int)frame->arg2, (int)frame->arg3);
|
||||
case SYS_BTSCAN:
|
||||
return Sys_BtScan((BtScanResult*)frame->arg1, (int)frame->arg2, (uint32_t)frame->arg3);
|
||||
case SYS_BTCONNECT:
|
||||
return Sys_BtConnect((const uint8_t*)frame->arg1);
|
||||
case SYS_BTDISCONNECT:
|
||||
return Sys_BtDisconnect((const uint8_t*)frame->arg1);
|
||||
case SYS_BTLIST:
|
||||
return Sys_BtList((BtDevInfo*)frame->arg1, (int)frame->arg2);
|
||||
case SYS_BTINFO:
|
||||
return Sys_BtInfo((BtAdapterInfo*)frame->arg1);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -149,6 +149,28 @@ namespace Montauk {
|
||||
static constexpr uint64_t SYS_FSMOUNT = 75;
|
||||
static constexpr uint64_t SYS_FSFORMAT = 76;
|
||||
|
||||
/* Audio.hpp */
|
||||
static constexpr uint64_t SYS_AUDIOOPEN = 80;
|
||||
static constexpr uint64_t SYS_AUDIOCLOSE = 81;
|
||||
static constexpr uint64_t SYS_AUDIOWRITE = 82;
|
||||
static constexpr uint64_t SYS_AUDIOCTL = 83;
|
||||
|
||||
// Audio control commands (for SYS_AUDIOCTL)
|
||||
static constexpr int AUDIO_CTL_SET_VOLUME = 0;
|
||||
static constexpr int AUDIO_CTL_GET_VOLUME = 1;
|
||||
static constexpr int AUDIO_CTL_GET_POS = 2;
|
||||
static constexpr int AUDIO_CTL_PAUSE = 3;
|
||||
static constexpr int AUDIO_CTL_GET_OUTPUT = 4; // 0=HDA, 1=Bluetooth
|
||||
static constexpr int AUDIO_CTL_SET_OUTPUT = 5; // Switch audio output
|
||||
static constexpr int AUDIO_CTL_BT_STATUS = 6; // Get Bluetooth connection status
|
||||
|
||||
/* Bluetooth.hpp */
|
||||
static constexpr uint64_t SYS_BTSCAN = 84;
|
||||
static constexpr uint64_t SYS_BTCONNECT = 85;
|
||||
static constexpr uint64_t SYS_BTDISCONNECT = 86;
|
||||
static constexpr uint64_t SYS_BTLIST = 87;
|
||||
static constexpr uint64_t SYS_BTINFO = 88;
|
||||
|
||||
static constexpr int SOCK_TCP = 1;
|
||||
static constexpr int SOCK_UDP = 2;
|
||||
|
||||
@@ -244,8 +266,8 @@ namespace Montauk {
|
||||
};
|
||||
|
||||
struct DiskInfo {
|
||||
uint8_t port; // AHCI port index
|
||||
uint8_t type; // 0=none, 1=SATA, 2=SATAPI
|
||||
uint8_t port; // block device index
|
||||
uint8_t type; // 0=none, 1=SATA, 2=SATAPI, 3=NVMe
|
||||
uint8_t sataGen; // SATA gen (1/2/3)
|
||||
uint8_t _pad0;
|
||||
uint64_t sectorCount; // Total user-addressable sectors
|
||||
@@ -314,6 +336,34 @@ namespace Montauk {
|
||||
uint64_t heapUsed; // heapNext - UserHeapBase (bytes)
|
||||
};
|
||||
|
||||
// Bluetooth scan result (returned by SYS_BTSCAN)
|
||||
struct BtScanResult {
|
||||
uint8_t bdAddr[6];
|
||||
uint8_t _pad[2];
|
||||
uint32_t classOfDevice;
|
||||
int8_t rssi;
|
||||
uint8_t _pad2[3];
|
||||
char name[64];
|
||||
};
|
||||
|
||||
// Bluetooth connected device info (returned by SYS_BTLIST)
|
||||
struct BtDevInfo {
|
||||
uint8_t bdAddr[6];
|
||||
uint8_t connected;
|
||||
uint8_t encrypted;
|
||||
uint16_t handle;
|
||||
uint8_t linkType;
|
||||
uint8_t _pad;
|
||||
};
|
||||
|
||||
// Bluetooth adapter info (returned by SYS_BTINFO)
|
||||
struct BtAdapterInfo {
|
||||
uint8_t bdAddr[6];
|
||||
uint8_t initialized;
|
||||
uint8_t scanning;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
// Stack frame pushed by SyscallEntry.asm
|
||||
struct SyscallFrame {
|
||||
uint64_t r15, r14, r13, r12, rbp, rbx; // callee-saved
|
||||
|
||||
Reference in New Issue
Block a user