gobi: move open source gobi programs to open sdk

Move the Google written programs from the Qualcomm propriteary
repository to the open source gobi3-sdk.

This requires a corresponding CL to remove them from the qualcomm-sdk repository.

These files were moved in a non-history preserving way.

BUG=chrome-os-partner:7154
TEST=install, run powercycle-all-gobis

Change-Id: Id94c4725d780b31ad89069bb027626938b9fa42e
diff --git a/Makefile b/Makefile
index f0be379..4e1e7c1 100644
--- a/Makefile
+++ b/Makefile
@@ -18,3 +18,4 @@
 	$(MAKE) -C GobiConnectionMgmt install PREFIX=$(PREFIX)
 	$(MAKE) -C GobiImageMgmt install PREFIX=$(PREFIX)
 	$(MAKE) -C GobiQDLService install
+	$(MAKE) -C Tools install PREFIX=$(PREFIX)
diff --git a/Tools/Makefile b/Tools/Makefile
new file mode 100644
index 0000000..9e71cfa
--- /dev/null
+++ b/Tools/Makefile
@@ -0,0 +1,31 @@
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+BINDIR = $(PREFIX)/opt/Qualcomm/bin
+
+INCLUDES := -I. -I.. -I../Core
+LIBS := -L. -lGobiConnectionMgmt
+
+CFLAGS := $(CFLAGS) $(INCLUDES)
+CFLAGS := $(CFLAGS) -Wall -Wextra
+
+all : gobi-factory-reset sdk-stress open-deauth powercycle-all-gobis
+
+gobi-factory-reset : gobi-factory-reset.c libGobiConnectionMgmt.so
+	$(CC) $(CFLAGS) -o $@ $(filter %.c,$^) $(LIBS)
+
+sdk-stress : sdk-stress.c libGobiConnectionMgmt.so
+	$(CC) $(CFLAGS) -o $@ $(filter %.c,$^) $(LIBS)
+
+open-deauth : open-deauth.c libGobiConnectionMgmt.so
+	$(CC) $(CFLAGS) -o $@ $(filter %.c,$^) $(LIBS) -lpthread
+
+libGobiConnectionMgmt.so:
+	ln -s ../GobiConnectionMgmt/libGobiConnectionMgmt.so $@
+
+install : all
+	install -D gobi-factory-reset $(BINDIR)/gobi-factory-reset
+	install -D sdk-stress $(BINDIR)/sdk-stress
+	install -D open-deauth $(BINDIR)/open-deauth
+	install -D powercycle-all-gobis $(BINDIR)/powercycle-all-gobis
diff --git a/Tools/gobi-factory-reset.c b/Tools/gobi-factory-reset.c
new file mode 100644
index 0000000..c509b12
--- /dev/null
+++ b/Tools/gobi-factory-reset.c
@@ -0,0 +1,55 @@
+/* gobi-factory-reset.c - resets all Gobis to factory defaults */
+
+#include <stdio.h>
+
+#include <GobiConnectionMgmt/GobiConnectionMgmtAPI.h>
+
+#define MAX_DEVICES   16
+
+typedef struct device {
+  char node[256];
+  char key[16];
+} device_t;
+
+static int reset_device(device_t *dev, char *spc) {
+  ULONG ret = QCWWANConnect(dev->node, dev->key);
+  if (ret) {
+    printf("Connect path '%s' key '%s': %lu\n", dev->node, dev->key, ret);
+    return 1;
+  }
+  ret = ResetToFactoryDefaults(spc);
+  if (ret) {
+    printf("Reset path '%s' key '%s': %lu\n", dev->node, dev->key, ret);
+    QCWWANDisconnect();
+    return ret;
+  }
+  ret = QCWWANDisconnect();
+  if (ret) {
+    printf("Disconnect path '%s' key '%s': %lu\n", dev->node, dev->key, ret);
+  }
+  return ret;
+}
+
+int main(int argc, char *argv[]) {
+  device_t devices[MAX_DEVICES];
+  BYTE num_devices = MAX_DEVICES;
+  ULONG ret;
+  int i;
+
+  if (argc != 2) {
+    printf("Usage: %s <spc>\n", argv[0]);
+    return 1;
+  }
+
+  ret = QCWWANEnumerateDevices(&num_devices, (BYTE*)devices);
+  if (ret) {
+    printf("EnumerateDevices: %lu\n", ret);
+    return 2;
+  }
+
+  for (i = 0; i < num_devices; i++) {
+    ret = ret || reset_device(&devices[i], argv[1]);
+  }
+
+  return ret ? 3 : 0;
+}
diff --git a/Tools/open-deauth.c b/Tools/open-deauth.c
new file mode 100644
index 0000000..b449057
--- /dev/null
+++ b/Tools/open-deauth.c
@@ -0,0 +1,94 @@
+/* open-deauth.c - deauthorize the device while the SDK is in use. This
+ * simulates what happens across a suspend/resume cycle where the device was in
+ * use just before suspend. This test causes the SDK to spawn thousands of
+ * threads and consume nearly all the machine's CPU for about 30 seconds.
+ */
+
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+typedef unsigned char u8;
+
+static void die(char *prefix) {
+	perror(prefix);
+	exit(1);
+}
+
+struct device {
+	char name[256];
+	char key[16];
+};
+
+#define NDEV 16
+
+extern int QCWWANEnumerateDevices(u8 *size, struct device *devices);
+
+static struct device *finddev(void) {
+	int res;
+	u8 size = NDEV;
+	static struct device devices[NDEV];
+	struct device *dev = &devices[0];
+
+	res = QCWWANEnumerateDevices(&size, devices);
+	if (res)
+		die("QCWWANEnumerateDevices");
+	if (size == 0)
+		die("finddev: no devices");
+	return dev;
+}
+
+extern int QCWWANConnect(const char *name, const char *key);
+
+static void connect(const char *name, const char *key) {
+	int res = QCWWANConnect(name, key);
+	if (res)
+		die("QCWWANConnect");
+}
+
+static void deauth(const char *dev) {
+	char path[PATH_MAX];
+	snprintf(path, sizeof(path), "/sys/bus/usb/devices/%s/authorized", dev);
+	int f = open(path, O_WRONLY);
+	if (f == -1)
+		die("open");
+	int bytes = write(f, "0", 1);
+	if (bytes != 1)
+		die("write");
+	close(f);
+}
+
+extern int GetSerialNumbers(size_t esnsz, char *esn, size_t imeisz, char *imei,
+                            size_t meidsz, char *meid);
+
+static void getserials(void) {
+	int res;
+	char esn[1024];
+	char imei[1024];
+	char meid[1024];
+
+	res = GetSerialNumbers(sizeof(esn), esn, sizeof(imei), imei,
+	                       sizeof(meid), meid);
+	if (res)
+		die("GetSerialNumbers");
+}
+
+int main(int argc, char *argv[]) {
+	struct device *dev;
+
+	if (argc < 2) {
+		printf("Usage: %s <usb device>\n", argv[0]);
+		return 0;
+	}
+
+	dev = finddev();
+	connect(dev->name, dev->key);
+	deauth(argv[1]);
+	getserials();
+	printf("ok\n");
+	return 0;
+}
diff --git a/Tools/powercycle-all-gobis b/Tools/powercycle-all-gobis
new file mode 100644
index 0000000..99ca4af
--- /dev/null
+++ b/Tools/powercycle-all-gobis
@@ -0,0 +1,24 @@
+#!/bin/sh
+# This script, sadly, is distinct from gobi-modem-reset.c in gobi-cromo-plugin.
+# gobi-modem-reset is meant to be run setuid with a single USB ID as its target;
+# this script is run from an upstart job (i.e. already as root) before we know
+# the USB ID of the device. This script could be made to just determine the USB
+# device IDs and then invoke gobi-modem-reset, but it seems kind of dirty to
+# introduce a dependency between packages for such a trivial piece of
+# functionality.
+
+ps=''
+for x in /sys/bus/usb/drivers/qcserial/*; do
+	if [ -L "$x" -a -f "$x/../authorized" ] ; then
+		p=$(realpath "$x/../authorized")
+		if echo "$ps" | grep -vq "$p" ; then
+			ps="$ps $p"
+		fi
+	fi
+done
+
+for x in $ps; do
+	echo "reset $x"
+	echo 0 > "$x"
+	echo 1 > "$x"
+done
diff --git a/Tools/sdk-stress.c b/Tools/sdk-stress.c
new file mode 100644
index 0000000..60b2a5c
--- /dev/null
+++ b/Tools/sdk-stress.c
@@ -0,0 +1,77 @@
+/* sdk-stress.c - repeatedly disconnect uncleanly from the SDK
+ * This test exposes a bug in the Qualcomm kernel driver - it is unable to
+ * cleanly handle disconnects that are caused by abnormal process termination.
+ * Basically, the desired behavior is:
+ *   Process 1 calls QCWWANConnect() successfully
+ *   Process 1 terminated abnormally
+ *   Process 2 calls QCWWANConnect() successfully
+ * Currently, Process 2's call will fail with error code 10.
+ * This problem prevents us from restarting cromo if it crashes, since the
+ * restarted instance won't be able to connect to the device.
+ *
+ * Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+typedef unsigned char u8;
+typedef unsigned long u64;
+
+struct device {
+	char name[256];
+	char key[16];
+};
+
+#define NDEV 16
+
+extern u64 QCWWANEnumerateDevices(u8 *size, struct device *devices);
+extern u64 QCWWANConnect(char *name, char *key);
+
+static void test(struct device *dev) {
+	u64 res = QCWWANConnect(dev->name, dev->key);
+	printf("%d: connect: %lu\n", getpid(), res);
+	if (res)
+		exit(1);
+	sleep(2);
+	exit(0);
+}
+
+int main(void) {
+	u8 size = NDEV;
+	struct device devices[NDEV];
+	int res;
+	int status;
+	unsigned int i;
+
+	res = QCWWANEnumerateDevices(&size, devices);
+	if (res)
+		return -1;
+	for (i = 0; i < size; i++) {
+		printf("%d device: %s %s\n", getpid(), devices[i].name,
+		       devices[i].key);
+	}
+
+	while (1) {
+		printf("%d attempt\n", getpid());
+		res = fork();
+		if (res < 0)
+			return -2;
+		if (!res)
+			test(&devices[0]);
+		sleep(1);
+		kill(res, SIGKILL);
+		res = wait(&status);
+		printf("%d wait %d %d\n", getpid(), res, status);
+		if (WIFEXITED(status) && WEXITSTATUS(status) == 1)
+			printf("%d failed\n", res);
+	}
+
+	return 0;
+}