Bug 1091577: Use general-purpose notification runnable in Bluetooth daemon backend, r=shawnjohnjr

This patch converts all notification runnables in Bluetooth's daemon
backend to use the generic implementation. Unpack functions are replaced
by init operator classes. The init operator classes also validate the
complete unpacking of a PDU and warn about unused trailing data.
This commit is contained in:
Thomas Zimmermann 2014-11-05 15:43:07 +01:00
parent 9ff9ad0858
commit 13bf77b754
2 changed files with 545 additions and 60 deletions

View File

@ -862,6 +862,165 @@ UnpackPDU<nsString, nsString, uint32_t, nsString, uint32_t, 0x01, 0x87>(
return UnpackPDU(aPDU, aArg5);
}
//
// Init operators
//
// |PDUInitOP| provides functionality for init operators that unpack PDUs.
class PDUInitOp
{
protected:
PDUInitOp(BluetoothDaemonPDU& aPDU)
: mPDU(&aPDU)
{ }
BluetoothDaemonPDU& GetPDU() const
{
return *mPDU; // cannot be nullptr
}
void WarnAboutTrailingData() const
{
size_t size = mPDU->GetSize();
if (MOZ_LIKELY(!size)) {
return;
}
uint8_t service, opcode;
uint16_t payloadSize;
mPDU->GetHeader(service, opcode, payloadSize);
BT_LOGR("Unpacked PDU of type (%x,%x) still contains %zu Bytes of data.",
service, opcode, size);
}
private:
BluetoothDaemonPDU* mPDU; // Hold pointer to allow for constant instances
};
// |UnpackPDUInitOp| is a general-purpose init operator for all variants
// of |BluetoothResultRunnable| and |BluetoothNotificationRunnable|. The
// call operators of |UnpackPDUInitOp| unpack a PDU into the supplied
// arguments.
class UnpackPDUInitOp MOZ_FINAL : private PDUInitOp
{
public:
UnpackPDUInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult operator () () const
{
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1>
nsresult operator () (T1& aArg1) const
{
nsresult rv = UnpackPDU(GetPDU(), aArg1);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2>
nsresult operator () (T1& aArg1, T2& aArg2) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3, typename T4>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg4);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
T5& aArg5) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg4);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg5);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
//
// Result handling
//

View File

