summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/Makefile.am1
-rw-r--r--include/libiphone/sbservices.h56
-rw-r--r--src/Makefile.am1
-rw-r--r--src/SBServices.c291
-rw-r--r--src/SBServices.h33
5 files changed, 382 insertions, 0 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index df7b823..5e25a58 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,4 +2,5 @@ nobase_include_HEADERS = libiphone/libiphone.h \
2 libiphone/lockdown.h \ 2 libiphone/lockdown.h \
3 libiphone/afc.h \ 3 libiphone/afc.h \
4 libiphone/notification_proxy.h \ 4 libiphone/notification_proxy.h \
5 libiphone/sbservices.h \
5 libiphone/mobilesync.h 6 libiphone/mobilesync.h
diff --git a/include/libiphone/sbservices.h b/include/libiphone/sbservices.h
new file mode 100644
index 0000000..6ea8189
--- /dev/null
+++ b/include/libiphone/sbservices.h
@@ -0,0 +1,56 @@
1/**
2 * @file libiphone/sbservices.h
3 * @brief Implementation to talk to com.apple.springboardservices on a device
4 * \internal
5 *
6 * Copyright (c) 2009 Nikias Bassen All Rights Reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef SB_SERVICES_H
24#define SB_SERVICES_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include <libiphone/libiphone.h>
31
32/* Error Codes */
33#define SBSERVICES_E_SUCCESS 0
34#define SBSERVICES_E_INVALID_ARG -1
35#define SBSERVICES_E_PLIST_ERROR -2
36#define SBSERVICES_E_CONN_FAILED -3
37
38#define SBSERVICES_E_UNKNOWN_ERROR -256
39
40typedef int16_t sbservices_error_t;
41
42struct sbservices_client_int;
43typedef struct sbservices_client_int *sbservices_client_t;
44
45/* Interface */
46sbservices_error_t sbservices_client_new(iphone_device_t device, int dst_port, sbservices_client_t *client);
47sbservices_error_t sbservices_client_free(sbservices_client_t client);
48sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state);
49sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate);
50sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index ce1d237..d351a8a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ libiphone_la_SOURCES = iphone.c iphone.h \
8 lockdown.c lockdown.h\ 8 lockdown.c lockdown.h\
9 AFC.c AFC.h\ 9 AFC.c AFC.h\
10 NotificationProxy.c NotificationProxy.h\ 10 NotificationProxy.c NotificationProxy.h\
11 SBServices.c SBServices.h\
11 userpref.c userpref.h\ 12 userpref.c userpref.h\
12 utils.c utils.h\ 13 utils.c utils.h\
13 MobileSync.c MobileSync.h 14 MobileSync.c MobileSync.h
diff --git a/src/SBServices.c b/src/SBServices.c
new file mode 100644
index 0000000..9849415
--- /dev/null
+++ b/src/SBServices.c
@@ -0,0 +1,291 @@
1/*
2 * SBServices.c
3 * SpringBoard Services 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 <string.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <arpa/inet.h>
26#include <plist/plist.h>
27
28#include "SBServices.h"
29#include "iphone.h"
30#include "utils.h"
31
32/** Locks an sbservices client, done for thread safety stuff.
33 *
34 * @param client The sbservices client to lock.
35 */
36static void sbs_lock(sbservices_client_t client)
37{
38 log_debug_msg("SBServices: Locked\n");
39 g_mutex_lock(client->mutex);
40}
41
42/** Unlocks an sbservices client, done for thread safety stuff.
43 *
44 * @param client The sbservices client to unlock
45 */
46static void sbs_unlock(sbservices_client_t client)
47{
48 log_debug_msg("SBServices: Unlocked\n");
49 g_mutex_unlock(client->mutex);
50}
51
52sbservices_error_t sbservices_client_new(iphone_device_t device, int dst_port, sbservices_client_t *client)
53{
54 /* makes sure thread environment is available */
55 if (!g_thread_supported())
56 g_thread_init(NULL);
57
58 if (!device)
59 return SBSERVICES_E_INVALID_ARG;
60
61 /* Attempt connection */
62 iphone_connection_t connection = NULL;
63 if (iphone_device_connect(device, dst_port, &connection) != IPHONE_E_SUCCESS) {
64 return SBSERVICES_E_CONN_FAILED;
65 }
66
67 sbservices_client_t client_loc = (sbservices_client_t) malloc(sizeof(struct sbservices_client_int));
68 client_loc->connection = connection;
69 client_loc->mutex = g_mutex_new();
70
71 *client = client_loc;
72 return SBSERVICES_E_SUCCESS;
73}
74
75sbservices_error_t sbservices_client_free(sbservices_client_t client)
76{
77 if (!client)
78 return SBSERVICES_E_INVALID_ARG;
79
80 iphone_device_disconnect(client->connection);
81 client->connection = NULL;
82 if (client->mutex) {
83 g_mutex_free(client->mutex);
84 }
85 free(client);
86
87 return SBSERVICES_E_SUCCESS;
88}
89
90/**
91 * Sends a binary plist to the device using the connection specified in client.
92 * This function is only used internally.
93 *
94 * @param client InstallationProxy to send data to
95 * @param dict plist to send
96 *
97 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
98 * client or dict are NULL, SBSERVICES_E_PLIST_ERROR when dict is not a
99 * valid plist, or SBSERVICES_E_UNKNOWN_ERROR when an unspecified error
100 * occurs.
101 */
102static sbservices_error_t sbservices_plist_send(sbservices_client_t client, plist_t dict)
103{
104 char *content = NULL;
105 uint32_t length = 0;
106 uint32_t nlen = 0;
107 int bytes = 0;
108 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
109
110 if (!client || !dict) {
111 return SBSERVICES_E_INVALID_ARG;
112 }
113
114 plist_to_bin(dict, &content, &length);
115
116 if (!content || length == 0) {
117 return SBSERVICES_E_PLIST_ERROR;
118 }
119
120 nlen = htonl(length);
121 log_debug_msg("%s: sending %d bytes\n", __func__, length);
122 iphone_device_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes);
123 if (bytes == sizeof(nlen)) {
124 iphone_device_send(client->connection, content, length, (uint32_t*)&bytes);
125 if (bytes > 0) {
126 if ((uint32_t)bytes == length) {
127 res = SBSERVICES_E_SUCCESS;
128 } else {
129 log_debug_msg("%s: ERROR: Could not send all data (%d of %d)!\n", __func__, bytes, length);
130 }
131 }
132 }
133 if (bytes <= 0) {
134 log_debug_msg("%s: ERROR: sending to device failed.\n", __func__);
135 }
136
137 free(content);
138
139 return res;
140}
141
142sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state)
143{
144 if (!client || !client->connection || !state)
145 return SBSERVICES_E_INVALID_ARG;
146
147 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
148 uint32_t pktlen = 0;
149 uint32_t bytes = 0;
150
151 plist_t dict = plist_new_dict();
152 plist_dict_insert_item(dict, "command", plist_new_string("getIconState"));
153
154 sbs_lock(client);
155
156 res = sbservices_plist_send(client, dict);
157 plist_free(dict);
158 if (res != SBSERVICES_E_SUCCESS) {
159 log_debug_msg("%s: could not send plist\n", __func__);
160 goto leave_unlock;
161 }
162
163 iphone_device_recv(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes);
164 log_debug_msg("%s: initial read=%i\n", __func__, bytes);
165 if (bytes < 4) {
166 log_debug_msg("%s: initial read failed!\n");
167 res = 0;
168 } else {
169 if ((char)pktlen == 0) {
170 char *content = NULL;
171 uint32_t curlen = 0;
172 pktlen = ntohl(pktlen);
173 log_debug_msg("%s: %d bytes following\n", __func__, pktlen);
174 content = (char*)malloc(pktlen);
175 log_debug_msg("pointer %p\n", content);
176
177 while (curlen < pktlen) {
178 iphone_device_recv(client->connection, content+curlen, pktlen-curlen, &bytes);
179 if (bytes <= 0) {
180 res = SBSERVICES_E_UNKNOWN_ERROR;
181 break;
182 }
183 log_debug_msg("%s: received %d bytes\n", __func__, bytes);
184 curlen += bytes;
185 }
186 log_debug_buffer(content, pktlen);
187 plist_from_bin(content, pktlen, state);
188 res = SBSERVICES_E_SUCCESS;
189 free(content);
190 } else {
191 res = SBSERVICES_E_UNKNOWN_ERROR;
192 }
193 }
194
195leave_unlock:
196 sbs_unlock(client);
197 return res;
198}
199
200sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate)
201{
202 if (!client || !client->connection || !newstate)
203 return SBSERVICES_E_INVALID_ARG;
204
205 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
206
207 plist_t dict = plist_new_dict();
208 plist_dict_insert_item(dict, "command", plist_new_string("setIconState"));
209 plist_dict_insert_item(dict, "iconState", plist_copy(newstate));
210
211 sbs_lock(client);
212
213 res = sbservices_plist_send(client, dict);
214 plist_free(dict);
215 if (res != SBSERVICES_E_SUCCESS) {
216 log_debug_msg("%s: could not send plist\n", __func__);
217 goto leave_unlock;
218 }
219 // NO RESPONSE
220
221leave_unlock:
222 sbs_unlock(client);
223 return res;
224}
225
226sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize)
227{
228 if (!client || !client->connection || !pngdata)
229 return SBSERVICES_E_INVALID_ARG;
230
231 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
232 uint32_t pktlen = 0;
233 uint32_t bytes = 0;
234
235 plist_t dict = plist_new_dict();
236 plist_dict_insert_item(dict, "command", plist_new_string("getIconPNGData"));
237 plist_dict_insert_item(dict, "bundleId", plist_new_string(bundleId));
238
239 sbs_lock(client);
240
241 res = sbservices_plist_send(client, dict);
242 plist_free(dict);
243 if (res != SBSERVICES_E_SUCCESS) {
244 log_debug_msg("%s: could not send plist\n", __func__);
245 goto leave_unlock;
246 }
247
248 iphone_device_recv(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes);
249 log_debug_msg("%s: initial read=%i\n", __func__, bytes);
250 if (bytes < 4) {
251 log_debug_msg("%s: initial read failed!\n");
252 res = 0;
253 } else {
254 if ((char)pktlen == 0) {
255 char *content = NULL;
256 uint32_t curlen = 0;
257 pktlen = ntohl(pktlen);
258 log_debug_msg("%s: %d bytes following\n", __func__, pktlen);
259 content = (char*)malloc(pktlen);
260 log_debug_msg("pointer %p\n", content);
261
262 while (curlen < pktlen) {
263 iphone_device_recv(client->connection, content+curlen, pktlen-curlen, &bytes);
264 if (bytes <= 0) {
265 res = SBSERVICES_E_UNKNOWN_ERROR;
266 break;
267 }
268 log_debug_msg("%s: received %d bytes\n", __func__, bytes);
269 curlen += bytes;
270 }
271 log_debug_buffer(content, pktlen);
272 plist_t pngdict = NULL;
273 plist_from_bin(content, pktlen, &pngdict);
274 plist_t node = plist_dict_get_item(pngdict, "pngData");
275 if (node) {
276 plist_get_data_val(node, pngdata, pngsize);
277 }
278 plist_free(pngdict);
279 res = SBSERVICES_E_SUCCESS;
280 free(content);
281 } else {
282 res = SBSERVICES_E_UNKNOWN_ERROR;
283 }
284 }
285
286leave_unlock:
287 sbs_unlock(client);
288 return res;
289
290}
291
diff --git a/src/SBServices.h b/src/SBServices.h
new file mode 100644
index 0000000..8f923b9
--- /dev/null
+++ b/src/SBServices.h
@@ -0,0 +1,33 @@
1/*
2 * SBServices.h
3 * SpringBoard Services 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#ifndef ISBSERVICES_H
22#define ISBSERVICES_H
23
24#include <glib.h>
25
26#include "libiphone/sbservices.h"
27
28struct sbservices_client_int {
29 iphone_connection_t connection;
30 GMutex *mutex;
31};
32
33#endif