3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 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
32 #include <ofono/types.h>
42 * 0-127 from 24.011 Annex E2
43 * 127-255 23.040 Section 9.2.3.22
44 * Rest are from 27.005 Section 3.2.5
46 struct error_entry cms_errors[] = {
47 { 1, "Unassigned number" },
48 { 8, "Operator determined barring" },
49 { 10, "Call barred" },
50 { 21, "Short message transfer rejected" },
51 { 27, "Destination out of service" },
52 { 28, "Unindentified subscriber" },
53 { 29, "Facility rejected" },
54 { 30, "Unknown subscriber" },
55 { 38, "Network out of order" },
56 { 41, "Temporary failure" },
58 { 47, "Recources unavailable" },
59 { 50, "Requested facility not subscribed" },
60 { 69, "Requested facility not implemented" },
61 { 81, "Invalid short message transfer reference value" },
62 { 95, "Invalid message, unspecified" },
63 { 96, "Invalid mandatory information" },
64 { 97, "Message type non existent or not implemented" },
65 { 98, "Message not compatible with short message protocol state" },
66 { 99, "Information element non-existent or not implemented" },
67 { 111, "Protocol error, unspecified" },
68 { 127, "Internetworking error, unspecified" },
69 { 128, "Telematic internetworking not supported" },
70 { 129, "Short message type 0 not supported" },
71 { 130, "Cannot replace short message" },
72 { 143, "Unspecified TP-PID error" },
73 { 144, "Data code scheme not supported" },
74 { 145, "Message class not supported" },
75 { 159, "Unspecified TP-DCS error" },
76 { 160, "Command cannot be actioned" },
77 { 161, "Command unsupported" },
78 { 175, "Unspecified TP-Command error" },
79 { 176, "TPDU not supported" },
81 { 193, "No SC subscription" },
82 { 194, "SC System failure" },
83 { 195, "Invalid SME address" },
84 { 196, "Destination SME barred" },
85 { 197, "SM Rejected-Duplicate SM" },
86 { 198, "TP-VPF not supported" },
87 { 199, "TP-VP not supported" },
88 { 208, "(U)SIM SMS Storage full" },
89 { 209, "No SMS Storage capability in SIM" },
90 { 210, "Error in MS" },
91 { 211, "Memory capacity exceeded" },
92 { 212, "Sim application toolkit busy" },
93 { 213, "SIM data download error" },
94 { 255, "Unspecified error cause" },
95 { 300, "ME Failure" },
96 { 301, "SMS service of ME reserved" },
97 { 302, "Operation not allowed" },
98 { 303, "Operation not supported" },
99 { 304, "Invalid PDU mode parameter" },
100 { 305, "Invalid Text mode parameter" },
101 { 310, "(U)SIM not inserted" },
102 { 311, "(U)SIM PIN required" },
103 { 312, "PH-(U)SIM PIN required" },
104 { 313, "(U)SIM failure" },
105 { 314, "(U)SIM busy" },
106 { 315, "(U)SIM wrong" },
107 { 316, "(U)SIM PUK required" },
108 { 317, "(U)SIM PIN2 required" },
109 { 318, "(U)SIM PUK2 required" },
110 { 320, "Memory failure" },
111 { 321, "Invalid memory index" },
112 { 322, "Memory full" },
113 { 330, "SMSC address unknown" },
114 { 331, "No network service" },
115 { 332, "Network timeout" },
116 { 340, "No +CNMA expected" },
117 { 500, "Unknown error" },
120 /* 27.007, Section 9 */
121 struct error_entry cme_errors[] = {
122 { 0, "Phone failure" },
123 { 1, "No connection to phone" },
124 { 2, "Phone adapter link reserved" },
125 { 3, "Operation not allowed" },
126 { 4, "Operation not supported" },
127 { 5, "PH_SIM PIN required" },
128 { 6, "PH_FSIM PIN required" },
129 { 7, "PH_FSIM PUK required" },
130 { 10, "SIM not inserted" },
131 { 11, "SIM PIN required" },
132 { 12, "SIM PUK required" },
133 { 13, "SIM failure" },
136 { 16, "Incorrect password" },
137 { 17, "SIM PIN2 required" },
138 { 18, "SIM PUK2 required" },
139 { 20, "Memory full" },
140 { 21, "Invalid index" },
142 { 23, "Memory failure" },
143 { 24, "Text string too long" },
144 { 25, "Invalid characters in text string" },
145 { 26, "Dial string too long" },
146 { 27, "Invalid characters in dial string" },
147 { 30, "No network service" },
148 { 31, "Network timeout" },
149 { 32, "Network not allowed, emergency calls only" },
150 { 40, "Network personalization PIN required" },
151 { 41, "Network personalization PUK required" },
152 { 42, "Network subset personalization PIN required" },
153 { 43, "Network subset personalization PUK required" },
154 { 44, "Service provider personalization PIN required" },
155 { 45, "Service provider personalization PUK required" },
156 { 46, "Corporate personalization PIN required" },
157 { 47, "Corporate personalization PUK required" },
158 { 48, "PH-SIM PUK required" },
159 { 100, "Unknown error" },
160 { 103, "Illegal MS" },
161 { 106, "Illegal ME" },
162 { 107, "GPRS services not allowed" },
163 { 111, "PLMN not allowed" },
164 { 112, "Location area not allowed" },
165 { 113, "Roaming not allowed in this location area" },
166 { 126, "Operation temporary not allowed" },
167 { 132, "Service operation not supported" },
168 { 133, "Requested service option not subscribed" },
169 { 134, "Service option temporary out of order" },
170 { 148, "Unspecified GPRS error" },
171 { 149, "PDP authentication failure" },
172 { 150, "Invalid mobile class" },
173 { 256, "Operation temporarily not allowed" },
174 { 257, "Call barred" },
175 { 258, "Phone is busy" },
176 { 259, "User abort" },
177 { 260, "Invalid dial string" },
178 { 261, "SS not executed" },
179 { 262, "SIM Blocked" },
180 { 263, "Invalid block" },
181 { 772, "SIM powered down" },
185 struct error_entry ceer_errors[] = {
186 { 1, "Unassigned number" },
187 { 3, "No route to destination" },
188 { 6, "Channel unacceptable" },
189 { 8, "Operator determined barring" },
190 { 16, "Normal call clearing" },
192 { 18, "No user responding" },
193 { 19, "User alerting, no answer" },
194 { 21, "Call rejected" },
195 { 22, "Number changed" },
196 { 25, "Pre-emption" },
197 { 26, "Non-selected user clearing" },
198 { 27, "Destination out of order" },
199 { 28, "Invalid number format (incomplete number)" },
200 { 29, "Facility rejected" },
201 { 30, "Response to STATUS ENQUIRY" },
202 { 31, "Normal, unspecified" },
203 { 34, "No circuit/channel available" },
204 { 38, "Network out of order" },
205 { 41, "Temporary failure" },
206 { 42, "Switching equipment congestion" },
207 { 43, "Access information discared" },
208 { 44, "Requested circuit/channel not available" },
209 { 47, "Resource unavailable (unspecified)" },
210 { 49, "Quality of service unavailable" },
211 { 50, "Requested facility not subscribed" },
212 { 55, "Incoming calls barred within the CUG" },
213 { 57, "Bearer capability not authorized" },
214 { 58, "Bearar capability not presently available" },
215 { 63, "Service or option not available, unspecified" },
216 { 65, "Bearer service not implemented" },
217 { 68, "ACM equal to or greater than ACMmax" },
218 { 69, "Requested facility not implemented" },
219 { 70, "Only restricted digital information bearer capability is available" },
220 { 79, "Service or option not implemented, unspecified" },
221 { 81, "Invalid transaction identifier value" },
222 { 87, "User not member of CUG" },
223 { 88, "Incompatible destination" },
224 { 91, "Invalid transit network selection" },
225 { 95, "Semantically incorrect message" },
226 { 96, "Invalid mandatory information"},
227 { 97, "Message type non-existent or not implemented" },
228 { 98, "Message type not compatible with protocol state" },
229 { 99, "Information element non-existent or not implemented" },
230 { 100, "Conditional IE error" },
231 { 101, "Message not compatible with protocol state" },
232 { 102, "Recovery on timer expirty" },
233 { 111, "Protocol error, unspecified" },
234 { 127, "Interworking, unspecified" },
237 gboolean valid_number_format(const char *number, int length)
239 int len = strlen(number);
246 if (number[0] == '+')
252 if ((len - begin) > length)
255 for (i = begin; i < len; i++) {
256 if (number[i] >= '0' && number[i] <= '9')
259 if (number[i] == '*' || number[i] == '#')
269 * According to 3GPP TS 24.011 or 3GPP TS 31.102, some
270 * addresses (or numbers), like Service Centre address,
271 * Destination address, or EFADN (Abbreviated dialling numbers),
274 gboolean valid_phone_number_format(const char *number)
276 return valid_number_format(number, 20);
279 gboolean valid_long_phone_number_format(const char *number)
281 return valid_number_format(number, OFONO_MAX_PHONE_NUMBER_LENGTH);
284 gboolean valid_cdma_phone_number_format(const char *number)
286 int len = strlen(number);
292 if (len > OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH)
295 for (i = 0; i < len; i++) {
296 if (number[i] >= '0' && number[i] <= '9')
299 if (number[i] == '*' || number[i] == '#')
308 const char *telephony_error_to_str(const struct ofono_error *error)
310 struct error_entry *e;
314 switch (error->type) {
315 case OFONO_ERROR_TYPE_CME:
317 maxentries = sizeof(cme_errors) / sizeof(struct error_entry);
319 case OFONO_ERROR_TYPE_CMS:
321 maxentries = sizeof(cms_errors) / sizeof(struct error_entry);
323 case OFONO_ERROR_TYPE_CEER:
325 maxentries = sizeof(ceer_errors) / sizeof(struct error_entry);
328 return "Unknown error type";
331 for (i = 0; i < maxentries; i++)
332 if (e[i].error == error->error)
335 return "Unknown error";
338 int mmi_service_code_to_bearer_class(int code)
343 * Teleservices according to 22.004
346 * 3,4,5 - Unallocated
354 /* 22.030: 1 to 6, 12 */
356 cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX | BEARER_CLASS_SMS;
360 cls = BEARER_CLASS_VOICE;
364 cls = BEARER_CLASS_SMS | BEARER_CLASS_FAX;
368 cls = BEARER_CLASS_FAX;
372 cls = BEARER_CLASS_SMS;
374 /* TODO: Voice Group Call & Broadcast VGCS & VBS */
378 /* 22.030: 1, 3 to 6, 12 */
380 cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX;
384 * 22.004 only defines BS 7 (Data Sync) & BS 8 (Data Async)
385 * and PAD and Packet bearer services are deprecated. Still,
386 * AT modems rely on these to differentiate between sending
387 * a 'All Sync' or 'All Data Sync' message types. In theory
388 * both message types cover the same bearer services, but we
389 * must still send these for conformance reasons.
392 cls = BEARER_CLASS_DATA_ASYNC | BEARER_CLASS_DATA_SYNC |
393 BEARER_CLASS_PAD | BEARER_CLASS_PACKET;
395 /* According to 22.030: All Async (7) */
397 cls = BEARER_CLASS_DATA_ASYNC | BEARER_CLASS_PAD;
399 /* According to 22.030: All Data Async (7)*/
401 cls = BEARER_CLASS_DATA_ASYNC;
403 /* According to 22.030: All Sync (8) */
405 cls = BEARER_CLASS_DATA_SYNC | BEARER_CLASS_PACKET;
407 /* According to 22.030: All Data Sync (8) */
409 cls = BEARER_CLASS_DATA_SYNC;
411 /* According to 22.030: Telephony & All Sync services (1, 8) */
413 cls = BEARER_CLASS_VOICE | BEARER_CLASS_DATA_SYNC |
423 const char *phone_number_to_string(const struct ofono_phone_number *ph)
425 static char buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 2];
427 if (ph->type == 145 && (strlen(ph->number) > 0) &&
428 ph->number[0] != '+') {
430 strncpy(buffer + 1, ph->number, OFONO_MAX_PHONE_NUMBER_LENGTH);
431 buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 1] = '\0';
433 strncpy(buffer, ph->number, OFONO_MAX_PHONE_NUMBER_LENGTH + 1);
434 buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 1] = '\0';
440 void string_to_phone_number(const char *str, struct ofono_phone_number *ph)
443 strcpy(ph->number, str+1);
444 ph->type = 145; /* International */
446 strcpy(ph->number, str);
447 ph->type = 129; /* Local */
451 const char *cdma_phone_number_to_string(
452 const struct ofono_cdma_phone_number *ph)
454 static char buffer[OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH + 1];
456 strncpy(buffer, ph->number, OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH);
457 buffer[OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH] = '\0';
462 void string_to_cdma_phone_number(const char *str,
463 struct ofono_cdma_phone_number *ph)
465 strcpy(ph->number, str);
468 gboolean valid_ussd_string(const char *str, gboolean call_in_progress)
470 int len = strlen(str);
476 * Return true if an MMI input string is to be sent as USSD.
478 * According to 3GPP TS 22.030, after checking the well-known
479 * supplementary service control, SIM control and manufacturer
480 * defined control codes, the terminal should check if the input
481 * should be sent as USSD according to the following rules:
483 * 1) Terminated by '#'
484 * 2) A short string of 1 or 2 digits
486 * As an exception, if a 2 digit string starts with a '1' and
487 * there are no calls in progress then this string is treated as
488 * a call setup request instead.
491 if (str[len-1] == '#')
494 if (!call_in_progress && len == 2 && str[0] != '1')
503 const char *ss_control_type_to_string(enum ss_control_type type)
506 case SS_CONTROL_TYPE_ACTIVATION:
508 case SS_CONTROL_TYPE_REGISTRATION:
509 return "registration";
510 case SS_CONTROL_TYPE_QUERY:
511 return "interrogation";
512 case SS_CONTROL_TYPE_DEACTIVATION:
513 return "deactivation";
514 case SS_CONTROL_TYPE_ERASURE:
521 #define NEXT_FIELD(str, dest) \
525 str = strchrnul(str, '*'); \
533 * Note: The str will be modified, so in case of error you should
534 * throw it away and start over
536 gboolean parse_ss_control_string(char *str, int *ss_type,
537 char **sc, char **sia,
538 char **sib, char **sic,
539 char **sid, char **dn)
541 int len = strlen(str);
545 gboolean ret = FALSE;
547 /* Minimum is {*,#}SC# */
551 if (str[0] != '*' && str[0] != '#')
556 if (str[1] != '*' && str[1] != '#' && str[1] > '9' && str[1] < '0')
559 if (str[0] == '#' && str[1] == '*')
562 if (str[1] == '#' || str[1] == '*')
565 if (str[0] == '*' && str[1] == '*')
566 *ss_type = SS_CONTROL_TYPE_REGISTRATION;
567 else if (str[0] == '#' && str[1] == '#')
568 *ss_type = SS_CONTROL_TYPE_ERASURE;
569 else if (str[0] == '*' && str[1] == '#')
570 *ss_type = SS_CONTROL_TYPE_QUERY;
571 else if (str[0] == '*')
572 *ss_type = SS_CONTROL_TYPE_ACTIVATION;
574 *ss_type = SS_CONTROL_TYPE_DEACTIVATION;
576 /* Must have at least one other '#' */
577 c = strrchr(str+cur, '#');
585 if (strlen(*dn) > 0 && !valid_phone_number_format(*dn))
593 * According to 22.030 SC is 2 or 3 digits, there can be
594 * an optional digit 'n' if this is a call setup string,
595 * however 22.030 does not define any SC of length 3
596 * with an 'n' present
598 if (strlen(*sc) < 2 || strlen(*sc) > 3)
601 for (i = 0; i < strlen(*sc); i++)
602 if (!g_ascii_isdigit((*sc)[i]))
617 static const char *bearer_class_lut[] = {
628 const char *bearer_class_to_string(enum bearer_class cls)
631 case BEARER_CLASS_VOICE:
632 return bearer_class_lut[0];
633 case BEARER_CLASS_DATA:
634 return bearer_class_lut[1];
635 case BEARER_CLASS_FAX:
636 return bearer_class_lut[2];
637 case BEARER_CLASS_SMS:
638 return bearer_class_lut[3];
639 case BEARER_CLASS_DATA_SYNC:
640 return bearer_class_lut[4];
641 case BEARER_CLASS_DATA_ASYNC:
642 return bearer_class_lut[5];
643 case BEARER_CLASS_PACKET:
644 return bearer_class_lut[6];
645 case BEARER_CLASS_PAD:
646 return bearer_class_lut[7];
647 case BEARER_CLASS_DEFAULT:
648 case BEARER_CLASS_SS_DEFAULT:
655 const char *registration_status_to_string(int status)
658 case NETWORK_REGISTRATION_STATUS_NOT_REGISTERED:
659 return "unregistered";
660 case NETWORK_REGISTRATION_STATUS_REGISTERED:
662 case NETWORK_REGISTRATION_STATUS_SEARCHING:
664 case NETWORK_REGISTRATION_STATUS_DENIED:
666 case NETWORK_REGISTRATION_STATUS_UNKNOWN:
668 case NETWORK_REGISTRATION_STATUS_ROAMING:
675 const char *registration_tech_to_string(int tech)
678 case ACCESS_TECHNOLOGY_GSM:
680 case ACCESS_TECHNOLOGY_GSM_COMPACT:
682 case ACCESS_TECHNOLOGY_UTRAN:
684 case ACCESS_TECHNOLOGY_GSM_EGPRS:
686 case ACCESS_TECHNOLOGY_UTRAN_HSDPA:
688 case ACCESS_TECHNOLOGY_UTRAN_HSUPA:
690 case ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA:
692 case ACCESS_TECHNOLOGY_EUTRAN:
699 gboolean is_valid_apn(const char *apn)
704 if (apn[0] == '.' || apn[0] == '\0')
707 for (i = 0; apn[i] != '\0'; i++) {
708 if (g_ascii_isalnum(apn[i]))
714 if (apn[i] == '.' && (i - last_period) > 1) {
725 const char *ofono_uuid_to_str(const struct ofono_uuid *uuid)
727 static char buf[OFONO_SHA1_UUID_LEN * 2 + 1];
729 return encode_hex_own_buf(uuid->uuid, OFONO_SHA1_UUID_LEN, 0, buf);
732 void ofono_call_init(struct ofono_call *call)
734 memset(call, 0, sizeof(struct ofono_call));
735 call->cnap_validity = CNAP_VALIDITY_NOT_AVAILABLE;
736 call->clip_validity = CLIP_VALIDITY_NOT_AVAILABLE;