proximity: factoring the proximity code out to a separate repository

This CL depends on https://veyron-review.googlesource.com/4012

Change-Id: I2de6b553ccd64c79c7d99c864fe7eb845f6830f6
diff --git a/lib/bluetooth/addr_linux.go b/lib/bluetooth/addr_linux.go
deleted file mode 100644
index 0b9bc8c..0000000
--- a/lib/bluetooth/addr_linux.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"bytes"
-	"fmt"
-	"net"
-	"strconv"
-	"strings"
-)
-
-// addr represents an RFCOMM over bluetooth address in the <MAC-channelID>
-// format, where channelID denotes one of the available RFCOMM channels.
-//
-// It implements the net.Addr interface.
-type addr struct {
-	mac     net.HardwareAddr
-	channel int
-}
-
-// anyMAC is a MAC address "00:00:00:00:00:00", which means first available
-// (bluetooth) device.
-var anyMAC net.HardwareAddr
-
-func init() {
-	var err error
-	if anyMAC, err = net.ParseMAC("00:00:00:00:00:00"); err != nil {
-		panic("can't parse address 00:00:00:00:00:00")
-	}
-}
-
-// parseAddress parses an address string in the <MAC-channelID> format (e.g.,
-// "01:23:45:67:89:AB-1").  It returns an error if the address is in the wrong
-// format.  It is legal for a MAC address sub-part to be empty, in which case
-// it will be treated as anyMAC (i.e., "00:00:00:00:00:00").
-func parseAddress(address string) (*addr, error) {
-	parts := strings.Split(address, "-")
-	if len(parts) != 2 {
-		return nil, fmt.Errorf("too many or too few \"-\" in address: %s", address)
-	}
-	ms := parts[0]
-	ps := parts[1]
-	if len(ms) == 0 {
-		channel, err := strconv.ParseInt(ps, 0, 32)
-		if err != nil {
-			return nil, err
-		}
-		return &addr{anyMAC, int(channel)}, nil
-	} else {
-		mac, err := net.ParseMAC(ms)
-		if err != nil {
-			return nil, err
-		}
-		channel, err := strconv.ParseInt(ps, 0, 32)
-		if err != nil {
-			return nil, err
-		}
-		return &addr{mac, int(channel)}, nil
-	}
-}
-
-// Implements the net.Addr interface.
-func (a *addr) Network() string {
-	return Network
-}
-
-// Implements the net.Addr interface.
-func (a *addr) String() string {
-	return fmt.Sprintf("%s-%d", a.mac, a.channel)
-}
-
-// isAnyMAC returns true iff the mac address is "any" (i.e.,
-// "00:00:00:00:00:00")
-func (a *addr) isAnyMAC() bool {
-	return bytes.Equal(a.mac, anyMAC)
-}
diff --git a/lib/bluetooth/addr_linux_test.go b/lib/bluetooth/addr_linux_test.go
deleted file mode 100644
index 303764e..0000000
--- a/lib/bluetooth/addr_linux_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import "testing"
-
-func TestParseValidAddr(t *testing.T) {
-	testdata := []struct{ before, after string }{
-		{"-1", "00:00:00:00:00:00-1"},
-		{"0A:0B:33:55:C9:9a-8", "0a:0b:33:55:c9:9a-8"},
-	}
-	for _, d := range testdata {
-		addr, err := parseAddress(d.before)
-		if err != nil {
-			t.Errorf("failed to parse %q: %v", d.before, err)
-			continue
-		}
-		if got, want := addr.String(), d.after; got != want {
-			t.Errorf("Got %q, want %q", got, want)
-		}
-	}
-}
-
-func TestParseInvalidAddr(t *testing.T) {
-	testdata := []string{
-		"00:01:02:03:04:05",      // missing channel
-		"00:01:02:03:04:05:06-1", // invalid MAC addr
-	}
-	for _, d := range testdata {
-		addr, err := parseAddress(d)
-		if err == nil {
-			t.Errorf("Got %q, want error for parseAddress(%q)", addr, d)
-		}
-	}
-}
diff --git a/lib/bluetooth/bluetooth_common.go b/lib/bluetooth/bluetooth_common.go
deleted file mode 100644
index d782914..0000000
--- a/lib/bluetooth/bluetooth_common.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package bluetooth
-
-import (
-	"net"
-	"time"
-
-	"veyron/lib/unit"
-)
-
-// Network string for net.Addr implementations used by the bluetooth
-// package.
-const Network = "bluetooth"
-
-// ScanReading holds a single reading of a Low-Energy scan on the Bluetooth device.
-type ScanReading struct {
-	// Name represents a local name of the remote device.  It can also store
-	// arbitrary application-specific data.
-	Name string
-	// MAC is the hardware address of the remote device.
-	MAC net.HardwareAddr
-	// Distance represents the (power-estimated) distance to the remote device.
-	Distance unit.Distance
-	// Time is the time the advertisement packed was received/scanned.
-	Time time.Time
-}
-
-// Device is a struct representing an opened Bluetooth device.  It consists of
-// a device name, MAC address, id (e.g., 0 for hci0, 1 for hci1 etc.) and a
-// device descriptor.
-// It is not safe to invoke this type's methods concurrently from multiple
-// goroutines.
-type Device struct {
-	Name       string
-	MAC        net.HardwareAddr
-	id         int
-	descriptor int
-	leScanChan chan ScanReading
-}
diff --git a/lib/bluetooth/bluetooth_linux.go b/lib/bluetooth/bluetooth_linux.go
deleted file mode 100644
index 248b40a..0000000
--- a/lib/bluetooth/bluetooth_linux.go
+++ /dev/null
@@ -1,357 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"fmt"
-	"math"
-	"net"
-	"syscall"
-	"time"
-	"unsafe"
-
-	"veyron/lib/unit"
-	"veyron2/vlog"
-)
-
-// // Explicitly link libbluetooth and other libraries as "go build" cannot
-// // figure out these dependencies..
-// #cgo LDFLAGS: -lbluetooth
-// #include <bluetooth/bluetooth.h>
-// #include <bluetooth/hci.h>
-// #include <bluetooth/hci_lib.h>
-// #include <stdlib.h>
-// #include <unistd.h>
-// #include "bt_linux.h"
-import "C"
-
-var (
-	// MaxLEAdvertisingPayloadSize denotes the maximum size for the
-	// LE advertising payload.
-	// See the Bluetooth 4.0 spec for more info on Bluetooth LE payload
-	// structure:
-	// https://www.bluetooth.org/en-us/specification/adopted-specifications
-	MaxLEAdvertisingPayloadSize = int(C.kMaxLEPayloadSize)
-
-	// MaxChannel represents the highest channel id that can be used
-	// for establishing RFCOMM connections.
-	MaxChannel = int(C.kMaxChannel)
-
-	// maxDevices denotes a maximum number of local devices to scan over
-	// when a particular device isn't explicitly specified (e.g.,
-	// OpenFirstAvailableDevice).
-	maxDevices = int(C.kMaxDevices)
-)
-
-// OpenDevice opens the Bluetooth device with a specified id, returning an
-// error if the device couldn't be opened, or nil otherwise.
-func OpenDevice(deviceID int) (*Device, error) {
-	if deviceID < 0 {
-		return nil, fmt.Errorf("negative device id, use OpenFirstAvailableDevice() instead")
-	}
-	var descriptor C.int
-	var name *C.char
-	var localMAC *C.char
-	if es := C.bt_open_device(C.int(deviceID), &descriptor, &name, &localMAC); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return nil, fmt.Errorf("error opening device %d: %s", deviceID, C.GoString(es))
-	}
-	defer C.free(unsafe.Pointer(name))
-	defer C.free(unsafe.Pointer(localMAC))
-	mac, err := net.ParseMAC(C.GoString(localMAC))
-	if err != nil {
-		return nil, fmt.Errorf("illegal hardware address %q for device %d: %s", C.GoString(localMAC), deviceID, err)
-	}
-	return &Device{
-		Name:       C.GoString(name),
-		MAC:        mac,
-		id:         deviceID,
-		descriptor: int(descriptor),
-	}, nil
-}
-
-// OpenFirstAvailableDevice() opens the first available bluetooth device,
-// returning an error if no device could be opened, or nil otherwise.
-func OpenFirstAvailableDevice() (*Device, error) {
-	for devID := 0; devID < maxDevices; devID++ {
-		if d, err := OpenDevice(devID); err == nil {
-			return d, nil
-		}
-	}
-	return nil, fmt.Errorf("can't find an available bluetooth device")
-}
-
-// Listen creates a new listener for RFCOMM connections on the provided
-// local address, specified in the <MAC-Channel> format (e.g.,
-// "01:23:45:67:89:AB-1").  Channel number 0 means pick the first available
-// channel.  Empty MAC address means pick the first available bluetooth device.
-// Error is returned if a listener cannot be created.
-// Note that the returned net.Listener won't use the runtime network poller
-// and hence a new OS thread will be created for every outstanding connection.
-func Listen(localAddr string) (net.Listener, error) {
-	local, err := parseAddress(localAddr)
-	if err != nil {
-		return nil, fmt.Errorf("listen error: invalid local address format %s, error: %s", localAddr, err)
-	}
-	if local.channel > MaxChannel {
-		return nil, fmt.Errorf("listen error: channel %d too large - max: %d", local.channel, MaxChannel)
-	}
-
-	// Open a new local bluetooth socket.
-	socket := C.socket(C.AF_BLUETOOTH, C.SOCK_STREAM, C.BTPROTO_RFCOMM)
-	if socket < 0 {
-		return nil, fmt.Errorf("listen error: can't open new RFCOMM socket")
-	}
-
-	// Bind to the local socket.
-	var localMAC *C.char
-	if !local.isAnyMAC() {
-		localMAC = C.CString(local.mac.String())
-	}
-	defer C.free(unsafe.Pointer(localMAC))
-	localChannel := C.int(local.channel)
-	if es := C.bt_bind(socket, &localMAC, &localChannel); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		syscall.Close(int(socket))
-		return nil, fmt.Errorf("listen error: %v", C.GoString(es))
-	}
-	// Re-parse the address as it may have changed.
-	if local.mac, err = net.ParseMAC(C.GoString(localMAC)); err != nil {
-		syscall.Close(int(socket))
-		return nil, fmt.Errorf("listen error: invalid local MAC address: %s, err: %v", C.GoString(localMAC), err)
-	}
-	local.channel = int(localChannel)
-
-	// Create a listener for incoming connections.
-	const maxPendingConnections = 100
-	if err = syscall.Listen(int(socket), maxPendingConnections); err != nil {
-		syscall.Close(int(socket))
-		return nil, fmt.Errorf("listen error: %v", err)
-	}
-	return newListener(int(socket), local)
-}
-
-// Dial creates a new RFCOMM connection with the remote address, specified in
-// the <MAC/Channel> format (e.g., "01:23:45:67:89:AB-1").  It returns an error
-// if the connection cannot be established.
-// Note that the returned net.Conn won't use the runtime network poller and
-// hence a new OS thread will be created for every outstanding connection.
-func Dial(remoteAddr string) (net.Conn, error) {
-	remote, err := parseAddress(remoteAddr)
-	if err != nil {
-		return nil, fmt.Errorf("dial error: invalid remote address format %s, error %s", remoteAddr, err)
-	}
-	if remote.isAnyMAC() {
-		return nil, fmt.Errorf("dial error: must specify remote MAC address: %s", remoteAddr)
-	}
-	if remote.channel > MaxChannel {
-		return nil, fmt.Errorf("dial error: channel %d too large - max: %d", remote.channel, MaxChannel)
-	}
-
-	// Open a new local bluetooth socket.
-	socket := C.socket(C.AF_BLUETOOTH, C.SOCK_STREAM, C.BTPROTO_RFCOMM)
-	if socket < 0 {
-		return nil, fmt.Errorf("dial error: can't open new RFCOMM socket")
-	}
-
-	// Bind to the local socket.
-	var localMAC *C.char     // bind to first available device
-	localChannel := C.int(0) // bind to first available channel
-	if es := C.bt_bind(socket, &localMAC, &localChannel); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		syscall.Close(int(socket))
-		return nil, fmt.Errorf("dial error: %v", C.GoString(es))
-	}
-	defer C.free(unsafe.Pointer(localMAC))
-	// Parse the local address.
-	var local addr
-	if local.mac, err = net.ParseMAC(C.GoString(localMAC)); err != nil {
-		return nil, fmt.Errorf("dial error: invalid local MAC address: %s, err: %s", C.GoString(localMAC), err)
-	}
-	local.channel = int(localChannel)
-
-	// Connect to the remote address.
-	remoteMAC := C.CString(remote.mac.String())
-	defer C.free(unsafe.Pointer(remoteMAC))
-	remoteChannel := C.int(remote.channel)
-	if es := C.bt_connect(socket, remoteMAC, remoteChannel); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return nil, fmt.Errorf("dial error: error connecting to remote address: %s, error: %s", remoteAddr, C.GoString(es))
-	}
-	return newConn(int(socket), &local, remote)
-}
-
-func (d *Device) String() string {
-	return fmt.Sprintf("BT_DEVICE(%s, %v)", d.Name, d.MAC)
-}
-
-// StartAdvertising starts LE advertising on the Bluetooth device, sending
-// one advertising packet after every tick of the provided time interval.
-// The payload sent with each advertising packet can be specified via the
-// SetAdvertisingPayload method.
-// This method may be called again even if advertising is currently enabled,
-// in order to adjust the advertising interval.
-func (d *Device) StartAdvertising(interval time.Duration) error {
-	if es := C.bt_start_le_advertising(C.int(d.descriptor), C.int(int64(interval/time.Millisecond))); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return fmt.Errorf("error starting LE advertising on device: %v, error: %s", d, C.GoString(es))
-	}
-	return nil
-}
-
-// SetAdvertisingPayload sets the advertising payload that is sent with each
-// advertising packet.  This function may be called at any time to adjust the
-// payload that is currently being advertised.
-func (d *Device) SetAdvertisingPayload(payload string) error {
-	if es := C.bt_set_le_advertising_payload(C.int(d.descriptor), C.CString(payload)); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return fmt.Errorf("error setting advertising payload on device: %v, error: %s", d, C.GoString(es))
-	}
-	return nil
-}
-
-// StopAdvertising stops LE advertising on the Bluetooth device.  If the
-// device is not advertising, this function will be a noop.
-func (d *Device) StopAdvertising() error {
-	if es := C.bt_stop_le_advertising(C.int(d.descriptor)); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return fmt.Errorf("error stopping LE advertising on device: %v, error: %s", d, C.GoString(es))
-	}
-	return nil
-}
-
-// StartScan initiates a Low-Energy scan on the Bluetooth device.  The scan
-// will proceed over many duration intervals; within each interval, scan will
-// be ON only for a given duration window.  All scan readings encountered
-// during scan-ON periods are pushed onto the returned channel.  If the scan
-// cannot be started, an error is returned.
-func (d *Device) StartScan(scanInterval, scanWindow time.Duration) (<-chan ScanReading, error) {
-	if scanInterval < scanWindow {
-		return nil, fmt.Errorf("invalid scan settings: scan interval %d must be greater or equal to scan window %d", scanInterval, scanWindow)
-	}
-	// Set scan params.
-	const (
-		passiveScan      = 0x00
-		publicAddress    = 0x00
-		acceptAllPackets = 0x00
-		timeoutMS        = 1000
-	)
-	if ret, err := C.hci_le_set_scan_parameters(C.int(d.descriptor), passiveScan, C.uint16_t(scanInterval/time.Millisecond), C.uint16_t(scanWindow/time.Millisecond), publicAddress, acceptAllPackets, timeoutMS); ret < 0 {
-		return nil, fmt.Errorf("error setting LE scan parameters: %v", err)
-	}
-	// Enable scan.
-	const (
-		scanEnabled               = 0x01
-		disableDuplicateFiltering = 0x00
-	)
-	if ret, err := C.hci_le_set_scan_enable(C.int(d.descriptor), scanEnabled, disableDuplicateFiltering, timeoutMS); ret < 0 {
-		return nil, fmt.Errorf("error enabling LE scan: %v", err)
-	}
-	// Set the event filter options.  We're only interested in LE meta
-	// events.
-	var fopts C.struct_hci_filter
-	C.hci_filter_clear(&fopts)
-	C.hci_filter_set_ptype(C.HCI_EVENT_PKT, &fopts)
-	C.hci_filter_set_event(C.EVT_LE_META_EVENT, &fopts)
-	if ret, err := C.setsockopt(C.int(d.descriptor), C.SOL_HCI, C.HCI_FILTER, unsafe.Pointer(&fopts), C.socklen_t(unsafe.Sizeof(fopts))); ret < 0 {
-		return nil, fmt.Errorf("couldn't set filter options on socket: %v", err)
-	}
-
-	// Start the reading go-routine.
-	d.leScanChan = make(chan ScanReading, 10)
-	go d.leScanLoop()
-	return d.leScanChan, nil
-}
-
-func (d *Device) leScanLoop() {
-	defer vlog.Info("LE scan reading goroutine exiting")
-	buf := make([]byte, C.HCI_MAX_EVENT_SIZE)
-	for {
-		// Read one advertising meta event.
-		n, err := syscall.Read(int(C.int(d.descriptor)), buf)
-		if err != nil || n < 0 {
-			vlog.Errorf("error getting scan readings: %v", err)
-			return
-		}
-		// Get data of interest to us.
-		var remoteMAC, remoteName *C.char
-		var rssi, done C.int
-		if es := C.bt_parse_le_meta_event(unsafe.Pointer(&buf[0]), &remoteMAC, &remoteName, &rssi, &done); es != nil {
-			vlog.Errorf("couldn't parse LE meta event: %s", C.GoString(es))
-			C.free(unsafe.Pointer(es))
-			continue
-		}
-		if done != 0 { // Scan stopped.
-			return
-		}
-		name := C.GoString(remoteName)
-		C.free(unsafe.Pointer(remoteName))
-		mac, err := net.ParseMAC(C.GoString(remoteMAC))
-		C.free(unsafe.Pointer(remoteMAC))
-		if err != nil {
-			vlog.Errorf("invalid MAC address: %v", mac)
-			continue
-		}
-		d.leScanChan <- ScanReading{
-			Name:     name,
-			MAC:      mac,
-			Distance: distanceFromRSSI(int(rssi)),
-			Time:     time.Now(),
-		}
-	}
-}
-
-// StopScan stops any Low-Energy scan in progress on the Bluetooth device.
-// If the device is not scanning, this function will be a noop.
-func (d *Device) StopScan() error {
-	// Disable scan.  This will also stop the reading goroutine.
-	const (
-		scanDisabled              = 0x00
-		disableDuplicateFiltering = 0x00
-		timeoutMS                 = 1000
-	)
-	if ret, err := C.hci_le_set_scan_enable(C.int(d.descriptor), scanDisabled, disableDuplicateFiltering, timeoutMS); ret < 0 {
-		return fmt.Errorf("error disabling LE scan: %v", err)
-	}
-
-	close(d.leScanChan)
-	return nil
-}
-
-// Close closes our handle on the Bluetooth device.  Note that this call doesn't
-// stop any operations in progress on the device (e.g., LE advertising) - it
-// simply closes the handle to it.
-func (d *Device) Close() error {
-	if es := C.bt_close_device(C.int(d.descriptor)); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		return fmt.Errorf("error closing device %v, error: %s", d, C.GoString(es))
-	}
-	return nil
-}
-
-// distanceFromRSSI computes the distance to the neighboring device using
-// the RSSI of that device's advertising packet.
-func distanceFromRSSI(rssi int) unit.Distance {
-	// We're using the formula (and observed constants) from the following
-	// paper:
-	//   "Outdoor Localization System Using RSSI Measurement of Wireless
-	//    Sensor Network"
-	//   by: Oguejiofor O.S., Okorogu V.N., Adewale Abe, and Osuesu B.O
-	//   link: http://www.ijitee.org/attachments/File/v2i2/A0359112112.pdf
-	//
-	// Formula:
-	//
-	//       RSSI [dBm] = -10n log10(d [m]) + A [dBm]
-	//
-	//, where:
-	//
-	//       A = received signal strength at 1m (observed to be -44.8dBm)
-	//       n = propagation pathloss exponent (observed to be 2.2)
-	//       d = distance (in meters)
-	//
-	// The final formula for distance (in meters) therefore comes down to:
-	//
-	//       d = 10^((RSSI / -22) - 2.036)
-	//
-	return unit.Distance(math.Pow(10.0, (float64(rssi)/-22.0)-2.036)) * unit.Meter
-}
diff --git a/lib/bluetooth/bluetooth_linux_test.go b/lib/bluetooth/bluetooth_linux_test.go
deleted file mode 100644
index 3b6a152..0000000
--- a/lib/bluetooth/bluetooth_linux_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"math"
-	"testing"
-
-	"veyron/lib/unit"
-)
-
-func TestDistanceFromRSSI(t *testing.T) {
-	testcases := []struct {
-		rssi int
-		dist unit.Distance
-	}{
-		{-45, 1 * unit.Meter},
-		{-50, 1 * unit.Meter},
-		{-55, 2 * unit.Meter},
-		{-60, 4 * unit.Meter},
-		{-65, 8 * unit.Meter},
-		{-70, 13 * unit.Meter},
-		{-80, 39 * unit.Meter},
-		{-90, 113 * unit.Meter},
-	}
-	for _, tc := range testcases {
-		d := distanceFromRSSI(tc.rssi)
-		if math.Trunc(d.Meters()) != tc.dist.Meters() {
-			t.Errorf("distanceFromRSSI(%d) = %v; want %v", tc.rssi, d, tc.dist)
-		}
-	}
-}
diff --git a/lib/bluetooth/bluetooth_other.go b/lib/bluetooth/bluetooth_other.go
deleted file mode 100644
index 5d5897e..0000000
--- a/lib/bluetooth/bluetooth_other.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// +build !veyronbluetooth !linux android
-
-package bluetooth
-
-import (
-	"errors"
-	"net"
-	"time"
-)
-
-var errNotSupported = errors.New("bluetooth is not supported on this platform")
-
-func (d *Device) StartScan(scanInterval, scanWindow time.Duration) (<-chan ScanReading, error) {
-	return nil, errNotSupported
-}
-func (d *Device) StopScan() error                                  { return errNotSupported }
-func (d *Device) Close() error                                     { return errNotSupported }
-func (d *Device) StartAdvertising(advInterval time.Duration) error { return errNotSupported }
-func (d *Device) SetAdvertisingPayload(payload string) error       { return errNotSupported }
-func (d *Device) StopAdvertising() error                           { return errNotSupported }
-
-// Dial always returns an error since bluetooth is not yet supported
-// on this platform.
-func Dial(remoteaddr string) (net.Conn, error) {
-	return nil, errNotSupported
-}
-
-// Listen always returns an error since bluetooth is not yet supported
-// on this platform.
-func Listen(localaddr string) (net.Listener, error) {
-	return nil, errNotSupported
-}
-
-// OpenFirstAvailableDevice always returns an error since bluetooth is
-// not yet supported on this platform.
-func OpenFirstAvailableDevice() (*Device, error) {
-	return nil, errNotSupported
-}
diff --git a/lib/bluetooth/bt_linux.c b/lib/bluetooth/bt_linux.c
deleted file mode 100644
index f4ea910..0000000
--- a/lib/bluetooth/bt_linux.c
+++ /dev/null
@@ -1,336 +0,0 @@
-// +build veyronbluetooth,!android
-
-#include "bt_linux.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-
-#define EIR_FLAGS                   0x01  /* flags */
-#define EIR_UUID16_SOME             0x02  /* 16-bit UUID, more available */
-#define EIR_UUID16_ALL              0x03  /* 16-bit UUID, all listed */
-#define EIR_UUID32_SOME             0x04  /* 32-bit UUID, more available */
-#define EIR_UUID32_ALL              0x05  /* 32-bit UUID, all listed */
-#define EIR_UUID128_SOME            0x06  /* 128-bit UUID, more available */
-#define EIR_UUID128_ALL             0x07  /* 128-bit UUID, all listed */
-#define EIR_NAME_SHORT              0x08  /* shortened local name */
-#define EIR_NAME_COMPLETE           0x09  /* complete local name */
-#define EIR_TX_POWER                0x0A  /* transmit power level */
-#define EIR_DEVICE_ID               0x10  /* device ID */
-
-// Timeout for all hci requests, in milliseconds.
-static const int kTimeoutMs = 1000;
-static const int kMaxAddrStrSize = 18;
-
-const int kMaxLEPayloadSize = 26;
-const int kMaxChannel = 30;
-const int kMaxDevices = 5;
-
-char* bt_open_device(int dev_id, int* dd, char** name, char** local_address) {
-  char* err = NULL;
-  int sock;
-  struct hci_dev_req dev_req;
-  struct hci_dev_info di;
-  bdaddr_t loc_addr;
-
-  if (dev_id < 0) {
-    asprintf(err, "can't pass negative device id for bt_open_device().");
-    return err;
-  }
-
-  // Open HCI socket.
-  if ((sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
-    asprintf(&err, "can't open HCI socket:%d[%s]", errno, strerror(errno));
-    return err;
-  }
-
-  // Get device's name.
-  di.dev_id = dev_id;
-  if (ioctl(sock, HCIGETDEVINFO, (void *)&di) < 0) {
-    asprintf(&err, "can't get device info:%d[%s]", errno, strerror(errno));
-    close(sock);
-    return err;
-  }
-  *name = (char*) malloc(strlen(di.name) * sizeof(char));
-  strcpy(*name, di.name);
-
-  // Try to open the specified device.
-  ioctl(sock, HCIDEVUP, dev_id);
-  *dd = hci_open_dev(dev_id);
-  if (*dd < 0) {
-    asprintf(&err, "can't open device %d:%d[%s]", dev_id, errno, strerror(errno));
-    close(sock);
-    return err;
-  }
-
-  // NOTE(spetrovic): We need to enable page scanning on the device for
-  // RFCOMM connections to work.  Since this requires root access, it will
-  // probably need to be done elsewhere (e.g., 'sudo hciconfig hci0 pscan').
-
-  // Get device's local MAC address.
-  hci_devba(dev_id, &loc_addr);
-  *local_address = (char*) malloc(kMaxAddrStrSize * sizeof(char));
-  ba2str(&loc_addr, *local_address);
-
-  return NULL;
-}
-
-char* bt_bind(int sock, char** local_address, int* channel) {
-  char* err = NULL;
-  int dev_id, dd;
-  struct sockaddr_rc addr = { 0 };
-
-  if (*local_address == NULL) {
-    char* name = NULL;
-    // Find the first available device.
-    for (dev_id = 0; dev_id < kMaxDevices; dev_id++) {
-      if ((err = bt_open_device(dev_id, &dd, &name, local_address)) != NULL) {
-        free(err);
-        continue;
-      }
-      bt_close_device(dd);
-      assert(*local_address != NULL);
-      if ((err = bt_bind(sock, local_address, channel)) != NULL) {
-        free(err);
-        free(*local_address);
-        continue;
-      }
-      return NULL;
-    }
-    asprintf(&err, "can't find an available bluetooth device");
-    return err;
-  } else if (*channel == 0) {
-    // Find the first available channel.
-    for (*channel = 1; *channel < kMaxChannel; (*channel)++) {
-      if ((err = bt_bind(sock, local_address, channel)) != NULL) {
-        free(err);
-        continue;
-      }
-      return NULL;
-    }
-    asprintf(&err, "can't find an available bluetooth channel");
-    return err;
-  } else {  // *local_address != NULL && *channel > 0
-    addr.rc_family = AF_BLUETOOTH;
-    str2ba(*local_address, &addr.rc_bdaddr);
-    addr.rc_channel = (uint8_t) *channel;
-    if (bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
-      asprintf(&err, "can't bind to socket %d, addr %s, channel %d, error: %d[%s]",
-               sock, *local_address, *channel, errno, strerror(errno));
-      return err;
-    }
-    return NULL;
-  }
-}
-
-char* bt_accept(int sock, int* fd, char** remote_address) {
-  char* err = NULL;
-  struct sockaddr_rc remote_addr;
-  socklen_t opt = sizeof(remote_addr);
-
-  if ((*fd = accept(sock, (struct sockaddr *)&remote_addr, &opt)) < 0) {
-    asprintf(&err, "error accepting connection on socket %d, error: %d[%s]",
-             sock, errno, strerror(errno));
-    return err;
-  }
-  *remote_address = (char*) malloc(kMaxAddrStrSize * sizeof(char));
-  ba2str(&remote_addr.rc_bdaddr, *remote_address);
-
-  return NULL;
-}
-
-char* bt_connect(int sock, const char* remote_address, int remote_channel) {
-  char* err = NULL;
-  struct sockaddr_rc remote_addr = { 0 };
-
-  remote_addr.rc_family = AF_BLUETOOTH;
-  str2ba(remote_address, &remote_addr.rc_bdaddr);
-  remote_addr.rc_channel = (uint8_t) remote_channel;
-  if (connect(sock, (struct sockaddr*) &remote_addr, sizeof(remote_addr)) < 0) {
-    asprintf(&err, "can't connect to remote address %s and channel %d "
-             "on socket %d: %d[%s]", remote_address, remote_channel,
-             sock, errno, strerror(errno));
-    return err;
-  }
-  return NULL;
-}
-
-char* bt_close_device(int dd) {
-  char* err = NULL;
-  if (hci_close_dev(dd) < 0) {
-    asprintf(&err, "can't close device with dd: %d, error: %d[%s]", dd, errno, strerror(errno));
-    return err;
-  }
-  return NULL;
-}
-
-char* bt_enable_le_advertising(int dd, int enable) {
-  char* err = NULL;
-  struct hci_request req;
-  le_set_advertise_enable_cp adv_enable_cp;
-  uint8_t status;
-
-  memset(&adv_enable_cp, 0, sizeof(adv_enable_cp));
-  adv_enable_cp.enable = enable;
-
-  memset(&req, 0, sizeof(req));
-  req.ogf = OGF_LE_CTL;
-  req.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
-  req.cparam = &adv_enable_cp;
-  req.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
-  req.rparam = &status;
-  req.rlen = 1;
-
-  if (hci_send_req(dd, &req, kTimeoutMs) < 0) {
-    asprintf(&err,
-             "can't enable/disable advertising for dd: %d, status: %d, error: %d",
-             dd, status, errno);
-    return err;
-  }
-  return NULL;
-}
-
-char* bt_start_le_advertising(int dd, int adv_interval_ms) {
-  char* err = NULL;
-  struct hci_request req;
-  le_set_advertising_parameters_cp adv_params_cp;
-  le_set_advertise_enable_cp adv_enable_cp;
-  uint8_t status;
-
-  // Set advertising params.
-  memset(&adv_params_cp, 0, sizeof(adv_params_cp));
-  adv_params_cp.min_interval = adv_interval_ms;
-  adv_params_cp.max_interval = adv_interval_ms;
-  adv_params_cp.advtype = 0x00;  // Connectable undirected advertising.
-  adv_params_cp.chan_map = 7;
-
-  memset(&req, 0, sizeof(req));
-  req.ogf = OGF_LE_CTL;
-  req.ocf = OCF_LE_SET_ADVERTISING_PARAMETERS;
-  req.cparam = &adv_params_cp;
-  req.clen = LE_SET_ADVERTISING_PARAMETERS_CP_SIZE;
-  req.rparam = &status;
-  req.rlen = 1;
-
-  if (hci_send_req(dd, &req, kTimeoutMs) < 0) {
-    asprintf(&err,
-             "can't set advertising params for dd: %d, status: %d, error: %d",
-             dd, status, errno);
-    return err;
-  }
-
-  // Start advertising.
-  return bt_enable_le_advertising(dd, 1);
-}
-
-char* bt_set_le_advertising_payload(int dd, char* adv_payload) {
-  char* err = NULL;
-  int idx;
-  struct hci_request req;
-  le_set_advertising_data_cp adv_data_cp;
-  uint8_t status;
-
-  if (strlen(adv_payload) > kMaxLEPayloadSize) {
-    asprintf(&err, "payload too big");
-    return err;
-  }
-
-  // Set advertising data.
-  memset(&adv_data_cp, 0, sizeof(adv_data_cp));
-  idx = 0;
-  adv_data_cp.data[idx++] = 2;
-  adv_data_cp.data[idx++] = EIR_FLAGS;
-  adv_data_cp.data[idx++] = 0x06;  // general discoverable+BR/EDR Not Supported
-  adv_data_cp.data[idx++] = strlen(adv_payload) + 1;
-  adv_data_cp.data[idx++] = EIR_NAME_COMPLETE;
-  memcpy(&adv_data_cp.data[idx], adv_payload, strlen(adv_payload));
-  idx += strlen(adv_payload);
-  adv_data_cp.length = idx;
-
-  memset(&req, 0, sizeof(req));
-  req.ogf = OGF_LE_CTL;
-  req.ocf = OCF_LE_SET_ADVERTISING_DATA;
-  req.cparam = &adv_data_cp;
-  req.clen = LE_SET_ADVERTISING_DATA_CP_SIZE;
-  req.rparam = &status;
-  req.rlen = 1;
-
-  if (hci_send_req(dd, &req, kTimeoutMs) < 0) {
-    asprintf(&err,
-             "can't set advertising data for dd: %d, status: %d, error: %d\n",
-             dd, status, errno);
-    return err;
-  }
-  return NULL;
-}
-
-char* bt_stop_le_advertising(int dd) {
-  return bt_enable_le_advertising(dd, 0);
-}
-
-char* bt_parse_le_meta_event(
-    void* data, char** remote_addr, char** remote_name, int* rssi, int* done) {
-  char *err, *ptr, *end;
-  evt_le_meta_event* meta_event;
-  le_advertising_info* adv_info;
-
-  *done = 0;
-  meta_event = (evt_le_meta_event*) (data + 1 + HCI_EVENT_HDR_SIZE);
-  if (meta_event->subevent == 0x01 /* LE Connection Complete Event */) {
-    // This event is triggered when scan is disabled.
-    *done = 1;
-    return NULL;
-  } else if (meta_event->subevent != 0x02 /* LE Advertising Report Event */) {
-    asprintf(&err, "wrong event type: %d", meta_event->subevent);
-    return err;
-  }
-
-  adv_info = (le_advertising_info*) (meta_event->data + 1);
-  *remote_addr = malloc(kMaxAddrStrSize * sizeof(char));
-  ba2str(&adv_info->bdaddr, *remote_addr);
-  *rssi = *((int8_t*) adv_info->data + adv_info->length);
-
-  // Extract name.
-  // Max possible advertising data length, as defined by the standard.
-  // The actual maximum name length was observed to be less than that, but
-  // this value will do.
-  const int kMaxNameLength = 31;
-  *remote_name = malloc(kMaxNameLength * sizeof(char));
-  memset(*remote_name, 0, kMaxNameLength);
-  ptr = adv_info->data;
-  end = adv_info->data + adv_info->length;
-
-  // Go through all advertising data packets in the response.
-  while (ptr < end) {
-    int adv_data_length = *(ptr++);  // includes adv_data_type below.
-    int adv_data_type;
-    if (adv_data_length == 0) {  // end of response.
-      break;
-    } else if ((ptr + adv_data_length) > end) {
-      // Illegal adv_data length.
-      break;
-    }
-    adv_data_type = *(ptr++);
-    switch (adv_data_type) {
-      case EIR_NAME_SHORT:
-      case EIR_NAME_COMPLETE:
-        if (adv_data_length - 1 > kMaxNameLength) {
-          // Illegal name length.
-          break;
-        }
-        memcpy(*remote_name, ptr, adv_data_length - 1);
-        break;
-    }
-    ptr += adv_data_length - 1;
-  }
-  return NULL;
-}
diff --git a/lib/bluetooth/bt_linux.h b/lib/bluetooth/bt_linux.h
deleted file mode 100644
index 2e215d9..0000000
--- a/lib/bluetooth/bt_linux.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// +build veyronbluetooth,!android
-
-#include <stdlib.h>
-
-// Maximum allowed LE payload size. See the Bluetooth 4.0 spec for more info on
-// Bluetooth LE payload structure:
-//   https://www.bluetooth.org/en-us/specification/adopted-specifications
-const int kMaxLEPayloadSize;
-// The highest bluetooth channel that can be used for establishing RFCOMM
-// connections.
-const int kMaxChannel;
-
-// Maximum number of local devices to scan over when a particular device isn't
-// explicitly specified.
-const int kMaxDevices;
-
-// Opens the bluetooth device with the provided id, storing its device
-// descriptor into '*dd', its device name into '*name', and its MAC address
-// into '*local_address'.
-// Returns an error string if any error is encoutered.  If a non-NULL error
-// string is returned, the caller must free it.
-// The caller must free '*name' and '*local_address' strings whenever a NULL
-// error string is returned.
-// REQUIRES: dev_id >= 0
-char* bt_open_device(int dev_id, int* dd, char** name, char** local_address);
-
-// Closes the (previously opened) device with the given device descriptor.
-// Returns error string on failure, or NULL otherwise.  If a non-NULL error
-// string is returned, the caller must free it.
-char* bt_close_device(int dd);
-
-// Binds the given socket to the provided MAC address/channel.  If '*local_address'
-// is NULL, it will bind to the first available bluetooth device and overwrite
-// '*local_address' to contain that device's MAC address.  If '*channel' is zero,
-// it will bind to the first available channel on a given device and overwrite
-// '*channel' to contain that channel value.  (If both of the above are true, we will
-// find the first device/channel pair that works and overwrite both values.)
-// Returns an error string if any error is encoutered.  If a non-NULL error
-// string is returned, the caller must free it.
-// The caller must free '*local_address' string whenever a NULL value was passed
-// in and a NULL error string is returned.
-char* bt_bind(int sock, char** local_address, int* channel);
-
-// Accepts the next connection on the provided socket.  Stores the file
-// descriptor for the newly established connection into 'fd', and the MAC
-// address of the remote party into 'remote_address".  Returns an error string
-// if any error is encountered.  If a non-NULL error string is returned, the
-// caller must free it.
-// The caller must free '*remote_address' string whenever a NULL error string
-// is returned.
-char* bt_accept(int sock, int* fd, char** remote_address);
-
-// Connects to the remote address/channel pair, using the provided local socket.
-// Returns an error string if any error is encountered.  If a non-NULL error
-// string is returned, the caller must free it.
-char* bt_connect(int sock, const char* remote_address, int remote_channel);
-
-// Starts bluetooth LE advertising on the provided device descriptor, sending
-// one advertising packet every 'adv_interval_ms' milliseconds.
-// Returns error string on failure, or NULL otherwise.  If a non-NULL error
-// string is returned, the caller must free it.
-char* bt_start_le_advertising(int dd, int adv_interval_ms);
-
-// Sets the advertising payload that is sent with each advertising packet.
-// This function may be called at any time to adjust the payload that is
-// currently being advertised.
-// Returns error string on failure, or NULL otherwise.  If a non-NULL error
-// string is returned, the caller must free it.
-char* bt_set_le_advertising_payload(int dd, char* adv_payload);
-
-// Stops bluetooth LE advertising on the provided device descriptor.
-// Returns error string on failure, or NULL otherwise.  If a non-NULL error
-// string is returned, the caller must free it.
-char* bt_stop_le_advertising(int dd);
-
-// Parses the LE meta event, extracting remote address, name, and RSSI.  It also
-// checks whether the event is "LE Connection Complete Event", which indicates
-// that the scan has stopped, and writes the result of that check into 'done'.
-// Returns error if data cannot be parsed.  If a non-NULL error string
-// is returned, the caller must free it.
-char* bt_parse_le_meta_event(
-    void* data, char** remote_addr, char** remote_name, int* rssi, int* done);
diff --git a/lib/bluetooth/conn_linux.go b/lib/bluetooth/conn_linux.go
deleted file mode 100644
index 9b5a573..0000000
--- a/lib/bluetooth/conn_linux.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"fmt"
-	"net"
-	"syscall"
-	"time"
-)
-
-// conn represents one RFCOMM connection between two bluetooth devices.
-// It implements the net.Conn interface.
-type conn struct {
-	fd                    *fd
-	localAddr, remoteAddr net.Addr
-	readDeadline          time.Time
-	writeDeadline         time.Time
-}
-
-func newConn(sockfd int, local, remote net.Addr) (net.Conn, error) {
-	fd, err := newFD(sockfd)
-	if err != nil {
-		syscall.Close(sockfd)
-		return nil, err
-	}
-	return &conn{fd: fd, localAddr: local, remoteAddr: remote}, nil
-}
-
-func (c *conn) String() string {
-	return fmt.Sprintf("Bluetooth (%s) <--> (%s)", c.localAddr, c.remoteAddr)
-}
-
-// net.Conn interface methods
-func (c *conn) Read(p []byte) (n int, err error)   { return c.fd.Read(p) }
-func (c *conn) Write(p []byte) (n int, err error)  { return c.fd.Write(p) }
-func (c *conn) Close() error                       { return c.fd.Close() }
-func (c *conn) LocalAddr() net.Addr                { return c.localAddr }
-func (c *conn) RemoteAddr() net.Addr               { return c.remoteAddr }
-func (c *conn) SetReadDeadline(t time.Time) error  { return c.setSockoptTimeval(t, syscall.SO_RCVTIMEO) }
-func (c *conn) SetWriteDeadline(t time.Time) error { return c.setSockoptTimeval(t, syscall.SO_SNDTIMEO) }
-func (c *conn) SetDeadline(t time.Time) error {
-	if err := c.SetReadDeadline(t); err != nil {
-		return err
-	}
-	if err := c.SetWriteDeadline(t); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (c *conn) setSockoptTimeval(t time.Time, opt int) error {
-	fd, err := c.fd.Reference()
-	if err != nil {
-		return err
-	}
-	defer c.fd.ReleaseReference()
-	if timeout := getTimeout(t); timeout != nil {
-		return syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, opt, timeout)
-	}
-	return nil
-}
-
-// getTimeout returns timeout for socket read/write operations, given the
-// deadline specified as absolute time.  Return value nil indicates no timeout.
-// Return value 0 indicates that the read/write operation should timeout
-// immediately.
-func getTimeout(deadline time.Time) *syscall.Timeval {
-	if deadline.IsZero() {
-		return nil
-	}
-	d := deadline.Sub(time.Now())
-	if d < 0 {
-		ret := syscall.NsecToTimeval(0)
-		return &ret
-	}
-	ret := syscall.NsecToTimeval(d.Nanoseconds())
-	return &ret
-}
diff --git a/lib/bluetooth/conn_linux_test.go b/lib/bluetooth/conn_linux_test.go
deleted file mode 100644
index e6803e8..0000000
--- a/lib/bluetooth/conn_linux_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"runtime"
-	"syscall"
-	"testing"
-)
-
-// TestConnConcurrency attempts to tests that methods on the *conn type be
-// friendly to concurrent invocation. Unable to figure out a clean way to do
-// this, the author has resorted to just firing up a bunch of goroutines and
-// hoping that failures will manifest often.
-func TestConnConcurrency(t *testing.T) {
-	const (
-		// These numbers were tuned to make the test fail "often"
-		// without the accompanying change to conn.go in the commit
-		// that added this test on the machine that the author was
-		// using at the time.
-		nConcurrentReaders = 30
-		nConcurrentClosers = 10
-	)
-	mp := runtime.GOMAXPROCS(nConcurrentReaders)
-	defer runtime.GOMAXPROCS(mp)
-
-	pipe := func() (rfd, wfd int) {
-		var fds [2]int
-		if err := syscall.Pipe(fds[:]); err != nil {
-			t.Fatal(err)
-		}
-		return fds[0], fds[1]
-	}
-	rfd, wfd := pipe()
-	rConn, _ := newConn(rfd, nil, nil)
-	wConn, _ := newConn(wfd, nil, nil)
-	const (
-		bugs  = "bugs bunny"
-		daffy = "daffy duck"
-	)
-	rchan := make(chan string)
-	// Write a bunch of times
-	for i := 0; i < nConcurrentReaders; i++ {
-		go wConn.Write([]byte(bugs))
-	}
-	read := func() {
-		buf := make([]byte, len(bugs))
-		if n, err := rConn.Read(buf); err == nil {
-			rchan <- string(buf[:n])
-			return
-		}
-		rchan <- ""
-	}
-	// Fire up half the readers before Close
-	for i := 0; i < nConcurrentReaders; i += 2 {
-		go read()
-	}
-	// Fire up the closers (and attempt to reassign the file descriptors to
-	// something new).
-	for i := 0; i < nConcurrentClosers; i++ {
-		go func() {
-			rConn.Close()
-			// Create new FDs, which may re-use the closed file descriptors
-			// and write something else to them.
-			rfd, wfd := pipe()
-			syscall.Write(wfd, []byte(daffy))
-			syscall.Close(wfd)
-			syscall.Close(rfd)
-		}()
-	}
-	// And then the remaining readers
-	for i := 1; i < nConcurrentReaders; i += 2 {
-		go read()
-	}
-	// Now read from the channel, should either see full bugs bunnies or empty strings.
-	nEmpty := 0
-	for i := 0; i < nConcurrentReaders; i++ {
-		got := <-rchan
-		switch {
-		case len(got) == 0:
-			nEmpty++
-		case got != bugs:
-			t.Errorf("Read %q, wanted %q or empty string", got, bugs)
-		}
-	}
-	t.Logf("Read returned non-empty %d/%d times", (nConcurrentReaders - nEmpty), nConcurrentReaders)
-}
diff --git a/lib/bluetooth/doc.go b/lib/bluetooth/doc.go
deleted file mode 100644
index b1d0622..0000000
--- a/lib/bluetooth/doc.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// Package bluetooth provides methods for interacting with attached bluetooth
-// devices.
-package bluetooth
diff --git a/lib/bluetooth/fd_linux.go b/lib/bluetooth/fd_linux.go
deleted file mode 100644
index 57b6e27..0000000
--- a/lib/bluetooth/fd_linux.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-// #include <stddef.h>
-// #include <sys/eventfd.h>
-// #include <sys/select.h>
-//
-// int add_to_eventfd(int fd) {
-//	uint64_t val = 1;
-//	return write(fd, &val, 8);
-// }
-//
-// int wait(int eventfd, int readfd, int writefd) {
-//	fd_set readfds, writefds;
-//	FD_ZERO(&readfds);
-//	FD_ZERO(&writefds);
-//	fd_set* writefdsp = NULL;
-//
-//	FD_SET(eventfd, &readfds);
-//	int nfds = eventfd + 1;
-//
-//	if (readfd >= 0) {
-//		FD_SET(readfd, &readfds);
-//		if (readfd >= nfds) {
-//			nfds = readfd + 1;
-//		}
-//	}
-//	if (writefd >= 0) {
-//		FD_SET(writefd, &writefds);
-//		if (writefd >= nfds) {
-//			nfds = writefd + 1;
-//		}
-//		writefdsp = &writefds;
-//	}
-//	// TODO(ashankar): Should EINTR be handled by a retry?
-//	// See "Select Law" section of "man 2 select_tut".
-//	int nready = select(nfds, &readfds, writefdsp, NULL, NULL);
-//	if (nready < 0) {
-//	  return nready;
-//	}
-//	return (readfd >= 0 && FD_ISSET(readfd, &readfds)) ||
-//	       (writefd >= 0 && FD_ISSET(writefd, &writefds));
-// }
-import "C"
-
-import (
-	"fmt"
-	"io"
-	"sync"
-	"syscall"
-)
-
-// An fd enables concurrent invocations of Read, Write and Close on a file
-// descriptor.
-//
-// It ensures that read, write and close operations do not conflict and thereby
-// avoids races between file descriptors being closed and re-used while a
-// read/write is being initiated.
-//
-// This is achieved by using an eventfd to signal the intention to close a
-// descriptor and a select over the eventfd and the file descriptor being
-// protected.
-type fd struct {
-	mu              sync.Mutex
-	datafd, eventfd C.int
-	closing         bool       // Whether Close has been or is being invoked.
-	done            *sync.Cond // Signaled when no Read or Writes are pending.
-	refcnt          int
-}
-
-// newFD creates an fd object providing read, write and close operations
-// over datafd that are not hostile to concurrent invocations.
-func newFD(datafd int) (*fd, error) {
-	eventfd, err := C.eventfd(0, C.EFD_CLOEXEC)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create eventfd: %v", err)
-	}
-	ret := &fd{datafd: C.int(datafd), eventfd: eventfd}
-	ret.done = sync.NewCond(&ret.mu)
-	return ret, nil
-}
-
-func (fd *fd) Read(p []byte) (int, error) {
-	e, d, err := fd.prepare()
-	if err != nil {
-		return 0, err
-	}
-	defer fd.finish()
-	if err := wait(e, d, -1); err != nil {
-		return 0, err
-	}
-	return fd.rw(syscall.Read(int(fd.datafd), p))
-}
-
-func (fd *fd) Write(p []byte) (int, error) {
-	e, d, err := fd.prepare()
-	if err != nil {
-		return 0, err
-	}
-	defer fd.finish()
-	if err := wait(e, -1, d); err != nil {
-		return 0, err
-	}
-	return fd.rw(syscall.Write(int(fd.datafd), p))
-}
-
-// RunWhenReadable invokes f(file descriptor) when the file descriptor is ready
-// to be read. It returns an error if the file descriptor has been closed
-// either before or while this method is being invoked.
-//
-// f must NOT close readfd.
-func (fd *fd) RunWhenReadable(f func(readfd int)) error {
-	e, d, err := fd.prepare()
-	if err != nil {
-		return err
-	}
-	defer fd.finish()
-	if err := wait(e, d, -1); err != nil {
-		return err
-	}
-	f(int(d))
-	return nil
-}
-
-// Reference returns the underlying file descriptor and ensures that calls to
-// Close will block until ReleaseReference has been called.
-//
-// Clients must NOT close the returned file descriptor.
-func (fd *fd) Reference() (int, error) {
-	fd.mu.Lock()
-	defer fd.mu.Unlock()
-	if fd.closing {
-		return -1, fmt.Errorf("closing")
-	}
-	if fd.datafd < 0 {
-		return -1, fmt.Errorf("closed")
-	}
-	fd.refcnt++
-	return int(fd.datafd), nil
-}
-
-// ReleaseReference returns a reference to the file descriptor grabbed by a
-// call to Reference, thereby unblocking any Close operations.
-func (fd *fd) ReleaseReference() { fd.finish() }
-
-// helper method for Read and Write that ensures:
-// - the returned 'n' is always >= 0, as per guidelines for the io.Reader and
-//   io.Writer interfaces.
-func (fd *fd) rw(n int, err error) (int, error) {
-	if n == 0 && err == nil {
-		err = io.EOF
-	}
-	if n < 0 {
-		n = 0
-	}
-	return n, err
-}
-
-func (fd *fd) prepare() (eventfd, datafd C.int, err error) {
-	fd.mu.Lock()
-	defer fd.mu.Unlock()
-	if fd.closing {
-		return 0, 0, fmt.Errorf("closing")
-	}
-	fd.refcnt++
-	// returned file descriptors are guaranteed to be
-	// valid till refcnt is reduced by at least 1, since
-	// Close waits for the refcnt to go down to zero before
-	// closing these file descriptors.
-	return fd.eventfd, fd.datafd, nil
-}
-
-func wait(eventfd, readfd, writefd C.int) error {
-	ok, err := C.wait(eventfd, readfd, writefd)
-	if err != nil {
-		return err
-	}
-	if ok <= 0 {
-		return fmt.Errorf("closing")
-	}
-	return nil
-}
-
-func (fd *fd) finish() {
-	fd.mu.Lock()
-	fd.refcnt--
-	if fd.closing && fd.refcnt == 0 {
-		fd.done.Broadcast()
-	}
-	fd.mu.Unlock()
-}
-
-func (fd *fd) Close() error {
-	fd.mu.Lock()
-	defer fd.mu.Unlock()
-	if !fd.closing {
-		// Send an "event" to notify of closures.
-		if _, err := C.add_to_eventfd(fd.eventfd); err != nil {
-			return fmt.Errorf("failed to notify closure on eventfd: %v", err)
-		}
-		// Prevent any new Read/Write/RunWhenReadable calls from starting.
-		fd.closing = true
-	}
-	for fd.refcnt > 0 {
-		fd.done.Wait()
-	}
-	// At this point, there are no concurrent Read/Write/RunWhenReadable
-	// calls that are using the file descriptors.
-	if fd.eventfd > 0 {
-		if err := syscall.Close(int(fd.eventfd)); err != nil {
-			return fmt.Errorf("failed to close eventfd: %v", err)
-		}
-		fd.eventfd = -1
-	}
-	if fd.datafd > 0 {
-		if err := syscall.Close(int(fd.datafd)); err != nil {
-			return fmt.Errorf("failed to close underlying socket/filedescriptor: %v", err)
-		}
-		fd.datafd = -1
-	}
-	return nil
-}
diff --git a/lib/bluetooth/fd_linux_test.go b/lib/bluetooth/fd_linux_test.go
deleted file mode 100644
index 7b4e359..0000000
--- a/lib/bluetooth/fd_linux_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"fmt"
-	"io"
-	"sort"
-	"syscall"
-	"testing"
-	"time"
-)
-
-// mkfds returns two *fds, one on which Read can be called and one on which
-// Write can be called by using the pipe system call. This pipe is a cheap
-// approximation of a file descriptor backed by a network socket that the fd type
-// is really intended for.
-func mkfds() (readfd, writefd *fd, err error) {
-	var fds [2]int
-	if err = syscall.Pipe(fds[:]); err != nil {
-		err = fmt.Errorf("syscall.Pipe failed: %v", err)
-		return
-	}
-	if readfd, err = newFD(fds[0]); err != nil {
-		err = fmt.Errorf("newFD failed for readfd: %v", err)
-		return
-	}
-	if writefd, err = newFD(fds[1]); err != nil {
-		err = fmt.Errorf("newFD failed for writefd: %v", err)
-		return
-	}
-	return
-}
-
-// canClose calls fd.Close and returns true if fd.Close returns.
-// It returns false if fd.Close blocks.
-// This function uses time to guess whether fd.Close is blocked or
-// not, and is thus not the most accurate implementation. The author
-// welcomes advice on restructuring this function or tests involving
-// it to make the testing deterministically accurate.
-func canClose(fd *fd) bool {
-	c := make(chan error)
-	go func() {
-		c <- fd.Close()
-	}()
-	select {
-	case <-c:
-		return true
-	case <-time.After(time.Millisecond):
-		return false
-	}
-}
-
-func TestFDBasic(t *testing.T) {
-	rfd, wfd, err := mkfds()
-	if err != nil {
-		t.Fatal(err)
-	}
-	const batman = "batman"
-	if n, err := wfd.Write([]byte(batman)); n != 6 || err != nil {
-		t.Errorf("Got (%d, %v) want (6, nil)", n, err)
-	}
-	var read [1024]byte
-	if n, err := rfd.Read(read[:]); n != 6 || err != nil || string(read[:n]) != string(batman) {
-		t.Errorf("Got (%d, %v) = %q, want (6, nil) = %q", n, err, read[:n], batman)
-	}
-	if err := rfd.Close(); err != nil {
-		t.Error(err)
-	}
-	if err := wfd.Close(); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestFDReference(t *testing.T) {
-	fd, _, err := mkfds()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if _, err := fd.Reference(); err != nil {
-		t.Fatal(err)
-	}
-	if canClose(fd) {
-		t.Errorf("Should not be able to close fd since there is an outstanding reference")
-	}
-	fd.ReleaseReference()
-	if !canClose(fd) {
-		t.Errorf("Should be able to close fd since there are no outstanding references")
-	}
-}
-
-func TestFDReadEOF(t *testing.T) {
-	rfd, wfd, err := mkfds()
-	if err != nil {
-		t.Fatal(err)
-	}
-	const (
-		bugs  = "bugs"
-		bunny = "bunny"
-	)
-	if n, err := wfd.Write([]byte(bugs)); n != len(bugs) || err != nil {
-		t.Fatalf("Got (%d, %v) want (%d, nil)", n, err, len(bugs))
-	}
-	if n, err := wfd.Write([]byte(bunny)); n != len(bunny) || err != nil {
-		t.Fatalf("Got (%d, %v) want (%d, nil)", n, err, len(bunny))
-	}
-	if err := wfd.Close(); err != nil {
-		t.Fatal(err)
-	}
-	var read [1024]byte
-	if n, err := rfd.Read(read[:]); n != len(bugs)+len(bunny) || err != nil {
-		t.Errorf("Got (%d, %v) = %q, want (%d, nil) = %q", n, err, read[:n], len(bugs)+len(bunny), "bugsbunny")
-	}
-	if n, err := rfd.Read(read[:]); n != 0 || err != io.EOF {
-		t.Errorf("Got (%d, %v) = %q, want (0, EOF)", n, err, read[:n])
-	}
-}
-
-func TestFDReadLessThanReady(t *testing.T) {
-	rfd, wfd, err := mkfds()
-	if err != nil {
-		t.Fatal(err)
-	}
-	const nbytes = 20
-	rchan := make(chan int, nbytes)
-	written := make([]byte, nbytes)
-	for i := 1; i <= nbytes; i++ {
-		written[i-1] = byte(i)
-		go func() {
-			var buf [1]byte
-			rfd.Read(buf[:])
-			rchan <- int(buf[0])
-		}()
-	}
-	if n, err := wfd.Write(written); n != nbytes || err != nil {
-		t.Fatal("Got (%d, %v), want (%d, nil)", n, err, nbytes)
-	}
-	if err := wfd.Close(); err != nil {
-		t.Fatal(err)
-	}
-	read := make([]int, nbytes)
-	for i := 0; i < nbytes; i++ {
-		read[i] = <-rchan
-	}
-	sort.Ints(read)
-	for i, v := range read {
-		if i != v-1 {
-			t.Fatalf("Got %v, wanted it to be sorted", read)
-		}
-	}
-}
diff --git a/lib/bluetooth/listener_linux.go b/lib/bluetooth/listener_linux.go
deleted file mode 100644
index c951baa..0000000
--- a/lib/bluetooth/listener_linux.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// +build veyronbluetooth,!android
-
-package bluetooth
-
-import (
-	"fmt"
-	"net"
-	"unsafe"
-)
-
-// // Explicitly link libbluetooth and other libraries as "go build" cannot
-// // figure out these dependencies..
-// #cgo LDFLAGS: -lbluetooth
-// #include <stdlib.h>
-// #include <unistd.h>
-// #include "bt_linux.h"
-import "C"
-
-// listener waits for incoming RFCOMM connections on the provided socket.
-// It implements the net.Listener interface.
-type listener struct {
-	fd         *fd
-	acceptChan chan (acceptResult)
-	localAddr  net.Addr
-}
-
-type acceptResult struct {
-	conn net.Conn
-	err  error
-}
-
-func newListener(sockfd int, addr net.Addr) (net.Listener, error) {
-	fd, err := newFD(sockfd)
-	if err != nil {
-		return nil, err
-	}
-	return &listener{fd: fd, acceptChan: make(chan acceptResult), localAddr: addr}, nil
-}
-
-// Implements the net.Listener interface.
-func (l *listener) Accept() (net.Conn, error) {
-	go l.fd.RunWhenReadable(l.accept)
-	r := <-l.acceptChan
-	return r.conn, r.err
-}
-
-func (l *listener) accept(sockfd int) {
-	var fd C.int
-	var remoteMAC *C.char
-	var result acceptResult
-	defer func() { l.acceptChan <- result }()
-	if es := C.bt_accept(C.int(sockfd), &fd, &remoteMAC); es != nil {
-		defer C.free(unsafe.Pointer(es))
-		result.err = fmt.Errorf("error accepting connection on %s, socket: %d, error: %s", l.localAddr, sockfd, C.GoString(es))
-		return
-	}
-	defer C.free(unsafe.Pointer(remoteMAC))
-
-	// Parse remote address.
-	var remote addr
-	var err error
-	if remote.mac, err = net.ParseMAC(C.GoString(remoteMAC)); err != nil {
-		result.err = fmt.Errorf("invalid remote MAC address: %s, err: %s", C.GoString(remoteMAC), err)
-		return
-	}
-	// There's no way to get accurate remote channel number, so use 0.
-	remote.channel = 0
-	result.conn, result.err = newConn(int(fd), l.localAddr, &remote)
-}
-
-// Implements the net.Listener interface.
-func (l *listener) Close() error {
-	return l.fd.Close()
-}
-
-// Implements the net.Listener interface.
-func (l *listener) Addr() net.Addr {
-	return l.localAddr
-}
diff --git a/runtimes/google/ipc/jni/arg_getter.go b/runtimes/google/ipc/jni/arg_getter.go
index ef24b5d..5eb718e 100644
--- a/runtimes/google/ipc/jni/arg_getter.go
+++ b/runtimes/google/ipc/jni/arg_getter.go
@@ -5,12 +5,14 @@
 	"path"
 	"reflect"
 
+	"veyron.io/proximity/api/services/proximity"
+
 	// Imported VDLs.  Please add a link to all VDLs you care about here,
 	// and add all interfaces you care about to the init() function below.
 	"veyron/examples/fortune"
+
 	ctx "veyron2/context"
 	"veyron2/ipc"
-	"veyron2/services/proximity"
 )
 
 func init() {
diff --git a/runtimes/google/ipc/stream/manager/manager.go b/runtimes/google/ipc/stream/manager/manager.go
index 48824f3..1993a0f 100644
--- a/runtimes/google/ipc/stream/manager/manager.go
+++ b/runtimes/google/ipc/stream/manager/manager.go
@@ -8,7 +8,8 @@
 	"strings"
 	"sync"
 
-	"veyron/lib/bluetooth"
+	"veyron.io/proximity/lib/bluetooth"
+
 	"veyron/runtimes/google/ipc/stream/crypto"
 	"veyron/runtimes/google/ipc/stream/vif"
 	"veyron/runtimes/google/ipc/version"
diff --git a/services/gateway/gatewayd/main_linux.go b/services/gateway/gatewayd/main_linux.go
deleted file mode 100644
index 3025812..0000000
--- a/services/gateway/gatewayd/main_linux.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Binary gatewayd provides TCP/IP connectivity to devices that don't have it
-// by using their alternate connections (e.g., Bluetooth).  This binary
-// should be started on both connected and non-connected devices and it will
-// take an appropriate role depending on that device's configuration (i.e., it
-// will take on either a connectivity-giving or a connectivity-taking role).
-package main
-
-import (
-	"flag"
-	"fmt"
-	"os"
-
-	"veyron/lib/signals"
-
-	"veyron/services/gateway/lib"
-	"veyron2/rt"
-	"veyron2/vlog"
-)
-
-// TODO(spetrovic): Once the mounttable is finalized, get this endpoint by
-// traversing the device-wide mounttable, looking for the proximity service
-// name.
-var (
-	proximity   = flag.String("proximity", "", "Endpoint string for the proximity service, running on this device")
-	forceClient = flag.Bool("force_client", false, "Force this device to act as a client, for testing purposes")
-)
-
-func main() {
-	// TODO(cnicolaou): rt.Init also calls flag.Parse and has its own
-	// flags etc. We need to somehow expose those here so that a complete
-	// usage description can be provided by apps that have their own flags.
-	flag.Parse()
-	flag.Usage = func() {
-		fmt.Fprintf(os.Stderr, "%s: gateway daemon that brings TCP/IP connectivity to devices using their alternate connections (e.g., Bluetooth).", os.Args[0])
-		flag.PrintDefaults()
-	}
-
-	// Get the runtime.
-	r := rt.Init()
-	defer r.Cleanup()
-
-	// Create a new instance of the gateway service.
-	vlog.Info("Connecting to proximity service: ", *proximity)
-	g, err := gateway.New(*proximity, *forceClient)
-	if err != nil {
-		vlog.Errorf("couldn't create gateway service: %v", err)
-		return
-	}
-	defer g.Stop()
-
-	// Block until the process gets terminated (either by AppMgr or system).
-	<-signals.ShutdownOnSignals()
-}
diff --git a/services/gateway/lib/client_linux.go b/services/gateway/lib/client_linux.go
deleted file mode 100644
index a70ffd1..0000000
--- a/services/gateway/lib/client_linux.go
+++ /dev/null
@@ -1,287 +0,0 @@
-package gateway
-
-import (
-	"fmt"
-	"math"
-	"net"
-	"os/exec"
-	"strings"
-	"time"
-
-	"veyron/lib/unit"
-	"veyron2/rt"
-	"veyron2/services/proximity"
-	"veyron2/vlog"
-
-	dbus "github.com/guelfey/go.dbus"
-)
-
-// Bluetooth service UUID string for the NAP service.
-const napUUID = "0x1116"
-
-type device struct {
-	mac      net.HardwareAddr
-	distance unit.Distance
-	rtt      time.Duration
-}
-
-func (d *device) String() string {
-	return d.mac.String()
-}
-
-// affinity returns a value in the range [0, inf), indicating how beneficial
-// this device would be as a gateway.  When choosing gateways, smaller affinity
-// values are preferred to larger ones.
-func (d *device) affinity() float64 {
-	if d.rtt.Seconds() < 0 || d.distance.Millimeters() < 0 {
-		return math.Inf(1)
-	}
-	if d.distance.Millimeters() == 0 {
-		return 0
-	}
-	return d.rtt.Seconds() / d.distance.Millimeters()
-}
-
-type client struct {
-	proximity proximity.Proximity
-	conn      *dbus.Conn
-	done      chan bool
-}
-
-func newClient(p proximity.Proximity) (*client, error) {
-	c := &client{
-		proximity: p,
-		done:      make(chan bool),
-	}
-
-	// Connect to DBus and export a bluetooth agent.
-	var err error
-	if c.conn, err = dbus.SystemBus(); err != nil {
-		return nil, fmt.Errorf("couldn't access system dbus: %v", err)
-	}
-	if err = c.conn.Export(&yesAgent{}, agentPath, agentIface); err != nil {
-		return nil, fmt.Errorf("error exporting agent to dbus: %v", err)
-	}
-
-	// Start background loops.
-	go c.updateLoop()
-
-	return c, nil
-}
-
-func (c *client) Stop() {
-	c.conn.Export(nil, agentPath, agentIface)
-	close(c.done)
-}
-
-// updateLoop obtains a list of nearby devices from proximity service
-// and updates the local gateway, if needed.
-func (c *client) updateLoop() {
-	defer vlog.VI(1).Infof("device update loop exiting.")
-	t := time.Tick(1 * time.Second)
-	var gateway *net.HardwareAddr
-	var gatewayIface string
-	for {
-		select {
-		case <-c.done:
-			return
-		case <-t:
-		}
-
-		nearby, err := c.proximity.NearbyDevices(rt.R().TODOContext())
-		if err != nil {
-			vlog.Errorf("error getting nearby devices list: %v", err)
-			continue
-		}
-
-		// Find the device with the smallest affinity.
-		var d, g *device
-		min := math.Inf(1)
-		for _, n := range nearby {
-			mac, err := net.ParseMAC(n.MAC)
-			if err != nil {
-				vlog.Errorf("error parsing MAC address %q: %v", n.MAC, err)
-				continue
-			}
-			distance, err := unit.ParseDistance(n.Distance)
-			if err != nil {
-				vlog.Errorf("error parsing distance %q: %v", n.Distance, err)
-				continue
-			}
-			rtt, found := rttFromNames(n.Names)
-			if !found {
-				continue
-			}
-			dev := &device{
-				mac:      mac,
-				distance: distance,
-				rtt:      rtt,
-			}
-			if dev.affinity() < min {
-				d = dev
-				min = dev.affinity()
-			}
-			if gateway != nil && gateway.String() == dev.mac.String() {
-				g = dev
-			}
-		}
-
-		if shouldUpdateGateway(g, d) {
-			vlog.VI(1).Infof("connecting new gateway %q", d.mac)
-			if iface, err := c.connectDevice(d.mac); err == nil {
-				vlog.VI(1).Infof("connected")
-				if gateway != nil {
-					vlog.VI(1).Infof("disconnecting (old) gateway %q", *gateway)
-					c.disconnectDevice(*gateway)
-					vlog.VI(1).Infof("disconnected")
-				}
-				gateway = &d.mac
-				gatewayIface = iface
-			} else {
-				vlog.Errorf("couldn't connect to new gateway %q: %v", d, err)
-			}
-		}
-
-		// Test if the gateway is (still) functional and if not
-		// disconnect it.
-		if len(gatewayIface) > 0 && !testInterface(gatewayIface) {
-			// Gateway not functional - disconnect it.
-			vlog.VI(1).Infof("disconnecting non-functional gateway %q", *gateway)
-			c.disconnectDevice(*gateway)
-			gateway = nil
-			gatewayIface = ""
-		}
-	}
-}
-
-func (c *client) connectDevice(mac net.HardwareAddr) (string, error) {
-	// Find the local bluetooth adapter.
-	obj := c.conn.Object("org.bluez", dbus.ObjectPath("/"))
-	var adapterPath dbus.ObjectPath
-	if err := obj.Call("org.bluez.Manager.DefaultAdapter", 0).Store(&adapterPath); err != nil {
-		return "", fmt.Errorf("couldn't find bluetooth adapter: %v", err)
-	}
-	adapter := c.conn.Object("org.bluez", adapterPath)
-
-	// Create a new local device object corresponding to the remote device.
-	var devicePath dbus.ObjectPath
-	if err := adapter.Call("org.bluez.Adapter.FindDevice", 0, mac.String()).Store(&devicePath); err != nil {
-		// Local device object doesn't exist - create it.
-		if err := adapter.Call("org.bluez.Adapter.CreateDevice", 0, mac.String()).Store(&devicePath); err != nil {
-			return "", fmt.Errorf("couldn't create local device object %q: %v", mac, err)
-		}
-	}
-	// Re-discover the Network service for the remote device.  This will
-	// ensure that we have local bindings for the NAP-connect call below.
-	dev := c.conn.Object("org.bluez", devicePath)
-	if call := dev.Call("org.bluez.Device.DiscoverServices", 0, napUUID); call.Err != nil {
-		vlog.Errorf("couldn't (re)discover Network service for device %q: %v", mac, call.Err)
-	}
-
-	// Pair with the device.  We ignore any errors because an already-paired
-	// device returns it as well.  (Should the pairing legitimately fail,
-	// the NAP-connect method below will fail.)
-	adapter.Call("org.bluez.Adapter.CreatePairedDevice", 0, mac.String(), agentPath, "NoInputNoOutput")
-
-	// Disconnect the device for good measure, in case we are connected but
-	// don't know it. (This can happen if, for example, the server
-	// terminated the connection and it didn't get cleaned up correctly.)
-	c.disconnectDevice(mac)
-
-	// Establish (a new) NAP connection to the device.
-	var iface string
-	if err := dev.Call("org.bluez.Network.Connect", 0).Store(&iface); err != nil {
-		return "", fmt.Errorf("couldn't establish NAP connection to device %q: %v", mac, err)
-	}
-
-	// Start DHCP client.
-	cmd := exec.Command("dhcpcd", "-4", "-C", "resolv.conf", "-C", "mtu", iface)
-	if err := cmd.Run(); err != nil {
-		c.disconnectDevice(mac)
-		return "", fmt.Errorf("couldn't start dhcpcd for device %q: %v", mac, err)
-	}
-
-	return iface, nil
-}
-
-func (c *client) disconnectDevice(mac net.HardwareAddr) {
-	obj := c.conn.Object("org.bluez", dbus.ObjectPath("/"))
-	var adapterPath dbus.ObjectPath
-	if err := obj.Call("org.bluez.Manager.DefaultAdapter", 0).Store(&adapterPath); err != nil {
-		return
-	}
-	adapter := c.conn.Object("org.bluez", adapterPath)
-
-	var devicePath dbus.ObjectPath
-	if err := adapter.Call("org.bluez.Adapter.FindDevice", 0, mac.String()).Store(&devicePath); err != nil {
-		return
-	}
-
-	device := c.conn.Object("org.bluez", devicePath)
-	device.Call("org.bluez.Network.Disconnect", 0)
-}
-
-func shouldUpdateGateway(curg, newg *device) bool {
-	if newg == nil {
-		return false
-	}
-	if curg == nil {
-		return true
-	}
-	return curg.mac.String() != newg.mac.String() && curg.affinity() > 4*newg.affinity()
-}
-
-// testInterface tests that the provided interface has an assigned IP address
-// and is functional.
-func testInterface(iface string) bool {
-	vlog.VI(1).Infof("Testing interface %v", iface)
-	ip, err := gatewayIP(iface)
-	if err != nil {
-		vlog.VI(1).Infof("couldn't get gateway IP for iface %q: %v", iface, err)
-		return false
-	}
-
-	rtt, err := ping(ip)
-	if err != nil || len(rtt) == 0 {
-		vlog.VI(1).Infof("interface %q has no connectivity", iface)
-		return false
-	}
-	return true
-}
-
-// gatewayIP finds the address on "the other side" of the provided interface.
-func gatewayIP(iface string) (string, error) {
-	i, err := net.InterfaceByName(iface)
-	if err != nil {
-		return "", fmt.Errorf("couldn't find interface %q: %v", iface, err)
-	}
-	addrs, err := i.Addrs()
-	if err != nil {
-		return "", fmt.Errorf("couldn't get addresses for interface %q: %v", iface, err)
-	}
-	if len(addrs) == 0 {
-		return "", fmt.Errorf("interface %q has no addresses", iface)
-	}
-	var ip net.IP
-	for _, addr := range addrs {
-		if ipa, ok := addr.(*net.IPAddr); ok {
-			if ip4 := ipa.IP.To4(); ip4 != nil {
-				ip = ip4
-				break
-			}
-		}
-	}
-	if ip == nil {
-		return "", fmt.Errorf("no IP4 address for interface %q", iface)
-	}
-	return strings.Join(append(strings.Split(ip.String(), ".")[:3], "1"), "."), nil
-}
-
-func rttFromNames(names []string) (time.Duration, bool) {
-	for _, name := range names {
-		if rtt, err := rttFromName(name); err == nil {
-			return rtt, true
-		}
-	}
-	return 0, false
-}
diff --git a/services/gateway/lib/doc_linux.go b/services/gateway/lib/doc_linux.go
deleted file mode 100644
index b9d9001..0000000
--- a/services/gateway/lib/doc_linux.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Package gateway implements client and server methods that (1) allow a device
-// to act as an IP gateway and (2) allow devices without an IP connection to
-// obtain it via a gateway device.
-//
-// The main gateway functionality is achieved through the Bluetooth BNEP
-// protocol.  This protocol allows a virtual Ethernet connection to be
-// established between multiple Bluetooth devices.  We plugin the remaining
-// functionality (IP forwarding, DHCP) using standard Linux tools (e.g.,
-// route/dhcpd).  The current implementation is therefore platform-specific and
-// for now only supported on Linux.
-//
-// For the Bluetooth stack, we use Bluez 4.101 library along with standard
-// linux Bluetooth drivers.  As Bluez libraries go through extensive
-// non-backward-compatible changes, we require that this exact library version
-// is installed on target systems.  We use DBus to communicate with the Bluez
-// library.
-//
-// To configure the IP stack we use a number of standard Linux tools, namely:
-// awk, grep, cut, route, dhcpcd, and dhcpd.  These tools must be installed on
-// target systems and must be present in system's $PATH environmental variable.
-// We also rely on IP4 addressing and must revisit the implementation should
-// IPv6 become the only standard.
-package gateway
diff --git a/services/gateway/lib/gateway_linux.go b/services/gateway/lib/gateway_linux.go
deleted file mode 100644
index d7700e2..0000000
--- a/services/gateway/lib/gateway_linux.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package gateway
-
-import (
-	"fmt"
-
-	"veyron/lib/bluetooth"
-	"veyron2/services/proximity"
-	"veyron2/vlog"
-)
-
-var gatewayCmd = [][]string{
-	{"route"},
-	// TODO(spetrovic): Use Go's string libraries to reduce
-	// dependence on these tools.
-	{"grep", "UG[ \t]"},
-	{"grep", "^default"},
-	{"head", "-1"},
-	{"awk", `{printf "%s", $NF}`},
-}
-
-// New creates a new instance of the gateway service given the name of the
-// local proximity service.  Since the gateway server operates in two modes
-// (i.e., server and client) depending on whether it provides or obtains
-// internet connectivity, the provided boolean option lets us force a client
-// mode, which can be useful for testing.
-func New(proximityService string, forceClient bool) (*Service, error) {
-	// See if we have bluetooth on this device.
-	d, err := bluetooth.OpenFirstAvailableDevice()
-	if err != nil {
-		return nil, fmt.Errorf("no bluetooth devices found: %v", err)
-	}
-
-	// Find the default gateway interface.
-	gateway, err := runPipedCmd(gatewayCmd)
-	if err != nil {
-		gateway = ""
-	}
-
-	p, err := proximity.BindProximity(proximityService)
-	if err != nil {
-		return nil, fmt.Errorf("error connecting to proximity service %q: %v", proximityService, err)
-	}
-
-	// If gateway is present, start the server; otherwise, start the client.
-	s := new(Service)
-	if gateway == "" || forceClient {
-		vlog.Info("No IP interfaces detected: starting the gateway client.")
-		var err error
-		if s.client, err = newClient(p); err != nil {
-			return nil, fmt.Errorf("couldn't start gateway client: %v", err)
-		}
-	} else {
-		vlog.Infof("IP interface %q detected: starting the gateway server.", gateway)
-		if s.server, err = newServer(p, gateway, d.Name); err != nil {
-			return nil, fmt.Errorf("couldn't start gateway server: %v", err)
-		}
-	}
-	return s, nil
-}
-
-type Service struct {
-	client *client
-	server *server
-}
-
-// Stop stops the gateway service.
-func (s *Service) Stop() {
-	if s.client != nil {
-		s.client.Stop()
-	}
-	if s.server != nil {
-		s.server.Stop()
-	}
-}
diff --git a/services/gateway/lib/server_linux.go b/services/gateway/lib/server_linux.go
deleted file mode 100644
index a295647..0000000
--- a/services/gateway/lib/server_linux.go
+++ /dev/null
@@ -1,336 +0,0 @@
-package gateway
-
-import (
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"strconv"
-	"text/template"
-	"time"
-
-	"veyron2/rt"
-	"veyron2/services/proximity"
-	"veyron2/vlog"
-
-	dbus "github.com/guelfey/go.dbus"
-)
-
-const (
-	ipFwdFile  = "/proc/sys/net/ipv4/ip_forward"
-	pingTarget = "www.google.com"
-	bridgeName = "napbr0"
-	// TODO(spetrovic): Instead of statically assigned addresses, scan
-	// over all existing interfaces and find the one that's surely unused.
-	bridgeIPAddr        = "192.168.9.1"
-	bridgeIPSubnetShort = "192.168.9.0"
-	bridgeIPSubnetLong  = "192.168.9.0/24"
-	bridgeIPMask        = "255.255.255.0"
-	bridgeIPBroadcast   = "192.168.9.255"
-	bridgeDHCPStart     = "192.168.9.2"
-	bridgeDHCPEnd       = "192.168.9.254"
-	dhcpdTemplateStr    = `
-# dhcpd config for the NAP bridge interface {{.Bridge}}
-#
-# {{.Bridge}} ip addr is expected to be {{.IPAddr}}
-# serves {{.IPAddrStart}} - {{.IPAddrEnd}}
-
-authoritative;
-
-subnet {{.Subnet}} netmask {{.Netmask}} {
-  interface "{{.Bridge}}";
-  range {{.IPAddrStart}} {{.IPAddrEnd}};
-  option routers {{.IPAddr}};
-  option broadcast-address {{.Broadcast}};
-}`
-	bridgeUpTemplateStr = `
-#!/bin/bash
-# Script that creates and configures the bridge interface.
-
-brctl addbr {{.Bridge}}
-ifconfig {{.Bridge}} inet {{.BridgeAddr}} netmask {{.BridgeMask}} up
-`
-	bridgeDownTemplateStr = `
-#!/bin/bash
-# Script that creates and configures the bridge interface.
-
-ifconfig {{.Bridge}} down
-brctl delbr {{.Bridge}}
-`
-	natStartTemplateStr = `
-#!/bin/bash
-# Script that turns this server's NAT role on.
-cp -f {{.IPFwdFile}} {{.IPFwdFile}}.old
-echo "1" > {{.IPFwdFile}}
-iptables -t nat -A POSTROUTING -s {{.BridgeSubnet}} -j MASQUERADE
-iptables -A FORWARD -i {{.Bridge}} -o {{.Gateway}} -j ACCEPT
-iptables -A FORWARD -o {{.Bridge}} -i {{.Gateway}} -j ACCEPT
-`
-	natStopTemplateStr = `
-#!/bin/bash
-# Script that turns this server's NAT role off.
-cp -f {{.IPFwdFile}}.old {{.IPFwdFile}}
-iptables -t nat -D POSTROUTING -s {{.BridgeSubnet}} -j MASQUERADE
-iptables -D FORWARD -i {{.Bridge}} -o {{.Gateway}} -j ACCEPT
-iptables -D FORWARD -o {{.Bridge}} -i {{.Gateway}} -j ACCEPT
-`
-)
-
-var (
-	dhcpdConfig        string
-	dhcpdTemplate      = template.Must(template.New("dhcpd").Parse(dhcpdTemplateStr))
-	bridgeUpTemplate   = template.Must(template.New("bridgeUp").Parse(bridgeUpTemplateStr))
-	bridgeDownTemplate = template.Must(template.New("bridgeDown").Parse(bridgeDownTemplateStr))
-	natStartTemplate   = template.Must(template.New("natStart").Parse(natStartTemplateStr))
-	natStopTemplate    = template.Must(template.New("natStop").Parse(natStopTemplateStr))
-)
-
-func init() {
-	d := struct {
-		Bridge, IPAddr, IPAddrStart, IPAddrEnd, Subnet, Netmask, Broadcast string
-	}{
-		bridgeName, bridgeIPAddr, bridgeDHCPStart, bridgeDHCPEnd, bridgeIPSubnetShort, bridgeIPMask, bridgeIPBroadcast,
-	}
-	var err error
-	if dhcpdConfig, err = fileFromTemplate(dhcpdTemplate, d, 0644); err != nil {
-		panic(err)
-	}
-}
-
-func newServer(p proximity.Proximity, gateway, device string) (*server, error) {
-	s := &server{
-		proximity: p,
-		gateway:   gateway,
-		device:    device,
-		done:      make(chan bool),
-	}
-	err := s.configureBluetooth()
-	if err == nil {
-		err = s.bridgeUp()
-	}
-	if err == nil {
-		err = s.startNAT()
-	}
-	if err == nil {
-		err = s.startDHCP()
-	}
-	if err == nil {
-		err = s.startNAP()
-	}
-	if err != nil {
-		s.Stop()
-		return nil, err
-	}
-	go s.rttLoop()
-	return s, nil
-}
-
-type server struct {
-	proximity       proximity.Proximity
-	gateway, device string
-	dhcpCmd         *exec.Cmd
-	oldFwdVal       []byte
-	conn            *dbus.Conn
-	done            chan bool
-	advertisedName  string
-}
-
-func (s *server) Stop() {
-	s.stopNAP()
-	s.stopDHCP()
-	s.stopNAT()
-	s.bridgeDown()
-	close(s.done) // terminates rttLoop
-}
-
-func (s *server) bridgeUp() error {
-	d := struct {
-		Bridge, BridgeAddr, BridgeMask string
-	}{
-		bridgeName, bridgeIPAddr, bridgeIPMask,
-	}
-	if err := runScript(bridgeUpTemplate, d); err != nil {
-		return fmt.Errorf("couldn't create bridge: %v", err)
-	}
-	return nil
-}
-
-func (s *server) bridgeDown() {
-	d := struct {
-		Bridge string
-	}{
-		bridgeName,
-	}
-	runScript(bridgeDownTemplate, d)
-}
-
-func (s *server) startNAT() error {
-	d := struct {
-		IPFwdFile, Bridge, Gateway, BridgeSubnet string
-	}{
-		ipFwdFile, bridgeName, s.gateway, bridgeIPSubnetLong,
-	}
-	if err := runScript(natStartTemplate, d); err != nil {
-		return fmt.Errorf("couldn't start NAT: %v", err)
-	}
-	return nil
-}
-
-func (s *server) stopNAT() {
-	d := struct {
-		IPFwdFile, Bridge, Gateway, BridgeSubnet string
-	}{
-		ipFwdFile, bridgeName, s.gateway, bridgeIPSubnetLong,
-	}
-	runScript(natStopTemplate, d)
-}
-
-func (s *server) startDHCP() error {
-	s.dhcpCmd = exec.Command("dhcpd", "-cf", dhcpdConfig, "-f", bridgeName)
-	if err := s.dhcpCmd.Start(); err != nil {
-		return fmt.Errorf("couldn't start dhcpd on bridge %q: %v", bridgeName, err)
-	}
-	return nil
-}
-
-func (s *server) stopDHCP() {
-	if s.dhcpCmd == nil || s.dhcpCmd.Process == nil {
-		// dhcpd not started?
-		return
-	}
-	s.dhcpCmd.Process.Kill()
-}
-
-func (s *server) configureBluetooth() error {
-	if err := exec.Command("hciconfig", s.device, "piscan").Run(); err != nil {
-		return fmt.Errorf("couldn't make Bluetooth device %q discoverable: %v", s.device, err)
-	}
-	return nil
-}
-
-func (s *server) startNAP() error {
-	var err error
-	if s.conn, err = dbus.SystemBus(); err != nil {
-		return fmt.Errorf("couldn't access system dbus: %v", err)
-	}
-	// Get the adapter.
-	obj := s.conn.Object("org.bluez", dbus.ObjectPath("/"))
-	var adapterPath dbus.ObjectPath
-	if err := obj.Call("org.bluez.Manager.DefaultAdapter", 0).Store(&adapterPath); err != nil {
-		return fmt.Errorf("couldn't find device %q: %v", s.device, err)
-	}
-	adapter := s.conn.Object("org.bluez", adapterPath)
-	// Add a bluetooth agent.
-	agent := &yesAgent{}
-	if err = s.conn.Export(agent, agentPath, agentIface); err != nil {
-		return fmt.Errorf("error exporting agent to dbus: %v", err)
-	}
-	if call := adapter.Call("org.bluez.Adapter.RegisterAgent", 0, agentPath, "NoInputNoOutput"); call.Err != nil {
-		return fmt.Errorf("couldn't register agent: %v", call.Err)
-	}
-	// Register the NAP server.
-	if call := adapter.Call("org.bluez.NetworkServer.Register", 0, "nap", bridgeName); call.Err != nil {
-		return fmt.Errorf("couldn't start NAP server: %v", call.Err)
-	}
-	return nil
-}
-
-func (s *server) stopNAP() {
-	if s.conn == nil {
-		return
-	}
-	// Unregister the NAP server.
-	obj := s.conn.Object("org.bluez", dbus.ObjectPath(fmt.Sprintf("/org/bluez/%s", s.device)))
-	obj.Call("org.bluez.NetworkServer.Unegister", 0, "nap")
-
-	// Remove the bluetooth agent.
-	obj.Call("org.bluez.Adapter.UnregisterAgent", 0, agentPath)
-	s.conn.Export(nil, agentPath, agentIface)
-}
-
-func (s *server) rttLoop() {
-	defer vlog.VI(1).Info("gateway server's RTT loop exiting")
-	for {
-		select {
-		case <-s.done:
-			return
-		case <-time.After(1 * time.Second):
-		}
-
-		rtt, err := rtt()
-		if err != nil {
-			vlog.Errorf("error getting RTT: %v", err)
-			s.advertiseName("")
-		} else {
-			s.advertiseName(nameFromRTT(rtt))
-		}
-	}
-}
-
-func (s *server) advertiseName(name string) {
-	if s.advertisedName != "" {
-		if err := s.proximity.UnregisterName(rt.R().TODOContext(), s.advertisedName); err != nil {
-			vlog.Errorf("error unregistering name %q with proximity service: %v", s.advertisedName, err)
-		}
-	}
-	s.advertisedName = ""
-	if name != "" {
-		if err := s.proximity.RegisterName(rt.R().TODOContext(), name); err == nil {
-			s.advertisedName = name
-		} else {
-			vlog.Errorf("error registering name %q with proximity service: %v", name, err)
-		}
-	}
-}
-
-func runScript(t *template.Template, data interface{}) error {
-	fname, err := fileFromTemplate(t, data, 0777)
-	if err != nil {
-		return fmt.Errorf("couldn't create template file: %v", err)
-	}
-	defer os.Remove(fname)
-	if err := exec.Command("bash", fname).Run(); err != nil {
-		return fmt.Errorf("couldn't execute script %q: %v", fname, err)
-	}
-	return nil
-}
-
-func fileFromTemplate(t *template.Template, data interface{}, perm os.FileMode) (string, error) {
-	// Create temp file and set the right permissions on it.
-	f, err := ioutil.TempFile("", "tmp")
-	if err != nil {
-		return "", fmt.Errorf("couldn't create temp file: %v", err)
-	}
-	if err := os.Chmod(f.Name(), perm); err != nil {
-		f.Close()
-		os.Remove(f.Name())
-		return "", fmt.Errorf("couldn't change permissions on file %q to %v: err", f.Name(), perm, err)
-	}
-
-	// Execute the template and write it out into the temp file.
-	if err := t.Execute(f, data); err != nil {
-		f.Close()
-		os.Remove(f.Name())
-		return "", err
-	}
-	return f.Name(), nil
-}
-
-func rtt() (time.Duration, error) {
-	v, err := ping(pingTarget)
-	if err != nil {
-		return 0, fmt.Errorf("error executing RTT command: %v", err)
-	}
-	if len(v) == 0 {
-		return 0, errors.New("got empty RTT value")
-	}
-	f, err := strconv.ParseFloat(v, 64)
-	if err != nil {
-		return 0, fmt.Errorf("error parsing RTT value %q: %v", v, err)
-	}
-	if f < 0 {
-		return 0, fmt.Errorf("negative RTT value: %f", f)
-	}
-	return time.Duration(int(f+0.5)) * time.Millisecond, nil
-}
diff --git a/services/gateway/lib/util_linux.go b/services/gateway/lib/util_linux.go
deleted file mode 100644
index 591fef4..0000000
--- a/services/gateway/lib/util_linux.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package gateway
-
-import (
-	"bytes"
-	"fmt"
-	"os/exec"
-	"strings"
-	"time"
-	"veyron2/vlog"
-
-	dbus "github.com/guelfey/go.dbus"
-)
-
-const (
-	agentPath  = dbus.ObjectPath("/org/veyron/internal/lib/gateway/yesagent")
-	agentIface = "org.bluez.Agent"
-)
-
-var pingCmd = [][]string{
-	{"ping", "-i", "0.1", "-c", "3", "-w", "1.0", "-q"},
-	// TODO(spetrovic): Use Go's string libraries to reduce
-	// dependence on these tools.
-	{"grep", "rtt"},
-	{"cut", "-d", " ", "-f", "4"},
-	{"cut", "-d", "/", "-f", "2"},
-	{"awk", `{printf "%s", $NF}`},
-}
-
-func runPipedCmd(cmd [][]string) (string, error) {
-	if len(cmd) == 0 {
-		return "", fmt.Errorf("invalid command %q", cmd)
-	}
-	for _, c := range cmd {
-		if len(c) == 0 || len(c[0]) == 0 {
-			return "", fmt.Errorf("invalid command %q", cmd)
-		}
-	}
-	cs := make([]*exec.Cmd, len(cmd))
-	for i, c := range cmd {
-		cs[i] = exec.Command(c[0], c[1:]...)
-	}
-	for i := 1; i < len(cs); i++ {
-		var err error
-		if cs[i].Stdin, err = cs[i-1].StdoutPipe(); err != nil {
-			return "", fmt.Errorf("piping error: %v", err)
-		}
-	}
-	var out bytes.Buffer
-	cs[len(cs)-1].Stdout = &out
-	for _, c := range cs {
-		if err := c.Start(); err != nil {
-			return "", fmt.Errorf("error starting command %q: %q", c, err)
-		}
-	}
-	for _, c := range cs {
-		if err := c.Wait(); err != nil {
-			return "", fmt.Errorf("error executing command %q: %q", c, err)
-		}
-	}
-	return out.String(), nil
-}
-
-func ping(target string) (string, error) {
-	cmd := make([][]string, len(pingCmd))
-	copy(cmd, pingCmd)
-	cmd[0] = make([]string, len(pingCmd[0]))
-	copy(cmd[0], pingCmd[0])
-	cmd[0] = append(cmd[0], target)
-	return runPipedCmd(cmd)
-}
-
-func nameFromRTT(rtt time.Duration) string {
-	return fmt.Sprintf("NAP(%v)", rtt)
-}
-
-func rttFromName(name string) (time.Duration, error) {
-	if !strings.HasPrefix(name, "NAP(") || !strings.HasSuffix(name, ")") {
-		return 0, fmt.Errorf("invalid string %q", name)
-	}
-	d, err := time.ParseDuration(name[4 : len(name)-1])
-	if err != nil {
-		return 0, fmt.Errorf("couldn't parse RTT in name %q: %v", name, err)
-	}
-	return d, nil
-}
-
-// yesAgent implements the org.bluez.Agent DBus interface, allowing two devices
-// to connect without any security. This DBus interface is compatible
-// with bluez-4.101 package.
-type yesAgent struct{}
-
-func (*yesAgent) Release() *dbus.Error {
-	vlog.VI(1).Info("Release() called")
-	return nil
-}
-
-func (*yesAgent) RequestPinCode(device dbus.ObjectPath) (string, *dbus.Error) {
-	vlog.VI(1).Info("RequestPinCode(%q) called", device)
-	return "1234", nil
-}
-
-func (*yesAgent) RequestPasskey(device dbus.ObjectPath) (uint32, *dbus.Error) {
-	vlog.VI(1).Info("RequestPasskey(%q) called", device)
-	return 123456, nil
-}
-
-func (*yesAgent) DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint8) *dbus.Error {
-	vlog.VI(1).Info("DisplayPasskey(%q, %d, %d) called", device, passkey, entered)
-	return nil
-}
-
-func (*yesAgent) DisplayPinCode(device dbus.ObjectPath, pincode string) *dbus.Error {
-	vlog.VI(1).Info("DisplayPinCode(%q, %q) called", device, pincode)
-	return nil
-}
-
-func (*yesAgent) RequestConfirmation(device dbus.ObjectPath, passkey uint32) *dbus.Error {
-	vlog.VI(1).Info("RequestConfirmation(%q, %d) called", device, passkey)
-	return nil
-}
-
-func (*yesAgent) Authorize(device dbus.ObjectPath, uuid string) *dbus.Error {
-	vlog.VI(1).Info("AuthorizeService(%q, %q) called", device, uuid)
-	return nil
-}
-
-func (*yesAgent) ConfirmModeChange(mode string) *dbus.Error {
-	vlog.VI(1).Info("ConfirmModeChange(%q) called", mode)
-	return nil
-}
-
-func (*yesAgent) Cancel() *dbus.Error {
-	vlog.VI(1).Info("Cancel() called")
-	return nil
-}
diff --git a/services/proximity/lib/advertiser.go b/services/proximity/lib/advertiser.go
deleted file mode 100644
index d46a7d8..0000000
--- a/services/proximity/lib/advertiser.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package proximity
-
-import "time"
-
-// Advertiser denotes a (local) entity that is capable of advertising small
-// payloads to neighboring devices (e.g., Bluetooth).
-type Advertiser interface {
-	// StartAdvertising initiates the process of sending advertising packets
-	// after every tick of the provided time interval.  The payload sent
-	// with each advertising packet can be specified via
-	// SetAdvertisingPayload.
-	// This method may be called again even if advertising is currently
-	// enabled, in order to adjust the advertising interval.
-	StartAdvertising(advInterval time.Duration) error
-
-	// SetAdvertisingPayload sets the advertising payload that is sent with
-	// each advertising packet.  This function may be called at any time to
-	// adjust the payload that is currently being advertised.
-	SetAdvertisingPayload(payload string) error
-
-	// StopAdvertising stops advertising.  If the device is not advertising,
-	// this function will be a noop.
-	StopAdvertising() error
-}
diff --git a/services/proximity/lib/bluetooth_scanner.go b/services/proximity/lib/bluetooth_scanner.go
deleted file mode 100644
index 7929ece..0000000
--- a/services/proximity/lib/bluetooth_scanner.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package proximity
-
-import (
-	"fmt"
-	"time"
-
-	"veyron/lib/bluetooth"
-)
-
-// NewBluetoothScanner returns a Scanner instance that uses Low-Energy Bluetooth to scan
-// for nearby devices.
-func NewBluetoothScanner() (Scanner, error) {
-	return &bluetoothScanner{}, nil
-}
-
-type bluetoothScanner struct {
-	device *bluetooth.Device
-	c      chan ScanReading
-}
-
-func (s *bluetoothScanner) StartScan(scanInterval, scanWindow time.Duration) (<-chan ScanReading, error) {
-	if s.device != nil || s.c != nil {
-		return nil, fmt.Errorf("scan already in progress")
-	}
-	var err error
-	s.device, err = bluetooth.OpenFirstAvailableDevice()
-	if err != nil {
-		return nil, fmt.Errorf("couldn't find an available bluetooth device: %v", err)
-	}
-	bc, err := s.device.StartScan(scanInterval, scanWindow)
-	if err != nil {
-		return nil, fmt.Errorf("couldn't start bluetooth scan: %v", err)
-	}
-	s.c = make(chan ScanReading, 10)
-	go func() {
-		for r := range bc {
-			s.c <- ScanReading{
-				Name:     r.Name,
-				MAC:      r.MAC,
-				Distance: r.Distance,
-				Time:     r.Time,
-			}
-		}
-	}()
-	return s.c, nil
-}
-
-func (s *bluetoothScanner) StopScan() error {
-	if s.device == nil || s.c == nil {
-		if s.device != nil {
-			s.device.StopScan()
-			s.device.Close()
-			s.device = nil
-		} else {
-			close(s.c)
-			s.c = nil
-		}
-		return fmt.Errorf("scan not in progress")
-	}
-	s.device.StopScan()
-	s.device.Close()
-	s.device = nil
-	close(s.c)
-	s.c = nil
-	return nil
-}
diff --git a/services/proximity/lib/doc.go b/services/proximity/lib/doc.go
deleted file mode 100644
index 6839ece..0000000
--- a/services/proximity/lib/doc.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// Package proximity provides methods for maintaining proximity information
-// between devices.
-package proximity
diff --git a/services/proximity/lib/scanner.go b/services/proximity/lib/scanner.go
deleted file mode 100644
index 197b9b8..0000000
--- a/services/proximity/lib/scanner.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package proximity
-
-import (
-	"net"
-	"time"
-
-	"veyron/lib/unit"
-)
-
-// Scanner denotes a (local) entity that is capable of scanning for nearby
-// devices (e.g., Bluetooth).
-type Scanner interface {
-	// StartScan initiates a scan on the local device.  The scan will
-	// proceed over many duration intervals; within each interval, scan will
-	// be ON only for a given duration window.  All scan readings
-	// encountered during scan-ON periods will be pushed onto the returned
-	// channel.  If the scan cannot be started, an error is returned.
-	StartScan(scanInterval, scanWindow time.Duration) (<-chan ScanReading, error)
-	// StopScan stops any scan in progress on the local device, closing
-	// the channel returned by the previous call to StartScan().
-	// If the device is not scanning, this function will be a noop.
-	StopScan() error
-}
-
-// ScanReading holds a single reading of a neighborhood device's advertisement
-// during a scan.  Typically, there will be many such readings for a particular
-// neighborhood device.
-type ScanReading struct {
-	// Name represents a local name of the remote device.  It can also store
-	// arbitrary application-specific data.
-	Name string
-	// MAC is the hardware address of the remote device.
-	MAC net.HardwareAddr
-	// Distance represents the (estimated) distance to the neighborhood
-	// device.
-	Distance unit.Distance
-	// Time is the time the advertisement packed was received/scanned.
-	Time time.Time
-}
diff --git a/services/proximity/lib/service.go b/services/proximity/lib/service.go
deleted file mode 100644
index 2bbdd51..0000000
--- a/services/proximity/lib/service.go
+++ /dev/null
@@ -1,377 +0,0 @@
-package proximity
-
-import (
-	"fmt"
-	"net"
-	"sort"
-	"sync"
-	"time"
-
-	"veyron/lib/unit"
-	"veyron2/ipc"
-	"veyron2/services/proximity"
-	"veyron2/vlog"
-)
-
-const (
-	// maxRegisteredNames denotes the maximum number of names that can be
-	// actively registered for this device.
-	maxRegisteredNames = 10
-	// advInterval specifies the frequency at which the advertising packets
-	// are sent.
-	advInterval = 32 * time.Millisecond
-	// advCycleInterval specifies the frequency at which we change the
-	// currently advertised name (out of at most maxRegisteredNames names).
-	advCycleInterval = 4 * advInterval
-	// scanInterval splits the entire scan duration into intervals of
-	// provided length.
-	scanInterval = 32 * time.Millisecond
-	// scanWindow specifies, for each scanInterval, the duration during
-	// which the scan will be ON.  (For the remainder of scanInterval,
-	// scan will be OFF.)
-	scanWindow = 16 * time.Millisecond
-	// minHistoryWindow denotes the minimum time window into the past
-	// beyond which proximity readings should be ignored.  In order to
-	// catch all unique remote names (i.e., at most maxRegisteredNames of
-	// them), we set this to double the interval at which the advertiser
-	// can cycle through all the names.
-	minHistoryWindow = 2 * maxRegisteredNames * advCycleInterval
-)
-
-// New returns a new instance of proximity service, given the provided
-// advertiser and scanner (e.g., Bluetooth). historyWindow denotes the time
-// window into the past beyond which proximity readings should be ignored.
-// refreshFrequency specifies how often the list of nearby devices should be
-// refreshed - shorter time duration means that the list will be more
-// up-to-date but more resources will be consumed.  If the service cannot be
-// created, an error is returned.
-func New(a Advertiser, s Scanner, historyWindow, refreshFrequency time.Duration) (*service, error) {
-	// Start advertising.
-	if err := a.StartAdvertising(advInterval); err != nil {
-		return nil, err
-	}
-
-	// Start scanning.
-	r, err := s.StartScan(scanInterval, scanWindow)
-	if err != nil {
-		return nil, err
-	}
-
-	// If the history window is too small, update it.
-	if historyWindow < minHistoryWindow {
-		historyWindow = minHistoryWindow
-	}
-	srv := &service{
-		devices:          make(map[string]*device),
-		names:            make(map[string]int),
-		advertiser:       a,
-		scanner:          s,
-		window:           historyWindow,
-		freq:             refreshFrequency,
-		readChan:         r,
-		updateChan:       make(chan bool),
-		updateTickerChan: time.Tick(refreshFrequency),
-		advDoneChan:      make(chan bool),
-	}
-	go srv.readLoop()
-	go srv.updateLoop()
-	go srv.advLoop()
-	return srv, nil
-}
-
-// device represents one neighborhood device.  It contains that device's MAC
-// address, average distance, list of recent scan readings, and a list of all
-// unique names stored in those scan readings.
-type device struct {
-	lock     sync.Mutex
-	mac      net.HardwareAddr
-	distance unit.Distance
-	names    []string
-	readings []ScanReading
-}
-
-// service maintains a list of devices in our close proximity, using scan
-// readings returned by the Scanner.  It implements the ProximityService
-// interface, generated from proximity.idl file.
-type service struct {
-	deviceLock sync.RWMutex
-	nameLock   sync.RWMutex
-	devices    map[string]*device
-	nearby     []proximity.Device
-	names      map[string]int
-
-	advertiser       Advertiser
-	scanner          Scanner
-	window           time.Duration
-	freq             time.Duration
-	readChan         <-chan ScanReading
-	updateChan       chan bool
-	updateTickerChan <-chan time.Time
-	advDoneChan      chan bool
-}
-
-func (s *service) RegisterName(_ ipc.ServerContext, name string) error {
-	s.nameLock.Lock()
-	defer s.nameLock.Unlock()
-	if v, ok := s.names[name]; ok {
-		s.names[name] = v + 1
-		return nil
-	}
-	if len(s.names) >= maxRegisteredNames {
-		return fmt.Errorf("too many unique registered names, max allowed is %d", maxRegisteredNames)
-	}
-	s.names[name] = 1
-	return nil
-}
-
-func (s *service) UnregisterName(_ ipc.ServerContext, name string) error {
-	s.nameLock.Lock()
-	defer s.nameLock.Unlock()
-	v, ok := s.names[name]
-	if !ok {
-		return fmt.Errorf("name %q not registered", name)
-	}
-	if v <= 1 {
-		delete(s.names, name)
-	} else {
-		s.names[name] = v - 1
-	}
-	return nil
-}
-
-// NearbyDevices returns the list of nearby devices, sorted in increasing
-// distance order.
-func (s *service) NearbyDevices(_ ipc.ServerContext) ([]proximity.Device, error) {
-	s.deviceLock.RLock()
-	defer s.deviceLock.RUnlock()
-	return s.nearby, nil
-}
-
-// Stop terminates the process of gathering proximity information, returning
-// any error encountered.
-func (s *service) Stop() {
-	vlog.VI(1).Info("stopping proximity service")
-	// Stop the scanner.  This action will cause the following cascading
-	// effect: readChan closed -> readLoop terminated -> updateChan closed
-	// -> updateLoop terminated.
-	s.scanner.StopScan()
-	// Stop the advertiser.
-	s.advertiser.StopAdvertising()
-	// Close advDoneChan, which will terminate advLoop.
-	close(s.advDoneChan)
-}
-
-// readLoop extracts readings from readChan and writes notifications to
-// updateChan.
-func (s *service) readLoop() {
-	for r := range s.readChan {
-		s.deviceLock.Lock()
-		d := s.devices[r.MAC.String()]
-		if d == nil {
-			d = &device{
-				mac: r.MAC,
-			}
-			s.devices[d.mac.String()] = d
-		}
-		d.lock.Lock()
-		d.readings = append(d.readings, r)
-		d.lock.Unlock()
-		s.deviceLock.Unlock()
-
-		// Notify.  We want at most one outstanding notification but
-		// don't want to block.
-		select {
-		case s.updateChan <- true:
-		default:
-		}
-	}
-	close(s.updateChan)
-	vlog.VI(1).Info("proximity service's read goroutine exiting")
-}
-
-// updateLoop periodically updates the state of nearby devices.
-func (s *service) updateLoop() {
-	defer vlog.VI(1).Info("proximity service's update goroutine exiting")
-	for {
-		// Wait for a ticker.  The ticker helps us avoid wasting
-		// resources by doing too-frequent updates. If either the ticker
-		// or the update channel gets closed in the meantime, we exit
-		// this goroutine.
-		var exit bool
-		for !exit {
-			select {
-			case _, ok := <-s.updateTickerChan:
-				if !ok {
-					return
-				}
-				exit = true
-			case _, ok := <-s.updateChan:
-				if !ok {
-					return
-				}
-			}
-		}
-
-		s.updateNearbyState()
-	}
-}
-
-// advLoop cycles through all registered names and advertises each one
-// for a specified time interval (advCycleInterval).  It listens on advDoneChan
-// and terminates when something is sent on it or when it gets closed.
-func (s *service) advLoop() {
-	tickerChan := time.Tick(advCycleInterval)
-	var ns []string
-	var idx int
-	defer vlog.VI(1).Info("proximity service's advertising goroutine exiting")
-	for {
-		select {
-		case <-s.advDoneChan:
-			return
-		case <-tickerChan:
-		}
-
-		if idx >= len(ns) {
-			// Cycled once through all copied names - create a
-			// new copy of registered names.
-			s.nameLock.RLock()
-			ns = nil
-			for key := range s.names {
-				ns = append(ns, key)
-			}
-			s.nameLock.RUnlock()
-			idx = 0
-			if len(ns) == 0 {
-				// No names to advertise: advertise an empty
-				// string so that neighbors will at least
-				// know this device exists.
-				ns = append(ns, "")
-			}
-		}
-		name := ns[idx]
-		if err := s.advertiser.SetAdvertisingPayload(name); err != nil {
-			vlog.Errorf("couldn't set advertising payload %s: %v", name, err)
-		}
-		idx++
-	}
-}
-
-// updateNearbyStates re-computes the neighborhood list using the most recent
-// scan readings and updates it in-place.
-func (s *service) updateNearbyState() {
-	// Reject all readings with timestamps before this barrier.
-	barrier := time.Now().Add(-1 * s.window)
-
-	// Get devices with recent readings and purge the rest.
-	var recent []*device
-	s.deviceLock.Lock()
-	for _, d := range s.devices {
-		d.lock.Lock()
-		if len(d.readings) == 0 || d.readings[len(d.readings)-1].Time.Before(barrier) { // no recent readings.
-			delete(s.devices, d.mac.String())
-		} else {
-			recent = append(recent, d)
-		}
-		d.lock.Unlock()
-	}
-	s.deviceLock.Unlock()
-
-	// Purge stale readings from remaining devices and compute average
-	// proximity.
-	devices := make([]device, 0, len(recent))
-	for _, d := range recent {
-		d.lock.Lock()
-		// Find the index at which readings become stale.
-		var idx int
-		for idx = len(d.readings) - 1; idx >= 0; idx-- {
-			if r := d.readings[idx]; r.Time.Before(barrier) {
-				break
-			}
-		}
-		// Remove stale readings.
-		d.readings = d.readings[idx+1:]
-
-		// If we have a non-infinite distance, add the device to our
-		// list.
-		if dist := avgDistance(d.readings); dist != unit.MaxDistance {
-			devices = append(devices, device{
-				names:    uniqueNames(d.readings),
-				mac:      d.mac,
-				distance: dist,
-			})
-		}
-		d.lock.Unlock()
-	}
-
-	// Sort all devices by proximity.
-	incDistance := func(d1, d2 device) bool {
-		return d1.distance < d2.distance
-	}
-	sort.Sort(&deviceSorter{
-		devices: devices,
-		by:      incDistance,
-	})
-
-	// Update device list.
-	newDevs := make([]proximity.Device, len(devices))
-	for i, d := range devices {
-		// Sort names just for stability.
-		sort.Strings(d.names)
-		newDevs[i] = proximity.Device{
-			Names:    d.names,
-			MAC:      d.mac.String(),
-			Distance: d.distance.String(),
-		}
-	}
-
-	vlog.VI(1).Info("Nearby devices:", newDevs)
-
-	s.deviceLock.Lock()
-	s.nearby = newDevs
-	s.deviceLock.Unlock()
-}
-
-func avgDistance(readings []ScanReading) unit.Distance {
-	if len(readings) == 0 {
-		return unit.MaxDistance
-	}
-	// Ignore the smallest and largest 33% of the readings.
-	decRSSI := func(r1, r2 ScanReading) bool {
-		return r1.Distance < r2.Distance
-	}
-	sort.Sort(&readingSorter{
-		readings: readings,
-		by:       decRSSI,
-	})
-	trim := len(readings) / 3
-	readings = readings[trim : len(readings)-trim]
-
-	// Prune all readings with unit.MaxDistance distance.
-	idx := len(readings) - 1
-	for ; idx >= 0 && readings[idx].Distance == unit.MaxDistance; idx-- {
-	}
-	readings = readings[:idx+1]
-
-	if len(readings) == 0 {
-		return unit.MaxDistance
-	}
-
-	// Compute average distance.
-	var totalDistance unit.Distance
-	for _, r := range readings {
-		totalDistance += r.Distance
-	}
-	return totalDistance / unit.Distance(len(readings))
-}
-
-func uniqueNames(readings []ScanReading) []string {
-	ns := make(map[string]bool)
-	for _, r := range readings {
-		ns[r.Name] = true
-	}
-	var names []string
-	for name := range ns {
-		names = append(names, name)
-	}
-	return names
-}
diff --git a/services/proximity/lib/service_test.go b/services/proximity/lib/service_test.go
deleted file mode 100644
index 9d086c5..0000000
--- a/services/proximity/lib/service_test.go
+++ /dev/null
@@ -1,233 +0,0 @@
-package proximity
-
-import (
-	"reflect"
-	"testing"
-	"time"
-
-	"veyron/lib/unit"
-	"veyron2/services/proximity"
-)
-
-type testStream struct {
-	c chan<- []proximity.Device
-}
-
-func (s *testStream) Send(item []proximity.Device) error {
-	s.c <- item
-	return nil
-}
-
-func testNearbyDevices(t *testing.T, history time.Duration, input []ScanReading, expected []proximity.Device) {
-	const freq = 1 * time.Nanosecond // update as fast as possible
-
-	// Append a dummy scan reading with a unique device name.  We will later
-	// wait until we see this device in the output, indicating that all of
-	// the scan readings have been processed and accounted for.
-	const dummyName = "$!dummy#@"
-	input = append(input, ScanReading{dummyName, mac(0), 0, time.Now()})
-	adv, _ := newMockAdvertiser()
-	s, err := New(adv, &mockScanner{readings: input}, history, freq)
-	if err != nil {
-		t.Fatalf("couldn't create proximity service: %v", err)
-	}
-
-	// Loop until we reach the expected number of devices/readings.
-	for {
-		devices, err := s.NearbyDevices(nil)
-		if err != nil {
-			t.Fatalf("error getting nearby devices: %v", err)
-		}
-		var done bool
-		for i, d := range devices {
-			if len(d.Names) == 1 && d.Names[0] == dummyName {
-				// Remove dummy device from the list.
-				devices = append(devices[:i], devices[i+1:]...)
-				done = true
-				break
-			}
-		}
-		if done {
-			if !reflect.DeepEqual(devices, expected) {
-				t.Errorf("devices mismatch: got %#v, want %#v", devices, expected)
-			}
-			break
-		}
-	}
-
-	// Stop proximity.
-	s.Stop()
-}
-
-func TestNearbyDevicesUniq(t *testing.T) {
-	now := time.Now()
-	testNearbyDevices(t, 100*time.Hour,
-		[]ScanReading{
-			{"N1", mac(1), 5 * unit.Meter, now},
-			{"N2", mac(2), 2 * unit.Meter, now},
-			{"N3", mac(3), 1 * unit.Meter, now},
-			{"N4", mac(4), 7 * unit.Meter, now},
-			{"N5", mac(5), 3 * unit.Meter, now},
-			{"N6", mac(6), 4 * unit.Meter, now},
-			{"N7", mac(7), 6 * unit.Meter, now},
-		},
-		[]proximity.Device{
-			{mac(3).String(), []string{"N3"}, (1 * unit.Meter).String()},
-			{mac(2).String(), []string{"N2"}, (2 * unit.Meter).String()},
-			{mac(5).String(), []string{"N5"}, (3 * unit.Meter).String()},
-			{mac(6).String(), []string{"N6"}, (4 * unit.Meter).String()},
-			{mac(1).String(), []string{"N1"}, (5 * unit.Meter).String()},
-			{mac(7).String(), []string{"N7"}, (6 * unit.Meter).String()},
-			{mac(4).String(), []string{"N4"}, (7 * unit.Meter).String()},
-		})
-}
-
-func TestNearbyDevicesAggr(t *testing.T) {
-	now := time.Now()
-	testNearbyDevices(t, 100*time.Hour,
-		[]ScanReading{
-			{"N1", mac(1), 5 * unit.Meter, now},
-			{"N2", mac(2), 2 * unit.Meter, now},
-			{"N1", mac(1), 7 * unit.Meter, now},
-			{"N2", mac(2), 2 * unit.Meter, now},
-			{"N1", mac(1), 3 * unit.Meter, now},
-			{"N2", mac(2), 5 * unit.Meter, now},
-			{"N1", mac(1), 1 * unit.Meter, now},
-			{"N2", mac(2), 5 * unit.Meter, now},
-			{"N3", mac(3), 1 * unit.Meter, now},
-		},
-		[]proximity.Device{
-			{mac(3).String(), []string{"N3"}, (1 * unit.Meter).String()},
-			{mac(2).String(), []string{"N2"}, (3.5 * unit.Meter).String()},
-			{mac(1).String(), []string{"N1"}, (4 * unit.Meter).String()},
-		})
-}
-
-func TestNearbyDevicesReadingsStale(t *testing.T) {
-	now := time.Now()
-	oneHrAgo := now.Add(-1 * time.Hour)
-
-	testNearbyDevices(t, 10*time.Minute,
-		[]ScanReading{
-			{"N1", mac(1), 5 * unit.Meter, oneHrAgo},
-			{"N2", mac(2), 2 * unit.Meter, oneHrAgo},
-			{"N1", mac(1), 9 * unit.Meter, oneHrAgo},
-			{"N2", mac(2), 3 * unit.Meter, now},
-			{"N1", mac(1), 4 * unit.Meter, now},
-			{"N2", mac(2), 4 * unit.Meter, now},
-			{"N3", mac(3), 1 * unit.Meter, now},
-		},
-		[]proximity.Device{
-			{mac(3).String(), []string{"N3"}, (1 * unit.Meter).String()},
-			{mac(2).String(), []string{"N2"}, (3.5 * unit.Meter).String()},
-			{mac(1).String(), []string{"N1"}, (4 * unit.Meter).String()},
-		})
-}
-
-func TestNearbyDevicesDevicesStale(t *testing.T) {
-	now := time.Now()
-	oneHrAgo := now.Add(-1 * time.Hour)
-
-	testNearbyDevices(t, 10*time.Minute,
-		[]ScanReading{
-			{"N1", mac(1), 5 * unit.Meter, oneHrAgo},
-			{"N2", mac(2), 2 * unit.Meter, oneHrAgo},
-			{"N3", mac(3), 1 * unit.Meter, oneHrAgo},
-			{"N1", mac(1), 7 * unit.Meter, now},
-			{"N2", mac(2), 2 * unit.Meter, now},
-			{"N1", mac(1), 4 * unit.Meter, now},
-			{"N2", mac(2), 4 * unit.Meter, now},
-		},
-		[]proximity.Device{
-			{mac(2).String(), []string{"N2"}, (3 * unit.Meter).String()},
-			{mac(1).String(), []string{"N1"}, (5.5 * unit.Meter).String()},
-		})
-}
-
-func TestNearbyDevicesManyNames(t *testing.T) {
-	now := time.Now()
-	testNearbyDevices(t, 100*time.Hour,
-		[]ScanReading{
-			{"N1B", mac(1), 6 * unit.Meter, now},
-			{"N2A", mac(2), 2 * unit.Meter, now},
-			{"N1A", mac(1), 7 * unit.Meter, now},
-			{"N2A", mac(2), 2 * unit.Meter, now},
-			{"N1A", mac(1), 5 * unit.Meter, now},
-			{"N2B", mac(2), 5 * unit.Meter, now},
-			{"N1A", mac(1), 1 * unit.Meter, now},
-			{"N2B", mac(2), 5 * unit.Meter, now},
-			{"N1A", mac(1), 4 * unit.Meter, now},
-			{"N3", mac(3), 1 * unit.Meter, now},
-		},
-		[]proximity.Device{
-			{mac(3).String(), []string{"N3"}, (1 * unit.Meter).String()},
-			{mac(2).String(), []string{"N2A", "N2B"}, (3.5 * unit.Meter).String()},
-			{mac(1).String(), []string{"N1A", "N1B"}, (5 * unit.Meter).String()},
-		})
-}
-
-func TestRegisterName(t *testing.T) {
-	adv, advChan := newMockAdvertiser()
-	s, err := New(adv, &mockScanner{}, time.Second, time.Second)
-	if err != nil {
-		t.Errorf("error creating proximity service: %v", err)
-	}
-
-	// Empty string should be advertising initially.
-	for name := range advChan {
-		if name != "" {
-			t.Errorf("got advertised name %q, expected %q", name, "")
-		}
-		break
-	}
-
-	// Register name and wait for it to begin advertising.
-	s.RegisterName(nil, "N1")
-	for name := range advChan {
-		if name == "N1" {
-			break
-		} else if name != "" {
-			t.Errorf("got advertised name %q, expected %q", name, "N1")
-		}
-	}
-
-	// Register another name and wait for it to begin advertising.
-	s.RegisterName(nil, "N2")
-	var found1, found2 bool
-Loop:
-	for name := range advChan {
-		switch name {
-		case "N1":
-			found1 = true
-		case "N2":
-			found2 = true
-		default:
-			t.Errorf("got advertised name %q, expected %q or %q", name, "N1", "N2")
-			break Loop
-		}
-		if found1 && found2 {
-			break
-		}
-	}
-
-	// Unregister a name and wait for it to disappear.  We'll consider a
-	// name disappearing if it doesn't show up in 30 consecutive
-	// advertisements.
-	s.UnregisterName(nil, "N1")
-	var n int
-	for name := range advChan {
-		if name == "N1" {
-			n = 0
-		} else {
-			n++
-			if n >= 30 {
-				break
-			}
-		}
-	}
-
-	// Stop service and wait for the advertising channel to be closed.
-	s.Stop()
-	for _ = range advChan {
-	}
-}
diff --git a/services/proximity/lib/sorting.go b/services/proximity/lib/sorting.go
deleted file mode 100644
index ec72860..0000000
--- a/services/proximity/lib/sorting.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package proximity
-
-type readingSorter struct {
-	readings []ScanReading
-	by       func(r1, r2 ScanReading) bool
-}
-
-func (s *readingSorter) Len() int {
-	return len(s.readings)
-}
-
-func (s *readingSorter) Swap(i, j int) {
-	s.readings[i], s.readings[j] = s.readings[j], s.readings[i]
-}
-
-func (s *readingSorter) Less(i, j int) bool {
-	return s.by(s.readings[i], s.readings[j])
-}
-
-type deviceSorter struct {
-	devices []device
-	by      func(d1, d2 device) bool
-}
-
-func (s *deviceSorter) Len() int {
-	return len(s.devices)
-}
-
-func (s *deviceSorter) Swap(i, j int) {
-	s.devices[i], s.devices[j] = s.devices[j], s.devices[i]
-}
-
-func (s *deviceSorter) Less(i, j int) bool {
-	return s.by(s.devices[i], s.devices[j])
-}
diff --git a/services/proximity/lib/util_test.go b/services/proximity/lib/util_test.go
deleted file mode 100644
index c3aade9..0000000
--- a/services/proximity/lib/util_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package proximity
-
-import (
-	"fmt"
-	"net"
-	"sync"
-	"time"
-)
-
-type mockScanner struct {
-	readings []ScanReading
-	c        chan ScanReading
-}
-
-func (s *mockScanner) StartScan(_, _ time.Duration) (<-chan ScanReading, error) {
-	s.c = make(chan ScanReading, len(s.readings))
-	for _, r := range s.readings {
-		s.c <- r
-	}
-	return s.c, nil
-}
-
-func (s *mockScanner) StopScan() error {
-	close(s.c)
-	return nil
-}
-
-type mockAdvertiser struct {
-	lock    sync.RWMutex
-	payload string
-	c       chan string
-	done    chan bool
-}
-
-func newMockAdvertiser() (Advertiser, <-chan string) {
-	c := make(chan string)
-	return &mockAdvertiser{
-		c:    c,
-		done: make(chan bool),
-	}, c
-}
-
-func (a *mockAdvertiser) StartAdvertising(interval time.Duration) error {
-	go func() {
-		defer close(a.c)
-		for _ = range time.Tick(interval) {
-			select {
-			case <-a.done:
-				return
-			default:
-			}
-			a.lock.RLock()
-			p := a.payload
-			a.lock.RUnlock()
-			a.c <- p
-		}
-	}()
-	return nil
-}
-
-func (a *mockAdvertiser) SetAdvertisingPayload(payload string) error {
-	a.lock.Lock()
-	a.payload = payload
-	a.lock.Unlock()
-	return nil
-}
-
-func (a *mockAdvertiser) StopAdvertising() error {
-	close(a.done)
-	for _ = range <-a.c {
-	}
-	return nil
-}
-
-func mac(id int) net.HardwareAddr {
-	if id >= 256 {
-		panic(fmt.Sprintf("id %d too large", id))
-	}
-	addr, err := net.ParseMAC(fmt.Sprintf("00:00:00:00:00:%02x", id))
-	if err != nil {
-		panic(fmt.Sprintf("can't create MAC address for id %d: %v", id, err))
-	}
-	return addr
-}
diff --git a/services/proximity/proximityd/main.go b/services/proximity/proximityd/main.go
deleted file mode 100644
index a67c5e1..0000000
--- a/services/proximity/proximityd/main.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Binary proximityd provides means for devices to announce their precence
-// to nearby devices and to obtain the list of nearby devices.
-package main
-
-import (
-	"flag"
-	"time"
-
-	"veyron/lib/signals"
-
-	"veyron/lib/bluetooth"
-	vflag "veyron/security/flag"
-	"veyron/services/proximity/lib"
-	"veyron2/ipc"
-	"veyron2/rt"
-	prox "veyron2/services/proximity"
-	"veyron2/vlog"
-)
-
-var (
-	// TODO(rthellend): Remove the protocol and address flags when the config
-	// manager is working.
-	protocol = flag.String("protocol", "tcp", "protocol to listen on")
-	address  = flag.String("address", ":0", "address to listen on")
-
-	name = flag.String("name", "", "name to mount the proximity service as")
-)
-
-func main() {
-	// Get the runtime.
-	r := rt.Init()
-	defer r.Cleanup()
-
-	// Create a new server.
-	s, err := r.NewServer()
-	if err != nil {
-		vlog.Fatal("error creating server: ", err)
-	}
-	defer s.Stop()
-
-	// Create a new instance of the proximity service that uses bluetooth.
-	// NOTE(spetrovic): the underlying Linux bluetooth library doesn't
-	// allow us to scan and advertise on the same bluetooth device
-	// descriptor.  We therefore open separate device descriptors for
-	// advertising and scanning.
-	advertiser, err := bluetooth.OpenFirstAvailableDevice()
-	if err != nil {
-		vlog.Fatal("couldn't find an available bluetooth device")
-	}
-	defer advertiser.Close()
-	scanner, err := proximity.NewBluetoothScanner()
-	if err != nil {
-		vlog.Fatalf("couldn't create bluetooth scanner: %v", err)
-	}
-	p, err := proximity.New(advertiser, scanner, 1*time.Second, 500*time.Millisecond)
-	if err != nil {
-		vlog.Fatal("couldn't create proximity service:", err)
-	}
-	defer p.Stop()
-
-	// Create an endpoint to listen on.
-	endpoint, err := s.Listen(*protocol, *address)
-	if err != nil {
-		vlog.Fatal("error listening:", err)
-	}
-	vlog.Info("Endpoint: ", endpoint)
-
-	// Start the server and register it with the mounttable under the
-	// given name.
-	if err := s.Serve(*name, ipc.LeafDispatcher(prox.NewServerProximity(p), vflag.NewAuthorizerOrDie())); err != nil {
-		vlog.Fatalf("error publishing service (%s): %v", *name, err)
-	}
-
-	// Wait until shutdown.
-	<-signals.ShutdownOnSignals()
-}
diff --git a/tools/proximity/impl/impl.go b/tools/proximity/impl/impl.go
deleted file mode 100644
index 907436a..0000000
--- a/tools/proximity/impl/impl.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package impl
-
-import (
-	"fmt"
-
-	"veyron/lib/cmdline"
-
-	"veyron2/rt"
-	"veyron2/services/proximity"
-)
-
-var cmdRegister = &cmdline.Command{
-	Run:      runRegister,
-	Name:     "register",
-	Short:    "register adds a name that the remote device will be associated with.",
-	Long:     "register adds a name that the remote device will be associated with.",
-	ArgsName: "<address> <name>",
-	ArgsLong: `
-<address> is the object name of the proximity server.
-<name> is the name to register.
-`,
-}
-
-func runRegister(cmd *cmdline.Command, args []string) error {
-	if expected, got := 2, len(args); expected != got {
-		return cmd.Errorf("register: incorrect number of arguments, expected %d, got %d", expected, got)
-	}
-	p, err := proximity.BindProximity(args[0])
-	if err != nil {
-		return fmt.Errorf("bind error: %v", err)
-	}
-	if err = p.RegisterName(rt.R().TODOContext(), args[1]); err != nil {
-		return err
-	}
-	fmt.Fprintf(cmd.Stdout(), "Name registered successfully\n")
-	return nil
-}
-
-var cmdUnregister = &cmdline.Command{
-	Run:      runUnregister,
-	Name:     "unregister",
-	Short:    "unregister removes a name that the remote device it is associated with.",
-	Long:     "unregister removes a name that the remote device it is associated with.",
-	ArgsName: "<address> <name>",
-	ArgsLong: `
-<address> is the object name of the proximity server.
-<name> is the name to unregister.
-`,
-}
-
-func runUnregister(cmd *cmdline.Command, args []string) error {
-	if expected, got := 2, len(args); expected != got {
-		return cmd.Errorf("unregister: incorrect number of arguments, expected %d, got %d", expected, got)
-	}
-	p, err := proximity.BindProximity(args[0])
-	if err != nil {
-		return fmt.Errorf("bind error: %v", err)
-	}
-	if err = p.UnregisterName(rt.R().TODOContext(), args[1]); err != nil {
-		return err
-	}
-	fmt.Fprintf(cmd.Stdout(), "Name unregistered successfully\n")
-	return nil
-}
-
-var cmdNearbyDevices = &cmdline.Command{
-	Run:      runNearbyDevices,
-	Name:     "nearbydevices",
-	Short:    "nearbydevices displayes the most up-to-date list of nearby devices.",
-	Long:     "nearbydevices displayes the most up-to-date list of nearby devices.",
-	ArgsName: "<address>",
-	ArgsLong: "<address> is the object name of the proximity server.",
-}
-
-func runNearbyDevices(cmd *cmdline.Command, args []string) error {
-	if expected, got := 1, len(args); expected != got {
-		return cmd.Errorf("download: incorrect number of arguments, expected %d, got %d", expected, got)
-	}
-
-	p, err := proximity.BindProximity(args[0])
-	if err != nil {
-		return fmt.Errorf("bind error: %v", err)
-	}
-
-	devices, err := p.NearbyDevices(rt.R().TODOContext())
-	if err != nil {
-		return err
-	}
-
-	fmt.Fprintf(cmd.Stdout(), "Nearby Devices:\n")
-	if len(devices) == 0 {
-		fmt.Fprintf(cmd.Stdout(), "None\n")
-		return nil
-	}
-
-	for i, d := range devices {
-		fmt.Fprintf(cmd.Stdout(), "%d: MAC=%s Names=%v Distance=%s\n", i, d.MAC, d.Names, d.Distance)
-	}
-	return nil
-}
-
-func Root() *cmdline.Command {
-	return &cmdline.Command{
-		Name:     "proximity",
-		Short:    "Command-line tool for interacting with the Veyron proximity server",
-		Long:     "Command-line tool for interacting with the Veyron proximity server",
-		Children: []*cmdline.Command{cmdRegister, cmdUnregister, cmdNearbyDevices},
-	}
-}
diff --git a/tools/proximity/impl/impl_test.go b/tools/proximity/impl/impl_test.go
deleted file mode 100644
index 7ae5914..0000000
--- a/tools/proximity/impl/impl_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package impl_test
-
-import (
-	"bytes"
-	"strings"
-	"testing"
-
-	"veyron/tools/proximity/impl"
-
-	"veyron2"
-	"veyron2/ipc"
-	"veyron2/naming"
-	"veyron2/rt"
-	"veyron2/security"
-	"veyron2/services/proximity"
-	"veyron2/vlog"
-)
-
-type server struct {
-}
-
-func (s *server) RegisterName(_ ipc.ServerContext, name string) error {
-	vlog.VI(2).Infof("RegisterName(%q) was called", name)
-	return nil
-}
-
-func (s *server) UnregisterName(_ ipc.ServerContext, name string) error {
-	vlog.VI(2).Infof("UnregisterName(%q) was called", name)
-	return nil
-}
-
-func (s *server) NearbyDevices(_ ipc.ServerContext) ([]proximity.Device, error) {
-	vlog.VI(2).Info("NearbyDevices() was called")
-	devices := []proximity.Device{
-		{MAC: "xx:xx:xx:xx:xx:xx", Names: []string{"name1", "name2"}, Distance: "1m"},
-		{MAC: "yy:yy:yy:yy:yy:yy", Names: []string{"name3"}, Distance: "2m"},
-	}
-	return devices, nil
-}
-
-type dispatcher struct {
-}
-
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
-	invoker := ipc.ReflectInvoker(proximity.NewServerProximity(&server{}))
-	return invoker, nil, nil
-}
-
-func startServer(t *testing.T, r veyron2.Runtime) (ipc.Server, naming.Endpoint, error) {
-	dispatcher := &dispatcher{}
-	server, err := r.NewServer()
-	if err != nil {
-		t.Errorf("NewServer failed: %v", err)
-		return nil, nil, err
-	}
-	endpoint, err := server.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Errorf("Listen failed: %v", err)
-		return nil, nil, err
-	}
-	if err := server.Serve("", dispatcher); err != nil {
-		t.Errorf("Serve failed: %v", err)
-		return nil, nil, err
-	}
-	return server, endpoint, nil
-}
-
-func stopServer(t *testing.T, server ipc.Server) {
-	if err := server.Stop(); err != nil {
-		t.Errorf("server.Stop failed: %v", err)
-	}
-}
-
-func TestProximityClient(t *testing.T) {
-	runtime := rt.Init()
-	server, endpoint, err := startServer(t, runtime)
-	if err != nil {
-		return
-	}
-	defer stopServer(t, server)
-	// Setup the command-line.
-	cmd := impl.Root()
-	var stdout, stderr bytes.Buffer
-	cmd.Init(nil, &stdout, &stderr)
-	address := naming.JoinAddressName(endpoint.String(), "")
-
-	// Test the 'register' command.
-	if err := cmd.Execute([]string{"register", address, "myname"}); err != nil {
-		t.Fatalf("%v", err)
-	}
-	if expected, got := "Name registered successfully", strings.TrimSpace(stdout.String()); got != expected {
-		t.Errorf("Got %q, expected %q", got, expected)
-	}
-	stdout.Reset()
-
-	// Test the 'unregister' command.
-	if err := cmd.Execute([]string{"unregister", address, "myname"}); err != nil {
-		t.Fatalf("%v", err)
-	}
-	if expected, got := "Name unregistered successfully", strings.TrimSpace(stdout.String()); got != expected {
-		t.Errorf("Got %q, expected %q", got, expected)
-	}
-	stdout.Reset()
-
-	// Test the 'nearbydevices' command.
-	if err := cmd.Execute([]string{"nearbydevices", address}); err != nil {
-		t.Fatalf("%v", err)
-	}
-	if expected, got := "Nearby Devices:\n0: MAC=xx:xx:xx:xx:xx:xx Names=[name1 name2] Distance=1m\n1: MAC=yy:yy:yy:yy:yy:yy Names=[name3] Distance=2m", strings.TrimSpace(stdout.String()); got != expected {
-		t.Errorf("Got %q, expected %q", got, expected)
-	}
-	stdout.Reset()
-}
diff --git a/tools/proximity/main.go b/tools/proximity/main.go
deleted file mode 100644
index a5d8826..0000000
--- a/tools/proximity/main.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package main
-
-import (
-	"veyron/tools/proximity/impl"
-
-	"veyron2/rt"
-)
-
-func main() {
-	defer rt.Init().Cleanup()
-	impl.Root().Main()
-}