GCC Code Coverage Report


Directory: ./
File: panels/wwan/cc-wwan-device.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 618 0.0%
Functions: 0 64 0.0%
Branches: 0 685 0.0%

Line Branch Exec Source
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* cc-wwan-device.c
3 *
4 * Copyright 2019-2020 Purism SPC
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
18 *
19 * Author(s):
20 * Mohammed Sadiq <sadiq@sadiqpk.org>
21 *
22 * SPDX-License-Identifier: GPL-3.0-or-later
23 */
24
25 #undef G_LOG_DOMAIN
26 #define G_LOG_DOMAIN "cc-wwan-device"
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib/gi18n.h>
33 #include <polkit/polkit.h>
34 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
35 # include <NetworkManager.h>
36 # include <nma-mobile-providers.h>
37 #endif
38
39 #include "cc-wwan-errors-private.h"
40 #include "cc-wwan-device.h"
41
42 /**
43 * @short_description: Device Object
44 * @include: "cc-wwan-device.h"
45 */
46
47 struct _CcWwanDevice
48 {
49 GObject parent_instance;
50
51 MMObject *mm_object;
52 MMModem *modem;
53 MMSim *sim;
54 MMModem3gpp *modem_3gpp;
55
56 const char *operator_code; /* MCCMNC */
57 GError *error;
58
59 /* Building with NetworkManager is optional,
60 * so #NMclient type can’t be used here.
61 */
62 GObject *nm_client; /* An #NMClient */
63 CcWwanData *wwan_data;
64
65 gulong modem_3gpp_id;
66 gulong modem_3gpp_locks_id;
67
68 /* Enabled locks like PIN, PIN2, PUK, etc. */
69 MMModem3gppFacility locks;
70
71 CcWwanState registration_state;
72 gboolean network_is_manual;
73 };
74
75 G_DEFINE_TYPE (CcWwanDevice, cc_wwan_device, G_TYPE_OBJECT)
76
77
78 enum {
79 PROP_0,
80 PROP_OPERATOR_NAME,
81 PROP_ENABLED_LOCKS,
82 PROP_ERROR,
83 PROP_HAS_DATA,
84 PROP_NETWORK_MODE,
85 PROP_REGISTRATION_STATE,
86 PROP_SIGNAL,
87 PROP_UNLOCK_REQUIRED,
88 N_PROPS
89 };
90
91 static GParamSpec *properties[N_PROPS];
92
93 static void
94 cc_wwan_device_state_changed_cb (CcWwanDevice *self)
95 {
96 MMModem3gppRegistrationState state;
97
98 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OPERATOR_NAME]);
99
100 state = mm_modem_3gpp_get_registration_state (self->modem_3gpp);
101
102 switch (state)
103 {
104 case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN:
105 self->registration_state = CC_WWAN_REGISTRATION_STATE_UNKNOWN;
106 break;
107
108 case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED:
109 self->registration_state = CC_WWAN_REGISTRATION_STATE_DENIED;
110 break;
111
112 case MM_MODEM_3GPP_REGISTRATION_STATE_IDLE:
113 self->registration_state = CC_WWAN_REGISTRATION_STATE_IDLE;
114 break;
115
116 case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING:
117 self->registration_state = CC_WWAN_REGISTRATION_STATE_SEARCHING;
118 break;
119
120 case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
121 self->registration_state = CC_WWAN_REGISTRATION_STATE_ROAMING;
122 break;
123
124 default:
125 self->registration_state = CC_WWAN_REGISTRATION_STATE_REGISTERED;
126 break;
127 }
128
129 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_REGISTRATION_STATE]);
130 }
131
132 static void
133 cc_wwan_device_locks_changed_cb (CcWwanDevice *self)
134 {
135 self->locks = mm_modem_3gpp_get_enabled_facility_locks (self->modem_3gpp);
136
137 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ENABLED_LOCKS]);
138 }
139
140 static void
141 cc_wwan_device_3gpp_changed_cb (CcWwanDevice *self)
142 {
143 gulong handler_id = 0;
144
145 if (self->modem_3gpp_id)
146 g_signal_handler_disconnect (self->modem_3gpp, self->modem_3gpp_id);
147 self->modem_3gpp_id = 0;
148
149 if (self->modem_3gpp_locks_id)
150 g_signal_handler_disconnect (self->modem_3gpp, self->modem_3gpp_locks_id);
151 self->modem_3gpp_locks_id = 0;
152
153 g_clear_object (&self->modem_3gpp);
154 self->modem_3gpp = mm_object_get_modem_3gpp (self->mm_object);
155
156 if (self->modem_3gpp)
157 {
158 handler_id = g_signal_connect_object (self->modem_3gpp, "notify::registration-state",
159 G_CALLBACK (cc_wwan_device_state_changed_cb),
160 self, G_CONNECT_SWAPPED);
161 self->modem_3gpp_id = handler_id;
162
163 handler_id = g_signal_connect_object (self->modem_3gpp, "notify::enabled-facility-locks",
164 G_CALLBACK (cc_wwan_device_locks_changed_cb),
165 self, G_CONNECT_SWAPPED);
166 self->modem_3gpp_locks_id = handler_id;
167 cc_wwan_device_locks_changed_cb (self);
168 cc_wwan_device_state_changed_cb (self);
169 }
170 }
171
172 static void
173 cc_wwan_device_signal_quality_changed_cb (CcWwanDevice *self)
174 {
175 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIGNAL]);
176 }
177
178 static void
179 cc_wwan_device_mode_changed_cb (CcWwanDevice *self)
180 {
181 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_NETWORK_MODE]);
182 }
183
184 static void
185 wwan_device_emit_data_changed (CcWwanDevice *self)
186 {
187 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_DATA]);
188 }
189
190 static void
191 cc_wwan_device_unlock_required_cb (CcWwanDevice *self)
192 {
193 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UNLOCK_REQUIRED]);
194 }
195
196 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
197 static void
198 cc_wwan_device_nm_changed_cb (CcWwanDevice *self,
199 GParamSpec *pspec,
200 NMClient *client)
201 {
202 gboolean nm_is_running;
203
204 nm_is_running = nm_client_get_nm_running (client);
205
206 if (!nm_is_running && self->wwan_data != NULL)
207 {
208 g_clear_object (&self->wwan_data);
209 wwan_device_emit_data_changed (self);
210 }
211 }
212
213 static void
214 cc_wwan_device_nm_device_added_cb (CcWwanDevice *self,
215 NMDevice *nm_device)
216 {
217 if (!NM_IS_DEVICE_MODEM (nm_device))
218 return;
219
220 if(!self->sim || !cc_wwan_device_is_nm_device (self, G_OBJECT (nm_device)))
221 return;
222
223 self->wwan_data = cc_wwan_data_new (self->mm_object,
224 NM_CLIENT (self->nm_client));
225
226 if (self->wwan_data)
227 {
228 g_signal_connect_object (self->wwan_data, "notify::enabled",
229 G_CALLBACK (wwan_device_emit_data_changed),
230 self, G_CONNECT_SWAPPED);
231 wwan_device_emit_data_changed (self);
232 }
233 }
234 #endif
235
236 static void
237 cc_wwan_device_get_property (GObject *object,
238 guint prop_id,
239 GValue *value,
240 GParamSpec *pspec)
241 {
242 CcWwanDevice *self = (CcWwanDevice *)object;
243 MMModemMode allowed, preferred;
244
245 switch (prop_id)
246 {
247 case PROP_OPERATOR_NAME:
248 g_value_set_string (value, cc_wwan_device_get_operator_name (self));
249 break;
250
251 case PROP_ERROR:
252 g_value_set_boolean (value, self->error != NULL);
253 break;
254
255 case PROP_HAS_DATA:
256 g_value_set_boolean (value, self->wwan_data != NULL);
257 break;
258
259 case PROP_ENABLED_LOCKS:
260 g_value_set_int (value, self->locks);
261 break;
262
263 case PROP_NETWORK_MODE:
264 if (cc_wwan_device_get_current_mode (self, &allowed, &preferred))
265 g_value_take_string (value, cc_wwan_device_get_string_from_mode (self, allowed, preferred));
266 break;
267
268 case PROP_REGISTRATION_STATE:
269 g_value_set_int (value, self->registration_state);
270 break;
271
272 case PROP_UNLOCK_REQUIRED:
273 g_value_set_int (value, cc_wwan_device_get_lock (self));
274 break;
275
276 default:
277 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
278 }
279 }
280
281 static void
282 cc_wwan_device_dispose (GObject *object)
283 {
284 CcWwanDevice *self = (CcWwanDevice *)object;
285
286 g_clear_error (&self->error);
287 g_clear_object (&self->modem);
288 g_clear_object (&self->mm_object);
289 g_clear_object (&self->sim);
290 g_clear_object (&self->modem_3gpp);
291
292 g_clear_object (&self->nm_client);
293 g_clear_object (&self->wwan_data);
294
295 G_OBJECT_CLASS (cc_wwan_device_parent_class)->dispose (object);
296 }
297
298 static void
299 cc_wwan_device_class_init (CcWwanDeviceClass *klass)
300 {
301 GObjectClass *object_class = G_OBJECT_CLASS (klass);
302
303 object_class->get_property = cc_wwan_device_get_property;
304 object_class->dispose = cc_wwan_device_dispose;
305
306 properties[PROP_OPERATOR_NAME] =
307 g_param_spec_string ("operator-name",
308 "Operator Name",
309 "Operator Name the device is connected to",
310 NULL,
311 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
312
313 properties[PROP_ENABLED_LOCKS] =
314 g_param_spec_int ("enabled-locks",
315 "Enabled Locks",
316 "Locks Enabled in Modem",
317 MM_MODEM_3GPP_FACILITY_NONE,
318 MM_MODEM_3GPP_FACILITY_CORP_PERS,
319 MM_MODEM_3GPP_FACILITY_NONE,
320 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
321
322 properties[PROP_ERROR] =
323 g_param_spec_boolean ("error",
324 "Error",
325 "Set if some Error occurs",
326 FALSE,
327 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
328
329 properties[PROP_HAS_DATA] =
330 g_param_spec_boolean ("has-data",
331 "has-data",
332 "Data for the device",
333 FALSE,
334 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
335
336 properties[PROP_NETWORK_MODE] =
337 g_param_spec_string ("network-mode",
338 "Network Mode",
339 "A String representing preferred network mode",
340 NULL,
341 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
342
343 properties[PROP_REGISTRATION_STATE] =
344 g_param_spec_int ("registration-state",
345 "Registration State",
346 "The current network registration state",
347 CC_WWAN_REGISTRATION_STATE_UNKNOWN,
348 CC_WWAN_REGISTRATION_STATE_DENIED,
349 CC_WWAN_REGISTRATION_STATE_UNKNOWN,
350 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
351
352 properties[PROP_UNLOCK_REQUIRED] =
353 g_param_spec_int ("unlock-required",
354 "Unlock Required",
355 "The Modem lock status changed",
356 MM_MODEM_LOCK_UNKNOWN,
357 MM_MODEM_LOCK_PH_NETSUB_PUK,
358 MM_MODEM_LOCK_UNKNOWN,
359 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
360
361 properties[PROP_SIGNAL] =
362 g_param_spec_int ("signal",
363 "Signal",
364 "Get Device Signal",
365 0, 100, 0,
366 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
367
368 g_object_class_install_properties (object_class, N_PROPS, properties);
369 }
370
371 static void
372 cc_wwan_device_init (CcWwanDevice *self)
373 {
374 }
375
376 /**
377 * cc_wwan_device_new:
378 * @mm_object: (transfer full): An #MMObject
379 *
380 * Create a new device representing the given
381 * @mm_object.
382 *
383 * Returns: A #CcWwanDevice
384 */
385 CcWwanDevice *
386 cc_wwan_device_new (MMObject *mm_object,
387 GObject *nm_client)
388 {
389 CcWwanDevice *self;
390
391 g_return_val_if_fail (MM_IS_OBJECT (mm_object), NULL);
392 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
393 g_return_val_if_fail (NM_IS_CLIENT (nm_client), NULL);
394 #else
395 g_return_val_if_fail (!nm_client, NULL);
396 #endif
397
398 self = g_object_new (CC_TYPE_WWAN_DEVICE, NULL);
399
400 self->mm_object = g_object_ref (mm_object);
401 self->modem = mm_object_get_modem (mm_object);
402 self->sim = mm_modem_get_sim_sync (self->modem, NULL, NULL);
403 g_set_object (&self->nm_client, nm_client);
404 if (self->sim)
405 {
406 self->operator_code = mm_sim_get_operator_identifier (self->sim);
407 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
408 self->wwan_data = cc_wwan_data_new (mm_object,
409 NM_CLIENT (self->nm_client));
410 #endif
411 }
412
413 g_signal_connect_object (self->mm_object, "notify::unlock-required",
414 G_CALLBACK (cc_wwan_device_unlock_required_cb),
415 self, G_CONNECT_SWAPPED);
416 if (self->wwan_data)
417 g_signal_connect_object (self->wwan_data, "notify::enabled",
418 G_CALLBACK (wwan_device_emit_data_changed),
419 self, G_CONNECT_SWAPPED);
420
421 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
422 g_signal_connect_object (self->nm_client, "notify::nm-running" ,
423 G_CALLBACK (cc_wwan_device_nm_changed_cb), self,
424 G_CONNECT_SWAPPED);
425
426 g_signal_connect_object (self->nm_client, "device-added",
427 G_CALLBACK (cc_wwan_device_nm_device_added_cb),
428 self, G_CONNECT_SWAPPED);
429 #endif
430
431 g_signal_connect_object (self->mm_object, "notify::modem3gpp",
432 G_CALLBACK (cc_wwan_device_3gpp_changed_cb),
433 self, G_CONNECT_SWAPPED);
434 g_signal_connect_object (self->modem, "notify::signal-quality",
435 G_CALLBACK (cc_wwan_device_signal_quality_changed_cb),
436 self, G_CONNECT_SWAPPED);
437
438 cc_wwan_device_3gpp_changed_cb (self);
439 g_signal_connect_object (self->modem, "notify::current-modes",
440 G_CALLBACK (cc_wwan_device_mode_changed_cb),
441 self, G_CONNECT_SWAPPED);
442
443 return self;
444 }
445
446 gboolean
447 cc_wwan_device_has_sim (CcWwanDevice *self)
448 {
449 MMModemStateFailedReason state_reason;
450
451 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
452
453 state_reason = mm_modem_get_state_failed_reason (self->modem);
454
455 if (state_reason == MM_MODEM_STATE_FAILED_REASON_SIM_MISSING)
456 return FALSE;
457
458 return TRUE;
459 }
460
461 /**
462 * cc_wwan_device_get_lock:
463 * @self: a #CcWwanDevice
464 *
465 * Get the active device lock that is required to
466 * be unlocked for accessing device features.
467 *
468 * Returns: %TRUE if PIN enabled, %FALSE otherwise.
469 */
470 MMModemLock
471 cc_wwan_device_get_lock (CcWwanDevice *self)
472 {
473 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), MM_MODEM_LOCK_UNKNOWN);
474
475 return mm_modem_get_unlock_required (self->modem);
476 }
477
478
479 /**
480 * cc_wwan_device_get_sim_lock:
481 * @self: a #CcWwanDevice
482 *
483 * Get if SIM lock with PIN is enabled. SIM PIN
484 * enabled doesn’t mean that SIM is locked.
485 * See cc_wwan_device_get_lock().
486 *
487 * Returns: %TRUE if PIN enabled, %FALSE otherwise.
488 */
489 gboolean
490 cc_wwan_device_get_sim_lock (CcWwanDevice *self)
491 {
492 gboolean sim_lock;
493
494 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
495
496 sim_lock = self->locks & MM_MODEM_3GPP_FACILITY_SIM;
497
498 return !!sim_lock;
499 }
500
501 guint
502 cc_wwan_device_get_unlock_retries (CcWwanDevice *self,
503 MMModemLock lock)
504 {
505 MMUnlockRetries *retries;
506
507 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), 0);
508
509 retries = mm_modem_get_unlock_retries (self->modem);
510
511 return mm_unlock_retries_get (retries, lock);
512 }
513
514 static void
515 cc_wwan_device_pin_sent_cb (GObject *object,
516 GAsyncResult *result,
517 gpointer user_data)
518 {
519 CcWwanDevice *self;
520 MMSim *sim = (MMSim *)object;
521 g_autoptr(GTask) task = user_data;
522 g_autoptr(GError) error = NULL;
523
524 if (!mm_sim_send_pin_finish (sim, result, &error))
525 {
526 self = g_task_get_source_object (G_TASK (task));
527
528 g_clear_error (&self->error);
529 self->error = g_error_copy (error);
530 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
531
532 g_task_return_error (task, g_steal_pointer (&error));
533 }
534 else
535 {
536 g_task_return_boolean (task, TRUE);
537 }
538 }
539
540 void
541 cc_wwan_device_send_pin (CcWwanDevice *self,
542 const gchar *pin,
543 GCancellable *cancellable,
544 GAsyncReadyCallback callback,
545 gpointer user_data)
546 {
547 g_autoptr(GTask) task = NULL;
548
549 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
550 g_return_if_fail (MM_IS_SIM (self->sim));
551 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
552 g_return_if_fail (pin && *pin);
553
554 task = g_task_new (self, cancellable, callback, user_data);
555
556 mm_sim_send_pin (self->sim, pin, cancellable,
557 cc_wwan_device_pin_sent_cb,
558 g_steal_pointer (&task));
559 }
560
561 gboolean
562 cc_wwan_device_send_pin_finish (CcWwanDevice *self,
563 GAsyncResult *result,
564 GError **error)
565 {
566 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
567 g_return_val_if_fail (G_IS_TASK (result), FALSE);
568
569 return g_task_propagate_boolean (G_TASK (result), error);
570 }
571
572 static void
573 cc_wwan_device_puk_sent_cb (GObject *object,
574 GAsyncResult *result,
575 gpointer user_data)
576 {
577 CcWwanDevice *self;
578 MMSim *sim = (MMSim *)object;
579 g_autoptr(GTask) task = user_data;
580 g_autoptr(GError) error = NULL;
581
582 if (!mm_sim_send_puk_finish (sim, result, &error))
583 {
584 self = g_task_get_source_object (G_TASK (task));
585
586 g_clear_error (&self->error);
587 self->error = g_error_copy (error);
588 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
589
590 g_task_return_error (task, g_steal_pointer (&error));
591 }
592 else
593 {
594 g_task_return_boolean (task, TRUE);
595 }
596 }
597
598 void
599 cc_wwan_device_send_puk (CcWwanDevice *self,
600 const gchar *puk,
601 const gchar *pin,
602 GCancellable *cancellable,
603 GAsyncReadyCallback callback,
604 gpointer user_data)
605 {
606 g_autoptr(GTask) task = NULL;
607
608 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
609 g_return_if_fail (MM_IS_SIM (self->sim));
610 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
611 g_return_if_fail (puk && *puk);
612 g_return_if_fail (pin && *pin);
613
614 task = g_task_new (self, cancellable, callback, user_data);
615
616 mm_sim_send_puk (self->sim, puk, pin, cancellable,
617 cc_wwan_device_puk_sent_cb,
618 g_steal_pointer (&task));
619 }
620
621 gboolean
622 cc_wwan_device_send_puk_finish (CcWwanDevice *self,
623 GAsyncResult *result,
624 GError **error)
625 {
626 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
627 g_return_val_if_fail (G_IS_TASK (result), FALSE);
628
629 return g_task_propagate_boolean (G_TASK (result), error);
630 }
631
632 static void
633 cc_wwan_device_enable_pin_cb (GObject *object,
634 GAsyncResult *result,
635 gpointer user_data)
636 {
637 CcWwanDevice *self;
638 MMSim *sim = (MMSim *)object;
639 g_autoptr(GTask) task = user_data;
640 g_autoptr(GError) error = NULL;
641
642 if (!mm_sim_enable_pin_finish (sim, result, &error))
643 {
644 self = g_task_get_source_object (G_TASK (task));
645
646 g_clear_error (&self->error);
647 self->error = g_error_copy (error);
648 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
649
650 g_task_return_error (task, g_steal_pointer (&error));
651 }
652 else
653 {
654 g_task_return_boolean (task, TRUE);
655 }
656 }
657
658 void
659 cc_wwan_device_enable_pin (CcWwanDevice *self,
660 const gchar *pin,
661 GCancellable *cancellable,
662 GAsyncReadyCallback callback,
663 gpointer user_data)
664 {
665 g_autoptr(GTask) task = NULL;
666
667 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
668 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
669 g_return_if_fail (pin && *pin);
670
671 task = g_task_new (self, cancellable, callback, user_data);
672
673 mm_sim_enable_pin (self->sim, pin, cancellable,
674 cc_wwan_device_enable_pin_cb,
675 g_steal_pointer (&task));
676 }
677
678 gboolean
679 cc_wwan_device_enable_pin_finish (CcWwanDevice *self,
680 GAsyncResult *result,
681 GError **error)
682 {
683 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
684 g_return_val_if_fail (G_IS_TASK (result), FALSE);
685
686 return g_task_propagate_boolean (G_TASK (result), error);
687 }
688
689 static void
690 cc_wwan_device_disable_pin_cb (GObject *object,
691 GAsyncResult *result,
692 gpointer user_data)
693 {
694 CcWwanDevice *self;
695 MMSim *sim = (MMSim *)object;
696 g_autoptr(GTask) task = user_data;
697 g_autoptr(GError) error = NULL;
698
699 if (!mm_sim_disable_pin_finish (sim, result, &error))
700 {
701 self = g_task_get_source_object (G_TASK (task));
702
703 g_clear_error (&self->error);
704 self->error = g_error_copy (error);
705 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
706
707 g_task_return_error (task, g_steal_pointer (&error));
708 }
709 else
710 {
711 g_task_return_boolean (task, TRUE);
712 }
713 }
714
715 void
716 cc_wwan_device_disable_pin (CcWwanDevice *self,
717 const gchar *pin,
718 GCancellable *cancellable,
719 GAsyncReadyCallback callback,
720 gpointer user_data)
721 {
722 g_autoptr(GTask) task = NULL;
723
724 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
725 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
726 g_return_if_fail (pin && *pin);
727
728 task = g_task_new (self, cancellable, callback, user_data);
729
730 mm_sim_disable_pin (self->sim, pin, cancellable,
731 cc_wwan_device_disable_pin_cb,
732 g_steal_pointer (&task));
733 }
734
735 gboolean
736 cc_wwan_device_disable_pin_finish (CcWwanDevice *self,
737 GAsyncResult *result,
738 GError **error)
739 {
740 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
741 g_return_val_if_fail (G_IS_TASK (result), FALSE);
742
743 return g_task_propagate_boolean (G_TASK (result), error);
744 }
745
746 static void
747 cc_wwan_device_change_pin_cb (GObject *object,
748 GAsyncResult *result,
749 gpointer user_data)
750 {
751 CcWwanDevice *self;
752 MMSim *sim = (MMSim *)object;
753 g_autoptr(GTask) task = user_data;
754 g_autoptr(GError) error = NULL;
755
756 if (!mm_sim_change_pin_finish (sim, result, &error))
757 {
758 self = g_task_get_source_object (G_TASK (task));
759
760 g_clear_error (&self->error);
761 self->error = g_error_copy (error);
762 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
763
764 g_task_return_error (task, g_steal_pointer (&error));
765 }
766 else
767 {
768 g_task_return_boolean (task, TRUE);
769 }
770 }
771
772 void
773 cc_wwan_device_change_pin (CcWwanDevice *self,
774 const gchar *old_pin,
775 const gchar *new_pin,
776 GCancellable *cancellable,
777 GAsyncReadyCallback callback,
778 gpointer user_data)
779 {
780 g_autoptr(GTask) task = NULL;
781
782 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
783 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
784 g_return_if_fail (old_pin && *old_pin);
785 g_return_if_fail (new_pin && *new_pin);
786
787 task = g_task_new (self, cancellable, callback, user_data);
788
789 mm_sim_change_pin (self->sim, old_pin, new_pin, cancellable,
790 cc_wwan_device_change_pin_cb,
791 g_steal_pointer (&task));
792 }
793
794 gboolean
795 cc_wwan_device_change_pin_finish (CcWwanDevice *self,
796 GAsyncResult *result,
797 GError **error)
798 {
799 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
800 g_return_val_if_fail (G_IS_TASK (result), FALSE);
801
802 return g_task_propagate_boolean (G_TASK (result), error);
803 }
804
805 static void
806 cc_wwan_device_network_mode_set_cb (GObject *object,
807 GAsyncResult *result,
808 gpointer user_data)
809 {
810 CcWwanDevice *self;
811 MMModem *modem = (MMModem *)object;
812 g_autoptr(GTask) task = user_data;
813 g_autoptr(GError) error = NULL;
814
815 if (!mm_modem_set_current_modes_finish (modem, result, &error))
816 {
817 self = g_task_get_source_object (G_TASK (task));
818
819 g_clear_error (&self->error);
820 self->error = g_error_copy (error);
821 g_warning ("Error: %s", error->message);
822 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
823
824 g_task_return_error (task, g_steal_pointer (&error));
825 }
826 else
827 {
828 g_task_return_boolean (task, TRUE);
829 }
830 }
831
832 /**
833 * cc_wwan_device_set_network_mode:
834 * @self: a #CcWwanDevice
835 * @allowed: The allowed #MMModemModes
836 * @preferred: The preferred #MMModemMode
837 * @cancellable: (nullable): a #GCancellable or %NULL
838 * @callback: (nullable): a #GAsyncReadyCallback or %NULL
839 * @user_data: (nullable): closure data for @callback
840 *
841 * Asynchronously set preferred network mode.
842 *
843 * Call @cc_wwan_device_set_current_mode_finish()
844 * in @callback to get the result of operation.
845 */
846 void
847 cc_wwan_device_set_current_mode (CcWwanDevice *self,
848 MMModemMode allowed,
849 MMModemMode preferred,
850 GCancellable *cancellable,
851 GAsyncReadyCallback callback,
852 gpointer user_data)
853 {
854 g_autoptr(GTask) task = NULL;
855 GPermission *permission;
856 g_autoptr(GError) error = NULL;
857
858 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
859 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
860
861 task = g_task_new (self, cancellable, callback, user_data);
862 permission = polkit_permission_new_sync ("org.freedesktop.ModemManager1.Device.Control",
863 NULL, cancellable, &error);
864 if (permission)
865 g_task_set_task_data (task, permission, g_object_unref);
866
867 if (error)
868 g_warning ("error: %s", error->message);
869
870 if (error)
871 {
872 g_task_return_error (task, g_steal_pointer (&error));
873 }
874 else if (!g_permission_get_allowed (permission))
875 {
876 error = g_error_new (G_IO_ERROR,
877 G_IO_ERROR_PERMISSION_DENIED,
878 "Access Denied");
879 g_clear_error (&self->error);
880 self->error = g_error_copy (error);
881 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
882
883 g_task_return_error (task, g_steal_pointer (&error));
884 }
885 else
886 {
887 mm_modem_set_current_modes (self->modem, allowed, preferred,
888 cancellable, cc_wwan_device_network_mode_set_cb,
889 g_steal_pointer (&task));
890 }
891 }
892
893 /**
894 * cc_wwan_device_set_current_mode_finish:
895 * @self: a #CcWwanDevice
896 * @result: a #GAsyncResult
897 * @error: a location for #GError or %NULL
898 *
899 * Get the status whether setting network mode
900 * succeeded
901 *
902 * Returns: %TRUE if network mode was successfully set,
903 * %FALSE otherwise.
904 */
905 gboolean
906 cc_wwan_device_set_current_mode_finish (CcWwanDevice *self,
907 GAsyncResult *result,
908 GError **error)
909 {
910 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
911 g_return_val_if_fail (G_IS_TASK (result), FALSE);
912
913 return g_task_propagate_boolean (G_TASK (result), error);
914 }
915
916 gboolean
917 cc_wwan_device_get_current_mode (CcWwanDevice *self,
918 MMModemMode *allowed,
919 MMModemMode *preferred)
920 {
921 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
922
923 return mm_modem_get_current_modes (self->modem, allowed, preferred);
924 }
925
926 gboolean
927 cc_wwan_device_is_auto_network (CcWwanDevice *self)
928 {
929 /*
930 * XXX: ModemManager Doesn’t have a true API to check
931 * if registration is automatic or manual. So Let’s
932 * do some guess work.
933 */
934 if (self->registration_state == CC_WWAN_REGISTRATION_STATE_DENIED)
935 return FALSE;
936
937 return !self->network_is_manual;
938 }
939
940 CcWwanState
941 cc_wwan_device_get_network_state (CcWwanDevice *self)
942 {
943 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), 0);
944
945 return self->registration_state;
946 }
947
948 gboolean
949 cc_wwan_device_get_supported_modes (CcWwanDevice *self,
950 MMModemMode *allowed,
951 MMModemMode *preferred)
952 {
953 g_autofree MMModemModeCombination *modes = NULL;
954 guint n_modes, i;
955
956 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
957
958 if (!mm_modem_get_supported_modes (self->modem, &modes, &n_modes))
959 return FALSE;
960
961 if (allowed)
962 *allowed = 0;
963 if (preferred)
964 *preferred = 0;
965
966 for (i = 0; i < n_modes; i++)
967 {
968 if (allowed)
969 *allowed = *allowed | modes[i].allowed;
970 if (preferred)
971 *preferred = *preferred | modes[i].preferred;
972 }
973
974 return TRUE;
975 }
976
977 gchar *
978 cc_wwan_device_get_string_from_mode (CcWwanDevice *self,
979 MMModemMode allowed,
980 MMModemMode preferred)
981 {
982 GString *str;
983
984 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
985 g_return_val_if_fail (allowed != 0, NULL);
986
987 if (allowed == MM_MODEM_MODE_2G)
988 return g_strdup (_("2G Only"));
989
990 if (allowed == MM_MODEM_MODE_3G)
991 return g_strdup (_("3G Only"));
992
993 if (allowed == MM_MODEM_MODE_4G)
994 return g_strdup (_("4G Only"));
995
996 if (allowed == MM_MODEM_MODE_5G)
997 return g_strdup (_("5G Only"));
998
999 str = g_string_sized_new (10);
1000
1001 if (allowed & MM_MODEM_MODE_2G &&
1002 allowed & MM_MODEM_MODE_3G &&
1003 allowed & MM_MODEM_MODE_4G &&
1004 allowed & MM_MODEM_MODE_5G)
1005 {
1006 if (preferred & MM_MODEM_MODE_5G)
1007 g_string_append (str, _("2G, 3G, 4G, 5G (Preferred)"));
1008 else if (preferred & MM_MODEM_MODE_4G)
1009 g_string_append (str, _("2G, 3G, 4G (Preferred), 5G"));
1010 else if (preferred & MM_MODEM_MODE_3G)
1011 g_string_append (str, _("2G, 3G (Preferred), 4G, 5G"));
1012 else if (preferred & MM_MODEM_MODE_2G)
1013 g_string_append (str, _("2G (Preferred), 3G, 4G, 5G"));
1014 else
1015 g_string_append (str, _("2G, 3G, 4G, 5G"));
1016 }
1017 else if (allowed & MM_MODEM_MODE_2G &&
1018 allowed & MM_MODEM_MODE_3G &&
1019 allowed & MM_MODEM_MODE_4G)
1020 {
1021 if (preferred & MM_MODEM_MODE_4G)
1022 g_string_append (str, _("2G, 3G, 4G (Preferred)"));
1023 else if (preferred & MM_MODEM_MODE_3G)
1024 g_string_append (str, _("2G, 3G (Preferred), 4G"));
1025 else if (preferred & MM_MODEM_MODE_2G)
1026 g_string_append (str, _("2G (Preferred), 3G, 4G"));
1027 else
1028 g_string_append (str, _("2G, 3G, 4G"));
1029 }
1030 else if (allowed & MM_MODEM_MODE_3G &&
1031 allowed & MM_MODEM_MODE_4G &&
1032 allowed & MM_MODEM_MODE_5G)
1033 {
1034 if (preferred & MM_MODEM_MODE_5G)
1035 g_string_append (str, _("3G, 4G, 5G (Preferred)"));
1036 else if (preferred & MM_MODEM_MODE_4G)
1037 g_string_append (str, _("3G, 4G (Preferred), 5G"));
1038 else if (preferred & MM_MODEM_MODE_2G)
1039 g_string_append (str, _("3G (Preferred), 4G, 5G"));
1040 else
1041 g_string_append (str, _("3G, 4G, 5G"));
1042 }
1043 else if (allowed & MM_MODEM_MODE_2G &&
1044 allowed & MM_MODEM_MODE_4G &&
1045 allowed & MM_MODEM_MODE_5G)
1046 {
1047 if (preferred & MM_MODEM_MODE_5G)
1048 g_string_append (str, _("2G, 4G, 5G (Preferred)"));
1049 else if (preferred & MM_MODEM_MODE_4G)
1050 g_string_append (str, _("2G, 4G (Preferred), 5G"));
1051 else if (preferred & MM_MODEM_MODE_2G)
1052 g_string_append (str, _("2G (Preferred), 4G, 5G"));
1053 else
1054 g_string_append (str, _("2G, 4G, 5G"));
1055 }
1056 else if (allowed & MM_MODEM_MODE_2G &&
1057 allowed & MM_MODEM_MODE_3G &&
1058 allowed & MM_MODEM_MODE_5G)
1059 {
1060 if (preferred & MM_MODEM_MODE_5G)
1061 g_string_append (str, _("2G, 3G, 5G (Preferred)"));
1062 else if (preferred & MM_MODEM_MODE_3G)
1063 g_string_append (str, _("2G, 3G (Preferred), 5G"));
1064 else if (preferred & MM_MODEM_MODE_2G)
1065 g_string_append (str, _("2G (Preferred), 3G, 5G"));
1066 else
1067 g_string_append (str, _("2G, 3G, 5G"));
1068 }
1069 else if (allowed & MM_MODEM_MODE_3G &&
1070 allowed & MM_MODEM_MODE_4G)
1071 {
1072 if (preferred & MM_MODEM_MODE_4G)
1073 g_string_append (str, _("3G, 4G (Preferred)"));
1074 else if (preferred & MM_MODEM_MODE_3G)
1075 g_string_append (str, _("3G (Preferred), 4G"));
1076 else
1077 g_string_append (str, _("3G, 4G"));
1078 }
1079 else if (allowed & MM_MODEM_MODE_2G &&
1080 allowed & MM_MODEM_MODE_4G)
1081 {
1082 if (preferred & MM_MODEM_MODE_4G)
1083 g_string_append (str, _("2G, 4G (Preferred)"));
1084 else if (preferred & MM_MODEM_MODE_2G)
1085 g_string_append (str, _("2G (Preferred), 4G"));
1086 else
1087 g_string_append (str, _("2G, 4G"));
1088 }
1089 else if (allowed & MM_MODEM_MODE_2G &&
1090 allowed & MM_MODEM_MODE_3G)
1091 {
1092 if (preferred & MM_MODEM_MODE_3G)
1093 g_string_append (str, _("2G, 3G (Preferred)"));
1094 else if (preferred & MM_MODEM_MODE_2G)
1095 g_string_append (str, _("2G (Preferred), 3G"));
1096 else
1097 g_string_append (str, _("2G, 3G"));
1098 }
1099 else if (allowed & MM_MODEM_MODE_2G &&
1100 allowed & MM_MODEM_MODE_5G)
1101 {
1102 if (preferred & MM_MODEM_MODE_5G)
1103 g_string_append (str, _("2G, 5G (Preferred)"));
1104 else if (preferred & MM_MODEM_MODE_2G)
1105 g_string_append (str, _("2G (Preferred), 5G"));
1106 else
1107 g_string_append (str, _("2G, 5G"));
1108 }
1109 else if (allowed & MM_MODEM_MODE_3G &&
1110 allowed & MM_MODEM_MODE_5G)
1111 {
1112 if (preferred & MM_MODEM_MODE_5G)
1113 g_string_append (str, _("3G, 5G (Preferred)"));
1114 else if (preferred & MM_MODEM_MODE_3G)
1115 g_string_append (str, _("3G (Preferred), 5G"));
1116 else
1117 g_string_append (str, _("3G, 5G"));
1118 }
1119 else if (allowed & MM_MODEM_MODE_4G &&
1120 allowed & MM_MODEM_MODE_5G)
1121 {
1122 if (preferred & MM_MODEM_MODE_5G)
1123 g_string_append (str, _("4G, 5G (Preferred)"));
1124 else if (preferred & MM_MODEM_MODE_4G)
1125 g_string_append (str, _("4G (Preferred), 5G"));
1126 else
1127 g_string_append (str, _("4G, 5G"));
1128 }
1129
1130 if (!str->len)
1131 g_string_append (str, C_("Network mode", "Unknown"));
1132
1133 return g_string_free (str, FALSE);
1134 }
1135
1136 static void
1137 wwan_network_list_free (GList *network_list)
1138 {
1139 g_list_free_full (network_list, (GDestroyNotify)mm_modem_3gpp_network_free);
1140 }
1141
1142 static void
1143 cc_wwan_device_scan_complete_cb (GObject *object,
1144 GAsyncResult *result,
1145 gpointer user_data)
1146 {
1147 MMModem3gpp *modem_3gpp = (MMModem3gpp *)object;
1148 g_autoptr(GTask) task = user_data;
1149 g_autoptr(GError) error = NULL;
1150 GList *network_list;
1151
1152 network_list = mm_modem_3gpp_scan_finish (modem_3gpp, result, &error);
1153
1154 if (error)
1155 g_task_return_error (task, g_steal_pointer (&error));
1156 else
1157 g_task_return_pointer (task, network_list, (GDestroyNotify)wwan_network_list_free);
1158 }
1159
1160 void
1161 cc_wwan_device_scan_networks (CcWwanDevice *self,
1162 GCancellable *cancellable,
1163 GAsyncReadyCallback callback,
1164 gpointer user_data)
1165 {
1166 g_autoptr(GTask) task = NULL;
1167
1168 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
1169 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1170
1171 task = g_task_new (self, cancellable, callback, user_data);
1172
1173 mm_modem_3gpp_scan (self->modem_3gpp, cancellable,
1174 cc_wwan_device_scan_complete_cb,
1175 g_steal_pointer (&task));
1176 }
1177
1178 GList *
1179 cc_wwan_device_scan_networks_finish (CcWwanDevice *self,
1180 GAsyncResult *result,
1181 GError **error)
1182 {
1183 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
1184 g_return_val_if_fail (G_IS_TASK (result), FALSE);
1185
1186 return g_task_propagate_pointer (G_TASK (result), error);
1187 }
1188
1189 static void
1190 cc_wwan_device_register_network_complete_cb (GObject *object,
1191 GAsyncResult *result,
1192 gpointer user_data)
1193 {
1194 CcWwanDevice *self;
1195 MMModem3gpp *modem_3gpp = (MMModem3gpp *)object;
1196 g_autoptr(GTask) task = user_data;
1197 g_autoptr(GError) error = NULL;
1198
1199 if (!mm_modem_3gpp_register_finish (modem_3gpp, result, &error))
1200 {
1201 self = g_task_get_source_object (G_TASK (task));
1202
1203 g_clear_error (&self->error);
1204 self->error = g_error_copy (error);
1205 g_warning ("Error: %s", error->message);
1206 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ERROR]);
1207
1208 g_task_return_error (task, g_steal_pointer (&error));
1209 }
1210 else
1211 {
1212 g_task_return_boolean (task, TRUE);
1213 }
1214 }
1215
1216 void
1217 cc_wwan_device_register_network (CcWwanDevice *self,
1218 const gchar *network_id,
1219 GCancellable *cancellable,
1220 GAsyncReadyCallback callback,
1221 gpointer user_data)
1222 {
1223 g_autoptr(GTask) task = NULL;
1224
1225 g_return_if_fail (CC_IS_WWAN_DEVICE (self));
1226 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
1227
1228 task = g_task_new (self, cancellable, callback, user_data);
1229
1230 if (network_id && *network_id)
1231 self->network_is_manual = TRUE;
1232 else
1233 self->network_is_manual = FALSE;
1234
1235 mm_modem_3gpp_register (self->modem_3gpp, network_id, cancellable,
1236 cc_wwan_device_register_network_complete_cb,
1237 g_steal_pointer (&task));
1238 }
1239
1240 gboolean
1241 cc_wwan_device_register_network_finish (CcWwanDevice *self,
1242 GAsyncResult *result,
1243 GError **error)
1244 {
1245 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), FALSE);
1246 g_return_val_if_fail (G_IS_TASK (result), FALSE);
1247
1248 return g_task_propagate_boolean (G_TASK (result), error);
1249 }
1250
1251 /**
1252 * cc_wwan_device_get_operator_name:
1253 * @self: a #CcWwanDevice
1254 *
1255 * Get the human readable network operator name
1256 * currently the device is connected to.
1257 *
1258 * Returns: (nullable): The operator name or %NULL
1259 */
1260 const gchar *
1261 cc_wwan_device_get_operator_name (CcWwanDevice *self)
1262 {
1263 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1264
1265 if (!self->modem_3gpp)
1266 return NULL;
1267
1268 return mm_modem_3gpp_get_operator_name (self->modem_3gpp);
1269 }
1270
1271 gchar *
1272 cc_wwan_device_dup_own_numbers (CcWwanDevice *self)
1273 {
1274 const char *const *own_numbers;
1275
1276 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1277
1278 own_numbers = mm_modem_get_own_numbers (self->modem);
1279
1280 if (!own_numbers)
1281 return NULL;
1282
1283 return g_strjoinv ("\n", (char **)own_numbers);
1284 }
1285
1286 gchar *
1287 cc_wwan_device_dup_network_type_string (CcWwanDevice *self)
1288 {
1289 MMModemAccessTechnology type;
1290
1291 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1292
1293 type = mm_modem_get_access_technologies (self->modem);
1294
1295 return mm_modem_access_technology_build_string_from_mask (type);
1296 }
1297
1298 gchar *
1299 cc_wwan_device_dup_signal_string (CcWwanDevice *self)
1300 {
1301 MMModemSignal *modem_signal;
1302 MMSignal *signal;
1303 GString *str;
1304 gdouble value;
1305 gboolean recent;
1306 guint refresh_rate;
1307
1308 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1309
1310 modem_signal = mm_object_peek_modem_signal (self->mm_object);
1311
1312 if (modem_signal)
1313 refresh_rate = mm_modem_signal_get_rate (modem_signal);
1314
1315 if (!modem_signal || !refresh_rate)
1316 return g_strdup_printf ("%d%%", mm_modem_get_signal_quality (self->modem, &recent));
1317
1318 str = g_string_new ("");
1319
1320 /* Adapted from ModemManager mmcli-modem-signal.c */
1321 signal = mm_modem_signal_peek_cdma (modem_signal);
1322 if (signal)
1323 {
1324 if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN)
1325 g_string_append_printf (str, "rssi: %.2g dBm ", value);
1326 if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN)
1327 g_string_append_printf (str, "ecio: %.2g dBm ", value);
1328 }
1329
1330 signal = mm_modem_signal_peek_evdo (modem_signal);
1331 if (signal)
1332 {
1333 if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN)
1334 g_string_append_printf (str, "rssi: %.2g dBm ", value);
1335 if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN)
1336 g_string_append_printf (str, "ecio: %.2g dBm ", value);
1337 if ((value = mm_signal_get_sinr (signal)) != MM_SIGNAL_UNKNOWN)
1338 g_string_append_printf (str, "sinr: %.2g dB ", value);
1339 if ((value = mm_signal_get_io (signal)) != MM_SIGNAL_UNKNOWN)
1340 g_string_append_printf (str, "io: %.2g dBm ", value);
1341 }
1342
1343 signal = mm_modem_signal_peek_gsm (modem_signal);
1344 if (signal)
1345 if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN)
1346 g_string_append_printf (str, "rssi: %.2g dBm ", value);
1347
1348 signal = mm_modem_signal_peek_umts (modem_signal);
1349 if (signal)
1350 {
1351 if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN)
1352 g_string_append_printf (str, "rssi: %.2g dBm ", value);
1353 if ((value = mm_signal_get_rscp (signal)) != MM_SIGNAL_UNKNOWN)
1354 g_string_append_printf (str, "rscp: %.2g dBm ", value);
1355 if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN)
1356 g_string_append_printf (str, "ecio: %.2g dBm ", value);
1357 }
1358
1359 signal = mm_modem_signal_peek_lte (modem_signal);
1360 if (signal)
1361 {
1362 if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN)
1363 g_string_append_printf (str, "rssi: %.2g dBm ", value);
1364 if ((value = mm_signal_get_rsrq (signal)) != MM_SIGNAL_UNKNOWN)
1365 g_string_append_printf (str, "rsrq: %.2g dB ", value);
1366 if ((value = mm_signal_get_rsrp (signal)) != MM_SIGNAL_UNKNOWN)
1367 g_string_append_printf (str, "rsrp: %.2g dBm ", value);
1368 if ((value = mm_signal_get_snr (signal)) != MM_SIGNAL_UNKNOWN)
1369 g_string_append_printf (str, "snr: %.2g dB ", value);
1370 }
1371
1372 return g_string_free (str, FALSE);
1373 }
1374
1375 const gchar *
1376 cc_wwan_device_get_manufacturer (CcWwanDevice *self)
1377 {
1378 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1379
1380 return mm_modem_get_manufacturer (self->modem);
1381 }
1382
1383 const gchar *
1384 cc_wwan_device_get_model (CcWwanDevice *self)
1385 {
1386 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1387
1388 return mm_modem_get_model (self->modem);
1389 }
1390
1391 const gchar *
1392 cc_wwan_device_get_firmware_version (CcWwanDevice *self)
1393 {
1394 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1395
1396 return mm_modem_get_revision (self->modem);
1397 }
1398
1399 const gchar *
1400 cc_wwan_device_get_identifier (CcWwanDevice *self)
1401 {
1402 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1403
1404 return mm_modem_get_equipment_identifier (self->modem);
1405 }
1406
1407 const gchar *
1408 cc_wwan_device_get_simple_error (CcWwanDevice *self)
1409 {
1410 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1411
1412 if (!self->error)
1413 return NULL;
1414
1415 g_dbus_error_strip_remote_error (self->error);
1416
1417 return cc_wwan_error_get_message (self->error);
1418 }
1419
1420 gboolean
1421 cc_wwan_device_is_nm_device (CcWwanDevice *self,
1422 GObject *nm_device)
1423 {
1424 #if defined(HAVE_NETWORK_MANAGER) && defined(BUILD_NETWORK)
1425 g_return_val_if_fail (NM_IS_DEVICE (nm_device), FALSE);
1426
1427 return g_str_equal (mm_modem_get_primary_port (self->modem),
1428 nm_device_get_iface (NM_DEVICE (nm_device)));
1429 #else
1430 return FALSE;
1431 #endif
1432 }
1433
1434 const gchar *
1435 cc_wwan_device_get_path (CcWwanDevice *self)
1436 {
1437 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), "");
1438
1439 return mm_object_get_path (self->mm_object);
1440 }
1441
1442 CcWwanData *
1443 cc_wwan_device_get_data (CcWwanDevice *self)
1444 {
1445 g_return_val_if_fail (CC_IS_WWAN_DEVICE (self), NULL);
1446
1447 return self->wwan_data;
1448 }
1449
1450 gboolean
1451 cc_wwan_device_pin_valid (const gchar *password,
1452 MMModemLock lock)
1453 {
1454 size_t len;
1455
1456 g_return_val_if_fail (lock == MM_MODEM_LOCK_SIM_PIN ||
1457 lock == MM_MODEM_LOCK_SIM_PIN2 ||
1458 lock == MM_MODEM_LOCK_SIM_PUK ||
1459 lock == MM_MODEM_LOCK_SIM_PUK2, FALSE);
1460 if (!password)
1461 return FALSE;
1462
1463 len = strlen (password);
1464
1465 if (len < 4 || len > 8)
1466 return FALSE;
1467
1468 if (strspn (password, "0123456789") != len)
1469 return FALSE;
1470
1471 /*
1472 * XXX: Can PUK code be something other than 8 digits?
1473 * 3GPP standard seems mum on this
1474 */
1475 if (lock == MM_MODEM_LOCK_SIM_PUK ||
1476 lock == MM_MODEM_LOCK_SIM_PUK2)
1477 if (len != 8)
1478 return FALSE;
1479
1480 return TRUE;
1481 }
1482