1 /* 2 * Copyright (C) 2013 Samsung System LSI 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 package com.android.bluetooth.map; 16 17 import java.io.UnsupportedEncodingException; 18 import java.nio.ByteBuffer; 19 import java.nio.ByteOrder; 20 import java.text.ParseException; 21 import java.text.SimpleDateFormat; 22 import java.util.Arrays; 23 import java.util.Date; 24 25 import android.util.Log; 26 27 /** 28 * This class encapsulates the appParams needed for MAP. 29 */ 30 public class BluetoothMapAppParams { 31 32 private static final String TAG = "BluetoothMapAppParams"; 33 34 private static final int MAX_LIST_COUNT = 0x01; 35 private static final int MAX_LIST_COUNT_LEN = 0x02; //, 0x0000, 0xFFFF), 36 private static final int START_OFFSET = 0x02; 37 private static final int START_OFFSET_LEN = 0x02; //, 0x0000, 0xFFFF), 38 private static final int FILTER_MESSAGE_TYPE = 0x03; 39 private static final int FILTER_MESSAGE_TYPE_LEN = 0x01; //, 0x0000, 0x000f), 40 private static final int FILTER_PERIOD_BEGIN = 0x04; 41 private static final int FILTER_PERIOD_END = 0x05; 42 private static final int FILTER_READ_STATUS = 0x06; 43 private static final int FILTER_READ_STATUS_LEN = 0x01; //, 0x0000, 0x0002), 44 private static final int FILTER_RECIPIENT = 0x07; 45 private static final int FILTER_ORIGINATOR = 0x08; 46 private static final int FILTER_PRIORITY = 0x09; 47 private static final int FILTER_PRIORITY_LEN = 0x01; //, 0x0000, 0x0002), 48 private static final int ATTACHMENT = 0x0A; 49 private static final int ATTACHMENT_LEN = 0x01; //, 0x0000, 0x0001), 50 private static final int TRANSPARENT = 0x0B; 51 private static final int TRANSPARENT_LEN = 0x01; //, 0x0000, 0x0001), 52 private static final int RETRY = 0x0C; 53 private static final int RETRY_LEN = 0x01; //, 0x0000, 0x0001), 54 private static final int NEW_MESSAGE = 0x0D; 55 private static final int NEW_MESSAGE_LEN = 0x01; //, 0x0000, 0x0001), 56 private static final int NOTIFICATION_STATUS = 0x0E; 57 private static final int NOTIFICATION_STATUS_LEN = 0x01; //, 0x0000, 0xFFFF), 58 private static final int MAS_INSTANCE_ID = 0x0F; 59 private static final int MAS_INSTANCE_ID_LEN = 0x01; //, 0x0000, 0x00FF), 60 private static final int PARAMETER_MASK = 0x10; 61 private static final int PARAMETER_MASK_LEN = 0x04; //, 0x0000, 0x0000), 62 private static final int FOLDER_LISTING_SIZE = 0x11; 63 private static final int FOLDER_LISTING_SIZE_LEN = 0x02; //, 0x0000, 0xFFFF), 64 private static final int MESSAGE_LISTING_SIZE = 0x12; 65 private static final int MESSAGE_LISTING_SIZE_LEN = 0x02; //, 0x0000, 0xFFFF), 66 private static final int SUBJECT_LENGTH = 0x13; 67 private static final int SUBJECT_LENGTH_LEN = 0x01; //, 0x0000, 0x00FF), 68 private static final int CHARSET = 0x14; 69 private static final int CHARSET_LEN = 0x01; //, 0x0000, 0x0001), 70 private static final int FRACTION_REQUEST = 0x15; 71 private static final int FRACTION_REQUEST_LEN = 0x01; //, 0x0000, 0x0001), 72 private static final int FRACTION_DELIVER = 0x16; 73 private static final int FRACTION_DELIVER_LEN = 0x01; //, 0x0000, 0x0001), 74 private static final int STATUS_INDICATOR = 0x17; 75 private static final int STATUS_INDICATOR_LEN = 0x01; //, 0x0000, 0x0001), 76 private static final int STATUS_VALUE = 0x18; 77 private static final int STATUS_VALUE_LEN = 0x01; //, 0x0000, 0x0001), 78 private static final int MSE_TIME = 0x19; 79 80 public static final int INVALID_VALUE_PARAMETER = -1; 81 public static final int NOTIFICATION_STATUS_NO = 0; 82 public static final int NOTIFICATION_STATUS_YES = 1; 83 public static final int STATUS_INDICATOR_READ = 0; 84 public static final int STATUS_INDICATOR_DELETED = 1; 85 public static final int STATUS_VALUE_YES = 1; 86 public static final int STATUS_VALUE_NO = 0; 87 public static final int CHARSET_NATIVE = 0; 88 public static final int CHARSET_UTF8 = 1; 89 public static final int FRACTION_REQUEST_FIRST = 0; 90 public static final int FRACTION_REQUEST_NEXT = 1; 91 public static final int FRACTION_DELIVER_MORE = 0; 92 public static final int FRACTION_DELIVER_LAST = 1; 93 94 95 public static final int FILTER_NO_SMS_GSM = 0x01; 96 public static final int FILTER_NO_SMS_CDMA = 0x02; 97 public static final int FILTER_NO_EMAIL = 0x04; 98 public static final int FILTER_NO_MMS = 0x08; 99 100 /* Default values for omitted application parameters */ 101 public static final long PARAMETER_MASK_ALL_ENABLED = 0xFFFF; // TODO: Update when bit 16-31 will be used. 102 103 private int mMaxListCount = INVALID_VALUE_PARAMETER; 104 private int mStartOffset = INVALID_VALUE_PARAMETER; 105 private int mFilterMessageType = INVALID_VALUE_PARAMETER; 106 private long mFilterPeriodBegin = INVALID_VALUE_PARAMETER; 107 private long mFilterPeriodEnd = INVALID_VALUE_PARAMETER; 108 private int mFilterReadStatus = INVALID_VALUE_PARAMETER; 109 private String mFilterRecipient = null; 110 private String mFilterOriginator = null; 111 private int mFilterPriority = INVALID_VALUE_PARAMETER; 112 private int mAttachment = INVALID_VALUE_PARAMETER; 113 private int mTransparent = INVALID_VALUE_PARAMETER; 114 private int mRetry = INVALID_VALUE_PARAMETER; 115 private int mNewMessage = INVALID_VALUE_PARAMETER; 116 private int mNotificationStatus = INVALID_VALUE_PARAMETER; 117 private int mMasInstanceId = INVALID_VALUE_PARAMETER; 118 private long mParameterMask = INVALID_VALUE_PARAMETER; 119 private int mFolderListingSize = INVALID_VALUE_PARAMETER; 120 private int mMessageListingSize = INVALID_VALUE_PARAMETER; 121 private int mSubjectLength = INVALID_VALUE_PARAMETER; 122 private int mCharset = INVALID_VALUE_PARAMETER; 123 private int mFractionRequest = INVALID_VALUE_PARAMETER; 124 private int mFractionDeliver = INVALID_VALUE_PARAMETER; 125 private int mStatusIndicator = INVALID_VALUE_PARAMETER; 126 private int mStatusValue = INVALID_VALUE_PARAMETER; 127 private long mMseTime = INVALID_VALUE_PARAMETER; 128 129 /** 130 * Default constructor, used to build an application parameter object to be 131 * encoded. By default the member variables will be initialized to 132 * {@link INVALID_VALUE_PARAMETER} for values, and empty strings for String 133 * typed members. 134 */ BluetoothMapAppParams()135 public BluetoothMapAppParams() { 136 } 137 138 /** 139 * Creates an application parameter object based on a application parameter 140 * OBEX header. The content of the {@link appParam} byte array will be 141 * parsed, and its content will be stored in the member variables. 142 * {@link INVALID_VALUE_PARAMETER} can be used to determine if a value is 143 * set or not, where strings will be empty, if {@link appParam} did not 144 * contain the parameter. 145 * 146 * @param appParams 147 * the byte array containing the application parameters OBEX 148 * header 149 * @throws IllegalArgumentException 150 * when a parameter does not respect the valid ranges specified 151 * in the MAP spec. 152 * @throws ParseException 153 * if a parameter string if formated incorrectly. 154 */ BluetoothMapAppParams(final byte[] appParams)155 public BluetoothMapAppParams(final byte[] appParams) 156 throws IllegalArgumentException, ParseException { 157 ParseParams(appParams); 158 } 159 160 /** 161 * Parse an application parameter OBEX header stored in a ByteArray. 162 * 163 * @param appParams 164 * the byte array containing the application parameters OBEX 165 * header 166 * @throws IllegalArgumentException 167 * when a parameter does not respect the valid ranges specified 168 * in the MAP spec. 169 * @throws ParseException 170 * if a parameter string if formated incorrectly. 171 */ ParseParams(final byte[] appParams)172 private void ParseParams(final byte[] appParams) throws ParseException, 173 IllegalArgumentException { 174 int i = 0; 175 int tagId, tagLength; 176 ByteBuffer appParamBuf = ByteBuffer.wrap(appParams); 177 appParamBuf.order(ByteOrder.BIG_ENDIAN); 178 while (i < appParams.length) { 179 tagId = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 180 tagLength = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 181 switch (tagId) { 182 case MAX_LIST_COUNT: 183 if (tagLength != MAX_LIST_COUNT_LEN) { 184 Log.w(TAG, "MAX_LIST_COUNT: Wrong length received: " + tagLength 185 + " expected: " + MAX_LIST_COUNT_LEN); 186 break; 187 } 188 setMaxListCount(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 189 break; 190 case START_OFFSET: 191 if (tagLength != START_OFFSET_LEN) { 192 Log.w(TAG, "START_OFFSET: Wrong length received: " + tagLength + " expected: " 193 + START_OFFSET_LEN); 194 break; 195 } 196 setStartOffset(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 197 break; 198 case FILTER_MESSAGE_TYPE: 199 if (tagLength != FILTER_MESSAGE_TYPE_LEN) { 200 Log.w(TAG, "FILTER_MESSAGE_TYPE: Wrong length received: " + tagLength + " expected: " 201 + FILTER_MESSAGE_TYPE_LEN); 202 break; 203 } 204 setFilterMessageType(appParams[i] & 0x0f); 205 break; 206 case FILTER_PERIOD_BEGIN: 207 if(tagLength != 0) { 208 setFilterPeriodBegin(new String(appParams, i, tagLength)); 209 } 210 break; 211 case FILTER_PERIOD_END: 212 if(tagLength != 0) { 213 setFilterPeriodEnd(new String(appParams, i, tagLength)); 214 } 215 break; 216 case FILTER_READ_STATUS: 217 if (tagLength != FILTER_READ_STATUS_LEN) { 218 Log.w(TAG, "FILTER_READ_STATUS: Wrong length received: " + tagLength + " expected: " 219 + FILTER_READ_STATUS_LEN); 220 break; 221 } 222 setFilterReadStatus(appParams[i] & 0x03); // Lower two bits 223 break; 224 case FILTER_RECIPIENT: 225 if(tagLength != 0) { 226 setFilterRecipient(new String(appParams, i, tagLength)); 227 } 228 break; 229 case FILTER_ORIGINATOR: 230 if(tagLength != 0) { 231 setFilterOriginator(new String(appParams, i, tagLength)); 232 } 233 break; 234 case FILTER_PRIORITY: 235 if (tagLength != FILTER_PRIORITY_LEN) { 236 Log.w(TAG, "FILTER_PRIORITY: Wrong length received: " + tagLength + " expected: " 237 + FILTER_PRIORITY_LEN); 238 break; 239 } 240 setFilterPriority(appParams[i] & 0x03); // Lower two bits 241 break; 242 case ATTACHMENT: 243 if (tagLength != ATTACHMENT_LEN) { 244 Log.w(TAG, "ATTACHMENT: Wrong length received: " + tagLength + " expected: " 245 + ATTACHMENT_LEN); 246 break; 247 } 248 setAttachment(appParams[i] & 0x01); // Lower bit 249 break; 250 case TRANSPARENT: 251 if (tagLength != TRANSPARENT_LEN) { 252 Log.w(TAG, "TRANSPARENT: Wrong length received: " + tagLength + " expected: " 253 + TRANSPARENT_LEN); 254 break; 255 } 256 setTransparent(appParams[i] & 0x01); // Lower bit 257 break; 258 case RETRY: 259 if (tagLength != RETRY_LEN) { 260 Log.w(TAG, "RETRY: Wrong length received: " + tagLength + " expected: " 261 + RETRY_LEN); 262 break; 263 } 264 setRetry(appParams[i] & 0x01); // Lower bit 265 break; 266 case NEW_MESSAGE: 267 if (tagLength != NEW_MESSAGE_LEN) { 268 Log.w(TAG, "NEW_MESSAGE: Wrong length received: " + tagLength + " expected: " 269 + NEW_MESSAGE_LEN); 270 break; 271 } 272 setNewMessage(appParams[i] & 0x01); // Lower bit 273 break; 274 case NOTIFICATION_STATUS: 275 if (tagLength != NOTIFICATION_STATUS_LEN) { 276 Log.w(TAG, "NOTIFICATION_STATUS: Wrong length received: " + tagLength + " expected: " 277 + NOTIFICATION_STATUS_LEN); 278 break; 279 } 280 setNotificationStatus(appParams[i] & 0x01); // Lower bit 281 break; 282 case MAS_INSTANCE_ID: 283 if (tagLength != MAS_INSTANCE_ID_LEN) { 284 Log.w(TAG, "MAS_INSTANCE_ID: Wrong length received: " + tagLength + " expected: " 285 + MAS_INSTANCE_ID_LEN); 286 break; 287 } 288 setMasInstanceId(appParams[i] & 0xff); 289 break; 290 case PARAMETER_MASK: 291 if (tagLength != PARAMETER_MASK_LEN) { 292 Log.w(TAG, "PARAMETER_MASK: Wrong length received: " + tagLength + " expected: " 293 + PARAMETER_MASK_LEN); 294 break; 295 } 296 setParameterMask(appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned 297 break; 298 case FOLDER_LISTING_SIZE: 299 if (tagLength != FOLDER_LISTING_SIZE_LEN) { 300 Log.w(TAG, "FOLDER_LISTING_SIZE: Wrong length received: " + tagLength + " expected: " 301 + FOLDER_LISTING_SIZE_LEN); 302 break; 303 } 304 setFolderListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 305 break; 306 case MESSAGE_LISTING_SIZE: 307 if (tagLength != MESSAGE_LISTING_SIZE_LEN) { 308 Log.w(TAG, "MESSAGE_LISTING_SIZE: Wrong length received: " + tagLength + " expected: " 309 + MESSAGE_LISTING_SIZE_LEN); 310 break; 311 } 312 setMessageListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 313 break; 314 case SUBJECT_LENGTH: 315 if (tagLength != SUBJECT_LENGTH_LEN) { 316 Log.w(TAG, "SUBJECT_LENGTH: Wrong length received: " + tagLength + " expected: " 317 + SUBJECT_LENGTH_LEN); 318 break; 319 } 320 setSubjectLength(appParams[i] & 0xff); 321 break; 322 case CHARSET: 323 if (tagLength != CHARSET_LEN) { 324 Log.w(TAG, "CHARSET: Wrong length received: " + tagLength + " expected: " 325 + CHARSET_LEN); 326 break; 327 } 328 setCharset(appParams[i] & 0x01); // Lower bit 329 break; 330 case FRACTION_REQUEST: 331 if (tagLength != FRACTION_REQUEST_LEN) { 332 Log.w(TAG, "FRACTION_REQUEST: Wrong length received: " + tagLength + " expected: " 333 + FRACTION_REQUEST_LEN); 334 break; 335 } 336 setFractionRequest(appParams[i] & 0x01); // Lower bit 337 break; 338 case FRACTION_DELIVER: 339 if (tagLength != FRACTION_DELIVER_LEN) { 340 Log.w(TAG, "FRACTION_DELIVER: Wrong length received: " + tagLength + " expected: " 341 + FRACTION_DELIVER_LEN); 342 break; 343 } 344 setFractionDeliver(appParams[i] & 0x01); // Lower bit 345 break; 346 case STATUS_INDICATOR: 347 if (tagLength != STATUS_INDICATOR_LEN) { 348 Log.w(TAG, "STATUS_INDICATOR: Wrong length received: " + tagLength + " expected: " 349 + STATUS_INDICATOR_LEN); 350 break; 351 } 352 setStatusIndicator(appParams[i] & 0x01); // Lower bit 353 break; 354 case STATUS_VALUE: 355 if (tagLength != STATUS_VALUE_LEN) { 356 Log.w(TAG, "STATUS_VALUER: Wrong length received: " + tagLength + " expected: " 357 + STATUS_VALUE_LEN); 358 break; 359 } 360 setStatusValue(appParams[i] & 0x01); // Lower bit 361 break; 362 case MSE_TIME: 363 setMseTime(new String(appParams, i, tagLength)); 364 break; 365 default: 366 // Just skip unknown Tags, no need to report error 367 Log.w(TAG, "Unknown TagId received ( 0x" + Integer.toString(tagId, 16) 368 + "), skipping..."); 369 break; 370 } 371 i += tagLength; // Offset to next TagId 372 } 373 } 374 375 /** 376 * Get the approximate length needed to store the appParameters in a byte 377 * array. 378 * 379 * @return the length in bytes 380 * @throws UnsupportedEncodingException 381 * if the platform does not support UTF-8 encoding. 382 */ getParamMaxLength()383 private int getParamMaxLength() throws UnsupportedEncodingException { 384 int length = 0; 385 length += 25 * 2; // tagId + tagLength 386 length += 27; // fixed sizes 387 length += getFilterPeriodBegin() == INVALID_VALUE_PARAMETER ? 0 : 15; 388 length += getFilterPeriodEnd() == INVALID_VALUE_PARAMETER ? 0 : 15; 389 if (getFilterRecipient() != null) 390 length += getFilterRecipient().getBytes("UTF-8").length; 391 if (getFilterOriginator() != null) 392 length += getFilterOriginator().getBytes("UTF-8").length; 393 length += getMseTime() == INVALID_VALUE_PARAMETER ? 0 : 20; 394 return length; 395 } 396 397 /** 398 * Encode the application parameter object to a byte array. 399 * 400 * @return a byte Array representation of the application parameter object. 401 * @throws UnsupportedEncodingException 402 * if the platform does not support UTF-8 encoding. 403 */ EncodeParams()404 public byte[] EncodeParams() throws UnsupportedEncodingException { 405 ByteBuffer appParamBuf = ByteBuffer.allocate(getParamMaxLength()); 406 appParamBuf.order(ByteOrder.BIG_ENDIAN); 407 byte[] retBuf; 408 409 if (getMaxListCount() != INVALID_VALUE_PARAMETER) { 410 appParamBuf.put((byte) MAX_LIST_COUNT); 411 appParamBuf.put((byte) MAX_LIST_COUNT_LEN); 412 appParamBuf.putShort((short) getMaxListCount()); 413 } 414 if (getStartOffset() != INVALID_VALUE_PARAMETER) { 415 appParamBuf.put((byte) START_OFFSET); 416 appParamBuf.put((byte) START_OFFSET_LEN); 417 appParamBuf.putShort((short) getStartOffset()); 418 } 419 if (getFilterMessageType() != INVALID_VALUE_PARAMETER) { 420 appParamBuf.put((byte) FILTER_MESSAGE_TYPE); 421 appParamBuf.put((byte) FILTER_MESSAGE_TYPE_LEN); 422 appParamBuf.put((byte) getFilterMessageType()); 423 } 424 if (getFilterPeriodBegin() != INVALID_VALUE_PARAMETER) { 425 appParamBuf.put((byte) FILTER_PERIOD_BEGIN); 426 appParamBuf.put((byte) getFilterPeriodBeginString().getBytes("UTF-8").length); 427 appParamBuf.put(getFilterPeriodBeginString().getBytes("UTF-8")); 428 } 429 if (getFilterPeriodEnd() != INVALID_VALUE_PARAMETER) { 430 appParamBuf.put((byte) FILTER_PERIOD_END); 431 appParamBuf.put((byte) getFilterPeriodEndString().getBytes("UTF-8").length); 432 appParamBuf.put(getFilterPeriodEndString().getBytes("UTF-8")); 433 } 434 if (getFilterReadStatus() != INVALID_VALUE_PARAMETER) { 435 appParamBuf.put((byte) FILTER_READ_STATUS); 436 appParamBuf.put((byte) FILTER_READ_STATUS_LEN); 437 appParamBuf.put((byte) getFilterReadStatus()); 438 } 439 if (getFilterRecipient() != null) { 440 appParamBuf.put((byte) FILTER_RECIPIENT); 441 appParamBuf.put((byte) getFilterRecipient().getBytes("UTF-8").length); 442 appParamBuf.put(getFilterRecipient().getBytes("UTF-8")); 443 } 444 if (getFilterOriginator() != null) { 445 appParamBuf.put((byte) FILTER_ORIGINATOR); 446 appParamBuf.put((byte) getFilterOriginator().getBytes("UTF-8").length); 447 appParamBuf.put(getFilterOriginator().getBytes("UTF-8")); 448 } 449 if (getFilterPriority() != INVALID_VALUE_PARAMETER) { 450 appParamBuf.put((byte) FILTER_PRIORITY); 451 appParamBuf.put((byte) FILTER_PRIORITY_LEN); 452 appParamBuf.put((byte) getFilterPriority()); 453 } 454 if (getAttachment() != INVALID_VALUE_PARAMETER) { 455 appParamBuf.put((byte) ATTACHMENT); 456 appParamBuf.put((byte) ATTACHMENT_LEN); 457 appParamBuf.put((byte) getAttachment()); 458 } 459 if (getTransparent() != INVALID_VALUE_PARAMETER) { 460 appParamBuf.put((byte) TRANSPARENT); 461 appParamBuf.put((byte) TRANSPARENT_LEN); 462 appParamBuf.put((byte) getTransparent()); 463 } 464 if (getRetry() != INVALID_VALUE_PARAMETER) { 465 appParamBuf.put((byte) RETRY); 466 appParamBuf.put((byte) RETRY_LEN); 467 appParamBuf.put((byte) getRetry()); 468 } 469 if (getNewMessage() != INVALID_VALUE_PARAMETER) { 470 appParamBuf.put((byte) NEW_MESSAGE); 471 appParamBuf.put((byte) NEW_MESSAGE_LEN); 472 appParamBuf.put((byte) getNewMessage()); 473 } 474 if (getNotificationStatus() != INVALID_VALUE_PARAMETER) { 475 appParamBuf.put((byte) NOTIFICATION_STATUS); 476 appParamBuf.put((byte) NOTIFICATION_STATUS_LEN); 477 appParamBuf.putShort((short) getNotificationStatus()); 478 } 479 if (getMasInstanceId() != INVALID_VALUE_PARAMETER) { 480 appParamBuf.put((byte) MAS_INSTANCE_ID); 481 appParamBuf.put((byte) MAS_INSTANCE_ID_LEN); 482 appParamBuf.put((byte) getMasInstanceId()); 483 } 484 if (getParameterMask() != INVALID_VALUE_PARAMETER) { 485 appParamBuf.put((byte) PARAMETER_MASK); 486 appParamBuf.put((byte) PARAMETER_MASK_LEN); 487 appParamBuf.putInt((int) getParameterMask()); 488 } 489 if (getFolderListingSize() != INVALID_VALUE_PARAMETER) { 490 appParamBuf.put((byte) FOLDER_LISTING_SIZE); 491 appParamBuf.put((byte) FOLDER_LISTING_SIZE_LEN); 492 appParamBuf.putShort((short) getFolderListingSize()); 493 } 494 if (getMessageListingSize() != INVALID_VALUE_PARAMETER) { 495 appParamBuf.put((byte) MESSAGE_LISTING_SIZE); 496 appParamBuf.put((byte) MESSAGE_LISTING_SIZE_LEN); 497 appParamBuf.putShort((short) getMessageListingSize()); 498 } 499 if (getSubjectLength() != INVALID_VALUE_PARAMETER) { 500 appParamBuf.put((byte) SUBJECT_LENGTH); 501 appParamBuf.put((byte) SUBJECT_LENGTH_LEN); 502 appParamBuf.put((byte) getSubjectLength()); 503 } 504 if (getCharset() != INVALID_VALUE_PARAMETER) { 505 appParamBuf.put((byte) CHARSET); 506 appParamBuf.put((byte) CHARSET_LEN); 507 appParamBuf.put((byte) getCharset()); 508 } 509 if (getFractionRequest() != INVALID_VALUE_PARAMETER) { 510 appParamBuf.put((byte) FRACTION_REQUEST); 511 appParamBuf.put((byte) FRACTION_REQUEST_LEN); 512 appParamBuf.put((byte) getFractionRequest()); 513 } 514 if (getFractionDeliver() != INVALID_VALUE_PARAMETER) { 515 appParamBuf.put((byte) FRACTION_DELIVER); 516 appParamBuf.put((byte) FRACTION_DELIVER_LEN); 517 appParamBuf.put((byte) getFractionDeliver()); 518 } 519 if (getStatusIndicator() != INVALID_VALUE_PARAMETER) { 520 appParamBuf.put((byte) STATUS_INDICATOR); 521 appParamBuf.put((byte) STATUS_INDICATOR_LEN); 522 appParamBuf.put((byte) getStatusIndicator()); 523 } 524 if (getStatusValue() != INVALID_VALUE_PARAMETER) { 525 appParamBuf.put((byte) STATUS_VALUE); 526 appParamBuf.put((byte) STATUS_VALUE_LEN); 527 appParamBuf.put((byte) getStatusValue()); 528 } 529 if (getMseTime() != INVALID_VALUE_PARAMETER) { 530 appParamBuf.put((byte) MSE_TIME); 531 appParamBuf.put((byte) getMseTimeString().getBytes("UTF-8").length); 532 appParamBuf.put(getMseTimeString().getBytes("UTF-8")); 533 } 534 // We need to reduce the length of the array to match the content 535 retBuf = Arrays.copyOfRange(appParamBuf.array(), appParamBuf.arrayOffset(), 536 appParamBuf.arrayOffset() + appParamBuf.position()); 537 return retBuf; 538 } 539 getMaxListCount()540 public int getMaxListCount() { 541 return mMaxListCount; 542 } 543 setMaxListCount(int maxListCount)544 public void setMaxListCount(int maxListCount) throws IllegalArgumentException { 545 if (maxListCount < 0 || maxListCount > 0xFFFF) 546 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 547 this.mMaxListCount = maxListCount; 548 } 549 getStartOffset()550 public int getStartOffset() { 551 return mStartOffset; 552 } 553 setStartOffset(int startOffset)554 public void setStartOffset(int startOffset) throws IllegalArgumentException { 555 if (startOffset < 0 || startOffset > 0xFFFF) 556 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 557 this.mStartOffset = startOffset; 558 } 559 getFilterMessageType()560 public int getFilterMessageType() { 561 return mFilterMessageType; 562 } 563 setFilterMessageType(int filterMessageType)564 public void setFilterMessageType(int filterMessageType) throws IllegalArgumentException { 565 if (filterMessageType < 0 || filterMessageType > 0x000F) 566 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x000F"); 567 this.mFilterMessageType = filterMessageType; 568 } 569 getFilterPeriodBegin()570 public long getFilterPeriodBegin() { 571 return mFilterPeriodBegin; 572 } 573 getFilterPeriodBeginString()574 public String getFilterPeriodBeginString() { 575 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 576 Date date = new Date(mFilterPeriodBegin); 577 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 578 } 579 setFilterPeriodBegin(long filterPeriodBegin)580 public void setFilterPeriodBegin(long filterPeriodBegin) { 581 this.mFilterPeriodBegin = filterPeriodBegin; 582 } 583 setFilterPeriodBegin(String filterPeriodBegin)584 public void setFilterPeriodBegin(String filterPeriodBegin) throws ParseException { 585 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 586 Date date = format.parse(filterPeriodBegin); 587 this.mFilterPeriodBegin = date.getTime(); 588 } 589 getFilterPeriodEnd()590 public long getFilterPeriodEnd() { 591 return mFilterPeriodEnd; 592 } 593 getFilterPeriodEndString()594 public String getFilterPeriodEndString() { 595 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 596 Date date = new Date(mFilterPeriodEnd); 597 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 598 } 599 setFilterPeriodEnd(long filterPeriodEnd)600 public void setFilterPeriodEnd(long filterPeriodEnd) { 601 this.mFilterPeriodEnd = filterPeriodEnd; 602 } 603 setFilterPeriodEnd(String filterPeriodEnd)604 public void setFilterPeriodEnd(String filterPeriodEnd) throws ParseException { 605 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 606 Date date = format.parse(filterPeriodEnd); 607 this.mFilterPeriodEnd = date.getTime(); 608 } 609 getFilterReadStatus()610 public int getFilterReadStatus() { 611 return mFilterReadStatus; 612 } 613 setFilterReadStatus(int filterReadStatus)614 public void setFilterReadStatus(int filterReadStatus) throws IllegalArgumentException { 615 if (filterReadStatus < 0 || filterReadStatus > 0x0002) 616 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002"); 617 this.mFilterReadStatus = filterReadStatus; 618 } 619 getFilterRecipient()620 public String getFilterRecipient() { 621 return mFilterRecipient; 622 } 623 setFilterRecipient(String filterRecipient)624 public void setFilterRecipient(String filterRecipient) { 625 this.mFilterRecipient = filterRecipient; 626 } 627 getFilterOriginator()628 public String getFilterOriginator() { 629 return mFilterOriginator; 630 } 631 setFilterOriginator(String filterOriginator)632 public void setFilterOriginator(String filterOriginator) { 633 this.mFilterOriginator = filterOriginator; 634 } 635 getFilterPriority()636 public int getFilterPriority() { 637 return mFilterPriority; 638 } 639 setFilterPriority(int filterPriority)640 public void setFilterPriority(int filterPriority) throws IllegalArgumentException { 641 if (filterPriority < 0 || filterPriority > 0x0002) 642 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002"); 643 this.mFilterPriority = filterPriority; 644 } 645 getAttachment()646 public int getAttachment() { 647 return mAttachment; 648 } 649 setAttachment(int attachment)650 public void setAttachment(int attachment) throws IllegalArgumentException { 651 if (attachment < 0 || attachment > 0x0001) 652 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 653 this.mAttachment = attachment; 654 } 655 getTransparent()656 public int getTransparent() { 657 return mTransparent; 658 } 659 setTransparent(int transparent)660 public void setTransparent(int transparent) throws IllegalArgumentException { 661 if (transparent < 0 || transparent > 0x0001) 662 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 663 this.mTransparent = transparent; 664 } 665 getRetry()666 public int getRetry() { 667 return mRetry; 668 } 669 setRetry(int retry)670 public void setRetry(int retry) throws IllegalArgumentException { 671 if (retry < 0 || retry > 0x0001) 672 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 673 this.mRetry = retry; 674 } 675 getNewMessage()676 public int getNewMessage() { 677 return mNewMessage; 678 } 679 setNewMessage(int newMessage)680 public void setNewMessage(int newMessage) throws IllegalArgumentException { 681 if (newMessage < 0 || newMessage > 0x0001) 682 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 683 this.mNewMessage = newMessage; 684 } 685 getNotificationStatus()686 public int getNotificationStatus() { 687 return mNotificationStatus; 688 } 689 setNotificationStatus(int notificationStatus)690 public void setNotificationStatus(int notificationStatus) throws IllegalArgumentException { 691 if (notificationStatus < 0 || notificationStatus > 0x0001) 692 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 693 this.mNotificationStatus = notificationStatus; 694 } 695 getMasInstanceId()696 public int getMasInstanceId() { 697 return mMasInstanceId; 698 } 699 setMasInstanceId(int masInstanceId)700 public void setMasInstanceId(int masInstanceId) { 701 if (masInstanceId < 0 || masInstanceId > 0x00FF) 702 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 703 this.mMasInstanceId = masInstanceId; 704 } 705 getParameterMask()706 public long getParameterMask() { 707 return mParameterMask; 708 } 709 setParameterMask(long parameterMask)710 public void setParameterMask(long parameterMask) { 711 if (parameterMask < 0 || parameterMask > 0xFFFFFFFFL) 712 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFFFFFF"); 713 this.mParameterMask = parameterMask; 714 } 715 getFolderListingSize()716 public int getFolderListingSize() { 717 return mFolderListingSize; 718 } 719 setFolderListingSize(int folderListingSize)720 public void setFolderListingSize(int folderListingSize) { 721 if (folderListingSize < 0 || folderListingSize > 0xFFFF) 722 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 723 this.mFolderListingSize = folderListingSize; 724 } 725 getMessageListingSize()726 public int getMessageListingSize() { 727 return mMessageListingSize; 728 } 729 setMessageListingSize(int messageListingSize)730 public void setMessageListingSize(int messageListingSize) { 731 if (messageListingSize < 0 || messageListingSize > 0xFFFF) 732 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 733 this.mMessageListingSize = messageListingSize; 734 } 735 getSubjectLength()736 public int getSubjectLength() { 737 return mSubjectLength; 738 } 739 setSubjectLength(int subjectLength)740 public void setSubjectLength(int subjectLength) { 741 if (subjectLength < 0 || subjectLength > 0xFF) 742 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 743 this.mSubjectLength = subjectLength; 744 } 745 getCharset()746 public int getCharset() { 747 return mCharset; 748 } 749 setCharset(int charset)750 public void setCharset(int charset) { 751 if (charset < 0 || charset > 0x1) 752 throw new IllegalArgumentException("Out of range: " + charset + ", valid range is 0x0000 to 0x0001"); 753 this.mCharset = charset; 754 } 755 getFractionRequest()756 public int getFractionRequest() { 757 return mFractionRequest; 758 } 759 setFractionRequest(int fractionRequest)760 public void setFractionRequest(int fractionRequest) { 761 if (fractionRequest < 0 || fractionRequest > 0x1) 762 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 763 this.mFractionRequest = fractionRequest; 764 } 765 getFractionDeliver()766 public int getFractionDeliver() { 767 return mFractionDeliver; 768 } 769 setFractionDeliver(int fractionDeliver)770 public void setFractionDeliver(int fractionDeliver) { 771 if (fractionDeliver < 0 || fractionDeliver > 0x1) 772 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 773 this.mFractionDeliver = fractionDeliver; 774 } 775 getStatusIndicator()776 public int getStatusIndicator() { 777 return mStatusIndicator; 778 } 779 setStatusIndicator(int statusIndicator)780 public void setStatusIndicator(int statusIndicator) { 781 if (statusIndicator < 0 || statusIndicator > 0x1) 782 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 783 this.mStatusIndicator = statusIndicator; 784 } 785 getStatusValue()786 public int getStatusValue() { 787 return mStatusValue; 788 } 789 setStatusValue(int statusValue)790 public void setStatusValue(int statusValue) { 791 if (statusValue < 0 || statusValue > 0x1) 792 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 793 this.mStatusValue = statusValue; 794 } 795 getMseTime()796 public long getMseTime() { 797 return mMseTime; 798 } 799 getMseTimeString()800 public String getMseTimeString() { 801 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 802 Date date = new Date(getMseTime()); 803 return format.format(date); // Format to YYYYMMDDTHHMMSS±hhmm UTC time ± offset 804 } 805 setMseTime(long mseTime)806 public void setMseTime(long mseTime) { 807 this.mMseTime = mseTime; 808 } 809 setMseTime(String mseTime)810 public void setMseTime(String mseTime) throws ParseException { 811 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 812 Date date = format.parse(mseTime); 813 this.mMseTime = date.getTime(); 814 } 815 } 816