SmsMessageBase.java revision daccacb865947c00f277f1823333e2fbf91e652a
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import android.util.Log; 20import com.android.internal.telephony.SmsHeader; 21import java.util.Arrays; 22 23import static android.telephony.SmsMessage.MessageClass; 24 25/** 26 * Base class declaring the specific methods and members for SmsMessage. 27 * {@hide} 28 */ 29public abstract class SmsMessageBase { 30 private static final String LOG_TAG = "SMS"; 31 32 /** {@hide} The address of the SMSC. May be null */ 33 protected String scAddress; 34 35 /** {@hide} The address of the sender */ 36 protected SmsAddress originatingAddress; 37 38 /** {@hide} The message body as a string. May be null if the message isn't text */ 39 protected String messageBody; 40 41 /** {@hide} */ 42 protected String pseudoSubject; 43 44 /** {@hide} Non-null if this is an email gateway message */ 45 protected String emailFrom; 46 47 /** {@hide} Non-null if this is an email gateway message */ 48 protected String emailBody; 49 50 /** {@hide} */ 51 protected boolean isEmail; 52 53 /** {@hide} */ 54 protected long scTimeMillis; 55 56 /** {@hide} The raw PDU of the message */ 57 protected byte[] mPdu; 58 59 /** {@hide} The raw bytes for the user data section of the message */ 60 protected byte[] userData; 61 62 /** {@hide} */ 63 protected SmsHeader userDataHeader; 64 65 // "Message Waiting Indication Group" 66 // 23.038 Section 4 67 /** {@hide} */ 68 protected boolean isMwi; 69 70 /** {@hide} */ 71 protected boolean mwiSense; 72 73 /** {@hide} */ 74 protected boolean mwiDontStore; 75 76 /** 77 * Indicates status for messages stored on the ICC. 78 */ 79 protected int statusOnIcc = -1; 80 81 /** 82 * Record index of message in the EF. 83 */ 84 protected int indexOnIcc = -1; 85 86 /** TP-Message-Reference - Message Reference of sent message. @hide */ 87 public int messageRef; 88 89 /** 90 * For a specific text string, this object describes protocol 91 * properties of encoding it for transmission as message user 92 * data. 93 */ 94 public static class TextEncodingDetails { 95 /** 96 *The number of SMS's required to encode the text. 97 */ 98 public int msgCount; 99 100 /** 101 * The number of code units consumed so far, where code units 102 * are basically characters in the encoding -- for example, 103 * septets for the standard ASCII and GSM encodings, and 16 104 * bits for Unicode. 105 */ 106 public int codeUnitCount; 107 108 /** 109 * How many code units are still available without spilling 110 * into an additional message. 111 */ 112 public int codeUnitsRemaining; 113 114 /** 115 * The encoding code unit size (specified using 116 * android.telephony.SmsMessage ENCODING_*). 117 */ 118 public int codeUnitSize; 119 } 120 121 public static abstract class SubmitPduBase { 122 public byte[] encodedScAddress; // Null if not applicable. 123 public byte[] encodedMessage; 124 125 public String toString() { 126 return "SubmitPdu: encodedScAddress = " 127 + Arrays.toString(encodedScAddress) 128 + ", encodedMessage = " 129 + Arrays.toString(encodedMessage); 130 } 131 } 132 133 /** 134 * Returns the address of the SMS service center that relayed this message 135 * or null if there is none. 136 */ 137 public String getServiceCenterAddress() { 138 return scAddress; 139 } 140 141 /** 142 * Returns the originating address (sender) of this SMS message in String 143 * form or null if unavailable 144 */ 145 public String getOriginatingAddress() { 146 if (originatingAddress == null) { 147 return null; 148 } 149 150 return originatingAddress.getAddressString(); 151 } 152 153 /** 154 * Returns the originating address, or email from address if this message 155 * was from an email gateway. Returns null if originating address 156 * unavailable. 157 */ 158 public String getDisplayOriginatingAddress() { 159 if (isEmail) { 160 return emailFrom; 161 } else { 162 return getOriginatingAddress(); 163 } 164 } 165 166 /** 167 * Returns the message body as a String, if it exists and is text based. 168 * @return message body is there is one, otherwise null 169 */ 170 public String getMessageBody() { 171 return messageBody; 172 } 173 174 /** 175 * Returns the class of this message. 176 */ 177 public abstract MessageClass getMessageClass(); 178 179 /** 180 * Returns the message body, or email message body if this message was from 181 * an email gateway. Returns null if message body unavailable. 182 */ 183 public String getDisplayMessageBody() { 184 if (isEmail) { 185 return emailBody; 186 } else { 187 return getMessageBody(); 188 } 189 } 190 191 /** 192 * Unofficial convention of a subject line enclosed in parens empty string 193 * if not present 194 */ 195 public String getPseudoSubject() { 196 return pseudoSubject == null ? "" : pseudoSubject; 197 } 198 199 /** 200 * Returns the service centre timestamp in currentTimeMillis() format 201 */ 202 public long getTimestampMillis() { 203 return scTimeMillis; 204 } 205 206 /** 207 * Returns true if message is an email. 208 * 209 * @return true if this message came through an email gateway and email 210 * sender / subject / parsed body are available 211 */ 212 public boolean isEmail() { 213 return isEmail; 214 } 215 216 /** 217 * @return if isEmail() is true, body of the email sent through the gateway. 218 * null otherwise 219 */ 220 public String getEmailBody() { 221 return emailBody; 222 } 223 224 /** 225 * @return if isEmail() is true, email from address of email sent through 226 * the gateway. null otherwise 227 */ 228 public String getEmailFrom() { 229 return emailFrom; 230 } 231 232 /** 233 * Get protocol identifier. 234 */ 235 public abstract int getProtocolIdentifier(); 236 237 /** 238 * See TS 23.040 9.2.3.9 returns true if this is a "replace short message" 239 * SMS 240 */ 241 public abstract boolean isReplace(); 242 243 /** 244 * Returns true for CPHS MWI toggle message. 245 * 246 * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section 247 * B.4.2 248 */ 249 public abstract boolean isCphsMwiMessage(); 250 251 /** 252 * returns true if this message is a CPHS voicemail / message waiting 253 * indicator (MWI) clear message 254 */ 255 public abstract boolean isMWIClearMessage(); 256 257 /** 258 * returns true if this message is a CPHS voicemail / message waiting 259 * indicator (MWI) set message 260 */ 261 public abstract boolean isMWISetMessage(); 262 263 /** 264 * returns true if this message is a "Message Waiting Indication Group: 265 * Discard Message" notification and should not be stored. 266 */ 267 public abstract boolean isMwiDontStore(); 268 269 /** 270 * returns the user data section minus the user data header if one was 271 * present. 272 */ 273 public byte[] getUserData() { 274 return userData; 275 } 276 277 /** 278 * Returns an object representing the user data header 279 * 280 * {@hide} 281 */ 282 public SmsHeader getUserDataHeader() { 283 return userDataHeader; 284 } 285 286 /** 287 * TODO(cleanup): The term PDU is used in a seemingly non-unique 288 * manner -- for example, what is the difference between this byte 289 * array and the contents of SubmitPdu objects. Maybe a more 290 * illustrative term would be appropriate. 291 */ 292 293 /** 294 * Returns the raw PDU for the message. 295 */ 296 public byte[] getPdu() { 297 return mPdu; 298 } 299 300 /** 301 * For an SMS-STATUS-REPORT message, this returns the status field from 302 * the status report. This field indicates the status of a previously 303 * submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a 304 * description of values. 305 * 306 * @return 0 indicates the previously sent message was received. 307 * See TS 23.040, 9.9.2.3.15 for a description of other possible 308 * values. 309 */ 310 public abstract int getStatus(); 311 312 /** 313 * Return true iff the message is a SMS-STATUS-REPORT message. 314 */ 315 public abstract boolean isStatusReportMessage(); 316 317 /** 318 * Returns true iff the <code>TP-Reply-Path</code> bit is set in 319 * this message. 320 */ 321 public abstract boolean isReplyPathPresent(); 322 323 /** 324 * Returns the status of the message on the ICC (read, unread, sent, unsent). 325 * 326 * @return the status of the message on the ICC. These are: 327 * SmsManager.STATUS_ON_ICC_FREE 328 * SmsManager.STATUS_ON_ICC_READ 329 * SmsManager.STATUS_ON_ICC_UNREAD 330 * SmsManager.STATUS_ON_ICC_SEND 331 * SmsManager.STATUS_ON_ICC_UNSENT 332 */ 333 public int getStatusOnIcc() { 334 return statusOnIcc; 335 } 336 337 /** 338 * Returns the record index of the message on the ICC (1-based index). 339 * @return the record index of the message on the ICC, or -1 if this 340 * SmsMessage was not created from a ICC SMS EF record. 341 */ 342 public int getIndexOnIcc() { 343 return indexOnIcc; 344 } 345 346 protected void parseMessageBody() { 347 // originatingAddress could be null if this message is from a status 348 // report. 349 if (originatingAddress != null && originatingAddress.couldBeEmailGateway()) { 350 extractEmailAddressFromMessageBody(); 351 } 352 } 353 354 /** 355 * Try to parse this message as an email gateway message 356 * There are two ways specified in TS 23.040 Section 3.8 : 357 * - SMS message "may have its TP-PID set for internet electronic mail - MT 358 * SMS format: [<from-address><space>]<message> - "Depending on the 359 * nature of the gateway, the destination/origination address is either 360 * derived from the content of the SMS TP-OA or TP-DA field, or the 361 * TP-OA/TP-DA field contains a generic gateway address and the to/from 362 * address is added at the beginning as shown above." (which is supported here) 363 * - Multiple addreses separated by commas, no spaces, Subject field delimited 364 * by '()' or '##' and '#' Section 9.2.3.24.11 (which are NOT supported here) 365 */ 366 protected void extractEmailAddressFromMessageBody() { 367 368 /* Some carriers may use " /" delimiter as below 369 * 370 * 1. [x@y][ ]/[subject][ ]/[body] 371 * -or- 372 * 2. [x@y][ ]/[body] 373 */ 374 String[] parts = messageBody.split("( /)|( )", 3); 375 if (parts.length < 2 || parts[0].indexOf('@') == -1) return; 376 emailFrom = parts[0]; 377 if (parts.length == 3) { 378 pseudoSubject = parts[1]; 379 emailBody = parts[2]; 380 } else { 381 pseudoSubject = null; 382 emailBody = parts[1]; 383 } 384 isEmail = true; 385 } 386 387} 388