~oem-solutions-group/network-manager/ubuntu.hardy.07

« back to all changes in this revision

Viewing changes to src/nm-gsm-device.c

(merge) RELEASE 0.7~~svn20080928t225540+eni0-0ubuntu1 to ubuntu/intrepid

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
        NMGsmSecret need_secret;
29
29
        guint pending_id;
30
30
        guint state_to_disconnected_id;
 
31
 
 
32
        guint reg_tries;
31
33
} NMGsmDevicePrivate;
32
34
 
33
35
enum {
46
48
static guint signals[LAST_SIGNAL] = { 0 };
47
49
 
48
50
static void enter_pin (NMGsmDevice *device, gboolean retry);
 
51
static void manual_registration (NMGsmDevice *device);
49
52
static void automatic_registration (NMGsmDevice *device);
50
53
 
51
54
NMGsmDevice *
70
73
 
71
74
static void
72
75
modem_wait_for_reply (NMGsmDevice *self,
73
 
                                  const char *command,
74
 
                                  guint timeout,
75
 
                                  char **responses,
76
 
                                  char **terminators,
77
 
                                  NMSerialWaitForReplyFn callback,
78
 
                                  gpointer user_data)
 
76
                      const char *command,
 
77
                      guint timeout,
 
78
                      const char **responses,
 
79
                      const char **terminators,
 
80
                      NMSerialWaitForReplyFn callback,
 
81
                      gpointer user_data)
79
82
{
80
83
        NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
81
84
        guint id = 0;
87
90
                nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
88
91
}
89
92
 
90
 
static void
91
 
modem_get_reply (NMGsmDevice *self,
92
 
                          const char *command,
93
 
                          guint timeout,
94
 
                          const char *terminators,
95
 
                          NMSerialGetReplyFn callback)
96
 
{
97
 
        NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
98
 
        guint id = 0;
99
 
 
100
 
        if (nm_serial_device_send_command_string (serial, command))
101
 
                id = nm_serial_device_get_reply (serial, timeout, terminators, callback, NULL);
102
 
 
103
 
        if (id == 0)
104
 
                nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
105
 
}
106
 
 
107
93
static NMSetting *
108
94
gsm_device_get_setting (NMGsmDevice *device, GType setting_type)
109
95
{
124
110
 
125
111
static void
126
112
dial_done (NMSerialDevice *device,
127
 
                 int reply_index,
128
 
                 gpointer user_data)
 
113
           int reply_index,
 
114
           const char *reply,
 
115
           gpointer user_data)
