Coverage Report

Created: 2025-01-28 06:45

/src/bluez/gobex/gobex-transfer.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 *
4
 *  OBEX library with GLib integration
5
 *
6
 *  Copyright (C) 2011  Intel Corporation. All rights reserved.
7
 *
8
 */
9
10
#ifdef HAVE_CONFIG_H
11
#include <config.h>
12
#endif
13
14
#include <string.h>
15
#include <errno.h>
16
17
#include "gobex/gobex.h"
18
#include "gobex/gobex-debug.h"
19
20
0
#define FIRST_PACKET_TIMEOUT 60
21
22
static GSList *transfers = NULL;
23
24
static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
25
              gpointer user_data);
26
27
struct transfer {
28
  guint id;
29
  guint8 opcode;
30
31
  GObex *obex;
32
33
  guint req_id;
34
35
  guint put_id;
36
  guint get_id;
37
  guint abort_id;
38
39
  GObexDataProducer data_producer;
40
  GObexDataConsumer data_consumer;
41
  GObexFunc complete_func;
42
43
  gpointer user_data;
44
};
45
46
static void transfer_free(struct transfer *transfer)
47
0
{
48
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
49
50
0
  transfers = g_slist_remove(transfers, transfer);
51
52
0
  if (transfer->req_id > 0)
53
0
    g_obex_cancel_req(transfer->obex, transfer->req_id, TRUE);
54
55
0
  if (transfer->put_id > 0)
56
0
    g_obex_remove_request_function(transfer->obex,
57
0
              transfer->put_id);
58
59
0
  if (transfer->get_id > 0)
60
0
    g_obex_remove_request_function(transfer->obex,
61
0
              transfer->get_id);
62
63
0
  if (transfer->abort_id > 0)
64
0
    g_obex_remove_request_function(transfer->obex,
65
0
              transfer->abort_id);
66
67
0
  g_obex_unref(transfer->obex);
68
0
  g_free(transfer);
69
0
}
70
71
static struct transfer *find_transfer(guint id)
72
0
{
73
0
  GSList *l;
74
75
0
  for (l = transfers; l != NULL; l = g_slist_next(l)) {
76
0
    struct transfer *t = l->data;
77
0
    if (t->id == id)
78
0
      return t;
79
0
  }
80
81
0
  return NULL;
82
0
}
83
84
static void transfer_complete(struct transfer *transfer, GError *err)
85
0
{
86
0
  guint id = transfer->id;
87
88
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", id);
89
90
0
  if (err) {
91
    /* No further tx must be performed */
92
0
    g_obex_drop_tx_queue(transfer->obex);
93
0
  }
94
95
0
  transfer->complete_func(transfer->obex, err, transfer->user_data);
96
  /* Check if the complete_func removed the transfer */
97
0
  if (find_transfer(id) == NULL)
98
0
    return;
99
100
0
  transfer_free(transfer);
101
0
}
102
103
static void transfer_abort_response(GObex *obex, GError *err, GObexPacket *rsp,
104
              gpointer user_data)
105
0
{
106
0
  struct transfer *transfer = user_data;
107
108
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
109
110
0
  transfer->req_id = 0;
111
112
  /* Intentionally override error */
113
0
  err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
114
0
            "Operation was aborted");
115
0
  g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
116
0
  transfer_complete(transfer, err);
117
0
  g_error_free(err);
118
0
}
119
120
121
static gssize put_get_data(void *buf, gsize len, gpointer user_data)
122
0
{
123
0
  struct transfer *transfer = user_data;
124
0
  GObexPacket *req;
125
0
  GError *err = NULL;
126
0
  gssize ret;
127
128
0
  ret = transfer->data_producer(buf, len, transfer->user_data);
129
0
  if (ret == 0 || ret == -EAGAIN)
130
0
    return ret;
131
132
0
  if (ret > 0) {
133
    /* Check if SRM is active */
134
0
    if (!g_obex_srm_active(transfer->obex))
135
0
      return ret;
136
137
    /* Generate next packet */
138
0
    req = g_obex_packet_new(transfer->opcode, FALSE,
139
0
              G_OBEX_HDR_INVALID);
140
0
    g_obex_packet_add_body(req, put_get_data, transfer);
141
0
    transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
142
0
            transfer_response, transfer,
143
0
            &err);
144
0
    goto done;
145
0
  }
