~ubuntu-branches/ubuntu/utopic/ofono/utopic-proposed

« back to all changes in this revision

Viewing changes to plugins/ifx.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-08-22 19:59:08 UTC
  • mfrom: (1.4.3)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120822195908-20ccett2uhgcz7f6
Tags: upstream-1.9
ImportĀ upstreamĀ versionĀ 1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 *  oFono - Open Source Telephony
4
4
 *
5
 
 *  Copyright (C) 2008-2010  Intel Corporation. All rights reserved.
 
5
 *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6
6
 *
7
7
 *  This program is free software; you can redistribute it and/or modify
8
8
 *  it under the terms of the GNU General Public License version 2 as
47
47
#include <ofono/call-settings.h>
48
48
#include <ofono/call-volume.h>
49
49
#include <ofono/message-waiting.h>
50
 
#include <ofono/ssn.h>
51
50
#include <ofono/sim.h>
52
51
#include <ofono/cbs.h>
53
52
#include <ofono/sms.h>
56
55
#include <ofono/gprs-context.h>
57
56
#include <ofono/radio-settings.h>
58
57
#include <ofono/audio-settings.h>
 
58
#include <ofono/gnss.h>
59
59
#include <ofono/stk.h>
60
60
#include <ofono/ctm.h>
61
61
#include <ofono/log.h>
80
80
                                        "/dev/ttyGSM5", "/dev/ttyGSM6" };
81
81
 
82
82
static const char *none_prefix[] = { NULL };
83
 
static const char *xdrv_prefix[] = { "+XDRV:", NULL };
 
83
static const char *xgendata_prefix[] = { "+XGENDATA:", NULL };
 
84
static const char *xsimstate_prefix[] = { "+XSIMSTATE:", NULL };
84
85
 
85
86
struct ifx_data {
86
87
        GIOChannel *device;
93
94
        guint frame_size;
94
95
        int mux_ldisc;
95
96
        int saved_ldisc;
96
 
        int audio_source;
97
 
        int audio_dest;
98
 
        int audio_context;
99
 
        const char *audio_setting;
100
 
        int audio_loopback;
101
97
        struct ofono_sim *sim;
102
98
        gboolean have_sim;
103
99
};
138
134
        g_free(data);
139
135
}
140
136
 
141
 
static void xsim_notify(GAtResult *result, gpointer user_data)
 
137
static void ifx_set_sim_state(struct ifx_data *data, int state)
142
138
{
143
 
        struct ofono_modem *modem = user_data;
144
 
        struct ifx_data *data = ofono_modem_get_data(modem);
145
 
 
146
 
        GAtResultIter iter;
147
 
        int state;
148
 
 
149
 
        if (data->sim == NULL)
150
 
                return;
151
 
 
152
 
        g_at_result_iter_init(&iter, result);
153
 
 
154
 
        if (!g_at_result_iter_next(&iter, "+XSIM:"))
155
 
                return;
156
 
 
157
 
        if (!g_at_result_iter_next_number(&iter, &state))
158
 
                return;
159
 
 
160
139
        DBG("state %d", state);
161
140
 
162
141
        switch (state) {
186
165
        }
187
166
}
188
167
 
 
168
static void xsim_notify(GAtResult *result, gpointer user_data)
 
169
{
 
170
        struct ofono_modem *modem = user_data;
 
171
        struct ifx_data *data = ofono_modem_get_data(modem);
 
172
 
 
173
        GAtResultIter iter;
 
174
        int state;
 
175
 
 
176
        if (data->sim == NULL)
 
177
                return;
 
178
 
 
179
        g_at_result_iter_init(&iter, result);
 
180
 
 
181
        if (!g_at_result_iter_next(&iter, "+XSIM:"))
 
182
                return;
 
183
 
 
184
        if (!g_at_result_iter_next_number(&iter, &state))
 
185
                return;
 
186
 
 
187
        ifx_set_sim_state(data, state);
 
188
}
 
189
 
 
190
static void xsimstate_query(gboolean ok, GAtResult *result, gpointer user_data)
 
