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;
+}