summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac28
-rw-r--r--dev/Makefile.am3
-rw-r--r--dev/main.c59
-rw-r--r--fdi/31-apple-mobile-device.fdi5
-rw-r--r--include/libiphone/libiphone.h5
-rw-r--r--src/AFC.c106
-rw-r--r--src/AFC.h40
-rw-r--r--src/Makefile.am4
-rw-r--r--src/NotificationProxy.c263
-rw-r--r--src/NotificationProxy.h31
-rw-r--r--src/usbmux.c7
11 files changed, 529 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac
index ec7e11a..a91d9f9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,4 +68,32 @@ fi
68AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") 68AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter")
69AC_SUBST(GLOBAL_CFLAGS) 69AC_SUBST(GLOBAL_CFLAGS)
70 70
71# check for large file support
72AC_SYS_LARGEFILE
73LFS_CFLAGS=''
74if test "$enable_largefile" != no; then
75 if test "$ac_cv_sys_file_offset_bits" != 'no'; then
76 LFS_CFLAGS="$LFS_CFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
77 else
78 AC_MSG_CHECKING(for native large file support)
79 AC_RUN_IFELSE([#include <unistd.h>
80 int main (int argc, char **argv)
81 {
82 exit(!(sizeof(off_t) == 8));
83 }],
84 [ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64)
85 AC_MSG_RESULT(yes)],
86 [AC_MSG_RESULT(no)])
87 fi
88 if test "$ac_cv_sys_large_files" != 'no'; then
89 LFS_CFLAGS="$LFS_CFLAGS -D_LARGE_FILES=1"
90 fi
91 AC_FUNC_FSEEKO
92 if test "$ac_cv_sys_largefile_source" != 'no'; then
93 LFS_CFLAGS="$LFS_CFLAGS -D_LARGEFILE_SOURCE=1"
94 fi
95fi
96AC_SUBST(LFS_CFLAGS)
97
71AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile libiphone-1.0.pc) 98AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile libiphone-1.0.pc)
99
diff --git a/dev/Makefile.am b/dev/Makefile.am
index f976ccc..f7d1109 100644
--- a/dev/Makefile.am
+++ b/dev/Makefile.am
@@ -1,6 +1,6 @@
1INCLUDES = -I$(top_srcdir)/include 1INCLUDES = -I$(top_srcdir)/include
2 2
3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g 3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS)
4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) 4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)
5 5
6bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient 6bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient
@@ -22,3 +22,4 @@ msyncclient_SOURCES = msyncclient.c
22msyncclient_CFLAGS = $(AM_CFLAGS) 22msyncclient_CFLAGS = $(AM_CFLAGS)
23msyncclient_LDFLAGS = $(AM_LDFLAGS) 23msyncclient_LDFLAGS = $(AM_LDFLAGS)
24msyncclient_LDADD = ../src/libiphone.la 24msyncclient_LDADD = ../src/libiphone.la
25
diff --git a/dev/main.c b/dev/main.c
index 6514bf8..babcf67 100644
--- a/dev/main.c
+++ b/dev/main.c
@@ -27,12 +27,51 @@
27#include <libiphone/libiphone.h> 27#include <libiphone/libiphone.h>
28#include "../src/utils.h" 28#include "../src/utils.h"
29 29
30void perform_syncWillStart(iphone_device_t phone, iphone_lckd_client_t control)
31{
32 int nport = 0;
33 iphone_np_client_t np;
34
35 iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport);
36 if (nport) {
37 printf("::::::::::::::: np was started ::::::::::::\n");
38 iphone_np_new_client(phone, 3555, nport, &np);
39 if (np) {
40 printf("::::::::: PostNotification com.apple.itunes-mobdev.syncWillStart\n");
41 iphone_np_post_notification(np, "com.apple.itunes-mobdev.syncWillStart");
42 iphone_np_free_client(np);
43 }
44 } else {
45 printf("::::::::::::::: np was NOT started ::::::::::::\n");
46 }
47}
48
49void perform_syncDidStart(iphone_device_t phone, iphone_lckd_client_t control)
50{
51 int nport = 0;
52 iphone_np_client_t np;
53
54 iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport);
55 if (nport) {
56 printf("::::::::::::::: np was started ::::::::::::\n");
57 sleep(1);
58 iphone_np_new_client(phone, 3555, nport, &np);
59 if (np) {
60 printf("::::::::: PostNotification com.apple.itunes-mobdev.syncDidStart\n");
61 iphone_np_post_notification(np, "com.apple.itunes-mobdev.syncDidStart");
62 iphone_np_free_client(np);
63 }
64 } else {
65 printf("::::::::::::::: np was NOT started ::::::::::::\n");
66 }
67}
30 68
31int main(int argc, char *argv[]) 69int main(int argc, char *argv[])
32{ 70{
33 int bytes = 0, port = 0, i = 0; 71 int bytes = 0, port = 0, i = 0;
34 iphone_lckd_client_t control = NULL; 72 iphone_lckd_client_t control = NULL;
35 iphone_device_t phone = NULL; 73 iphone_device_t phone = NULL;
74 iphone_afc_file_t lockfile = NULL;
36 75
37 if (argc > 1 && !strcasecmp(argv[1], "--debug")) { 76 if (argc > 1 && !strcasecmp(argv[1], "--debug")) {
38 iphone_set_debug(1); 77 iphone_set_debug(1);
@@ -64,6 +103,16 @@ int main(int argc, char *argv[])
64 iphone_afc_client_t afc = NULL; 103 iphone_afc_client_t afc = NULL;
65 iphone_afc_new_client(phone, 3432, port, &afc); 104 iphone_afc_new_client(phone, 3432, port, &afc);
66 if (afc) { 105 if (afc) {
106 perform_syncWillStart(phone, control);
107
108 iphone_afc_open_file(afc, "/com.apple.itunes.lock_sync", IPHONE_AFC_FILE_WRITE, &lockfile);
109 if (lockfile) {
110 printf("locking file\n");
111 iphone_afc_lock_file(afc, lockfile, 2 | 4);
112
113 perform_syncDidStart(phone, control);
114 }
115
67 char **dirs = NULL; 116 char **dirs = NULL;
68 iphone_afc_get_dir_list(afc, "/eafaedf", &dirs); 117 iphone_afc_get_dir_list(afc, "/eafaedf", &dirs);
69 if (!dirs) 118 if (!dirs)
@@ -138,7 +187,17 @@ int main(int argc, char *argv[])
138 printf("Couldn't read!\n"); 187 printf("Couldn't read!\n");
139 free(threeletterword); 188 free(threeletterword);
140 iphone_afc_close_file(afc, my_file); 189 iphone_afc_close_file(afc, my_file);
190 }
191
192 if (lockfile) {
193 printf("XXX sleeping 2 seconds\n");
194 sleep(2);
195
196 printf("XXX unlocking file\n");
197 iphone_afc_lock_file(afc, lockfile, 8 | 4);
141 198
199 printf("XXX closing file\n");
200 iphone_afc_close_file(afc, lockfile);
142 } 201 }
143 iphone_afc_free_client(afc); 202 iphone_afc_free_client(afc);
144 } else { 203 } else {
diff --git a/fdi/31-apple-mobile-device.fdi b/fdi/31-apple-mobile-device.fdi
index 3e9ccc9..d598409 100644
--- a/fdi/31-apple-mobile-device.fdi
+++ b/fdi/31-apple-mobile-device.fdi
@@ -5,11 +5,12 @@
5 <match key="usb.vendor_id" int="0x05ac"> 5 <match key="usb.vendor_id" int="0x05ac">
6 <match key="usb.product_id" compare_ge="0x1290"> 6 <match key="usb.product_id" compare_ge="0x1290">
7 <match key="usb.product_id" compare_le="0x1293"> 7 <match key="usb.product_id" compare_le="0x1293">
8 <append key="info.capabilities" type="strlist">afc</append> 8 <match key="usb.interface.number" int="0x1">
9 <append key="info.capabilities" type="strlist">afc</append>
10 </match>
9 </match> 11 </match>
10 </match> 12 </match>
11 </match> 13 </match>
12 </match> 14 </match>
13 </device> 15 </device>
14</deviceinfo> 16</deviceinfo>
15
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h
index 9823bed..0035e2f 100644
--- a/include/libiphone/libiphone.h
+++ b/include/libiphone/libiphone.h
@@ -81,6 +81,9 @@ typedef struct iphone_afc_file_int *iphone_afc_file_t;
81struct iphone_msync_client_int; 81struct iphone_msync_client_int;
82typedef struct iphone_msync_client_int *iphone_msync_client_t; 82typedef struct iphone_msync_client_int *iphone_msync_client_t;
83 83
84struct iphone_np_client_int;
85typedef struct iphone_np_client_int *iphone_np_client_t;
86
84//debug related functions 87//debug related functions
85#define DBGMASK_ALL 0xFFFF 88#define DBGMASK_ALL 0xFFFF
86#define DBGMASK_NONE 0x0000 89#define DBGMASK_NONE 0x0000
@@ -124,6 +127,7 @@ iphone_error_t iphone_afc_get_dir_list ( iphone_afc_client_t client, const char
124iphone_error_t iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf ); 127iphone_error_t iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf );
125iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, iphone_afc_file_mode_t file_mode, iphone_afc_file_t *file ); 128iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, iphone_afc_file_mode_t file_mode, iphone_afc_file_t *file );
126iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file); 129iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file);
130iphone_error_t iphone_afc_lock_file ( iphone_afc_client_t client, iphone_afc_file_t file, int operation);
127iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t *bytes); 131iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t *bytes);
128iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length, uint32_t *bytes); 132iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length, uint32_t *bytes);
129iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos); 133iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos);
@@ -131,6 +135,7 @@ iphone_error_t iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc
131iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path); 135iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path);
132iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to); 136iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to);
133iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); 137iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir);
138iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize);
134 139
135 140
136 141
diff --git a/src/AFC.c b/src/AFC.c
index 67d37f3..dfe8af7 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -178,7 +178,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int
178 log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n"); 178 log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n");
179 log_debug_msg("Length: %i\n", length - offset); 179 log_debug_msg("Length: %i\n", length - offset);
180 log_debug_msg("Buffer: \n"); 180 log_debug_msg("Buffer: \n");
181 log_debug_msg(data + offset); 181 log_debug_buffer(data + offset, length - offset);
182 182
183 iphone_mux_send(client->connection, data + offset, length - offset, &bytes); 183 iphone_mux_send(client->connection, data + offset, length - offset, &bytes);
184 return bytes; 184 return bytes;
@@ -916,6 +916,63 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file
916 return IPHONE_E_SUCCESS; 916 return IPHONE_E_SUCCESS;
917} 917}
918 918
919/** Locks or unlocks a file on the phone.
920 *
921 * makes use of flock, see
922 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html
923 *
924 * operation (same as in sys/file.h on linux):
925 *
926 * LOCK_SH 1 // shared lock
927 * LOCK_EX 2 // exclusive lock
928 * LOCK_NB 4 // don't block when locking
929 * LOCK_UN 8 // unlock
930 *
931 * @param client The client to close the file with.
932 * @param file A pointer to an AFCFile struct containing the file handle of the
933 * file to close.
934 * @operation the lock or unlock operation to perform.
935 */
936iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_t file, int operation)
937{
938 if (!client || !file)
939 return IPHONE_E_INVALID_ARG;
940 char *buffer = malloc(16);
941 uint32_t zero = 0;
942 int bytes = 0;
943 uint64_t op = operation;
944
945 afc_lock(client);
946
947 log_debug_msg("afc_lock_file: File handle %i\n", file->filehandle);
948
949 // Send command
950 memcpy(buffer, &file->filehandle, sizeof(uint32_t));
951 memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));
952 memcpy(buffer + 8, &op, 8);
953
954 client->afc_packet->operation = AFC_FILE_LOCK;
955 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
956 bytes = dispatch_AFC_packet(client, buffer, 15);
957 free(buffer);
958 buffer = NULL;
959
960 if (bytes <= 0) {
961 afc_unlock(client);
962 log_debug_msg("fuck\n");
963 return IPHONE_E_UNKNOWN_ERROR;
964 }
965 // Receive the response
966 bytes = receive_AFC_data(client, &buffer);
967 log_debug_msg("%s: receiving response (%d bytes)\n", __func__, bytes);
968 if (buffer) {
969 log_debug_buffer(buffer, bytes);
970 free(buffer);
971 }
972 afc_unlock(client);
973 return IPHONE_E_SUCCESS;
974}
975
919/** Seeks to a given position of a pre-opened file on the phone. 976/** Seeks to a given position of a pre-opened file on the phone.
920 * 977 *
921 * @param client The client to use to seek to the position. 978 * @param client The client to use to seek to the position.
@@ -1016,6 +1073,53 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f
1016 } 1073 }
1017} 1074}
1018 1075
1076/** Sets the size of a file on the phone without prior opening it.
1077 *
1078 * @param client The client to use to set the file size.
1079 * @param path The path of the file to be truncated.
1080 * @param newsize The size to set the file to.
1081 *
1082 * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG
1083 * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
1084 */
1085iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize)
1086{
1087 char *response = NULL;
1088 char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
1089 int bytes = 0;
1090 uint64_t size_requested = newsize;
1091
1092 if (!client || !path || !client->afc_packet || !client->connection)
1093 return IPHONE_E_INVALID_ARG;
1094
1095 afc_lock(client);
1096
1097 // Send command
1098 memcpy(send, &size_requested, 8);
1099 memcpy(send + 8, path, strlen(path) + 1);
1100 client->afc_packet->entire_length = client->afc_packet->this_length = 0;
1101 client->afc_packet->operation = AFC_TRUNCATE;
1102 bytes = dispatch_AFC_packet(client, send, 8 + strlen(path));
1103 free(send);
1104 if (bytes <= 0) {
1105 afc_unlock(client);
1106 return IPHONE_E_NOT_ENOUGH_DATA;
1107 }
1108 // Receive response
1109 bytes = receive_AFC_data(client, &response);
1110 if (response)
1111 free(response);
1112
1113 afc_unlock(client);
1114
1115 if (bytes < 0) {
1116 return IPHONE_E_NOT_ENOUGH_DATA;
1117 } else {
1118 return IPHONE_E_SUCCESS;
1119 }
1120}
1121
1122
1019uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file) 1123uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)
1020{ 1124{
1021 return file->filehandle; 1125 return file->filehandle;
diff --git a/src/AFC.h b/src/AFC.h
index 5e4d17c..90b406a 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -58,20 +58,34 @@ struct iphone_afc_file_int {
58 58
59enum { 59enum {
60 AFC_ERROR = 0x00000001, 60 AFC_ERROR = 0x00000001,
61 AFC_GET_INFO = 0x0000000a,
62 AFC_GET_DEVINFO = 0x0000000b,
63 AFC_LIST_DIR = 0x00000003,
64 AFC_MAKE_DIR = 0x00000009,
65 AFC_DELETE = 0x00000008,
66 AFC_RENAME = 0x00000018,
67 AFC_SUCCESS_RESPONSE = 0x00000002, 61 AFC_SUCCESS_RESPONSE = 0x00000002,
68 AFC_FILE_OPEN = 0x0000000d, 62 AFC_LIST_DIR = 0x00000003, // ReadDir
69 AFC_FILE_CLOSE = 0x00000014, 63 // 0x00000004 // ReadFile
70 AFC_FILE_SEEK = 0x00000011, 64 // 0x00000005 // WriteFile
71 AFC_FILE_TRUNCATE = 0x00000015, 65 // 0x00000006 // WritePart
72 AFC_FILE_HANDLE = 0x0000000e, 66 AFC_TRUNCATE = 0x00000007, // Truncate
73 AFC_READ = 0x0000000f, 67 AFC_DELETE = 0x00000008, // RemovePath
74 AFC_WRITE = 0x00000010 68 AFC_MAKE_DIR = 0x00000009, // MakeDir
69 AFC_GET_INFO = 0x0000000a, // GetFileInfo
70 AFC_GET_DEVINFO = 0x0000000b, // GetDeviceInfo
71 // 0x0000000c // same as 5, but writes to temp file, then renames it.
72 AFC_FILE_OPEN = 0x0000000d, // FileRefOpen
73 AFC_FILE_HANDLE = 0x0000000e, // _unknownPacket
74 AFC_READ = 0x0000000f, // FileRefRead
75 AFC_WRITE = 0x00000010, // FileRefWrite
76 AFC_FILE_SEEK = 0x00000011, // FileRefSeek
77 AFC_FILE_TELL = 0x00000012, // FileRefTell
78 // 0x00000013 // _unknownPacket
79 AFC_FILE_CLOSE = 0x00000014, // FileRefClose
80 AFC_FILE_TRUNCATE = 0x00000015, // FileRefSetFileSize (ftruncate)
81 // 0x00000016 // SetFatalError
82 // 0x00000017 // SetConnectionOptions
83 AFC_RENAME = 0x00000018, // RenamePath
84 // 0x00000019 // SetFSBlockSize (0x800000)
85 // 0x0000001A // SetBlockSize (0x800000)
86 AFC_FILE_LOCK = 0x0000001B, // FileRefLock
87 AFC_MAKE_LINK = 0x0000001C // MakeLink
75}; 88};
76 89
90
77uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file); 91uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file);
diff --git a/src/Makefile.am b/src/Makefile.am
index 039632f..71667ae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
1INCLUDES = -I$(top_srcdir)/include 1INCLUDES = -I$(top_srcdir)/include
2 2
3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) -g 3AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS)
4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) 4AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS)
5 5
6bin_PROGRAMS = libiphone-initconf 6bin_PROGRAMS = libiphone-initconf
@@ -12,4 +12,4 @@ libiphone_initconf_LDFLAGS = $(libgthread2_LIBS) $(AM_LDFLAGS)
12 12
13 13
14lib_LTLIBRARIES = libiphone.la 14lib_LTLIBRARIES = libiphone.la
15libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c userpref.c utils.c MobileSync.c 15libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c NotificationProxy.c userpref.c utils.c MobileSync.c
diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c
new file mode 100644
index 0000000..eec7857
--- /dev/null
+++ b/src/NotificationProxy.c
@@ -0,0 +1,263 @@
1/*
2 * NotificationProxy.c
3 * Notification Proxy implementation.
4 *
5 * Copyright (c) 2009 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <stdio.h>
23#include <plist/plist.h>
24#include "NotificationProxy.h"
25#include "utils.h"
26
27/** Locks an NP client, done for thread safety stuff.
28 *
29 * @param client The NP
30 */
31static void np_lock(iphone_np_client_t client)
32{
33 log_debug_msg("NP: Locked\n");
34 g_mutex_lock(client->mutex);
35}
36
37/** Unlocks an NP client, done for thread safety stuff.
38 *
39 * @param client The NP
40 */
41static void np_unlock(iphone_np_client_t client)
42{
43 log_debug_msg("NP: Unlocked\n");
44 g_mutex_unlock(client->mutex);
45}
46
47/** Makes a connection to the NP service on the phone.
48 *
49 * @param phone The iPhone to connect on.
50 * @param s_port The source port.
51 * @param d_port The destination port.
52 *
53 * @return A handle to the newly-connected client or NULL upon error.
54 */
55iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client )
56{
57 int ret = IPHONE_E_SUCCESS;
58
59 //makes sure thread environment is available
60 if (!g_thread_supported())
61 g_thread_init(NULL);
62 iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int));
63
64 if (!device)
65 return IPHONE_E_INVALID_ARG;
66
67 // Attempt connection
68 client_loc->connection = NULL;
69 ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection);
70 if (IPHONE_E_SUCCESS != ret || !client_loc->connection) {
71 free(client_loc);
72 return ret;
73 }
74
75 client_loc->mutex = g_mutex_new();
76
77 *client = client_loc;
78 return IPHONE_E_SUCCESS;
79}
80
81/** Disconnects an NP client from the phone.
82 *
83 * @param client The client to disconnect.
84 */
85iphone_error_t iphone_np_free_client ( iphone_np_client_t client )
86{
87 if (!client || !client->connection )
88 return IPHONE_E_INVALID_ARG;
89
90 iphone_mux_free_client(client->connection);
91 free(client);
92 return IPHONE_E_SUCCESS;
93}
94
95/** Sends a notification to the NP client.
96 *
97 * notification messages seen so far:
98 * com.apple.itunes-mobdev.syncWillStart
99 * com.apple.itunes-mobdev.syncDidStart
100 *
101 * @param client The client to send to
102 * @param notification The notification Message
103 */
104iphone_error_t iphone_np_post_notification( iphone_np_client_t client, const char *notification )
105{
106 char *XML_content = NULL;
107 uint32_t length = 0;
108 int bytes = 0;
109 iphone_error_t ret;
110 unsigned char sndbuf[4096];
111 int sndlen = 0;
112 int nlen = 0;
113 plist_t dict = NULL;
114
115 if (!client || !notification) {
116 return IPHONE_E_INVALID_ARG;
117 }
118 np_lock(client);
119
120 dict = plist_new_dict();
121 plist_add_sub_key_el(dict, "Command");
122 plist_add_sub_string_el(dict, "PostNotification");
123 plist_add_sub_key_el(dict, "Name");
124 plist_add_sub_string_el(dict, notification);
125 plist_to_xml(dict, &XML_content, &length);
126
127 nlen = htonl(length);
128
129 memcpy(sndbuf+sndlen, &nlen, 4);
130 sndlen += 4;
131 memcpy(sndbuf+sndlen, XML_content, length);
132 sndlen += length;
133
134 plist_free(dict);
135 dict = NULL;
136 free(XML_content);
137 XML_content = NULL;
138
139 dict = plist_new_dict();
140 plist_add_sub_key_el(dict, "Command");
141 plist_add_sub_string_el(dict, "Shutdown");
142 plist_to_xml(dict, &XML_content, &length);
143
144 nlen = htonl(length);
145
146 memcpy(sndbuf+sndlen, &nlen, 4);
147 sndlen+=4;
148
149 memcpy(sndbuf+sndlen, XML_content, length);
150 sndlen+=length;
151
152 plist_free(dict);
153 dict = NULL;
154 free(XML_content);
155 XML_content = NULL;
156
157 log_debug_buffer(sndbuf, sndlen);
158
159 iphone_mux_send(client->connection, sndbuf, sndlen, &bytes);
160 if (bytes <= 0) {
161 np_unlock(client);
162 return bytes;
163 }
164
165 np_unlock(client);
166 return bytes;
167}
168
169/** Notifies the iphone to send a notification on certain events.
170 *
171 * observation messages seen so far:
172 * com.apple.itunes-client.syncCancelRequest
173 * com.apple.itunes-client.syncSuspendRequest
174 * com.apple.itunes-client.syncResumeRequest
175 * com.apple.mobile.lockdown.phone_number_changed
176 * com.apple.mobile.lockdown.device_name_changed
177 * com.apple.springboard.attemptactivation
178 * com.apple.mobile.data_sync.domain_changed
179 * com.apple.mobile.application_installed
180 * com.apple.mobile.application_uninstalled
181 *
182 * @param client The client to send to
183 */
184iphone_error_t iphone_np_observe_notification( iphone_np_client_t client )
185{
186 plist_t dict = NULL;
187 char *XML_content = NULL;
188 uint32_t length = 0;
189 int bytes = 0;
190 iphone_error_t ret;
191 unsigned char sndbuf[4096];
192 int sndlen = 0;
193 int nlen = 0;
194 int i=0;
195 const char *notifications[10] = {
196 "com.apple.itunes-client.syncCancelRequest",
197 "com.apple.itunes-client.syncSuspendRequest",
198 "com.apple.itunes-client.syncResumeRequest",
199 "com.apple.mobile.lockdown.phone_number_changed",
200 "com.apple.mobile.lockdown.device_name_changed",
201 "com.apple.springboard.attemptactivation",
202 "com.apple.mobile.data_sync.domain_changed",
203 "com.apple.mobile.application_installed",
204 "com.apple.mobile.application_uninstalled",
205 NULL};
206
207 sndlen = 0;
208
209 if (!client) {
210 return IPHONE_E_INVALID_ARG;
211 }
212 np_lock(client);
213
214 while (notifications[i]) {
215
216 dict = plist_new_dict();
217 plist_add_sub_key_el(dict, "Command");
218 plist_add_sub_string_el(dict, "ObserveNotification");
219 plist_add_sub_key_el(dict, "Name");
220 plist_add_sub_string_el(dict, notifications[i++]);
221 plist_to_xml(dict, &XML_content, &length);
222
223 nlen = htonl(length);
224 memcpy(sndbuf+sndlen, &nlen, 4);
225 sndlen += 4;
226 memcpy(sndbuf+sndlen, XML_content, length);
227 sndlen += length;
228
229 plist_free(dict);
230 dict = NULL;
231 free(XML_content);
232 XML_content = NULL;
233 }
234
235 dict = plist_new_dict();
236 plist_add_sub_key_el(dict, "Command");
237 plist_add_sub_string_el(dict, "Shutdown");
238 plist_to_xml(dict, &XML_content, &length);
239
240 nlen = htonl(length);
241
242 memcpy(sndbuf+sndlen, &nlen, 4);
243 sndlen+=4;
244
245 memcpy(sndbuf+sndlen, XML_content, length);
246 sndlen+=length;
247
248 plist_free(dict);
249 dict = NULL;
250 free(XML_content);
251 XML_content = NULL;
252
253 log_debug_buffer(sndbuf, sndlen);
254
255 iphone_mux_send(client->connection, sndbuf, sndlen, &bytes);
256 if (bytes <= 0) {
257 np_unlock(client);
258 return bytes;
259 }
260
261 np_unlock(client);
262 return bytes;
263}
diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h
new file mode 100644
index 0000000..57ad751
--- /dev/null
+++ b/src/NotificationProxy.h
@@ -0,0 +1,31 @@
1/*
2 * NotificationProxy.h
3 * Notification Proxy header file.
4 *
5 * Copyright (c) 2009 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include "libiphone/libiphone.h"
22#include "usbmux.h"
23#include "iphone.h"
24
25#include <glib.h>
26
27struct iphone_np_client_int {
28 iphone_umux_client_t connection;
29 GMutex *mutex;
30};
31
diff --git a/src/usbmux.c b/src/usbmux.c
index 5eaa1d1..22ce588 100644
--- a/src/usbmux.c
+++ b/src/usbmux.c
@@ -309,7 +309,8 @@ iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t
309 } 309 }
310 310
311 // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. 311 // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above.
312 return datalen; 312 *recv_bytes = datalen;
313 return IPHONE_E_SUCCESS;
313 } else { 314 } else {
314 memcpy(data, client->recv_buffer, client->r_len); 315 memcpy(data, client->recv_buffer, client->r_len);
315 free(client->recv_buffer); // don't need to deal with anymore, but... 316 free(client->recv_buffer); // don't need to deal with anymore, but...
@@ -362,10 +363,10 @@ iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t
362 if ((bytes - 28) > datalen) { 363 if ((bytes - 28) > datalen) {
363 // Copy what we need into the data, buffer the rest because we can. 364 // Copy what we need into the data, buffer the rest because we can.
364 memcpy(data + offset, buffer + 28, datalen); // data+offset: see #2b, above 365 memcpy(data + offset, buffer + 28, datalen); // data+offset: see #2b, above
365 complex = client->r_len + (bytes - 28) - datalen; 366 complex = client->r_len + ((bytes - 28) - datalen);
366 client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex)); 367 client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex));
367 client->r_len = complex; 368 client->r_len = complex;
368 complex = client->r_len - (bytes - 28) - datalen; 369 complex = client->r_len - ((bytes - 28) - datalen);
369 memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen); 370 memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen);
370 free(buffer); 371 free(buffer);
371 client->header->ocnt += bytes - 28; 372 client->header->ocnt += bytes - 28;