146
147
0
  transfer->req_id = g_obex_abort(transfer->obex, transfer_abort_response,
148
0
                transfer, &err);
149
0
done:
150
0
  if (err != NULL) {
151
0
    transfer_complete(transfer, err);
152
0
    g_error_free(err);
153
0
  }
154
155
0
  return ret;
156
0
}
157
158
static gboolean handle_get_body(struct transfer *transfer, GObexPacket *rsp,
159
                GError **err)
160
0
{
161
0
  GObexHeader *body = g_obex_packet_get_body(rsp);
162
0
  gboolean ret;
163
0
  const guint8 *buf;
164
0
  gsize len;
165
166
0
  if (body == NULL)
167
0
    return TRUE;
168
169
0
  g_obex_header_get_bytes(body, &buf, &len);
170
0
  if (len == 0)
171
0
    return TRUE;
172
173
0
  ret = transfer->data_consumer(buf, len, transfer->user_data);
174
0
  if (ret == FALSE)
175
0
    g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
176
0
        "Data consumer callback failed");
177
178
0
  return ret;
179
0
}
180
181
static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
182
              gpointer user_data)
183
0
{
184
0
  struct transfer *transfer = user_data;
185
0
  GObexPacket *req;
186
0
  gboolean rspcode, final;
187
0
  guint id;
188
189
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
190
191
0
  id = transfer->req_id;
192
0
  transfer->req_id = 0;
193
194
0
  if (err != NULL) {
195
0
    transfer_complete(transfer, err);
196
0
    return;
197
0
  }
198
199
0
  rspcode = g_obex_packet_get_operation(rsp, &final);
200
0
  if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
201
0
    err = g_error_new(G_OBEX_ERROR, rspcode, "%s",
202
0
            g_obex_strerror(rspcode));
203
0
    goto failed;
204
0
  }
205
206
0
  if (transfer->opcode == G_OBEX_OP_GET) {
207
0
    handle_get_body(transfer, rsp, &err);
208
0
    if (err != NULL)
209
0
      goto failed;
210
0
  }
211
212
0
  if (rspcode == G_OBEX_RSP_SUCCESS) {
213
0
    transfer_complete(transfer, NULL);
214
0
    return;
215
0
  }
216
217
0
  if (transfer->opcode == G_OBEX_OP_PUT) {
218
0
    req = g_obex_packet_new(transfer->opcode, FALSE,
219
0
              G_OBEX_HDR_INVALID);
220
0
    g_obex_packet_add_body(req, put_get_data, transfer);
221
0
  } else if (!g_obex_srm_active(transfer->obex)) {
222
0
    req = g_obex_packet_new(transfer->opcode, TRUE,
223
0
              G_OBEX_HDR_INVALID);
224
0
  } else {
225
    /* Keep id since request still outstanting */
226
0
    transfer->req_id = id;
227
0
    return;
228
0
  }
229
230
0
  transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
231
0
              transfer, &err);
232
0
failed:
233
0
  if (err != NULL) {
234
0
    g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
235
0
    transfer_complete(transfer, err);
236
0
    g_error_free(err);
237
0
  }
238
0
}
239
240
static struct transfer *transfer_new(GObex *obex, guint8 opcode,
241
        GObexFunc complete_func, gpointer user_data)
242
0
{
243
0
  static guint next_id = 1;
244
0
  struct transfer *transfer;
245
246
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p opcode %u", obex, opcode);
247
248
0
  transfer = g_new0(struct transfer, 1);
249
250
0
  transfer->id = next_id++;
251
0
  transfer->opcode = opcode;
252
0
  transfer->obex = g_obex_ref(obex);
253
0
  transfer->complete_func = complete_func;
254
0
  transfer->user_data = user_data;
255
256
0
  transfers = g_slist_append(transfers, transfer);
257
258
0
  return transfer;
259
0
}
260
261
guint g_obex_put_req_pkt(GObex *obex, GObexPacket *req,
262
      GObexDataProducer data_func, GObexFunc complete_func,
263
      gpointer user_data, GError **err)
