Bug 756299: Patch 1 - IPC Socket Functions; r=mrbkap
authorKyle Machulis <kyle@nonpolynomial.com>
Wed, 05 Sep 2012 20:06:06 -0700
changeset 104409 b5f9c880652ac1acb2b6428994a66fdbe66a29d6
parent 104408 ff19aab9d56c1c8fad79592543be65116c65ae4a
child 104410 740dd374fca7ab212a6370eea5343771290446f5
push id23422
push useremorley@mozilla.com
push dateThu, 06 Sep 2012 09:22:07 +0000
treeherdermozilla-central@5f7e3a8d6640 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs756299
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 756299: Patch 1 - IPC Socket Functions; r=mrbkap
configure.in
ipc/Makefile.in
ipc/socket/Makefile.in
ipc/socket/Socket.cpp
ipc/socket/Socket.h
toolkit/library/Makefile.in
--- a/configure.in
+++ b/configure.in
@@ -186,17 +186,17 @@ if test -n "$gonkdir" ; then
     arm)
         ARCH_DIR=arch-arm
         ;;
     i?86)
         ARCH_DIR=arch-x86
         ;;
     esac
 
-    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice -I$gonkdir/frameworks/base/services/camera -I$gonkdir/system/media/wilhelm/include"
+    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice -I$gonkdir/frameworks/base/services/camera -I$gonkdir/system/media/wilhelm/include"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS $STLPORT_CPPFLAGS"
     dnl Add -llog by default, since we use it all over the place.
     LIBS="$LIBS -llog $STLPORT_LIBS"
 
     LDFLAGS="-mandroid -L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib --sysroot=$gonkdir/out/target/product/$GONK_PRODUCT/obj/ $LDFLAGS"
 
     dnl prevent cross compile section from using these flags as host flags
--- a/ipc/Makefile.in
+++ b/ipc/Makefile.in
@@ -11,17 +11,17 @@ include $(DEPTH)/config/autoconf.mk
 
 DIRS += chromium glue ipdl testshell
 
 ifdef MOZ_B2G_RIL #{
 DIRS += ril
 endif #}
 
 ifdef MOZ_B2G_BT #{
-DIRS += dbus
+DIRS += dbus socket
 endif #}
 
 ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 DIRS += netd
 endif
 
 TOOL_DIRS = app
 
