3
* oFono - Open Source Telephony
5
* Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
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.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
40
/* 0-127 from 24.011 Annex E2
41
* 127-255 23.040 Section 9.2.3.22
42
* Rest are from 27.005 Section 3.2.5
44
struct error_entry cms_errors[] = {
45
{ 1, "Unassigned number" },
46
{ 8, "Operator determined barring" },
47
{ 10, "Call barred" },
48
{ 21, "Short message transfer rejected" },
49
{ 27, "Destination out of service" },
50
{ 28, "Unindentified subscriber" },
51
{ 29, "Facility rejected" },
52
{ 30, "Unknown subscriber" },
53
{ 38, "Network out of order" },
54
{ 41, "Temporary failure" },
56
{ 47, "Recources unavailable" },
57
{ 50, "Requested facility not subscribed" },
58
{ 69, "Requested facility not implemented" },
59
{ 81, "Invalid short message transfer reference value" },
60
{ 95, "Invalid message, unspecified" },
61
{ 96, "Invalid mandatory information" },
62
{ 97, "Message type non existent or not implemented" },
63
{ 98, "Message not compatible with short message protocol state" },
64
{ 99, "Information element non-existent or not implemented" },
65
{ 111, "Protocol error, unspecified" },
66
{ 127, "Internetworking error, unspecified" },
67
{ 128, "Telematic internetworking not supported" },
68
{ 129, "Short message type 0 not supported" },
69
{ 130, "Cannot replace short message" },
70
{ 143, "Unspecified TP-PID error" },
71
{ 144, "Data code scheme not supported" },
72
{ 145, "Message class not supported" },
73
{ 159, "Unspecified TP-DCS error" },
74
{ 160, "Command cannot be actioned" },
75
{ 161, "Command unsupported" },
76
{ 175, "Unspecified TP-Command error" },
77
{ 176, "TPDU not supported" },
79
{ 193, "No SC subscription" },
80
{ 194, "SC System failure" },
81
{ 195, "Invalid SME address" },
82
{ 196, "Destination SME barred" },
83
{ 197, "SM Rejected-Duplicate SM" },
84
{ 198, "TP-VPF not supported" },
85
{ 199, "TP-VP not supported" },
86
{ 208, "(U)SIM SMS Storage full" },
87
{ 209, "No SMS Storage capability in SIM" },
88
{ 210, "Error in MS" },
89
{ 211, "Memory capacity exceeded" },
90
{ 212, "Sim application toolkit busy" },
91
{ 213, "SIM data download error" },
92
{ 255, "Unspecified error cause" },
93
{ 300, "ME Failure" },
94
{ 301, "SMS service of ME reserved" },
95
{ 302, "Operation not allowed" },
96
{ 303, "Operation not supported" },
97
{ 304, "Invalid PDU mode parameter" },
98
{ 305, "Invalid Text mode parameter" },
99
{ 310, "(U)SIM not inserted" },
100
{ 311, "(U)SIM PIN required" },
101
{ 312, "PH-(U)SIM PIN required" },
102
{ 313, "(U)SIM failure" },
103
{ 314, "(U)SIM busy" },
104
{ 315, "(U)SIM wrong" },
105
{ 316, "(U)SIM PUK required" },
106
{ 317, "(U)SIM PIN2 required" },
107
{ 318, "(U)SIM PUK2 required" },
108
{ 320, "Memory failure" },
109
{ 321, "Invalid memory index" },
110
{ 322, "Memory full" },
111
{ 330, "SMSC address unknown" },
112
{ 331, "No network service" },
113
{ 332, "Network timeout" },
114
{ 340, "No +CNMA expected" },
115
{ 500, "Unknown error" },
118
/* 27.007, Section 9 */
119
struct error_entry cme_errors[] = {
120
{ 0, "Phone failure" },
121
{ 1, "No connection to phone" },
122
{ 2, "Phone adapter link reserved" },
123
{ 3, "Operation not allowed" },
124
{ 4, "Operation not supported" },
125
{ 5, "PH_SIM PIN required" },
126
{ 6, "PH_FSIM PIN required" },
127
{ 7, "PH_FSIM PUK required" },
128
{ 10, "SIM not inserted" },
129
{ 11, "SIM PIN required" },
130
{ 12, "SIM PUK required" },
131
{ 13, "SIM failure" },
134
{ 16, "Incorrect password" },
135
{ 17, "SIM PIN2 required" },
136
{ 18, "SIM PUK2 required" },
137
{ 20, "Memory full" },
138
{ 21, "Invalid index" },
140
{ 23, "Memory failure" },
141
{ 24, "Text string too long" },
142
{ 25, "Invalid characters in text string" },
143
{ 26, "Dial string too long" },
144
{ 27, "Invalid characters in dial string" },
145
{ 30, "No network service" },
146
{ 31, "Network timeout" },
147
{ 32, "Network not allowed, emergency calls only" },
148
{ 40, "Network personalization PIN required" },
149
{ 41, "Network personalization PUK required" },
150
{ 42, "Network subset personalization PIN required" },
151
{ 43, "Network subset personalization PUK required" },
152
{ 44, "Service provider personalization PIN required" },
153
{ 45, "Service provider personalization PUK required" },
154
{ 46, "Corporate personalization PIN required" },
155
{ 47, "Corporate personalization PUK required" },
156
{ 48, "PH-SIM PUK required" },
157
{ 100, "Unknown error" },
158
{ 103, "Illegal MS" },
159
{ 106, "Illegal ME" },
160
{ 107, "GPRS services not allowed" },
161
{ 111, "PLMN not allowed" },
162
{ 112, "Location area not allowed" },
163
{ 113, "Roaming not allowed in this location area" },
164
{ 126, "Operation temporary not allowed" },
165
{ 132, "Service operation not supported" },
166
{ 133, "Requested service option not subscribed" },
167
{ 134, "Service option temporary out of order" },
168
{ 148, "Unspecified GPRS error" },
169
{ 149, "PDP authentication failure" },
170
{ 150, "Invalid mobile class" },
171
{ 256, "Operation temporarily not allowed" },
172
{ 257, "Call barred" },
173
{ 258, "Phone is busy" },
174
{ 259, "User abort" },
175
{ 260, "Invalid dial string" },
176
{ 261, "SS not executed" },
177
{ 262, "SIM Blocked" },
178
{ 263, "Invalid block" },
179
{ 772, "SIM powered down" },
183
struct error_entry ceer_errors[] = {
184
{ 1, "Unassigned number" },
185
{ 3, "No route to destination" },
186
{ 6, "Channel unacceptable" },
187
{ 8, "Operator determined barring" },
188
{ 16, "Normal call clearing" },
190
{ 18, "No user responding" },
191
{ 19, "User alerting, no answer" },
192
{ 21, "Call rejected" },
193
{ 22, "Number changed" },
194
{ 25, "Pre-emption" },
195
{ 26, "Non-selected user clearing" },
196
{ 27, "Destination out of order" },
197
{ 28, "Invalid number format (incomplete number)" },
198
{ 29, "Facility rejected" },
199
{ 30, "Response to STATUS ENQUIRY" },
200
{ 31, "Normal, unspecified" },
201
{ 34, "No circuit/channel available" },
202
{ 38, "Network out of order" },
203
{ 41, "Temporary failure" },
204
{ 42, "Switching equipment congestion" },
205
{ 43, "Access information discared" },
206
{ 44, "Requested circuit/channel not available" },
207
{ 47, "Resource unavailable (unspecified)" },
208
{ 49, "Quality of service unavailable" },
209
{ 50, "Requested facility not subscribed" },
210
{ 55, "Incoming calls barred within the CUG" },
211
{ 57, "Bearer capability not authorized" },
212
{ 58, "Bearar capability not presently available" },
213
{ 63, "Service or option not available, unspecified" },
214
{ 65, "Bearer service not implemented" },
215
{ 68, "ACM equal to or greater than ACMmax" },
216
{ 69, "Requested facility not implemented" },
217
{ 70, "Only restricted digital information bearer capability is available" },
218
{ 79, "Service or option not implemented, unspecified" },
219
{ 81, "Invalid transaction identifier value" },
220
{ 87, "User not member of CUG" },
221
{ 88, "Incompatible destination" },
222
{ 91, "Invalid transit network selection" },
223
{ 95, "Semantically incorrect message" },
224
{ 96, "Invalid mandatory information"},
225
{ 97, "Message type non-existent or not implemented" },
226
{ 98, "Message type not compatible with protocol state" },
227
{ 99, "Information element non-existent or not implemented" },
228
{ 100, "Conditional IE error" },
229
{ 101, "Message not compatible with protocol state" },
230
{ 102, "Recovery on timer expirty" },
231
{ 111, "Protocol error, unspecified" },
232
{ 127, "Interworking, unspecified" },
235
gboolean valid_phone_number_format(const char *number)
237
int len = strlen(number);
244
if (number[0] == '+')
247
if ((len - begin) > OFONO_MAX_PHONE_NUMBER_LENGTH)
250
for (i = begin; i < len; i++) {
251
if (number[i] >= '0' && number[i] <= '9')
254
if (number[i] == '*' || number[i] == '#')
263
const char *telephony_error_to_str(const struct ofono_error *error)
265
struct error_entry *e;
269
switch (error->type) {
270
case OFONO_ERROR_TYPE_CME:
272
maxentries = sizeof(cme_errors) / sizeof(struct error_entry);
274
case OFONO_ERROR_TYPE_CMS:
276
maxentries = sizeof(cme_errors) / sizeof(struct error_entry);
278
case OFONO_ERROR_TYPE_CEER:
280
maxentries = sizeof(ceer_errors) / sizeof(struct error_entry);
286
for (i = 0; i < maxentries; i++)
287
if (e[i].error == error->error)
293
int mmi_service_code_to_bearer_class(int code)
297
/* Teleservices according to 22.004
300
* 3,4,5 - Unallocated
308
/* 22.030: 1 to 6, 12 */
310
cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX | BEARER_CLASS_SMS;
314
cls = BEARER_CLASS_VOICE;
318
cls = BEARER_CLASS_SMS | BEARER_CLASS_FAX;
322
cls = BEARER_CLASS_FAX;
326
cls = BEARER_CLASS_SMS;
328
/* TODO: Voice Group Call & Broadcast VGCS & VBS */
332
/* 22.030: 1, 3 to 6, 12 */
334
cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX;
338
/* 22.004 only defines BS 7 (Data Sync) & BS 8 (Data Async) */
340
cls = BEARER_CLASS_DATA_ASYNC | BEARER_CLASS_DATA_SYNC;
342
/* According to 22.030: All Async */
344
/* According to 22.030: All Data Async */
346
cls = BEARER_CLASS_DATA_ASYNC;
348
/* According to 22.030: All Sync */
350
/* According to 22.030: All Data Sync */
352
cls = BEARER_CLASS_DATA_SYNC;
354
/* According to 22.030: Telephony & All Sync services */
356
cls = BEARER_CLASS_VOICE | BEARER_CLASS_DATA_SYNC;
365
const char *phone_number_to_string(const struct ofono_phone_number *ph)
367
static char buffer[64];
369
if (ph->type == 145 && (strlen(ph->number) > 0) &&
370
ph->number[0] != '+') {
372
strncpy(buffer + 1, ph->number, 62);
375
strncpy(buffer, ph->number, 63);
382
void string_to_phone_number(const char *str, struct ofono_phone_number *ph)
384
if (strlen(str) && str[0] == '+') {
385
strcpy(ph->number, str+1);
386
ph->type = 145; /* International */
388
strcpy(ph->number, str);
389
ph->type = 129; /* Local */
393
int valid_ussd_string(const char *str)
395
int len = strlen(str);
400
/* It is hard to understand exactly what constitutes a valid USSD string
401
* According to 22.090:
402
* Case a - 1, 2 or 3 digits from the set (*, #) followed by 1X(Y),
403
* where X=any number 0‑4, Y=any number 0‑9, then, optionally "*
404
* followed by any number of any characters", and concluding with #SEND
406
* Case b - 1, 2 or 3 digits from the set (*, #) followed by 1X(Y),
407
* where X=any number 5‑9, Y=any number 0‑9, then, optionally "*
408
* followed by any number of any characters", and concluding with #SEND
410
* Case c - 7(Y) SEND, where Y=any number 0‑9
412
* Case d - All other formats
414
* According to 22.030 Figure 3.5.3.2 USSD strings can be:
416
* Supplementary service control
418
* Manufacturer defined
420
* Short String - This can be any 2 digit short string. If the string
421
* starts with a '1' and no calls are in progress then
422
* this string is treated as a call setup request
424
* Everything else is not a valid USSD string
427
if (len != 2 && str[len-1] != '#')
433
const char *ss_control_type_to_string(enum ss_control_type type)
436
case SS_CONTROL_TYPE_ACTIVATION:
438
case SS_CONTROL_TYPE_REGISTRATION:
439
return "registration";
440
case SS_CONTROL_TYPE_QUERY:
441
return "interrogation";
442
case SS_CONTROL_TYPE_DEACTIVATION:
443
return "deactivation";
444
case SS_CONTROL_TYPE_ERASURE:
451
#define NEXT_FIELD(str, dest) \
455
str = strchrnul(str, '*'); \
462
/* Note: The str will be modified, so in case of error you should
463
* throw it away and start over
465
gboolean parse_ss_control_string(char *str, int *ss_type,
466
char **sc, char **sia,
467
char **sib, char **sic,
468
char **sid, char **dn)
470
int len = strlen(str);
474
gboolean ret = FALSE;
476
/* Minimum is {*,#}SC# */
480
if (str[0] != '*' && str[0] != '#')
485
if (str[1] != '*' && str[1] != '#' && str[1] > '9' && str[1] < '0')
488
if (str[0] == '#' && str[1] == '*')
491
if (str[1] == '#' || str[1] == '*')
494
if (str[0] == '*' && str[1] == '*')
495
*ss_type = SS_CONTROL_TYPE_REGISTRATION;
496
else if (str[0] == '#' && str[1] == '#')
497
*ss_type = SS_CONTROL_TYPE_ERASURE;
498
else if (str[0] == '*' && str[1] == '#')
499
*ss_type = SS_CONTROL_TYPE_QUERY;
500
else if (str[0] == '*')
501
*ss_type = SS_CONTROL_TYPE_ACTIVATION;
503
*ss_type = SS_CONTROL_TYPE_DEACTIVATION;
505
/* Must have at least one other '#' */
506
c = strrchr(str+cur, '#');
514
if (strlen(*dn) > 0 && !valid_phone_number_format(*dn))
521
/* According to 22.030 SC is 2 or 3 digits, there can be
522
* an optional digit 'n' if this is a call setup string,
523
* however 22.030 does not define any SC of length 3
524
* with an 'n' present
526
if (strlen(*sc) < 2 || strlen(*sc) > 3)
529
for (i = 0; i < strlen(*sc); i++)
530
if (!isdigit((*sc)[i]))
545
static const char *bearer_class_lut[] = {
556
const char *bearer_class_to_string(enum bearer_class cls)
559
case BEARER_CLASS_VOICE:
560
return bearer_class_lut[0];
561
case BEARER_CLASS_DATA:
562
return bearer_class_lut[1];
563
case BEARER_CLASS_FAX:
564
return bearer_class_lut[2];
565
case BEARER_CLASS_SMS:
566
return bearer_class_lut[3];
567
case BEARER_CLASS_DATA_SYNC:
568
return bearer_class_lut[4];
569
case BEARER_CLASS_DATA_ASYNC:
570
return bearer_class_lut[5];
571
case BEARER_CLASS_PACKET:
572
return bearer_class_lut[6];
573
case BEARER_CLASS_PAD:
574
return bearer_class_lut[7];
575
case BEARER_CLASS_DEFAULT:
576
case BEARER_CLASS_SS_DEFAULT:
583
gboolean is_valid_pin(const char *pin)
587
for (i = 0; i < strlen(pin); i++)
588
if (pin[i] < '0' || pin[i] > '9')