ifx: Make sure query XSIMSTATE
[platform/upstream/ofono.git] / plugins / ifx.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <sys/stat.h>
30 #include <sys/ioctl.h>
31
32 #include <glib.h>
33 #include <gatchat.h>
34 #include <gatmux.h>
35 #include <gattty.h>
36
37 #define OFONO_API_SUBJECT_TO_CHANGE
38 #include <ofono/plugin.h>
39 #include <ofono/modem.h>
40 #include <ofono/devinfo.h>
41 #include <ofono/netreg.h>
42 #include <ofono/phonebook.h>
43 #include <ofono/voicecall.h>
44 #include <ofono/call-barring.h>
45 #include <ofono/call-forwarding.h>
46 #include <ofono/call-meter.h>
47 #include <ofono/call-settings.h>
48 #include <ofono/call-volume.h>
49 #include <ofono/message-waiting.h>
50 #include <ofono/sim.h>
51 #include <ofono/cbs.h>
52 #include <ofono/sms.h>
53 #include <ofono/ussd.h>
54 #include <ofono/gprs.h>
55 #include <ofono/gprs-context.h>
56 #include <ofono/radio-settings.h>
57 #include <ofono/audio-settings.h>
58 #include <ofono/stk.h>
59 #include <ofono/ctm.h>
60 #include <ofono/log.h>
61
62 #include <drivers/atmodem/atutil.h>
63 #include <drivers/atmodem/vendor.h>
64
65 #define NUM_DLC  6
66
67 #define VOICE_DLC   0
68 #define NETREG_DLC  1
69 #define GPRS1_DLC   2
70 #define GPRS2_DLC   3
71 #define GPRS3_DLC   4
72 #define AUX_DLC     5
73
74 static char *dlc_prefixes[NUM_DLC] = { "Voice: ", "Net: ", "GPRS1: ",
75                                         "GPRS2: ", "GPRS3: ", "Aux: " };
76
77 static const char *dlc_nodes[NUM_DLC] = { "/dev/ttyGSM1", "/dev/ttyGSM2",
78                                         "/dev/ttyGSM3", "/dev/ttyGSM4",
79                                         "/dev/ttyGSM5", "/dev/ttyGSM6" };
80
81 static const char *none_prefix[] = { NULL };
82 static const char *xdrv_prefix[] = { "+XDRV:", NULL };
83 static const char *xgendata_prefix[] = { "+XGENDATA:", NULL };
84 static const char *xsimstate_prefix[] = { "+XSIMSTATE:", NULL };
85
86 struct ifx_data {
87         GIOChannel *device;
88         GAtMux *mux;
89         GAtChat *dlcs[NUM_DLC];
90         guint dlc_poll_count;
91         guint dlc_poll_source;
92         guint dlc_init_source;
93         guint mux_init_timeout;
94         guint frame_size;
95         int mux_ldisc;
96         int saved_ldisc;
97         int audio_source;
98         int audio_dest;
99         int audio_context;
100         const char *audio_setting;
101         int audio_loopback;
102         struct ofono_sim *sim;
103         gboolean have_sim;
104 };
105
106 static void ifx_debug(const char *str, void *user_data)
107 {
108         const char *prefix = user_data;
109
110         ofono_info("%s%s", prefix, str);
111 }
112
113 static int ifx_probe(struct ofono_modem *modem)
114 {
115         struct ifx_data *data;
116
117         DBG("%p", modem);
118
119         data = g_try_new0(struct ifx_data, 1);
120         if (data == NULL)
121                 return -ENOMEM;
122
123         data->mux_ldisc = -1;
124         data->saved_ldisc = -1;
125
126         ofono_modem_set_data(modem, data);
127
128         return 0;
129 }
130
131 static void ifx_remove(struct ofono_modem *modem)
132 {
133         struct ifx_data *data = ofono_modem_get_data(modem);
134
135         DBG("%p", modem);
136
137         ofono_modem_set_data(modem, NULL);
138
139         g_free(data);
140 }
141
142 static void ifx_set_sim_state(struct ofono_modem *modem, int state)
143 {
144         struct ifx_data *data = ofono_modem_get_data(modem);
145
146         DBG("state %d", state);
147
148         switch (state) {
149         case 0: /* SIM not present */
150         case 9: /* SIM Removed */
151                 if (data->have_sim == TRUE) {
152                         ofono_sim_inserted_notify(data->sim, FALSE);
153                         data->have_sim = FALSE;
154                 }
155                 break;
156         case 1: /* PIN verification needed */
157         case 2: /* PIN verification not needed – Ready */
158         case 3: /* PIN verified – Ready */
159         case 4: /* PUK verification needed */
160         case 5: /* SIM permanently blocked */
161         case 6: /* SIM Error */
162         case 7: /* ready for attach (+COPS) */
163         case 8: /* SIM Technical Problem */
164                 if (data->have_sim == FALSE) {
165                         ofono_sim_inserted_notify(data->sim, TRUE);
166                         data->have_sim = TRUE;
167                 }
168                 break;
169         default:
170                 ofono_warn("Unknown SIM state %d received", state);
171                 break;
172         }
173 }
174
175 static void xsim_notify(GAtResult *result, gpointer user_data)
176 {
177         struct ofono_modem *modem = user_data;
178         struct ifx_data *data = ofono_modem_get_data(modem);
179
180         GAtResultIter iter;
181         int state;
182
183         if (data->sim == NULL)
184                 return;
185
186         g_at_result_iter_init(&iter, result);
187
188         if (!g_at_result_iter_next(&iter, "+XSIM:"))
189                 return;
190
191         if (!g_at_result_iter_next_number(&iter, &state))
192                 return;
193
194         ifx_set_sim_state(modem, state);
195 }
196
197 static void xsimstate_query(gboolean ok, GAtResult *result, gpointer user_data)
198 {
199         struct ofono_modem *modem = user_data;
200         struct ifx_data *data = ofono_modem_get_data(modem);
201         GAtResultIter iter;
202         int mode;
203         int state;
204
205         DBG("");
206
207         if (!ok)
208                 return;
209
210         g_at_result_iter_init(&iter, result);
211
212         if (!g_at_result_iter_next(&iter, "+XSIMSTATE:"))
213                 return;
214
215         if (!g_at_result_iter_next_number(&iter, &mode))
216                 return;
217
218         if (!g_at_result_iter_next_number(&iter, &state))
219                 return;
220
221         ifx_set_sim_state(modem, state);
222 }
223
224 static void shutdown_device(struct ifx_data *data)
225 {
226         int i, fd;
227
228         DBG("");
229
230         if (data->dlc_init_source > 0) {
231                 g_source_remove(data->dlc_init_source);
232                 data->dlc_init_source = 0;
233         }
234
235         for (i = 0; i < NUM_DLC; i++) {
236                 if (data->dlcs[i] == NULL)
237                         continue;
238
239                 g_at_chat_unref(data->dlcs[i]);
240                 data->dlcs[i] = NULL;
241         }
242
243         if (data->mux) {
244                 g_at_mux_shutdown(data->mux);
245                 g_at_mux_unref(data->mux);
246                 data->mux = NULL;
247                 goto done;
248         }
249
250         fd = g_io_channel_unix_get_fd(data->device);
251
252         if (ioctl(fd, TIOCSETD, &data->saved_ldisc) < 0)
253                 ofono_warn("Failed to restore line discipline");
254
255 done:
256         g_io_channel_unref(data->device);
257         data->device = NULL;
258 }
259
260 static void dlc_disconnect(gpointer user_data)
261 {
262         struct ofono_modem *modem = user_data;
263         struct ifx_data *data = ofono_modem_get_data(modem);
264
265         DBG("");
266
267         ofono_warn("Disconnect of modem channel");
268
269         shutdown_device(data);
270 }
271
272 static GAtChat *create_chat(GIOChannel *channel, struct ofono_modem *modem,
273                                                                 char *debug)
274 {
275         GAtSyntax *syntax;
276         GAtChat *chat;
277
278         if (channel == NULL)
279                 return NULL;
280
281         syntax = g_at_syntax_new_gsmv1();
282         chat = g_at_chat_new(channel, syntax);
283         g_at_syntax_unref(syntax);
284         g_io_channel_unref(channel);
285
286         if (chat == NULL)
287                 return NULL;
288
289         if (getenv("OFONO_AT_DEBUG"))
290                 g_at_chat_set_debug(chat, ifx_debug, debug);
291
292         g_at_chat_set_disconnect_function(chat, dlc_disconnect, modem);
293
294         return chat;
295 }
296
297 static void xgendata_query(gboolean ok, GAtResult *result, gpointer user_data)
298 {
299         struct ofono_modem *modem = user_data;
300         struct ifx_data *data = ofono_modem_get_data(modem);
301         GAtResultIter iter;
302         const char *gendata;
303
304         DBG("");
305
306         if (!ok)
307                 goto error;
308
309         g_at_result_iter_init(&iter, result);
310
311         if (!g_at_result_iter_next(&iter, "+XGENDATA:"))
312                 goto error;
313
314         if (!g_at_result_iter_next_string(&iter, &gendata))
315                 goto error;
316
317         DBG("\n%s", gendata);
318
319         if (g_str_has_prefix(gendata, "    XMM6260") == TRUE) {
320                 ofono_info("Detected XMM6260 modem");
321                 data->audio_source = 4;
322                 data->audio_dest = 3;
323                 data->audio_context = 0;
324         }
325
326         /* disable UART for power saving */
327         g_at_chat_send(data->dlcs[AUX_DLC], "AT+XPOW=0,0,0", none_prefix,
328                                                         NULL, NULL, NULL);
329
330         if (data->audio_setting && data->audio_source && data->audio_dest) {
331                 char buf[64];
332
333                 /* configure source */
334                 snprintf(buf, sizeof(buf), "AT+XDRV=40,4,%d,%d,%s",
335                                                 data->audio_source,
336                                                 data->audio_context,
337                                                 data->audio_setting);
338                 g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
339                                                 NULL, NULL, NULL);
340
341                 /* configure destination */
342                 snprintf(buf, sizeof(buf), "AT+XDRV=40,5,%d,%d,%s",
343                                                 data->audio_dest,
344                                                 data->audio_context,
345                                                 data->audio_setting);
346                 g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
347                                                 NULL, NULL, NULL);
348
349                 if (data->audio_loopback) {
350                         /* set destination for source */
351                         snprintf(buf, sizeof(buf), "AT+XDRV=40,6,%d,%d",
352                                         data->audio_source, data->audio_dest);
353                         g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
354                                                         NULL, NULL, NULL);
355
356                         /* enable source */
357                         snprintf(buf, sizeof(buf), "AT+XDRV=40,2,%d",
358                                                         data->audio_source);
359                         g_at_chat_send(data->dlcs[AUX_DLC], buf, xdrv_prefix,
360                                                         NULL, NULL, NULL);
361                 }
362         }
363
364         data->have_sim = FALSE;
365
366         /* notify that the modem is ready so that pre_sim gets called */
367         ofono_modem_set_powered(modem, TRUE);
368
369         g_at_chat_register(data->dlcs[AUX_DLC], "+XSIM:", xsim_notify,
370                                                 FALSE, modem, NULL);
371
372         /* enable XSIM and XLOCK notifications */
373         g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE=1", none_prefix,
374                                                 NULL, NULL, NULL);
375
376         g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE?", xsimstate_prefix,
377                                         xsimstate_query, modem, NULL);
378
379         return;
380
381 error:
382         shutdown_device(data);
383         ofono_modem_set_powered(modem, FALSE);
384 }
385
386 static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
387 {
388         struct ofono_modem *modem = user_data;
389         struct ifx_data *data = ofono_modem_get_data(modem);
390
391         DBG("");
392
393         if (!ok) {
394                 shutdown_device(data);
395                 ofono_modem_set_powered(modem, FALSE);
396                 return;
397         }
398
399         g_at_chat_send(data->dlcs[AUX_DLC], "AT+XGENDATA", xgendata_prefix,
400                                         xgendata_query, modem, NULL);
401 }
402
403 static gboolean dlc_setup(gpointer user_data)
404 {
405         struct ofono_modem *modem = user_data;
406         struct ifx_data *data = ofono_modem_get_data(modem);
407         int i;
408
409         DBG("");
410
411         for (i = 0; i < NUM_DLC; i++)
412                 g_at_chat_send(data->dlcs[i], "ATE0 +CMEE=1", NULL,
413                                                 NULL, NULL, NULL);
414
415         g_at_chat_set_slave(data->dlcs[GPRS1_DLC], data->dlcs[NETREG_DLC]);
416         g_at_chat_set_slave(data->dlcs[GPRS2_DLC], data->dlcs[NETREG_DLC]);
417         g_at_chat_set_slave(data->dlcs[GPRS3_DLC], data->dlcs[NETREG_DLC]);
418
419         g_at_chat_send(data->dlcs[AUX_DLC], "AT+CFUN=4", NULL,
420                                         cfun_enable, modem, NULL);
421
422         data->dlc_init_source = 0;
423
424         return FALSE;
425 }
426
427 static gboolean dlc_ready_check(gpointer user_data)
428 {
429         struct ofono_modem *modem = user_data;
430         struct ifx_data *data = ofono_modem_get_data(modem);
431         struct stat st;
432         int i;
433
434         DBG("");
435
436         data->dlc_poll_count++;
437
438         if (stat(dlc_nodes[AUX_DLC], &st) < 0) {
439                 /* only possible error is ENOENT */
440                 if (data->dlc_poll_count > 6)
441                         goto error;
442
443                 return TRUE;
444         }
445
446         for (i = 0; i < NUM_DLC; i++) {
447                 GIOChannel *channel = g_at_tty_open(dlc_nodes[i], NULL);
448
449                 data->dlcs[i] = create_chat(channel, modem, dlc_prefixes[i]);
450                 if (data->dlcs[i] == NULL) {
451                         ofono_error("Failed to open %s", dlc_nodes[i]);
452                         goto error;
453                 }
454         }
455
456         data->dlc_poll_source = 0;
457
458         /* iterate through mainloop */
459         data->dlc_init_source = g_timeout_add_seconds(0, dlc_setup, modem);
460
461         return FALSE;
462
463 error:
464         data->dlc_poll_source = 0;
465
466         shutdown_device(data);
467         ofono_modem_set_powered(modem, FALSE);
468
469         return FALSE;
470 }
471
472 static void setup_internal_mux(struct ofono_modem *modem)
473 {
474         struct ifx_data *data = ofono_modem_get_data(modem);
475         int i;
476
477         DBG("");
478
479         data->mux = g_at_mux_new_gsm0710_basic(data->device, data->frame_size);
480         if (data->mux == NULL)
481                 goto error;
482
483         if (getenv("OFONO_MUX_DEBUG"))
484                 g_at_mux_set_debug(data->mux, ifx_debug, "MUX: ");
485
486         g_at_mux_start(data->mux);
487
488         for (i = 0; i < NUM_DLC; i++) {
489                 GIOChannel *channel = g_at_mux_create_channel(data->mux);
490
491                 data->dlcs[i] = create_chat(channel, modem, dlc_prefixes[i]);
492                 if (data->dlcs[i] == NULL) {
493                         ofono_error("Failed to create channel");
494                         goto error;
495                 }
496         }
497
498         /* wait for DLC creation to settle */
499         data->dlc_init_source = g_timeout_add(10, dlc_setup, modem);
500
501         return;
502
503 error:
504         shutdown_device(data);
505         ofono_modem_set_powered(modem, FALSE);
506 }
507
508 static void mux_setup_cb(gboolean ok, GAtResult *result, gpointer user_data)
509 {
510         struct ofono_modem *modem = user_data;
511         struct ifx_data *data = ofono_modem_get_data(modem);
512         int fd;
513
514         DBG("");
515
516         if (data->mux_init_timeout > 0) {
517                 g_source_remove(data->mux_init_timeout);
518                 data->mux_init_timeout = 0;
519         }
520
521         g_at_chat_unref(data->dlcs[AUX_DLC]);
522         data->dlcs[AUX_DLC] = NULL;
523
524         if (!ok)
525                 goto error;
526
527         if (data->mux_ldisc < 0) {
528                 ofono_info("Using internal multiplexer");
529                 setup_internal_mux(modem);
530                 return;
531         }
532
533         fd = g_io_channel_unix_get_fd(data->device);
534
535         if (ioctl(fd, TIOCGETD, &data->saved_ldisc) < 0) {
536                 ofono_error("Failed to get current line discipline");
537                 goto error;
538         }
539
540         if (ioctl(fd, TIOCSETD, &data->mux_ldisc) < 0) {
541                 ofono_error("Failed to set multiplexer line discipline");
542                 goto error;
543         }
544
545         data->dlc_poll_count = 0;
546         data->dlc_poll_source = g_timeout_add_seconds(1, dlc_ready_check,
547                                                                 modem);
548
549         return;
550
551 error:
552         data->saved_ldisc = -1;
553
554         g_io_channel_unref(data->device);
555         data->device = NULL;
556
557         ofono_modem_set_powered(modem, FALSE);
558 }
559
560 static gboolean mux_timeout_cb(gpointer user_data)
561 {
562         struct ofono_modem *modem = user_data;
563         struct ifx_data *data = ofono_modem_get_data(modem);
564
565         ofono_error("Timeout with multiplexer setup");
566
567         data->mux_init_timeout = 0;
568
569         g_at_chat_unref(data->dlcs[AUX_DLC]);
570         data->dlcs[AUX_DLC] = NULL;
571
572         g_io_channel_unref(data->device);
573         data->device = NULL;
574
575         ofono_modem_set_powered(modem, FALSE);
576
577         return FALSE;
578 }
579
580 static int ifx_enable(struct ofono_modem *modem)
581 {
582         struct ifx_data *data = ofono_modem_get_data(modem);
583         const char *device, *ldisc, *audio, *loopback;
584         GAtSyntax *syntax;
585         GAtChat *chat;
586
587         DBG("%p", modem);
588
589         device = ofono_modem_get_string(modem, "Device");
590         if (device == NULL)
591                 return -EINVAL;
592
593         DBG("%s", device);
594
595         audio = ofono_modem_get_string(modem, "AudioSetting");
596         if (g_strcmp0(audio, "FULL_DUPLEX") == 0)
597                 data->audio_setting = "0,0,0,0,0,0,0,0,0";
598         else if (g_strcmp0(audio, "BURSTMODE_48KHZ") == 0)
599                 data->audio_setting = "0,0,8,0,2,0,0,0,0";
600         else if (g_strcmp0(audio, "BURSTMODE_96KHZ") == 0)
601                 data->audio_setting = "0,0,9,0,2,0,0,0,0";
602
603         loopback = ofono_modem_get_string(modem, "AudioLoopback");
604         if (loopback != NULL)
605                 data->audio_loopback = atoi(loopback);
606
607         ldisc = ofono_modem_get_string(modem, "LineDiscipline");
608         if (ldisc != NULL) {
609                 data->mux_ldisc = atoi(ldisc);
610                 ofono_info("Using multiplexer line discipline %d",
611                                                         data->mux_ldisc);
612         }
613
614         data->device = g_at_tty_open(device, NULL);
615         if (data->device == NULL)
616                 return -EIO;
617
618         syntax = g_at_syntax_new_gsmv1();
619         chat = g_at_chat_new(data->device, syntax);
620         g_at_syntax_unref(syntax);
621
622         if (chat == NULL) {
623                 g_io_channel_unref(data->device);
624                 return -EIO;
625         }
626
627         if (getenv("OFONO_AT_DEBUG"))
628                 g_at_chat_set_debug(chat, ifx_debug, "Master: ");
629
630         g_at_chat_send(chat, "ATE0 +CMEE=1", NULL,
631                                         NULL, NULL, NULL);
632
633         /* Enable multiplexer */
634         data->frame_size = 1509;
635
636         g_at_chat_send(chat, "AT+CMUX=0,0,,1509,10,3,30,,", NULL,
637                                         mux_setup_cb, modem, NULL);
638
639         data->mux_init_timeout = g_timeout_add_seconds(5, mux_timeout_cb,
640                                                                 modem);
641
642         data->dlcs[AUX_DLC] = chat;
643
644         return -EINPROGRESS;
645 }
646
647 static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
648 {
649         struct ofono_modem *modem = user_data;
650         struct ifx_data *data = ofono_modem_get_data(modem);
651
652         DBG("");
653
654         if (data->dlc_poll_source > 0) {
655                 g_source_remove(data->dlc_poll_source);
656                 data->dlc_poll_source = 0;
657         }
658
659         shutdown_device(data);
660
661         if (ok)
662                 ofono_modem_set_powered(modem, FALSE);
663 }
664
665 static int ifx_disable(struct ofono_modem *modem)
666 {
667         struct ifx_data *data = ofono_modem_get_data(modem);
668         int i;
669
670         DBG("%p", modem);
671
672         for (i = 0; i < NUM_DLC; i++) {
673                 g_at_chat_cancel_all(data->dlcs[i]);
674                 g_at_chat_unregister_all(data->dlcs[i]);
675         }
676
677         g_at_chat_send(data->dlcs[AUX_DLC], "AT+CFUN=4", NULL,
678                                         cfun_disable, modem, NULL);
679
680         return -EINPROGRESS;
681 }
682
683 static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
684 {
685         struct cb_data *cbd = user_data;
686         ofono_modem_online_cb_t cb = cbd->cb;
687         struct ofono_error error;
688
689         decode_at_error(&error, g_at_result_final_response(result));
690         cb(&error, cbd->data);
691 }
692
693 static void ifx_set_online(struct ofono_modem *modem, ofono_bool_t online,
694                                 ofono_modem_online_cb_t cb, void *user_data)
695 {
696         struct ifx_data *data = ofono_modem_get_data(modem);
697         struct cb_data *cbd = cb_data_new(cb, user_data);
698         char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
699
700         DBG("%p %s", modem, online ? "online" : "offline");
701
702         if (g_at_chat_send(data->dlcs[AUX_DLC], command, none_prefix,
703                                         set_online_cb, cbd, g_free) > 0)
704                 return;
705
706         CALLBACK_WITH_FAILURE(cb, cbd->data);
707
708         g_free(cbd);
709 }
710
711 static void ifx_pre_sim(struct ofono_modem *modem)
712 {
713         struct ifx_data *data = ofono_modem_get_data(modem);
714
715         DBG("%p", modem);
716
717         ofono_devinfo_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
718         data->sim = ofono_sim_create(modem, OFONO_VENDOR_IFX,
719                                         "atmodem", data->dlcs[AUX_DLC]);
720         ofono_voicecall_create(modem, 0, "ifxmodem", data->dlcs[VOICE_DLC]);
721         ofono_audio_settings_create(modem, 0,
722                                         "ifxmodem", data->dlcs[VOICE_DLC]);
723         ofono_ctm_create(modem, 0, "ifxmodem", data->dlcs[AUX_DLC]);
724 }
725
726 static void ifx_post_sim(struct ofono_modem *modem)
727 {
728         struct ifx_data *data = ofono_modem_get_data(modem);
729
730         DBG("%p", modem);
731
732         ofono_stk_create(modem, 0, "ifxmodem", data->dlcs[AUX_DLC]);
733         ofono_phonebook_create(modem, OFONO_VENDOR_IFX,
734                                         "atmodem", data->dlcs[AUX_DLC]);
735         ofono_call_forwarding_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
736         ofono_radio_settings_create(modem, 0, "ifxmodem", data->dlcs[AUX_DLC]);
737
738         ofono_sms_create(modem, OFONO_VENDOR_IFX,
739                                         "atmodem", data->dlcs[AUX_DLC]);
740 }
741
742 static void ifx_post_online(struct ofono_modem *modem)
743 {
744         struct ifx_data *data = ofono_modem_get_data(modem);
745         struct ofono_message_waiting *mw;
746         struct ofono_gprs *gprs;
747         struct ofono_gprs_context *gc;
748
749         DBG("%p", modem);
750
751         ofono_netreg_create(modem, OFONO_VENDOR_IFX,
752                                         "atmodem", data->dlcs[NETREG_DLC]);
753
754         ofono_cbs_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
755         ofono_ussd_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
756
757         ofono_call_settings_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
758         ofono_call_meter_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
759         ofono_call_barring_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
760         ofono_call_volume_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
761
762         mw = ofono_message_waiting_create(modem);
763         if (mw)
764                 ofono_message_waiting_register(mw);
765
766         gprs = ofono_gprs_create(modem, OFONO_VENDOR_IFX,
767                                         "atmodem", data->dlcs[NETREG_DLC]);
768         if (gprs == NULL)
769                 return;
770
771         if (data->mux_ldisc < 0) {
772                 gc = ofono_gprs_context_create(modem, 0,
773                                         "ifxmodem", data->dlcs[GPRS1_DLC]);
774                 if (gc)
775                         ofono_gprs_add_context(gprs, gc);
776
777                 gc = ofono_gprs_context_create(modem, 0,
778                                         "ifxmodem", data->dlcs[GPRS2_DLC]);
779                 if (gc)
780                         ofono_gprs_add_context(gprs, gc);
781
782                 gc = ofono_gprs_context_create(modem, 0,
783                                         "ifxmodem", data->dlcs[GPRS3_DLC]);
784                 if (gc)
785                         ofono_gprs_add_context(gprs, gc);
786         }
787 }
788
789 static struct ofono_modem_driver ifx_driver = {
790         .name           = "ifx",
791         .probe          = ifx_probe,
792         .remove         = ifx_remove,
793         .enable         = ifx_enable,
794         .disable        = ifx_disable,
795         .set_online     = ifx_set_online,
796         .pre_sim        = ifx_pre_sim,
797         .post_sim       = ifx_post_sim,
798         .post_online    = ifx_post_online,
799 };
800
801 static int ifx_init(void)
802 {
803         return ofono_modem_driver_register(&ifx_driver);
804 }
805
806 static void ifx_exit(void)
807 {
808         ofono_modem_driver_unregister(&ifx_driver);
809 }
810
811 OFONO_PLUGIN_DEFINE(ifx, "Infineon modem driver", VERSION,
812                         OFONO_PLUGIN_PRIORITY_DEFAULT, ifx_init, ifx_exit)