summaryrefslogtreecommitdiffstats
path: root/tools/idevicediagnostics.c
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2012-08-03 23:38:35 +0200
committerGravatar Martin Szulecki2012-10-21 14:19:50 +0200
commitb086f13c27558ca61645691ed40c2e25dd6e56dd (patch)
tree6e52454dca6580474070857d0f4616179afdecd5 /tools/idevicediagnostics.c
parent1e81510664853114d123a7154e236b538356111b (diff)
downloadlibimobiledevice-b086f13c27558ca61645691ed40c2e25dd6e56dd.tar.gz
libimobiledevice-b086f13c27558ca61645691ed40c2e25dd6e56dd.tar.bz2
idevicediagnostics: Implement multiple commands to make the tool useful
Diffstat (limited to 'tools/idevicediagnostics.c')
-rw-r--r--tools/idevicediagnostics.c235
1 files changed, 200 insertions, 35 deletions
diff --git a/tools/idevicediagnostics.c b/tools/idevicediagnostics.c
index e0bcb48..93211c3 100644
--- a/tools/idevicediagnostics.c
+++ b/tools/idevicediagnostics.c
@@ -31,13 +31,24 @@
31#include <libimobiledevice/lockdown.h> 31#include <libimobiledevice/lockdown.h>
32#include <libimobiledevice/diagnostics_relay.h> 32#include <libimobiledevice/diagnostics_relay.h>
33 33
34enum cmd_mode {
35 CMD_NONE = 0,
36 CMD_SLEEP,
37 CMD_RESTART,
38 CMD_SHUTDOWN,
39 CMD_DIAGNOSTICS,
40 CMD_MOBILEGESTALT,
41 CMD_IOREGISTRY
42};
43
34static void print_xml(plist_t node) 44static void print_xml(plist_t node)
35{ 45{
36 char *xml = NULL; 46 char *xml = NULL;
37 uint32_t len = 0; 47 uint32_t len = 0;
38 plist_to_xml(node, &xml, &len); 48 plist_to_xml(node, &xml, &len);
39 if (xml) 49 if (xml) {
40 puts(xml); 50 puts(xml);
51 }
41} 52}
42 53
43void print_usage(int argc, char **argv); 54void print_usage(int argc, char **argv);
@@ -45,12 +56,17 @@ void print_usage(int argc, char **argv);
45int main(int argc, char **argv) 56int main(int argc, char **argv)
46{ 57{
47 idevice_t device = NULL; 58 idevice_t device = NULL;
48 lockdownd_client_t lckd = NULL; 59 lockdownd_client_t lockdown_client = NULL;
49 diagnostics_relay_client_t diagc = NULL; 60 diagnostics_relay_client_t diagnostics_client = NULL;
61 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
50 uint16_t port = 0; 62 uint16_t port = 0;
51 int result = -1; 63 int result = -1;
52 int i; 64 int i;
53 char *udid = NULL; 65 char *udid = NULL;
66 int cmd = CMD_NONE;
67 char* cmd_arg = NULL;
68 plist_t node = NULL;
69 plist_t keys = NULL;
54 70
55 /* parse cmdline args */ 71 /* parse cmdline args */
56 for (i = 1; i < argc; i++) { 72 for (i = 1; i < argc; i++) {
@@ -62,14 +78,81 @@ int main(int argc, char **argv)
62 i++; 78 i++;
63 if (!argv[i] || (strlen(argv[i]) != 40)) { 79 if (!argv[i] || (strlen(argv[i]) != 40)) {
64 print_usage(argc, argv); 80 print_usage(argc, argv);
65 return 0; 81 result = 0;
82 goto cleanup;
66 } 83 }
67 udid = strdup(argv[i]); 84 udid = strdup(argv[i]);
68 continue; 85 continue;
69 } 86 }
70 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 87 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
71 print_usage(argc, argv); 88 print_usage(argc, argv);
72 return 0; 89 result = 0;
90 goto cleanup;
91 }
92 else if (!strcmp(argv[i], "sleep")) {
93 cmd = CMD_SLEEP;
94 }
95 else if (!strcmp(argv[i], "restart")) {
96 cmd = CMD_RESTART;
97 }
98 else if (!strcmp(argv[i], "shutdown")) {
99 cmd = CMD_SHUTDOWN;
100 }
101 else if (!strcmp(argv[i], "diagnostics")) {
102 cmd = CMD_DIAGNOSTICS;
103 /* read type */
104 i++;
105 if (!argv[i] || ((strcmp(argv[i], "All") != 0) && (strcmp(argv[i], "WiFi") != 0) && (strcmp(argv[i], "GasGauge") != 0) && (strcmp(argv[i], "NAND") != 0))) {
106 if (argv[i] == NULL) {
107 cmd_arg = strdup("All");
108 continue;
109 }
110
111 if (!strncmp(argv[i], "-", 1)) {
112 cmd_arg = strdup("All");
113 i--;
114 continue;
115 }
116
117 printf("Unknown TYPE %s\n", argv[i]);
118 print_usage(argc, argv);
119 goto cleanup;
120 }
121
122 cmd_arg = strdup(argv[i]);
123 continue;
124 }
125 else if (!strcmp(argv[i], "mobilegestalt")) {
126 cmd = CMD_MOBILEGESTALT;
127 /* read keys */
128 i++;
129
130 if (!argv[i] || argv[i] == NULL || (!strncmp(argv[i], "-", 1))) {
131 printf("Please supply the key to query.\n");
132 print_usage(argc, argv);
133 goto cleanup;
134 }
135
136 keys = plist_new_array();
137 while(1) {
138 if (argv[i] && (strlen(argv[i]) >= 2) && (strncmp(argv[i], "-", 1) != 0)) {
139 plist_array_append_item(keys, plist_new_string(argv[i]));
140 i++;
141 } else {
142 i--;
143 break;
144 }
145 }
146 continue;
147 }
148 else if (!strcmp(argv[i], "ioreg")) {
149 cmd = CMD_IOREGISTRY;
150 /* read plane */
151 i++;
152 if (argv[i]) {
153 cmd_arg = strdup(argv[i]);
154 }
155 continue;
73 } 156 }
74 else { 157 else {
75 print_usage(argc, argv); 158 print_usage(argc, argv);
@@ -77,58 +160,140 @@ int main(int argc, char **argv)
77 } 160 }
78 } 161 }
79 162
163 /* verify options */
164 if (cmd == CMD_NONE) {
165 print_usage(argc, argv);
166 goto cleanup;
167 }
168
80 if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) { 169 if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) {
81 printf("No device found, is it plugged in?\n"); 170 printf("No device found, is it plugged in?\n");
82 if (udid) { 171 goto cleanup;
83 free(udid);
84 }
85 return -1;
86 } 172 }
173
87 if (udid) { 174 if (udid) {
88 free(udid); 175 free(udid);
89 } 176 }
90 177
91 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lckd, NULL)) { 178 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lockdown_client, NULL)) {
92 idevice_free(device); 179 idevice_free(device);
93 printf("Exiting.\n"); 180 printf("Unable to connect to lockdownd.\n");
94 return -1; 181 goto cleanup;
95 } 182 }
96 183
97 lockdownd_start_service(lckd, "com.apple.mobile.diagnostics_relay", &port); 184 /* attempt to use newer diagnostics service available on iOS 5 and later */
98 lockdownd_client_free(lckd); 185 ret = lockdownd_start_service(lockdown_client, "com.apple.mobile.diagnostics_relay", &port);
99 if (port > 0) { 186 if (ret != LOCKDOWN_E_SUCCESS) {
100 if (diagnostics_relay_client_new(device, port, &diagc) != DIAGNOSTICS_RELAY_E_SUCCESS) { 187 /* attempt to use older diagnostics service */
188 ret = lockdownd_start_service(lockdown_client, "com.apple.iosdiagnostics.relay", &port);
189 }
190
191 lockdownd_client_free(lockdown_client);
192
193 if ((ret == LOCKDOWN_E_SUCCESS) && (port > 0)) {
194 if (diagnostics_relay_client_new(device, port, &diagnostics_client) != DIAGNOSTICS_RELAY_E_SUCCESS) {
101 printf("Could not connect to diagnostics_relay!\n"); 195 printf("Could not connect to diagnostics_relay!\n");
102 result = -1; 196 result = -1;
103 } else { 197 } else {
104 plist_t node = NULL; 198 switch (cmd) {
105 if (diagnostics_relay_request_diagnostics(diagc, DIAGNOSTICS_RELAY_REQUEST_TYPE_ALL, &node) != DIAGNOSTICS_RELAY_E_SUCCESS) { 199 case CMD_SLEEP:
106 printf("Unable to retrieve diagnostics"); 200 if (diagnostics_relay_sleep(diagnostics_client) == DIAGNOSTICS_RELAY_E_SUCCESS) {
201 printf("Putting device into deep sleep mode.\n");
202 result = EXIT_SUCCESS;
203 } else {
204 printf("Failed to put device into deep sleep mode.\n");
205 }
206 break;
207 case CMD_RESTART:
208 if (diagnostics_relay_restart(diagnostics_client, 0) == DIAGNOSTICS_RELAY_E_SUCCESS) {
209 printf("Restarting device.\n");
210 result = EXIT_SUCCESS;
211 } else {
212 printf("Failed to restart device.\n");
213 }
214 break;
215 case CMD_SHUTDOWN:
216 if (diagnostics_relay_shutdown(diagnostics_client, 0) == DIAGNOSTICS_RELAY_E_SUCCESS) {
217 printf("Shutting down device.\n");
218 result = EXIT_SUCCESS;
219 } else {
220 printf("Failed to shutdown device.\n");
221 }
222 break;
223 case CMD_MOBILEGESTALT:
224 if (diagnostics_relay_query_mobilegestalt(diagnostics_client, keys, &node) == DIAGNOSTICS_RELAY_E_SUCCESS) {
225 if (node) {
226 print_xml(node);
227 result = EXIT_SUCCESS;
228 }
229 } else {
230 printf("Unable to query mobilegestalt keys.\n");
231 }
232 break;
233 case CMD_IOREGISTRY:
234 if (diagnostics_relay_query_ioregistry_plane(diagnostics_client, cmd_arg == NULL ? "": cmd_arg, &node) == DIAGNOSTICS_RELAY_E_SUCCESS) {
235 if (node) {
236 print_xml(node);
237 result = EXIT_SUCCESS;
238 }
239 } else {
240 printf("Unable to retrieve IORegistry from device.\n");
241 }
242 break;
243 case CMD_DIAGNOSTICS:
244 default:
245 if (diagnostics_relay_request_diagnostics(diagnostics_client, cmd_arg, &node) == DIAGNOSTICS_RELAY_E_SUCCESS) {
246 if (node) {
247 print_xml(node);
248 result = EXIT_SUCCESS;
249 }
250 } else {
251 printf("Unable to retrieve diagnostics from device.\n");
252 }
253 break;
107 } 254 }
108 if (node) { 255
109 print_xml(node); 256 diagnostics_relay_goodbye(diagnostics_client);
110 plist_free(node); 257 diagnostics_relay_client_free(diagnostics_client);
111 }
112 diagnostics_relay_goodbye(diagc);
113 diagnostics_relay_client_free(diagc);
114 } 258 }
115 } else { 259 } else {
116 printf("Could not start diagnostics service!\n"); 260 printf("Could not start diagnostics service!\n");
117 } 261 }
262
118 idevice_free(device); 263 idevice_free(device);
119 264
265cleanup:
266 if (udid) {
267 free(udid);
268 }
269 if (node) {
270 plist_free(node);
271 }
272 if (keys) {
273 plist_free(keys);
274 }
275 if (cmd_arg) {
276 free(cmd_arg);
277 }
120 return result; 278 return result;
121} 279}
122 280
123void print_usage(int argc, char **argv) 281void print_usage(int argc, char **argv)
124{ 282{
125 char *name = NULL; 283 char *name = NULL;
126 284 name = strrchr(argv[0], '/');
127 name = strrchr(argv[0], '/'); 285 printf("Usage: %s COMMAND [OPTIONS]\n", (name ? name + 1: argv[0]));
128 printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); 286 printf("Use diagnostics interface of a device running iOS 4 or later.\n\n");
129 printf("Retrieves diagnostics information from a device.\n\n"); 287 printf(" Where COMMAND is one of:\n");
130 printf(" -d, --debug\t\tenable communication debugging\n"); 288 printf(" diagnostics [TYPE]\t\tprint diagnostics information from device by TYPE (All, WiFi, GasGauge, NAND)\n");
131 printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n"); 289 printf(" mobilegestalt KEY [...]\tprint mobilegestalt keys passed as arguments seperated by a space.\n");
132 printf(" -h, --help\t\tprints usage information\n"); 290 printf(" ioreg [PLANE]\t\t\tprint IORegistry of device, optionally by PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n");
133 printf("\n"); 291 printf(" shutdown\t\t\tshutdown device\n");
292 printf(" restart\t\t\trestart device\n");
293 printf(" sleep\t\t\t\tput device into sleep mode (disconnects from host)\n\n");
294 printf(" The following OPTIONS are accepted:\n");
295 printf(" -d, --debug\t\tenable communication debugging\n");
296 printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n");
297 printf(" -h, --help\t\tprints usage information\n");
298 printf("\n");
134} 299}