264
0
{
265
0
  struct transfer *transfer;
266
267
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
268
269
0
  if (g_obex_packet_get_operation(req, NULL) != G_OBEX_OP_PUT)
270
0
    return 0;
271
272
0
  transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
273
0
  transfer->data_producer = data_func;
274
275
0
  g_obex_packet_add_body(req, put_get_data, transfer);
276
277
0
  transfer->req_id = g_obex_send_req(obex, req, FIRST_PACKET_TIMEOUT,
278
0
          transfer_response, transfer, err);
279
0
  if (transfer->req_id == 0) {
280
0
    transfer_free(transfer);
281
0
    return 0;
282
0
  }
283
284
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
285
286
0
  return transfer->id;
287
0
}
288
289
guint g_obex_put_req(GObex *obex, GObexDataProducer data_func,
290
      GObexFunc complete_func, gpointer user_data,
291
      GError **err, guint first_hdr_id, ...)
292
0
{
293
0
  GObexPacket *req;
294
0
  va_list args;
295
296
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
297
298
0
  va_start(args, first_hdr_id);
299
0
  req = g_obex_packet_new_valist(G_OBEX_OP_PUT, FALSE,
300
0
              first_hdr_id, args);
301
0
  va_end(args);
302
303
0
  return g_obex_put_req_pkt(obex, req, data_func, complete_func,
304
0
              user_data, err);
305
0
}
306
307
static void transfer_abort_req(GObex *obex, GObexPacket *req, gpointer user_data)
308
0
{
309
0
  struct transfer *transfer = user_data;
310
0
  GObexPacket *rsp;
311
0
  GError *err;
312
313
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
314
315
0
  err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
316
0
            "Request was aborted");
317
0
  rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, G_OBEX_HDR_INVALID);
318
0
  g_obex_send(obex, rsp, NULL);
319
320
0
  transfer_complete(transfer, err);
321
0
  g_error_free(err);
322
0
}
323
324
static guint8 put_get_bytes(struct transfer *transfer, GObexPacket *req)
325
0
{
326
0
  GObexHeader *body;
327
0
  gboolean final;
328
0
  guint8 rsp;
329
0
  const guint8 *buf;
330
0
  gsize len;
331
332
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
333
334
0
  g_obex_packet_get_operation(req, &final);
335
0
  if (final)
336
0
    rsp = G_OBEX_RSP_SUCCESS;
337
0
  else
338
0
    rsp = G_OBEX_RSP_CONTINUE;
339
340
0
  body = g_obex_packet_get_body(req);
341
0
  if (body == NULL)
342
0
    return rsp;
343
344
0
  g_obex_header_get_bytes(body, &buf, &len);
345
0
  if (len == 0)
346
0
    return rsp;
347
348
0
  if (transfer->data_consumer(buf, len, transfer->user_data) == FALSE)
349
0
    rsp = G_OBEX_RSP_FORBIDDEN;
350
351
0
  return rsp;
352
0
}
353
354
static void transfer_put_req_first(struct transfer *transfer, GObexPacket *req,
355
          guint8 first_hdr_id, va_list args)
356
0
{
357
0
  GError *err = NULL;
358
0
  GObexPacket *rsp;
359
0
  guint8 rspcode;
360
361
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
362
363
0
  rspcode = put_get_bytes(transfer, req);
364
365
0
  rsp = g_obex_packet_new_valist(rspcode, TRUE, first_hdr_id, args);
366
367
0
  if (!g_obex_send(transfer->obex, rsp, &err)) {
368
0
    transfer_complete(transfer, err);
369
0
    g_error_free(err);
370
0
    return;
371
0
  }
372
373
0
  if (rspcode != G_OBEX_RSP_CONTINUE)
374
0
    transfer_complete(transfer, NULL);
375
0
}
376
377
static void transfer_put_req(GObex *obex, GObexPacket *req, gpointer user_data)
378
0
{
379
0
  struct transfer *transfer = user_data;
380
0
  GError *err = NULL;
381
0
  GObexPacket *rsp;
382
0
  guint8 rspcode;
383
384
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
385
386
0
  rspcode = put_get_bytes(transfer, req);
387
388
  /* Don't send continue while SRM is active */
389
0
  if (g_obex_srm_active(transfer->obex) &&
390
0
        rspcode == G_OBEX_RSP_CONTINUE)
391
0
    goto done;
392
393
0
  rsp = g_obex_packet_new(rspcode, TRUE, G_OBEX_HDR_INVALID);
394
395
0
  if (!g_obex_send(obex, rsp, &err)) {
396
0
    transfer_complete(transfer, err);
397
0
    g_error_free(err);
398
0
    return;
399
0
  }
400
401
0
done:
402
0
  if (rspcode != G_OBEX_RSP_CONTINUE)
403
0
    transfer_complete(transfer, NULL);
404
0
}
405
406
guint g_obex_put_rsp(GObex *obex, GObexPacket *req,
407
      GObexDataConsumer data_func, GObexFunc complete_func,
408
      gpointer user_data, GError **err,
409
      guint first_hdr_id, ...)