129
116
{
130
117
        gboolean success = FALSE;
131
118
        NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
168
155
{
169
156
        NMSettingGsm *setting;
170
157
        char *command;
171
 
        char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
 
158
        const char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
172
159
 
173
160
        setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
174
161
 
192
179
 
193
180
static void
194
181
set_apn_done (NMSerialDevice *device,
195
 
                    int reply_index,
196
 
                    gpointer user_data)
 
182
              int reply_index,
 
183
              const char *reply,
 
184
              gpointer user_data)
197
185
{
198
186
        switch (reply_index) {
199
187
        case 0:
211
199
static void
212
200
set_apn (NMGsmDevice *device)
213
201
{
 
202
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
214
203
        NMSettingGsm *setting;
215
204
        char *command;
216
 
        char *responses[] = { "OK", "ERROR", NULL };
 
205
        const char *responses[] = { "OK", "ERROR", NULL };
217
206
        guint cid = 1;
218
207
 
 
208
        priv->reg_tries = 0;
 
209
 
219
210
        setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
220
211
        if (!setting->apn) {
221
212
                /* APN not set, nothing to do */
224
215
        }
225
216
 
226
217
        command = g_strdup_printf ("AT+CGDCONT=%d, \"IP\", \"%s\"", cid, setting->apn);
227
 
        modem_wait_for_reply (device, command, 3, responses, responses, set_apn_done, GUINT_TO_POINTER (cid));
 
218
        modem_wait_for_reply (device, command, 7, responses, responses, set_apn_done, GUINT_TO_POINTER (cid));
228
219
        g_free (command);
229
220
}
230
221
 
231
 
static void
232
 
manual_registration_done (NMSerialDevice *device,
233
 
                                         int reply_index,
234
 
                                         gpointer user_data)
235
 
{
 
222
static gboolean
 
223
manual_registration_again (gpointer data)
 
224
{
 
225
        manual_registration (NM_GSM_DEVICE (data));
 
226
        return FALSE;
 
227
}
 
228
 
 
229
static void
 
230
schedule_manual_registration_again (NMGsmDevice *self)
 
231
{
 
232
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self);
 
233
 
 
234
        if (priv->pending_id)
 
235
                g_source_remove (priv->pending_id);
 
236
 
 
237
        priv->pending_id = g_idle_add (manual_registration_again, self);
 
238
}
 
239
 
 
240
static void
 
241
manual_registration_response (NMSerialDevice *device,
 
242
                              int reply_index,
 
243
                              const char *reply,
 
244
                              gpointer user_data)
 
245
{
 
246
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
 
247
 
236
248
        switch (reply_index) {
237
249
        case 0:
238
250
                set_apn (NM_GSM_DEVICE (device));
239
251
                break;
240
252
        case -1:
241
 
                nm_warning ("Manual registration timed out");
242
 
                nm_device_state_changed (NM_DEVICE (device),
243
 
                                         NM_DEVICE_STATE_FAILED,
244
 
                                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 
253
                /* Some cards (ex. Sierra AC860) don't immediately respond to commands
 
254
                 * after they are powered up with CFUN=1, but take a few seconds to come
 
255
                 * back to life.  So try registration a few times.
 
256
                 */
 
257
                if (priv->reg_tries++ < 6) {
 
258
                        schedule_manual_registration_again (NM_GSM_DEVICE (device));
 
259
                } else {
 
260
                        nm_warning ("Manual registration timed out");
 
261
                        priv->reg_tries = 0;
 
262
                        nm_device_state_changed (NM_DEVICE (device),
 
263
                                                 NM_DEVICE_STATE_FAILED,
 
264
                                                 NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 
265
                }
245
266
                break;
246
267
        default:
247
268
                nm_warning ("Manual registration failed");
257
278
{
258
279
        NMSettingGsm *setting;
259
280
        char *command;
260
 
        char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
281
        const char *responses[] = { "OK", "ERROR", "ERR", NULL };
261
282
 
262
283
        setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
263
284
 
264
285
        command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", setting->network_id);
265
 
        modem_wait_for_reply (device, command, 30, responses, responses, manual_registration_done, NULL);
 
286
        modem_wait_for_reply (device, command, 15, responses, responses, manual_registration_response, NULL);
266
287
        g_free (command);
267
288
}
268
289
 
269
290
static void
270
 
get_network_done (NMSerialDevice *device,
271
 
                           const char *response,
272
 
                           gpointer user_data)
 
291
get_network_response (NMSerialDevice *device,
 
292
                      int reply_index,
 
293
                      const char *reply,
 
294
                      gpointer user_data)
273
295
{
274
 
        if (response)
275
 
                nm_info ("Associated with network: %s", response);
276
 
        else
 
296
        switch (reply_index) {
 
297
        case 0:
 
298
                nm_info ("Associated with network: %s", reply);
 
299
                break;
 
300
        default:
277
301
                nm_warning ("Couldn't read active network name");
 
302
                break;
 
303
        }
278
304
 
279
305
        set_apn (NM_GSM_DEVICE (device));
280
306
}
282
308
static void
283
309
automatic_registration_get_network (NMGsmDevice *device)
284
310
{
285
 
        const char terminators[] = { '\r', '\n', '\0' };
 
311
        const char *responses[] = { "+COPS: ", NULL };
 
312
        const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
286
313
 
287
 
        modem_get_reply (device, "AT+COPS?", 10, terminators, get_network_done);
 
314
        modem_wait_for_reply (device, "AT+COPS?", 10, responses, terminators, get_network_response, NULL);
288
315
}
289
316
 
290
317
static gboolean
295
322
}
296
323
 
297
324
static void
 
325
schedule_automatic_registration_again (NMGsmDevice *self)
 
326
{
 
327
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self);
 
328
 
 
329
        if (priv->pending_id)
 
330
                g_source_remove (priv->pending_id);
 
331
 
 
332
        priv->pending_id = g_idle_add (automatic_registration_again, self);
 
333
}
 
334
 
 
335
static void
298
336
automatic_registration_response (NMSerialDevice *device,
299
 
                                                   int reply_index,
300
 
                                                   gpointer user_data)
 
337
                                 int reply_index,
 
338
                                 const char *reply,
 
339
                                 gpointer user_data)
301
340
{
 
341
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
 
342
 
302
343
        switch (reply_index) {
303
344
        case 0:
304
 
                nm_warning ("Automatic registration failed: not registered and not searching.");
305
 
                nm_device_state_changed (NM_DEVICE (device),
306
 
                                         NM_DEVICE_STATE_FAILED,
307
 
                                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING);
 
345
                /* Try autoregistration a few times here because the card is actually
 
346
                 * responding to the query and thus we aren't waiting as long for
 
347
                 * each CREG request.  Some cards (ex. Option iCON 225) return OK
 
348
                 * immediately from CFUN, but take a bit to start searching for a network.
 
349
                 */
 
350
                if (priv->reg_tries++ < 15) {
 
351
                        /* Can happen a few times while the modem is powering up */
 
352
                        schedule_automatic_registration_again (NM_GSM_DEVICE (device));
 
353
                } else {
 
354
                        priv->reg_tries = 0;
 
355
                        nm_warning ("Automatic registration failed: not registered and not searching.");
 
356
                        nm_device_state_changed (NM_DEVICE (device),
 
357
                                                 NM_DEVICE_STATE_FAILED,
 
358
                                                 NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING);
 
359
                }
308
360
                break;
309
361
        case 1:
310
362
                nm_info ("Registered on Home network");
311
363
                automatic_registration_get_network (NM_GSM_DEVICE (device));
312
364
                break;
313
365
        case 2:
314
 
                NM_GSM_DEVICE_GET_PRIVATE (device)->pending_id = g_timeout_add (1000, automatic_registration_again, device);
 
366
                nm_info ("Searching for a network...");
 
367
                schedule_automatic_registration_again (NM_GSM_DEVICE (device));
315
368
                break;
316
369
        case 3:
317
370
                nm_warning ("Automatic registration failed: registration denied.");
324
377
                automatic_registration_get_network (NM_GSM_DEVICE (device));
325
378
                break;
326
379
        case -1:
 
380
                /* Some cards (ex. Sierra AC860) don't immediately respond to commands
 
381
                 * after they are powered up with CFUN=1, but take a few seconds to come
 
382
                 * back to life.  So try registration a few times.
 
383
                 */
327
384
                nm_warning ("Automatic registration timed out");
328
 
                nm_device_state_changed (NM_DEVICE (device),
329
 
                                         NM_DEVICE_STATE_FAILED,
330
 
                                         NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 
385
                if (priv->reg_tries++ < 6) {
 
386
                        schedule_automatic_registration_again (NM_GSM_DEVICE (device));
 
387
                } else {
 
388
                        priv->reg_tries = 0;
 
389
                        nm_device_state_changed (NM_DEVICE (device),
 
390
                                                 NM_DEVICE_STATE_FAILED,
 
391
                                                 NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT);
 
392
                }
331
393
                break;
332
394
        default:
333
395
                nm_warning ("Automatic registration failed");
341
403
static void
342
404
automatic_registration (NMGsmDevice *device)
343
405
{
344
 
        char *responses[] = { "+CREG: 0,0", "+CREG: 0,1", "+CREG: 0,2", "+CREG: 0,3", "+CREG: 0,5", NULL };
345
 
        char *terminators[] = { "OK", "ERROR", "ERR", NULL };
 
406
        const char *responses[] = { "+CREG: 0,0", "+CREG: 0,1", "+CREG: 0,2", "+CREG: 0,3", "+CREG: 0,5", NULL };
 
407
        const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
346
408
 
347
 
        modem_wait_for_reply (device, "AT+CREG?", 60, responses, terminators, automatic_registration_response, NULL);
 
409
        modem_wait_for_reply (device, "AT+CREG?", 15, responses, terminators, automatic_registration_response, NULL);
348
410
}
349
411
 
350
412
static void
351
413
do_register (NMGsmDevice *device)
352
414
{
 
415
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
353
416
        NMSettingGsm *setting;
354
417
 
355
418
        setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
356
419
 
 
420
        priv->reg_tries = 0;
357
421
        if (setting->network_id)
358
422
                manual_registration (device);
359
423
        else
361
425
}
362
426
 
363
427
static void
 
428
power_up_response (NMSerialDevice *device,
 
429
                   int reply_index,
 
430
                   const char *reply,
 
431
                   gpointer user_data)
 
432
{
 
433
        /* Ignore errors */
 
434
        do_register (NM_GSM_DEVICE (device));
 
435
}
 
436
 
 
437
static void
 
438
power_up (NMGsmDevice *device)
 
439
{
 
440
        const char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
441
 
 
442
        nm_info ("(%s): powering up...", nm_device_get_iface (NM_DEVICE (device)));             
 
443
        modem_wait_for_reply (device, "AT+CFUN=1", 10, responses, responses, power_up_response, NULL);
 
444
}
 
445
 
 
446
static void
364
447
init_full_done (NMSerialDevice *device,
365
 
                         int reply_index,
366
 
                         gpointer user_data)
 
448
                int reply_index,
 
449
                const char *reply,
 
450
                gpointer user_data)
367
451
{
368
452
        switch (reply_index) {
369
453
        case 0:
370
 
                do_register (NM_GSM_DEVICE (device));
 
454
                power_up (NM_GSM_DEVICE (device));
371
455
                break;
372
456
        case -1:
373
457
                nm_warning ("Modem second stage initialization timed out");
387
471
static void
388
472
init_modem_full (NMGsmDevice *device)
389
473
{
390
 
        char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
474
        const char *responses[] = { "OK", "ERROR", "ERR", NULL };
391
475
 
392
476
        /* Send E0 too because some devices turn echo back on after CPIN which
393
477
         * just breaks stuff since echo-ed commands are interpreted as replies.
394
478
         * rh #456770
395
479
         */
396
 
        modem_wait_for_reply (device, "ATZ E0", 10, responses, responses, init_full_done, NULL);
 
480
        modem_wait_for_reply (device, "ATZ E0 V1 X4 &C1 +FCLASS=0", 10, responses, responses, init_full_done, NULL);
397
481
}
398
482
 
399
483
static void
400
484
enter_pin_done (NMSerialDevice *device,
401
 
                         int reply_index,
402
 
                         gpointer user_data)
 
485
                int reply_index,
 
486
                const char *reply,
 
487
                gpointer user_data)
403
488
{
404
489
        NMSettingGsm *setting;
405
490
 
464
549
                secret_name = NM_SETTING_GSM_PUK;
465
550
                break;
466
551
        default:
467
 
                do_register (device);
 
552
                power_up (device);
468
553
                return;
469
554
        }
470
555
 
471
556
        if (secret) {
472
557
                char *command;
473
 
                char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
558
                const char *responses[] = { "OK", "ERROR", "ERR", NULL };
474
559
 
475
560
                command = g_strdup_printf ("AT+CPIN=\"%s\"", secret);
476
561
                modem_wait_for_reply (device, command, 3, responses, responses, enter_pin_done, NULL);
491
576
 
492
577
static void
493
578
check_pin_done (NMSerialDevice *device,
494
 
                         int reply_index,
495
 
                         gpointer user_data)
 
579
                int reply_index,
 
580
                const char *reply,
 
581
                gpointer user_data)
496
582
{
497
583
        switch (reply_index) {
498
584
        case 0:
499
 
                do_register (NM_GSM_DEVICE (device));
 
585
                power_up (NM_GSM_DEVICE (device));
500
586
                break;
501
587
        case 1:
502
588
                NM_GSM_DEVICE_GET_PRIVATE (device)->need_secret = NM_GSM_SECRET_PIN;
524
610
static void
525
611
check_pin (NMGsmDevice *self)
526
612
{
527
 
        char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
528
 
        char *terminators[] = { "OK", "ERROR", "ERR", NULL };
 
613
        const char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
 
614
        const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
529
615
 
530
616
        modem_wait_for_reply (self, "AT+CPIN?", 3, responses, terminators, check_pin_done, NULL);
531
617
}
532
618
 
533
619
static void
534
620
init_done (NMSerialDevice *device,
535
 
                 int reply_index,
536
 
                 gpointer user_data)
 
621
           int reply_index,
 
622
           const char *reply,
 
623
           gpointer user_data)
537
624
{
538
625
        switch (reply_index) {
539
626
        case 0:
557
644
static void
558
645
init_modem (NMSerialDevice *device, gpointer user_data)
559
646
{
560
 
        char *responses[] = { "OK", "ERROR", "ERR", NULL };
 
647
        const char *responses[] = { "OK", "ERROR", "ERR", NULL };
561
648
 
562
 
        modem_wait_for_reply (NM_GSM_DEVICE (device), "AT E0", 10, responses, responses, init_done, NULL);
 
649
        modem_wait_for_reply (NM_GSM_DEVICE (device), "ATZ E0 V1 X4 &C1 +FCLASS=0", 10, responses, responses, init_done, NULL);
563
650
}
564
651
 
565
652
static NMActStageReturn
680
767
{
681
768
        NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
682
769
 
 
770
        priv->reg_tries = 0;
 
771
 
683
772
        if (priv->pending_id) {
684
773
                g_source_remove (priv->pending_id);
685
774
                priv->pending_id = 0;
686
775
        }
687
776
 
688
 
        NM_DEVICE_CLASS (nm_gsm_device_parent_class)->deactivate_quickly (device);
 
777
        if (NM_DEVICE_CLASS (nm_gsm_device_parent_class)->deactivate_quickly)
 
778
                NM_DEVICE_CLASS (nm_gsm_device_parent_class)->deactivate_quickly (device);
689
779
}
690
780
 
691
781
/*****************************************************************************/
793
883
                priv->state_to_disconnected_id = 0;
794
884
        }
795
885
 
796
 
        /* If transitioning to UNAVAILBLE and we have a carrier, transition to
797
 
         * DISCONNECTED because the device is ready to use.  Otherwise the carrier-on
798
 
         * handler will handle the transition to DISCONNECTED when the carrier is detected.
799
 
         */
 
886
        /* Transition to DISCONNECTED from an idle handler */
800
887
        if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
801
888
                priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self);
802
889