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 android.bluetooth.BluetoothProfile; 18 import android.bluetooth.BluetoothProtoEnums; 19 import android.util.Log; 20 21 import com.android.bluetooth.BluetoothStatsLog; 22 import com.android.bluetooth.SignedLongLong; 23 import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; 24 25 import java.io.UnsupportedEncodingException; 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 import java.text.ParseException; 29 import java.text.SimpleDateFormat; 30 import java.util.Arrays; 31 import java.util.Date; 32 33 /** This class encapsulates the appParams needed for MAP. */ 34 // Next tag value for ContentProfileErrorReportUtils.report(): 41 35 public class BluetoothMapAppParams { 36 37 private static final String TAG = "BluetoothMapAppParams"; 38 39 private static final int MAX_LIST_COUNT = 0x01; 40 private static final int START_OFFSET = 0x02; 41 private static final int FILTER_MESSAGE_TYPE = 0x03; 42 private static final int FILTER_PERIOD_BEGIN = 0x04; 43 private static final int FILTER_PERIOD_END = 0x05; 44 private static final int FILTER_READ_STATUS = 0x06; 45 private static final int FILTER_RECIPIENT = 0x07; 46 private static final int FILTER_ORIGINATOR = 0x08; 47 private static final int FILTER_PRIORITY = 0x09; 48 private static final int ATTACHMENT = 0x0A; 49 private static final int TRANSPARENT = 0x0B; 50 private static final int RETRY = 0x0C; 51 private static final int NEW_MESSAGE = 0x0D; 52 private static final int NOTIFICATION_STATUS = 0x0E; 53 private static final int MAS_INSTANCE_ID = 0x0F; 54 private static final int PARAMETER_MASK = 0x10; 55 private static final int FOLDER_LISTING_SIZE = 0x11; 56 private static final int MESSAGE_LISTING_SIZE = 0x12; 57 private static final int SUBJECT_LENGTH = 0x13; 58 private static final int CHARSET = 0x14; 59 private static final int FRACTION_REQUEST = 0x15; 60 private static final int FRACTION_DELIVER = 0x16; 61 private static final int STATUS_INDICATOR = 0x17; 62 private static final int STATUS_VALUE = 0x18; 63 private static final int MSE_TIME = 0x19; 64 private static final int DATABASE_INDETIFIER = 0x1A; 65 private static final int CONVO_LIST_VER_COUNTER = 0x1B; 66 private static final int PRESENCE_AVAILABLE = 0x1C; 67 private static final int PRESENCE_TEXT = 0x1D; 68 private static final int LAST_ACTIVITY = 0x1E; 69 private static final int CHAT_STATE = 0x21; 70 private static final int FILTER_CONVO_ID = 0x22; 71 private static final int CONVO_LISTING_SIZE = 0x36; 72 private static final int FILTER_PRESENCE = 0x37; 73 private static final int FILTER_UID_PRESENT = 0x38; 74 private static final int CHAT_STATE_CONVO_ID = 0x39; 75 private static final int FOLDER_VER_COUNTER = 0x23; 76 private static final int FILTER_MESSAGE_HANDLE = 0x24; 77 private static final int NOTIFICATION_FILTER = 0x25; 78 private static final int CONVO_PARAMETER_MASK = 0x26; 79 80 // Length defined for Application Parameters 81 private static final int MAX_LIST_COUNT_LEN = 0x02; // , 0x0000, 0xFFFF), 82 private static final int START_OFFSET_LEN = 0x02; // , 0x0000, 0xFFFF), 83 private static final int FILTER_MESSAGE_TYPE_LEN = 0x01; // , 0x0000, 0x000f), 84 private static final int FILTER_READ_STATUS_LEN = 0x01; // , 0x0000, 0x0002), 85 private static final int FILTER_PRIORITY_LEN = 0x01; // , 0x0000, 0x0002), 86 private static final int ATTACHMENT_LEN = 0x01; // , 0x0000, 0x0001), 87 private static final int TRANSPARENT_LEN = 0x01; // , 0x0000, 0x0001), 88 private static final int RETRY_LEN = 0x01; // , 0x0000, 0x0001), 89 private static final int NEW_MESSAGE_LEN = 0x01; // , 0x0000, 0x0001), 90 private static final int NOTIFICATION_STATUS_LEN = 0x01; // , 0x0000, 0xFFFF), 91 private static final int MAS_INSTANCE_ID_LEN = 0x01; // , 0x0000, 0x00FF), 92 private static final int PARAMETER_MASK_LEN = 0x04; // , 0x0000, 0x0000), 93 private static final int FOLDER_LISTING_SIZE_LEN = 0x02; // , 0x0000, 0xFFFF), 94 private static final int MESSAGE_LISTING_SIZE_LEN = 0x02; // , 0x0000, 0xFFFF), 95 private static final int SUBJECT_LENGTH_LEN = 0x01; // , 0x0000, 0x00FF), 96 private static final int CHARSET_LEN = 0x01; // , 0x0000, 0x0001), 97 private static final int FRACTION_REQUEST_LEN = 0x01; // , 0x0000, 0x0001), 98 private static final int FRACTION_DELIVER_LEN = 0x01; // , 0x0000, 0x0001), 99 private static final int STATUS_INDICATOR_LEN = 0x01; // , 0x0000, 0x0001), 100 private static final int STATUS_VALUE_LEN = 0x01; // , 0x0000, 0x0001), 101 private static final int DATABASE_INDETIFIER_LEN = 0x10; 102 private static final int CONVO_LIST_VER_COUNTER_LEN = 0x10; 103 private static final int PRESENCE_AVAILABLE_LEN = 0X01; 104 private static final int CHAT_STATE_LEN = 0x01; 105 private static final int CHAT_STATE_CONVO_ID_LEN = 0x10; 106 private static final int FILTER_CONVO_ID_LEN = 0x20; 107 private static final int CONVO_LISTING_SIZE_LEN = 0x02; 108 private static final int FILTER_PRESENCE_LEN = 0x01; 109 private static final int FILTER_UID_PRESENT_LEN = 0x01; 110 private static final int FOLDER_VER_COUNTER_LEN = 0x20; 111 private static final int FILTER_MESSAGE_HANDLE_LEN = 0x08; 112 private static final int NOTIFICATION_FILTER_LEN = 0x04; 113 private static final int CONVO_PARAMETER_MASK_LEN = 0x04; 114 115 // Default values 116 public static final int INVALID_VALUE_PARAMETER = -1; 117 public static final int NOTIFICATION_STATUS_NO = 0; 118 public static final int NOTIFICATION_STATUS_YES = 1; 119 public static final int STATUS_INDICATOR_READ = 0; 120 public static final int STATUS_INDICATOR_DELETED = 1; 121 public static final int STATUS_VALUE_YES = 1; 122 public static final int STATUS_VALUE_NO = 0; 123 public static final int CHARSET_NATIVE = 0; 124 public static final int CHARSET_UTF8 = 1; 125 public static final int FRACTION_REQUEST_FIRST = 0; 126 public static final int FRACTION_REQUEST_NEXT = 1; 127 public static final int FRACTION_DELIVER_MORE = 0; 128 public static final int FRACTION_DELIVER_LAST = 1; 129 130 public static final int FILTER_NO_SMS_GSM = 0x01; 131 public static final int FILTER_NO_SMS_CDMA = 0x02; 132 public static final int FILTER_NO_EMAIL = 0x04; 133 public static final int FILTER_NO_MMS = 0x08; 134 public static final int FILTER_NO_IM = 0x10; 135 public static final int FILTER_MSG_TYPE_MASK = 0x1F; 136 137 private int mMaxListCount = INVALID_VALUE_PARAMETER; 138 private int mStartOffset = INVALID_VALUE_PARAMETER; 139 private int mFilterMessageType = INVALID_VALUE_PARAMETER; 140 // It seems like these are not implemented... 141 private long mFilterPeriodBegin = INVALID_VALUE_PARAMETER; 142 private long mFilterPeriodEnd = INVALID_VALUE_PARAMETER; 143 private int mFilterReadStatus = INVALID_VALUE_PARAMETER; 144 private String mFilterRecipient = null; 145 private String mFilterOriginator = null; 146 private int mFilterPriority = INVALID_VALUE_PARAMETER; 147 private int mAttachment = INVALID_VALUE_PARAMETER; 148 private int mTransparent = INVALID_VALUE_PARAMETER; 149 private int mRetry = INVALID_VALUE_PARAMETER; 150 private int mNewMessage = INVALID_VALUE_PARAMETER; 151 private int mNotificationStatus = INVALID_VALUE_PARAMETER; 152 private long mNotificationFilter = INVALID_VALUE_PARAMETER; 153 private int mMasInstanceId = INVALID_VALUE_PARAMETER; 154 private long mParameterMask = INVALID_VALUE_PARAMETER; 155 private int mFolderListingSize = INVALID_VALUE_PARAMETER; 156 private int mMessageListingSize = INVALID_VALUE_PARAMETER; 157 private int mConvoListingSize = INVALID_VALUE_PARAMETER; 158 private int mSubjectLength = INVALID_VALUE_PARAMETER; 159 private int mCharset = INVALID_VALUE_PARAMETER; 160 private int mFractionRequest = INVALID_VALUE_PARAMETER; 161 private int mFractionDeliver = INVALID_VALUE_PARAMETER; 162 private int mStatusIndicator = INVALID_VALUE_PARAMETER; 163 private int mStatusValue = INVALID_VALUE_PARAMETER; 164 private long mMseTime = INVALID_VALUE_PARAMETER; 165 // TODO: Change to use SignedLongLong? 166 private long mConvoListingVerCounterLow = INVALID_VALUE_PARAMETER; 167 private long mConvoListingVerCounterHigh = INVALID_VALUE_PARAMETER; 168 private long mDatabaseIdentifierLow = INVALID_VALUE_PARAMETER; 169 private long mDatabaseIdentifierHigh = INVALID_VALUE_PARAMETER; 170 private long mFolderVerCounterLow = INVALID_VALUE_PARAMETER; 171 private long mFolderVerCounterHigh = INVALID_VALUE_PARAMETER; 172 private int mPresenceAvailability = INVALID_VALUE_PARAMETER; 173 private String mPresenceStatus = null; 174 private long mLastActivity = INVALID_VALUE_PARAMETER; 175 private int mChatState = INVALID_VALUE_PARAMETER; 176 private SignedLongLong mFilterConvoId = null; 177 private int mFilterPresence = INVALID_VALUE_PARAMETER; 178 private int mFilterUidPresent = INVALID_VALUE_PARAMETER; 179 private SignedLongLong mChatStateConvoId = null; 180 private long mFilterMsgHandle = INVALID_VALUE_PARAMETER; 181 private long mConvoParameterMask = INVALID_VALUE_PARAMETER; 182 183 /** 184 * Default constructor, used to build an application parameter object to be encoded. By default 185 * the member variables will be initialized to {@link INVALID_VALUE_PARAMETER} for values, and 186 * empty strings for String typed members. 187 */ BluetoothMapAppParams()188 public BluetoothMapAppParams() {} 189 190 /** 191 * Creates an application parameter object based on a application parameter OBEX header. The 192 * content of the {@link appParam} byte array will be parsed, and its content will be stored in 193 * the member variables. {@link INVALID_VALUE_PARAMETER} can be used to determine if a value is 194 * set or not, where strings will be empty, if {@link appParam} did not contain the parameter. 195 * 196 * @param appParams the byte array containing the application parameters OBEX header 197 * @throws IllegalArgumentException when a parameter does not respect the valid ranges specified 198 * in the MAP spec. 199 * @throws ParseException if a parameter string if formated incorrectly. 200 */ BluetoothMapAppParams(final byte[] appParams)201 public BluetoothMapAppParams(final byte[] appParams) 202 throws IllegalArgumentException, ParseException { 203 parseParams(appParams); 204 } 205 206 /** 207 * Parse an application parameter OBEX header stored in a byte array. 208 * 209 * @param appParams the byte array containing the application parameters OBEX header 210 * @throws IllegalArgumentException when a parameter does not respect the valid ranges specified 211 * in the MAP spec. 212 * @throws ParseException if a parameter string if formated incorrectly. 213 */ parseParams(final byte[] appParams)214 private void parseParams(final byte[] appParams) 215 throws ParseException, IllegalArgumentException { 216 int i = 0; 217 int tagId, tagLength; 218 ByteBuffer appParamBuf = ByteBuffer.wrap(appParams); 219 appParamBuf.order(ByteOrder.BIG_ENDIAN); 220 while (i < appParams.length) { 221 tagId = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 222 tagLength = appParams[i++] & 0xff; // Convert to unsigned to support values above 127 223 switch (tagId) { 224 case MAX_LIST_COUNT: 225 if (tagLength != MAX_LIST_COUNT_LEN) { 226 Log.w( 227 TAG, 228 "MAX_LIST_COUNT: Wrong length received: " 229 + tagLength 230 + " expected: " 231 + MAX_LIST_COUNT_LEN); 232 ContentProfileErrorReportUtils.report( 233 BluetoothProfile.MAP, 234 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 235 BluetoothStatsLog 236 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 237 0); 238 } else { 239 setMaxListCount(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 240 } 241 break; 242 case START_OFFSET: 243 if (tagLength != START_OFFSET_LEN) { 244 Log.w( 245 TAG, 246 "START_OFFSET: Wrong length received: " 247 + tagLength 248 + " expected: " 249 + START_OFFSET_LEN); 250 ContentProfileErrorReportUtils.report( 251 BluetoothProfile.MAP, 252 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 253 BluetoothStatsLog 254 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 255 1); 256 } else { 257 setStartOffset(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 258 } 259 break; 260 case FILTER_MESSAGE_TYPE: 261 if (tagLength != FILTER_MESSAGE_TYPE_LEN) { 262 Log.w( 263 TAG, 264 "FILTER_MESSAGE_TYPE: Wrong length received: " 265 + tagLength 266 + " expected: " 267 + FILTER_MESSAGE_TYPE_LEN); 268 ContentProfileErrorReportUtils.report( 269 BluetoothProfile.MAP, 270 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 271 BluetoothStatsLog 272 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 273 2); 274 } else { 275 setFilterMessageType(appParams[i] & 0x1f); 276 } 277 break; 278 case FILTER_PERIOD_BEGIN: 279 if (tagLength != 0) { 280 setFilterPeriodBegin(new String(appParams, i, tagLength)); 281 } else { 282 Log.w( 283 TAG, 284 "FILTER_PERIOD_BEGIN: Wrong length received: " 285 + tagLength 286 + " expected to be more than 0"); 287 ContentProfileErrorReportUtils.report( 288 BluetoothProfile.MAP, 289 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 290 BluetoothStatsLog 291 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 292 3); 293 } 294 break; 295 case FILTER_PERIOD_END: 296 if (tagLength != 0) { 297 setFilterPeriodEnd(new String(appParams, i, tagLength)); 298 } else { 299 Log.w( 300 TAG, 301 "FILTER_PERIOD_END: Wrong length received: " 302 + tagLength 303 + " expected to be more than 0"); 304 ContentProfileErrorReportUtils.report( 305 BluetoothProfile.MAP, 306 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 307 BluetoothStatsLog 308 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 309 4); 310 } 311 break; 312 case FILTER_READ_STATUS: 313 if (tagLength != FILTER_READ_STATUS_LEN) { 314 Log.w( 315 TAG, 316 "FILTER_READ_STATUS: Wrong length received: " 317 + tagLength 318 + " expected: " 319 + FILTER_READ_STATUS_LEN); 320 ContentProfileErrorReportUtils.report( 321 BluetoothProfile.MAP, 322 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 323 BluetoothStatsLog 324 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 325 5); 326 } else { 327 setFilterReadStatus(appParams[i] & 0x03); // Lower two bits 328 } 329 break; 330 case FILTER_RECIPIENT: 331 if (tagLength != 0) { 332 setFilterRecipient(new String(appParams, i, tagLength)); 333 } else { 334 Log.w( 335 TAG, 336 "FILTER_RECIPIENT: Wrong length received: " 337 + tagLength 338 + " expected to be more than 0"); 339 ContentProfileErrorReportUtils.report( 340 BluetoothProfile.MAP, 341 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 342 BluetoothStatsLog 343 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 344 6); 345 } 346 break; 347 case FILTER_ORIGINATOR: 348 if (tagLength != 0) { 349 setFilterOriginator(new String(appParams, i, tagLength)); 350 } else { 351 Log.w( 352 TAG, 353 "FILTER_ORIGINATOR: Wrong length received: " 354 + tagLength 355 + " expected to be more than 0"); 356 ContentProfileErrorReportUtils.report( 357 BluetoothProfile.MAP, 358 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 359 BluetoothStatsLog 360 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 361 7); 362 } 363 break; 364 case FILTER_PRIORITY: 365 if (tagLength != FILTER_PRIORITY_LEN) { 366 Log.w( 367 TAG, 368 "FILTER_PRIORITY: Wrong length received: " 369 + tagLength 370 + " expected: " 371 + FILTER_PRIORITY_LEN); 372 ContentProfileErrorReportUtils.report( 373 BluetoothProfile.MAP, 374 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 375 BluetoothStatsLog 376 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 377 8); 378 } else { 379 setFilterPriority(appParams[i] & 0x03); // Lower two bits 380 } 381 break; 382 case ATTACHMENT: 383 if (tagLength != ATTACHMENT_LEN) { 384 Log.w( 385 TAG, 386 "ATTACHMENT: Wrong length received: " 387 + tagLength 388 + " expected: " 389 + ATTACHMENT_LEN); 390 ContentProfileErrorReportUtils.report( 391 BluetoothProfile.MAP, 392 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 393 BluetoothStatsLog 394 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 395 9); 396 } else { 397 setAttachment(appParams[i] & 0x01); // Lower bit 398 } 399 break; 400 case TRANSPARENT: 401 if (tagLength != TRANSPARENT_LEN) { 402 Log.w( 403 TAG, 404 "TRANSPARENT: Wrong length received: " 405 + tagLength 406 + " expected: " 407 + TRANSPARENT_LEN); 408 ContentProfileErrorReportUtils.report( 409 BluetoothProfile.MAP, 410 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 411 BluetoothStatsLog 412 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 413 10); 414 } else { 415 setTransparent(appParams[i] & 0x01); // Lower bit 416 } 417 break; 418 case RETRY: 419 if (tagLength != RETRY_LEN) { 420 Log.w( 421 TAG, 422 "RETRY: Wrong length received: " 423 + tagLength 424 + " expected: " 425 + RETRY_LEN); 426 ContentProfileErrorReportUtils.report( 427 BluetoothProfile.MAP, 428 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 429 BluetoothStatsLog 430 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 431 11); 432 } else { 433 setRetry(appParams[i] & 0x01); // Lower bit 434 } 435 break; 436 case NEW_MESSAGE: 437 if (tagLength != NEW_MESSAGE_LEN) { 438 Log.w( 439 TAG, 440 "NEW_MESSAGE: Wrong length received: " 441 + tagLength 442 + " expected: " 443 + NEW_MESSAGE_LEN); 444 ContentProfileErrorReportUtils.report( 445 BluetoothProfile.MAP, 446 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 447 BluetoothStatsLog 448 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 449 12); 450 } else { 451 setNewMessage(appParams[i] & 0x01); // Lower bit 452 } 453 break; 454 case NOTIFICATION_STATUS: 455 if (tagLength != NOTIFICATION_STATUS_LEN) { 456 Log.w( 457 TAG, 458 "NOTIFICATION_STATUS: Wrong length received: " 459 + tagLength 460 + " expected: " 461 + NOTIFICATION_STATUS_LEN); 462 ContentProfileErrorReportUtils.report( 463 BluetoothProfile.MAP, 464 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 465 BluetoothStatsLog 466 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 467 13); 468 } else { 469 setNotificationStatus(appParams[i] & 0x01); // Lower bit 470 } 471 break; 472 case NOTIFICATION_FILTER: 473 if (tagLength != NOTIFICATION_FILTER_LEN) { 474 Log.w( 475 TAG, 476 "NOTIFICATION_FILTER: Wrong length received: " 477 + tagLength 478 + " expected: " 479 + NOTIFICATION_FILTER_LEN); 480 ContentProfileErrorReportUtils.report( 481 BluetoothProfile.MAP, 482 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 483 BluetoothStatsLog 484 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 485 14); 486 } else { 487 setNotificationFilter(appParamBuf.getInt(i) & 0xffffffffL); // 4 bytes 488 } 489 break; 490 case MAS_INSTANCE_ID: 491 if (tagLength != MAS_INSTANCE_ID_LEN) { 492 Log.w( 493 TAG, 494 "MAS_INSTANCE_ID: Wrong length received: " 495 + tagLength 496 + " expected: " 497 + MAS_INSTANCE_ID_LEN); 498 ContentProfileErrorReportUtils.report( 499 BluetoothProfile.MAP, 500 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 501 BluetoothStatsLog 502 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 503 15); 504 } else { 505 setMasInstanceId(appParams[i] & 0xff); 506 } 507 break; 508 case PARAMETER_MASK: 509 if (tagLength != PARAMETER_MASK_LEN) { 510 Log.w( 511 TAG, 512 "PARAMETER_MASK: Wrong length received: " 513 + tagLength 514 + " expected: " 515 + PARAMETER_MASK_LEN); 516 ContentProfileErrorReportUtils.report( 517 BluetoothProfile.MAP, 518 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 519 BluetoothStatsLog 520 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 521 16); 522 } else { 523 setParameterMask(appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned 524 } 525 break; 526 case FOLDER_LISTING_SIZE: 527 if (tagLength != FOLDER_LISTING_SIZE_LEN) { 528 Log.w( 529 TAG, 530 "FOLDER_LISTING_SIZE: Wrong length received: " 531 + tagLength 532 + " expected: " 533 + FOLDER_LISTING_SIZE_LEN); 534 ContentProfileErrorReportUtils.report( 535 BluetoothProfile.MAP, 536 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 537 BluetoothStatsLog 538 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 539 17); 540 } else { 541 setFolderListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 542 } 543 break; 544 case MESSAGE_LISTING_SIZE: 545 if (tagLength != MESSAGE_LISTING_SIZE_LEN) { 546 Log.w( 547 TAG, 548 "MESSAGE_LISTING_SIZE: Wrong length received: " 549 + tagLength 550 + " expected: " 551 + MESSAGE_LISTING_SIZE_LEN); 552 ContentProfileErrorReportUtils.report( 553 BluetoothProfile.MAP, 554 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 555 BluetoothStatsLog 556 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 557 18); 558 } else { 559 setMessageListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned 560 } 561 break; 562 case SUBJECT_LENGTH: 563 if (tagLength != SUBJECT_LENGTH_LEN) { 564 Log.w( 565 TAG, 566 "SUBJECT_LENGTH: Wrong length received: " 567 + tagLength 568 + " expected: " 569 + SUBJECT_LENGTH_LEN); 570 ContentProfileErrorReportUtils.report( 571 BluetoothProfile.MAP, 572 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 573 BluetoothStatsLog 574 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 575 19); 576 } else { 577 setSubjectLength(appParams[i] & 0xff); 578 } 579 break; 580 case CHARSET: 581 if (tagLength != CHARSET_LEN) { 582 Log.w( 583 TAG, 584 "CHARSET: Wrong length received: " 585 + tagLength 586 + " expected: " 587 + CHARSET_LEN); 588 ContentProfileErrorReportUtils.report( 589 BluetoothProfile.MAP, 590 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 591 BluetoothStatsLog 592 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 593 20); 594 } else { 595 setCharset(appParams[i] & 0x01); // Lower bit 596 } 597 break; 598 case FRACTION_REQUEST: 599 if (tagLength != FRACTION_REQUEST_LEN) { 600 Log.w( 601 TAG, 602 "FRACTION_REQUEST: Wrong length received: " 603 + tagLength 604 + " expected: " 605 + FRACTION_REQUEST_LEN); 606 ContentProfileErrorReportUtils.report( 607 BluetoothProfile.MAP, 608 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 609 BluetoothStatsLog 610 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 611 21); 612 } else { 613 setFractionRequest(appParams[i] & 0x01); // Lower bit 614 } 615 break; 616 case FRACTION_DELIVER: 617 if (tagLength != FRACTION_DELIVER_LEN) { 618 Log.w( 619 TAG, 620 "FRACTION_DELIVER: Wrong length received: " 621 + tagLength 622 + " expected: " 623 + FRACTION_DELIVER_LEN); 624 ContentProfileErrorReportUtils.report( 625 BluetoothProfile.MAP, 626 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 627 BluetoothStatsLog 628 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 629 22); 630 } else { 631 setFractionDeliver(appParams[i] & 0x01); // Lower bit 632 } 633 break; 634 case STATUS_INDICATOR: 635 if (tagLength != STATUS_INDICATOR_LEN) { 636 Log.w( 637 TAG, 638 "STATUS_INDICATOR: Wrong length received: " 639 + tagLength 640 + " expected: " 641 + STATUS_INDICATOR_LEN); 642 ContentProfileErrorReportUtils.report( 643 BluetoothProfile.MAP, 644 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 645 BluetoothStatsLog 646 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 647 23); 648 } else { 649 setStatusIndicator(appParams[i] & 0x01); // Lower bit 650 } 651 break; 652 case STATUS_VALUE: 653 if (tagLength != STATUS_VALUE_LEN) { 654 Log.w( 655 TAG, 656 "STATUS_VALUER: Wrong length received: " 657 + tagLength 658 + " expected: " 659 + STATUS_VALUE_LEN); 660 ContentProfileErrorReportUtils.report( 661 BluetoothProfile.MAP, 662 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 663 BluetoothStatsLog 664 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 665 24); 666 } else { 667 setStatusValue(appParams[i] & 0x01); // Lower bit 668 } 669 break; 670 case MSE_TIME: 671 setMseTime(new String(appParams, i, tagLength)); 672 break; 673 case DATABASE_INDETIFIER: 674 if ((tagLength != DATABASE_INDETIFIER_LEN)) { 675 Log.w( 676 TAG, 677 "DATABASE_IDENTIFIER: Wrong length received: " 678 + tagLength 679 + " expected: " 680 + DATABASE_INDETIFIER_LEN); 681 ContentProfileErrorReportUtils.report( 682 BluetoothProfile.MAP, 683 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 684 BluetoothStatsLog 685 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 686 25); 687 } else { 688 setDatabaseIdentifier( 689 appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); 690 } 691 break; 692 case CONVO_LIST_VER_COUNTER: 693 if ((tagLength != CONVO_LIST_VER_COUNTER_LEN)) { 694 Log.w( 695 TAG, 696 "CONVO_LIST_VER_COUNTER: Wrong length received: " 697 + tagLength 698 + " expected: " 699 + CONVO_LIST_VER_COUNTER_LEN); 700 ContentProfileErrorReportUtils.report( 701 BluetoothProfile.MAP, 702 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 703 BluetoothStatsLog 704 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 705 26); 706 } else { 707 setConvoListingVerCounter( 708 appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); 709 } 710 break; 711 case PRESENCE_AVAILABLE: 712 if ((tagLength != PRESENCE_AVAILABLE_LEN)) { 713 Log.w( 714 TAG, 715 "PRESENCE_AVAILABLE: Wrong length received: " 716 + tagLength 717 + " expected: " 718 + PRESENCE_AVAILABLE_LEN); 719 ContentProfileErrorReportUtils.report( 720 BluetoothProfile.MAP, 721 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 722 BluetoothStatsLog 723 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 724 27); 725 } else { 726 setPresenceAvailability(appParams[i]); 727 } 728 break; 729 case PRESENCE_TEXT: 730 if (tagLength != 0) { 731 setPresenceStatus(new String(appParams, i, tagLength)); 732 } else { 733 Log.w( 734 TAG, 735 "PRESENCE_STATUS: Wrong length received: " 736 + tagLength 737 + " expected to be more than 0"); 738 ContentProfileErrorReportUtils.report( 739 BluetoothProfile.MAP, 740 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 741 BluetoothStatsLog 742 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 743 28); 744 } 745 break; 746 case LAST_ACTIVITY: 747 if (tagLength != 0) { 748 setLastActivity(new String(appParams, i, tagLength)); 749 } else { 750 Log.w( 751 TAG, 752 "LAST_ACTIVITY: Wrong length received: " 753 + tagLength 754 + " expected to be more than 0"); 755 ContentProfileErrorReportUtils.report( 756 BluetoothProfile.MAP, 757 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 758 BluetoothStatsLog 759 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 760 29); 761 } 762 break; 763 case CHAT_STATE: 764 if ((tagLength != CHAT_STATE_LEN)) { 765 Log.w( 766 TAG, 767 "CHAT_STATE: Wrong length received: " 768 + tagLength 769 + " expected: " 770 + CHAT_STATE_LEN); 771 ContentProfileErrorReportUtils.report( 772 BluetoothProfile.MAP, 773 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 774 BluetoothStatsLog 775 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 776 30); 777 } else { 778 setChatState(appParams[i]); 779 } 780 break; 781 case FILTER_CONVO_ID: 782 if ((tagLength != 0) && (tagLength <= FILTER_CONVO_ID_LEN)) { 783 setFilterConvoId(new String(appParams, i, tagLength)); 784 } else { 785 Log.w( 786 TAG, 787 "FILTER_CONVO_ID: Wrong length received: " 788 + tagLength 789 + " expected: " 790 + FILTER_CONVO_ID_LEN); 791 ContentProfileErrorReportUtils.report( 792 BluetoothProfile.MAP, 793 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 794 BluetoothStatsLog 795 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 796 31); 797 } 798 break; 799 case CONVO_LISTING_SIZE: 800 if (tagLength != CONVO_LISTING_SIZE_LEN) { 801 Log.w( 802 TAG, 803 "LISTING_SIZE: Wrong length received: " 804 + tagLength 805 + " expected: " 806 + CONVO_LISTING_SIZE_LEN); 807 ContentProfileErrorReportUtils.report( 808 BluetoothProfile.MAP, 809 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 810 BluetoothStatsLog 811 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 812 32); 813 } else { 814 setConvoListingSize(appParamBuf.getShort(i) & 0xffff); 815 } 816 break; 817 case FILTER_PRESENCE: 818 if ((tagLength != FILTER_PRESENCE_LEN)) { 819 Log.w( 820 TAG, 821 "FILTER_PRESENCE: Wrong length received: " 822 + tagLength 823 + " expected: " 824 + FILTER_PRESENCE_LEN); 825 ContentProfileErrorReportUtils.report( 826 BluetoothProfile.MAP, 827 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 828 BluetoothStatsLog 829 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 830 33); 831 } else { 832 setFilterPresence(appParams[i]); 833 } 834 break; 835 case FILTER_UID_PRESENT: 836 if ((tagLength != FILTER_UID_PRESENT_LEN)) { 837 Log.w( 838 TAG, 839 "FILTER_UID_PRESENT: Wrong length received: " 840 + tagLength 841 + " expected: " 842 + FILTER_UID_PRESENT_LEN); 843 ContentProfileErrorReportUtils.report( 844 BluetoothProfile.MAP, 845 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 846 BluetoothStatsLog 847 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 848 34); 849 } else { 850 setFilterUidPresent(appParams[i] & 0x1); 851 } 852 break; 853 case CHAT_STATE_CONVO_ID: 854 if ((tagLength != CHAT_STATE_CONVO_ID_LEN)) { 855 Log.w( 856 TAG, 857 "CHAT_STATE_CONVO_ID: Wrong length received: " 858 + tagLength 859 + " expected: " 860 + CHAT_STATE_CONVO_ID_LEN); 861 ContentProfileErrorReportUtils.report( 862 BluetoothProfile.MAP, 863 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 864 BluetoothStatsLog 865 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 866 35); 867 } else { 868 /* TODO: Is this correct convoId handling? */ 869 setChatStateConvoId( 870 appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); 871 Log.d( 872 TAG, 873 "CHAT_STATE_CONVO_ID: convo id " 874 + "MSB=" 875 + BluetoothMapUtils.getLongAsString(appParamBuf.getLong(i)) 876 + ", LSB(+8)=" 877 + BluetoothMapUtils.getLongAsString( 878 appParamBuf.getLong(i + 8))); 879 } 880 break; 881 case FOLDER_VER_COUNTER: 882 break; 883 case FILTER_MESSAGE_HANDLE: 884 if ((tagLength != 0 && tagLength <= FILTER_MESSAGE_HANDLE_LEN)) { 885 setFilterMsgHandle(new String(appParams, i, tagLength)); 886 } else { 887 Log.w( 888 TAG, 889 "FILTER_MESSAGE_HANDLE: Wrong length received: " 890 + tagLength 891 + " expected: " 892 + FILTER_MESSAGE_HANDLE_LEN); 893 ContentProfileErrorReportUtils.report( 894 BluetoothProfile.MAP, 895 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 896 BluetoothStatsLog 897 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 898 36); 899 } 900 901 break; 902 case CONVO_PARAMETER_MASK: 903 if (tagLength != CONVO_PARAMETER_MASK_LEN) { 904 Log.w( 905 TAG, 906 "CONVO_PARAMETER_MASK: Wrong length received: " 907 + tagLength 908 + " expected: " 909 + CONVO_PARAMETER_MASK_LEN); 910 ContentProfileErrorReportUtils.report( 911 BluetoothProfile.MAP, 912 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 913 BluetoothStatsLog 914 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 915 37); 916 } else { 917 setConvoParameterMask( 918 appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned 919 } 920 break; 921 default: 922 // Just skip unknown Tags, no need to report error 923 Log.w( 924 TAG, 925 "Unknown TagId received ( 0x" 926 + Integer.toString(tagId, 16) 927 + "), skipping..."); 928 ContentProfileErrorReportUtils.report( 929 BluetoothProfile.MAP, 930 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 931 BluetoothStatsLog 932 .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, 933 38); 934 break; 935 } 936 i += tagLength; // Offset to next TagId 937 } 938 } 939 940 /** 941 * Get the approximate length needed to store the appParameters in a byte array. 942 * 943 * @return the length in bytes 944 * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. 945 */ getParamMaxLength()946 private int getParamMaxLength() throws UnsupportedEncodingException { 947 int length = 0; 948 length += 38 * 2; // tagId + tagLength 949 length += 33 + 4 * 16; // fixed sizes TODO: Update when spec is ready 950 length += getFilterPeriodBegin() == INVALID_VALUE_PARAMETER ? 0 : 20; 951 length += getFilterPeriodEnd() == INVALID_VALUE_PARAMETER ? 0 : 20; 952 if (getFilterRecipient() != null) { 953 length += getFilterRecipient().getBytes("UTF-8").length; 954 } 955 if (getFilterOriginator() != null) { 956 length += getFilterOriginator().getBytes("UTF-8").length; 957 } 958 length += getMseTime() == INVALID_VALUE_PARAMETER ? 0 : 20; 959 if (getPresenceStatus() != null) { 960 length += getPresenceStatus().getBytes("UTF-8").length; 961 } 962 length += (getLastActivity() == INVALID_VALUE_PARAMETER) ? 0 : 20; 963 return length; 964 } 965 966 /** 967 * Encode the application parameter object to a byte array. 968 * 969 * @return a byte Array representation of the application parameter object. 970 * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. 971 */ encodeParams()972 public byte[] encodeParams() throws UnsupportedEncodingException { 973 ByteBuffer appParamBuf = ByteBuffer.allocate(getParamMaxLength()); 974 appParamBuf.order(ByteOrder.BIG_ENDIAN); 975 byte[] retBuf; 976 977 if (getMaxListCount() != INVALID_VALUE_PARAMETER) { 978 appParamBuf.put((byte) MAX_LIST_COUNT); 979 appParamBuf.put((byte) MAX_LIST_COUNT_LEN); 980 appParamBuf.putShort((short) getMaxListCount()); 981 } 982 if (getStartOffset() != INVALID_VALUE_PARAMETER) { 983 appParamBuf.put((byte) START_OFFSET); 984 appParamBuf.put((byte) START_OFFSET_LEN); 985 appParamBuf.putShort((short) getStartOffset()); 986 } 987 if (getFilterMessageType() != INVALID_VALUE_PARAMETER) { 988 appParamBuf.put((byte) FILTER_MESSAGE_TYPE); 989 appParamBuf.put((byte) FILTER_MESSAGE_TYPE_LEN); 990 appParamBuf.put((byte) getFilterMessageType()); 991 } 992 if (getFilterPeriodBegin() != INVALID_VALUE_PARAMETER) { 993 appParamBuf.put((byte) FILTER_PERIOD_BEGIN); 994 appParamBuf.put((byte) getFilterPeriodBeginString().getBytes("UTF-8").length); 995 appParamBuf.put(getFilterPeriodBeginString().getBytes("UTF-8")); 996 } 997 if (getFilterPeriodEnd() != INVALID_VALUE_PARAMETER) { 998 appParamBuf.put((byte) FILTER_PERIOD_END); 999 appParamBuf.put((byte) getFilterPeriodEndString().getBytes("UTF-8").length); 1000 appParamBuf.put(getFilterPeriodEndString().getBytes("UTF-8")); 1001 } 1002 if (getFilterReadStatus() != INVALID_VALUE_PARAMETER) { 1003 appParamBuf.put((byte) FILTER_READ_STATUS); 1004 appParamBuf.put((byte) FILTER_READ_STATUS_LEN); 1005 appParamBuf.put((byte) getFilterReadStatus()); 1006 } 1007 if (getFilterRecipient() != null) { 1008 appParamBuf.put((byte) FILTER_RECIPIENT); 1009 appParamBuf.put((byte) getFilterRecipient().getBytes("UTF-8").length); 1010 appParamBuf.put(getFilterRecipient().getBytes("UTF-8")); 1011 } 1012 if (getFilterOriginator() != null) { 1013 appParamBuf.put((byte) FILTER_ORIGINATOR); 1014 appParamBuf.put((byte) getFilterOriginator().getBytes("UTF-8").length); 1015 appParamBuf.put(getFilterOriginator().getBytes("UTF-8")); 1016 } 1017 if (getFilterPriority() != INVALID_VALUE_PARAMETER) { 1018 appParamBuf.put((byte) FILTER_PRIORITY); 1019 appParamBuf.put((byte) FILTER_PRIORITY_LEN); 1020 appParamBuf.put((byte) getFilterPriority()); 1021 } 1022 if (getAttachment() != INVALID_VALUE_PARAMETER) { 1023 appParamBuf.put((byte) ATTACHMENT); 1024 appParamBuf.put((byte) ATTACHMENT_LEN); 1025 appParamBuf.put((byte) getAttachment()); 1026 } 1027 if (getTransparent() != INVALID_VALUE_PARAMETER) { 1028 appParamBuf.put((byte) TRANSPARENT); 1029 appParamBuf.put((byte) TRANSPARENT_LEN); 1030 appParamBuf.put((byte) getTransparent()); 1031 } 1032 if (getRetry() != INVALID_VALUE_PARAMETER) { 1033 appParamBuf.put((byte) RETRY); 1034 appParamBuf.put((byte) RETRY_LEN); 1035 appParamBuf.put((byte) getRetry()); 1036 } 1037 if (getNewMessage() != INVALID_VALUE_PARAMETER) { 1038 appParamBuf.put((byte) NEW_MESSAGE); 1039 appParamBuf.put((byte) NEW_MESSAGE_LEN); 1040 appParamBuf.put((byte) getNewMessage()); 1041 } 1042 if (getNotificationStatus() != INVALID_VALUE_PARAMETER) { 1043 appParamBuf.put((byte) NOTIFICATION_STATUS); 1044 appParamBuf.put((byte) NOTIFICATION_STATUS_LEN); 1045 appParamBuf.putShort((short) getNotificationStatus()); 1046 } 1047 if (getNotificationFilter() != INVALID_VALUE_PARAMETER) { 1048 appParamBuf.put((byte) NOTIFICATION_FILTER); 1049 appParamBuf.put((byte) NOTIFICATION_FILTER_LEN); 1050 appParamBuf.putInt((int) getNotificationFilter()); 1051 } 1052 if (getMasInstanceId() != INVALID_VALUE_PARAMETER) { 1053 appParamBuf.put((byte) MAS_INSTANCE_ID); 1054 appParamBuf.put((byte) MAS_INSTANCE_ID_LEN); 1055 appParamBuf.put((byte) getMasInstanceId()); 1056 } 1057 if (getParameterMask() != INVALID_VALUE_PARAMETER) { 1058 appParamBuf.put((byte) PARAMETER_MASK); 1059 appParamBuf.put((byte) PARAMETER_MASK_LEN); 1060 appParamBuf.putInt((int) getParameterMask()); 1061 } 1062 if (getFolderListingSize() != INVALID_VALUE_PARAMETER) { 1063 appParamBuf.put((byte) FOLDER_LISTING_SIZE); 1064 appParamBuf.put((byte) FOLDER_LISTING_SIZE_LEN); 1065 appParamBuf.putShort((short) getFolderListingSize()); 1066 } 1067 if (getMessageListingSize() != INVALID_VALUE_PARAMETER) { 1068 appParamBuf.put((byte) MESSAGE_LISTING_SIZE); 1069 appParamBuf.put((byte) MESSAGE_LISTING_SIZE_LEN); 1070 appParamBuf.putShort((short) getMessageListingSize()); 1071 } 1072 if (getSubjectLength() != INVALID_VALUE_PARAMETER) { 1073 appParamBuf.put((byte) SUBJECT_LENGTH); 1074 appParamBuf.put((byte) SUBJECT_LENGTH_LEN); 1075 appParamBuf.put((byte) getSubjectLength()); 1076 } 1077 if (getCharset() != INVALID_VALUE_PARAMETER) { 1078 appParamBuf.put((byte) CHARSET); 1079 appParamBuf.put((byte) CHARSET_LEN); 1080 appParamBuf.put((byte) getCharset()); 1081 } 1082 if (getFractionRequest() != INVALID_VALUE_PARAMETER) { 1083 appParamBuf.put((byte) FRACTION_REQUEST); 1084 appParamBuf.put((byte) FRACTION_REQUEST_LEN); 1085 appParamBuf.put((byte) getFractionRequest()); 1086 } 1087 if (getFractionDeliver() != INVALID_VALUE_PARAMETER) { 1088 appParamBuf.put((byte) FRACTION_DELIVER); 1089 appParamBuf.put((byte) FRACTION_DELIVER_LEN); 1090 appParamBuf.put((byte) getFractionDeliver()); 1091 } 1092 if (getStatusIndicator() != INVALID_VALUE_PARAMETER) { 1093 appParamBuf.put((byte) STATUS_INDICATOR); 1094 appParamBuf.put((byte) STATUS_INDICATOR_LEN); 1095 appParamBuf.put((byte) getStatusIndicator()); 1096 } 1097 if (getStatusValue() != INVALID_VALUE_PARAMETER) { 1098 appParamBuf.put((byte) STATUS_VALUE); 1099 appParamBuf.put((byte) STATUS_VALUE_LEN); 1100 appParamBuf.put((byte) getStatusValue()); 1101 } 1102 if (getMseTime() != INVALID_VALUE_PARAMETER) { 1103 appParamBuf.put((byte) MSE_TIME); 1104 appParamBuf.put((byte) getMseTimeString().getBytes("UTF-8").length); 1105 appParamBuf.put(getMseTimeString().getBytes("UTF-8")); 1106 } 1107 // Note: New for IM 1108 if (getDatabaseIdentifier() != null) { 1109 appParamBuf.put((byte) DATABASE_INDETIFIER); 1110 appParamBuf.put((byte) DATABASE_INDETIFIER_LEN); 1111 appParamBuf.put(getDatabaseIdentifier()); 1112 } 1113 if (getConvoListingVerCounter() != null) { 1114 appParamBuf.put((byte) CONVO_LIST_VER_COUNTER); 1115 appParamBuf.put((byte) CONVO_LIST_VER_COUNTER_LEN); 1116 appParamBuf.put(getConvoListingVerCounter()); 1117 } 1118 if (getPresenceAvailability() != INVALID_VALUE_PARAMETER) { 1119 appParamBuf.put((byte) PRESENCE_AVAILABLE); 1120 appParamBuf.put((byte) PRESENCE_AVAILABLE_LEN); 1121 appParamBuf.putInt((int) getPresenceAvailability()); 1122 } 1123 if (getPresenceStatus() != null) { 1124 appParamBuf.put((byte) PRESENCE_TEXT); 1125 appParamBuf.put((byte) getPresenceStatus().getBytes("UTF-8").length); 1126 appParamBuf.put(getPresenceStatus().getBytes()); 1127 } 1128 if (getLastActivity() != INVALID_VALUE_PARAMETER) { 1129 appParamBuf.put((byte) LAST_ACTIVITY); 1130 appParamBuf.put((byte) getLastActivityString().getBytes("UTF-8").length); 1131 appParamBuf.put(getLastActivityString().getBytes()); 1132 } 1133 if (getChatState() != INVALID_VALUE_PARAMETER) { 1134 appParamBuf.put((byte) CHAT_STATE); 1135 appParamBuf.put((byte) CHAT_STATE_LEN); 1136 appParamBuf.putShort((short) getChatState()); 1137 } 1138 if (getFilterConvoId() != null) { 1139 appParamBuf.put((byte) FILTER_CONVO_ID); 1140 appParamBuf.put((byte) FILTER_CONVO_ID_LEN); 1141 appParamBuf.putLong(getFilterConvoId().getMostSignificantBits()); 1142 appParamBuf.putLong(getFilterConvoId().getLeastSignificantBits()); 1143 } 1144 if (getConvoListingSize() != INVALID_VALUE_PARAMETER) { 1145 appParamBuf.put((byte) CONVO_LISTING_SIZE); 1146 appParamBuf.put((byte) CONVO_LISTING_SIZE_LEN); 1147 appParamBuf.putShort((short) getConvoListingSize()); 1148 } 1149 if (getFilterPresence() != INVALID_VALUE_PARAMETER) { 1150 appParamBuf.put((byte) FILTER_PRESENCE); 1151 appParamBuf.put((byte) FILTER_PRESENCE_LEN); 1152 appParamBuf.putShort((short) getFilterPresence()); 1153 } 1154 if (getFilterUidPresent() != INVALID_VALUE_PARAMETER) { 1155 appParamBuf.put((byte) FILTER_UID_PRESENT); 1156 appParamBuf.put((byte) FILTER_UID_PRESENT_LEN); 1157 appParamBuf.putShort((short) getFilterUidPresent()); 1158 } 1159 if (getChatStateConvoId() != null) { 1160 appParamBuf.put((byte) CHAT_STATE_CONVO_ID); 1161 appParamBuf.put((byte) CHAT_STATE_CONVO_ID_LEN); 1162 appParamBuf.putLong(getChatStateConvoId().getMostSignificantBits()); 1163 appParamBuf.putLong(getChatStateConvoId().getLeastSignificantBits()); 1164 } 1165 if (getFolderVerCounter() != null) { 1166 appParamBuf.put((byte) FOLDER_VER_COUNTER); 1167 appParamBuf.put((byte) FOLDER_VER_COUNTER_LEN); 1168 appParamBuf.put(getFolderVerCounter()); 1169 } 1170 if (getFilterMsgHandle() != INVALID_VALUE_PARAMETER) { 1171 appParamBuf.put((byte) FILTER_MESSAGE_HANDLE); 1172 appParamBuf.put((byte) FILTER_MESSAGE_HANDLE_LEN); 1173 appParamBuf.putLong(getFilterMsgHandle()); 1174 } 1175 if (getConvoParameterMask() != INVALID_VALUE_PARAMETER) { 1176 appParamBuf.put((byte) CONVO_PARAMETER_MASK); 1177 appParamBuf.put((byte) CONVO_PARAMETER_MASK_LEN); 1178 appParamBuf.putInt((int) getConvoParameterMask()); 1179 } 1180 1181 // We need to reduce the length of the array to match the content 1182 retBuf = 1183 Arrays.copyOfRange( 1184 appParamBuf.array(), 1185 appParamBuf.arrayOffset(), 1186 appParamBuf.arrayOffset() + appParamBuf.position()); 1187 return retBuf; 1188 } 1189 getMaxListCount()1190 public int getMaxListCount() { 1191 return mMaxListCount; 1192 } 1193 setMaxListCount(int maxListCount)1194 public void setMaxListCount(int maxListCount) throws IllegalArgumentException { 1195 if (maxListCount < 0 || maxListCount > 0xFFFF) { 1196 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1197 } 1198 this.mMaxListCount = maxListCount; 1199 } 1200 getStartOffset()1201 public int getStartOffset() { 1202 return mStartOffset; 1203 } 1204 setStartOffset(int startOffset)1205 public void setStartOffset(int startOffset) throws IllegalArgumentException { 1206 if (startOffset < 0 || startOffset > 0xFFFF) { 1207 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1208 } 1209 this.mStartOffset = startOffset; 1210 } 1211 getFilterMessageType()1212 public int getFilterMessageType() { 1213 return mFilterMessageType; 1214 } 1215 setFilterMessageType(int filterMessageType)1216 public void setFilterMessageType(int filterMessageType) throws IllegalArgumentException { 1217 if (filterMessageType < 0 || filterMessageType > 0x001F) { 1218 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x001F"); 1219 } 1220 this.mFilterMessageType = filterMessageType; 1221 } 1222 getFilterPeriodBegin()1223 public long getFilterPeriodBegin() { 1224 return mFilterPeriodBegin; 1225 } 1226 getFilterPeriodBeginString()1227 public String getFilterPeriodBeginString() { 1228 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1229 Date date = new Date(mFilterPeriodBegin); 1230 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 1231 } 1232 setFilterPeriodBegin(long filterPeriodBegin)1233 public void setFilterPeriodBegin(long filterPeriodBegin) { 1234 this.mFilterPeriodBegin = filterPeriodBegin; 1235 } 1236 setFilterPeriodBegin(String filterPeriodBegin)1237 public void setFilterPeriodBegin(String filterPeriodBegin) throws ParseException { 1238 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1239 Date date = format.parse(filterPeriodBegin); 1240 this.mFilterPeriodBegin = date.getTime(); 1241 } 1242 getFilterLastActivityBegin()1243 public long getFilterLastActivityBegin() { 1244 return mFilterPeriodBegin; 1245 } 1246 getFilterLastActivityBeginString()1247 public String getFilterLastActivityBeginString() { 1248 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1249 Date date = new Date(mFilterPeriodBegin); 1250 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 1251 } 1252 setFilterLastActivityBegin(long filterPeriodBegin)1253 public void setFilterLastActivityBegin(long filterPeriodBegin) { 1254 this.mFilterPeriodBegin = filterPeriodBegin; 1255 } 1256 setFilterLastActivityBegin(String filterPeriodBegin)1257 public void setFilterLastActivityBegin(String filterPeriodBegin) throws ParseException { 1258 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1259 Date date = format.parse(filterPeriodBegin); 1260 this.mFilterPeriodBegin = date.getTime(); 1261 } 1262 getFilterPeriodEnd()1263 public long getFilterPeriodEnd() { 1264 return mFilterPeriodEnd; 1265 } 1266 getFilterLastActivityEnd()1267 public long getFilterLastActivityEnd() { 1268 return mFilterPeriodEnd; 1269 } 1270 getFilterLastActivityEndString()1271 public String getFilterLastActivityEndString() { 1272 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1273 Date date = new Date(mFilterPeriodEnd); 1274 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 1275 } 1276 setFilterLastActivityEnd(long filterPeriodEnd)1277 public void setFilterLastActivityEnd(long filterPeriodEnd) { 1278 this.mFilterPeriodEnd = filterPeriodEnd; // er reuse the same 1279 } 1280 setFilterPeriodEnd(String filterPeriodEnd)1281 public void setFilterPeriodEnd(String filterPeriodEnd) throws ParseException { 1282 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1283 Date date = format.parse(filterPeriodEnd); 1284 this.mFilterPeriodEnd = date.getTime(); 1285 } 1286 getFilterPeriodEndString()1287 public String getFilterPeriodEndString() { 1288 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1289 Date date = new Date(mFilterPeriodEnd); 1290 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 1291 } 1292 setFilterPeriodEnd(long filterPeriodEnd)1293 public void setFilterPeriodEnd(long filterPeriodEnd) { 1294 this.mFilterPeriodEnd = filterPeriodEnd; 1295 } 1296 setFilterLastActivityEnd(String filterPeriodEnd)1297 public void setFilterLastActivityEnd(String filterPeriodEnd) throws ParseException { 1298 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 1299 Date date = format.parse(filterPeriodEnd); 1300 this.mFilterPeriodEnd = date.getTime(); 1301 } 1302 getFilterReadStatus()1303 public int getFilterReadStatus() { 1304 return mFilterReadStatus; 1305 } 1306 setFilterReadStatus(int filterReadStatus)1307 public void setFilterReadStatus(int filterReadStatus) throws IllegalArgumentException { 1308 if (filterReadStatus < 0 || filterReadStatus > 0x0002) { 1309 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002"); 1310 } 1311 this.mFilterReadStatus = filterReadStatus; 1312 } 1313 getFilterRecipient()1314 public String getFilterRecipient() { 1315 return mFilterRecipient; 1316 } 1317 setFilterRecipient(String filterRecipient)1318 public void setFilterRecipient(String filterRecipient) { 1319 this.mFilterRecipient = filterRecipient; 1320 } 1321 getFilterOriginator()1322 public String getFilterOriginator() { 1323 return mFilterOriginator; 1324 } 1325 setFilterOriginator(String filterOriginator)1326 public void setFilterOriginator(String filterOriginator) { 1327 this.mFilterOriginator = filterOriginator; 1328 } 1329 getFilterPriority()1330 public int getFilterPriority() { 1331 return mFilterPriority; 1332 } 1333 setFilterPriority(int filterPriority)1334 public void setFilterPriority(int filterPriority) throws IllegalArgumentException { 1335 if (filterPriority < 0 || filterPriority > 0x0002) { 1336 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002"); 1337 } 1338 this.mFilterPriority = filterPriority; 1339 } 1340 setDatabaseIdentifier(long idHigh, long idLow)1341 public void setDatabaseIdentifier(long idHigh, long idLow) { 1342 this.mDatabaseIdentifierHigh = idHigh; 1343 this.mDatabaseIdentifierLow = idLow; 1344 } 1345 getDatabaseIdentifier()1346 public byte[] getDatabaseIdentifier() { 1347 if (mDatabaseIdentifierLow != INVALID_VALUE_PARAMETER 1348 && mDatabaseIdentifierHigh != INVALID_VALUE_PARAMETER) { 1349 ByteBuffer ret = ByteBuffer.allocate(16); 1350 ret.putLong(mDatabaseIdentifierHigh); 1351 ret.putLong(mDatabaseIdentifierLow); 1352 return ret.array(); 1353 } else { 1354 return null; 1355 } 1356 } 1357 setConvoListingVerCounter(long countLow, long countHigh)1358 public void setConvoListingVerCounter(long countLow, long countHigh) { 1359 this.mConvoListingVerCounterHigh = countHigh; 1360 this.mConvoListingVerCounterLow = countLow; 1361 } 1362 getConvoListingVerCounter()1363 public byte[] getConvoListingVerCounter() { 1364 if (mConvoListingVerCounterHigh != INVALID_VALUE_PARAMETER 1365 && mConvoListingVerCounterLow != INVALID_VALUE_PARAMETER) { 1366 ByteBuffer ret = ByteBuffer.allocate(16); 1367 ret.putLong(mConvoListingVerCounterHigh); 1368 ret.putLong(mConvoListingVerCounterLow); 1369 return ret.array(); 1370 } else { 1371 return null; 1372 } 1373 } 1374 setFolderVerCounter(long countLow, long countHigh)1375 public void setFolderVerCounter(long countLow, long countHigh) { 1376 this.mFolderVerCounterHigh = countHigh; 1377 this.mFolderVerCounterLow = countLow; 1378 } 1379 getFolderVerCounter()1380 public byte[] getFolderVerCounter() { 1381 if (mFolderVerCounterHigh != INVALID_VALUE_PARAMETER 1382 && mFolderVerCounterLow != INVALID_VALUE_PARAMETER) { 1383 ByteBuffer ret = ByteBuffer.allocate(16); 1384 ret.putLong(mFolderVerCounterHigh); 1385 ret.putLong(mFolderVerCounterLow); 1386 return ret.array(); 1387 } else { 1388 return null; 1389 } 1390 } 1391 getChatStateConvoId()1392 public SignedLongLong getChatStateConvoId() { 1393 return mChatStateConvoId; 1394 } 1395 getChatStateConvoIdByteArray()1396 public byte[] getChatStateConvoIdByteArray() { 1397 if (mChatStateConvoId != null) { 1398 ByteBuffer ret = ByteBuffer.allocate(16); 1399 ret.putLong(mChatStateConvoId.getMostSignificantBits()); 1400 ret.putLong(mChatStateConvoId.getLeastSignificantBits()); 1401 return ret.array(); 1402 } else { 1403 return null; 1404 } 1405 } 1406 getChatStateConvoIdString()1407 public String getChatStateConvoIdString() { 1408 return new String(this.getChatStateConvoIdByteArray()); 1409 } 1410 setChatStateConvoId(long idHigh, long idLow)1411 public void setChatStateConvoId(long idHigh, long idLow) { 1412 mChatStateConvoId = new SignedLongLong(idLow, idHigh); 1413 } 1414 setFilterMsgHandle(String handle)1415 public void setFilterMsgHandle(String handle) { 1416 try { 1417 mFilterMsgHandle = BluetoothMapUtils.getLongFromString(handle); 1418 } catch (UnsupportedEncodingException | NumberFormatException e) { 1419 ContentProfileErrorReportUtils.report( 1420 BluetoothProfile.MAP, 1421 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 1422 BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 1423 39); 1424 Log.w(TAG, "Error creating long from handle string", e); 1425 } 1426 } 1427 getFilterMsgHandle()1428 public long getFilterMsgHandle() { 1429 return mFilterMsgHandle; 1430 } 1431 getFilterMsgHandleString()1432 public String getFilterMsgHandleString() { 1433 String str = null; 1434 if (mFilterMsgHandle != INVALID_VALUE_PARAMETER) { 1435 str = BluetoothMapUtils.getLongAsString(mFilterMsgHandle); 1436 } 1437 return str; 1438 } 1439 getFilterUidPresent()1440 public int getFilterUidPresent() { 1441 return mFilterUidPresent; 1442 } 1443 setFilterUidPresent(int present)1444 public void setFilterUidPresent(int present) { 1445 if (present < 0 || present > 0x00FF) { 1446 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 1447 } 1448 this.mFilterUidPresent = present; 1449 } 1450 getFilterPresence()1451 public int getFilterPresence() { 1452 return mFilterPresence; 1453 } 1454 getFilterConvoId()1455 public SignedLongLong getFilterConvoId() { 1456 return mFilterConvoId; 1457 } 1458 1459 /** 1460 * Get a decimal representation of the lower bits of the ConvoId - used for queries. The upper 1461 * bits are used for convo-type. 1462 * 1463 * @return decimal representation of the convo ID. 1464 */ getFilterConvoIdString()1465 public String getFilterConvoIdString() { 1466 String str = null; 1467 if (mFilterConvoId != null) { 1468 str = BluetoothMapUtils.getLongAsString(mFilterConvoId.getLeastSignificantBits()); 1469 } 1470 return str; 1471 } 1472 setFilterConvoId(String id)1473 public void setFilterConvoId(String id) { 1474 try { 1475 mFilterConvoId = SignedLongLong.fromString(id); 1476 } catch (UnsupportedEncodingException | NumberFormatException e) { 1477 ContentProfileErrorReportUtils.report( 1478 BluetoothProfile.MAP, 1479 BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, 1480 BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 1481 40); 1482 Log.w(TAG, "Error creating long from id string", e); 1483 } 1484 } 1485 setChatState(int state)1486 public void setChatState(int state) { 1487 if (state < 0 || state > 0x00FF) { 1488 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 1489 } 1490 this.mChatState = state; 1491 } 1492 getChatState()1493 public int getChatState() { 1494 return mChatState; 1495 } 1496 getLastActivity()1497 public long getLastActivity() { 1498 return this.mLastActivity; 1499 } 1500 getLastActivityString()1501 public String getLastActivityString() { 1502 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 1503 Date date = new Date(mLastActivity); 1504 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 1505 } 1506 setLastActivity(long last)1507 public void setLastActivity(long last) { 1508 this.mLastActivity = last; 1509 } 1510 setLastActivity(String lastActivity)1511 public void setLastActivity(String lastActivity) throws ParseException { 1512 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 1513 Date date = format.parse(lastActivity); 1514 this.mLastActivity = date.getTime(); 1515 } 1516 setPresenceStatus(String status)1517 public void setPresenceStatus(String status) { 1518 this.mPresenceStatus = status; 1519 } 1520 getPresenceStatus()1521 public String getPresenceStatus() { 1522 return this.mPresenceStatus; 1523 } 1524 setFilterPresence(int presence)1525 public void setFilterPresence(int presence) { 1526 if (presence < 0 || presence > 0xFFFF) { 1527 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1528 } 1529 this.mFilterPresence = presence; 1530 } 1531 setPresenceAvailability(int availability)1532 public void setPresenceAvailability(int availability) { 1533 if (availability < 0 || availability > 0x00FF) { 1534 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 1535 } 1536 this.mPresenceAvailability = availability; 1537 } 1538 getPresenceAvailability()1539 public int getPresenceAvailability() { 1540 return mPresenceAvailability; 1541 } 1542 getSubjectLength()1543 public int getSubjectLength() { 1544 return mSubjectLength; 1545 } 1546 getAttachment()1547 public int getAttachment() { 1548 return mAttachment; 1549 } 1550 setAttachment(int attachment)1551 public void setAttachment(int attachment) throws IllegalArgumentException { 1552 if (attachment < 0 || attachment > 0x0001) { 1553 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1554 } 1555 this.mAttachment = attachment; 1556 } 1557 getTransparent()1558 public int getTransparent() { 1559 return mTransparent; 1560 } 1561 setTransparent(int transparent)1562 public void setTransparent(int transparent) throws IllegalArgumentException { 1563 if (transparent < 0 || transparent > 0x0001) { 1564 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1565 } 1566 this.mTransparent = transparent; 1567 } 1568 getRetry()1569 public int getRetry() { 1570 return mRetry; 1571 } 1572 setRetry(int retry)1573 public void setRetry(int retry) throws IllegalArgumentException { 1574 if (retry < 0 || retry > 0x0001) { 1575 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1576 } 1577 this.mRetry = retry; 1578 } 1579 getNewMessage()1580 public int getNewMessage() { 1581 return mNewMessage; 1582 } 1583 setNewMessage(int newMessage)1584 public void setNewMessage(int newMessage) throws IllegalArgumentException { 1585 if (newMessage < 0 || newMessage > 0x0001) { 1586 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1587 } 1588 this.mNewMessage = newMessage; 1589 } 1590 getNotificationStatus()1591 public int getNotificationStatus() { 1592 return mNotificationStatus; 1593 } 1594 setNotificationStatus(int notificationStatus)1595 public void setNotificationStatus(int notificationStatus) throws IllegalArgumentException { 1596 if (notificationStatus < 0 || notificationStatus > 0x0001) { 1597 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1598 } 1599 this.mNotificationStatus = notificationStatus; 1600 } 1601 getNotificationFilter()1602 public long getNotificationFilter() { 1603 return mNotificationFilter; 1604 } 1605 setNotificationFilter(long notificationFilter)1606 public void setNotificationFilter(long notificationFilter) throws IllegalArgumentException { 1607 if (notificationFilter < 0 || notificationFilter > 0xFFFFFFFFL) { 1608 throw new IllegalArgumentException( 1609 "Out of range, valid range is 0x0000 to 0xFFFFFFFFL"); 1610 } 1611 this.mNotificationFilter = notificationFilter; 1612 } 1613 getMasInstanceId()1614 public int getMasInstanceId() { 1615 return mMasInstanceId; 1616 } 1617 setMasInstanceId(int masInstanceId)1618 public void setMasInstanceId(int masInstanceId) { 1619 if (masInstanceId < 0 || masInstanceId > 0x00FF) { 1620 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 1621 } 1622 this.mMasInstanceId = masInstanceId; 1623 } 1624 getParameterMask()1625 public long getParameterMask() { 1626 return mParameterMask; 1627 } 1628 setParameterMask(long parameterMask)1629 public void setParameterMask(long parameterMask) { 1630 if (parameterMask < 0 || parameterMask > 0xFFFFFFFFL) { 1631 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFFFFFF"); 1632 } 1633 this.mParameterMask = parameterMask; 1634 } 1635 setConvoParameterMask(long parameterMask)1636 public void setConvoParameterMask(long parameterMask) { 1637 if (parameterMask < 0 || parameterMask > 0xFFFFFFFFL) { 1638 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFFFFFF"); 1639 } 1640 this.mConvoParameterMask = parameterMask; 1641 } 1642 getConvoParameterMask()1643 public long getConvoParameterMask() { 1644 return mConvoParameterMask; 1645 } 1646 getFolderListingSize()1647 public int getFolderListingSize() { 1648 return mFolderListingSize; 1649 } 1650 setFolderListingSize(int folderListingSize)1651 public void setFolderListingSize(int folderListingSize) { 1652 if (folderListingSize < 0 || folderListingSize > 0xFFFF) { 1653 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1654 } 1655 this.mFolderListingSize = folderListingSize; 1656 } 1657 getMessageListingSize()1658 public int getMessageListingSize() { 1659 return mMessageListingSize; 1660 } 1661 setMessageListingSize(int messageListingSize)1662 public void setMessageListingSize(int messageListingSize) { 1663 if (messageListingSize < 0 || messageListingSize > 0xFFFF) { 1664 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1665 } 1666 this.mMessageListingSize = messageListingSize; 1667 } 1668 getConvoListingSize()1669 public int getConvoListingSize() { 1670 return mConvoListingSize; 1671 } 1672 setConvoListingSize(int convoListingSize)1673 public void setConvoListingSize(int convoListingSize) { 1674 if (convoListingSize < 0 || convoListingSize > 0xFFFF) { 1675 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF"); 1676 } 1677 this.mConvoListingSize = convoListingSize; 1678 } 1679 setSubjectLength(int subjectLength)1680 public void setSubjectLength(int subjectLength) { 1681 if (subjectLength < 0 || subjectLength > 0xFF) { 1682 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF"); 1683 } 1684 this.mSubjectLength = subjectLength; 1685 } 1686 getCharset()1687 public int getCharset() { 1688 return mCharset; 1689 } 1690 setCharset(int charset)1691 public void setCharset(int charset) { 1692 if (charset < 0 || charset > 0x1) { 1693 throw new IllegalArgumentException( 1694 "Out of range: " + charset + ", valid range is 0x0000 to 0x0001"); 1695 } 1696 this.mCharset = charset; 1697 } 1698 getFractionRequest()1699 public int getFractionRequest() { 1700 return mFractionRequest; 1701 } 1702 setFractionRequest(int fractionRequest)1703 public void setFractionRequest(int fractionRequest) { 1704 if (fractionRequest < 0 || fractionRequest > 0x1) { 1705 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1706 } 1707 this.mFractionRequest = fractionRequest; 1708 } 1709 getFractionDeliver()1710 public int getFractionDeliver() { 1711 return mFractionDeliver; 1712 } 1713 setFractionDeliver(int fractionDeliver)1714 public void setFractionDeliver(int fractionDeliver) { 1715 if (fractionDeliver < 0 || fractionDeliver > 0x1) { 1716 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1717 } 1718 this.mFractionDeliver = fractionDeliver; 1719 } 1720 getStatusIndicator()1721 public int getStatusIndicator() { 1722 return mStatusIndicator; 1723 } 1724 setStatusIndicator(int statusIndicator)1725 public void setStatusIndicator(int statusIndicator) { 1726 if (statusIndicator < 0 || statusIndicator > 0x1) { 1727 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1728 } 1729 this.mStatusIndicator = statusIndicator; 1730 } 1731 getStatusValue()1732 public int getStatusValue() { 1733 return mStatusValue; 1734 } 1735 setStatusValue(int statusValue)1736 public void setStatusValue(int statusValue) { 1737 if (statusValue < 0 || statusValue > 0x1) { 1738 throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001"); 1739 } 1740 this.mStatusValue = statusValue; 1741 } 1742 getMseTime()1743 public long getMseTime() { 1744 return mMseTime; 1745 } 1746 getMseTimeString()1747 public String getMseTimeString() { 1748 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 1749 Date date = new Date(getMseTime()); 1750 return format.format(date); // Format to YYYYMMDDTHHMMSS±hhmm UTC time ± offset 1751 } 1752 setMseTime(long mseTime)1753 public void setMseTime(long mseTime) { 1754 this.mMseTime = mseTime; 1755 } 1756 setMseTime(String mseTime)1757 public void setMseTime(String mseTime) throws ParseException { 1758 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ"); 1759 Date date = format.parse(mseTime); 1760 this.mMseTime = date.getTime(); 1761 } 1762 } 1763