Bug 790739: Patch 2 - BluetoothSocketConnection changes for server sockets; r=cjones
authorKyle Machulis <kyle@nonpolynomial.com>
Mon, 01 Oct 2012 00:03:28 -0700
changeset 108843 307b15d6a63f369793f48c3c4ef9a53c221c0360
parent 108842 aade44131d6c270a90faca358e1734709d51f74b
child 108844 22011fdcca0146964984e22dcff0827f84a4ac19
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerscjones
bugs790739
milestone18.0a1
Bug 790739: Patch 2 - BluetoothSocketConnection changes for server sockets; r=cjones
dom/bluetooth/BluetoothUnixSocketConnector.cpp
dom/bluetooth/BluetoothUnixSocketConnector.h
--- a/dom/bluetooth/BluetoothUnixSocketConnector.cpp
+++ b/dom/bluetooth/BluetoothUnixSocketConnector.cpp
@@ -30,16 +30,25 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sco.h>
 #include <bluetooth/rfcomm.h>
 #include <bluetooth/l2cap.h>
 
 #include "BluetoothUnixSocketConnector.h"
 #include "nsThreadUtils.h"
 
+#undef LOG
+#if defined(MOZ_WIDGET_GONK)
+#include <android/log.h>
+#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GonkDBus", args);
+#else
+#define BTDEBUG true
+#define LOG(args...) if (BTDEBUG) printf(args);
+#endif
+
 USING_BLUETOOTH_NAMESPACE
 
 static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
 
 static
 int get_bdaddr(const char *str, bdaddr_t *ba)
 {
   char *d = ((char*)ba) + 5, *endp;
@@ -57,119 +66,116 @@ BluetoothUnixSocketConnector::BluetoothU
   bool aAuth,
   bool aEncrypt) : mType(aType)
                  , mChannel(aChannel)
                  , mAuth(aAuth)
                  , mEncrypt(aEncrypt)
 {
 }
 
-int
-BluetoothUnixSocketConnector::Create()
+bool
+BluetoothUnixSocketConnector::Setup(int aFd)
 {
-  MOZ_ASSERT(!NS_IsMainThread());
   int lm = 0;
-  int fd = -1;
   int sndbuf;
-
-  switch (mType) {
-  case BluetoothSocketType::RFCOMM:
-    fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-    break;
-  case BluetoothSocketType::SCO:
-    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
-    break;
-  case BluetoothSocketType::L2CAP:
-    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
-    break;
-  default:
-    return -1;
-  }
-
-  if (fd < 0) {
-    NS_WARNING("Could not open bluetooth socket!");
-    return -1;
-  }
-
   /* kernel does not yet support LM for SCO */
   switch (mType) {
   case BluetoothSocketType::RFCOMM:
     lm |= mAuth ? RFCOMM_LM_AUTH : 0;
     lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
     lm |= (mAuth && mEncrypt) ? RFCOMM_LM_SECURE : 0;
     break;
   case BluetoothSocketType::L2CAP:
     lm |= mAuth ? L2CAP_LM_AUTH : 0;
     lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
     lm |= (mAuth && mEncrypt) ? L2CAP_LM_SECURE : 0;
     break;
   }
 
   if (lm) {
-    if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
+    if (setsockopt(aFd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
       NS_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
-      return -1;
+      return false;
     }
   }
 
   if (mType == BluetoothSocketType::RFCOMM) {
     sndbuf = RFCOMM_SO_SNDBUF;
-    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
+    if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
       NS_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
-      return -1;
+      return false;
     }
   }
 
+  return true;
+}
+
+int
+BluetoothUnixSocketConnector::Create()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+  int fd = -1;
+
+  switch (mType) {
+  case BluetoothSocketType::RFCOMM:
+    fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+    break;
+  case BluetoothSocketType::SCO:
+    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+    break;
+  case BluetoothSocketType::L2CAP:
+    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+    break;
+  default:
+    MOZ_NOT_REACHED();
+  }
+
+  if (fd < 0) {
+    NS_WARNING("Could not open bluetooth socket!");
+    return -1;
+  }
+
+  if (!Setup(fd)) {
+    NS_WARNING("Could not set up socket!");
+  }
   return fd;
 }
 
