From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============9201058847548339146==" MIME-Version: 1.0 From: Denis Kenzior Subject: Re: [PATCH v2, 3/7] cdma-sms: Add CDMA SMS Support Date: Tue, 04 Jan 2011 15:17:50 -0600 Message-ID: <4D238E7E.3020200@gmail.com> In-Reply-To: <1292976149-15598-4-git-send-email-lei.2.yu@nokia.com> List-Id: To: ofono@ofono.org --===============9201058847548339146== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Hi Lei, On 12/21/2010 06:02 PM, Lei Yu wrote: > --- > Makefile.am | 3 +- > src/cdma-smsutil.c | 484 ++++++++++++++++++++++++++++++++++++++++++++++= ++++++ > src/cdma-smsutil.h | 264 ++++++++++++++++++++++++++++ > 3 files changed, 750 insertions(+), 1 deletions(-) > create mode 100644 src/cdma-smsutil.c > create mode 100644 src/cdma-smsutil.h > = > diff --git a/Makefile.am b/Makefile.am > index aa00016..e85f522 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -319,7 +319,8 @@ src_ofonod_SOURCES =3D $(gdbus_sources) $(builtin_sou= rces) src/ofono.ver \ > src/radio-settings.c src/stkutil.h src/stkutil.c \ > src/nettime.c src/stkagent.c src/stkagent.h \ > src/simfs.c src/simfs.h src/audio-settings.c \ > - src/smsagent.c src/smsagent.h src/ctm.c > + src/smsagent.c src/smsagent.h src/ctm.c \ > + src/cdma-smsutil.c Make sure to include src/cdma-smsutil.h as well. I'm still not really familiar with the CDMA SMS pdu spec, so take my comments with a grain of salt ;) > = > src_ofonod_LDADD =3D $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LI= BS@ -ldl > = > diff --git a/src/cdma-smsutil.c b/src/cdma-smsutil.c > new file mode 100644 > index 0000000..b80002c > --- /dev/null > +++ b/src/cdma-smsutil.c > @@ -0,0 +1,484 @@ > +/* > + * > + * oFono - Open Source Telephony > + * > + * Copyright (C) 2010 Nokia 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 > +#endif > + > +#define _GNU_SOURCE > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "cdma-smsutil.h" > + > +/* > + * Mapping from binary DTMF code to the digit it represents. > + * As defined in Table 2.7.1.3.2.4-4 of 3GPP2 C.S0005-E v2.0. > + * Note, 0 is NOT a valid value and not mapped to > + * any valid DTMF digit. > + */ > +const char cdma_sms_dtmf_digits[13] =3D {0, '1', '2', '3', '4', '5', '6'= , '7', > + '8', '9', '0', '*', '#'}; > + > + > +/* Unpacks the byte stream. */ > +static guint32 bit_field_unpack(const guint8 *buf, guint32 offset, > + guint32 nbit) > +{ > + guint32 val =3D 0; > + guint32 byteIndex; > + guint32 remainder; > + > + if (buf =3D=3D NULL) > + return 0; > + > + byteIndex =3D offset >> 3; > + remainder =3D (offset & 0x7); > + > + if (remainder !=3D 0) { > + /* > + * The field to be unpacked does not start at the byte > + * boundary. Retrieve those bits first. > + */ > + guint32 mask; > + > + mask =3D (1 << (8 - remainder)) - 1; > + val =3D buf[byteIndex] & mask; > + > + /* The field is within current byte */ > + if (nbit < (8 - remainder)) > + return (val >> (8 - remainder - nbit)); > + > + /* The field at least spans till end of the byte. */ > + nbit -=3D (8 - remainder); > + byteIndex++; > + } > + > + /* Unpack rest of the bits in the field in 8-bit chunk. */ > + while (nbit >=3D 8) { > + val =3D (val << 8) | buf[byteIndex]; > + nbit -=3D 8; > + byteIndex++; > + } > + > + /* If still some left, unpack the last remaining bits. */ > + if (nbit > 0) > + val =3D (val << nbit) | (buf[byteIndex] >> (8 - nbit)); > + > + return val; > +} So it looks to me like this function takes arbitrary bit fields from a stream. Is this a 'peculiarity' of the address field or will this be used elsewhere? This looks like a really inefficient function to call for every field, so it might makes things easier if the offsets were simply hardcoded... > + > +/* Convert CDMA DTMF digits into a string */ > +static gboolean cdma_sms_dtmf_to_ascii(char *buf, const char *addr, > + guint8 num_fields) > +{ > + guint8 index; > + guint8 value; > + > + if (buf =3D=3D NULL || addr =3D=3D NULL) > + return FALSE; > + > + for (index =3D 0; index < num_fields; index++) { > + if ((addr[index] <=3D 0) || (addr[index] > 12)) > + return FALSE; /* Invalid digit in address field */ > + > + value =3D (guint8) addr[index]; > + buf[index] =3D cdma_sms_dtmf_digits[value]; > + } > + > + buf[index] =3D 0; /* Make it NULL terminated string */ > + > + return TRUE; > +} > + > +char *cdma_sms_address_to_string(const struct cdma_sms_address *addr) > +{ > + char *buf; > + > + if (addr =3D=3D NULL) > + return NULL; > + > + if (addr->digit_mode !=3D DTMF_4_BIT) > + return NULL; /* TODO: Only support DTMF_4_BIT currently */ > + > + buf =3D g_new(char, addr->num_fields + 1); > + if (buf =3D=3D NULL) > + return NULL; > + > + if (!cdma_sms_dtmf_to_ascii(buf, addr->address, addr->num_fields)) { > + g_free(buf); > + return NULL; > + } > + > + return buf; > +} Does the address really need to be malloced? We have generally tried to avoid this in the past. The address usually goes directly to a dbus_message which takes care of copying the contents. Since oFono is not multi-threaded, using a static buffer might be sufficient here. > + > +/* Decode Address parameter record */ > +static gboolean cdma_sms_decode_addr(const unsigned char *buf, int len, > + struct cdma_sms_address *addr) > +{ > + guint32 bit_offset =3D 0; > + guint8 chari_len; > + guint32 total_num_bits =3D len * 8; > + guint8 index; > + > + if (len <=3D 0 || buf =3D=3D NULL || addr =3D=3D NULL) > + return FALSE; > + > + addr->digit_mode =3D (enum cdma_sms_digit_mode) Explicit casts should be avoided > + bit_field_unpack(buf, 0, 1); > + bit_offset +=3D 1; Try to logically separate the fields by using an empty line between each one. > + addr->number_mode =3D (guint8) bit_field_unpack(buf, bit_offset, 1); > + bit_offset +=3D 1; > + > + if (addr->digit_mode =3D=3D CODE_8_BIT) { > + addr->number_type =3D (guint8) > + bit_field_unpack(buf, bit_offset, 3); > + bit_offset +=3D 3; > + > + if (addr->number_mode =3D=3D 0) { > + if (bit_offset + 4 > total_num_bits) > + return FALSE; > + > + addr->number_plan =3D (enum cdma_sms_numbering_plan) > + bit_field_unpack(buf, bit_offset, 4); > + bit_offset +=3D 4; > + } > + } > + > + if ((bit_offset + 8) > total_num_bits) > + return FALSE; > + > + addr->num_fields =3D (guint8) bit_field_unpack(buf, bit_offset, 8); > + bit_offset +=3D 8; > + > + if (addr->digit_mode =3D=3D DTMF_4_BIT) > + chari_len =3D 4; > + else > + chari_len =3D 8; > + > + if ((bit_offset + chari_len * addr->num_fields) > total_num_bits) > + return FALSE; > + > + for (index =3D 0; index < addr->num_fields; index++) { > + addr->address[index] =3D (char) bit_field_unpack(buf, > + bit_offset, > + chari_len); > + bit_offset +=3D chari_len; > + } > + > + return TRUE; > +} > + > +char *cdma_sms_decode_text(struct cdma_sms_ud *ud) > +{ > + char *buf; > + > + if (ud =3D=3D NULL) > + return NULL; > + > + /* TODO: Only support MSG_ENCODING_7BIT_ASCII currently */ > + if (ud->msg_encoding !=3D MSG_ENCODING_7BIT_ASCII) > + return NULL; > + > + buf =3D g_new(char, ud->num_fields + 1); > + if (buf =3D=3D NULL) > + return NULL; > + > + memcpy(buf, ud->chari, ud->num_fields); > + buf[ud->num_fields] =3D 0; /* Make it NULL terminated string */ > + > + return buf; > +} > + > +/* Decode User Data */ > +static gboolean cdma_sms_decode_ud(const unsigned char *buf, int len, > + struct cdma_sms_ud *ud) > +{ > + guint32 bit_offset =3D 0; > + guint8 chari_len =3D 0; > + guint32 total_num_bits =3D len * 8; > + guint8 index; > + enum cdma_sms_message_encoding msg_encoding; > + > + if (buf =3D=3D NULL || ud =3D=3D NULL) > + return FALSE; > + > + if (total_num_bits < 13) > + return FALSE; > + > + msg_encoding =3D (enum cdma_sms_message_encoding) > + bit_field_unpack(buf, bit_offset, 5); > + ud->msg_encoding =3D msg_encoding; > + bit_offset +=3D 5; > + > + if (ud->msg_encoding =3D=3D MSG_ENCODING_EXTENDED_PROTOCOL_MSG || > + ud->msg_encoding =3D=3D MSG_ENCODING_GSM_DATA_CODING) { > + /* Skip message type field */ > + /* TODO: Add support for message type field */ > + bit_offset +=3D 8; > + } > + > + if (bit_offset + 8 > total_num_bits) > + return FALSE; > + > + ud->num_fields =3D (guint8) bit_field_unpack(buf, bit_offset, 8); > + bit_offset +=3D 8; > + > + switch (msg_encoding) { > + case MSG_ENCODING_OCTET: > + chari_len =3D 8; > + break; > + case MSG_ENCODING_EXTENDED_PROTOCOL_MSG: > + return FALSE; /* TODO */ > + case MSG_ENCODING_7BIT_ASCII: > + case MSG_ENCODING_IA5: > + chari_len =3D 7; > + break; > + case MSG_ENCODING_UNICODE: > + case MSG_ENCODING_SHIFT_JIS: > + case MSG_ENCODING_KOREAN: > + return FALSE; /* TODO */ > + case MSG_ENCODING_LATIN_HEBREW: > + case MSG_ENCODING_LATIN: > + chari_len =3D 8; > + break; > + case MSG_ENCODING_GSM_7BIT: > + chari_len =3D 7; > + break; > + case MSG_ENCODING_GSM_DATA_CODING: > + return FALSE; /* TODO */ > + } > + > + if (chari_len =3D=3D 0) > + return FALSE; > + > + if (bit_offset + chari_len * ud->num_fields > total_num_bits) > + return FALSE; > + > + for (index =3D 0; index < ud->num_fields; index++) { > + ud->chari[index] =3D (guint8) bit_field_unpack(buf, > + bit_offset, > + chari_len); > + bit_offset +=3D chari_len; > + } > + > + return TRUE; > +} > + > +/* Decode Message Identifier */ > +static gboolean cdma_sms_decode_message_id(const unsigned char *buf, int= len, > + struct cdma_sms_identifier *id) > +{ > + guint32 bit_offset =3D 0; > + > + if (buf =3D=3D NULL || id =3D=3D NULL) > + return FALSE; > + > + if (len !=3D 3) > + return FALSE; > + > + id->msg_type =3D (enum cdma_sms_msg_type) > + bit_field_unpack(buf, bit_offset, 4); > + bit_offset +=3D 4; > + id->msg_id =3D (guint16) bit_field_unpack(buf, bit_offset, 16); > + bit_offset +=3D 16; > + id->header_ind =3D (gboolean) bit_field_unpack(buf, bit_offset, 1); > + > + return TRUE; > +} > + > +/* Decode Bearer Data */ > +static gboolean cdma_sms_decode_bearer_data(const unsigned char *buf, in= t len, > + struct cdma_sms_bearer_data *bearer_data) > +{ > + gboolean ret =3D TRUE; > + enum cdma_sms_subparam_id subparam_id; > + guint8 subparam_len; > + > + if (buf =3D=3D NULL || bearer_data =3D=3D NULL) > + return FALSE; > + Have you looked at how STK pdus are decoded in stkutil.c, parse_dataobj() in particular. Looking at the basic code structure so far, that design pattern could be (or not) a really nice fit here and save you some kLoC in the future. > + while (len !=3D 0) { > + > + if (len < 2) > + return FALSE; > + > + subparam_id =3D (enum cdma_sms_subparam_id) > + bit_field_unpack(buf, 0, 8); > + buf +=3D 1; > + subparam_len =3D (guint8) bit_field_unpack(buf, 0, 8); > + buf +=3D 1; > + > + len -=3D 2; > + > + if (len < subparam_len) > + return FALSE; > + > + switch (subparam_id) { > + case CDMA_SMS_SUBPARAM_ID_MESSAGE_ID: > + ret =3D cdma_sms_decode_message_id(buf, subparam_len, > + &bearer_data->id); > + set_bitmap(&bearer_data->subparam_bitmap, > + CDMA_SMS_SUBPARAM_ID_MESSAGE_ID); > + break; > + case CDMA_SMS_SUBPARAM_ID_USER_DATA: > + ret =3D cdma_sms_decode_ud(buf, subparam_len, > + &bearer_data->ud); > + set_bitmap(&bearer_data->subparam_bitmap, > + CDMA_SMS_SUBPARAM_ID_USER_DATA); > + break; > + case CDMA_SMS_SUBPARAM_ID_USER_RESPONSE_CODE: > + case CDMA_SMS_SUBPARAM_ID_MC_TIME_STAMP: > + case CDMA_SMS_SUBPARAM_ID_VALIDITY_PERIOD_ABSOLUTE: > + case CDMA_SMS_SUBPARAM_ID_VALIDITY_PERIOD_RELATIVE: > + case CDMA_SMS_SUBPARAM_ID_DEFERRED_DELIVERY_TIME_ABSOLUTE: > + case CDMA_SMS_SUBPARAM_ID_DEFERRED_DELIVERY_TIME_RELATIVE: > + case CDMA_SMS_SUBPARAM_ID_PRIORITY_INDICATOR: > + case CDMA_SMS_SUBPARAM_ID_PRIVACY_INDICATOR: > + case CDMA_SMS_SUBPARAM_ID_REPLY_OPTION: > + case CDMA_SMS_SUBPARAM_ID_NUMBER_OF_MESSAGES: > + case CDMA_SMS_SUBPARAM_ID_ALERT_ON_MESSAGE_DELIVERY: > + case CDMA_SMS_SUBPARAM_ID_LANGUAGE_INDICATOR: > + case CDMA_SMS_SUBPARAM_ID_CALL_BACK_NUMBER: > + case CDMA_SMS_SUBPARAM_ID_MESSAGE_DISPLAY_MODE: > + case CDMA_SMS_SUBPARAM_ID_MULTIPLE_ENCODING_USER_DATA: > + case CDMA_SMS_SUBPARAM_ID_MESSAGE_DEPOSIT_INDEX: > + case CDMA_SMS_SUBPARAM_ID_SERVICE_CATEGORY_PROGRAM_DATA: > + case CDMA_SMS_SUBPARAM_ID_SERVICE_CATEGORY_PROGRAM_RESULT: > + case CDMA_SMS_SUBPARAM_ID_MESSAGE_STATUS: > + case CDMA_SMS_SUBPARAM_ID_TP_FAILURE_CAUSE: > + case CDMA_SMS_SUBPARAM_ID_ENHANCED_VMN: > + case CDMA_SMS_SUBPARAM_ID_ENHANCED_VMN_ACK: > + /* > + * TODO: Ignore any unsupported parameter. > + * Also ignore any un-recognized parameter for > + * future standard revision. > + */ > + break; > + } > + > + if (ret =3D=3D FALSE) > + return FALSE; > + > + len -=3D subparam_len; > + buf +=3D subparam_len; > + } > + > + return TRUE; > +} > + > +static gboolean cdma_sms_p2p_decode(const unsigned char *pdu, int len, > + struct cdma_sms *incoming) > +{ > + gboolean ret =3D TRUE; > + enum cdma_sms_param_id rec_id; > + guint8 rec_len; > + > + if (pdu =3D=3D NULL || incoming =3D=3D NULL) > + return FALSE; > + > + while (len !=3D 0) { > + > + if (len <=3D 2) > + return FALSE; > + > + rec_id =3D (enum cdma_sms_param_id) bit_field_unpack(pdu, 0, 8); > + pdu +=3D 1; > + rec_len =3D (guint8) bit_field_unpack(pdu, 0, 8); > + pdu +=3D 1; > + > + len -=3D 2; > + > + if (len < rec_len) > + return FALSE; > + > + switch (rec_id) { > + case CDMA_SMS_PARAM_ID_TELESERVICE_IDENTIFIER: > + incoming->p2p_msg.teleservice_id =3D > + (enum cdma_sms_teleservice_id) > + bit_field_unpack(pdu, 0, 16); > + set_bitmap(&incoming->p2p_msg.param_bitmap, > + CDMA_SMS_PARAM_ID_TELESERVICE_IDENTIFIER); > + break; > + case CDMA_SMS_PARAM_ID_SERVICE_CATEGORY: > + break; /* TODO */ > + case CDMA_SMS_PARAM_ID_ORIGINATING_ADDRESS: > + ret =3D cdma_sms_decode_addr(pdu, rec_len, > + &incoming->p2p_msg.oaddr); > + set_bitmap(&incoming->p2p_msg.param_bitmap, > + CDMA_SMS_PARAM_ID_ORIGINATING_ADDRESS); > + break; > + case CDMA_SMS_PARAM_ID_ORIGINATING_SUBADDRESS: > + case CDMA_SMS_PARAM_ID_DESTINATION_ADDRESS: > + case CDMA_SMS_PARAM_ID_DESTINATION_SUBADDRESS: > + case CDMA_SMS_PARAM_ID_BEARER_REPLY_OPTION: > + case CDMA_SMS_PARAM_ID_CAUSE_CODE: > + break; /* TODO */ > + case CDMA_SMS_PARAM_ID_BEARER_DATA: > + ret =3D cdma_sms_decode_bearer_data(pdu, rec_len, > + &incoming->p2p_msg.bearer_data); > + set_bitmap(&incoming->p2p_msg.param_bitmap, > + CDMA_SMS_PARAM_ID_BEARER_DATA); > + break; > + } > + > + if (!ret) > + return FALSE; > + > + len -=3D rec_len; > + pdu +=3D rec_len; > + } > + > + return TRUE; > +} > + > +gboolean cdma_sms_decode(const unsigned char *pdu, int len, > + struct cdma_sms *incoming) > +{ > + gboolean ret =3D FALSE; The preference is not to initialize this variable. If you can't find a nicer way around it, and if the compiler complains, then use the uninitialized_var() trick from smsutil.c. > + > + if ((len =3D=3D 0) || (pdu =3D=3D NULL) || (incoming =3D=3D NULL)) > + return FALSE; > + > + incoming->type =3D (enum cdma_sms_tp_msg_type) > + bit_field_unpack(pdu, 0, 8); > + pdu +=3D 1; > + len -=3D 1; > + > + switch (incoming->type) { > + case CDMA_SMS_P2P: > + ret =3D cdma_sms_p2p_decode(pdu, len, incoming); I suggest a simple return cdma_sms_p2p_decode() here.. > + break; > + case CDMA_SMS_BCAST: > + case CDMA_SMS_ACK: > + /* TODO: Not supported yet */ > + ret =3D FALSE; > + break; and a return FALSE here > + } > + > + return ret; and a return FALSE here. > +} > diff --git a/src/cdma-smsutil.h b/src/cdma-smsutil.h > new file mode 100644 > index 0000000..bfe2abb > --- /dev/null > +++ b/src/cdma-smsutil.h > @@ -0,0 +1,264 @@ > +/* > + * > + * oFono - Open Source Telephony > + * > + * Copyright (C) 2010 Nokia 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 > + * > + */ > + > +/* 3GPP2 C.S0015-B v2.0, Table 3.4-1 */ > +enum cdma_sms_tp_msg_type { > + CDMA_SMS_P2P =3D 0, > + CDMA_SMS_BCAST =3D 1, > + CDMA_SMS_ACK =3D 2 > +}; > + > +/* 3GPP2 X.S0004-550-E, Section 2.256 */ > +enum cdma_sms_teleservice_id { > + TELESERVICE_CMT91 =3D 4096, > + TELESERVICE_WPT =3D 4097, > + TELESERVICE_WMT =3D 4098, > + TELESERVICE_VMN =3D 4099, > + TELESERVICE_WAP =3D 4100, > + TELESERVICE_WEMT =3D 4101, > + TELESERVICE_SCPT =3D 4102, > + TELESERVICE_CATPT =3D 4103 > +}; > + > +/* 3GPP2 C.S0005-E v2.0 Table 2.7.1.3.2.4-2 */ > +enum cdma_sms_digi_number_type { > + CDMA_SMS_NUM_TYPE_UNKNOWN =3D 0, > + CDMA_SMS_NUM_TYPE_INTERNATIONAL_NUMBER =3D 1, > + CDMA_SMS_NUM_TYPE_NATIONAL_NUMBER =3D 2, > + CDMA_SMS_NUM_TYPE_NETWORK_SPECIFIC_NUMBER =3D 3, > + CDMA_SMS_NUM_TYPE_SUBSCRIBER_NUMBER =3D 4, > + /* Reserved 5 */ > + CDMA_SMS_NUM_TYPE_ABBREVIATED_NUMBER =3D 6 > + /* Reserved 7 */ > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 3.4.3.3-1 */ > +enum cdma_sms_data_network_number_type { > + CDMA_SMS_NETWORK_NUM_TYPE_UNKNOWN =3D 0, > + CDMA_SMS_NETWORK_TYPE_INTERNET_PROTOCOL =3D 1, > + CDMA_SMS_NETWORK_TYPE_INTERNET_EMAIL_ADDRESS =3D 2, > + /* All Other Values Reserved */ > +}; > + > +/* 3GPP2 C.S0005-E v2.0 Table 2.7.1.3.2.4-3 */ > +enum cdma_sms_numbering_plan { > + CDMA_SMS_NUMBERING_PLAN_UNKNOWN =3D 0, > + CDMA_SMS_NUMBERING_PLAN_ISDN =3D 1, > + CDMA_SMS_NUMBERING_PLAN_DATA =3D 3, > + CDMA_SMS_NUMBERING_PLAN_TELEX =3D 4, > + CDMA_SMS_NUMBERING_PLAN_PRIVATE =3D 9, > + CDMA_SMS_NUMBERING_PLAN_RESERVED =3D 15 > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 4.5.1-1 */ > +enum cdma_sms_msg_type { > + CDMA_SMS_RESERVED =3D 0, > + CDMA_SMS_DELIVER =3D 1, > + CDMA_SMS_SUBMIT =3D 2, > + CDMA_SMS_CANCEL =3D 3, > + CDMA_SMS_DELIVER_ACK =3D 4, > + CDMA_SMS_USER_ACK =3D 5, > + CDMA_SMS_READ_ACK =3D 6, > +}; > + > +/* C.R1001-G_v1.0 Table 9.1-1 */ > +enum cdma_sms_message_encoding { > + MSG_ENCODING_OCTET =3D 0, > + MSG_ENCODING_EXTENDED_PROTOCOL_MSG =3D 1, > + MSG_ENCODING_7BIT_ASCII =3D 2, > + MSG_ENCODING_IA5 =3D 3, > + MSG_ENCODING_UNICODE =3D 4, > + MSG_ENCODING_SHIFT_JIS =3D 5, > + MSG_ENCODING_KOREAN =3D 6, > + MSG_ENCODING_LATIN_HEBREW =3D 7, > + MSG_ENCODING_LATIN =3D 8, > + MSG_ENCODING_GSM_7BIT =3D 9, > + MSG_ENCODING_GSM_DATA_CODING =3D 10 > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 3.4.3-1 */ > +enum cdma_sms_param_id { > + CDMA_SMS_PARAM_ID_TELESERVICE_IDENTIFIER =3D 0x00, > + CDMA_SMS_PARAM_ID_SERVICE_CATEGORY =3D 0x01, > + CDMA_SMS_PARAM_ID_ORIGINATING_ADDRESS =3D 0x02, > + CDMA_SMS_PARAM_ID_ORIGINATING_SUBADDRESS =3D 0x03, > + CDMA_SMS_PARAM_ID_DESTINATION_ADDRESS =3D 0x04, > + CDMA_SMS_PARAM_ID_DESTINATION_SUBADDRESS =3D 0x05, > + CDMA_SMS_PARAM_ID_BEARER_REPLY_OPTION =3D 0x06, > + CDMA_SMS_PARAM_ID_CAUSE_CODE =3D 0x07, > + CDMA_SMS_PARAM_ID_BEARER_DATA =3D 0x08 > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 4.5-1 */ > +enum cdma_sms_subparam_id { > + CDMA_SMS_SUBPARAM_ID_MESSAGE_ID =3D 0x00, > + CDMA_SMS_SUBPARAM_ID_USER_DATA =3D 0x01, > + CDMA_SMS_SUBPARAM_ID_USER_RESPONSE_CODE =3D 0x02, > + CDMA_SMS_SUBPARAM_ID_MC_TIME_STAMP =3D 0x03, > + CDMA_SMS_SUBPARAM_ID_VALIDITY_PERIOD_ABSOLUTE =3D 0x04, > + CDMA_SMS_SUBPARAM_ID_VALIDITY_PERIOD_RELATIVE =3D 0x05, > + CDMA_SMS_SUBPARAM_ID_DEFERRED_DELIVERY_TIME_ABSOLUTE =3D 0x06, > + CDMA_SMS_SUBPARAM_ID_DEFERRED_DELIVERY_TIME_RELATIVE =3D 0x07, > + CDMA_SMS_SUBPARAM_ID_PRIORITY_INDICATOR =3D 0x08, > + CDMA_SMS_SUBPARAM_ID_PRIVACY_INDICATOR =3D 0x09, > + CDMA_SMS_SUBPARAM_ID_REPLY_OPTION =3D 0x0A, > + CDMA_SMS_SUBPARAM_ID_NUMBER_OF_MESSAGES =3D 0x0B, > + CDMA_SMS_SUBPARAM_ID_ALERT_ON_MESSAGE_DELIVERY =3D 0x0C, > + CDMA_SMS_SUBPARAM_ID_LANGUAGE_INDICATOR =3D 0x0D, > + CDMA_SMS_SUBPARAM_ID_CALL_BACK_NUMBER =3D 0x0E, > + CDMA_SMS_SUBPARAM_ID_MESSAGE_DISPLAY_MODE =3D 0x0F, > + CDMA_SMS_SUBPARAM_ID_MULTIPLE_ENCODING_USER_DATA =3D 0x10, > + CDMA_SMS_SUBPARAM_ID_MESSAGE_DEPOSIT_INDEX =3D 0x11, > + CDMA_SMS_SUBPARAM_ID_SERVICE_CATEGORY_PROGRAM_DATA =3D 0x12, > + CDMA_SMS_SUBPARAM_ID_SERVICE_CATEGORY_PROGRAM_RESULT =3D 0x13, > + CDMA_SMS_SUBPARAM_ID_MESSAGE_STATUS =3D 0x14, > + CDMA_SMS_SUBPARAM_ID_TP_FAILURE_CAUSE =3D 0x15, > + CDMA_SMS_SUBPARAM_ID_ENHANCED_VMN =3D 0x16, > + CDMA_SMS_SUBPARAM_ID_ENHANCED_VMN_ACK =3D 0x17 > +}; > + > +/* 3GPP2 C.R1001-G Table 9.3.1-1 */ > +enum cdma_sms_service_category { > + SERVICE_CAT_EMERGENCY_BROADCAST =3D 1, > + SERVICE_CAT_ADMINISTRATIVE =3D 2, > + SERVICE_CAT_MAINTENANCE =3D 3, > + SERVICE_CAT_GENERALNEWSLOCAL =3D 4, Please use the underscore some more, e.g. GENERAL_NEWS_LOCAL > + SERVICE_CAT_GENERALNEWSREGIONAL =3D 5, > + SERVICE_CAT_GENERALNEWSNATIONAL =3D 6, > + SERVICE_CAT_GENERALNEWSINTERNATIONAL =3D 7, > + SERVICE_CAT_BUSINESSFINALNEWSLOCAL =3D 8, > + SERVICE_CAT_BUSINESSFINALNEWSREGIONAL =3D 9, > + SERVICE_CAT_BUSINESSFINALNEWSNATIONAL =3D 10, > + SERVICE_CAT_BUSINESSFINALNEWSINTNL =3D 11, > + SERVICE_CAT_SPORTSNEWSLOCAL =3D 12, > + SERVICE_CAT_SPORTSNEWSREGIONAL =3D 13, > + SERVICE_CAT_SPORTSNEWSNATIONAL =3D 14, > + SERVICE_CAT_SPORTSNEWSINTERNATIONAL =3D 15, > + SERVICE_CAT_ENTERTAINMENTNEWSLOCAL =3D 16, > + SERVICE_CAT_ENTERTAINMENTNEWSREGIONAL =3D 17, > + SERVICE_CAT_ENTERTAINMENTNEWSNATIONAL =3D 18, > + SERVICE_CAT_ENTERTAINMENTNEWSINTERNATIONAL =3D 19, > + SERVICE_CAT_ENTERTAINMENTNEWSLOCALWEATHER =3D 20, > + SERVICE_CAT_AREATRAFFICREPORTS =3D 21, > + SERVICE_CAT_LOCALAIRTPORTFLIGHTSCHEDULES =3D 22, > + SERVICE_CAT_RESTURANTS =3D 23, Is this mis-spelled? > + SERVICE_CAT_LODGINGS =3D 24, > + SERVICE_CAT_RETAILDIRECTORYADVERTISEMENTS =3D 25, > + SERVICE_CAT_ADVERTISEMENTS =3D 26, > + SERVICE_CAT_STOCKQUOTES =3D 27, > + SERVICE_CAT_EMPLOYMENTOPPORTUNITIES =3D 28, > + SERVICE_CAT_MEDICALHEALTHHOSPITALS =3D 29, > + SERVICE_CAT_TECHNOLOGYNEWS =3D 30, > + SERVICE_CAT_MULTICATEGORY =3D 31, > + SERVICE_CAT_CAPT =3D 32 > +}; > + > +enum cdma_sms_digit_mode { > + DTMF_4_BIT =3D 0, > + CODE_8_BIT =3D 1 > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 3.4.3.3 */ > +struct cdma_sms_address { > + enum cdma_sms_digit_mode digit_mode; > + guint8 number_mode; > + guint8 number_type; > + enum cdma_sms_numbering_plan number_plan; > + guint8 num_fields; > + char address[256]; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 3.4.3.6 */ > +struct cdma_sms_cause_code { > + guint8 reply_seq; > + guint8 error_class; > + guint8 cause_code; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 4.5.1 */ > +struct cdma_sms_identifier { > + enum cdma_sms_msg_type msg_type; > + guint16 msg_id; > + gboolean header_ind; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 4.5.2 */ > +struct cdma_sms_ud { > + enum cdma_sms_message_encoding msg_encoding; > + guint8 num_fields; > + guint8 chari[512]; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 4.5 */ > +struct cdma_sms_bearer_data { > + guint32 subparam_bitmap; > + struct cdma_sms_identifier id; > + struct cdma_sms_ud ud; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 3.4.2.1-1. */ > +struct cdma_sms_p2p_msg { > + guint32 param_bitmap; > + enum cdma_sms_teleservice_id teleservice_id; > + struct cdma_sms_address oaddr; > + struct cdma_sms_bearer_data bearer_data; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 3.4.2.2-1 */ > +struct cdma_sms_broadcast_msg { > + enum cdma_sms_service_category service_category; > + struct cdma_sms_bearer_data bearer_data; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Table 3.4.2.3-1 */ > +struct cdma_sms_ack_msg { > + struct cdma_sms_address daddr; > + struct cdma_sms_cause_code cause_code; > +}; > + > +/* 3GPP2 C.S0015-B v2.0 Section 3.4.1 */ > +struct cdma_sms { > + enum cdma_sms_tp_msg_type type; > + union { > + struct cdma_sms_p2p_msg p2p_msg; > + struct cdma_sms_broadcast_msg broadcast_msg; > + struct cdma_sms_ack_msg ack_msg; > + }; > +}; > + > +static inline gboolean check_bitmap(guint32 bitmap, guint32 pos) > +{ > + guint32 mask =3D 0x1 << pos; > + return bitmap & mask ? TRUE : FALSE; > +} > + I don't see this function being used by this patch. Does it logically belong to a later patch? > +static inline void set_bitmap(guint32 *bitmap, guint32 pos) > +{ > + if (bitmap =3D=3D NULL) > + return; > + > + *bitmap =3D *bitmap | (1 << pos); > +} Why are these functions defined in the header? Are they meant to be used elsewhere? > + > +gboolean cdma_sms_decode(const unsigned char *pdu, int len, > + struct cdma_sms *out); > +char *cdma_sms_decode_text(struct cdma_sms_ud *ud); > +char *cdma_sms_address_to_string(const struct cdma_sms_address *addr); Regards, -Denis --===============9201058847548339146==--