mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
btdrv: Added support for the new 12.0.0 cmds.
This commit is contained in:
parent
0d32a2c0d5
commit
2e2cf43cf5
@ -225,6 +225,15 @@ typedef struct {
|
||||
} data;
|
||||
} BtdrvHidReportEventInfoBufferData;
|
||||
|
||||
/// Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType.
|
||||
typedef union {
|
||||
struct {
|
||||
u32 status; ///< Status: 0 = AV connection closed, 1 = AV connection opened, 2 = failed to open AV connection.
|
||||
BtdrvAddress addr; ///< Device address.
|
||||
u8 pad[2]; ///< Padding
|
||||
} connection; ///< ::BtdrvAudioEventType_Connection
|
||||
} BtdrvAudioEventInfo;
|
||||
|
||||
/// CircularBuffer
|
||||
typedef struct {
|
||||
Mutex mutex;
|
||||
@ -1083,6 +1092,163 @@ Result btdrvSetBleScanParameter(u16 unk0, u16 unk1);
|
||||
*/
|
||||
Result btdrvMoveToSecondaryPiconet(BtdrvAddress addr);
|
||||
|
||||
/**
|
||||
* @brief IsBluetoothEnabled
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] out Output flag.
|
||||
*/
|
||||
Result btdrvIsBluetoothEnabled(bool *out);
|
||||
|
||||
/**
|
||||
* @brief AcquireAudioEvent
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] out_event Output Event.
|
||||
* @param[in] autoclear Event autoclear.
|
||||
*/
|
||||
Result btdrvAcquireAudioEvent(Event* out_event, bool autoclear);
|
||||
|
||||
/**
|
||||
* @brief GetAudioEventInfo
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] buffer Output buffer, see \ref BtdrvAudioEventInfo.
|
||||
* @param[in] size Output buffer size.
|
||||
* @param[out] type \ref BtdrvAudioEventType.
|
||||
*/
|
||||
Result btdrvGetAudioEventInfo(void* buffer, size_t size, BtdrvAudioEventType *type);
|
||||
|
||||
/**
|
||||
* @brief OpenAudioConnection
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] addr \ref BtdrvAddress
|
||||
*/
|
||||
Result btdrvOpenAudioConnection(BtdrvAddress addr);
|
||||
|
||||
/**
|
||||
* @brief CloseAudioConnection
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] addr \ref BtdrvAddress
|
||||
*/
|
||||
Result btdrvCloseAudioConnection(BtdrvAddress addr);
|
||||
|
||||
/**
|
||||
* @brief OpenAudioOut
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] addr \ref BtdrvAddress
|
||||
* @param[out] audio_handle Audio handle.
|
||||
*/
|
||||
Result btdrvOpenAudioOut(BtdrvAddress addr, u32 *audio_handle);
|
||||
|
||||
/**
|
||||
* @brief CloseAudioOut
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
*/
|
||||
Result btdrvCloseAudioOut(u32 audio_handle);
|
||||
|
||||
/**
|
||||
* @brief StartAudioOut
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[in] pcm_param \ref BtdrvPcmParameter
|
||||
* @param[in] in_latency Input latency in nanoseconds.
|
||||
* @param[out] out_latency Output latency in nanoseconds.
|
||||
* @param[out] out1 Unknown output.
|
||||
*/
|
||||
Result btdrvStartAudioOut(u32 audio_handle, const BtdrvPcmParameter *pcm_param, s64 in_latency, s64 *out_latency, u64 *out1);
|
||||
|
||||
/**
|
||||
* @brief StopAudioOut
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
*/
|
||||
Result btdrvStopAudioOut(u32 audio_handle);
|
||||
|
||||
/**
|
||||
* @brief GetAudioOutState
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[out] out \ref BtdrvAudioOutState
|
||||
*/
|
||||
Result btdrvGetAudioOutState(u32 audio_handle, BtdrvAudioOutState *out);
|
||||
|
||||
/**
|
||||
* @brief GetAudioOutFeedingCodec
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[out] out \ref BtdrvAudioCodec
|
||||
*/
|
||||
Result btdrvGetAudioOutFeedingCodec(u32 audio_handle, BtdrvAudioCodec *out);
|
||||
|
||||
/**
|
||||
* @brief GetAudioOutFeedingParameter
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[out] out \ref BtdrvPcmParameter
|
||||
*/
|
||||
Result btdrvGetAudioOutFeedingParameter(u32 audio_handle, BtdrvPcmParameter *out);
|
||||
|
||||
/**
|
||||
* @brief AcquireAudioOutStateChangedEvent
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[out] out_event Output Event.
|
||||
* @param[in] autoclear Event autoclear.
|
||||
*/
|
||||
Result btdrvAcquireAudioOutStateChangedEvent(u32 audio_handle, Event* out_event, bool autoclear);
|
||||
|
||||
/**
|
||||
* @brief AcquireAudioOutBufferAvailableEvent
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[out] out_event Output Event.
|
||||
* @param[in] autoclear Event autoclear.
|
||||
*/
|
||||
Result btdrvAcquireAudioOutBufferAvailableEvent(u32 audio_handle, Event* out_event, bool autoclear);
|
||||
|
||||
/**
|
||||
* @brief SendAudioData
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut.
|
||||
* @param[in] buffer Input buffer.
|
||||
* @param[in] size Input buffer size.
|
||||
* @param[out] Output transferred size. This is always either 0 (error occured) or the buffer size.
|
||||
*/
|
||||
Result btdrvSendAudioData(u32 audio_handle, const void* buffer, size_t size, u64 *transferred_size);
|
||||
|
||||
/**
|
||||
* @brief AcquireAudioControlInputStateChangedEvent
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] out_event Output Event.
|
||||
* @param[in] autoclear Event autoclear.
|
||||
*/
|
||||
Result btdrvAcquireAudioControlInputStateChangedEvent(Event* out_event, bool autoclear);
|
||||
|
||||
/**
|
||||
* @brief GetAudioControlInputState
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] states Output array of \ref BtdrvAudioControlButtonState.
|
||||
* @param[in] count Size of the states array in entries, the maximum is 0xF.
|
||||
* @param[out] total_out Total output entries.
|
||||
*/
|
||||
Result btdrvGetAudioControlInputState(BtdrvAudioControlButtonState *states, s32 count, s32 *total_out);
|
||||
|
||||
/**
|
||||
* @brief AcquireAudioConnectionStateChangedEvent
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] out_event Output Event.
|
||||
* @param[in] autoclear Event autoclear.
|
||||
*/
|
||||
Result btdrvAcquireAudioConnectionStateChangedEvent(Event* out_event, bool autoclear);
|
||||
|
||||
/**
|
||||
* @brief GetConnectedAudioDevice
|
||||
* @note Only available on [12.0.0+].
|
||||
* @param[out] addrs Output array of \ref BtdrvAddress.
|
||||
* @param[in] count Size of the addrs array in entries, the maximum is 0x8.
|
||||
* @param[out] total_out Total output entries.
|
||||
*/
|
||||
Result btdrvGetConnectedAudioDevice(BtdrvAddress *addrs, s32 count, s32 *total_out);
|
||||
|
||||
/**
|
||||
* @brief IsManufacturingMode
|
||||
* @note Only available on [5.0.0+].
|
||||
|
@ -73,6 +73,23 @@ typedef enum {
|
||||
BtdrvFatalReason_Enable = 7, ///< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field.
|
||||
} BtdrvFatalReason;
|
||||
|
||||
/// AudioEventType
|
||||
typedef enum {
|
||||
BtdrvAudioEventType_None = 0, ///< None
|
||||
BtdrvAudioEventType_Connection = 1, ///< Connection
|
||||
} BtdrvAudioEventType;
|
||||
|
||||
/// AudioOutState
|
||||
typedef enum {
|
||||
BtdrvAudioOutState_Stopped = 0, ///< Stopped
|
||||
BtdrvAudioOutState_Started = 1, ///< Started
|
||||
} BtdrvAudioOutState;
|
||||
|
||||
/// AudioCodec
|
||||
typedef enum {
|
||||
BtdrvAudioCodec_Pcm = 0, ///< Raw PCM
|
||||
} BtdrvAudioCodec;
|
||||
|
||||
/// Address
|
||||
typedef struct {
|
||||
u8 address[0x6]; ///< Address
|
||||
@ -220,3 +237,15 @@ typedef struct {
|
||||
u8 data[0x200]; ///< BtdrvLeEventInfo::data
|
||||
} BtdrvBleClientGattOperationInfo;
|
||||
|
||||
/// PcmParameter
|
||||
typedef struct {
|
||||
u32 unk_x0; ///< Must be 0-3. Controls number of channels: 0 = mono, non-zero = stereo.
|
||||
s32 sample_rate; ///< Sample rate. Must be one of the following: 16000, 32000, 44100, 48000.
|
||||
u32 bits_per_sample; ///< Bits per sample. Must be 8 or 16.
|
||||
} BtdrvPcmParameter;
|
||||
|
||||
/// AudioControlButtonState
|
||||
typedef struct {
|
||||
u8 unk_x0[0x10]; ///< Unknown
|
||||
} BtdrvAudioControlButtonState;
|
||||
|
||||
|
@ -99,6 +99,10 @@ static Result _btdrvCmdNoInOutBool(bool *out, u32 cmd_id) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _btdrvCmdInU32OutU32(u32 inval, u32 *out, u32 cmd_id) {
|
||||
return serviceDispatchInOut(&g_btdrvSrv, cmd_id, inval, *out);
|
||||
}
|
||||
|
||||
static Result _btdrvCmdGetEvent(Event* out_event, bool autoclear, u32 cmd_id) {
|
||||
Handle tmp_handle = INVALID_HANDLE;
|
||||
Result rc = 0;
|
||||
@ -108,6 +112,18 @@ static Result _btdrvCmdGetEvent(Event* out_event, bool autoclear, u32 cmd_id) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _btdrvCmdInU32OutEvent(u32 inval, Event* out_event, bool autoclear, u32 cmd_id) {
|
||||
Handle tmp_handle = INVALID_HANDLE;
|
||||
|
||||
Result rc = serviceDispatchIn(&g_btdrvSrv, cmd_id, inval,
|
||||
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
|
||||
.out_handles = &tmp_handle,
|
||||
);
|
||||
|
||||
if (R_SUCCEEDED(rc)) eventLoadRemote(out_event, tmp_handle, autoclear);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _btdrvCmdInBufPtrFixed(const void* buffer, size_t size, u32 cmd_id) {
|
||||
return serviceDispatch(&g_btdrvSrv, cmd_id,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In | SfBufferAttr_FixedSize },
|
||||
@ -1125,6 +1141,167 @@ Result btdrvMoveToSecondaryPiconet(BtdrvAddress addr) {
|
||||
return _btdrvCmdInAddrNoOut(addr, 99);
|
||||
}
|
||||
|
||||
Result btdrvIsBluetoothEnabled(bool *out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdNoInOutBool(out, 100);
|
||||
}
|
||||
|
||||
Result btdrvAcquireAudioEvent(Event* out_event, bool autoclear) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdGetEvent(out_event, autoclear, 128);
|
||||
}
|
||||
|
||||
Result btdrvGetAudioEventInfo(void* buffer, size_t size, BtdrvAudioEventType *type) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
u32 tmp=0;
|
||||
Result rc = _btdrvCmdOutU32OutBuf(buffer, size, &tmp, 129);
|
||||
if (R_SUCCEEDED(rc) && type) *type = tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result btdrvOpenAudioConnection(BtdrvAddress addr) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInAddrNoOut(addr, 130);
|
||||
}
|
||||
|
||||
Result btdrvCloseAudioConnection(BtdrvAddress addr) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInAddrNoOut(addr, 131);
|
||||
}
|
||||
|
||||
Result btdrvOpenAudioOut(BtdrvAddress addr, u32 *audio_handle) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return serviceDispatchInOut(&g_btdrvSrv, 132, addr, *audio_handle);
|
||||
}
|
||||
|
||||
Result btdrvCloseAudioOut(u32 audio_handle) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInU32NoOut(audio_handle, 133);
|
||||
}
|
||||
|
||||
Result btdrvAcquireAudioOutStateChangedEvent(u32 audio_handle, Event* out_event, bool autoclear) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInU32OutEvent(audio_handle, out_event, autoclear, 134);
|
||||
}
|
||||
|
||||
Result btdrvStartAudioOut(u32 audio_handle, const BtdrvPcmParameter *pcm_param, s64 in_latency, s64 *out_latency, u64 *out1) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
const struct {
|
||||
u32 audio_handle;
|
||||
BtdrvPcmParameter pcm_param;
|
||||
s64 latency;
|
||||
} in = { audio_handle, *pcm_param, in_latency };
|
||||
|
||||
struct {
|
||||
s64 latency;
|
||||
u64 out1;
|
||||
} out;
|
||||
|
||||
Result rc = serviceDispatchInOut(&g_btdrvSrv, 135, in, out);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (out_latency) *out_latency = out.latency;
|
||||
if (out1) *out1 = out.out1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result btdrvStopAudioOut(u32 audio_handle) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInU32NoOut(audio_handle, 136);
|
||||
}
|
||||
|
||||
Result btdrvGetAudioOutState(u32 audio_handle, BtdrvAudioOutState *out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
u32 tmp=0;
|
||||
Result rc = _btdrvCmdInU32OutU32(audio_handle, &tmp, 137);
|
||||
if (R_SUCCEEDED(rc) && out) *out = tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result btdrvGetAudioOutFeedingCodec(u32 audio_handle, BtdrvAudioCodec *out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
u32 tmp=0;
|
||||
Result rc = _btdrvCmdInU32OutU32(audio_handle, &tmp, 138);
|
||||
if (R_SUCCEEDED(rc) && out) *out = tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result btdrvGetAudioOutFeedingParameter(u32 audio_handle, BtdrvPcmParameter *out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return serviceDispatchInOut(&g_btdrvSrv, 139, audio_handle, *out);
|
||||
}
|
||||
|
||||
Result btdrvAcquireAudioOutBufferAvailableEvent(u32 audio_handle, Event* out_event, bool autoclear) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdInU32OutEvent(audio_handle, out_event, autoclear, 140);
|
||||
}
|
||||
|
||||
Result btdrvSendAudioData(u32 audio_handle, const void* buffer, size_t size, u64 *transferred_size) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return serviceDispatchInOut(&g_btdrvSrv, 141, audio_handle, *transferred_size,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
|
||||
.buffers = { { buffer, size } },
|
||||
);
|
||||
}
|
||||
|
||||
Result btdrvAcquireAudioControlInputStateChangedEvent(Event* out_event, bool autoclear) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdGetEvent(out_event, autoclear, 142);
|
||||
}
|
||||
|
||||
Result btdrvGetAudioControlInputState(BtdrvAudioControlButtonState *states, s32 count, s32 *total_out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdOutU32OutBuf(states, count*sizeof(BtdrvAudioControlButtonState), (u32*)total_out, 143);
|
||||
}
|
||||
|
||||
Result btdrvAcquireAudioConnectionStateChangedEvent(Event* out_event, bool autoclear) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdGetEvent(out_event, autoclear, 144);
|
||||
}
|
||||
|
||||
Result btdrvGetConnectedAudioDevice(BtdrvAddress *addrs, s32 count, s32 *total_out) {
|
||||
if (hosversionBefore(12,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _btdrvCmdOutU32OutBuf(addrs, count*sizeof(BtdrvAddress), (u32*)total_out, 145);
|
||||
}
|
||||
|
||||
Result btdrvIsManufacturingMode(bool *out) {
|
||||
if (hosversionBefore(5,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
Loading…
Reference in New Issue
Block a user