~cyphermox/ubuntu/natty/ofono/release-0.41

« back to all changes in this revision

Viewing changes to drivers/ifxmodem/voicecall.c

  • Committer: Mathieu Trudel-Lapierre
  • Date: 2011-02-11 02:17:20 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: mathieu-tl@ubuntu.com-20110211021720-cvxc3erw1keomunj
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include "gatchat.h"
39
39
#include "gatresult.h"
40
40
 
 
41
#include "common.h"
41
42
#include "ifxmodem.h"
42
43
 
43
 
/* Amount of ms we wait between CLCC calls */
44
 
#define POLL_CLCC_INTERVAL 500
45
 
 
46
 
 /* Amount of time we give for CLIP to arrive before we commence CLCC poll */
47
 
#define CLIP_INTERVAL 200
48
 
 
49
44
static const char *none_prefix[] = { NULL };
50
45
 
51
46
/* According to 27.007 COLP is an intermediate status for ATD */
93
88
        struct ofono_call *call;
94
89
 
95
90
        /* Generate a call structure for the waiting call */
96
 
        call = g_try_new0(struct ofono_call, 1);
97
 
        if (!call)
 
91
        call = g_try_new(struct ofono_call, 1);
 
92
        if (call == NULL)
98
93
                return NULL;
99
94
 
 
95
        ofono_call_init(call);
 
96
 
100
97
        call->id = ofono_voicecall_get_next_callid(vc);
101
98
        call->type = type;
102
99
        call->direction = direction;
147
144
                 * In the case of incoming, we will get the info from CLIP
148
145
                 * indications.
149
146
                 */
