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