Bug 1136514 - Add ReadRemoteRssi in GATT client. f=jocelyn, r=btian, r=mrbkap

This commit is contained in:
Bruce Sun 2015-03-16 16:55:50 +08:00
Родитель 0ce684afcd
Коммит 95d9f5aead
15 изменённых файлов: 235 добавлений и 1 удалений

Просмотреть файл

@ -167,6 +167,55 @@ BluetoothGatt::Disconnect(ErrorResult& aRv)
return promise.forget();
}
class ReadRemoteRssiTask MOZ_FINAL : public BluetoothReplyRunnable
{
public:
ReadRemoteRssiTask(Promise* aPromise)
: BluetoothReplyRunnable(nullptr, aPromise,
NS_LITERAL_STRING("GattClientReadRemoteRssi"))
{
MOZ_ASSERT(aPromise);
}
bool
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
{
aValue.setUndefined();
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
NS_ENSURE_TRUE(v.type() == BluetoothValue::Tuint32_t, false);
aValue.setInt32(static_cast<int32_t>(v.get_uint32_t()));
return true;
}
};
already_AddRefed<Promise>
BluetoothGatt::ReadRemoteRssi(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(
mConnectionState == BluetoothConnectionState::Connected,
NS_ERROR_DOM_INVALID_STATE_ERR);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
nsRefPtr<BluetoothReplyRunnable> result =
new ReadRemoteRssiTask(promise);
bs->GattClientReadRemoteRssiInternal(mClientIf, mDeviceAddr, result);
return promise.forget();
}
void
BluetoothGatt::UpdateConnectionState(BluetoothConnectionState aState)
{

Просмотреть файл

@ -51,6 +51,7 @@ public:
***************************************************************************/
already_AddRefed<Promise> Connect(ErrorResult& aRv);
already_AddRefed<Promise> Disconnect(ErrorResult& aRv);
already_AddRefed<Promise> ReadRemoteRssi(ErrorResult& aRv);
/****************************************************************************
* Others

Просмотреть файл

@ -349,6 +349,13 @@ public:
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Request RSSI for a remote GATT server. (platform specific implementation)
*/
virtual void
GattClientReadRemoteRssiInternal(int aClientIf,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) = 0;
bool
IsEnabled() const

Просмотреть файл

@ -57,6 +57,7 @@ public:
mConnectRunnable = nullptr;
mDisconnectRunnable = nullptr;
mUnregisterClientRunnable = nullptr;
mReadRemoteRssiRunnable = nullptr;
}
nsString mAppUuid;
@ -66,6 +67,7 @@ public:
nsRefPtr<BluetoothReplyRunnable> mConnectRunnable;
nsRefPtr<BluetoothReplyRunnable> mDisconnectRunnable;
nsRefPtr<BluetoothReplyRunnable> mUnregisterClientRunnable;
nsRefPtr<BluetoothReplyRunnable> mReadRemoteRssiRunnable;
};
NS_IMPL_ISUPPORTS0(BluetoothGattClient)
@ -484,6 +486,63 @@ BluetoothGattManager::Disconnect(const nsAString& aAppUuid,
new DisconnectResultHandler(client));
}
class BluetoothGattManager::ReadRemoteRssiResultHandler MOZ_FINAL
: public BluetoothGattClientResultHandler
{
public:
ReadRemoteRssiResultHandler(BluetoothGattClient* aClient)
: mClient(aClient)
{
MOZ_ASSERT(mClient);
}
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattClientInterface::ReadRemoteRssi failed: %d",
(int)aStatus);
MOZ_ASSERT(mClient->mReadRemoteRssiRunnable);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
// Reject the read remote rssi request
DispatchReplyError(mClient->mReadRemoteRssiRunnable,
NS_LITERAL_STRING("ReadRemoteRssi failed"));
mClient->mReadRemoteRssiRunnable = nullptr;
}
private:
nsRefPtr<BluetoothGattClient> mClient;
};
void
BluetoothGattManager::ReadRemoteRssi(int aClientIf,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
ClientIfComparator());
// Reject the read remote rssi request if the client is not found
if (index == sClients->NoIndex) {
DispatchReplyError(aRunnable,
NS_LITERAL_STRING("Read remote RSSI failed"));
return;
}
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mReadRemoteRssiRunnable = aRunnable;
sBluetoothGattClientInterface->ReadRemoteRssi(
aClientIf, aDeviceAddr,
new ReadRemoteRssiResultHandler(client));
}
//
// Notification Handlers
//
@ -728,7 +787,40 @@ BluetoothGattManager::ReadRemoteRssiNotification(int aClientIf,
const nsAString& aBdAddr,
int aRssi,
BluetoothGattStatus aStatus)
{ }
{
BT_API2_LOGR();
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
ClientIfComparator());
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
if (aStatus != GATT_STATUS_SUCCESS) { // operation failed
BT_API2_LOGR("ReadRemoteRssi failed, clientIf = %d, bdAddr = %s, " \
"rssi = %d, status = %d", aClientIf,
NS_ConvertUTF16toUTF8(aBdAddr).get(), aRssi, (int)aStatus);
// Reject the read remote rssi request
if (client->mReadRemoteRssiRunnable) {
DispatchReplyError(client->mReadRemoteRssiRunnable,
NS_LITERAL_STRING("ReadRemoteRssi failed"));
client->mReadRemoteRssiRunnable = nullptr;
}
return;
}
// Resolve the read remote rssi request
if (client->mReadRemoteRssiRunnable) {
DispatchReplySuccess(client->mReadRemoteRssiRunnable,
BluetoothValue(static_cast<uint32_t>(aRssi)));
client->mReadRemoteRssiRunnable = nullptr;
}
}
void
BluetoothGattManager::ListenNotification(BluetoothGattStatus aStatus,

Просмотреть файл

@ -38,6 +38,10 @@ public:
void UnregisterClient(int aClientIf,
BluetoothReplyRunnable* aRunnable);
void ReadRemoteRssi(int aClientIf,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable);
private:
class CleanupResultHandler;
class CleanupResultHandlerRunnable;
@ -46,6 +50,7 @@ private:
class UnregisterClientResultHandler;
class ConnectResultHandler;
class DisconnectResultHandler;
class ReadRemoteRssiResultHandler;
BluetoothGattManager();

Просмотреть файл

@ -1131,6 +1131,21 @@ BluetoothServiceBluedroid::UnregisterGattClientInternal(
gatt->UnregisterClient(aClientIf, aRunnable);
}
void
BluetoothServiceBluedroid::GattClientReadRemoteRssiInternal(
int aClientIf, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->ReadRemoteRssi(aClientIf, aDeviceAddress, aRunnable);
}
//
// Bluetooth notifications
//

Просмотреть файл

@ -188,6 +188,11 @@ public:
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
GattClientReadRemoteRssiInternal(
int aClientIf, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
//
// Bluetooth notifications
//

Просмотреть файл

@ -4296,3 +4296,10 @@ BluetoothDBusService::UnregisterGattClientInternal(
int aClientIf, BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::GattClientReadRemoteRssiInternal(
int aClientIf, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
}

Просмотреть файл

@ -198,6 +198,11 @@ public:
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
GattClientReadRemoteRssiInternal(
int aClientIf, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
private:
nsresult SendGetPropertyMessage(const nsAString& aPath,
const char* aInterface,

Просмотреть файл

@ -256,6 +256,8 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
return actor->DoRequest(aRequest.get_DisconnectGattClientRequest());
case Request::TUnregisterGattClientRequest:
return actor->DoRequest(aRequest.get_UnregisterGattClientRequest());
case Request::TGattClientReadRemoteRssiRequest:
return actor->DoRequest(aRequest.get_GattClientReadRemoteRssiRequest());
default:
MOZ_CRASH("Unknown type!");
}
@ -728,3 +730,17 @@ BluetoothRequestParent::DoRequest(const UnregisterGattClientRequest& aRequest)
return true;
}
bool
BluetoothRequestParent::DoRequest(
const GattClientReadRemoteRssiRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TGattClientReadRemoteRssiRequest);
mService->GattClientReadRemoteRssiInternal(aRequest.clientIf(),
aRequest.deviceAddress(),
mReplyRunnable.get());
return true;
}

Просмотреть файл

@ -225,6 +225,9 @@ protected:
bool
DoRequest(const UnregisterGattClientRequest& aRequest);
bool
DoRequest(const GattClientReadRemoteRssiRequest& aRequest);
};
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -404,6 +404,16 @@ BluetoothServiceChildProcess::UnregisterGattClientInternal(
SendRequest(aRunnable, UnregisterGattClientRequest(aClientIf));
}
void
BluetoothServiceChildProcess::GattClientReadRemoteRssiInternal(
int aClientIf, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
GattClientReadRemoteRssiRequest(aClientIf,
nsString(aDeviceAddress)));
}
nsresult
BluetoothServiceChildProcess::HandleStartup()
{

Просмотреть файл

@ -206,6 +206,11 @@ public:
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
GattClientReadRemoteRssiInternal(int aClientIf,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
protected:
BluetoothServiceChildProcess();
virtual ~BluetoothServiceChildProcess();

Просмотреть файл

@ -193,6 +193,12 @@ struct UnregisterGattClientRequest
int clientIf;
};
struct GattClientReadRemoteRssiRequest
{
int clientIf;
nsString deviceAddress;
};
union Request
{
GetAdaptersRequest;
@ -228,6 +234,7 @@ union Request
ConnectGattClientRequest;
DisconnectGattClientRequest;
UnregisterGattClientRequest;
GattClientReadRemoteRssiRequest;
};
protocol PBluetooth

Просмотреть файл

@ -27,6 +27,13 @@ interface BluetoothGatt : EventTarget
Promise<void> connect();
[NewObject]
Promise<void> disconnect();
/**
* Read RSSI for the remote BLE device if the connectState is connected.
* Otherwise, the Promise will be rejected directly.
*/
[NewObject]
Promise<short> readRemoteRssi();
};
enum BluetoothConnectionState