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

« back to all changes in this revision

Viewing changes to drivers/atmodem/network-registration.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 "atmodem.h"
42
43
#include "vendor.h"
43
44
 
82
83
{
83
84
        GAtResultIter iter;
84
85
        int s, octi, ouwcti;
85
 
        int tech = -1;
 
86
        int tech;
86
87
 
87
88
        g_at_result_iter_init(&iter, result);
88
89
 
106
107
 
107
108
        switch (octi) {
108
109
        case 1: /* GSM */
109
 
                tech = 0;
 
110
                tech = ACCESS_TECHNOLOGY_GSM;
110
111
                break;
111
112
        case 2: /* GPRS */
112
 
                tech = 1;
 
113
                tech = ACCESS_TECHNOLOGY_GSM;
113
114
                break;
114
115
        case 3: /* EDGE */
115
 
                tech = 3;
 
116
                tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
 
117
                break;
 
118
        default:
 
119
                tech = -1;
116
120
                break;
117
121
        }
118
122
 
119
123
        switch (ouwcti) {
120
124
        case 1: /* UMTS */
121
 
                tech = 2;
 
125
                tech = ACCESS_TECHNOLOGY_UTRAN;
122
126
                break;
123
127
        case 2: /* HSDPA */
124
 
                tech = 4;
 
128
                tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA;
125
129
                break;
126
130
        case 3: /* HSUPA */
127
 
                tech = 5;
 
131
                tech = ACCESS_TECHNOLOGY_UTRAN_HSUPA;
128
132
                break;
129
133
        case 4: /* HSPA */
130
 
                tech = 6;
 
134
                tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
131
135
                break;
132
136
        }
133
137
 
182
186
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
183
187
        struct cb_data *cbd = cb_data_new(cb, data);
184
188
 
185
 
        if (!cbd)
186
 
                goto error;
187
 
 
188
189
        cbd->user = nd;
189
190
 
190
191
        switch (nd->vendor) {
196
197
                g_at_chat_send(nd->chat, "AT*ERINFO?", none_prefix,
197
198
                                NULL, NULL, NULL);
198
199
                break;
 
200
        case OFONO_VENDOR_GOBI:
 
201
                /*
 
202
                 * Send *CNTI=0 to find out the current tech, it will be
 
203
                 * intercepted in gobi_cnti_notify
 
204
                 */
 
205
                g_at_chat_send(nd->chat, "AT*CNTI=0", none_prefix,
 
206
                                NULL, NULL, NULL);
 
207
                break;
199
208
        case OFONO_VENDOR_NOVATEL:
200
209
                /*
201
210
                 * Send $CNTI=0 to find out the current tech, it will be
220
229
                                at_creg_cb, cbd, g_free) > 0)
221
230
                return;
222
231
 
223
 
error:
224
232
        g_free(cbd);
225
233
 
226
234
        CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
259
267
 
260
268
        /* Default to GSM */
261
269
        if (g_at_result_iter_next_number(&iter, &tech) == FALSE)
262
 
                tech = 0;
 
270
                tech = ACCESS_TECHNOLOGY_GSM;
263
271
 
264
272
        strncpy(op.name, name, OFONO_MAX_OPERATOR_NAME_LENGTH);
265
273
        op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
349
357
        struct cb_data *cbd = cb_data_new(cb, data);
350
358
        gboolean ok;
351
359
 
352
 
        if (!cbd)
353
 
                goto error;
354
 
 
355
360
        cbd->user = netreg;
356
361
 
357
362
        /* Nokia modems have a broken return value for the string
376
381
        if (ok)
377
382
                return;
378
383
 
379
 
error:
380
384
        g_free(cbd);
381
385
 
382
386
        CALLBACK_WITH_FAILURE(cb, NULL, data);
408
412
        DBG("Got %d elements", num);
409
413
 
410
414
        list = g_try_new0(struct ofono_network_operator, num);
411
 
 
412
 
        if (!list) {
 
415
        if (list == NULL) {
413
416
                CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
414
417
                return;
415
418
        }
455
458
                        extract_mcc_mnc(n, list[num].mcc, list[num].mnc);
456
459
 
457
460
                        if (!g_at_result_iter_next_number(&iter, &tech))
458
 
                                tech = 0;
 
461
                                tech = ACCESS_TECHNOLOGY_GSM;
459
462
 
460
463
                        list[num].tech = tech;
461
464
 
492
495
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
493
496
        struct cb_data *cbd = cb_data_new(cb, data);
494
497
 
495
 
        if (!cbd)
496
 
                goto error;
497
 
 
498
498
        if (g_at_chat_send(nd->chat, "AT+COPS=?", cops_prefix,
499
499
                                cops_list_cb, cbd, g_free) > 0)
500
500
                return;
501
501
 
502
 
error:
503
502
        g_free(cbd);
504
503
 
505
504
        CALLBACK_WITH_FAILURE(cb, 0, NULL, data);
522
521
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
523
522
        struct cb_data *cbd = cb_data_new(cb, data);
524
523
 
525
 
        if (!cbd)
526
 
                goto error;
527
 
 
528
524
        if (g_at_chat_send(nd->chat, "AT+COPS=0", none_prefix,
529
525
                                register_cb, cbd, g_free) > 0)
530
526
                return;
531
527
 
532
 
error:
533
528
        g_free(cbd);
534
529
 
535
530
        CALLBACK_WITH_FAILURE(cb, data);
543
538
        struct cb_data *cbd = cb_data_new(cb, data);
544
539
        char buf[128];
545
540
 
546
 
        if (!cbd)
547
 
                goto error;
548
 
 
549
541
        snprintf(buf, sizeof(buf), "AT+COPS=1,2,\"%s%s\"", mcc, mnc);
550
542
 
551
543
        if (g_at_chat_send(nd->chat, buf, none_prefix,
552
544
                                register_cb, cbd, g_free) > 0)
553
545
                return;
554
546
 
555
 
error:
556
 
        g_free(cbd);
557
 
 
558
 
        CALLBACK_WITH_FAILURE(cb, data);
559
 
}
560
 
 
561
 
static void at_deregister(struct ofono_netreg *netreg,
562
 
                                ofono_netreg_register_cb_t cb, void *data)
563
 
{
564
 
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
565
 
        struct cb_data *cbd = cb_data_new(cb, data);
566
 
 
567
 
        if (!cbd)
568
 
                goto error;
569
 
 
570
 
        if (g_at_chat_send(nd->chat, "AT+COPS=2", none_prefix,
571
 
                                register_cb, cbd, g_free) > 0)
572
 
                return;
573
 
 
574
 
error:
575
547
        g_free(cbd);
576
548
 
577
549
        CALLBACK_WITH_FAILURE(cb, data);
663
635
                return;
664
636
 
665
637
        if (ind == 0)
666
 
                strength = 0;
 
638
                strength = -1;
667
639
        else if (ind == 7)
668
640
                strength = 100;
669
641
        else
670
642
                strength = (ind * 15);
671
643
 
672
 
        ofono_netreg_strength_notify(netreg, ind);
 
644
        ofono_netreg_strength_notify(netreg, strength);
673
645
}
674
646
 
675
647
static void ciev_notify(GAtResult *result, gpointer user_data)
699
671
 
700
672
static void ctzv_notify(GAtResult *result, gpointer user_data)
701
673
{
702
 
        //struct ofono_netreg *netreg = user_data;
703
 
        //struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
674
        struct ofono_netreg *netreg = user_data;
 
675
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
704
676
        const char *tz;
705
677
        GAtResultIter iter;
706
678
 
713
685
                return;
714
686
 
715
687
        DBG("tz %s", tz);
 
688
 
 
689
        nd->time.utcoff = atoi(tz) * 15 * 60;
 
690
 
 
691
        ofono_netreg_time_notify(netreg, &nd->time);
716
692
}
717
693
 
718
694
static void ifx_ctzv_notify(GAtResult *result, gpointer user_data)
862
838
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
863
839
        struct cb_data *cbd = cb_data_new(cb, data);
864
840
 
865
 
        if (!cbd)
866
 
                goto error;
867
 
 
868
841
        cbd->user = nd;
869
842
 
870
843
        /*
881
854
                        return;
882
855
        }
883
856
 
884
 
error:
885
857
        g_free(cbd);
886
858
 
887
859
        CALLBACK_WITH_FAILURE(cb, -1, data);
969
941
        /* Convert to tech values from 27.007 */
970
942
        switch (gsm) {
971
943
        case 1: /* GSM */
972
 
                nd->tech = 0;
 
944
                nd->tech = ACCESS_TECHNOLOGY_GSM;
973
945
                break;
974
946
        case 2: /* EDGE */
975
 
                nd->tech = 3;
 
947
                nd->tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
976
948
                break;
977
949
        default:
978
950
                nd->tech = -1;
980
952
 
981
953
        switch (umts) {
982
954
        case 1: /* UMTS */
983
 
                nd->tech = 2;
 
955
                nd->tech = ACCESS_TECHNOLOGY_UTRAN;
984
956
                break;
985
957
        case 2: /* UMTS + HSDPA */
986
 
                nd->tech = 4;
987
 
                break;
988
 
        default:
 
958
                nd->tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA;
989
959
                break;
990
960
        }
991
961
}
992
962
 
 
963
static int cnti_to_tech(const char *cnti)
 
964
{
 
965
        if (g_str_equal(cnti, "GSM") == TRUE ||
 
966
                        g_str_equal(cnti, "GPRS") == TRUE)
 
967
                return ACCESS_TECHNOLOGY_GSM;
 
968
        else if (g_str_equal(cnti, "EDGE") == TRUE)
 
969
                return ACCESS_TECHNOLOGY_GSM_EGPRS;
 
970
        else if (g_str_equal(cnti, "UMTS") == TRUE)
 
971
                return ACCESS_TECHNOLOGY_UTRAN;
 
972
        else if (g_str_equal(cnti, "HSDPA") == TRUE)
 
973
                return ACCESS_TECHNOLOGY_UTRAN_HSDPA;
 
974
        else if (g_str_equal(cnti, "HSUPA") == TRUE)
 
975
                return ACCESS_TECHNOLOGY_UTRAN_HSUPA;
 
976
 
 
977
        return -1;
 
978
}
 
979
 
 
980
static void gobi_cnti_notify(GAtResult *result, gpointer user_data)
 
981
{
 
982
        struct ofono_netreg *netreg = user_data;
 
983
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
984
        GAtResultIter iter;
 
985
        const char *tech;
 
986
        int option;
 
987
 
 
988
        g_at_result_iter_init(&iter, result);
 
989
 
 
990
        if (g_at_result_iter_next(&iter, "*CNTI:") == FALSE)
 
991
                return;
 
992
 
 
993
        if (g_at_result_iter_next_number(&iter, &option) == FALSE)
 
994
                return;
 
995
 
 
996
        if (option != 0)
 
997
                return;
 
998
 
 
999
        if (g_at_result_iter_next_unquoted_string(&iter, &tech) == FALSE)
 
1000
                return;
 
1001
 
 
1002
        nd->tech = cnti_to_tech(tech);
 
1003
}
 
1004
 
993
1005
static void nw_cnti_notify(GAtResult *result, gpointer user_data)
994
1006
{
995
 
        //struct ofono_netreg *netreg = user_data;
996
 
        //struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
1007
        struct ofono_netreg *netreg = user_data;
 
1008
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
997
1009
        GAtResultIter iter;
998
1010
        const char *tech;
999
1011
        int option;
1012
1024
        if (g_at_result_iter_next_unquoted_string(&iter, &tech) == FALSE)
1013
1025
                return;
1014
1026
 
1015
 
        ofono_info("CNTI: %s", tech);
1016
 
}
1017
 
 
1018
 
static void option_query_tech_cb(gboolean ok,
1019
 
                        GAtResult *result, gpointer user_data)
1020
 
{
1021
 
        struct tech_query *tq = user_data;
1022
 
        int tech = -1;
 
1027
        nd->tech = cnti_to_tech(tech);
 
1028
}
 
1029
 
 
1030
static void cnti_query_tech_cb(gboolean ok, GAtResult *result,
 
1031
                                                gpointer user_data)
 
1032
{
 
1033
        struct tech_query *tq = user_data;
 
1034
        struct netreg_data *nd = ofono_netreg_get_data(tq->netreg);
 
1035
 
 
1036
        ofono_netreg_status_notify(tq->netreg,
 
1037
                        tq->status, tq->lac, tq->ci, nd->tech);
 
1038
}
 
1039
 
 
1040
static void option_query_tech_cb(gboolean ok, GAtResult *result,
 
1041
                                                gpointer user_data)
 
1042
{
 
1043
        struct tech_query *tq = user_data;
 
1044
        int tech;
1023
1045
 
1024
1046
        if (ok)
1025
1047
                tech = option_parse_tech(result);
 
1048
        else
 
1049
                tech = -1;
1026
1050
 
1027
1051
        ofono_netreg_status_notify(tq->netreg,
1028
1052
                        tq->status, tq->lac, tq->ci, tech);
1042
1066
        if (status != 1 && status != 5)
1043
1067
                goto notify;
1044
1068
 
 
1069
        tq = g_try_new0(struct tech_query, 1);
 
1070
        if (tq == NULL)
 
1071
                goto notify;
 
1072
 
 
1073
        tq->status = status;
 
1074
        tq->lac = lac;
 
1075
        tq->ci = ci;
 
1076
        tq->netreg = netreg;
 
1077
 
1045
1078
        switch (nd->vendor) {
 
1079
        case OFONO_VENDOR_GOBI:
 
1080
                if (g_at_chat_send(nd->chat, "AT*CNTI=0", none_prefix,
 
1081
                                        cnti_query_tech_cb, tq, g_free) > 0)
 
1082
                        return;
 
1083
                break;
 
1084
        case OFONO_VENDOR_NOVATEL:
 
1085
                if (g_at_chat_send(nd->chat, "AT$CNTI=0", none_prefix,
 
1086
                                        cnti_query_tech_cb, tq, g_free) > 0)
 
1087
                        return;
 
1088
                break;
1046
1089
        case OFONO_VENDOR_OPTION_HSO:
1047
 
                tq = g_new0(struct tech_query, 1);
1048
 
                if (!tq)
1049
 
                        break;
1050
 
 
1051
 
                tq->status = status;
1052
 
                tq->lac = lac;
1053
 
                tq->ci = ci;
1054
 
                tq->netreg = netreg;
1055
 
 
1056
1090
                if (g_at_chat_send(nd->chat, "AT_OCTI?;_OUWCTI?",
1057
1091
                                        option_tech_prefix,
1058
1092
                                        option_query_tech_cb, tq, g_free) > 0)
1059
1093
                        return;
1060
 
 
1061
 
                g_free(tq);
1062
1094
                break;
1063
1095
        }
1064
1096
 
 
1097
        g_free(tq);
 
1098
 
1065
1099
        if ((status == 1 || status == 5) && tech == -1)
1066
1100
                tech = nd->tech;
1067
1101
 
1198
1232
                g_at_chat_send(nd->chat, "AT+CIND=?", cind_prefix,
1199
1233
                                        cind_support_cb, netreg, NULL);
1200
1234
                return;
 
1235
        case OFONO_VENDOR_GOBI:
 
1236
                /*
 
1237
                 * Gobi devices don't support unsolicited notifications
 
1238
                 * of technology changes, but register a handle for
 
1239
                 * CNTI so we get notified by any query.
 
1240
                 */
 
1241
                g_at_chat_register(nd->chat, "*CNTI:", gobi_cnti_notify,
 
1242
                                        FALSE, netreg, NULL);
 
1243
                break;
1201
1244
        case OFONO_VENDOR_NOVATEL:
1202
1245
                /*
1203
1246
                 * Novatel doesn't support unsolicited notifications
1339
1382
        .list_operators                 = at_list_operators,
1340
1383
        .register_auto                  = at_register_auto,
1341
1384
        .register_manual                = at_register_manual,
1342
 
        .deregister                     = at_deregister,
1343
1385
        .strength                       = at_signal_strength,
1344
1386
};
1345
1387
 
1346
 
void at_netreg_init()
 
1388
void at_netreg_init(void)
1347
1389
{
1348
1390
        ofono_netreg_driver_register(&driver);
1349
1391
}
1350
1392
 
1351
 
void at_netreg_exit()
 
1393
void at_netreg_exit(void)
1352
1394
{
1353
1395
        ofono_netreg_driver_unregister(&driver);
1354
1396
}