410
0
{
411
0
  struct transfer *transfer;
412
0
  va_list args;
413
0
  guint id;
414
415
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
416
417
0
  transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
418
0
  transfer->data_consumer = data_func;
419
420
0
  va_start(args, first_hdr_id);
421
0
  transfer_put_req_first(transfer, req, first_hdr_id, args);
422
0
  va_end(args);
423
0
  if (!g_slist_find(transfers, transfer))
424
0
    return 0;
425
426
0
  id = g_obex_add_request_function(obex, G_OBEX_OP_PUT, transfer_put_req,
427
0
                transfer);
428
0
  transfer->put_id = id;
429
430
0
  id = g_obex_add_request_function(obex, G_OBEX_OP_ABORT,
431
0
            transfer_abort_req, transfer);
432
0
  transfer->abort_id = id;
433
434
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
435
436
0
  return transfer->id;
437
0
}
438
439
guint g_obex_get_req_pkt(GObex *obex, GObexPacket *req,
440
      GObexDataConsumer data_func, GObexFunc complete_func,
441
      gpointer user_data, GError **err)
442
0
{
443
0
  struct transfer *transfer;
444
445
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
446
447
0
  if (g_obex_packet_get_operation(req, NULL) != G_OBEX_OP_GET)
448
0
    return 0;
449
450
0
  transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
451
0
  transfer->data_consumer = data_func;
452
0
  transfer->req_id = g_obex_send_req(obex, req, FIRST_PACKET_TIMEOUT,
453
0
          transfer_response, transfer, err);
454
0
  if (transfer->req_id == 0) {
455
0
    transfer_free(transfer);
456
0
    return 0;
457
0
  }
458
459
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
460
461
0
  return transfer->id;
462
0
}
463
464
guint g_obex_get_req(GObex *obex, GObexDataConsumer data_func,
465
      GObexFunc complete_func, gpointer user_data,
466
      GError **err, guint first_hdr_id, ...)
467
0
{
468
0
  struct transfer *transfer;
469
0
  GObexPacket *req;
470
0
  va_list args;
471
472
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
473
474
0
  transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
475
0
  transfer->data_consumer = data_func;
476
477
0
  va_start(args, first_hdr_id);
478
0
  req = g_obex_packet_new_valist(G_OBEX_OP_GET, TRUE,
479
0
              first_hdr_id, args);
480
0
  va_end(args);
481
482
0
  transfer->req_id = g_obex_send_req(obex, req, FIRST_PACKET_TIMEOUT,
483
0
          transfer_response, transfer, err);
484
0
  if (transfer->req_id == 0) {
485
0
    transfer_free(transfer);
486
0
    return 0;
487
0
  }
488
489
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
490
491
0
  return transfer->id;
492
0
}
493
494
static gssize get_get_data(void *buf, gsize len, gpointer user_data)
495
0
{
496
0
  struct transfer *transfer = user_data;
497
0
  GObexPacket *req, *rsp;
498
0
  GError *err = NULL;
499
0
  gssize ret;
500
0
  guint8 op;
501
502
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
503
504
0
  ret = transfer->data_producer(buf, len, transfer->user_data);
505
0
  if (ret > 0) {
506
0
    if (!g_obex_srm_active(transfer->obex))
507
0
      return ret;
508
509
    /* Generate next response */
510
0
    rsp = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE,
511
0
              G_OBEX_HDR_INVALID);
512
0
    g_obex_packet_add_body(rsp, get_get_data, transfer);
513
514
0
    if (!g_obex_send(transfer->obex, rsp, &err)) {
515
0
      transfer_complete(transfer, err);
516
0
      g_error_free(err);
517
0
    }
518
519
0
    return ret;
520
0
  }
521
522
0
  if (ret == -EAGAIN)
523
0
    return ret;
524
525
0
  if (ret == 0) {
526
0
    transfer_complete(transfer, NULL);
527
0
    return ret;
528
0
  }
529
530
0
  op = g_obex_errno_to_rsp(ret);
