void
BluetoothProfileController::StartSession()
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!mDeviceAddress.IsEmpty());
  MOZ_ASSERT(mProfilesIndex == -1);
  MOZ_ASSERT(mTimer);

  if (!IsBtServiceAvailable()) {
    EndSession();
    return;
  }

  if (mProfiles.Length() < 1) {
    BT_LOGR("No queued profile.");
    EndSession();
    return;
  }

  if (mTimer) {
    mTimer->InitWithCallback(new CheckProfileStatusCallback(this),
                             CONNECTION_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT);
  }

  BT_LOGR("%s", mConnect ? "connecting" : "disconnecting");

  Next();
}
nsresult
NamedValueToProperty(const BluetoothNamedValue& aValue,
                     BluetoothProperty& aProperty)
{
  nsresult rv = StringToPropertyType(aValue.name(), aProperty.mType);
  if (NS_FAILED(rv)) {
    return rv;
  }

  switch (aProperty.mType) {
    case PROPERTY_BDNAME:
      if (aValue.value().type() != BluetoothValue::TnsString) {
        BT_LOGR("Bluetooth property value is not a string");
        return NS_ERROR_ILLEGAL_VALUE;
      }
      // Set name
      aProperty.mString = aValue.value().get_nsString();
      break;

    case PROPERTY_ADAPTER_SCAN_MODE:
      if (aValue.value().type() != BluetoothValue::Tbool) {
        BT_LOGR("Bluetooth property value is not a boolean");
        return NS_ERROR_ILLEGAL_VALUE;
      }
      // Set scan mode
      if (aValue.value().get_bool()) {
        aProperty.mScanMode = SCAN_MODE_CONNECTABLE_DISCOVERABLE;
      } else {
        aProperty.mScanMode = SCAN_MODE_CONNECTABLE;
      }
      break;

    case PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
      if (aValue.value().type() != BluetoothValue::Tuint32_t) {
        BT_LOGR("Bluetooth property value is not an unsigned integer");
        return NS_ERROR_ILLEGAL_VALUE;
      }
      // Set discoverable timeout
      aProperty.mUint32 = aValue.value().get_uint32_t();
      break;

    default:
      BT_LOGR("Invalid property value type");
      return NS_ERROR_ILLEGAL_VALUE;
  }

  return NS_OK;
}
nsresult
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
{
  nsresult rv = PackPDU(
    PackConversion<nsString, BluetoothPropertyType>(aIn.name()), aPDU);
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (aIn.value().type() == BluetoothValue::Tuint32_t) {
    // Set discoverable timeout
    rv = PackPDU(static_cast<uint16_t>(sizeof(uint32_t)),
                 aIn.value().get_uint32_t(), aPDU);
  } else if (aIn.value().type() == BluetoothValue::TnsString) {
    // Set name
    const nsCString value =
      NS_ConvertUTF16toUTF8(aIn.value().get_nsString());

    rv = PackPDU(PackConversion<size_t, uint16_t>(value.Length()),
                 PackArray<uint8_t>(
                   reinterpret_cast<const uint8_t*>(value.get()),
                   value.Length()),
                 aPDU);
  } else if (aIn.value().type() == BluetoothValue::Tbool) {
    // Set scan mode
    bool value = aIn.value().get_bool();

    rv = PackPDU(static_cast<uint16_t>(sizeof(int32_t)),
                 PackConversion<bool, BluetoothScanMode>(value), aPDU);
  } else {
    BT_LOGR("Invalid property value type");
    rv = NS_ERROR_ILLEGAL_VALUE;
  }
  return rv;
}
void
BluetoothProfileController::EndSession()
{
  MOZ_ASSERT(mRunnable && mCallback);

  BT_LOGR("mSuccess %d", mSuccess);

  // Don't have to check profile status and retrigger session after connection
  // timeout, since session is end.
  if (mTimer) {
    mTimer->Cancel();
  }

  // The action has completed, so the DOM request should be replied then invoke
  // the callback.
  if (mSuccess) {
    DispatchReplySuccess(mRunnable);
  } else if (mConnect) {
    DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
  } else {
    DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
  }

  mCallback();
}
Exemple #5
0
nsresult
Convert(ConvertNamedValue& aIn, bt_property_t& aOut)
{
  nsresult rv = Convert(aIn.mNamedValue.name(), aOut.type);
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (aIn.mNamedValue.value().type() == BluetoothValue::Tuint32_t) {
    // Set discoverable timeout
    aOut.val = const_cast<void*>(static_cast<const void*>(
      &(aIn.mNamedValue.value().get_uint32_t())));
      aOut.len = sizeof(uint32_t);
  } else if (aIn.mNamedValue.value().type() == BluetoothValue::TnsString) {
    // Set name
    aIn.mStringValue =
      NS_ConvertUTF16toUTF8(aIn.mNamedValue.value().get_nsString());
    aOut.val =
      const_cast<void*>(static_cast<const void*>(aIn.mStringValue.get()));
    aOut.len = strlen(static_cast<char*>(aOut.val));
  } else if (aIn.mNamedValue.value().type() == BluetoothValue::Tbool) {
    // Set scan mode
    rv = Convert(aIn.mNamedValue.value().get_bool(), aIn.mScanMode);
    if (NS_FAILED(rv)) {
      return rv;
    }
    aOut.val = &aIn.mScanMode;
    aOut.len = sizeof(aIn.mScanMode);
  } else {
    BT_LOGR("Invalid property value type");
    return NS_ERROR_ILLEGAL_VALUE;
  }

  return NS_OK;
}
Exemple #6
0
void
BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
{
  // Stop listening
  ListenMobileConnAndIccInfo(false);

  /**
   * aRegistered:
   * - TRUE:  service becomes registered. We were listening to all clients
   *          and one of them becomes available. Select it to listen.
   * - FALSE: service becomes un-registered. The client we were listening
   *          becomes unavailable. Select another registered one to listen.
   */
  if (aRegistered) {
    mClientId = aClientId;
  } else {
    SelectClient();
  }

  // Restart listening
  ListenMobileConnAndIccInfo(true);

  BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
          (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
}
void
BluetoothPairingListener::TryListeningToBluetoothSignal()
{
  if (mHasListenedToSignal) {
    // We've handled prior pending pairing requests
    return;
  }

  // Listen to bluetooth signal only if all pairing event handlers have been
  // attached. All pending pairing requests queued in BluetoothService would
  // be fired when pairing listener starts listening to bluetooth signal.
  if (!HasListenersFor(nsGkAtoms::ondisplaypasskeyreq) ||
      !HasListenersFor(nsGkAtoms::onenterpincodereq) ||
      !HasListenersFor(nsGkAtoms::onpairingconfirmationreq) ||
      !HasListenersFor(nsGkAtoms::onpairingconsentreq)) {
    BT_LOGR("Pairing listener is not ready to handle pairing requests!");
    return;
  }

  // Start listening to bluetooth signal to handle pairing requests
  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE_VOID(bs);
  bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                                     this);

  mHasListenedToSignal = true;
}
nsresult
PinCodeToString(const BluetoothPinCode& aPinCode, nsAString& aString)
{
  if (aPinCode.mLength > sizeof(aPinCode.mPinCode)) {
    BT_LOGR("Pin-code string too long");
    return NS_ERROR_ILLEGAL_VALUE;
  }

  aString = NS_ConvertUTF8toUTF16(
    nsCString(reinterpret_cast<const char*>(aPinCode.mPinCode),
              aPinCode.mLength));

  return NS_OK;
}
nsresult
Convert(const nsAString& aIn, BluetoothPropertyType& aOut)
{
  if (aIn.EqualsLiteral("Name")) {
    aOut = PROPERTY_BDNAME;
  } else if (aIn.EqualsLiteral("Discoverable")) {
    aOut = PROPERTY_ADAPTER_SCAN_MODE;
  } else if (aIn.EqualsLiteral("DiscoverableTimeout")) {
    aOut = PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
  } else {
    BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aIn).get());
    aOut = static_cast<BluetoothPropertyType>(0); // silences compiler warning
    return NS_ERROR_ILLEGAL_VALUE;
  }
  return NS_OK;
}
nsresult
StringToPropertyType(const nsAString& aString, BluetoothPropertyType& aType)
{
  if (aString.EqualsLiteral("Name")) {
    aType = PROPERTY_BDNAME;
  } else if (aString.EqualsLiteral("Discoverable")) {
    aType = PROPERTY_ADAPTER_SCAN_MODE;
  } else if (aString.EqualsLiteral("DiscoverableTimeout")) {
    aType = PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
  } else {
    BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aString).get());
    aType = PROPERTY_UNKNOWN; // silences compiler warning
    return NS_ERROR_ILLEGAL_VALUE;
  }
  return NS_OK;
}
nsresult
Convert(const nsAString& aIn, BluetoothSspVariant& aOut)
{
  if (aIn.EqualsLiteral("PasskeyConfirmation")) {
    aOut = SSP_VARIANT_PASSKEY_CONFIRMATION;
  } else if (aIn.EqualsLiteral("PasskeyEntry")) {
    aOut = SSP_VARIANT_PASSKEY_ENTRY;
  } else if (aIn.EqualsLiteral("Consent")) {
    aOut = SSP_VARIANT_CONSENT;
  } else if (aIn.EqualsLiteral("PasskeyNotification")) {
    aOut = SSP_VARIANT_PASSKEY_NOTIFICATION;
  } else {
    BT_LOGR("Invalid SSP variant name: %s", NS_ConvertUTF16toUTF8(aIn).get());
    aOut = SSP_VARIANT_PASSKEY_CONFIRMATION; // silences compiler warning
    return NS_ERROR_ILLEGAL_VALUE;
  }
  return NS_OK;
}
nsresult
StringToPinCode(const nsAString& aString, BluetoothPinCode& aPinCode)
{
  NS_ConvertUTF16toUTF8 stringUTF8(aString);

  auto len = stringUTF8.Length();

  if (len > sizeof(aPinCode.mPinCode)) {
    BT_LOGR("Service-name string too long");
    return NS_ERROR_ILLEGAL_VALUE;
  }

  auto str = stringUTF8.get();

  memcpy(aPinCode.mPinCode, str, len);
  memset(aPinCode.mPinCode + len, 0, sizeof(aPinCode.mPinCode) - len);
  aPinCode.mLength = len;

  return NS_OK;
}
nsresult
StringToServiceName(const nsAString& aString,
                    BluetoothServiceName& aServiceName)
{
  NS_ConvertUTF16toUTF8 serviceNameUTF8(aString);

  auto len = serviceNameUTF8.Length();

  if (len > sizeof(aServiceName.mName)) {
    BT_LOGR("Service-name string too long");
    return NS_ERROR_ILLEGAL_VALUE;
  }

  auto str = serviceNameUTF8.get();

  memcpy(aServiceName.mName, str, len);
  memset(aServiceName.mName + len, 0, sizeof(aServiceName.mName) - len);

  return NS_OK;
}
static nsresult
DispatchBluetoothHALResult(BluetoothResultHandler* aRes,
                           void (BluetoothResultHandler::*aMethod)(),
                           BluetoothStatus aStatus)
{
  MOZ_ASSERT(aRes);

  nsRunnable* runnable;

  if (aStatus == STATUS_SUCCESS) {
    runnable = new BluetoothHALResultRunnable(aRes, aMethod);
  } else {
    runnable = new BluetoothHALErrorRunnable(
      aRes, &BluetoothResultHandler::OnError, aStatus);
  }
  nsresult rv = NS_DispatchToMainThread(runnable);
  if (NS_FAILED(rv)) {
    BT_LOGR("NS_DispatchToMainThread failed: %X", rv);
  }
  return rv;
}
Exemple #15
0
BEGIN_BLUETOOTH_NAMESPACE

