diff options
| author | Girish Pattabiraman <[email protected]> | 2018-11-12 18:08:19 -0800 |
|---|---|---|
| committer | Adonais Romero González <[email protected]> | 2018-11-12 18:08:19 -0800 |
| commit | 995e20f6dbca7ad10a039fa62a2de69eed092ffc (patch) | |
| tree | 67075f06fd8aaedad732d6c73b682c6e0fda9dba /audio/sysvad/UsbHsDevice.h | |
| parent | c9110a3bc1634a5be8e7922119ad383311104095 (diff) | |
RS5 Updates (#311)
* Format Changes
==============
* Add KSEVENT_PINCAPS_FORMATCHANGE to Bluetooth HFP Endpoints
* Remove 8 bit formats from Bluetooth HFP Endpoints
Name Template
==============
* Bluetooth Endpoints are now based on templates in INF and then customized with endpoints specific data
Sideband Common Interface for future Sideband buses
===================================================
* Add ISidebandDevice
* Add current directory to TabletAudioSample include path. Remove unused compiler flags.
* RS4 bug fixes
* Replace FastMutex with Spinlock for DeviceFormatsAndModes to work well at DISPATCH_LEVEL
* Resync with Microsoft-master branch
* Replace FastMutex with Spinlock for DeviceFormatsAndModes to work well at DISPATCH_LEVEL
* RS5 updates:
- USB Sideband implementation
- Power management options: _USE_IPortClsRuntimePower, _USE_SingleComponentMultiFxStates
Diffstat (limited to 'audio/sysvad/UsbHsDevice.h')
| -rw-r--r-- | audio/sysvad/UsbHsDevice.h | 623 |
1 files changed, 623 insertions, 0 deletions
diff --git a/audio/sysvad/UsbHsDevice.h b/audio/sysvad/UsbHsDevice.h new file mode 100644 index 00000000..625352af --- /dev/null +++ b/audio/sysvad/UsbHsDevice.h @@ -0,0 +1,623 @@ +// +// This class represents a the Bluetooth Hands-Free Profile USB Headset device. +// There is one class for each interface (id = symbolic-link-name). +// +#ifdef SYSVAD_USB_SIDEBAND + + +//===================================================================== +// +// USB Sideband Headset class definition. +// + +class CAdapterCommon; +class UsbHsDevice; + +struct UsbHsWorkItemContext +{ + CAdapterCommon * Adapter; +}; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME +( + UsbHsWorkItemContext, + GetUsbHsWorkItemContext +) + +// start/stop the device +enum eUsbHsTaskAction +{ + eUsbHsTaskStart = 1, + eUsbHsTaskStop = 2, +}; + +struct UsbHsWorkTask +{ + LIST_ENTRY ListEntry; + UsbHsDevice * Device; + eUsbHsTaskAction Action; +}; + + +//===================================================================== +// +// Device: Bluetooth Hands-Free Profile USB Headset definitions. +// + +// BTH HFP device's notification work-item context. +struct UsbHsDeviceNotificationWorkItemContext +{ + UsbHsDevice * UsbHsDevice; +}; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME +( + UsbHsDeviceNotificationWorkItemContext, + GetUsbHsDeviceNotificationWorkItemContext +) + +// USB HS device's notification request context. +union UsbHsDeviceNotificationBuffer +{ + SIDEBANDAUDIO_VOLUME_PARAMS Volume; + SIDEBANDAUDIO_MUTE_PARAMS Mute; + SIDEBANDAUDIO_SIDETONE_PARAMS Sidetone; + SIDEBANDAUDIO_STREAM_STATUS_PARAMS streamStatus; +}; + +struct UsbHsDeviceNotificationReqContext +{ + UsbHsDevice *UsbHsDevice; + LONG Errors; + UsbHsDeviceNotificationBuffer Buffer; + WDFMEMORY MemIn; + WDFMEMORY MemOut; +}; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME +( + UsbHsDeviceNotificationReqContext, + GetUsbHsDeviceNotificationReqContext +) + +enum eUsbHsState +{ + eUsbHsStateInvalid = 0, + eUsbHsStateInitializing = 1, + eUsbHsStateRunning = 2, + eUsbHsStateStopping = 3, + eUsbHsStateStopped = 4, + eUsbHsStateFailed = 5, +}; + +// To support event notification. +struct UsbHsEventCallback +{ + PFNEVENTNOTIFICATION Handler; + PVOID Context; +}; + +typedef struct _USBHSDEVICE_EP_TRANSPORT_RESOURCES +{ + PUSB_INTERFACE_DESCRIPTOR pUsbInterfaceDescriptor; + PUSBD_ENDPOINT_OFFLOAD_INFORMATION pUsbOffloadInformation; + PUSBD_ENDPOINT_OFFLOAD_INFORMATION pSyncUsbOffloadInformation; + PSIDEBANDAUDIO_EP_USBAUDIO_TRANSPORT_RESOURCES pUsbAudioTransportResources; + PSIDEBANDAUDIO_EP_USBAUDIO_TRANSPORT_RESOURCES pSyncUsbAudioTransportResources; + PUSB_ENDPOINT_DESCRIPTOR pUsbEndpointDescriptor; + PUSB_ENDPOINT_DESCRIPTOR pSyncUsbEndpointDescriptor; +}USBHSDEVICE_EP_TRANSPORT_RESOURCES, *PUSBHSDEVICE_EP_TRANSPORT_RESOURCES; + +#endif // SYSVAD_USB_SIDEBAND +class UsbHsDevice : + ISidebandDeviceCommon, + public CUnknown +{ + private: + eUsbHsState m_State; + + IAdapterCommon * m_Adapter; + WDFIOTARGET m_WdfIoTarget; + + LIST_ENTRY m_ListEntry; + UNICODE_STRING m_SymbolicLinkName; + WCHAR m_SpeakerWaveNameBuffer[USBHS_INTERFACE_REFSTRING_MAX_LENGTH]; + UNICODE_STRING m_SpeakerWaveRefString; + WCHAR m_SpeakerTopologyNameBuffer[USBHS_INTERFACE_REFSTRING_MAX_LENGTH]; + UNICODE_STRING m_SpeakerTopologyRefString; + WCHAR m_MicWaveNameBuffer[USBHS_INTERFACE_REFSTRING_MAX_LENGTH]; + UNICODE_STRING m_MicWaveRefString; + WCHAR m_MicTopologyNameBuffer[USBHS_INTERFACE_REFSTRING_MAX_LENGTH]; + UNICODE_STRING m_MicTopologyRefString; + + // + // The Topo Filter Desc and Topo Pins structures referenced from + // the Miniports structure are deep copies: they start as copies of the + // static structures and are modified to allow USB-Device pin + // categories based on the info obtained from + // IOCTL_SBAUD_GET_ENDPOINT_DESCRIPTOR + // + PENDPOINT_MINIPAIR m_SpeakerMiniports; + PENDPOINT_MINIPAIR m_MicMiniports; + + PUNKNOWN m_UnknownSpeakerTopology; + PUNKNOWN m_UnknownSpeakerWave; + PUNKNOWN m_UnknownMicTopology; + PUNKNOWN m_UnknownMicWave; + + PSIDEBANDAUDIO_DEVICE_DESCRIPTOR m_Descriptor; + PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR m_pSpeakerDescriptor; + PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR m_pMicDescriptor; + PKSPROPERTY_DESCRIPTION m_SpeakerVolumePropValues; + LONG m_SpeakerVolumeLevel; + PKSPROPERTY_DESCRIPTION m_MicVolumePropValues; + LONG m_MicVolumeLevel; + + PKSPROPERTY_DESCRIPTION m_SpeakerMutePropValues; + ULONG m_ulSpeakerMutePropValuesSize; + LONG m_SpeakerMute; + PKSPROPERTY_DESCRIPTION m_MicMutePropValues; + ULONG m_ulMicMutePropValuesSize; + LONG m_MicMute; + + + ULONG m_SpeakerEpIndex; + ULONG m_MicEpIndex; + + union{ + NTSTATUS m_SpeakerStreamStatus; + LONG m_SpeakerStreamStatusLong; + }; // unnamed. + union{ + NTSTATUS m_MicStreamStatus; + LONG m_MicStreamStatusLong; + }; // unnamed. + + KEVENT m_SpeakerStreamStatusEvent; + KEVENT m_MicStreamStatusEvent; + + PSIDEBANDAUDIO_SUPPORTED_FORMATS m_pSpeakerSupportedFormatsIntersection; + ULONG m_SpeakerSelectedFormat; + PSIDEBANDAUDIO_SUPPORTED_FORMATS m_pMicSupportedFormatsIntersection; + ULONG m_MicSelectedFormat; + + USBHSDEVICE_EP_TRANSPORT_RESOURCES m_SpeakerTransportResources; + USBHSDEVICE_EP_TRANSPORT_RESOURCES m_MicTransportResources; + + // + // Set to TRUE when the HF (remote device) wants to disable the + // NR + EC of the AG (local system). + // + + WDFREQUEST m_SpeakerStreamReq; + WDFREQUEST m_MicStreamReq; + WDFREQUEST m_SpeakerVolumeReq; + WDFREQUEST m_MicVolumeReq; + WDFREQUEST m_SpeakerMuteReq; + WDFREQUEST m_MicMuteReq; + WDFWORKITEM m_WorkItem; + WDFCOLLECTION m_ReqCollection; + KSPIN_LOCK m_Lock; + + LONG m_nSpeakerStreamsOpen; // # of open streams. + LONG m_nMicStreamsOpen; // # of open streams. + + LONG m_nSpeakerStreamsStart; // # of Started streams. + LONG m_nMicStreamsStart; // # of Started streams. + + UsbHsEventCallback m_SpeakerVolumeCallback; + UsbHsEventCallback m_MicVolumeCallback; + + UsbHsEventCallback m_SpeakerMuteCallback; + UsbHsEventCallback m_MicMuteCallback; + + UsbHsEventCallback m_SpeakerConnectionStatusCallback; + UsbHsEventCallback m_MicConnectionStatusCallback; + + UsbHsEventCallback m_SpeakerFormatChangeCallback; + UsbHsEventCallback m_MicFormatChangeCallback; + + public: + //===================================================================== + // Default CUnknown + DECLARE_STD_UNKNOWN(); + DEFINE_STD_CONSTRUCTOR(UsbHsDevice); + ~UsbHsDevice(); + + NTSTATUS Init + ( + _In_ IAdapterCommon * Adapter, + _In_ PUNICODE_STRING SymbolicLinkName + ); + + public: + //===================================================================== + // + // Public functions used by CAdapterCommon object. + // + VOID Start(); + VOID Stop(); + + PLIST_ENTRY GetListEntry() + { + return &m_ListEntry; + } + + PUNICODE_STRING GetSymbolicLinkName() + { + return &m_SymbolicLinkName; + } + + static + UsbHsDevice * + GetUsbHsDevice + ( + _In_ PLIST_ENTRY le + ) + { + return CONTAINING_RECORD(le, UsbHsDevice, m_ListEntry); + } + + public: + //===================================================================== + // + // ISidebandDeviceCommon functions. + // + STDMETHODIMP_(BOOL) IsVolumeSupported + ( + _In_ eDeviceType deviceType + ); + + STDMETHODIMP_(PVOID) GetVolumeSettings + ( + _In_ eDeviceType deviceType, + _Out_ PULONG Size + ); + + STDMETHODIMP_(NTSTATUS) GetVolume + ( + _In_ eDeviceType deviceType, + _In_ LONG Channel, + _Out_ LONG *pVolume + ); + + STDMETHODIMP_(NTSTATUS) SetVolume + ( + _In_ eDeviceType deviceType, + _In_ LONG Channel, + _In_ LONG Volume + ); + + STDMETHODIMP_(BOOL) IsMuteSupported + ( + _In_ eDeviceType deviceType + ); + + STDMETHODIMP_(PVOID) GetMuteSettings + ( + _In_ eDeviceType deviceType, + _Out_ PULONG Size + ); + + STDMETHODIMP_(LONG) GetMute + ( + _In_ eDeviceType deviceType, + _In_ LONG Channel + ); + + STDMETHODIMP_(NTSTATUS) SetMute + ( + _In_ eDeviceType deviceType, + _In_ LONG Channel, + _In_ LONG Mute + ); + + STDMETHODIMP_(BOOL) GetConnectionStatus(); + + STDMETHODIMP_(NTSTATUS) Connect(); + + STDMETHODIMP_(NTSTATUS) Disconnect(); + + STDMETHODIMP_(BOOL) GetStreamStatus(_In_ eDeviceType deviceType); + + STDMETHODIMP_(NTSTATUS) StreamOpen(_In_ eDeviceType deviceType); + + STDMETHODIMP_(NTSTATUS) StreamStart(_In_ eDeviceType deviceType); + + STDMETHODIMP_(NTSTATUS) StreamSuspend(_In_ eDeviceType deviceType); + + STDMETHODIMP_(NTSTATUS) StreamClose(_In_ eDeviceType deviceType); + + STDMETHODIMP_(GUID) GetContainerId(_In_ eDeviceType deviceType); + + STDMETHODIMP_(VOID) SetVolumeHandler + ( + _In_ eDeviceType deviceType, + _In_opt_ PFNEVENTNOTIFICATION EventHandler, + _In_opt_ PVOID EventHandlerContext + ); + + STDMETHODIMP_(VOID) SetMuteHandler + ( + _In_ eDeviceType deviceType, + _In_opt_ PFNEVENTNOTIFICATION EventHandler, + _In_opt_ PVOID EventHandlerContext + ); + + STDMETHODIMP_(VOID) SetConnectionStatusHandler + ( + _In_ eDeviceType deviceType, + _In_opt_ PFNEVENTNOTIFICATION EventHandler, + _In_opt_ PVOID EventHandlerContext + ); + + STDMETHODIMP_(VOID) SetFormatChangeHandler + ( + _In_ eDeviceType deviceType, + _In_opt_ PFNEVENTNOTIFICATION EventHandler, + _In_opt_ PVOID EventHandlerContext + ); + + STDMETHODIMP_(PPIN_DEVICE_FORMATS_AND_MODES) GetFormatsAndModes + ( + _In_ eDeviceType deviceType + ); + + STDMETHODIMP_(BOOL) IsNRECSupported(); + + STDMETHODIMP_(BOOL) GetNRECDisableStatus(); + + private: + //===================================================================== + // + // Helper functions. + // + NTSTATUS SendIoCtrlSynchronously + ( + _In_opt_ WDFREQUEST Request, + _In_ ULONG IoControlCode, + _In_ ULONG InLength, + _In_ ULONG OutLength, + _When_(InLength > 0 || OutLength > 0, _In_) + _When_(InLength == 0 && OutLength == 0, _In_opt_) + PVOID Buffer + ); + + NTSTATUS SendIoCtrlSynchronously + ( + _In_opt_ WDFREQUEST Request, + _In_ ULONG IoControlCode, + _In_ ULONG InLength, + _In_ ULONG OutLength, + _When_(InLength > 0, _In_) + _When_(InLength == 0, _In_opt_) + PVOID InBuffer, + _When_(OutLength > 0, _In_) + _When_(OutLength == 0, _In_opt_) + PVOID OutBuffer + ); + + NTSTATUS SendIoCtrlAsynchronously + ( + _In_ WDFREQUEST Request, + _In_ ULONG IoControlCode, + _In_opt_ WDFMEMORY MemIn, + _In_opt_ WDFMEMORY MemOut, + _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine, + _In_ WDFCONTEXT Context + ); + + NTSTATUS GetUsbHsDescriptor + ( + _Out_ PSIDEBANDAUDIO_DEVICE_DESCRIPTOR *Descriptor + ); + + NTSTATUS GetUsbHsEndpointDescriptor + ( + _In_ ULONG EpIndex, + _Out_ PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR *EpDescriptor + ); + + NTSTATUS GetUsbHsVolumePropertyValues + ( + _In_ ULONG EpIndex, + _In_ ULONG Length, + _Out_ PKSPROPERTY_DESCRIPTION *PropValues + ); + + NTSTATUS SetUsbHsSpeakerVolume + ( + _In_ LONG Channel, + _In_ LONG Volume + ); + + NTSTATUS GetUsbHsSpeakerVolume + ( + _In_ LONG Channel, + _Out_ LONG *Volume + ); + + NTSTATUS EnableUsbHsSpeakerVolumeStatusNotification(); + + NTSTATUS SetUsbHsMicVolume + ( + _In_ LONG Channel, + _In_ LONG Volume + ); + + NTSTATUS GetUsbHsMicVolume + ( + _In_ LONG Channel, + _Out_ LONG * Volume + ); + + NTSTATUS EnableUsbHsMicVolumeStatusNotification(); + + NTSTATUS GetUsbHsMutePropertyValues + ( + _In_ ULONG EpIndex, + _Out_ PULONG pLength, + _Out_ PKSPROPERTY_DESCRIPTION *PropValues + ); + + NTSTATUS SetUsbHsSpeakerMute + ( + _In_ LONG Channel, + _In_ LONG Mute + ); + + NTSTATUS GetUsbHsSpeakerMute + ( + _In_ LONG Channel, + _Out_ LONG *Mute + ); + + NTSTATUS EnableUsbHsSpeakerMuteStatusNotification(); + + NTSTATUS SetUsbHsMicMute + ( + _In_ LONG Channel, + _In_ LONG Mute + ); + + NTSTATUS GetUsbHsMicMute + ( + _In_ LONG Channel, + _Out_ LONG *Mute + ); + + NTSTATUS EnableUsbHsMicMuteStatusNotification(); + + NTSTATUS GetUsbHsEndpointFormatsIntersection + ( + _In_ PSIDEBANDAUDIO_SUPPORTED_FORMATS pDeviceFormats, + _Out_ PSIDEBANDAUDIO_SUPPORTED_FORMATS *ppSupportedFormatsIntersection + ); + + NTSTATUS VerifyEndpointFormatCompatibility + ( + _In_ PSIDEBANDAUDIO_SUPPORTED_FORMATS EpSupportedFormats, + _In_ PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pHardwareSupportedFormats, + _In_ ULONG NumHardwareSupportedFormats, + _Out_ PULONG pHardwareFormatIndex + ); + + NTSTATUS FreeTransportResources + ( + _In_ PUSBHSDEVICE_EP_TRANSPORT_RESOURCES pTransportResources + ); + + NTSTATUS GetTransportResources + ( + _In_ ULONG EpIndex, + _In_ PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR pEndpointDescriptor, + _Out_ PUSBHSDEVICE_EP_TRANSPORT_RESOURCES pTransportResources + ); + + NTSTATUS SetTransportResources + ( + _In_ PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR pEndpointDescriptor, + _In_ ULONG EpIndex + ); + + NTSTATUS GetSiop + ( + _In_ ULONG EpIndex, + _In_ ULONG SiopTypeId, + _In_ ULONG PoolTag, + _Out_ PBYTE *ppOutputBuffer + ); + + static + NTSTATUS CreateCustomEndpointMinipair + ( + _In_ PENDPOINT_MINIPAIR pBaseMinipair, + _In_ PUNICODE_STRING FriendlyName, + _In_ PGUID pCategory, + _Outptr_ PENDPOINT_MINIPAIR *ppCustomMinipair + ); + + static + NTSTATUS UpdateCustomEndpointCategory + ( + _In_ PPCFILTER_DESCRIPTOR pCustomMinipairTopoFilter, + _In_ PPCPIN_DESCRIPTOR pCustomMinipairTopoPins, + _In_ PGUID pCategory + ); + + static + VOID DeleteCustomEndpointMinipair + ( + _In_ PENDPOINT_MINIPAIR CustomMinipair + ); + + NTSTATUS SetSidebandClaimed(_In_ BOOL bClaimed); + + NTSTATUS SpeakerStreamOpen(); + + NTSTATUS MicStreamOpen(); + + NTSTATUS SpeakerStreamStart(); + + NTSTATUS MicStreamStart(); + + NTSTATUS SpeakerStreamSuspend(); + + NTSTATUS MicStreamSuspend(); + + NTSTATUS SpeakerStreamClose(); + + NTSTATUS MicStreamClose(); + + NTSTATUS SetUsbHsStreamOpen(ULONG EpIndex, PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pStreamFormat, PSIDEBANDAUDIO_ENDPOINT_DESCRIPTOR pEndpointDescriptor); + + NTSTATUS SetUsbHsStreamStart(ULONG EpIndex); + + NTSTATUS SetUsbHsStreamSuspend(ULONG EpIndex); + + NTSTATUS SetUsbHsStreamClose(ULONG EpIndex); + + NTSTATUS EnableUsbHsSpeakerStreamStatusNotification(); + + NTSTATUS StopUsbHsSpeakerStreamStatusNotification(); + + NTSTATUS EnableUsbHsMicStreamStatusNotification(); + + NTSTATUS StopUsbHsMicStreamStatusNotification(); + + NTSTATUS CreateFilterNames( + _In_ PUNICODE_STRING UsbHsDeviceSymbolicLinkName + ); + + +#if 0 + NTSTATUS GetSpeakerTransportResources(); + NTSTATUS FreeSpeakerTransportResources(); + NTSTATUS GetMicTransportResources(); + NTSTATUS FreeMicTransportResources(); +#endif + + // + // WDF I/O Target callback. + // + static + EVT_WDF_IO_TARGET_QUERY_REMOVE EvtUsbHsTargetQueryRemove; + + static + EVT_WDF_IO_TARGET_REMOVE_CANCELED EvtUsbHsTargetRemoveCanceled; + + static + EVT_WDF_IO_TARGET_REMOVE_COMPLETE EvtUsbHsTargetRemoveComplete; + + // + // Status notifications callbacks. + // + static + EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtUsbHsDeviceStreamStatusCompletion; + + static + EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtUsbHsDeviceNotificationStatusCompletion; + + static + EVT_WDF_WORKITEM EvtUsbHsDeviceNotificationStatusWorkItem; +}; |
