diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/NotificationProxy.c | 256 | 
1 files changed, 256 insertions, 0 deletions
| diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c new file mode 100644 index 0000000..b0c10ea --- /dev/null +++ b/src/NotificationProxy.c @@ -0,0 +1,256 @@ +/* + * NotificationProxy.c + * Notification Proxy implementation. + * + * Copyright (c) 2009 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ + +#include <stdio.h> +#include "NotificationProxy.h" +#include "plist.h" +#include "utils.h" + +/** Locks an NP client, done for thread safety stuff. + * + * @param client The NP + */ +static void np_lock(iphone_np_client_t client) +{ +	log_debug_msg("NP: Locked\n"); +	g_mutex_lock(client->mutex); +} + +/** Unlocks an NP client, done for thread safety stuff. + *  + * @param client The NP + */ +static void np_unlock(iphone_np_client_t client) +{ +	log_debug_msg("NP: Unlocked\n"); +	g_mutex_unlock(client->mutex); +} + +/** Makes a connection to the NP service on the phone.  + *  + * @param phone The iPhone to connect on. + * @param s_port The source port.  + * @param d_port The destination port.  + *  + * @return A handle to the newly-connected client or NULL upon error. + */ +iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ) +{ +	int ret = IPHONE_E_SUCCESS; + +	//makes sure thread environment is available +	if (!g_thread_supported()) +		g_thread_init(NULL); +	iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int)); + +	if (!device) +		return IPHONE_E_INVALID_ARG; + +	// Attempt connection +	client_loc->connection = NULL; +	ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); +	if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { +		free(client_loc); +		return ret; +	} + +	client_loc->mutex = g_mutex_new(); + +	*client = client_loc; +	return IPHONE_E_SUCCESS;	 +} + +/** Disconnects an NP client from the phone. + *  + * @param client The client to disconnect. + */ +iphone_error_t iphone_np_free_client ( iphone_np_client_t client ) +{ +	if (!client || !client->connection ) +		return IPHONE_E_INVALID_ARG; + +	iphone_mux_free_client(client->connection); +	free(client); +	return IPHONE_E_SUCCESS; +} + +/** Sends a notification to the NP client. + * + * notification messages seen so far: + *   com.apple.itunes-mobdev.syncWillStart + *   com.apple.itunes-mobdev.syncDidStart + * + * @param client The client to send to + * @param notification The notification Message + */ +iphone_error_t iphone_np_post_notification( iphone_np_client_t client, const char *notification ) +{ +	xmlDocPtr plist; +	xmlNode *dict, *key; +    	char *XML_content; +	uint32_t length; +	int bytes; +	iphone_error_t ret; +	unsigned char sndbuf[4096]; +	int sndlen = 0; +	int nlen; + +	if (!client || !notification) { +		return IPHONE_E_INVALID_ARG; +	} +	np_lock(client); + +	plist = new_plist(); +	dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); +	key = add_key_str_dict_element(plist, dict, "Command", "PostNotification", 1); +	key = add_key_str_dict_element(plist, dict, "Name", notification, 1); +	xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen += 4; +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen += length; +  +	xmlFree(XML_content); +	xmlFreeDoc(plist); + +	plist = new_plist(); +	dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); +	key = add_key_str_dict_element(plist, dict, "Command", "Shutdown", 1); +	xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen+=4; + +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen+=length; + +	xmlFree(XML_content); +	xmlFreeDoc(plist); +	plist = NULL; + +	log_debug_buffer(sndbuf, sndlen); + +	iphone_mux_send(client->connection, sndbuf, sndlen, &bytes); +        if (bytes <= 0) { +		np_unlock(client); +		return bytes; +	} + +	np_unlock(client); +	return bytes; +} + +/** Notifies the iphone to send a notification on certain events. + * + * observation messages seen so far: + *   com.apple.itunes-client.syncCancelRequest + *   com.apple.itunes-client.syncSuspendRequest + *   com.apple.itunes-client.syncResumeRequest + *   com.apple.mobile.lockdown.phone_number_changed + *   com.apple.mobile.lockdown.device_name_changed + *   com.apple.springboard.attemptactivation + *   com.apple.mobile.data_sync.domain_changed + *   com.apple.mobile.application_installed + *   com.apple.mobile.application_uninstalled + * + * @param client The client to send to + */ +iphone_error_t iphone_np_observe_notification( iphone_np_client_t client ) +{ +	xmlDocPtr plist; +	xmlNode *dict, *key; +    	char *XML_content; +	uint32_t length; +	int bytes; +	iphone_error_t ret; +	unsigned char sndbuf[4096]; +	int sndlen = 0; +	int nlen; +	int i=0; +	char *notifications[10] = { +	    "com.apple.itunes-client.syncCancelRequest", +	    "com.apple.itunes-client.syncSuspendRequest", +	    "com.apple.itunes-client.syncResumeRequest", +	    "com.apple.mobile.lockdown.phone_number_changed", +	    "com.apple.mobile.lockdown.device_name_changed", +	    "com.apple.springboard.attemptactivation", +	    "com.apple.mobile.data_sync.domain_changed", +	    "com.apple.mobile.application_installed", +	    "com.apple.mobile.application_uninstalled", +	    NULL}; + +	sndlen = 0; + +	if (!client) { +		return IPHONE_E_INVALID_ARG; +	} +	np_lock(client); + +	while (notifications[i]) { +		plist = new_plist(); +		dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); +		key = add_key_str_dict_element(plist, dict, "Command", "ObserveNotification", 1); +		key = add_key_str_dict_element(plist, dict, "Name", notifications[i++], 1); +		xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); + +		nlen = htonl(length); +		memcpy(sndbuf+sndlen, &nlen, 4); +		sndlen += 4; +		memcpy(sndbuf+sndlen, XML_content, length); +		sndlen += length; +  +		xmlFree(XML_content); +		xmlFreeDoc(plist); +	} + +	plist = new_plist(); +	dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); +	key = add_key_str_dict_element(plist, dict, "Command", "Shutdown", 1); +	xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen+=4; + +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen+=length; + +	xmlFree(XML_content); +	xmlFreeDoc(plist); +	plist = NULL; + +	log_debug_buffer(sndbuf, sndlen); + +	iphone_mux_send(client->connection, sndbuf, sndlen, &bytes); +        if (bytes <= 0) { +		np_unlock(client); +		return bytes; +	} + +	np_unlock(client); +	return bytes; +} | 