new file mode 100644
--- /dev/null
+++ b/ipc/socket/Makefile.in
@@ -0,0 +1,31 @@
+# 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/.
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ipc
+LIBRARY_NAME = mozipcsocket_s
+FORCE_STATIC_LIB = 1
+LIBXUL_LIBRARY = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS_NAMESPACES = mozilla/ipc
+
+EXPORTS_mozilla/ipc = \
+  Socket.h \
+  $(NULL)
+
+CPPSRCS += \
+  Socket.cpp \
+  $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/ipc/socket/Socket.cpp
@@ -0,0 +1,180 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "Socket.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sco.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/l2cap.h>
+
+#include "nsThreadUtils.h"
+
+#undef LOG
+#if defined(MOZ_WIDGET_GONK)
+#include <android/log.h>
+#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
+#else
+#define LOG(args...)  printf(args);
+#endif
+#define TYPE_AS_STR(t)                                                  \
+  ((t) == TYPE_RFCOMM ? "RFCOMM" : ((t) == TYPE_SCO ? "SCO" : "L2CAP"))
+
+namespace mozilla {
+namespace ipc {
+static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
+
+static const int TYPE_RFCOMM = 1;
+static const int TYPE_SCO = 2;
+static const int TYPE_L2CAP = 3;
+
+static int get_bdaddr(const char *str, bdaddr_t *ba)
+{
+  char *d = ((char*)ba) + 5, *endp;
+  for (int i = 0; i < 6; i++) {
+    *d-- = strtol(str, &endp, 16);
+    MOZ_ASSERT(*endp != ':' && i != 5);
+    str = endp + 1;
+  }
+  return 0;
+}
+
+int
+OpenSocket(int type, const char* aAddress, int channel, bool auth, bool encrypt)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+  int lm = 0;
+  int fd = -1;
+  int sndbuf;
+
+  switch (type) {
+  case TYPE_RFCOMM:
+    fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+    break;
+  case TYPE_SCO:
+    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+    break;
+  case TYPE_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 (type) {
+  case TYPE_RFCOMM:
+    lm |= auth ? RFCOMM_LM_AUTH : 0;
+    lm |= encrypt ? RFCOMM_LM_ENCRYPT : 0;
+    lm |= (auth && encrypt) ? RFCOMM_LM_SECURE : 0;
+    break;
+  case TYPE_L2CAP:
+    lm |= auth ? L2CAP_LM_AUTH : 0;
+    lm |= encrypt ? L2CAP_LM_ENCRYPT : 0;
+    lm |= (auth && encrypt) ? L2CAP_LM_SECURE : 0;
+    break;
+  }
+
+  if (lm) {
+    if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
+      LOG("setsockopt(RFCOMM_LM) failed, throwing");
+      return -1;
+    }
+  }
+
+  if (type == TYPE_RFCOMM) {
+    sndbuf = RFCOMM_SO_SNDBUF;
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
+      LOG("setsockopt(SO_SNDBUF) failed, throwing");
+      return -1;
+    }
+  }
+
+  int n = 1;
+  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+  
+  socklen_t addr_sz;
+  struct sockaddr *addr;
+  bdaddr_t bd_address_obj;
+
+  int mPort = channel;
+
+  char mAddress[18];
+  mAddress[17] = '\0';
+  strncpy(&mAddress[0], aAddress, 17);
+
+  if (get_bdaddr(aAddress, &bd_address_obj)) {
+    NS_WARNING("Can't get bluetooth address!");
+    return -1;
+  }
+
+  switch (type) {
+  case TYPE_RFCOMM:
+    struct sockaddr_rc addr_rc;
+    addr = (struct sockaddr *)&addr_rc;
+    addr_sz = sizeof(addr_rc);
+
+    memset(addr, 0, addr_sz);
+    addr_rc.rc_family = AF_BLUETOOTH;
+    addr_rc.rc_channel = mPort;
+    memcpy(&addr_rc.rc_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
+    break;
+  case TYPE_SCO:
+    struct sockaddr_sco addr_sco;
+    addr = (struct sockaddr *)&addr_sco;
+    addr_sz = sizeof(addr_sco);
+
+    memset(addr, 0, addr_sz);
+    addr_sco.sco_family = AF_BLUETOOTH;
+    memcpy(&addr_sco.sco_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
+    break;
+  default:
+    NS_WARNING("Socket type unknown!");
+    return -1;
+  }
+
+  int ret = connect(fd, addr, addr_sz);
+
+  if (ret) {
+#if DEBUG
+    LOG("Socket connect errno=%d\n", errno);
+#endif
+    NS_WARNING("Socket connect error!");
+    return -1;
+  }
+
+  // Match android_bluetooth_HeadsetBase.cpp line 384
+  // Skip many lines
+  return fd;
+}
+
+int
+GetNewSocket(int type, const char* aAddress, int channel, bool auth, bool encrypt)
+{
+  return OpenSocket(type, aAddress, channel, auth, encrypt);
+}
+
+int
+CloseSocket(int aFd)
+{
+  // This can block since we aren't opening sockets O_NONBLOCK
+  MOZ_ASSERT(!NS_IsMainThread());
+  return close(aFd);
+}
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/socket/Socket.h
@@ -0,0 +1,22 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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_ipc_Socket_h
+#define mozilla_ipc_Socket_h
+
+namespace mozilla {
+namespace ipc {
+
+int
+GetNewSocket(int type, const char* aAddress, int channel, bool auth, bool encrypt);
+
+int
+CloseSocket(int aFd);
+
+} // namespace ipc
+} // namepsace mozilla
+
+#endif // mozilla_ipc_Socket_h
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -106,17 +106,17 @@ STATIC_LIBS += \
   dombindings_s \
   $(NULL)
 
 ifdef MOZ_B2G_RIL #{
 STATIC_LIBS += mozril_s
 endif #}
 
 ifdef MOZ_B2G_BT #{
-STATIC_LIBS += mozdbus_s
+STATIC_LIBS += mozdbus_s mozipcsocket_s
 endif #}
 
 ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 STATIC_LIBS += moznetd_s
 endif
 
 ifdef MOZ_IPDL_TESTS
 STATIC_LIBS += ipdlunittest_s