summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-10-25 10:35:26 +0000
committertick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-10-25 10:35:26 +0000
commit9e6cee624e011a163892e8798fb904cb6f2e804a (patch)
tree3cd7f4d69374c4bff10631eaf3e8f3f2dda7e8dc
parenta4ee05b6942d5b82269a1a0ea453b5467e44b96e (diff)
Adding decoder TP-DCS, and it's based on 3GPP TS23.038 Clause 4. (Erin Yueh)
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3265 99fdad57-331a-0410-800a-d7fa5415bdb3
-rw-r--r--include/gsmd/usock.h54
-rw-r--r--src/gsmd/sms_pdu.c100
-rw-r--r--src/util/event.c2
-rw-r--r--src/util/shell.c2
4 files changed, 158 insertions, 0 deletions
diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h
index 66cdf48..f37cfa8 100644
--- a/include/gsmd/usock.h
+++ b/include/gsmd/usock.h
@@ -121,6 +121,58 @@ enum gsmd_sms_alphabet {
ALPHABET_RESERVED = (0x11<<2),
};
+/* bit 1 & bit0 */
+enum gsmd_sms_msg_class {
+ MSG_CLASS_CLASS0 = 0,
+ MSG_CLASS_CLASS1 = 1,
+ MSG_CLASS_CLASS2 = 2,
+ MSG_CLASS_CLASS3 = 3,
+ MSG_CLASS_NONE = 4,
+};
+
+/* bit 3 & bit 2*/
+enum gsmd_sms_alphabet_type {
+ SMS_ALPHABET_7_BIT_DEFAULT = 0,
+ SMS_ALPHABET_8_BIT = 1,
+ SMS_ALPHABET_UCS2 = 2,
+ SMS_ALPHABET_RESESRVED = 3,
+};
+
+enum gsmd_sms_msg_compressed {
+ NOT_COMPRESSED = 0,
+ COMPRESSED = 1,
+};
+
+/* message waiting indication */
+enum gsmd_sms_msg_waiting_group {
+ MESSAGE_WAITING_NONE = 0,
+ MESSAGE_WAITING_DISCARD = 1,
+ MESSAGE_WAITING_STORE = 2,
+ MESSAGE_WAITING_NONE_1111 = 3,
+};
+
+enum gsmd_sms_msg_waiting_type {
+ MESSAGE_WAITING_VOICEMAIL = 0,
+ MESSAGE_WAITING_FAX = 1,
+ MESSAGE_WAITING_EMAIL = 2,
+ MESSAGE_WAITING_OTHER = 3,
+};
+
+enum gsmd_sms_msg_waiting_active {
+ NOT_ACTIVE = 0,
+ ACTIVE = 1,
+};
+
+struct gsmd_sms_datacodingscheme {
+ enum gsmd_sms_msg_class msg_class;
+ enum gsmd_sms_alphabet_type alphabet;
+ enum gsmd_sms_msg_compressed is_compressed;
+ enum gsmd_sms_msg_waiting_group mwi_group;
+ enum gsmd_sms_msg_waiting_active mwi_active;
+ enum gsmd_sms_msg_waiting_type mwi_kind;
+ u_int8_t raw_dcs_data;
+} __attribute__ ((packed));
+
/* Refer to GSM 03.40 subclause 9.2.3.1 */
enum gsmd_sms_tp_mti {
GSMD_SMS_TP_MTI_DELIVER = 0,
@@ -325,6 +377,8 @@ struct gsmd_sms {
u_int8_t length;
u_int8_t coding_scheme;
int has_header;
+ int is_voicemail;
+ struct gsmd_sms_datacodingscheme dcs;
char data[GSMD_SMS_DATA_MAXLEN+1];
} __attribute__ ((packed));
diff --git a/src/gsmd/sms_pdu.c b/src/gsmd/sms_pdu.c
index d461999..ae7a69d 100644
--- a/src/gsmd/sms_pdu.c
+++ b/src/gsmd/sms_pdu.c
@@ -87,6 +87,9 @@ int sms_pdu_to_msg(struct gsmd_sms_list *dst,
if (len < 1 || len < 1 + src[0] + pdulen || pdulen < 1)
return 1;
+ /* init voicemail is false */
+ dst->payload.is_voicemail = 0;
+
/* Skip SMSC number and its Type-of-address */
len -= 1 + src[0];
src += 1 + src[0];
@@ -111,7 +114,19 @@ int sms_pdu_to_msg(struct gsmd_sms_list *dst,
len -= 3 + i;
src += 3 + i;
+
+ /* check voicemail by TP-PID */
+ if(src[0] == 0x5f) /* return call message */
+ dst->payload.is_voicemail = 1;
+ /* decode TP-DCS */
+ if(sms_pdu_decode_dcs(&dst->payload.dcs,src+1))
+ return 1;
+ /* check voicemail by MWI */
+ if(dst->payload.dcs.mwi_kind == MESSAGE_WAITING_VOICEMAIL &&
+ (dst->payload.dcs.mwi_group == MESSAGE_WAITING_DISCARD ||
+ dst->payload.dcs.mwi_group == MESSAGE_WAITING_STORE))
+ dst->payload.is_voicemail = 1;
/* TP-DCS */
switch (src[1] >> 4) {
case 0x0 ... 3: /* General Data Coding indication */
@@ -315,3 +330,88 @@ int cbs_pdu_to_msg(struct gsmd_cbm *dst, u_int8_t *src, int pdulen, int len)
memcpy(dst->data, src + 6, len - 6);
return 0;
}
+
+/* Refer to GSM 03.38 Clause 4, for TP-DCS */
+int sms_pdu_decode_dcs(struct gsmd_sms_datacodingscheme *dcs,
+ const u_int8_t *data)
+{
+ int pos = 0, i;
+
+ /* init dcs value */
+ dcs->mwi_active = NOT_ACTIVE;
+ dcs->mwi_kind = MESSAGE_WAITING_OTHER;
+
+ /* bits 7-6 */
+ i = ( data[pos] & 0xC0 ) >> 6;
+ switch( i )
+ {
+ case 0: /* pattern 00xx xxxx */
+ dcs->is_compressed = data[pos] & 0x20;
+ if( data[pos] & 0x10 )
+ dcs->msg_class = data[pos] & 0x03;
+ else
+ /* no class information */
+ dcs->msg_class = MSG_CLASS_NONE;
+ dcs->alphabet = ( data[pos] & 0x0C ) >> 2;
+ dcs->mwi_group = MESSAGE_WAITING_NONE;
+ break;
+ case 3: /* pattern 1111 xxxx */
+ /* bits 5-4 */
+ if( (data[pos] & 0x30) == 0x30 )
+ {
+ /* bit 3 is reserved */
+ /* bit 2 */
+ dcs->alphabet = (data[pos] & 0x04 ) ? SMS_ALPHABET_8_BIT:
+ SMS_ALPHABET_7_BIT_DEFAULT;
+ /* bits 1-0 */
+ dcs->msg_class = data[pos] & 0x03;
+ /* set remaining fields */
+ dcs->is_compressed = NOT_COMPRESSED;
+ dcs->mwi_group = MESSAGE_WAITING_NONE_1111;
+ }
+ else
+ {
+ /* Message waiting groups */
+ dcs->is_compressed = NOT_COMPRESSED;
+ dcs->msg_class = MSG_CLASS_NONE;
+ /* bits 5-4 */
+ if( (data[pos] & 0x30) == 0x00 )
+ {
+ dcs->mwi_group = MESSAGE_WAITING_DISCARD;
+ dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT;
+ }
+ else if( (data[pos] & 0x30) == 0x10 )
+ {
+ dcs->mwi_group = MESSAGE_WAITING_STORE;
+ dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT;
+ }
+ else
+ {
+ dcs->mwi_group = MESSAGE_WAITING_STORE;
+ dcs->alphabet = SMS_ALPHABET_UCS2;
+ }
+ /* bit 3 */
+ dcs->mwi_active = ( data[pos] & 0x08 ) ? ACTIVE :
+ NOT_ACTIVE;
+ /* bit 2 is reserved */
+ /* bits 1-0 */
+ dcs->mwi_kind = data[pos] & 0x03;
+ }
+ break;
+ default:
+ /* reserved values */
+ dcs->msg_class = MSG_CLASS_NONE;
+ dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT;
+ dcs->is_compressed = NOT_COMPRESSED;
+ dcs->mwi_group = MESSAGE_WAITING_NONE;
+ dcs->mwi_active = NOT_ACTIVE;
+ dcs->mwi_kind = MESSAGE_WAITING_OTHER;
+ break;
+ }
+
+ if ( dcs->alphabet > SMS_ALPHABET_UCS2 )
+ dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT;
+ /* keep raw dcs data*/
+ dcs->raw_dcs_data = data[pos];
+ return 0;
+}
diff --git a/src/util/event.c b/src/util/event.c
index ea0dcb4..f14f906 100644
--- a/src/util/event.c
+++ b/src/util/event.c
@@ -42,6 +42,8 @@ static int insms_handler(struct lgsm_handle *lh, int evt,
char payload[GSMD_SMS_DATA_MAXLEN];
if (aux->u.sms.inlined) {
sms = (struct gsmd_sms_list *) aux->data;
+ if(sms->payload.is_voicemail)
+ printf("EVENT: You have a voice mail \n");
printf("EVENT: Incoming SMS from/to %s%s, at %i%i-%i%i-%i%i "
"%i%i:%i%i:%i%i, GMT%c%i\n",
((sms->addr.type & __GSMD_TOA_TON_MASK) ==
diff --git a/src/util/shell.c b/src/util/shell.c
index 922b64e..096b2cf 100644
--- a/src/util/shell.c
+++ b/src/util/shell.c
@@ -152,6 +152,8 @@ static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
case GSMD_SMS_LIST:
case GSMD_SMS_READ:
sms = (struct gsmd_sms_list *) ((void *) gmh + sizeof(*gmh));
+ if(sms->payload.is_voicemail)
+ printf("it's a voicemail \n");
printf("%s message %i from/to %s%s, at %i%i-%i%i-%i%i "
"%i%i:%i%i:%i%i, GMT%c%i\n",
msgtype[sms->stat], sms->index,
personal git repositories of Harald Welte. Your mileage may vary