summaryrefslogtreecommitdiffstats
path: root/src/sbservices.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbservices.c')
-rw-r--r--src/sbservices.c219
1 files changed, 94 insertions, 125 deletions
diff --git a/src/sbservices.c b/src/sbservices.c
index 3596cbd..365e130 100644
--- a/src/sbservices.c
+++ b/src/sbservices.c
@@ -8,17 +8,20 @@
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 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 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 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
22#include <string.h> 25#include <string.h>
23#include <stdlib.h> 26#include <stdlib.h>
24#include <unistd.h> 27#include <unistd.h>
@@ -26,28 +29,28 @@
26 29
27#include "sbservices.h" 30#include "sbservices.h"
28#include "property_list_service.h" 31#include "property_list_service.h"
29#include "debug.h" 32#include "common/debug.h"
30 33
31/** 34/**
32 * Locks an sbservices client, used for thread safety. 35 * Locks an sbservices client, used for thread safety.
33 * 36 *
34 * @param client sbservices client to lock. 37 * @param client sbservices client to lock.
35 */ 38 */
36static void sbs_lock(sbservices_client_t client) 39static void sbservices_lock(sbservices_client_t client)
37{ 40{
38 debug_info("SBServices: Locked"); 41 debug_info("Locked");
39 g_mutex_lock(client->mutex); 42 mutex_lock(&client->mutex);
40} 43}
41 44
42/** 45/**
43 * Unlocks an sbservices client, used for thread safety. 46 * Unlocks an sbservices client, used for thread safety.
44 * 47 *
45 * @param client sbservices client to unlock 48 * @param client sbservices client to unlock
46 */ 49 */
47static void sbs_unlock(sbservices_client_t client) 50static void sbservices_unlock(sbservices_client_t client)
48{ 51{
49 debug_info("SBServices: Unlocked"); 52 debug_info("Unlocked");
50 g_mutex_unlock(client->mutex); 53 mutex_unlock(&client->mutex);
51} 54}
52 55
53/** 56/**
@@ -61,64 +64,44 @@ static void sbs_unlock(sbservices_client_t client)
61 */ 64 */
62static sbservices_error_t sbservices_error(property_list_service_error_t err) 65static sbservices_error_t sbservices_error(property_list_service_error_t err)
63{ 66{
64 switch (err) { 67 switch (err) {
65 case PROPERTY_LIST_SERVICE_E_SUCCESS: 68 case PROPERTY_LIST_SERVICE_E_SUCCESS:
66 return SBSERVICES_E_SUCCESS; 69 return SBSERVICES_E_SUCCESS;
67 case PROPERTY_LIST_SERVICE_E_INVALID_ARG: 70 case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
68 return SBSERVICES_E_INVALID_ARG; 71 return SBSERVICES_E_INVALID_ARG;
69 case PROPERTY_LIST_SERVICE_E_PLIST_ERROR: 72 case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
70 return SBSERVICES_E_PLIST_ERROR; 73 return SBSERVICES_E_PLIST_ERROR;
71 case PROPERTY_LIST_SERVICE_E_MUX_ERROR: 74 case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
72 return SBSERVICES_E_CONN_FAILED; 75 return SBSERVICES_E_CONN_FAILED;
73 default: 76 default:
74 break; 77 break;
75 } 78 }
76 return SBSERVICES_E_UNKNOWN_ERROR; 79 return SBSERVICES_E_UNKNOWN_ERROR;
77} 80}
78 81
79/** 82sbservices_error_t sbservices_client_new(idevice_t device, lockdownd_service_descriptor_t service, sbservices_client_t *client)
80 * Connects to the springboardservices service on the specified device.
81 *
82 * @param device The device to connect to.
83 * @param port Destination port (usually given by lockdownd_start_service).
84 * @param client Pointer that will point to a newly allocated
85 * sbservices_client_t upon successful return.
86 *
87 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
88 * client is NULL, or an SBSERVICES_E_* error code otherwise.
89 */
90sbservices_error_t sbservices_client_new(idevice_t device, uint16_t port, sbservices_client_t *client)
91{ 83{
92 /* makes sure thread environment is available */
93 if (!g_thread_supported())
94 g_thread_init(NULL);
95
96 if (!device)
97 return SBSERVICES_E_INVALID_ARG;
98
99 property_list_service_client_t plistclient = NULL; 84 property_list_service_client_t plistclient = NULL;
100 sbservices_error_t err = sbservices_error(property_list_service_client_new(device, port, &plistclient)); 85 sbservices_error_t err = sbservices_error(property_list_service_client_new(device, service, &plistclient));
101 if (err != SBSERVICES_E_SUCCESS) { 86 if (err != SBSERVICES_E_SUCCESS) {
102 return err; 87 return err;
103 } 88 }
104 89
105 sbservices_client_t client_loc = (sbservices_client_t) malloc(sizeof(struct sbservices_client_private)); 90 sbservices_client_t client_loc = (sbservices_client_t) malloc(sizeof(struct sbservices_client_private));
106 client_loc->parent = plistclient; 91 client_loc->parent = plistclient;
107 client_loc->mutex = g_mutex_new(); 92 mutex_init(&client_loc->mutex);
108 93
109 *client = client_loc; 94 *client = client_loc;
110 return SBSERVICES_E_SUCCESS; 95 return SBSERVICES_E_SUCCESS;
111} 96}
112 97
113/** 98sbservices_error_t sbservices_client_start_service(idevice_t device, sbservices_client_t * client, const char* label)
114 * Disconnects an sbservices client from the device and frees up the 99{
115 * sbservices client data. 100 sbservices_error_t err = SBSERVICES_E_UNKNOWN_ERROR;
116 * 101 service_client_factory_start_service(device, SBSERVICES_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(sbservices_client_new), &err);
117 * @param client The sbservices client to disconnect and free. 102 return err;
118 * 103}
119 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when 104
120 * client is NULL, or an SBSERVICES_E_* error code otherwise.
121 */
122sbservices_error_t sbservices_client_free(sbservices_client_t client) 105sbservices_error_t sbservices_client_free(sbservices_client_t client)
123{ 106{
124 if (!client) 107 if (!client)
@@ -126,28 +109,12 @@ sbservices_error_t sbservices_client_free(sbservices_client_t client)
126 109
127 sbservices_error_t err = sbservices_error(property_list_service_client_free(client->parent)); 110 sbservices_error_t err = sbservices_error(property_list_service_client_free(client->parent));
128 client->parent = NULL; 111 client->parent = NULL;
129 if (client->mutex) { 112 mutex_destroy(&client->mutex);
130 g_mutex_free(client->mutex);
131 }
132 free(client); 113 free(client);
133 114
134 return err; 115 return err;
135} 116}
136 117
137/**
138 * Gets the icon state of the connected device.
139 *
140 * @param client The connected sbservices client to use.
141 * @param state Pointer that will point to a newly allocated plist containing
142 * the current icon state. It is up to the caller to free the memory.
143 * @param format_version A string to be passed as formatVersion along with
144 * the request, or NULL if no formatVersion should be passed. This is only
145 * supported since iOS 4.0 so for older firmware versions this must be set
146 * to NULL.
147 *
148 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
149 * client or state is invalid, or an SBSERVICES_E_* error code otherwise.
150 */
151sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state, const char *format_version) 118sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state, const char *format_version)
152{ 119{
153 if (!client || !client->parent || !state) 120 if (!client || !client->parent || !state)
@@ -156,12 +123,12 @@ sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t
156 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR; 123 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
157 124
158 plist_t dict = plist_new_dict(); 125 plist_t dict = plist_new_dict();
159 plist_dict_insert_item(dict, "command", plist_new_string("getIconState")); 126 plist_dict_set_item(dict, "command", plist_new_string("getIconState"));
160 if (format_version) { 127 if (format_version) {
161 plist_dict_insert_item(dict, "formatVersion", plist_new_string(format_version)); 128 plist_dict_set_item(dict, "formatVersion", plist_new_string(format_version));
162 } 129 }
163 130
164 sbs_lock(client); 131 sbservices_lock(client);
165 132
166 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict)); 133 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
167 if (res != SBSERVICES_E_SUCCESS) { 134 if (res != SBSERVICES_E_SUCCESS) {
@@ -184,19 +151,10 @@ leave_unlock:
184 if (dict) { 151 if (dict) {
185 plist_free(dict); 152 plist_free(dict);
186 } 153 }
187 sbs_unlock(client); 154 sbservices_unlock(client);
188 return res; 155 return res;
189} 156}
190 157
191/**
192 * Sets the icon state of the connected device.
193 *
194 * @param client The connected sbservices client to use.
195 * @param newstate A plist containing the new iconstate.
196 *
197 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
198 * client or newstate is NULL, or an SBSERVICES_E_* error code otherwise.
199 */
200sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate) 158sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate)
201{ 159{
202 if (!client || !client->parent || !newstate) 160 if (!client || !client->parent || !newstate)
@@ -205,39 +163,27 @@ sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t
205 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR; 163 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
206 164
207 plist_t dict = plist_new_dict(); 165 plist_t dict = plist_new_dict();
208 plist_dict_insert_item(dict, "command", plist_new_string("setIconState")); 166 plist_dict_set_item(dict, "command", plist_new_string("setIconState"));
209 plist_dict_insert_item(dict, "iconState", plist_copy(newstate)); 167 plist_dict_set_item(dict, "iconState", plist_copy(newstate));
210 168
211 sbs_lock(client); 169 sbservices_lock(client);
212 170
213 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict)); 171 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
214 if (res != SBSERVICES_E_SUCCESS) { 172 if (res != SBSERVICES_E_SUCCESS) {
215 debug_info("could not send plist, error %d", res); 173 debug_info("could not send plist, error %d", res);
216 } 174 }
217 /* NO RESPONSE */ 175
176 uint32_t bytes = 0;
177 service_receive_with_timeout(client->parent->parent, malloc(4), 4, &bytes, 2000);
178 debug_info("setIconState response: %u", bytes);
218 179
219 if (dict) { 180 if (dict) {
220 plist_free(dict); 181 plist_free(dict);
221 } 182 }
222 sbs_unlock(client); 183 sbservices_unlock(client);
223 return res; 184 return res;
224} 185}
225 186
226/**
227 * Get the icon of the specified app as PNG data.
228 *
229 * @param client The connected sbservices client to use.
230 * @param bundleId The bundle identifier of the app to retrieve the icon for.
231 * @param pngdata Pointer that will point to a newly allocated buffer
232 * containing the PNG data upon successful return. It is up to the caller
233 * to free the memory.
234 * @param pngsize Pointer to a uint64_t that will be set to the size of the
235 * buffer pngdata points to upon successful return.
236 *
237 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
238 * client, bundleId, or pngdata are invalid, or an SBSERVICES_E_* error
239 * code otherwise.
240 */
241sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize) 187sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize)
242{ 188{
243 if (!client || !client->parent || !bundleId || !pngdata) 189 if (!client || !client->parent || !bundleId || !pngdata)
@@ -246,10 +192,10 @@ sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const
246 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR; 192 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
247 193
248 plist_t dict = plist_new_dict(); 194 plist_t dict = plist_new_dict();
249 plist_dict_insert_item(dict, "command", plist_new_string("getIconPNGData")); 195 plist_dict_set_item(dict, "command", plist_new_string("getIconPNGData"));
250 plist_dict_insert_item(dict, "bundleId", plist_new_string(bundleId)); 196 plist_dict_set_item(dict, "bundleId", plist_new_string(bundleId));
251 197
252 sbs_lock(client); 198 sbservices_lock(client);
253 199
254 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict)); 200 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
255 if (res != SBSERVICES_E_SUCCESS) { 201 if (res != SBSERVICES_E_SUCCESS) {
@@ -271,25 +217,48 @@ leave_unlock:
271 if (dict) { 217 if (dict) {
272 plist_free(dict); 218 plist_free(dict);
273 } 219 }
274 sbs_unlock(client); 220 sbservices_unlock(client);
275 return res; 221 return res;
222}
223
224sbservices_error_t sbservices_get_interface_orientation(sbservices_client_t client, sbservices_interface_orientation_t* interface_orientation)
225{
226 if (!client || !client->parent || !interface_orientation)
227 return SBSERVICES_E_INVALID_ARG;
228
229 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
230
231 plist_t dict = plist_new_dict();
232 plist_dict_set_item(dict, "command", plist_new_string("getInterfaceOrientation"));
233
234 sbservices_lock(client);
235
236 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
237 if (res != SBSERVICES_E_SUCCESS) {
238 debug_info("could not send plist, error %d", res);
239 goto leave_unlock;
240 }
241 plist_free(dict);
242 dict = NULL;
243
244 res = sbservices_error(property_list_service_receive_plist(client->parent, &dict));
245 if (res == SBSERVICES_E_SUCCESS) {
246 plist_t node = plist_dict_get_item(dict, "interfaceOrientation");
247 if (node) {
248 uint64_t value = SBSERVICES_INTERFACE_ORIENTATION_UNKNOWN;
249 plist_get_uint_val(node, &value);
250 *interface_orientation = (sbservices_interface_orientation_t)value;
251 }
252 }
276 253
254leave_unlock:
255 if (dict) {
256 plist_free(dict);
257 }
258 sbservices_unlock(client);
259 return res;
277} 260}
278 261
279/**
280 * Get the home screen wallpaper as PNG data.
281 *
282 * @param client The connected sbservices client to use.
283 * @param pngdata Pointer that will point to a newly allocated buffer
284 * containing the PNG data upon successful return. It is up to the caller
285 * to free the memory.
286 * @param pngsize Pointer to a uint64_t that will be set to the size of the
287 * buffer pngdata points to upon successful return.
288 *
289 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
290 * client or pngdata are invalid, or an SBSERVICES_E_* error
291 * code otherwise.
292 */
293sbservices_error_t sbservices_get_home_screen_wallpaper_pngdata(sbservices_client_t client, char **pngdata, uint64_t *pngsize) 262sbservices_error_t sbservices_get_home_screen_wallpaper_pngdata(sbservices_client_t client, char **pngdata, uint64_t *pngsize)
294{ 263{
295 if (!client || !client->parent || !pngdata) 264 if (!client || !client->parent || !pngdata)
@@ -298,9 +267,9 @@ sbservices_error_t sbservices_get_home_screen_wallpaper_pngdata(sbservices_clien
298 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR; 267 sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;
299 268
300 plist_t dict = plist_new_dict(); 269 plist_t dict = plist_new_dict();
301 plist_dict_insert_item(dict, "command", plist_new_string("getHomeScreenWallpaperPNGData")); 270 plist_dict_set_item(dict, "command", plist_new_string("getHomeScreenWallpaperPNGData"));
302 271
303 sbs_lock(client); 272 sbservices_lock(client);
304 273
305 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict)); 274 res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
306 if (res != SBSERVICES_E_SUCCESS) { 275 if (res != SBSERVICES_E_SUCCESS) {
@@ -322,6 +291,6 @@ leave_unlock:
322 if (dict) { 291 if (dict) {
323 plist_free(dict); 292 plist_free(dict);
324 } 293 }
325 sbs_unlock(client); 294 sbservices_unlock(client);
326 return res; 295 return res;
327} 296}