diff options
| -rw-r--r-- | include/libimobiledevice/libimobiledevice.h | 36 | ||||
| -rw-r--r-- | src/idevice.c | 59 | ||||
| -rw-r--r-- | tools/idevicebtlogger.c | 5 | ||||
| -rw-r--r-- | tools/idevicesyslog.c | 5 | 
4 files changed, 89 insertions, 16 deletions
diff --git a/include/libimobiledevice/libimobiledevice.h b/include/libimobiledevice/libimobiledevice.h index c3b87cd..6851145 100644 --- a/include/libimobiledevice/libimobiledevice.h +++ b/include/libimobiledevice/libimobiledevice.h @@ -94,6 +94,9 @@ typedef struct {  /** Callback to notifiy if a device was added or removed. */  typedef void (*idevice_event_cb_t) (const idevice_event_t *event, void *user_data); +/** Event subscription context type */ +typedef struct idevice_subscription_context* idevice_subscription_context_t; +  /* functions */  /** @@ -104,9 +107,36 @@ typedef void (*idevice_event_cb_t) (const idevice_event_t *event, void *user_dat  void idevice_set_debug_level(int level);  /** - * Register a callback function that will be called when device add/remove + * Subscribe a callback function that will be called when device add/remove   * events occur.   * + * @param context A pointer to a idevice_subscription_context_t that will be + *    set upon creation of the subscription. The returned context must be + *    passed to idevice_events_unsubscribe() to unsubscribe the callback. + * @param callback Callback function to call. + * @param user_data Application-specific data passed as parameter + *   to the registered callback function. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +idevice_error_t idevice_events_subscribe(idevice_subscription_context_t *context, idevice_event_cb_t callback, void *user_data); + +/** + * Unsubscribe the event callback function that has been registered with + * idevice_events_subscribe(). + * + * @param context A valid context as returned from idevice_events_subscribe(). + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +idevice_error_t idevice_events_unsubscribe(idevice_subscription_context_t context); + +/** + * (DEPRECATED) Register a callback function that will be called when device add/remove + * events occur. + * + * @deprecated Use idevice_events_subscribe() instead. + *   * @param callback Callback function to call.   * @param user_data Application-specific data passed as parameter   *   to the registered callback function. @@ -116,9 +146,11 @@ void idevice_set_debug_level(int level);  idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data);  /** - * Release the event callback function that has been registered with + * (DEPRECATED) Release the event callback function that has been registered with   *  idevice_event_subscribe().   * + * @deprecated Use idevice_events_unsubscribe() instead. + *   * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred.   */  idevice_error_t idevice_event_unsubscribe(void); diff --git a/src/idevice.c b/src/idevice.c index 22d57e3..c8574fc 100644 --- a/src/idevice.c +++ b/src/idevice.c @@ -215,10 +215,17 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)  #warning No compiler support for constructor/destructor attributes, some features might not be available.  #endif -static idevice_event_cb_t event_cb = NULL; +struct idevice_subscription_context { +	idevice_event_cb_t callback; +	void *user_data; +	usbmuxd_subscription_context_t ctx; +}; + +static idevice_subscription_context_t event_ctx = NULL;  static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data)  { +	idevice_subscription_context_t context = (idevice_subscription_context_t)user_data;  	idevice_event_t ev;  	ev.event = event->event; @@ -232,34 +239,66 @@ static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data)  		debug_info("Unknown connection type %d", event->device.conn_type);  	} -	if (event_cb) { -		event_cb(&ev, user_data); +	if (context->callback) { +		context->callback(&ev, context->user_data);  	}  } -LIBIMOBILEDEVICE_API idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data) +LIBIMOBILEDEVICE_API idevice_error_t idevice_events_subscribe(idevice_subscription_context_t *context, idevice_event_cb_t callback, void *user_data)  { -	event_cb = callback; -	int res = usbmuxd_subscribe(usbmux_event_cb, user_data); +	if (!context || !callback) { +		return IDEVICE_E_INVALID_ARG; +	} +	*context = malloc(sizeof(struct idevice_subscription_context)); +	if (!*context) { +		debug_info("ERROR: %s: Failed to allocate subscription context\n", __func__); +		return IDEVICE_E_UNKNOWN_ERROR; +	} +	(*context)->callback = callback; +	(*context)->user_data = user_data; +	int res = usbmuxd_events_subscribe(&(*context)->ctx, usbmux_event_cb, *context);  	if (res != 0) { -		event_cb = NULL; +		free(*context); +		*context = NULL;  		debug_info("ERROR: usbmuxd_subscribe() returned %d!", res);  		return IDEVICE_E_UNKNOWN_ERROR;  	}  	return IDEVICE_E_SUCCESS;  } -LIBIMOBILEDEVICE_API idevice_error_t idevice_event_unsubscribe(void) +LIBIMOBILEDEVICE_API idevice_error_t idevice_events_unsubscribe(idevice_subscription_context_t context)  { -	event_cb = NULL; -	int res = usbmuxd_unsubscribe(); +	if (!context) { +		return IDEVICE_E_INVALID_ARG; +	} +	int res = usbmuxd_events_unsubscribe(context->ctx);  	if (res != 0) {  		debug_info("ERROR: usbmuxd_unsubscribe() returned %d!", res);  		return IDEVICE_E_UNKNOWN_ERROR;  	} +	if (context == event_ctx) { +		event_ctx = NULL; +	} +	free(context);  	return IDEVICE_E_SUCCESS;  } +LIBIMOBILEDEVICE_API idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data) +{ +	if (event_ctx) { +		idevice_events_unsubscribe(event_ctx); +	} +	return idevice_events_subscribe(&event_ctx, callback, user_data); +} + +LIBIMOBILEDEVICE_API idevice_error_t idevice_event_unsubscribe(void) +{ +	if (!event_ctx) { +		return IDEVICE_E_SUCCESS; +	} +	return idevice_events_unsubscribe(event_ctx); +} +  LIBIMOBILEDEVICE_API idevice_error_t idevice_get_device_list_extended(idevice_info_t **devices, int *count)  {  	usbmuxd_device_info_t *dev_list; diff --git a/tools/idevicebtlogger.c b/tools/idevicebtlogger.c index 421ce98..8de6b22 100644 --- a/tools/idevicebtlogger.c +++ b/tools/idevicebtlogger.c @@ -440,13 +440,14 @@ int main(int argc, char *argv[])  			assert(0);  			return -2;  	} -	idevice_event_subscribe(device_event_cb, NULL); +	idevice_subscription_context_t context = NULL; +	idevice_events_subscribe(&context, device_event_cb, NULL);  	while (!quit_flag) {  		sleep(1);  	} -	idevice_event_unsubscribe(); +	idevice_events_unsubscribe(context);  	stop_logging();  	fclose(packetlogger_file); diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c index f85c7cc..3084b97 100644 --- a/tools/idevicesyslog.c +++ b/tools/idevicesyslog.c @@ -709,12 +709,13 @@ int main(int argc, char *argv[])  	line_buffer_size = 1024;  	line = malloc(line_buffer_size); -	idevice_event_subscribe(device_event_cb, NULL); +	idevice_subscription_context_t context = NULL; +	idevice_events_subscribe(&context, device_event_cb, NULL);  	while (!quit_flag) {  		sleep(1);  	} -	idevice_event_unsubscribe(); +	idevice_events_unsubscribe(context);  	stop_logging();  	if (num_proc_filters > 0) {  | 
