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 |
|
|
|