-bool
-BluetoothUnixSocketConnector::ConnectInternal(int aFd, const char* aAddress)
+void
+BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
+                                         socklen_t& aAddrSize,
+                                         struct sockaddr* aAddr,
+                                         const char* aAddress)
 {
-  int n = 1;
-  setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
-  
-  socklen_t addr_sz;
-  struct sockaddr *addr;
-  bdaddr_t bd_address_obj;
+  // Set to BDADDR_ANY, if it's not a server, we'll reset.
+  bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}};
 
-  if (get_bdaddr(aAddress, &bd_address_obj)) {
-    NS_WARNING("Can't get bluetooth address!");
-    return false;
+  if (!aIsServer && aAddress && strlen(aAddress) > 0) {
+    if (get_bdaddr(aAddress, &bd_address_obj)) {
+      NS_WARNING("Can't get bluetooth address!");
+      return;
+    }
   }
 
   switch (mType) {
   case BluetoothSocketType::RFCOMM:
     struct sockaddr_rc addr_rc;
-    addr = (struct sockaddr *)&addr_rc;
-    addr_sz = sizeof(addr_rc);
-
-    memset(addr, 0, addr_sz);
+    aAddrSize = sizeof(addr_rc);
+    memset(aAddr, 0, aAddrSize);
     addr_rc.rc_family = AF_BLUETOOTH;
     addr_rc.rc_channel = mChannel;
     memcpy(&addr_rc.rc_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
+    memcpy(aAddr, &addr_rc, sizeof(addr_rc));
     break;
   case BluetoothSocketType::SCO:
     struct sockaddr_sco addr_sco;
-    addr = (struct sockaddr *)&addr_sco;
-    addr_sz = sizeof(addr_sco);
+    aAddrSize = sizeof(addr_sco);
 
-    memset(addr, 0, addr_sz);
+    memset(aAddr, 0, aAddrSize);
     addr_sco.sco_family = AF_BLUETOOTH;
     memcpy(&addr_sco.sco_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
+    memcpy(aAddr, &addr_sco, sizeof(addr_sco));
     break;
   default:
     NS_WARNING("Socket type unknown!");
-    return false;
   }
-
-  int ret = connect(aFd, addr, addr_sz);
+}
 
-  if (ret) {
-#if DEBUG
-    //LOG("Socket connect errno=%d\n", errno);
-#endif
-    NS_WARNING("Socket connect error!");
-    return false;
-  }
-
-  return true;
-}
--- a/dom/bluetooth/BluetoothUnixSocketConnector.h
+++ b/dom/bluetooth/BluetoothUnixSocketConnector.h
@@ -3,30 +3,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
 #define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
 
 #include "BluetoothCommon.h"
+#include <sys/socket.h>
 #include <mozilla/ipc/UnixSocket.h>
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothUnixSocketConnector : public mozilla::ipc::UnixSocketConnector
 {
 public:
   BluetoothUnixSocketConnector(BluetoothSocketType aType, int aChannel,
                                bool aAuth, bool aEncrypt);
   virtual ~BluetoothUnixSocketConnector()
   {}
   virtual int Create() MOZ_OVERRIDE;
-  virtual bool ConnectInternal(int aFd, const char* aAddress) MOZ_OVERRIDE;
-
+  virtual void CreateAddr(bool aIsServer,
+                          socklen_t& aAddrSize,
+                          struct sockaddr* aAddr,
+                          const char* aAddress) MOZ_OVERRIDE;
+  virtual bool Setup(int aFd) MOZ_OVERRIDE;
 private:
   BluetoothSocketType mType;
   int mChannel;
   bool mAuth;
   bool mEncrypt;
 };
 
 END_BLUETOOTH_NAMESPACE