@ -32,47 +32,17 @@ Receiver::Receiver(std::string path) :
{
if ( ! supportsDjReports ( raw_device - > reportDescriptor ( ) ) )
throw InvalidReceiver ( InvalidReceiver : : NoDJReports ) ;
// Pass all HID++ events on DefaultDevice to handleHidppEvent
RawEventHandler hidppRawEventHandler ;
hidppRawEventHandler . condition = [ this ] ( std : : vector < uint8_t > & report ) - > bool
{
return ( report [ hidpp : : Offset : : Type ] = = hidpp : : Report : : Type : : Short | |
report [ hidpp : : Offset : : Type ] = = hidpp : : Report : : Type : : Long ) & &
( report [ hidpp : : Offset : : DeviceIndex ] = = hidpp : : DefaultDevice ) ;
} ;
hidppRawEventHandler . callback = [ this ] ( std : : vector < uint8_t > & report ) - > void
{
hidpp : : Report _report ( report ) ;
this - > handleHidppEvent ( _report ) ;
} ;
// Pass all DJ events with device index to handleHidppEvent
RawEventHandler djRawEventHandler ;
djRawEventHandler . condition = [ this ] ( std : : vector < uint8_t > & report ) - > bool
{
return ( report [ Offset : : Type ] = = Report : : Type : : Short | |
report [ Offset : : Type ] = = Report : : Type : : Long ) ;
} ;
djRawEventHandler . callback = [ this ] ( std : : vector < uint8_t > & report ) - > void
{
Report _report ( report ) ;
this - > handleDjEvent ( _report ) ;
} ;
raw_device - > addEventHandler ( " RECV_HIDPP " , hidppRawEventHandler ) ;
raw_device - > addEventHandler ( " RECV_DJ " , djRawEventHandler ) ;
}
void Receiver : : enumerate ( )
void Receiver : : enumerateDj ( )
{
sendDjRequest ( hidpp : : DefaultDevice , GetPairedDevices , { } ) ;
}
Receiver : : notification_flags Receiver : : getHidppNotifications ( )
{
auto response = _hidpp10_device . getRegister ( EnableHidppNotifications , { } ) ;
auto response = _hidpp10_device . getRegister ( EnableHidppNotifications , { } ,
hidpp : : ReportType : : Short ) ;
notification_flags flags { } ;
flags . device_battery_status = response [ 0 ] & ( 1 < < 4 ) ;
@ -89,17 +59,28 @@ void Receiver::enableHidppNotifications(notification_flags flags)
if ( flags . device_battery_status )
request [ 0 ] | = ( 1 < < 4 ) ;
if ( flags . receiver_wireless_notifications )
request [ 1 ] | = ( 1 < < 0 ) ;
request [ 1 ] | = 1 ;
if ( flags . receiver_software_present )
request [ 1 ] | = ( 1 < < 3 ) ;
_hidpp10_device . setRegister ( EnableHidppNotifications , request ) ;
_hidpp10_device . setRegister ( EnableHidppNotifications , request ,
hidpp : : ReportType : : Short ) ;
}
void Receiver : : enumerateHidpp ( )
{
/* This isn't in the documentation but this is how solaar does it
* All I know is that when ( p0 & 2 ) , devices are enumerated
*/
_hidpp10_device . setRegister ( ConnectionState , { 2 } ,
hidpp : : ReportType : : Short ) ;
}
///TODO: Investigate usage
uint8_t Receiver : : getConnectionState ( hidpp : : DeviceIndex index )
{
auto response = _hidpp10_device . setRegister ( ConnectionState , { index } ) ;
auto response = _hidpp10_device . getRegister ( ConnectionState , { index } ,
hidpp : : ReportType : : Short ) ;
return response [ 0 ] ;
}
@ -113,7 +94,8 @@ void Receiver::startPairing(uint8_t timeout)
request [ 1 ] = hidpp : : DefaultDevice ;
request [ 2 ] = timeout ;
_hidpp10_device . setRegister ( DevicePairing , request ) ;
_hidpp10_device . setRegister ( DevicePairing , request ,
hidpp : : ReportType : : Short ) ;
}
void Receiver : : stopPairing ( )
@ -124,7 +106,8 @@ void Receiver::stopPairing()
request [ 0 ] = 2 ;
request [ 1 ] = hidpp : : DefaultDevice ;
_hidpp10_device . setRegister ( DevicePairing , request ) ;
_hidpp10_device . setRegister ( DevicePairing , request ,
hidpp : : ReportType : : Short ) ;
}
void Receiver : : disconnect ( hidpp : : DeviceIndex index )
@ -135,12 +118,14 @@ void Receiver::disconnect(hidpp::DeviceIndex index)
request [ 0 ] = 3 ;
request [ 1 ] = index ;
_hidpp10_device . setRegister ( DevicePairing , request ) ;
_hidpp10_device . setRegister ( DevicePairing , request ,
hidpp : : ReportType : : Short ) ;
}
std : : map < hidpp : : DeviceIndex , uint8_t > Receiver : : getDeviceActivity ( )
{
auto response = _hidpp10_device . getRegister ( DeviceActivity , { } ) ;
auto response = _hidpp10_device . getRegister ( DeviceActivity , { } ,
hidpp : : ReportType : : Long ) ;
std : : map < hidpp : : DeviceIndex , uint8_t > device_activity ;
for ( uint8_t i = hidpp : : WirelessDevice1 ; i < = hidpp : : WirelessDevice6 ; i + + )
@ -156,7 +141,8 @@ struct Receiver::PairingInfo
request [ 0 ] = index ;
request [ 0 ] + = 0x19 ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ) ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ,
hidpp : : ReportType : : Long ) ;
struct PairingInfo info { } ;
info . destinationId = response [ 0 ] ;
@ -175,7 +161,8 @@ struct Receiver::ExtendedPairingInfo
request [ 0 ] = index ;
request [ 0 ] + = 0x29 ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ) ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ,
hidpp : : ReportType : : Long ) ;
ExtendedPairingInfo info { } ;
@ -197,7 +184,8 @@ std::string Receiver::getDeviceName(hidpp::DeviceIndex index)
request [ 0 ] = index ;
request [ 0 ] + = 0x39 ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ) ;
auto response = _hidpp10_device . getRegister ( PairingInfo , request ,
hidpp : : ReportType : : Long ) ;
uint8_t size = response [ 0 ] ;
assert ( size < = 14 ) ;
@ -215,12 +203,12 @@ hidpp::DeviceIndex Receiver::deviceDisconnectionEvent(hidpp::Report& report)
return report . deviceIndex ( ) ;
}
Receiver : : DeviceConnectionEvent Receiver : : deviceConnectionEvent (
hidpp : : DeviceConnectionEvent Receiver : : deviceConnectionEvent (
hidpp : : Report & report )
{
assert ( report . subId ( ) = = DeviceConnection ) ;
DeviceConnectionEvent event { } ;
hidpp : : DeviceConnectionEvent event { } ;
event . index = report . deviceIndex ( ) ;
event . unifying = ( ( report . paramBegin ( ) [ 0 ] & 0b111 ) = = 0x04 ) ;
@ -240,23 +228,54 @@ Receiver::DeviceConnectionEvent Receiver::deviceConnectionEvent(
void Receiver : : handleDjEvent ( Report & report )
{
if ( report . feature ( ) = = DeviceConnection | |
report . feature ( ) = = DeviceDisconnection | |
report . feature ( ) = = ConnectionStatus )
{
printf ( " %s DJ IN: " , raw_device - > hidrawPath ( ) . c_str ( ) ) ;
for ( auto & i : report . rawData ( ) )
printf ( " %02x " , i ) ;
printf ( " \n " ) ;
}
for ( auto & handler : dj_event_handlers )
if ( handler . second - > condition ( report ) )
handler . second - > callback ( report ) ;
}
void Receiver : : handleHidppEvent ( hidpp : : Report & report )
{
printf ( " %s HID++ IN: " , raw_device - > hidrawPath ( ) . c_str ( ) ) ;
for ( auto & i : report . rawReport ( ) )
printf ( " %02x " , i ) ;
printf ( " \n " ) ;
for ( auto & handler : hidpp_event_handlers )
if ( handler . second - > condition ( report ) )
handler . second - > callback ( report ) ;
}
void Receiver : : addDjEventHandler ( const std : : string & nickname ,
const std : : shared_ptr < EventHandler > & handler )
{
auto it = dj_event_handlers . find ( nickname ) ;
assert ( it = = dj_event_handlers . end ( ) ) ;
dj_event_handlers . emplace ( nickname , handler ) ;
}
void Receiver : : removeDjEventHandler ( const std : : string & nickname )
{
dj_event_handlers . erase ( nickname ) ;
}
const std : : map < std : : string , std : : shared_ptr < EventHandler > > &
Receiver : : djEventHandlers ( )
{
return dj_event_handlers ;
}
void Receiver : : addHidppEventHandler ( const std : : string & nickname ,
const std : : shared_ptr < hidpp : : EventHandler > & handler )
{
auto it = hidpp_event_handlers . find ( nickname ) ;
assert ( it = = hidpp_event_handlers . end ( ) ) ;
hidpp_event_handlers . emplace ( nickname , handler ) ;
}
void Receiver : : removeHidppEventHandler ( const std : : string & nickname )
{
hidpp_event_handlers . erase ( nickname ) ;
}
const std : : map < std : : string , std : : shared_ptr < hidpp : : EventHandler > > &
Receiver : : hidppEventHandlers ( )
{
return hidpp_event_handlers ;
}
void Receiver : : sendDjRequest ( hidpp : : DeviceIndex index , uint8_t function ,
@ -276,10 +295,56 @@ void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
void Receiver : : listen ( )
{
std : : thread { [ = ] ( ) { raw_device - > listen ( ) ; } } . detach ( ) ;
if ( ! raw_device - > isListening ( ) )
std : : thread { [ = ] ( ) { raw_device - > listen ( ) ; } } . detach ( ) ;
if ( raw_device - > eventHandlers ( ) . find ( " RECV_HIDPP " ) = =
raw_device - > eventHandlers ( ) . end ( ) ) {
// Pass all HID++ events on DefaultDevice to handleHidppEvent
std : : shared_ptr < RawEventHandler > hidppRawEventHandler =
std : : make_shared < RawEventHandler > ( ) ;
hidppRawEventHandler - > condition = [ ] ( std : : vector < uint8_t > & report ) - > bool
{
return ( report [ hidpp : : Offset : : Type ] = = hidpp : : Report : : Type : : Short | |
report [ hidpp : : Offset : : Type ] = = hidpp : : Report : : Type : : Long ) ;
} ;
hidppRawEventHandler - > callback = [ this ] ( std : : vector < uint8_t > & report ) - > void
{
hidpp : : Report _report ( report ) ;
this - > handleHidppEvent ( _report ) ;
} ;
raw_device - > addEventHandler ( " RECV_HIDPP " , hidppRawEventHandler ) ;
}
if ( raw_device - > eventHandlers ( ) . find ( " RECV_DJ " ) = =
raw_device - > eventHandlers ( ) . end ( ) ) {
// Pass all DJ events with device index to handleHidppEvent
std : : shared_ptr < RawEventHandler > djRawEventHandler =
std : : make_shared < RawEventHandler > ( ) ;
djRawEventHandler - > condition = [ ] ( std : : vector < uint8_t > & report ) - > bool
{
return ( report [ Offset : : Type ] = = Report : : Type : : Short | |
report [ Offset : : Type ] = = Report : : Type : : Long ) ;
} ;
djRawEventHandler - > callback = [ this ] ( std : : vector < uint8_t > & report ) - > void
{
Report _report ( report ) ;
this - > handleDjEvent ( _report ) ;
} ;
raw_device - > addEventHandler ( " RECV_DJ " , djRawEventHandler ) ;
}
}
void Receiver : : stopListening ( )
{
raw_device - > stopListener ( ) ;
raw_device - > removeEventHandler ( " RECV_HIDPP " ) ;
raw_device - > removeEventHandler ( " RECV_DJ " ) ;
if ( raw_device - > eventHandlers ( ) . empty ( ) )
raw_device - > stopListener ( ) ;
}
std : : shared_ptr < raw : : RawDevice > Receiver : : rawDevice ( ) const
{
return raw_device ;
}