191
{
 
192
        struct ofono_modem *modem = user_data;
 
193
        struct ifx_data *data = ofono_modem_get_data(modem);
 
194
        GAtResultIter iter;
 
195
        int mode;
 
196
        int state;
 
197
 
 
198
        DBG("");
 
199
 
 
200
        if (!ok)
 
201
                return;
 
202
 
 
203
        g_at_result_iter_init(&iter, result);
 
204
 
 
205
        if (!g_at_result_iter_next(&iter, "+XSIMSTATE:"))
 
206
                return;
 
207
 
 
208
        if (!g_at_result_iter_next_number(&iter, &mode))
 
209
                return;
 
210
 
 
211
        if (!g_at_result_iter_next_number(&iter, &state))
 
212
                return;
 
213
 
 
214
        ifx_set_sim_state(data, state);
 
215
}
 
216
 
189
217
static void shutdown_device(struct ifx_data *data)
190
218
{
191
219
        int i, fd;
281
309
 
282
310
        DBG("\n%s", gendata);
283
311
 
284
 
        if (g_str_has_prefix(gendata, "    XMM6260") == TRUE) {
285
 
                ofono_info("Detected XMM6260 modem");
286
 
                data->audio_source = 4;
287
 
                data->audio_dest = 3;
288
 
                data->audio_context = 0;
289
 
        }
 
312
        /* switch to GSM character set instead of IRA */
 
313
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+CSCS=\"GSM\"", none_prefix,
 
314
                                                        NULL, NULL, NULL);
290
315
 
291
316
        /* disable UART for power saving */
292
317
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+XPOW=0,0,0", none_prefix,
293
318
                                                        NULL, NULL, NULL);
294
319
 
295
 
        if (data->audio_setting && data->audio_source && data->audio_dest) {
296
 
                char buf[64];
297
 
 
298
 
                /* configure source */
299
 
                snprintf(buf, sizeof(buf), "AT+XDRV=40,4,%d,%d,%s",
300
 
                                                data->audio_source,
301
 
                                                data->audio_context,
302
 
                                                data->audio_setting);
303
 
                g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
304
 
                                                NULL, NULL, NULL);
305
 
 
306
 
                /* configure destination */
307
 
                snprintf(buf, sizeof(buf), "AT+XDRV=40,5,%d,%d,%s",
308
 
                                                data->audio_dest,
309
 
                                                data->audio_context,
310
 
                                                data->audio_setting);
311
 
                g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
312
 
                                                NULL, NULL, NULL);
313
 
 
314
 
                if (data->audio_loopback) {
315
 
                        /* set destination for source */
316
 
                        snprintf(buf, sizeof(buf), "AT+XDRV=40,6,%d,%d",
317
 
                                        data->audio_source, data->audio_dest);
318
 
                        g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
319
 
                                                        NULL, NULL, NULL);
320
 
 
321
 
                        /* enable source */
322
 
                        snprintf(buf, sizeof(buf), "AT+XDRV=40,2,%d",
323
 
                                                        data->audio_source);
324
 
                        g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
325
 
                                                        NULL, NULL, NULL);
326
 
                }
327
 
        }
328
 
 
329
320
        data->have_sim = FALSE;
330
321
 
331
322
        /* notify that the modem is ready so that pre_sim gets called */
338
329
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE=1", none_prefix,
339
330
                                                NULL, NULL, NULL);
340
331
 
 
332
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE?", xsimstate_prefix,
 
333
                                        xsimstate_query, modem, NULL);
 
334
 
341
335
        return;
342
336
 
343
337
error:
358
352
                return;
359
353
        }
360
354
 
361
 
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+XGENDATA", NULL,
 
355
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+XGENDATA", xgendata_prefix,
362
356
                                        xgendata_query, modem, NULL);
363
357
}
364
358
 
455
449
                        ofono_error("Failed to create channel");
456
450
                        goto error;
457
451
                }
458
 
        }
 
452
        }
459
453
 
460
454
        /* wait for DLC creation to settle */
461
455
        data->dlc_init_source = g_timeout_add(10, dlc_setup, modem);
