summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2014-12-23 14:12:11 +0100
committerGravatar Martin Szulecki2015-01-12 16:27:43 +0100
commit016e06d4938e73bd4c0417dad2aacd5ea2b53152 (patch)
tree49d1fd190dfc123667435d93086552bed5f7c162
parent1d9e6e351b51e7401898dde96418c0ee10ad878f (diff)
downloadlibimobiledevice-016e06d4938e73bd4c0417dad2aacd5ea2b53152.tar.gz
libimobiledevice-016e06d4938e73bd4c0417dad2aacd5ea2b53152.tar.bz2
Add new "idevicenotificationproxy" tool to post or observe notifications
-rw-r--r--docs/Makefile.am2
-rw-r--r--docs/idevicenotificationproxy.133
-rw-r--r--tools/Makefile.am7
-rw-r--r--tools/idevicenotificationproxy.c257
4 files changed, 297 insertions, 2 deletions
diff --git a/docs/Makefile.am b/docs/Makefile.am
index e9fc21c..d788297 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -1,4 +1,4 @@
-man_MANS = idevice_id.1 ideviceinfo.1 idevicesyslog.1 idevicebackup.1 idevicebackup2.1 ideviceimagemounter.1 idevicescreenshot.1 idevicepair.1 ideviceenterrecovery.1 idevicedate.1 ideviceprovision.1 idevicedebugserverproxy.1 idevicediagnostics.1 idevicecrashreport.1 idevicename.1 idevicedebug.1
+man_MANS = idevice_id.1 ideviceinfo.1 idevicesyslog.1 idevicebackup.1 idevicebackup2.1 ideviceimagemounter.1 idevicescreenshot.1 idevicepair.1 ideviceenterrecovery.1 idevicedate.1 ideviceprovision.1 idevicedebugserverproxy.1 idevicediagnostics.1 idevicecrashreport.1 idevicename.1 idevicedebug.1 idevicenotificationproxy.1
EXTRA_DIST = $(man_MANS)
diff --git a/docs/idevicenotificationproxy.1 b/docs/idevicenotificationproxy.1
new file mode 100644
index 0000000..d7ecb32
--- /dev/null
+++ b/docs/idevicenotificationproxy.1
@@ -0,0 +1,33 @@
+.TH "idevicenotificationproxy" 1
+.SH NAME
+idevicenotificationproxy \- Post or observe notifications on a device.
+.SH SYNOPSIS
+.B idevicenotificationproxy
+[OPTIONS] COMMAND
+
+.SH DESCRIPTION
+
+Post or observe notifications on an iOS device from the command line.
+
+.SH OPTIONS
+.TP
+.B \-u, \-\-udid UDID
+target specific device by its 40-digit device UDID.
+.TP
+.B \-d, \-\-debug
+enable communication debugging.
+.TP
+.B \-h, \-\-help
+prints usage information.
+
+.SH COMMANDS
+.TP
+.B post ID [ID...]
+post notification IDs to device and exit.
+.TP
+.B observe ID [ID...]
+observe notification IDs in the foreground until CTRL+C or signal is received.
+
+.SH AUTHORS
+
+Martin Szulecki
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 8cda9f5..698e083 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
AM_CFLAGS = $(GLOBAL_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgcrypt_CFLAGS) $(openssl_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS)
AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgcrypt_LIBS) $(openssl_LIBS) $(libplist_LIBS)
-bin_PROGRAMS = idevice_id ideviceinfo idevicename idevicepair idevicesyslog ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate idevicebackup idevicebackup2 ideviceprovision idevicedebugserverproxy idevicediagnostics idevicedebug
+bin_PROGRAMS = idevice_id ideviceinfo idevicename idevicepair idevicesyslog ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate idevicebackup idevicebackup2 ideviceprovision idevicedebugserverproxy idevicediagnostics idevicedebug idevicenotificationproxy
ideviceinfo_SOURCES = ideviceinfo.c
ideviceinfo_CFLAGS = $(AM_CFLAGS)
@@ -80,6 +80,11 @@ idevicedebug_CFLAGS = $(AM_CFLAGS)
idevicedebug_LDFLAGS = $(top_builddir)/common/libinternalcommon.la $(AM_LDFLAGS)
idevicedebug_LDADD = $(top_builddir)/src/libimobiledevice.la
+idevicenotificationproxy_SOURCES = idevicenotificationproxy.c
+idevicenotificationproxy_CFLAGS = $(AM_CFLAGS)
+idevicenotificationproxy_LDFLAGS = $(AM_LDFLAGS)
+idevicenotificationproxy_LDADD = $(top_builddir)/src/libimobiledevice.la
+
if !WIN32
bin_PROGRAMS += idevicecrashreport
idevicecrashreport_SOURCES = idevicecrashreport.c
diff --git a/tools/idevicenotificationproxy.c b/tools/idevicenotificationproxy.c
new file mode 100644
index 0000000..15a3ba8
--- /dev/null
+++ b/tools/idevicenotificationproxy.c
@@ -0,0 +1,257 @@
+/*
+ * idevicenotificationproxy.c
+ * Simple client for the notification_proxy service
+ *
+ * Copyright (c) 2009-2015 Martin Szulecki All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+#include <windows.h>
+#define sleep(x) Sleep(x*1000)
+#else
+#include <unistd.h>
+#endif
+
+#include <libimobiledevice/libimobiledevice.h>
+#include <libimobiledevice/lockdown.h>
+#include <libimobiledevice/notification_proxy.h>
+
+enum cmd_mode {
+ CMD_NONE = 0,
+ CMD_OBSERVE,
+ CMD_POST
+};
+
+static int quit_flag = 0;
+
+/**
+ * signal handler function for cleaning up properly
+ */
+static void clean_exit(int sig)
+{
+ fprintf(stderr, "Exiting...\n");
+ quit_flag++;
+}
+
+static void print_usage(int argc, char **argv)
+{
+ char *name = NULL;
+
+ name = strrchr(argv[0], '/');
+ printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
+ printf("Post or observe notifications on a device.\n\n");
+ printf(" Where COMMAND is one of:\n");
+ printf(" post ID [...]\t\tpost notification IDs to device and exit\n");
+ printf(" observe ID [...]\tobserve notification IDs in the foreground until CTRL+C or signal is received\n");
+ printf("\n");
+ printf(" The following OPTIONS are accepted:\n");
+ printf(" -d, --debug\t\tenable communication debugging\n");
+ printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n");
+ printf(" -h, --help\t\tprints usage information\n");
+ printf("\n");
+}
+
+static void notify_cb(const char *notification, void *user_data)
+{
+ printf("> %s\n", notification);
+}
+
+int main(int argc, char *argv[])
+{
+ lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
+ lockdownd_service_descriptor_t service = NULL;
+ lockdownd_client_t client = NULL;
+ idevice_t device = NULL;
+ np_client_t gnp = NULL;
+
+ int result = -1;
+ int i;
+ const char* udid = NULL;
+ int cmd = CMD_NONE;
+ char* cmd_arg = NULL;
+
+ int count = 0;
+ char **nspec = NULL;
+ char **nspectmp = NULL;
+
+ signal(SIGINT, clean_exit);
+ signal(SIGTERM, clean_exit);
+#ifndef WIN32
+ signal(SIGQUIT, clean_exit);
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ /* parse cmdline args */
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
+ idevice_set_debug_level(1);
+ continue;
+ }
+ else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
+ i++;
+ if (!argv[i] || (strlen(argv[i]) != 40)) {
+ print_usage(argc, argv);
+ result = 0;
+ goto cleanup;
+ }
+ udid = argv[i];
+ continue;
+ }
+ else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
+ print_usage(argc, argv);
+ result = 0;
+ goto cleanup;
+ }
+ else if (!strcmp(argv[i], "post") || !strcmp(argv[i], "observe")) {
+ cmd = CMD_POST;
+ if (!strcmp(argv[i], "observe")) {
+ cmd = CMD_OBSERVE;
+ }
+
+ i++;
+
+ if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) {
+ printf("Please supply a valid notification identifier.\n");
+ print_usage(argc, argv);
+ goto cleanup;
+ }
+
+ count = 0;
+ nspec = malloc(sizeof(char*) * (count+1));
+
+ while(1) {
+ if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) {
+ nspectmp = realloc(nspec, sizeof(char*) * (count+1));
+ nspectmp[count] = strdup(argv[i]);
+ nspec = nspectmp;
+ count = count+1;
+ i++;
+ } else {
+ i--;
+ break;
+ }
+ }
+
+ nspectmp = realloc(nspec, sizeof(char*) * (count+1));
+ nspectmp[count] = NULL;
+ nspec = nspectmp;
+ continue;
+ }
+ else {
+ print_usage(argc, argv);
+ return 0;
+ }
+ }
+
+ /* verify options */
+ if (cmd == CMD_NONE) {
+ print_usage(argc, argv);
+ goto cleanup;
+ }
+
+ if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) {
+ if (udid) {
+ printf("No device found with udid %s, is it plugged in?\n", udid);
+ } else {
+ printf("No device found, is it plugged in?\n");
+ }
+ goto cleanup;
+ }
+
+ if (LOCKDOWN_E_SUCCESS != (ret = lockdownd_client_new_with_handshake(device, &client, "idevicenotificationproxy"))) {
+ fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ret);
+ goto cleanup;
+ }
+
+ ret = lockdownd_start_service(client, NP_SERVICE_NAME, &service);
+
+ lockdownd_client_free(client);
+
+ if ((ret == LOCKDOWN_E_SUCCESS) && (service->port > 0)) {
+ if (np_client_new(device, service, &gnp) != NP_E_SUCCESS) {
+ printf("Could not connect to notification_proxy!\n");
+ result = -1;
+ } else {
+ np_set_notify_callback(gnp, notify_cb, NULL);
+
+ switch (cmd) {
+ case CMD_POST:
+ i = 0;
+ while(nspec[i] != NULL && i < (count+1)) {
+ printf("< posting \"%s\"\n", nspec[i]);
+ np_post_notification(gnp, nspec[i]);
+ i++;
+ }
+ break;
+ case CMD_OBSERVE:
+ default:
+ i = 0;
+ while(nspec[i] != NULL && i < (count+1)) {
+ printf("! observing \"%s\"\n", nspec[i]);
+ np_observe_notification(gnp, nspec[i]);
+ i++;
+ }
+
+ /* just sleep and wait for notifications */
+ while (!quit_flag) {
+ sleep(1);
+ }
+
+ break;
+ }
+
+ result = EXIT_SUCCESS;
+
+ if (gnp) {
+ np_client_free(gnp);
+ gnp = NULL;
+ }
+ }
+ } else {
+ printf("Could not start notification_proxy service on device.\n");
+ }
+
+ if (service) {
+ lockdownd_service_descriptor_free(service);
+ service = NULL;
+ }
+
+cleanup:
+ if (nspec) {
+ i = 0;
+ while(nspec[i] != NULL && i < (count+1)) {
+ free(nspec[i]);
+ i++;
+ }
+ free(nspec);
+ }
+
+ if (cmd_arg) {
+ free(cmd_arg);
+ }
+
+ if (device)
+ idevice_free(device);
+
+ return result;
+}