@ -8,6 +8,7 @@
#include "BluetoothDaemonHelpers.h"
#include "BluetoothDaemonSetupInterface.h"
#include "BluetoothDaemonSocketInterface.h"
#include "BluetoothInterfaceHelpers.h"
#include "mozilla/unused.h"
using namespace mozilla::ipc;
@ -841,142 +842,467 @@ private:
}
};
typedef BluetoothDaemonNotificationRunnable1<NotificationHandlerWrapper, void,
bool>
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
bool>
AdapterStateChangedNotification;
typedef BluetoothDaemonNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, int,
const BluetoothProperty*>
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, int,
const BluetoothProperty*>
AdapterPropertiesNotification;
typedef BluetoothDaemonNotificationRunnable4<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, const nsAString&,
int, const BluetoothProperty*>
typedef BluetoothNotificationRunnable4<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, const nsAString&,
int, const BluetoothProperty*>
RemoteDevicePropertiesNotification;
typedef BluetoothDaemonNotificationRunnable2<NotificationHandlerWrapper, void,
int,
nsAutoArrayPtr<BluetoothProperty>,
int, const BluetoothProperty*>
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
int,
nsAutoArrayPtr<BluetoothProperty>,
int, const BluetoothProperty*>
DeviceFoundNotification;
typedef BluetoothDaemonNotificationRunnable1<NotificationHandlerWrapper, void,
bool>
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
bool>
DiscoveryStateChangedNotification;
typedef BluetoothDaemonNotificationRunnable3<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
const nsAString&, const nsAString&>
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
const nsAString&, const nsAString&>
PinRequestNotification;
typedef BluetoothDaemonNotificationRunnable5<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
nsString, uint32_t,
const nsAString&, const nsAString&,
uint32_t, const nsAString&>
typedef BluetoothNotificationRunnable5<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
nsString, uint32_t,
const nsAString&, const nsAString&,
uint32_t, const nsAString&>
SspRequestNotification;
typedef BluetoothDaemonNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString,
BluetoothBondState,
BluetoothStatus, const nsAString&>
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString,
BluetoothBondState,
BluetoothStatus, const nsAString&>
BondStateChangedNotification;
typedef BluetoothDaemonNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, bool,
BluetoothStatus, const nsAString&>
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, bool,
BluetoothStatus, const nsAString&>
AclStateChangedNotification;
typedef BluetoothDaemonNotificationRunnable3<NotificationHandlerWrapper, void,
uint16_t, nsAutoArrayPtr<uint8_t>,
uint8_t, uint16_t, const uint8_t*>
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
uint16_t, nsAutoArrayPtr<uint8_t>,
uint8_t, uint16_t, const uint8_t*>
DutModeRecvNotification;
typedef BluetoothDaemonNotificationRunnable2<NotificationHandlerWrapper, void,
BluetoothStatus, uint16_t>
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
BluetoothStatus, uint16_t>
LeTestModeNotification;
void AdapterStateChangedNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
AdapterStateChangedNotification::Dispatch<0x01, 0x81>(
&BluetoothNotificationHandler::AdapterStateChangedNotification, aPDU);
AdapterStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AdapterStateChangedNotification,
UnpackPDUInitOp(aPDU));
}
// Init operator class for AdapterPropertiesNotification
class AdapterPropertiesInitOp MOZ_FINAL : private PDUInitOp
{
public:
AdapterPropertiesInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (BluetoothStatus& aArg1, int& aArg2,
nsAutoArrayPtr<BluetoothProperty>& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read status */
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
/* Read number of properties */
uint8_t numProperties;
rv = UnpackPDU(pdu, numProperties);
if (NS_FAILED(rv)) {
return rv;
}
aArg2 = numProperties;
/* Read properties array */
UnpackArray<BluetoothProperty> properties(aArg3, aArg2);
rv = UnpackPDU(pdu, properties);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void AdapterPropertiesNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
AdapterPropertiesNotification::Dispatch<0x01, 0x82>(
&BluetoothNotificationHandler::AdapterPropertiesNotification, aPDU);
AdapterPropertiesNotification::Dispatch(
&BluetoothNotificationHandler::AdapterPropertiesNotification,
AdapterPropertiesInitOp(aPDU));
}
// Init operator class for RemoteDevicePropertiesNotification
class RemoteDevicePropertiesInitOp MOZ_FINAL : private PDUInitOp
{
public:
RemoteDevicePropertiesInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (BluetoothStatus& aArg1, nsString& aArg2, int& aArg3,
nsAutoArrayPtr<BluetoothProperty>& aArg4) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read status */
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
/* Read address */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
if (NS_FAILED(rv)) {
return rv;
}
/* Read number of properties */
uint8_t numProperties;
rv = UnpackPDU(pdu, numProperties);
if (NS_FAILED(rv)) {
return rv;
}
aArg3 = numProperties;
/* Read properties array */
UnpackArray<BluetoothProperty> properties(aArg4, aArg3);
rv = UnpackPDU(pdu, properties);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void RemoteDevicePropertiesNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
RemoteDevicePropertiesNotification::Dispatch<0x01, 0x83>(
RemoteDevicePropertiesNotification::Dispatch(
&BluetoothNotificationHandler::RemoteDevicePropertiesNotification,
aPDU);
RemoteDevicePropertiesInitOp(aPDU));
}
// Init operator class for DeviceFoundNotification
class DeviceFoundInitOp MOZ_FINAL : private PDUInitOp
{
public:
DeviceFoundInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (int& aArg1, nsAutoArrayPtr<BluetoothProperty>& aArg2) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read number of properties */
uint8_t numProperties;
nsresult rv = UnpackPDU(pdu, numProperties);
if (NS_FAILED(rv)) {
return rv;
}
aArg1 = numProperties;
/* Read properties array */
UnpackArray<BluetoothProperty> properties(aArg2, aArg1);
rv = UnpackPDU(pdu, properties);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void DeviceFoundNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
DeviceFoundNotification::Dispatch<0x01, 0x84>(
&BluetoothNotificationHandler::DeviceFoundNotification, aPDU);
DeviceFoundNotification::Dispatch(
&BluetoothNotificationHandler::DeviceFoundNotification,
DeviceFoundInitOp(aPDU));
}
void DiscoveryStateChangedNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
DiscoveryStateChangedNotification::Dispatch<0x01, 0x85>(
&BluetoothNotificationHandler::DiscoveryStateChangedNotification, aPDU);
DiscoveryStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::DiscoveryStateChangedNotification,
UnpackPDUInitOp(aPDU));
}
// Init operator class for PinRequestNotification
class PinRequestInitOp MOZ_FINAL : private PDUInitOp
{
public:
PinRequestInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read remote address */
nsresult rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
if (NS_FAILED(rv)) {
return rv;
}
/* Read remote name */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
if (NS_FAILED(rv)) {
return rv;
}
/* Read CoD */
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void PinRequestNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
PinRequestNotification::Dispatch<0x01, 0x86>(
&BluetoothNotificationHandler::PinRequestNotification, aPDU);
PinRequestNotification::Dispatch(
&BluetoothNotificationHandler::PinRequestNotification,
PinRequestInitOp(aPDU));
}
// Init operator class for SspRequestNotification
class SspRequestInitOp MOZ_FINAL : private PDUInitOp
{
public:
SspRequestInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
nsString& aArg4, uint32_t& aArg5) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read remote address */
nsresult rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
if (NS_FAILED(rv)) {
return rv;
}
/* Read remote name */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
if (NS_FAILED(rv)) {
return rv;
}
/* Read CoD */
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
/* Read pairing variant */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothSspPairingVariant, nsAString>(aArg4));
if (NS_FAILED(rv)) {
return rv;
}
/* Read passkey */
rv = UnpackPDU(pdu, aArg5);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void SspRequestNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
SspRequestNotification::Dispatch<0x01, 0x87>(
&BluetoothNotificationHandler::SspRequestNotification, aPDU);
SspRequestNotification::Dispatch(
&BluetoothNotificationHandler::SspRequestNotification,
SspRequestInitOp(aPDU));
}
// Init operator class for BondStateChangedNotification
class BondStateChangedInitOp MOZ_FINAL : private PDUInitOp
{
public:
BondStateChangedInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (BluetoothStatus& aArg1, nsString& aArg2,
BluetoothBondState& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read status */
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
/* Read remote address */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
if (NS_FAILED(rv)) {
return rv;
}
/* Read bond state */
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void BondStateChangedNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
BondStateChangedNotification::Dispatch<0x01, 0x88>(
&BluetoothNotificationHandler::BondStateChangedNotification, aPDU);
BondStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::BondStateChangedNotification,
BondStateChangedInitOp(aPDU));
}
// Init operator class for AclStateChangedNotification
class AclStateChangedInitOp MOZ_FINAL : private PDUInitOp
{
public:
AclStateChangedInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (BluetoothStatus& aArg1, nsString& aArg2, bool& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read status */
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
/* Read remote address */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
if (NS_FAILED(rv)) {
return rv;
}
/* Read ACL state */
rv = UnpackPDU(
pdu, UnpackConversion<BluetoothAclState, bool>(aArg3));
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void AclStateChangedNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
AclStateChangedNotification::Dispatch<0x01, 0x89>(
&BluetoothNotificationHandler::AclStateChangedNotification, aPDU);
AclStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AclStateChangedNotification,
AclStateChangedInitOp(aPDU));
}
// Init operator class for DutModeRecvNotification
class DutModeRecvInitOp MOZ_FINAL : private PDUInitOp
{
public:
DutModeRecvInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult
operator () (uint16_t& aArg1, nsAutoArrayPtr<uint8_t>& aArg2,
uint8_t& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
/* Read opcode */
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
/* Read length */
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
/* Read data */
rv = UnpackPDU(pdu, UnpackArray<uint8_t>(aArg2, aArg3));
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
void DutModeRecvNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
DutModeRecvNotification::Dispatch<0x01, 0x8a>(
&BluetoothNotificationHandler::DutModeRecvNotification, aPDU);
DutModeRecvNotification::Dispatch(
&BluetoothNotificationHandler::DutModeRecvNotification,
DutModeRecvInitOp(aPDU));
}
void LeTestModeNtf(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU)
{
LeTestModeNotification::Dispatch<0x01, 0x8b>(
&BluetoothNotificationHandler::LeTestModeNotification, aPDU);
LeTestModeNotification::Dispatch(
&BluetoothNotificationHandler::LeTestModeNotification,
UnpackPDUInitOp(aPDU));
}
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,