542
536
static int ifx_enable(struct ofono_modem *modem)
543
537
{
544
538
        struct ifx_data *data = ofono_modem_get_data(modem);
545
 
        const char *device, *ldisc, *audio, *loopback;
 
539
        const char *device, *ldisc;
546
540
        GAtSyntax *syntax;
547
541
        GAtChat *chat;
548
542
 
554
548
 
555
549
        DBG("%s", device);
556
550
 
557
 
        audio = ofono_modem_get_string(modem, "AudioSetting");
558
 
        if (g_strcmp0(audio, "FULL_DUPLEX") == 0)
559
 
                data->audio_setting = "0,0,0,0,0,0,0,0,0";
560
 
        else if (g_strcmp0(audio, "BURSTMODE_48KHZ") == 0)
561
 
                data->audio_setting = "0,0,8,0,2,0,0,0,0";
562
 
        else if (g_strcmp0(audio, "BURSTMODE_96KHZ") == 0)
563
 
                data->audio_setting = "0,0,9,0,2,0,0,0,0";
564
 
 
565
 
        loopback = ofono_modem_get_string(modem, "AudioLoopback");
566
 
        if (loopback != NULL)
567
 
                data->audio_loopback = atoi(loopback);
568
 
 
569
551
        ldisc = ofono_modem_get_string(modem, "LineDiscipline");
570
552
        if (ldisc != NULL) {
571
553
                data->mux_ldisc = atoi(ldisc);
575
557
 
576
558
        data->device = g_at_tty_open(device, NULL);
577
559
        if (data->device == NULL)
578
 
                return -EIO;
 
560
                return -EIO;
579
561
 
580
562
        syntax = g_at_syntax_new_gsmv1();
581
563
        chat = g_at_chat_new(data->device, syntax);
583
565
 
584
566
        if (chat == NULL) {
585
567
                g_io_channel_unref(data->device);
586
 
                return -EIO;
 
568
                return -EIO;
587
569
        }
588
570
 
589
571
        if (getenv("OFONO_AT_DEBUG"))
592
574
        g_at_chat_send(chat, "ATE0 +CMEE=1", NULL,
593
575
                                        NULL, NULL, NULL);
594
576
 
 
577
        /* Enable multiplexer */
595
578
        data->frame_size = 1509;
596
579
 
597
580
        g_at_chat_send(chat, "AT+CMUX=0,0,,1509,10,3,30,,", NULL,
635
618
                g_at_chat_unregister_all(data->dlcs[i]);
636
619
        }
637
620
 
638
 
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+CFUN=4", NULL,
 
621
        g_at_chat_send(data->dlcs[AUX_DLC], "AT+CFUN=0", NULL,
639
622
                                        cfun_disable, modem, NULL);
640
623
 
641
624
        return -EINPROGRESS;
645
628
{
646
629
        struct cb_data *cbd = user_data;
647
630
        ofono_modem_online_cb_t cb = cbd->cb;
 
631
        struct ofono_error error;
648
632
 
649
 
        if (ok)
650
 
                CALLBACK_WITH_SUCCESS(cb, cbd->data);
651
 
        else
652
 
                CALLBACK_WITH_FAILURE(cb, cbd->data);
 
633
        decode_at_error(&error, g_at_result_final_response(result));
 
634
        cb(&error, cbd->data);
653
635
}
654
636
 
655
637
static void ifx_set_online(struct ofono_modem *modem, ofono_bool_t online,
661
643
 
662
644
        DBG("%p %s", modem, online ? "online" : "offline");
663
645
 
664
 
        if (g_at_chat_send(data->dlcs[AUX_DLC], command, NULL,
 
646
        if (g_at_chat_send(data->dlcs[AUX_DLC], command, none_prefix,
665
647
                                        set_online_cb, cbd, g_free) > 0)
666
648
                return;
667
649
 
 
650
        CALLBACK_WITH_FAILURE(cb, cbd->data);
 
651
 
668
652
        g_free(cbd);
669
 
 
670
 
        CALLBACK_WITH_FAILURE(cb, cbd->data);
671
653
}
672
654
 
673
655
static void ifx_pre_sim(struct ofono_modem *modem)
716
698
        ofono_cbs_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
717
699
        ofono_ussd_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
718
700
 
719
 
        ofono_ssn_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
 
701
        ofono_gnss_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
 
702
 
720
703
        ofono_call_settings_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
721
704
        ofono_call_meter_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
722
705
        ofono_call_barring_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);