Merge ~alfonsosanchezbeato/snappy-hwe-snaps/+git/modem-manager:workaround-serial-pls62 into ~snappy-hwe-team/snappy-hwe-snaps/+git/modem-manager:modem-manager/1.8.0

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Konrad Zapałowicz
Approved revision: ec7f5f82fe095bd821ad353282851fbc6022df03
Merged at revision: cc696d7f9511fb1bf74213c1ae6652db0aa5f3f3
Proposed branch: ~alfonsosanchezbeato/snappy-hwe-snaps/+git/modem-manager:workaround-serial-pls62
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/modem-manager:modem-manager/1.8.0
Diff against target: 290 lines (+274/-0)
1 file modified
plugins/cinterion/mm-broadband-bearer-pls62.c (+274/-0)
Reviewer Review Type Date Requested Status
Konrad Zapałowicz (community) Approve
System Enablement Bot continuous-integration Approve
Review via email: mp+369240@code.launchpad.net

Commit message

bearer: workaround serial not responding in PLS62-W

Do not try to deactivate the PDP context for the Gemalto PLS62-W modem,
let NM do the job for us. The reason is that due to a modem firmware
bug, if the timing between pppd and us deactivating is unfortunate, the
port ends up in a state in which it is unusable. Note also that this LTE
modem cannot really disconnect while attached, so the AT command always
returns an error anyway. Fixes LP: #1829293.

Description of the change

bearer: workaround serial not responding in PLS62-W

Do not try to deactivate the PDP context for the Gemalto PLS62-W modem,
let NM do the job for us. The reason is that due to a modem firmware
bug, if the timing between pppd and us deactivating is unfortunate, the
port ends up in a state in which it is unusable. Note also that this LTE
modem cannot really disconnect while attached, so the AT command always
returns an error anyway. Fixes LP: #1829293.