531
532
0
  req = g_obex_packet_new(op, TRUE, G_OBEX_HDR_INVALID);
533
0
  g_obex_send(transfer->obex, req, NULL);
534
535
0
  err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
536
0
        "Data producer function failed");
537
0
  g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
538
0
  transfer_complete(transfer, err);
539
0
  g_error_free(err);
540
541
0
  return ret;
542
0
}
543
544
static gboolean transfer_get_req_first(struct transfer *transfer,
545
              GObexPacket *rsp)
546
0
{
547
0
  GError *err = NULL;
548
549
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
550
551
0
  g_obex_packet_add_body(rsp, get_get_data, transfer);
552
553
0
  if (!g_obex_send(transfer->obex, rsp, &err)) {
554
0
    transfer_complete(transfer, err);
555
0
    g_error_free(err);
556
0
    return FALSE;
557
0
  }
558
559
0
  return TRUE;
560
0
}
561
562
static void transfer_get_req(GObex *obex, GObexPacket *req, gpointer user_data)
563
0
{
564
0
  struct transfer *transfer = user_data;
565
0
  GError *err = NULL;
566
0
  GObexPacket *rsp;
567
568
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
569
570
0
  rsp = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE, G_OBEX_HDR_INVALID);
571
0
  g_obex_packet_add_body(rsp, get_get_data, transfer);
572
573
0
  if (!g_obex_send(obex, rsp, &err)) {
574
0
    transfer_complete(transfer, err);
575
0
    g_error_free(err);
576
0
  }
577
0
}
578
579
guint g_obex_get_rsp_pkt(GObex *obex, GObexPacket *rsp,
580
      GObexDataProducer data_func, GObexFunc complete_func,
581
      gpointer user_data, GError **err)
582
0
{
583
0
  struct transfer *transfer;
584
0
  guint id;
585
586
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
587
588
0
  transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
589
0
  transfer->data_producer = data_func;
590
591
0
  if (!transfer_get_req_first(transfer, rsp))
592
0
    return 0;
593
594
0
  if (!g_slist_find(transfers, transfer))
595
0
    return 0;
596
597
0
  id = g_obex_add_request_function(obex, G_OBEX_OP_GET, transfer_get_req,
598
0
                transfer);
599
0
  transfer->get_id = id;
600
601
0
  id = g_obex_add_request_function(obex, G_OBEX_OP_ABORT,
602
0
            transfer_abort_req, transfer);
603
0
  transfer->abort_id = id;
604
605
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);
606
607
0
  return transfer->id;
608
0
}
609
610
guint g_obex_get_rsp(GObex *obex, GObexDataProducer data_func,
611
      GObexFunc complete_func, gpointer user_data,
612
      GError **err, guint first_hdr_id, ...)
613
0
{
614
0
  GObexPacket *rsp;
615
0
  va_list args;
616
617
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);
618
619
0
  va_start(args, first_hdr_id);
620
0
  rsp = g_obex_packet_new_valist(G_OBEX_RSP_CONTINUE, TRUE,
621
0
              first_hdr_id, args);
622
0
  va_end(args);
623
624
0
  return g_obex_get_rsp_pkt(obex, rsp, data_func, complete_func,
625
0
              user_data, err);
626
0
}
627
628
gboolean g_obex_cancel_transfer(guint id, GObexFunc complete_func,
629
      gpointer user_data)
630
0
{
631
0
  struct transfer *transfer = NULL;
632
0
  gboolean ret = TRUE;
633
634
0
  g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", id);
635
636
0
  transfer = find_transfer(id);
637
638
0
  if (transfer == NULL)
639
0
    return FALSE;
640
641
0
  if (complete_func == NULL)
642
0
    goto done;
643
644
0
  transfer->complete_func = complete_func;
645
0
  transfer->user_data = user_data;
646
647
0
  if (!transfer->req_id) {
648
0
    transfer->req_id = g_obex_abort(transfer->obex,
649
0
            transfer_abort_response,
650
0
            transfer, NULL);
651
0
    if (transfer->req_id)
652
0
      return TRUE;
653
0
  }
654
655
0
  ret = g_obex_cancel_req(transfer->obex, transfer->req_id, FALSE);
656
0
  if (ret)
657
0
    return TRUE;
658
659
0
done:
660
0
  transfer_free(transfer);
661
0
  return ret;
662
0
}