1/* 2 * Copyright (C) 2007 Esmertec AG. 3 * Copyright (C) 2007 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.messaging.mmslib.pdu; 19 20import android.util.SparseArray; 21 22import com.android.messaging.mmslib.InvalidHeaderValueException; 23 24import java.util.ArrayList; 25 26public class PduHeaders { 27 /** 28 * All pdu header fields. 29 */ 30 public static final int BCC = 0x81; 31 public static final int CC = 0x82; 32 public static final int CONTENT_LOCATION = 0x83; 33 public static final int CONTENT_TYPE = 0x84; 34 public static final int DATE = 0x85; 35 public static final int DELIVERY_REPORT = 0x86; 36 public static final int DELIVERY_TIME = 0x87; 37 public static final int EXPIRY = 0x88; 38 public static final int FROM = 0x89; 39 public static final int MESSAGE_CLASS = 0x8A; 40 public static final int MESSAGE_ID = 0x8B; 41 public static final int MESSAGE_TYPE = 0x8C; 42 public static final int MMS_VERSION = 0x8D; 43 public static final int MESSAGE_SIZE = 0x8E; 44 public static final int PRIORITY = 0x8F; 45 46 public static final int READ_REPLY = 0x90; 47 public static final int READ_REPORT = 0x90; 48 public static final int REPORT_ALLOWED = 0x91; 49 public static final int RESPONSE_STATUS = 0x92; 50 public static final int RESPONSE_TEXT = 0x93; 51 public static final int SENDER_VISIBILITY = 0x94; 52 public static final int STATUS = 0x95; 53 public static final int SUBJECT = 0x96; 54 public static final int TO = 0x97; 55 public static final int TRANSACTION_ID = 0x98; 56 public static final int RETRIEVE_STATUS = 0x99; 57 public static final int RETRIEVE_TEXT = 0x9A; 58 public static final int READ_STATUS = 0x9B; 59 public static final int REPLY_CHARGING = 0x9C; 60 public static final int REPLY_CHARGING_DEADLINE = 0x9D; 61 public static final int REPLY_CHARGING_ID = 0x9E; 62 public static final int REPLY_CHARGING_SIZE = 0x9F; 63 64 public static final int PREVIOUSLY_SENT_BY = 0xA0; 65 public static final int PREVIOUSLY_SENT_DATE = 0xA1; 66 public static final int STORE = 0xA2; 67 public static final int MM_STATE = 0xA3; 68 public static final int MM_FLAGS = 0xA4; 69 public static final int STORE_STATUS = 0xA5; 70 public static final int STORE_STATUS_TEXT = 0xA6; 71 public static final int STORED = 0xA7; 72 public static final int ATTRIBUTES = 0xA8; 73 public static final int TOTALS = 0xA9; 74 public static final int MBOX_TOTALS = 0xAA; 75 public static final int QUOTAS = 0xAB; 76 public static final int MBOX_QUOTAS = 0xAC; 77 public static final int MESSAGE_COUNT = 0xAD; 78 public static final int CONTENT = 0xAE; 79 public static final int START = 0xAF; 80 81 public static final int ADDITIONAL_HEADERS = 0xB0; 82 public static final int DISTRIBUTION_INDICATOR = 0xB1; 83 public static final int ELEMENT_DESCRIPTOR = 0xB2; 84 public static final int LIMIT = 0xB3; 85 public static final int RECOMMENDED_RETRIEVAL_MODE = 0xB4; 86 public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5; 87 public static final int STATUS_TEXT = 0xB6; 88 public static final int APPLIC_ID = 0xB7; 89 public static final int REPLY_APPLIC_ID = 0xB8; 90 public static final int AUX_APPLIC_ID = 0xB9; 91 public static final int CONTENT_CLASS = 0xBA; 92 public static final int DRM_CONTENT = 0xBB; 93 public static final int ADAPTATION_ALLOWED = 0xBC; 94 public static final int REPLACE_ID = 0xBD; 95 public static final int CANCEL_ID = 0xBE; 96 public static final int CANCEL_STATUS = 0xBF; 97 98 /** 99 * X-Mms-Message-Type field types. 100 */ 101 public static final int MESSAGE_TYPE_SEND_REQ = 0x80; 102 public static final int MESSAGE_TYPE_SEND_CONF = 0x81; 103 public static final int MESSAGE_TYPE_NOTIFICATION_IND = 0x82; 104 public static final int MESSAGE_TYPE_NOTIFYRESP_IND = 0x83; 105 public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; 106 public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND = 0x85; 107 public static final int MESSAGE_TYPE_DELIVERY_IND = 0x86; 108 public static final int MESSAGE_TYPE_READ_REC_IND = 0x87; 109 public static final int MESSAGE_TYPE_READ_ORIG_IND = 0x88; 110 public static final int MESSAGE_TYPE_FORWARD_REQ = 0x89; 111 public static final int MESSAGE_TYPE_FORWARD_CONF = 0x8A; 112 public static final int MESSAGE_TYPE_MBOX_STORE_REQ = 0x8B; 113 public static final int MESSAGE_TYPE_MBOX_STORE_CONF = 0x8C; 114 public static final int MESSAGE_TYPE_MBOX_VIEW_REQ = 0x8D; 115 public static final int MESSAGE_TYPE_MBOX_VIEW_CONF = 0x8E; 116 public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ = 0x8F; 117 public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF = 0x90; 118 public static final int MESSAGE_TYPE_MBOX_DELETE_REQ = 0x91; 119 public static final int MESSAGE_TYPE_MBOX_DELETE_CONF = 0x92; 120 public static final int MESSAGE_TYPE_MBOX_DESCR = 0x93; 121 public static final int MESSAGE_TYPE_DELETE_REQ = 0x94; 122 public static final int MESSAGE_TYPE_DELETE_CONF = 0x95; 123 public static final int MESSAGE_TYPE_CANCEL_REQ = 0x96; 124 public static final int MESSAGE_TYPE_CANCEL_CONF = 0x97; 125 126 /** 127 * X-Mms-Delivery-Report | 128 * X-Mms-Read-Report | 129 * X-Mms-Report-Allowed | 130 * X-Mms-Sender-Visibility | 131 * X-Mms-Store | 132 * X-Mms-Stored | 133 * X-Mms-Totals | 134 * X-Mms-Quotas | 135 * X-Mms-Distribution-Indicator | 136 * X-Mms-DRM-Content | 137 * X-Mms-Adaptation-Allowed | 138 * field types. 139 */ 140 public static final int VALUE_YES = 0x80; 141 public static final int VALUE_NO = 0x81; 142 143 /** 144 * Delivery-Time | 145 * Expiry and Reply-Charging-Deadline | 146 * field type components. 147 */ 148 public static final int VALUE_ABSOLUTE_TOKEN = 0x80; 149 public static final int VALUE_RELATIVE_TOKEN = 0x81; 150 151 /** 152 * X-Mms-MMS-Version field types. 153 */ 154 public static final int MMS_VERSION_1_3 = ((1 << 4) | 3); 155 public static final int MMS_VERSION_1_2 = ((1 << 4) | 2); 156 public static final int MMS_VERSION_1_1 = ((1 << 4) | 1); 157 public static final int MMS_VERSION_1_0 = ((1 << 4) | 0); 158 159 // Current version is 1.2. 160 public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2; 161 162 /** 163 * From field type components. 164 */ 165 public static final int FROM_ADDRESS_PRESENT_TOKEN = 0x80; 166 public static final int FROM_INSERT_ADDRESS_TOKEN = 0x81; 167 168 public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token"; 169 170 public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token"; 171 172 /** 173 * X-Mms-Status Field. 174 */ 175 public static final int STATUS_EXPIRED = 0x80; 176 public static final int STATUS_RETRIEVED = 0x81; 177 public static final int STATUS_REJECTED = 0x82; 178 public static final int STATUS_DEFERRED = 0x83; 179 public static final int STATUS_UNRECOGNIZED = 0x84; 180 public static final int STATUS_INDETERMINATE = 0x85; 181 public static final int STATUS_FORWARDED = 0x86; 182 public static final int STATUS_UNREACHABLE = 0x87; 183 184 /** 185 * MM-Flags field type components. 186 */ 187 public static final int MM_FLAGS_ADD_TOKEN = 0x80; 188 public static final int MM_FLAGS_REMOVE_TOKEN = 0x81; 189 public static final int MM_FLAGS_FILTER_TOKEN = 0x82; 190 191 /** 192 * X-Mms-Message-Class field types. 193 */ 194 public static final int MESSAGE_CLASS_PERSONAL = 0x80; 195 public static final int MESSAGE_CLASS_ADVERTISEMENT = 0x81; 196 public static final int MESSAGE_CLASS_INFORMATIONAL = 0x82; 197 public static final int MESSAGE_CLASS_AUTO = 0x83; 198 199 public static final String MESSAGE_CLASS_PERSONAL_STR = "personal"; 200 201 public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"; 202 203 public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational"; 204 205 public static final String MESSAGE_CLASS_AUTO_STR = "auto"; 206 207 /** 208 * X-Mms-Priority field types. 209 */ 210 public static final int PRIORITY_LOW = 0x80; 211 public static final int PRIORITY_NORMAL = 0x81; 212 public static final int PRIORITY_HIGH = 0x82; 213 214 /** 215 * X-Mms-Response-Status field types. 216 */ 217 public static final int RESPONSE_STATUS_OK = 0x80; 218 public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED = 0x81; 219 public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; 220 221 public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = 0x83; 222 public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84; 223 224 public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = 0x85; 225 public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = 0x86; 226 public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87; 227 public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = 0x88; 228 public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; 229 230 public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1; 231 public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC2; 232 public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC3; 233 public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS = 0xC4; 234 235 public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE 236 = 0xE0; 237 public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED 238 = 0xE1; 239 public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT 240 = 0xE2; 241 public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED 242 = 0xE3; 243 public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND 244 = 0xE4; 245 public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED 246 = 0xE5; 247 public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET 248 = 0xE6; 249 public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED 250 = 0xE7; 251 public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED 252 = 0xE8; 253 public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED 254 = 0xE9; 255 public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED 256 = 0xEA; 257 public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID 258 = 0xEB; 259 public static final int RESPONSE_STATUS_ERROR_PERMANENT_END 260 = 0xFF; 261 262 /** 263 * X-Mms-Retrieve-Status field types. 264 */ 265 public static final int RETRIEVE_STATUS_OK = 0x80; 266 public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; 267 public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC1; 268 public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC2; 269 public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; 270 public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; 271 public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE2; 272 public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3; 273 public static final int RETRIEVE_STATUS_ERROR_END = 0xFF; 274 275 /** 276 * X-Mms-Sender-Visibility field types. 277 */ 278 public static final int SENDER_VISIBILITY_HIDE = 0x80; 279 public static final int SENDER_VISIBILITY_SHOW = 0x81; 280 281 /** 282 * X-Mms-Read-Status field types. 283 */ 284 public static final int READ_STATUS_READ = 0x80; 285 public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81; 286 287 /** 288 * X-Mms-Cancel-Status field types. 289 */ 290 public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80; 291 public static final int CANCEL_STATUS_REQUEST_CORRUPTED = 0x81; 292 293 /** 294 * X-Mms-Reply-Charging field types. 295 */ 296 public static final int REPLY_CHARGING_REQUESTED = 0x80; 297 public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81; 298 public static final int REPLY_CHARGING_ACCEPTED = 0x82; 299 public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY = 0x83; 300 301 /** 302 * X-Mms-MM-State field types. 303 */ 304 public static final int MM_STATE_DRAFT = 0x80; 305 public static final int MM_STATE_SENT = 0x81; 306 public static final int MM_STATE_NEW = 0x82; 307 public static final int MM_STATE_RETRIEVED = 0x83; 308 public static final int MM_STATE_FORWARDED = 0x84; 309 310 /** 311 * X-Mms-Recommended-Retrieval-Mode field types. 312 */ 313 public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80; 314 315 /** 316 * X-Mms-Content-Class field types. 317 */ 318 public static final int CONTENT_CLASS_TEXT = 0x80; 319 public static final int CONTENT_CLASS_IMAGE_BASIC = 0x81; 320 public static final int CONTENT_CLASS_IMAGE_RICH = 0x82; 321 public static final int CONTENT_CLASS_VIDEO_BASIC = 0x83; 322 public static final int CONTENT_CLASS_VIDEO_RICH = 0x84; 323 public static final int CONTENT_CLASS_MEGAPIXEL = 0x85; 324 public static final int CONTENT_CLASS_CONTENT_BASIC = 0x86; 325 public static final int CONTENT_CLASS_CONTENT_RICH = 0x87; 326 327 /** 328 * X-Mms-Store-Status field types. 329 */ 330 public static final int STORE_STATUS_SUCCESS = 0x80; 331 public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; 332 public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC1; 333 public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; 334 public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; 335 public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; 336 public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE3; 337 public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL = 0xE4; 338 public static final int STORE_STATUS_ERROR_END = 0xFF; 339 340 /** 341 * The map contains the value of all headers. 342 */ 343 private SparseArray<Object> mHeaderMap = null; 344 345 /** 346 * Constructor of PduHeaders. 347 */ 348 public PduHeaders() { 349 mHeaderMap = new SparseArray<Object>(); 350 } 351 352 /** 353 * Get octet value by header field. 354 * 355 * @param field the field 356 * @return the octet value of the pdu header 357 * with specified header field. Return 0 if 358 * the value is not set. 359 */ 360 protected int getOctet(int field) { 361 Integer octet = (Integer) mHeaderMap.get(field); 362 if (null == octet) { 363 return 0; 364 } 365 366 return octet; 367 } 368 369 /** 370 * Set octet value to pdu header by header field. 371 * 372 * @param value the value 373 * @param field the field 374 * @throws InvalidHeaderValueException if the value is invalid. 375 */ 376 protected void setOctet(int value, int field) 377 throws InvalidHeaderValueException { 378 /** 379 * Check whether this field can be set for specific 380 * header and check validity of the field. 381 */ 382 switch (field) { 383 case REPORT_ALLOWED: 384 case ADAPTATION_ALLOWED: 385 case DELIVERY_REPORT: 386 case DRM_CONTENT: 387 case DISTRIBUTION_INDICATOR: 388 case QUOTAS: 389 case READ_REPORT: 390 case STORE: 391 case STORED: 392 case TOTALS: 393 case SENDER_VISIBILITY: 394 if ((VALUE_YES != value) && (VALUE_NO != value)) { 395 // Invalid value. 396 throw new InvalidHeaderValueException("Invalid Octet value!"); 397 } 398 break; 399 case READ_STATUS: 400 if ((READ_STATUS_READ != value) && 401 (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) { 402 // Invalid value. 403 throw new InvalidHeaderValueException("Invalid Octet value!"); 404 } 405 break; 406 case CANCEL_STATUS: 407 if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) && 408 (CANCEL_STATUS_REQUEST_CORRUPTED != value)) { 409 // Invalid value. 410 throw new InvalidHeaderValueException("Invalid Octet value!"); 411 } 412 break; 413 case PRIORITY: 414 if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) { 415 // Invalid value. 416 throw new InvalidHeaderValueException("Invalid Octet value!"); 417 } 418 break; 419 case STATUS: 420 if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) { 421 // Invalid value. 422 throw new InvalidHeaderValueException("Invalid Octet value!"); 423 } 424 break; 425 case REPLY_CHARGING: 426 if ((value < REPLY_CHARGING_REQUESTED) 427 || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) { 428 // Invalid value. 429 throw new InvalidHeaderValueException("Invalid Octet value!"); 430 } 431 break; 432 case MM_STATE: 433 if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) { 434 // Invalid value. 435 throw new InvalidHeaderValueException("Invalid Octet value!"); 436 } 437 break; 438 case RECOMMENDED_RETRIEVAL_MODE: 439 if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) { 440 // Invalid value. 441 throw new InvalidHeaderValueException("Invalid Octet value!"); 442 } 443 break; 444 case CONTENT_CLASS: 445 if ((value < CONTENT_CLASS_TEXT) 446 || (value > CONTENT_CLASS_CONTENT_RICH)) { 447 // Invalid value. 448 throw new InvalidHeaderValueException("Invalid Octet value!"); 449 } 450 break; 451 case RETRIEVE_STATUS: 452 // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value. 453 if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && 454 (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) { 455 value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE; 456 } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) && 457 (value <= RETRIEVE_STATUS_ERROR_END)) { 458 value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; 459 } else if ((value < RETRIEVE_STATUS_OK) || 460 ((value > RETRIEVE_STATUS_OK) && 461 (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) || 462 (value > RETRIEVE_STATUS_ERROR_END)) { 463 value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; 464 } 465 break; 466 case STORE_STATUS: 467 // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value. 468 if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && 469 (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) { 470 value = STORE_STATUS_ERROR_TRANSIENT_FAILURE; 471 } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) && 472 (value <= STORE_STATUS_ERROR_END)) { 473 value = STORE_STATUS_ERROR_PERMANENT_FAILURE; 474 } else if ((value < STORE_STATUS_SUCCESS) || 475 ((value > STORE_STATUS_SUCCESS) && 476 (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) || 477 (value > STORE_STATUS_ERROR_END)) { 478 value = STORE_STATUS_ERROR_PERMANENT_FAILURE; 479 } 480 break; 481 case RESPONSE_STATUS: 482 // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value. 483 if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) && 484 (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) { 485 value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE; 486 } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) && 487 (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) || 488 (value < RESPONSE_STATUS_OK) || 489 ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) && 490 (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) || 491 (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) { 492 value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE; 493 } 494 break; 495 case MMS_VERSION: 496 if ((value < MMS_VERSION_1_0) || (value > MMS_VERSION_1_3)) { 497 value = CURRENT_MMS_VERSION; // Current version is the default value. 498 } 499 break; 500 case MESSAGE_TYPE: 501 if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) { 502 // Invalid value. 503 throw new InvalidHeaderValueException("Invalid Octet value!"); 504 } 505 break; 506 default: 507 // This header value should not be Octect. 508 throw new RuntimeException("Invalid header field!"); 509 } 510 mHeaderMap.put(field, value); 511 } 512 513 /** 514 * Get TextString value by header field. 515 * 516 * @param field the field 517 * @return the TextString value of the pdu header 518 * with specified header field 519 */ 520 protected byte[] getTextString(int field) { 521 return (byte[]) mHeaderMap.get(field); 522 } 523 524 /** 525 * Set TextString value to pdu header by header field. 526 * 527 * @param value the value 528 * @param field the field 529 * @return the TextString value of the pdu header 530 * with specified header field 531 * @throws NullPointerException if the value is null. 532 */ 533 protected void setTextString(byte[] value, int field) { 534 /** 535 * Check whether this field can be set for specific 536 * header and check validity of the field. 537 */ 538 if (null == value) { 539 throw new NullPointerException(); 540 } 541 542 switch (field) { 543 case TRANSACTION_ID: 544 case REPLY_CHARGING_ID: 545 case AUX_APPLIC_ID: 546 case APPLIC_ID: 547 case REPLY_APPLIC_ID: 548 case MESSAGE_ID: 549 case REPLACE_ID: 550 case CANCEL_ID: 551 case CONTENT_LOCATION: 552 case MESSAGE_CLASS: 553 case CONTENT_TYPE: 554 break; 555 default: 556 // This header value should not be Text-String. 557 throw new RuntimeException("Invalid header field!"); 558 } 559 mHeaderMap.put(field, value); 560 } 561 562 /** 563 * Get EncodedStringValue value by header field. 564 * 565 * @param field the field 566 * @return the EncodedStringValue value of the pdu header 567 * with specified header field 568 */ 569 protected EncodedStringValue getEncodedStringValue(int field) { 570 return (EncodedStringValue) mHeaderMap.get(field); 571 } 572 573 /** 574 * Get TO, CC or BCC header value. 575 * 576 * @param field the field 577 * @return the EncodeStringValue array of the pdu header 578 * with specified header field 579 */ 580 protected EncodedStringValue[] getEncodedStringValues(int field) { 581 ArrayList<EncodedStringValue> list = 582 (ArrayList<EncodedStringValue>) mHeaderMap.get(field); 583 if (null == list) { 584 return null; 585 } 586 EncodedStringValue[] values = new EncodedStringValue[list.size()]; 587 return list.toArray(values); 588 } 589 590 /** 591 * Set EncodedStringValue value to pdu header by header field. 592 * 593 * @param value the value 594 * @param field the field 595 * @return the EncodedStringValue value of the pdu header 596 * with specified header field 597 * @throws NullPointerException if the value is null. 598 */ 599 protected void setEncodedStringValue(EncodedStringValue value, int field) { 600 /** 601 * Check whether this field can be set for specific 602 * header and check validity of the field. 603 */ 604 if (null == value) { 605 throw new NullPointerException(); 606 } 607 608 switch (field) { 609 case SUBJECT: 610 case RECOMMENDED_RETRIEVAL_MODE_TEXT: 611 case RETRIEVE_TEXT: 612 case STATUS_TEXT: 613 case STORE_STATUS_TEXT: 614 case RESPONSE_TEXT: 615 case FROM: 616 case PREVIOUSLY_SENT_BY: 617 case MM_FLAGS: 618 break; 619 default: 620 // This header value should not be Encoded-String-Value. 621 throw new RuntimeException("Invalid header field!"); 622 } 623 624 mHeaderMap.put(field, value); 625 } 626 627 /** 628 * Set TO, CC or BCC header value. 629 * 630 * @param value the value 631 * @param field the field 632 * @return the EncodedStringValue value array of the pdu header 633 * with specified header field 634 * @throws NullPointerException if the value is null. 635 */ 636 protected void setEncodedStringValues(EncodedStringValue[] value, int field) { 637 /** 638 * Check whether this field can be set for specific 639 * header and check validity of the field. 640 */ 641 if (null == value) { 642 throw new NullPointerException(); 643 } 644 645 switch (field) { 646 case BCC: 647 case CC: 648 case TO: 649 break; 650 default: 651 // This header value should not be Encoded-String-Value. 652 throw new RuntimeException("Invalid header field!"); 653 } 654 655 ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>(); 656 for (int i = 0; i < value.length; i++) { 657 list.add(value[i]); 658 } 659 mHeaderMap.put(field, list); 660 } 661 662 /** 663 * Append one EncodedStringValue to another. 664 * 665 * @param value the EncodedStringValue to append 666 * @param field the field 667 * @throws NullPointerException if the value is null. 668 */ 669 protected void appendEncodedStringValue(EncodedStringValue value, 670 int field) { 671 if (null == value) { 672 throw new NullPointerException(); 673 } 674 675 switch (field) { 676 case BCC: 677 case CC: 678 case TO: 679 break; 680 default: 681 throw new RuntimeException("Invalid header field!"); 682 } 683 684 ArrayList<EncodedStringValue> list = 685 (ArrayList<EncodedStringValue>) mHeaderMap.get(field); 686 if (null == list) { 687 list = new ArrayList<EncodedStringValue>(); 688 } 689 list.add(value); 690 mHeaderMap.put(field, list); 691 } 692 693 /** 694 * Get LongInteger value by header field. 695 * 696 * @param field the field 697 * @return the LongInteger value of the pdu header 698 * with specified header field. if return -1, the 699 * field is not existed in pdu header. 700 */ 701 protected long getLongInteger(int field) { 702 Long longInteger = (Long) mHeaderMap.get(field); 703 if (null == longInteger) { 704 return -1; 705 } 706 707 return longInteger.longValue(); 708 } 709 710 /** 711 * Set LongInteger value to pdu header by header field. 712 * 713 * @param value the value 714 * @param field the field 715 */ 716 protected void setLongInteger(long value, int field) { 717 /** 718 * Check whether this field can be set for specific 719 * header and check validity of the field. 720 */ 721 switch (field) { 722 case DATE: 723 case REPLY_CHARGING_SIZE: 724 case MESSAGE_SIZE: 725 case MESSAGE_COUNT: 726 case START: 727 case LIMIT: 728 case DELIVERY_TIME: 729 case EXPIRY: 730 case REPLY_CHARGING_DEADLINE: 731 case PREVIOUSLY_SENT_DATE: 732 break; 733 default: 734 // This header value should not be LongInteger. 735 throw new RuntimeException("Invalid header field!"); 736 } 737 mHeaderMap.put(field, value); 738 } 739 740 public boolean hasHeader(int field) { 741 return mHeaderMap.get(field, null) != null; 742 } 743} 744