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