@@ -121,10 +121,12 @@ def autoexit_command(debugger, command, result, internal_dict):\n\
121
121
")
122
122
123
123
typedef struct am_device * AMDeviceRef ;
124
+ mach_error_t AMDeviceSecureStartService (struct am_device * device , CFStringRef service_name , unsigned int * unknown , service_conn_t * handle );
124
125
int AMDeviceSecureTransferPath (int zero , AMDeviceRef device , CFURLRef url , CFDictionaryRef options , void * callback , int cbarg );
125
126
int AMDeviceSecureInstallApplication (int zero , AMDeviceRef device , CFURLRef url , CFDictionaryRef options , void * callback , int cbarg );
126
127
int AMDeviceMountImage (AMDeviceRef device , CFStringRef image , CFDictionaryRef options , void * callback , int cbarg );
127
128
mach_error_t AMDeviceLookupApplications (AMDeviceRef device , CFDictionaryRef options , CFDictionaryRef * result );
129
+ int AMDeviceGetInterfaceType (struct am_device * device );
128
130
129
131
bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true, uninstall = false;
130
132
bool command_only = false;
@@ -145,6 +147,7 @@ pid_t parent = 0;
145
147
pid_t child = 0 ;
146
148
// Signal sent from child to parent process when LLDB finishes.
147
149
const int SIGLLDB = SIGUSR1 ;
150
+ AMDeviceRef best_device_match = NULL ;
148
151
149
152
// Error codes we report on different failures, so scripts can distinguish between user app exit
150
153
// codes and our exit codes. For non app errors we use codes in reserved 128-255 range.
@@ -268,6 +271,125 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
268
271
}
269
272
}
270
273
274
+ // Please ensure that device is connected or the name will be unknown
275
+ const CFStringRef get_device_hardware_name (const AMDeviceRef device ) {
276
+ CFStringRef model = AMDeviceCopyValue (device , 0 , CFSTR ("HardwareModel" ));
277
+ const char * hwmodel = CFStringGetCStringPtr (model , CFStringGetSystemEncoding ());
278
+
279
+ if (hwmodel && !strcmp ("M68AP" , hwmodel ))
280
+ return CFSTR ("iPhone" );
281
+ if (hwmodel && !strcmp ("N45AP" , hwmodel ))
282
+ return CFSTR ("iPod touch" );
283
+ if (hwmodel && !strcmp ("N82AP" , hwmodel ))
284
+ return CFSTR ("iPhone 3G" );
285
+ if (hwmodel && !strcmp ("N72AP" , hwmodel ))
286
+ return CFSTR ("iPod touch 2G" );
287
+ if (hwmodel && !strcmp ("N88AP" , hwmodel ))
288
+ return CFSTR ("iPhone 3GS" );
289
+ if (hwmodel && !strcmp ("N18AP" , hwmodel ))
290
+ return CFSTR ("iPod touch 3G" );
291
+ if (hwmodel && !strcmp ("K48AP" , hwmodel ))
292
+ return CFSTR ("iPad" );
293
+ if (hwmodel && !strcmp ("N90AP" , hwmodel ))
294
+ return CFSTR ("iPhone 4 (GSM)" );
295
+ if (hwmodel && !strcmp ("N81AP" , hwmodel ))
296
+ return CFSTR ("iPod touch 4G" );
297
+ if (hwmodel && !strcmp ("K66AP" , hwmodel ))
298
+ return CFSTR ("Apple TV 2G" );
299
+ if (hwmodel && !strcmp ("N92AP" , hwmodel ))
300
+ return CFSTR ("iPhone 4 (CDMA)" );
301
+ if (hwmodel && !strcmp ("N90BAP" , hwmodel ))
302
+ return CFSTR ("iPhone 4 (GSM, revision A)" );
303
+ if (hwmodel && !strcmp ("K93AP" , hwmodel ))
304
+ return CFSTR ("iPad 2" );
305
+ if (hwmodel && !strcmp ("K94AP" , hwmodel ))
306
+ return CFSTR ("iPad 2 (GSM)" );
307
+ if (hwmodel && !strcmp ("K95AP" , hwmodel ))
308
+ return CFSTR ("iPad 2 (CDMA)" );
309
+ if (hwmodel && !strcmp ("K93AAP" , hwmodel ))
310
+ return CFSTR ("iPad 2 (Wi-Fi, revision A)" );
311
+ if (hwmodel && !strcmp ("P105AP" , hwmodel ))
312
+ return CFSTR ("iPad mini" );
313
+ if (hwmodel && !strcmp ("P106AP" , hwmodel ))
314
+ return CFSTR ("iPad mini (GSM)" );
315
+ if (hwmodel && !strcmp ("P107AP" , hwmodel ))
316
+ return CFSTR ("iPad mini (CDMA)" );
317
+ if (hwmodel && !strcmp ("N94AP" , hwmodel ))
318
+ return CFSTR ("iPhone 4S" );
319
+ if (hwmodel && !strcmp ("N41AP" , hwmodel ))
320
+ return CFSTR ("iPhone 5 (GSM)" );
321
+ if (hwmodel && !strcmp ("N42AP" , hwmodel ))
322
+ return CFSTR ("iPhone 5 (Global/CDMA)" );
323
+ if (hwmodel && !strcmp ("N48AP" , hwmodel ))
324
+ return CFSTR ("iPhone 5c (GSM)" );
325
+ if (hwmodel && !strcmp ("N49AP" , hwmodel ))
326
+ return CFSTR ("iPhone 5c (Global/CDMA)" );
327
+ if (hwmodel && !strcmp ("N51AP" , hwmodel ))
328
+ return CFSTR ("iPhone 5s (GSM)" );
329
+ if (hwmodel && !strcmp ("N53AP" , hwmodel ))
330
+ return CFSTR ("iPhone 5s (Global/CDMA)" );
331
+ if (hwmodel && !strcmp ("J1AP" , hwmodel ))
332
+ return CFSTR ("iPad 3" );
333
+ if (hwmodel && !strcmp ("J2AP" , hwmodel ))
334
+ return CFSTR ("iPad 3 (GSM)" );
335
+ if (hwmodel && !strcmp ("J2AAP" , hwmodel ))
336
+ return CFSTR ("iPad 3 (CDMA)" );
337
+ if (hwmodel && !strcmp ("P101AP" , hwmodel ))
338
+ return CFSTR ("iPad 4" );
339
+ if (hwmodel && !strcmp ("P102AP" , hwmodel ))
340
+ return CFSTR ("iPad 4 (GSM)" );
341
+ if (hwmodel && !strcmp ("P103AP" , hwmodel ))
342
+ return CFSTR ("iPad 4 (CDMA)" );
343
+ if (hwmodel && !strcmp ("N78AP" , hwmodel ))
344
+ return CFSTR ("iPod touch 5G" );
345
+ if (hwmodel && !strcmp ("J33AP" , hwmodel ))
346
+ return CFSTR ("Apple TV 3G" );
347
+ if (hwmodel && !strcmp ("J33IAP" , hwmodel ))
348
+ return CFSTR ("Apple TV 3.1G" );
349
+
350
+ return CFSTR ("Unknown Device" );
351
+ }
352
+
353
+ CFStringRef get_device_full_name (const AMDeviceRef device ) {
354
+ CFStringRef full_name = NULL ,
355
+ device_udid = AMDeviceCopyDeviceIdentifier (device ),
356
+ device_name = NULL ,
357
+ model_name = NULL ;
358
+
359
+ AMDeviceConnect (device );
360
+
361
+ device_name = AMDeviceCopyValue (device , 0 , CFSTR ("DeviceName" )),
362
+ model_name = get_device_hardware_name (device );
363
+
364
+ if (device_name != NULL && model_name != NULL )
365
+ full_name = CFStringCreateWithFormat (NULL , NULL , CFSTR ("%@ '%@' (%@)" ), model_name , device_name , device_udid );
366
+ else
367
+ full_name = CFStringCreateWithFormat (NULL , NULL , CFSTR ("(%@)" ), device_udid );
368
+
369
+ AMDeviceDisconnect (device );
370
+
371
+ if (device_udid != NULL )
372
+ CFRelease (device_udid );
373
+ if (device_name != NULL )
374
+ CFRelease (device_name );
375
+ if (model_name != NULL )
376
+ CFRelease (model_name );
377
+
378
+ return full_name ;
379
+ }
380
+
381
+ CFStringRef get_device_interface_name (const AMDeviceRef device ) {
382
+ // AMDeviceGetInterfaceType(device) 0=Unknown, 1 = Direct/USB, 2 = Indirect/WIFI
383
+ switch (AMDeviceGetInterfaceType (device )) {
384
+ case 1 :
385
+ return CFSTR ("USB" );
386
+ case 2 :
387
+ return CFSTR ("WIFI" );
388
+ default :
389
+ return CFSTR ("Unknown Connection" );
390
+ }
391
+ }
392
+
271
393
CFMutableArrayRef get_device_product_version_parts (AMDeviceRef device ) {
272
394
CFStringRef version = AMDeviceCopyValue (device , 0 , CFSTR ("ProductVersion" ));
273
395
CFArrayRef parts = CFStringCreateArrayBySeparatingStrings (NULL , version , CFSTR ("." ));
@@ -748,13 +870,24 @@ void setup_dummy_pipe_on_stdin(int pfd[2]) {
748
870
}
749
871
750
872
void launch_debugger (AMDeviceRef device , CFURLRef url ) {
873
+ CFStringRef device_full_name = get_device_full_name (device ),
874
+ device_interface_name = get_device_interface_name (device );
875
+
751
876
AMDeviceConnect (device );
752
877
assert (AMDeviceIsPaired (device ));
753
878
assert (AMDeviceValidatePairing (device ) == 0 );
754
879
assert (AMDeviceStartSession (device ) == 0 );
755
880
756
881
printf ("------ Debug phase ------\n" );
757
882
883
+ if (AMDeviceGetInterfaceType (device ) == 2 )
884
+ {
885
+ printf ("Cannot debug %s over %s.\n" , CFStringGetCStringPtr (device_full_name , CFStringGetSystemEncoding ()), CFStringGetCStringPtr (device_interface_name , CFStringGetSystemEncoding ()));
886
+ exit (0 );
887
+ }
888
+
889
+ printf ("Starting debug of %s connected through %s...\n" , CFStringGetCStringPtr (device_full_name , CFStringGetSystemEncoding ()), CFStringGetCStringPtr (device_interface_name , CFStringGetSystemEncoding ()));
890
+
758
891
mount_developer_image (device ); // put debugserver on the device
759
892
start_remote_debug_server (device ); // start debugserver
760
893
write_lldb_prep_cmds (device , url ); // dump the necessary lldb commands into a file
@@ -1030,8 +1163,12 @@ void upload_file(AMDeviceRef device) {
1030
1163
}
1031
1164
1032
1165
void handle_device (AMDeviceRef device ) {
1033
- if (found_device ) return ; // handle one device only
1034
- CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier (device );
1166
+ if (found_device )
1167
+ return ; // handle one device only
1168
+
1169
+ CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier (device ),
1170
+ device_full_name = get_device_full_name (device ),
1171
+ device_interface_name = get_device_interface_name (device );
1035
1172
1036
1173
if (device_id != NULL ) {
1037
1174
if (strcmp (device_id , CFStringGetCStringPtr (found_device_id , CFStringGetSystemEncoding ())) == 0 ) {
@@ -1044,7 +1181,7 @@ void handle_device(AMDeviceRef device) {
1044
1181
}
1045
1182
1046
1183
if (detect_only ) {
1047
- printf ("[....] Found device (%s) .\n" , CFStringGetCStringPtr (found_device_id , CFStringGetSystemEncoding ()));
1184
+ printf ("[....] Found %s connected through %s .\n" , CFStringGetCStringPtr (device_full_name , CFStringGetSystemEncoding ()), CFStringGetCStringPtr ( device_interface_name , CFStringGetSystemEncoding ()));
1048
1185
exit (0 );
1049
1186
}
1050
1187
@@ -1089,39 +1226,45 @@ void handle_device(AMDeviceRef device) {
1089
1226
1090
1227
if (install ) {
1091
1228
printf ("------ Install phase ------\n" );
1092
- printf ("[ 0%%] Found device (%s) , beginning install\n" , CFStringGetCStringPtr (found_device_id , CFStringGetSystemEncoding ()));
1229
+ printf ("[ 0%%] Found %s connected through %s , beginning install\n" , CFStringGetCStringPtr (device_full_name , CFStringGetSystemEncoding ()), CFStringGetCStringPtr ( device_interface_name , CFStringGetSystemEncoding ()));
1093
1230
1094
1231
AMDeviceConnect (device );
1095
1232
assert (AMDeviceIsPaired (device ));
1096
1233
assert (AMDeviceValidatePairing (device ) == 0 );
1097
1234
assert (AMDeviceStartSession (device ) == 0 );
1098
1235
1099
1236
1100
-
1237
+ // NOTE: the secure version doesn't seem to require us to start the AFC service
1101
1238
service_conn_t afcFd ;
1102
- assert (AMDeviceStartService (device , CFSTR ("com.apple.afc" ), & afcFd , NULL ) == 0 );
1239
+ assert (AMDeviceSecureStartService (device , CFSTR ("com.apple.afc" ), NULL , & afcFd ) == 0 );
1103
1240
assert (AMDeviceStopSession (device ) == 0 );
1104
1241
assert (AMDeviceDisconnect (device ) == 0 );
1105
- assert (AMDeviceTransferApplication (afcFd , path , NULL , transfer_callback , NULL ) == 0 );
1106
-
1107
- close (afcFd );
1108
1242
1109
1243
CFStringRef keys [] = { CFSTR ("PackageType" ) };
1110
1244
CFStringRef values [] = { CFSTR ("Developer" ) };
1111
1245
CFDictionaryRef options = CFDictionaryCreate (NULL , (const void * * )& keys , (const void * * )& values , 1 , & kCFTypeDictionaryKeyCallBacks , & kCFTypeDictionaryValueCallBacks );
1112
1246
1247
+ //assert(AMDeviceTransferApplication(afcFd, path, NULL, transfer_callback, NULL) == 0);
1248
+ assert (AMDeviceSecureTransferPath (0 , device , url , options , transfer_callback , 0 )== 0 );
1249
+
1250
+ close (afcFd );
1251
+
1252
+
1253
+
1113
1254
AMDeviceConnect (device );
1114
1255
assert (AMDeviceIsPaired (device ));
1115
1256
assert (AMDeviceValidatePairing (device ) == 0 );
1116
1257
assert (AMDeviceStartSession (device ) == 0 );
1117
1258
1118
- service_conn_t installFd ;
1119
- assert (AMDeviceStartService (device , CFSTR ("com.apple.mobile.installation_proxy" ), & installFd , NULL ) == 0 );
1259
+ // // NOTE: the secure version doesn't seem to require us to start the installation_proxy service
1260
+ // // Although I can't find it right now, I in some code that the first param of AMDeviceSecureInstallApplication was a "dontStartInstallProxy"
1261
+ // // implying this is done for us by iOS already
1120
1262
1121
- assert ( AMDeviceStopSession ( device ) == 0 ) ;
1122
- assert (AMDeviceDisconnect (device ) == 0 );
1263
+ //service_conn_t installFd ;
1264
+ // assert(AMDeviceSecureStartService (device, CFSTR("com.apple.mobile.installation_proxy"), NULL, &installFd ) == 0);
1123
1265
1124
- mach_error_t result = AMDeviceInstallApplication (installFd , path , options , install_callback , NULL );
1266
+ //mach_error_t result = AMDeviceInstallApplication(installFd, path, options, install_callback, NULL);
1267
+ mach_error_t result = AMDeviceSecureInstallApplication (0 , device , url , options , install_callback , 0 );
1125
1268
if (result != 0 )
1126
1269
{
1127
1270
char * error = "Unknown error." ;
@@ -1131,31 +1274,50 @@ void handle_device(AMDeviceRef device) {
1131
1274
exit (exitcode_error );
1132
1275
}
1133
1276
1134
- close (installFd );
1277
+ // close(installFd);
1278
+
1279
+ assert (AMDeviceStopSession (device ) == 0 );
1280
+ assert (AMDeviceDisconnect (device ) == 0 );
1135
1281
1136
1282
CFRelease (path );
1137
1283
CFRelease (options );
1138
1284
1139
1285
printf ("[100%%] Installed package %s\n" , app_path );
1140
1286
}
1141
1287
1142
- if (!debug ) exit (0 ); // no debug phase
1288
+ if (!debug )
1289
+ exit (0 ); // no debug phase
1290
+
1143
1291
launch_debugger (device , url );
1144
1292
}
1145
1293
1146
1294
void device_callback (struct am_device_notification_callback_info * info , void * arg ) {
1147
1295
switch (info -> msg ) {
1148
1296
case ADNCI_MSG_CONNECTED :
1149
- handle_device (info -> dev );
1297
+ if (device_id != NULL || !debug || AMDeviceGetInterfaceType (info -> dev ) != 2 ) {
1298
+ handle_device (info -> dev );
1299
+ } else if (best_device_match == NULL ) {
1300
+ best_device_match = info -> dev ;
1301
+ CFRetain (best_device_match );
1302
+ }
1150
1303
default :
1151
1304
break ;
1152
1305
}
1153
1306
}
1154
1307
1155
1308
void timeout_callback (CFRunLoopTimerRef timer , void * info ) {
1156
1309
if (!found_device ) {
1157
- printf ("[....] Timed out waiting for device.\n" );
1158
- exit (exitcode_error );
1310
+ if (best_device_match != NULL ) {
1311
+ handle_device (best_device_match );
1312
+
1313
+ CFRelease (best_device_match );
1314
+ best_device_match = NULL ;
1315
+ }
1316
+
1317
+ if (!found_device ) {
1318
+ printf ("[....] Timed out waiting for device.\n" );
1319
+ exit (exitcode_error );
1320
+ }
1159
1321
}
1160
1322
}
1161
1323
0 commit comments