To post a comment you must log in.
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Konrad Zapałowicz (kzapalowicz) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/plugins/cinterion/mm-broadband-bearer-pls62.c b/plugins/cinterion/mm-broadband-bearer-pls62.c
index 3d9b147..f2a7ae5 100644
--- a/plugins/cinterion/mm-broadband-bearer-pls62.c
+++ b/plugins/cinterion/mm-broadband-bearer-pls62.c
@@ -283,6 +283,278 @@ dial_3gpp (MMBroadbandBearer *self,
283}283}
284284
285/*****************************************************************************/285/*****************************************************************************/
286/* Detailed disconnect context */
287
288typedef struct {
289 MMBaseModem *modem;
290 MMPortSerialAt *primary;
291 MMPortSerialAt *secondary;
292 MMPort *data;
293
294 /* 3GPP-specific */
295 gchar *cgact_command;
296 gboolean cgact_sent;
297} DetailedDisconnectContext;
298
299static gboolean
300detailed_disconnect_finish (MMBroadbandBearer *self,
301 GAsyncResult *res,
302 GError **error)
303{
304 return g_task_propagate_boolean (G_TASK (res), error);
305}
306
307static void
308detailed_disconnect_context_free (DetailedDisconnectContext *ctx)
309{
310 if (ctx->cgact_command)
311 g_free (ctx->cgact_command);
312 g_object_unref (ctx->data);
313 g_object_unref (ctx->primary);
314 if (ctx->secondary)
315 g_object_unref (ctx->secondary);
316 g_object_unref (ctx->modem);
317 g_free (ctx);
318}
319
320static DetailedDisconnectContext *
321detailed_disconnect_context_new (MMBroadbandModem *modem,
322 MMPortSerialAt *primary,
323 MMPortSerialAt *secondary,
324 MMPort *data)
325{
326 DetailedDisconnectContext *ctx;
327
328 ctx = g_new0 (DetailedDisconnectContext, 1);
329 ctx->modem = MM_BASE_MODEM (g_object_ref (modem));
330 ctx->primary = g_object_ref (primary);
331 ctx->secondary = (secondary ? g_object_ref (secondary) : NULL);
332 ctx->data = g_object_ref (data);
333
334 return ctx;
335}
336
337/*****************************************************************************/
338/* 3GPP disconnect */
339
340static void
341cgact_data_ready (MMBaseModem *modem,
342 GAsyncResult *res,
343 GTask *task)
344{
345
346 GError *error = NULL;
347
348 /* Ignore errors for now */
349 mm_base_modem_at_command_full_finish (modem, res, &error);
350 if (error) {
351 mm_dbg ("PDP context deactivation failed (not fatal): %s", error->message);
352 g_error_free (error);
353 }
354
355 g_task_return_boolean (task, TRUE);
356 g_object_unref (task);
357}
358
359static void
360data_flash_3gpp_ready (MMPortSerial *data,
361 GAsyncResult *res,
362 GTask *task)
363{
364 MMBroadbandBearer *self;
365 DetailedDisconnectContext *ctx;
366 GError *error = NULL;
367
368 self = g_task_get_source_object (task);
369 ctx = g_task_get_task_data (task);
370
371 mm_port_serial_flash_finish (data, res, &error);
372
373 /* We kept the serial port open during connection, now we close that open
374 * count */
375 mm_port_serial_close (data);
376
377 /* Port is disconnected; update the state */
378 mm_port_set_connected (MM_PORT (data), FALSE);
379
380 if (error) {
381 /* Ignore "NO CARRIER" response when modem disconnects and any flash
382 * failures we might encounter. Other errors are hard errors.
383 */
384 if (!g_error_matches (error,
385 MM_CONNECTION_ERROR,
386 MM_CONNECTION_ERROR_NO_CARRIER) &&
387 !g_error_matches (error,
388 MM_SERIAL_ERROR,
389 MM_SERIAL_ERROR_FLASH_FAILED)) {
390 /* Fatal */
391 g_task_return_error (task, error);
392 g_object_unref (task);
393 return;
394 }
395
396 mm_dbg ("Port flashing failed (not fatal): %s", error->message);
397 g_error_free (error);
398 }
399
400 /* Run init port sequence in the data port */
401 mm_port_serial_at_run_init_sequence (MM_PORT_SERIAL_AT (data));
402
403 /* Don't bother doing the CGACT again if it was already done on the
404 * primary or secondary port */
405 if (ctx->cgact_sent) {
406 mm_dbg ("PDP disconnection already sent");
407 g_task_return_boolean (task, TRUE);
408 g_object_unref (task);
409 return;
410 }
411
412 /* Send another CGACT on the primary port (also the data port when the modem
413 * only has one serial port) if the previous one failed. Some modems, like
414 * the Huawei E173 (fw 11.126.15.00.445) stop responding on their primary
415 * port when the CGACT is sent on the separte data port.
416 */
417 if (MM_PORT_SERIAL (ctx->primary) == data)
418 mm_dbg ("Sending PDP context deactivation in primary/data port...");
419 else
420 mm_dbg ("Sending PDP context deactivation in primary port again...");
421
422 mm_base_modem_at_command_full (ctx->modem,
423 ctx->primary,
424 ctx->cgact_command,
425 10,
426 FALSE,
427 FALSE, /* raw */
428 NULL, /* cancellable */
429 (GAsyncReadyCallback)cgact_data_ready,
430 task);
431}
432
433static void
434data_reopen_3gpp_ready (MMPortSerial *data,
435 GAsyncResult *res,
436 GTask *task)
437{
438 DetailedDisconnectContext *ctx;
439 GError *error = NULL;
440
441 g_object_set (data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, TRUE, NULL);
442
443 if (!mm_port_serial_reopen_finish (data, res, &error)) {
444 /* Fatal */
445 g_task_return_error (task, error);
446 g_object_unref (task);
447 return;
448 }
449
450 ctx = g_task_get_task_data (task);
451
452 /* Just flash the data port */
453 mm_dbg ("Flashing data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
454 mm_port_serial_flash (MM_PORT_SERIAL (ctx->data),
455 1000,
456 TRUE,
457 (GAsyncReadyCallback)data_flash_3gpp_ready,
458 task);
459}
460
461static void
462data_reopen_3gpp (GTask *task)
463{
464 DetailedDisconnectContext *ctx;
465
466 ctx = g_task_get_task_data (task);
467
468 /* We don't want to run init sequence right away during the reopen, as we're
469 * going to flash afterwards. */
470 g_object_set (ctx->data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, FALSE, NULL);
471
472 /* Fully reopen the port before flashing */
473 mm_dbg ("Reopening data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
474 mm_port_serial_reopen (MM_PORT_SERIAL (ctx->data),
475 1000,
476 (GAsyncReadyCallback)data_reopen_3gpp_ready,
477 task);
478}
479
480static void
481cgact_ready (MMBaseModem *modem,
482 GAsyncResult *res,
483 GTask *task)
484{
485 DetailedDisconnectContext *ctx;
486 GError *error = NULL;
487
488 ctx = g_task_get_task_data (task);
489
490 mm_base_modem_at_command_full_finish (modem, res, &error);
491 if (!error)
492 ctx->cgact_sent = TRUE;
493 else {
494 mm_dbg ("PDP context deactivation failed (not fatal): %s", error->message);
495 g_error_free (error);
496 }
497
498 data_reopen_3gpp (task);
499}
500
501static void
502disconnect_3gpp (MMBroadbandBearer *self,
503 MMBroadbandModem *modem,
504 MMPortSerialAt *primary,
505 MMPortSerialAt *secondary,
506 MMPort *data,
507 guint cid,
508 GAsyncReadyCallback callback,
509 gpointer user_data)
510{
511 DetailedDisconnectContext *ctx;
512 GTask *task;
513
514 g_assert (primary != NULL);
515
516 /* Generic 3GPP plays only with SERIAL data ports */
517 g_assert (MM_IS_PORT_SERIAL (data));
518
519 ctx = detailed_disconnect_context_new (modem, primary, secondary, data);
520
521 /* If no specific CID was used, disable all PDP contexts */
522 ctx->cgact_command = (cid > 0 ?
523 g_strdup_printf ("+CGACT=0,%d", cid) :
524 g_strdup_printf ("+CGACT=0"));
525
526 task = g_task_new (self, NULL, callback, user_data);
527 g_task_set_task_data (task, ctx, (GDestroyNotify)detailed_disconnect_context_free);
528
529 /* If the primary port is NOT connected (doesn't have to be the data port),
530 * we'll send CGACT there */
531 if (!mm_port_get_connected (MM_PORT (ctx->primary))) {
532 mm_dbg ("Sending PDP context deactivation in primary port...");
533 mm_base_modem_at_command_full (ctx->modem,
534 ctx->primary,
535 ctx->cgact_command,
536 10,
537 FALSE,
538 FALSE, /* raw */
539 NULL, /* cancellable */
540 (GAsyncReadyCallback)cgact_ready,
541 task);
542 return;
543 }
544
545 /* If the primary port is busy with a data call, do not try to deactivate,
546 * let NM do the job for us. The reason is that due to a modem firmware bug
547 * in the PLS62-W, if the timing between pppd and us disconnecting is
548 * unfortunate, the port ends up in a state in which it is unusable. Note
549 * also that this LTE modem cannot really disconnect while attached, so
550 * trying to do so ends in error anyway.
551 */
552 mm_info ("PLS62-W modem, letting NM do the disconnect...");
553 /* Go on to reopen & flash the data/primary port */
554 data_reopen_3gpp (task);
555}
556
557/*****************************************************************************/
286/* Setup and Init Bearers */558/* Setup and Init Bearers */
287559
288MMBaseBearer *560MMBaseBearer *
@@ -336,4 +608,6 @@ mm_broadband_bearer_pls62_class_init (MMBroadbandBearerPls62Class *klass)
336608
337 broadband_bearer_class->dial_3gpp = dial_3gpp;609 broadband_bearer_class->dial_3gpp = dial_3gpp;
338 broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;610 broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
611 broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
612 broadband_bearer_class->disconnect_3gpp_finish = detailed_disconnect_finish;
339}613}

Subscribers

People subscribed via source and target branches