Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 827706
Collapse All | Expand All

(-)a/attrib/gattrib.c (-22 / +73 lines)
Lines 41-48 struct _GAttrib { Link Here
41
	struct queue *track_ids;
41
	struct queue *track_ids;
42
};
42
};
43
43
44
struct id_pair {
45
	unsigned int org_id;
46
	unsigned int pend_id;
47
};
48
44
struct attrib_callbacks {
49
struct attrib_callbacks {
45
	unsigned int id;
50
	struct id_pair *id;
46
	GAttribResultFunc result_func;
51
	GAttribResultFunc result_func;
47
	GAttribNotifyFunc notify_func;
52
	GAttribNotifyFunc notify_func;
48
	GDestroyNotify destroy_func;
53
	GDestroyNotify destroy_func;
Lines 51-56 struct attrib_callbacks { Link Here
51
	uint16_t notify_handle;
56
	uint16_t notify_handle;
52
};
57
};
53
58
59
static bool find_with_org_id(const void *data, const void *user_data)
60
{
61
	const struct id_pair *p = data;
62
	unsigned int orig_id = PTR_TO_UINT(user_data);
63
64
	return (p->org_id == orig_id);
65
}
66
67
static struct id_pair *store_id(GAttrib *attrib, unsigned int org_id,
68
							unsigned int pend_id)
69
{
70
	struct id_pair *t;
71
72
	t = new0(struct id_pair, 1);
73
	if (!t)
74
		return NULL;
75
76
	t->org_id = org_id;
77
	t->pend_id = pend_id;
78
79
	if (queue_push_tail(attrib->track_ids, t))
80
		return t;
81
82
	return NULL;
83
}
84
54
GAttrib *g_attrib_new(GIOChannel *io, guint16 mtu, bool ext_signed)
85
GAttrib *g_attrib_new(GIOChannel *io, guint16 mtu, bool ext_signed)
55
{
86
{
56
	gint fd;
87
	gint fd;
Lines 119-124 static void attrib_callbacks_destroy(void *data) Link Here
119
	if (cb->destroy_func)
150
	if (cb->destroy_func)
120
		cb->destroy_func(cb->user_data);
151
		cb->destroy_func(cb->user_data);
121
152
153
	if (queue_remove(cb->parent->track_ids, cb->id))
154
		free(cb->id);
155
122
	free(data);
156
	free(data);
123
}
157
}
124
158
Lines 148-154 void g_attrib_unref(GAttrib *attrib) Link Here
148
	bt_att_unref(attrib->att);
182
	bt_att_unref(attrib->att);
149
183
150
	queue_destroy(attrib->callbacks, attrib_callbacks_destroy);
184
	queue_destroy(attrib->callbacks, attrib_callbacks_destroy);
151
	queue_destroy(attrib->track_ids, NULL);
185
	queue_destroy(attrib->track_ids, free);
152
186
153
	free(attrib->buf);
187
	free(attrib->buf);
154
188
Lines 261-266 guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len, Link Here
261
	struct attrib_callbacks *cb = NULL;
295
	struct attrib_callbacks *cb = NULL;
262
	bt_att_response_func_t response_cb = NULL;
296
	bt_att_response_func_t response_cb = NULL;
263
	bt_att_destroy_func_t destroy_cb = NULL;
297
	bt_att_destroy_func_t destroy_cb = NULL;
298
	unsigned int pend_id;
264
299
265
	if (!attrib)
300
	if (!attrib)
266
		return 0;
301
		return 0;
Lines 282-328 guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len, Link Here
282
317
283
	}
318
	}
284
319
285
	if (id == 0)
320
	pend_id = bt_att_send(attrib->att, pdu[0], (void *) pdu + 1, len - 1,
286
		id = bt_att_send(attrib->att, pdu[0], (void *) pdu + 1,
321
						response_cb, cb, destroy_cb);
287
					len - 1, response_cb, cb, destroy_cb);
288
	else {
289
		int err;
290
291
		err = bt_att_resend(attrib->att, id, pdu[0], (void *) pdu + 1,
292
					len - 1, response_cb, cb, destroy_cb);
293
		if (err)
294
			return 0;
295
	}
296
322
297
	if (!id)
323
	/*
298
		return id;
324
	 * We store here pair as it is easier to handle it in response and in
325
	 * case where user request us to use specific id request - see below.
326
	 */
327
	if (id == 0)
328
		id = pend_id;
299
329
300
	/*
330
	/*
301
	 * If user what us to use given id, lets keep track on that so we give
331
	 * If user what us to use given id, lets keep track on that so we give
302
	 * user a possibility to cancel ongoing request.
332
	 * user a possibility to cancel ongoing request.
303
	 */
333
	 */
304
	if (cb) {
334
	if (cb)
305
		cb->id = id;
335
		cb->id = store_id(attrib, id, pend_id);
306
		queue_push_tail(attrib->track_ids, UINT_TO_PTR(id));
307
	}
308
336
309
	return id;
337
	return id;
310
}
338
}
311
339
312
gboolean g_attrib_cancel(GAttrib *attrib, guint id)
340
gboolean g_attrib_cancel(GAttrib *attrib, guint id)
313
{
341
{
342
	struct id_pair *p;
343
314
	if (!attrib)
344
	if (!attrib)
315
		return FALSE;
345
		return FALSE;
316
346
347
	/*
348
	 * If request belongs to gattrib and is not yet done it has to be on
349
	 * the tracking id queue
350
	 *
351
	 * FIXME: It can happen that on the queue there is id_pair with
352
	 * given id which was provided by the user. In the same time it might
353
	 * happen that other attrib user got dynamic allocated req_id with same
354
	 * value as the one provided by the other user.
355
	 * In such case there are two clients having same request id and in
356
	 * this point of time we don't know which one calls cancel. For
357
	 * now we cancel request in which id was specified by the user.
358
	 */
359
	p = queue_remove_if(attrib->track_ids, find_with_org_id,
360
							UINT_TO_PTR(id));
361
	if (!p)
362
		return FALSE;
363
364
	id = p->pend_id;
365
	free(p);
366
317
	return bt_att_cancel(attrib->att, id);
367
	return bt_att_cancel(attrib->att, id);
318
}
368
}
319
369
320
static void cancel_request(void *data, void *user_data)
370
static void cancel_request(void *data, void *user_data)
321
{
371
{
322
	unsigned int id = PTR_TO_UINT(data);
372
	struct id_pair *p = data;
323
	GAttrib *attrib = user_data;
373
	GAttrib *attrib = user_data;
324
374
325
	bt_att_cancel(attrib->att, id);
375
	bt_att_cancel(attrib->att, p->pend_id);
326
}
376
}
327
377
328
gboolean g_attrib_cancel_all(GAttrib *attrib)
378
gboolean g_attrib_cancel_all(GAttrib *attrib)
Lines 330-337 gboolean g_attrib_cancel_all(GAttrib *attrib) Link Here
330
	if (!attrib)
380
	if (!attrib)
331
		return FALSE;
381
		return FALSE;
332
382
383
	/* Cancel only request which belongs to gattrib */
333
	queue_foreach(attrib->track_ids, cancel_request, attrib);
384
	queue_foreach(attrib->track_ids, cancel_request, attrib);
334
	queue_remove_all(attrib->track_ids, NULL, NULL, NULL);
385
	queue_remove_all(attrib->track_ids, NULL, NULL, free);
335
386
336
	return TRUE;
387
	return TRUE;
337
}
388
}

Return to bug 827706