150
 
                if (status != 4 && status != 5) {
 
147
                if (status != CALL_STATUS_INCOMING &&
 
148
                                    status != CALL_STATUS_WAITING) {
151
149
                        ofono_info("Received an XCALLSTAT for an untracked"
152
150
                                        " call, this indicates a bug!");
153
151
                        return;
159
157
        call = l->data;
160
158
 
161
159
        /* Check if call has been disconnected */
162
 
        if (status == 6) {
 
160
        if (status == CALL_STATUS_DISCONNECTED) {
163
161
                enum ofono_disconnect_reason r;
164
162
 
165
 
                if (vd->local_release & (0x1 << call->id))
 
163
                if (vd->local_release & (1 << call->id))
166
164
                        r = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
167
165
                else
168
166
                        r = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
170
168
                if (call->type == 0)
171
169
                        ofono_voicecall_disconnected(vc, call->id, r, NULL);
172
170
 
173
 
                vd->local_release &= ~(0x1 << call->id);
 
171
                vd->local_release &= ~(1 << call->id);
174
172
                vd->calls = g_slist_remove(vd->calls, call);
175
173
                g_free(call);
176
174
 
229
227
                for (l = vd->calls; l; l = l->next) {
230
228
                        call = l->data;
231
229
 
232
 
                        if (req->affected_types & (0x1 << call->status))
233
 
                                vd->local_release |= (0x1 << call->id);
 
230
                        if (req->affected_types & (1 << call->status))
 
231
                                vd->local_release |= (1 << call->id);
234
232
                }
235
233
        }
236
234
 
247
245
        decode_at_error(&error, g_at_result_final_response(result));
248
246
 
249
247
        if (ok)
250
 
                vd->local_release |= 0x1 << req->id;
 
248
                vd->local_release |= 1 << req->id;
251
249
 
252
250
        req->cb(&error, req->data);
253
251
}
286
284
        }
287
285
 
288
286
        /* Generate a voice call that was just dialed, we guess the ID */
289
 
        call = create_call(vc, 0, 0, 2, num, type, validity);
290
 
        if (!call) {
 
287
        call = create_call(vc, 0, 0, CALL_STATUS_DIALING, num, type, validity);
 
288
        if (call == NULL) {
291
289
                ofono_error("Unable to malloc, call tracking will fail!");
292
290
                return;
293
291
        }
304
302
 
305
303
static void ifx_dial(struct ofono_voicecall *vc,
306
304
                        const struct ofono_phone_number *ph,
307
 
                        enum ofono_clir_option clir, enum ofono_cug_option cug,
308
 
                        ofono_voicecall_cb_t cb, void *data)
 
305
                        enum ofono_clir_option clir, ofono_voicecall_cb_t cb,
 
306
                        void *data)
309
307
{
310
308
        struct voicecall_data *vd = ofono_voicecall_get_data(vc);
311
309
        struct cb_data *cbd = cb_data_new(cb, data);
312
310
        char buf[256];
313
311
 
314
 
        if (!cbd)
315
 
                goto error;
316
 
 
317
312
        cbd->user = vc;
318
313
 
319
314
        if (ph->type == 145)
332
327
                break;
333
328
        }
334
329
 
335
 
        switch (cug) {
336
 
        case OFONO_CUG_OPTION_INVOCATION:
337
 
                strcat(buf, "G");
338
 
                break;
339
 
        default:
340
 
                break;
341
 
        }
342
 
 
343
330
        strcat(buf, ";");
344
331
 
345
332
        if (g_at_chat_send(vd->chat, buf, atd_prefix,
346
333
                                atd_cb, cbd, g_free) > 0)
347
334
                return;
348
335
 
349
 
error:
350
336
        g_free(cbd);
351
337
 
352
338
        CALLBACK_WITH_FAILURE(cb, data);
359
345
        struct voicecall_data *vd = ofono_voicecall_get_data(vc);
360
346
        struct change_state_req *req = g_try_new0(struct change_state_req, 1);
361
347
 
362
 
        if (!req)
 
348
        if (req == NULL)
363
349
                goto error;
364
350
 
365
351
        req->vc = vc;
406
392
static void ifx_release_all_held(struct ofono_voicecall *vc,
407
393
                                ofono_voicecall_cb_t cb, void *data)
408
394
{
409
 
        unsigned int held_status = 0x1 << 1;
 
395
        unsigned int held_status = 1 << CALL_STATUS_HELD;
410
396
        ifx_template("AT+CHLD=0", vc, generic_cb, held_status, cb, data);
411
397
}
412
398
 
413
399
static void ifx_set_udub(struct ofono_voicecall *vc,
414
400
                        ofono_voicecall_cb_t cb, void *data)
415
401
{
416
 
        unsigned int incoming_or_waiting = (0x1 << 4) | (0x1 << 5);
 
402
        unsigned int incoming_or_waiting =
 
403
                (1 << CALL_STATUS_INCOMING) | (1 << CALL_STATUS_WAITING);
 
404
 
417
405
        ifx_template("AT+CHLD=0", vc, generic_cb, incoming_or_waiting,
418
406
                        cb, data);
419
407
}
431
419
        struct release_id_req *req = g_try_new0(struct release_id_req, 1);
432
420
        char buf[32];
433
421
 
434
 
        if (!req)
 
422
        if (req == NULL)
435
423
                goto error;
436
424
 
437
425
        req->vc = vc;
486
474
                        ofono_voicecall_cb_t cb, void *data)