//
// Conversion
//

nsresult
Convert(const nsAString& aIn, bt_property_type_t& aOut)
{
  if (aIn.EqualsLiteral("Name")) {
    aOut = BT_PROPERTY_BDNAME;
  } else if (aIn.EqualsLiteral("Discoverable")) {
    aOut = BT_PROPERTY_ADAPTER_SCAN_MODE;
  } else if (aIn.EqualsLiteral("DiscoverableTimeout")) {
    aOut = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
  } else {
    BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aIn).get());
    return NS_ERROR_ILLEGAL_VALUE;
  }
  return NS_OK;
}
nsresult
StringToControlPlayStatus(const nsAString& aString,
                          ControlPlayStatus& aPlayStatus)
{
  if (aString.EqualsLiteral("STOPPED")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
  } else if (aString.EqualsLiteral("PLAYING")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_PLAYING;
  } else if (aString.EqualsLiteral("PAUSED")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_PAUSED;
  } else if (aString.EqualsLiteral("FWD_SEEK")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_FWD_SEEK;
  } else if (aString.EqualsLiteral("REV_SEEK")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_REV_SEEK;
  } else if (aString.EqualsLiteral("ERROR")) {
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_ERROR;
  } else {
    BT_LOGR("Invalid play status: %s", NS_ConvertUTF16toUTF8(aString).get());
    aPlayStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
    return NS_ERROR_ILLEGAL_VALUE;
  }

  return NS_OK;
}
void
BluetoothResultHandler::OnError(BluetoothStatus aStatus)
{
    BT_LOGR("Received error code %d", aStatus);
}
void
BluetoothMapFolder::DumpFolderInfo()
{
  BT_LOGR("Folder name: %s, subfolder counts: %d",
          NS_ConvertUTF16toUTF8(mName).get(), mSubFolders.Count());
}