ofono/src/common.c

837 lines
20 KiB
C

/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <ofono/types.h>
#include <ofono/gprs-context.h>
#include "common.h"
#include "util.h"
struct error_entry {
int error;
const char *str;
};
/*
* 0-127 from 24.011 Annex E2
* 127-255 23.040 Section 9.2.3.22
* Rest are from 27.005 Section 3.2.5
*/
struct error_entry cms_errors[] = {
{ 1, "Unassigned number" },
{ 8, "Operator determined barring" },
{ 10, "Call barred" },
{ 21, "Short message transfer rejected" },
{ 27, "Destination out of service" },
{ 28, "Unidentified subscriber" },
{ 29, "Facility rejected" },
{ 30, "Unknown subscriber" },
{ 38, "Network out of order" },
{ 41, "Temporary failure" },
{ 42, "Congestion" },
{ 47, "Resources unavailable" },
{ 50, "Requested facility not subscribed" },
{ 69, "Requested facility not implemented" },
{ 81, "Invalid short message transfer reference value" },
{ 95, "Invalid message, unspecified" },
{ 96, "Invalid mandatory information" },
{ 97, "Message type non existent or not implemented" },
{ 98, "Message not compatible with short message protocol state" },
{ 99, "Information element non-existent or not implemented" },
{ 111, "Protocol error, unspecified" },
{ 127, "Interworking error, unspecified" },
{ 128, "Telematic interworking not supported" },
{ 129, "Short message type 0 not supported" },
{ 130, "Cannot replace short message" },
{ 143, "Unspecified TP-PID error" },
{ 144, "Data code scheme not supported" },
{ 145, "Message class not supported" },
{ 159, "Unspecified TP-DCS error" },
{ 160, "Command cannot be actioned" },
{ 161, "Command unsupported" },
{ 175, "Unspecified TP-Command error" },
{ 176, "TPDU not supported" },
{ 192, "SC busy" },
{ 193, "No SC subscription" },
{ 194, "SC System failure" },
{ 195, "Invalid SME address" },
{ 196, "Destination SME barred" },
{ 197, "SM Rejected-Duplicate SM" },
{ 198, "TP-VPF not supported" },
{ 199, "TP-VP not supported" },
{ 208, "(U)SIM SMS Storage full" },
{ 209, "No SMS Storage capability in SIM" },
{ 210, "Error in MS" },
{ 211, "Memory capacity exceeded" },
{ 212, "SIM application toolkit busy" },
{ 213, "SIM data download error" },
{ 255, "Unspecified error cause" },
{ 300, "ME Failure" },
{ 301, "SMS service of ME reserved" },
{ 302, "Operation not allowed" },
{ 303, "Operation not supported" },
{ 304, "Invalid PDU mode parameter" },
{ 305, "Invalid Text mode parameter" },
{ 310, "(U)SIM not inserted" },
{ 311, "(U)SIM PIN required" },
{ 312, "PH-(U)SIM PIN required" },
{ 313, "(U)SIM failure" },
{ 314, "(U)SIM busy" },
{ 315, "(U)SIM wrong" },
{ 316, "(U)SIM PUK required" },
{ 317, "(U)SIM PIN2 required" },
{ 318, "(U)SIM PUK2 required" },
{ 320, "Memory failure" },
{ 321, "Invalid memory index" },
{ 322, "Memory full" },
{ 330, "SMSC address unknown" },
{ 331, "No network service" },
{ 332, "Network timeout" },
{ 340, "No +CNMA expected" },
{ 500, "Unknown error" },
};
/* 27.007, Section 9 */
struct error_entry cme_errors[] = {
{ 0, "Phone failure" },
{ 1, "No connection to phone" },
{ 2, "Phone adaptor link reserved" },
{ 3, "Operation not allowed" },
{ 4, "Operation not supported" },
{ 5, "PH_SIM PIN required" },
{ 6, "PH_FSIM PIN required" },
{ 7, "PH_FSIM PUK required" },
{ 10, "SIM not inserted" },
{ 11, "SIM PIN required" },
{ 12, "SIM PUK required" },
{ 13, "SIM failure" },
{ 14, "SIM busy" },
{ 15, "SIM wrong" },
{ 16, "Incorrect password" },
{ 17, "SIM PIN2 required" },
{ 18, "SIM PUK2 required" },
{ 20, "Memory full" },
{ 21, "Invalid index" },
{ 22, "Not found" },
{ 23, "Memory failure" },
{ 24, "Text string too long" },
{ 25, "Invalid characters in text string" },
{ 26, "Dial string too long" },
{ 27, "Invalid characters in dial string" },
{ 30, "No network service" },
{ 31, "Network timeout" },
{ 32, "Network not allowed, emergency calls only" },
{ 40, "Network personalization PIN required" },
{ 41, "Network personalization PUK required" },
{ 42, "Network subset personalization PIN required" },
{ 43, "Network subset personalization PUK required" },
{ 44, "Service provider personalization PIN required" },
{ 45, "Service provider personalization PUK required" },
{ 46, "Corporate personalization PIN required" },
{ 47, "Corporate personalization PUK required" },
{ 48, "PH-SIM PUK required" },
{ 50, "Incorrect parameters" },
{ 100, "Unknown error" },
{ 103, "Illegal MS" },
{ 106, "Illegal ME" },
{ 107, "GPRS services not allowed" },
{ 111, "PLMN not allowed" },
{ 112, "Location area not allowed" },
{ 113, "Roaming not allowed in this location area" },
{ 126, "Operation temporary not allowed" },
{ 132, "Service operation not supported" },
{ 133, "Requested service option not subscribed" },
{ 134, "Service option temporary out of order" },
{ 148, "Unspecified GPRS error" },
{ 149, "PDP authentication failure" },
{ 150, "Invalid mobile class" },
{ 256, "Operation temporarily not allowed" },
{ 257, "Call barred" },
{ 258, "Phone is busy" },
{ 259, "User abort" },
{ 260, "Invalid dial string" },
{ 261, "SS not executed" },
{ 262, "SIM Blocked" },
{ 263, "Invalid block" },
{ 772, "SIM powered down" },
};
/* 24.008 Annex H */
struct error_entry ceer_errors[] = {
{ 1, "Unassigned number" },
{ 3, "No route to destination" },
{ 6, "Channel unacceptable" },
{ 8, "Operator determined barring" },
{ 16, "Normal call clearing" },
{ 17, "User busy" },
{ 18, "No user responding" },
{ 19, "User alerting, no answer" },
{ 21, "Call rejected" },
{ 22, "Number changed" },
{ 25, "Pre-emption" },
{ 26, "Non-selected user clearing" },
{ 27, "Destination out of order" },
{ 28, "Invalid number format (incomplete number)" },
{ 29, "Facility rejected" },
{ 30, "Response to STATUS ENQUIRY" },
{ 31, "Normal, unspecified" },
{ 34, "No circuit/channel available" },
{ 38, "Network out of order" },
{ 41, "Temporary failure" },
{ 42, "Switching equipment congestion" },
{ 43, "Access information discarded" },
{ 44, "Requested circuit/channel not available" },
{ 47, "Resource unavailable (unspecified)" },
{ 49, "Quality of service unavailable" },
{ 50, "Requested facility not subscribed" },
{ 55, "Incoming calls barred within the CUG" },
{ 57, "Bearer capability not authorized" },
{ 58, "Bearer capability not presently available" },
{ 63, "Service or option not available, unspecified" },
{ 65, "Bearer service not implemented" },
{ 68, "ACM equal to or greater than ACMmax" },
{ 69, "Requested facility not implemented" },
{ 70, "Only restricted digital information bearer capability is available" },
{ 79, "Service or option not implemented, unspecified" },
{ 81, "Invalid transaction identifier value" },
{ 87, "User not member of CUG" },
{ 88, "Incompatible destination" },
{ 91, "Invalid transit network selection" },
{ 95, "Semantically incorrect message" },
{ 96, "Invalid mandatory information"},
{ 97, "Message type non-existent or not implemented" },
{ 98, "Message type not compatible with protocol state" },
{ 99, "Information element non-existent or not implemented" },
{ 100, "Conditional IE error" },
{ 101, "Message not compatible with protocol state" },
{ 102, "Recovery on timer expiry" },
{ 111, "Protocol error, unspecified" },
{ 127, "Interworking, unspecified" },
};
gboolean valid_number_format(const char *number, int length)
{
int len = strlen(number);
int begin = 0;
int i;
if (!len)
return FALSE;
if (number[0] == '+')
begin = 1;
if (begin == len)
return FALSE;
if ((len - begin) > length)
return FALSE;
for (i = begin; i < len; i++) {
if (number[i] >= '0' && number[i] <= '9')
continue;
if (number[i] == '*' || number[i] == '#')
continue;
return FALSE;
}
return TRUE;
}
/*
* According to 3GPP TS 24.011 or 3GPP TS 31.102, some
* addresses (or numbers), like Service Centre address,
* Destination address, or EFADN (Abbreviated dialling numbers),
* are up 20 digits.
*/
gboolean valid_phone_number_format(const char *number)
{
return valid_number_format(number, 20);
}
gboolean valid_long_phone_number_format(const char *number)
{
return valid_number_format(number, OFONO_MAX_PHONE_NUMBER_LENGTH);
}
gboolean valid_cdma_phone_number_format(const char *number)
{
int len = strlen(number);
int i;
if (!len)
return FALSE;
if (len > OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH)
return FALSE;
for (i = 0; i < len; i++) {
if (number[i] >= '0' && number[i] <= '9')
continue;
if (number[i] == '*' || number[i] == '#')
continue;
return FALSE;
}
return TRUE;
}
const char *telephony_error_to_str(const struct ofono_error *error)
{
struct error_entry *e;
int maxentries;
int i;
switch (error->type) {
case OFONO_ERROR_TYPE_CME:
e = cme_errors;
maxentries = sizeof(cme_errors) / sizeof(struct error_entry);
break;
case OFONO_ERROR_TYPE_CMS:
e = cms_errors;
maxentries = sizeof(cms_errors) / sizeof(struct error_entry);
break;
case OFONO_ERROR_TYPE_CEER:
e = ceer_errors;
maxentries = sizeof(ceer_errors) / sizeof(struct error_entry);
break;
default:
return "Unknown error type";
}
for (i = 0; i < maxentries; i++)
if (e[i].error == error->error)
return e[i].str;
return "Unknown error";
}
int mmi_service_code_to_bearer_class(int code)
{
int cls = 0;
/*
* Teleservices according to 22.004
* 1 - Voice
* 2 - SMS
* 3,4,5 - Unallocated
* 6 - Fax
* 7 - All Data Async
* 8 - All Data Sync
* 12 - Voice Group
*/
switch (code) {
/* 22.030: 1 to 6, 12 */
case 10:
cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX | BEARER_CLASS_SMS;
break;
/* 22.030: 1 */
case 11:
cls = BEARER_CLASS_VOICE;
break;
/* 22.030: 2-6 */
case 12:
cls = BEARER_CLASS_SMS | BEARER_CLASS_FAX;
break;
/* 22.030: 6 */
case 13:
cls = BEARER_CLASS_FAX;
break;
/* 22.030: 2 */
case 16:
cls = BEARER_CLASS_SMS;
break;
/* TODO: Voice Group Call & Broadcast VGCS & VBS */
case 17:
case 18:
break;
/* 22.030: 1, 3 to 6, 12 */
case 19:
cls = BEARER_CLASS_VOICE | BEARER_CLASS_FAX;
break;
/*
* 22.030: 7-11
* 22.004 only defines BS 7 (Data Sync) & BS 8 (Data Async)
* and PAD and Packet bearer services are deprecated. Still,
* AT modems rely on these to differentiate between sending
* a 'All Sync' or 'All Data Sync' message types. In theory
* both message types cover the same bearer services, but we
* must still send these for conformance reasons.
*/
case 20:
cls = BEARER_CLASS_DATA_ASYNC | BEARER_CLASS_DATA_SYNC |
BEARER_CLASS_PAD | BEARER_CLASS_PACKET;
break;
/* According to 22.030: All Async (7) */
case 21:
cls = BEARER_CLASS_DATA_ASYNC | BEARER_CLASS_PAD;
break;
/* According to 22.030: All Data Async (7)*/
case 25:
cls = BEARER_CLASS_DATA_ASYNC;
break;
/* According to 22.030: All Sync (8) */
case 22:
cls = BEARER_CLASS_DATA_SYNC | BEARER_CLASS_PACKET;
break;
/* According to 22.030: All Data Sync (8) */
case 24:
cls = BEARER_CLASS_DATA_SYNC;
break;
/* According to 22.030: Telephony & All Sync services (1, 8) */
case 26:
cls = BEARER_CLASS_VOICE | BEARER_CLASS_DATA_SYNC |
BEARER_CLASS_PACKET;
break;
default:
break;
}
return cls;
}
const char *phone_number_to_string(const struct ofono_phone_number *ph)
{
static char buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 2];
if (ph->type == 145 && (strlen(ph->number) > 0) &&
ph->number[0] != '+') {
buffer[0] = '+';
strncpy(buffer + 1, ph->number, OFONO_MAX_PHONE_NUMBER_LENGTH);
buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 1] = '\0';
} else {
strncpy(buffer, ph->number, OFONO_MAX_PHONE_NUMBER_LENGTH + 1);
buffer[OFONO_MAX_PHONE_NUMBER_LENGTH + 1] = '\0';
}
return buffer;
}
void string_to_phone_number(const char *str, struct ofono_phone_number *ph)
{
if (str[0] == '+') {
strcpy(ph->number, str+1);
ph->type = 145; /* International */
} else {
strcpy(ph->number, str);
ph->type = 129; /* Local */
}
}
const char *cdma_phone_number_to_string(
const struct ofono_cdma_phone_number *ph)
{
static char buffer[OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH + 1];
strncpy(buffer, ph->number, OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH);
buffer[OFONO_CDMA_MAX_PHONE_NUMBER_LENGTH] = '\0';
return buffer;
}
void string_to_cdma_phone_number(const char *str,
struct ofono_cdma_phone_number *ph)
{
strcpy(ph->number, str);
}
gboolean valid_ussd_string(const char *str, gboolean call_in_progress)
{
int len = strlen(str);
if (!len)
return FALSE;
/*
* Return true if an MMI input string is to be sent as USSD.
*
* According to 3GPP TS 22.030, after checking the well-known
* supplementary service control, SIM control and manufacturer
* defined control codes, the terminal should check if the input
* should be sent as USSD according to the following rules:
*
* 1) Terminated by '#'
* 2) A short string of 1 or 2 digits
*
* As an exception, if a 2 digit string starts with a '1' and
* there are no calls in progress then this string is treated as
* a call setup request instead.
*/
if (str[len-1] == '#')
return TRUE;
if (!call_in_progress && len == 2 && str[0] == '1')
return FALSE;
if (len <= 2)
return TRUE;
return FALSE;
}
const char *ss_control_type_to_string(enum ss_control_type type)
{
switch (type) {
case SS_CONTROL_TYPE_ACTIVATION:
return "activation";
case SS_CONTROL_TYPE_REGISTRATION:
return "registration";
case SS_CONTROL_TYPE_QUERY:
return "interrogation";
case SS_CONTROL_TYPE_DEACTIVATION:
return "deactivation";
case SS_CONTROL_TYPE_ERASURE:
return "erasure";
}
return NULL;
}
#define NEXT_FIELD(str, dest) \
do { \
dest = str; \
\
str = strchrnul(str, '*'); \
if (*str) { \
*str = '\0'; \
str += 1; \
} \
} while (0) \
/*
* Note: The str will be modified, so in case of error you should
* throw it away and start over
*/
gboolean parse_ss_control_string(char *str, int *ss_type,
char **sc, char **sia,
char **sib, char **sic,
char **sid, char **dn)
{
int len = strlen(str);
int cur = 0;
char *c;
unsigned int i;
gboolean ret = FALSE;
/* Minimum is {*,#}SC# */
if (len < 4)
goto out;
if (str[0] != '*' && str[0] != '#')
goto out;
cur = 1;
if (str[1] != '*' && str[1] != '#' && (str[1] > '9' || str[1] < '0'))
goto out;
if (str[0] == '#' && str[1] == '*')
goto out;
if (str[1] == '#' || str[1] == '*')
cur = 2;
if (str[0] == '*' && str[1] == '*')
*ss_type = SS_CONTROL_TYPE_REGISTRATION;
else if (str[0] == '#' && str[1] == '#')
*ss_type = SS_CONTROL_TYPE_ERASURE;
else if (str[0] == '*' && str[1] == '#')
*ss_type = SS_CONTROL_TYPE_QUERY;
else if (str[0] == '*')
*ss_type = SS_CONTROL_TYPE_ACTIVATION;
else
*ss_type = SS_CONTROL_TYPE_DEACTIVATION;
/* Must have at least one other '#' */
c = strrchr(str+cur, '#');
if (c == NULL)
goto out;
*dn = c+1;
*c = '\0';
if (strlen(*dn) > 0 && !valid_phone_number_format(*dn))
goto out;
c = str+cur;
NEXT_FIELD(c, *sc);
/*
* According to 22.030 SC is 2 or 3 digits, there can be
* an optional digit 'n' if this is a call setup string,
* however 22.030 does not define any SC of length 3
* with an 'n' present
*/
if (strlen(*sc) < 2 || strlen(*sc) > 3)
goto out;
for (i = 0; i < strlen(*sc); i++)
if (!g_ascii_isdigit((*sc)[i]))
goto out;
NEXT_FIELD(c, *sia);
NEXT_FIELD(c, *sib);
NEXT_FIELD(c, *sic);
NEXT_FIELD(c, *sid);
if (*c == '\0')
ret = TRUE;
out:
return ret;
}
static const char *bearer_class_lut[] = {
"Voice",
"Data",
"Fax",
"Sms",
"DataSync",
"DataAsync",
"DataPad",
"DataPacket"
};
const char *bearer_class_to_string(enum bearer_class cls)
{
switch (cls) {
case BEARER_CLASS_VOICE:
return bearer_class_lut[0];
case BEARER_CLASS_DATA:
return bearer_class_lut[1];
case BEARER_CLASS_FAX:
return bearer_class_lut[2];
case BEARER_CLASS_SMS:
return bearer_class_lut[3];
case BEARER_CLASS_DATA_SYNC:
return bearer_class_lut[4];
case BEARER_CLASS_DATA_ASYNC:
return bearer_class_lut[5];
case BEARER_CLASS_PACKET:
return bearer_class_lut[6];
case BEARER_CLASS_PAD:
return bearer_class_lut[7];
case BEARER_CLASS_DEFAULT:
case BEARER_CLASS_SS_DEFAULT:
break;
};
return NULL;
}
const char *registration_status_to_string(int status)
{
switch (status) {
case NETWORK_REGISTRATION_STATUS_NOT_REGISTERED:
return "unregistered";
case NETWORK_REGISTRATION_STATUS_REGISTERED:
return "registered";
case NETWORK_REGISTRATION_STATUS_SEARCHING:
return "searching";
case NETWORK_REGISTRATION_STATUS_DENIED:
return "denied";
case NETWORK_REGISTRATION_STATUS_UNKNOWN:
return "unknown";
case NETWORK_REGISTRATION_STATUS_ROAMING:
return "roaming";
case NETWORK_REGISTRATION_STATUS_REGISTERED_SMS_EUTRAN:
return "registered";
case NETWORK_REGISTRATION_STATUS_ROAMING_SMS_EUTRAN:
return "roaming";
}
return "";
}
const char *registration_tech_to_string(int tech)
{
switch (tech) {
case ACCESS_TECHNOLOGY_GSM:
return "gsm";
case ACCESS_TECHNOLOGY_GSM_COMPACT:
return "gsm";
case ACCESS_TECHNOLOGY_UTRAN:
return "umts";
case ACCESS_TECHNOLOGY_GSM_EGPRS:
return "edge";
case ACCESS_TECHNOLOGY_UTRAN_HSDPA:
return "hspa";
case ACCESS_TECHNOLOGY_UTRAN_HSUPA:
return "hspa";
case ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA:
return "hspa";
case ACCESS_TECHNOLOGY_EUTRAN:
return "lte";
case ACCESS_TECHNOLOGY_NB_IOT_M1:
return "lte-cat-m1";
case ACCESS_TECHNOLOGY_NB_IOT_NB1:
return "lte-cat-nb1";
default:
return "";
}
}
gboolean is_valid_apn(const char *apn)
{
int i;
int last_period = -1;
if (apn == NULL)
return FALSE;
if (apn[0] == '.' || apn[0] == '\0')
return FALSE;
if (strlen(apn) > OFONO_GPRS_MAX_APN_LENGTH)
return FALSE;
for (i = 0; apn[i] != '\0'; i++) {
if (g_ascii_isalnum(apn[i]))
continue;
if (apn[i] == '-')
continue;
if (apn[i] == '.' && (i - last_period) > 1) {
last_period = i;
continue;
}
return FALSE;
}
return TRUE;
}
const char *ofono_uuid_to_str(const struct ofono_uuid *uuid)
{
static char buf[OFONO_SHA1_UUID_LEN * 2 + 1];
return encode_hex_own_buf(uuid->uuid, OFONO_SHA1_UUID_LEN, 0, buf);
}
void ofono_call_init(struct ofono_call *call)
{
memset(call, 0, sizeof(struct ofono_call));
call->cnap_validity = CNAP_VALIDITY_NOT_AVAILABLE;
call->clip_validity = CLIP_VALIDITY_NOT_AVAILABLE;
}
const char *call_status_to_string(enum call_status status)
{
switch (status) {
case CALL_STATUS_ACTIVE:
return "active";
case CALL_STATUS_HELD:
return "held";
case CALL_STATUS_DIALING:
return "dialing";
case CALL_STATUS_ALERTING:
return "alerting";
case CALL_STATUS_INCOMING:
return "incoming";
case CALL_STATUS_WAITING:
return "waiting";
case CALL_STATUS_DISCONNECTED:
return "disconnected";
}
return "unknown";
}
const char *gprs_proto_to_string(enum ofono_gprs_proto proto)
{
switch (proto) {
case OFONO_GPRS_PROTO_IP:
return "ip";
case OFONO_GPRS_PROTO_IPV6:
return "ipv6";
case OFONO_GPRS_PROTO_IPV4V6:
return "dual";
};
return NULL;
}
gboolean gprs_proto_from_string(const char *str, enum ofono_gprs_proto *proto)
{
if (g_str_equal(str, "ip")) {
*proto = OFONO_GPRS_PROTO_IP;
return TRUE;
} else if (g_str_equal(str, "ipv6")) {
*proto = OFONO_GPRS_PROTO_IPV6;
return TRUE;
} else if (g_str_equal(str, "dual")) {
*proto = OFONO_GPRS_PROTO_IPV4V6;
return TRUE;
}
return FALSE;
}
const char *gprs_auth_method_to_string(enum ofono_gprs_auth_method auth)
{
switch (auth) {
case OFONO_GPRS_AUTH_METHOD_CHAP:
return "chap";
case OFONO_GPRS_AUTH_METHOD_PAP:
return "pap";
case OFONO_GPRS_AUTH_METHOD_NONE:
return "none";
};
return NULL;
}
gboolean gprs_auth_method_from_string(const char *str,
enum ofono_gprs_auth_method *auth)
{
if (g_str_equal(str, "chap")) {
*auth = OFONO_GPRS_AUTH_METHOD_CHAP;
return TRUE;
} else if (g_str_equal(str, "pap")) {
*auth = OFONO_GPRS_AUTH_METHOD_PAP;
return TRUE;
} else if (g_str_equal(str, "none")) {
*auth = OFONO_GPRS_AUTH_METHOD_NONE;
return TRUE;
}
return FALSE;
}