487
475
{
488
476
        char buf[128];
489
 
        unsigned int incoming_or_waiting = (0x1 << 4) | (0x1 << 5);
 
477
        unsigned int incoming_or_waiting =
 
478
                (1 << CALL_STATUS_INCOMING) | (1 << CALL_STATUS_WAITING);
490
479
 
491
480
        snprintf(buf, sizeof(buf), "AT+CTFR=%s,%d", ph->number, ph->type);
492
481
        ifx_template(buf, vc, generic_cb, incoming_or_waiting, cb, data);
518
507
        int i;
519
508
        char *buf;
520
509
 
521
 
        if (!cbd)
522
 
                goto error;
523
 
 
524
510
        /* strlen("+VTS=T\;") = 7 + initial AT + null */
525
511
        buf = g_try_new(char, len * 7 + 3);
526
 
        if (!buf)
 
512
        if (buf == NULL)
527
513
                goto error;
528
514
 
529
515
        s = sprintf(buf, "AT+VTS=%c", dtmf[0]);
560
546
         * the stage change.  If this happens, simply ignore the RING/CRING
561
547
         * when a waiting call exists (cannot have waiting + incoming in GSM)
562
548
         */
563
 
        if (g_slist_find_custom(vd->calls, GINT_TO_POINTER(5),
 
549
        if (g_slist_find_custom(vd->calls,
 
550
                                GINT_TO_POINTER(CALL_STATUS_WAITING),
564
551
                                at_util_call_compare_by_status))
565
552
                return;
566
553
 
567
554
        /* CRING can repeat, ignore if we already have an incoming call */
568
 
        if (g_slist_find_custom(vd->calls, GINT_TO_POINTER(4),
 
555
        if (g_slist_find_custom(vd->calls,
 
556
                                GINT_TO_POINTER(CALL_STATUS_INCOMING),
569
557
                                at_util_call_compare_by_status))
570
558
                return;
571
559
 
585
573
                type = 9;
586
574
 
587
575
        /* Generate an incoming call */
588
 
        create_call(vc, type, 1, 4, NULL, 128, 2);
 
576
        create_call(vc, type, 1, CALL_STATUS_INCOMING, NULL, 128, 2);
589
577
 
590
578
        /* Assume the CLIP always arrives, and we signal the call there */
591
579
        DBG("cring_notify");
601
589
        GSList *l;
602
590
        struct ofono_call *call;
603
591
 
604
 
        l = g_slist_find_custom(vd->calls, GINT_TO_POINTER(4),
 
592
        l = g_slist_find_custom(vd->calls,
 
593
                                GINT_TO_POINTER(CALL_STATUS_INCOMING),
605
594
                                at_util_call_compare_by_status);
606
595
        if (l == NULL) {
607
596
                ofono_error("CLIP for unknown call");
656
645
        struct ofono_call *call;
657
646
 
658
647
        /* Some modems resend CCWA, ignore it the second time around */
659
 
        if (g_slist_find_custom(vd->calls, GINT_TO_POINTER(5),
 
648
        if (g_slist_find_custom(vd->calls,
 
649
                                GINT_TO_POINTER(CALL_STATUS_WAITING),
660
650
                                at_util_call_compare_by_status))
661
651
                return;
662
652
 
687
677
 
688
678
        DBG("ccwa_notify: %s %d %d %d", num, num_type, cls, validity);
689
679
 
690
 
        call = create_call(vc, class_to_call_type(cls), 1, 5,
 
680
        call = create_call(vc, class_to_call_type(cls), 1, CALL_STATUS_WAITING,
691
681
                                num, num_type, validity);
692
 
        if (!call) {
 
682
        if (call == NULL) {
693
683
                ofono_error("Unable to malloc. Call management is fubar");
694
684
                return;
695
685
        }
723
713
        struct voicecall_data *vd;
724
714
 
725
715
        vd = g_try_new0(struct voicecall_data, 1);
726
 
        if (!vd)
 
716
        if (vd == NULL)
727
717
                return -ENOMEM;
728
718
 
729
719
        vd->chat = g_at_chat_clone(chat);
777
767
        .send_tones             = ifx_send_dtmf
778
768
};
779
769
 
780
 
void ifx_voicecall_init()
 
770
void ifx_voicecall_init(void)
781
771
{
782
772
        ofono_voicecall_driver_register(&driver);
783
773
}
784
774
 
785
 
void ifx_voicecall_exit()
 
775
void ifx_voicecall_exit(void)
786
776
{
787
777
        ofono_voicecall_driver_unregister(&driver);
788
778
}