blob: f0ecbb4b504704055a37093b2c7c0c244a55d8cc [file] [log] [blame]
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.bluetooth;
17
18import java.util.ArrayList;
19import java.util.IllegalFormatConversionException;
20import java.util.List;
21import java.util.UUID;
22
23/**
Matthew Xieddf7e472013-03-01 18:41:02 -080024 * Represents a Bluetooth GATT Characteristic
Matthew Xie33ec9842013-04-03 00:29:27 -070025 *
26 * <p>A GATT characteristic is a basic data element used to construct a GATT service,
27 * {@link BluetoothGattService}. The characteristic contains a value as well as
28 * additional information and optional GATT descriptors, {@link BluetoothGattDescriptor}.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -080029 */
30public class BluetoothGattCharacteristic {
31
32 /**
33 * Characteristic proprty: Characteristic is broadcastable.
34 */
35 public static final int PROPERTY_BROADCAST = 0x01;
36
37 /**
38 * Characteristic property: Characteristic is readable.
39 */
40 public static final int PROPERTY_READ = 0x02;
41
42 /**
43 * Characteristic property: Characteristic can be written without response.
44 */
45 public static final int PROPERTY_WRITE_NO_RESPONSE = 0x04;
46
47 /**
48 * Characteristic property: Characteristic can be written.
49 */
50 public static final int PROPERTY_WRITE = 0x08;
51
52 /**
53 * Characteristic property: Characteristic supports notification
54 */
55 public static final int PROPERTY_NOTIFY = 0x10;
56
57 /**
58 * Characteristic property: Characteristic supports indication
59 */
60 public static final int PROPERTY_INDICATE = 0x20;
61
62 /**
63 * Characteristic property: Characteristic supports write with signature
64 */
65 public static final int PROPERTY_SIGNED_WRITE = 0x40;
66
67 /**
68 * Characteristic property: Characteristic has extended properties
69 */
70 public static final int PROPERTY_EXTENDED_PROPS = 0x80;
71
72 /**
73 * Characteristic read permission
74 */
75 public static final int PERMISSION_READ = 0x01;
76
77 /**
78 * Characteristic permission: Allow encrypted read operations
79 */
80 public static final int PERMISSION_READ_ENCRYPTED = 0x02;
81
82 /**
83 * Characteristic permission: Allow reading with man-in-the-middle protection
84 */
85 public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
86
87 /**
88 * Characteristic write permission
89 */
90 public static final int PERMISSION_WRITE = 0x10;
91
92 /**
93 * Characteristic permission: Allow encrypted writes
94 */
95 public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
96
97 /**
98 * Characteristic permission: Allow encrypted writes with man-in-the-middle
99 * protection
100 */
101 public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
102
103 /**
104 * Characteristic permission: Allow signed write operations
105 */
106 public static final int PERMISSION_WRITE_SIGNED = 0x80;
107
108 /**
109 * Characteristic permission: Allow signed write operations with
110 * man-in-the-middle protection
111 */
112 public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
113
114 /**
115 * Write characteristic, requesting acknoledgement by the remote device
116 */
117 public static final int WRITE_TYPE_DEFAULT = 0x02;
118
119 /**
120 * Wrtite characteristic without requiring a response by the remote device
121 */
122 public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
123
124 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800125 * Write characteristic including authentication signature
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800126 */
127 public static final int WRITE_TYPE_SIGNED = 0x04;
128
129 /**
130 * Characteristic value format type uint8
131 */
132 public static final int FORMAT_UINT8 = 0x11;
133
134 /**
135 * Characteristic value format type uint16
136 */
137 public static final int FORMAT_UINT16 = 0x12;
138
139 /**
140 * Characteristic value format type uint32
141 */
142 public static final int FORMAT_UINT32 = 0x14;
143
144 /**
145 * Characteristic value format type sint8
146 */
147 public static final int FORMAT_SINT8 = 0x21;
148
149 /**
150 * Characteristic value format type sint16
151 */
152 public static final int FORMAT_SINT16 = 0x22;
153
154 /**
155 * Characteristic value format type sint32
156 */
157 public static final int FORMAT_SINT32 = 0x24;
158
159 /**
160 * Characteristic value format type sfloat (16-bit float)
161 */
162 public static final int FORMAT_SFLOAT = 0x32;
163
164 /**
165 * Characteristic value format type float (32-bit float)
166 */
167 public static final int FORMAT_FLOAT = 0x34;
168
169
170 /**
171 * The UUID of this characteristic.
172 * @hide
173 */
174 protected UUID mUuid;
175
176 /**
177 * Instance ID for this characteristic.
178 * @hide
179 */
180 protected int mInstance;
181
182 /**
183 * Characteristic properties.
184 * @hide
185 */
186 protected int mProperties;
187
188 /**
189 * Characteristic permissions.
190 * @hide
191 */
192 protected int mPermissions;
193
194 /**
195 * Key size (default = 16).
196 * @hide
197 */
198 protected int mKeySize = 16;
199
200 /**
201 * Write type for this characteristic.
202 * See WRITE_TYPE_* constants.
203 * @hide
204 */
205 protected int mWriteType;
206
207 /**
208 * Back-reference to the service this characteristic belongs to.
209 * @hide
210 */
211 protected BluetoothGattService mService;
212
213 /**
214 * The cached value of this characteristic.
215 * @hide
216 */
217 protected byte[] mValue;
218
219 /**
220 * List of descriptors included in this characteristic.
221 */
222 protected List<BluetoothGattDescriptor> mDescriptors;
223
224 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800225 * Create a new BluetoothGattCharacteristic.
226 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
227 *
228 * @param uuid The UUID for this characteristic
229 * @param properties Properties of this characteristic
230 * @param permissions Permissions for this characteristic
231 */
232 public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
233 initCharacteristic(null, uuid, 0, properties, permissions);
234 }
235
236 /**
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800237 * Create a new BluetoothGattCharacteristic
238 * @hide
239 */
240 /*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
241 UUID uuid, int instanceId,
242 int properties, int permissions) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800243 initCharacteristic(service, uuid, instanceId, properties, permissions);
244 }
245
246 private void initCharacteristic(BluetoothGattService service,
247 UUID uuid, int instanceId,
248 int properties, int permissions) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800249 mUuid = uuid;
250 mInstance = instanceId;
251 mProperties = properties;
252 mPermissions = permissions;
253 mService = service;
254 mValue = null;
255 mDescriptors = new ArrayList<BluetoothGattDescriptor>();
256
257 if ((mProperties & PROPERTY_WRITE_NO_RESPONSE) != 0) {
258 mWriteType = WRITE_TYPE_NO_RESPONSE;
259 } else {
260 mWriteType = WRITE_TYPE_DEFAULT;
261 }
262 }
263
264 /**
265 * Returns the deisred key size.
266 * @hide
267 */
268 /*package*/ int getKeySize() {
269 return mKeySize;
270 }
271
272 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800273 * Adds a descriptor to this characteristic.
274 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
275 *
276 * @param descriptor Descriptor to be added to this characteristic.
277 * @return true, if the descriptor was added to the characteristic
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800278 */
Matthew Xieddf7e472013-03-01 18:41:02 -0800279 public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800280 mDescriptors.add(descriptor);
Matthew Xieddf7e472013-03-01 18:41:02 -0800281 descriptor.setCharacteristic(this);
282 return true;
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800283 }
284
285 /**
Andre Eisenbach25b9cf92013-07-08 23:58:16 -0700286 * Get a descriptor by UUID and isntance id.
287 * @hide
288 */
289 /*package*/ BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
290 for(BluetoothGattDescriptor descriptor : mDescriptors) {
291 if (descriptor.getUuid().equals(uuid)
292 && descriptor.getInstanceId() == instanceId) {
293 return descriptor;
294 }
295 }
296 return null;
297 }
298
299 /**
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800300 * Returns the service this characteristic belongs to.
301 * @return The asscociated service
302 */
303 public BluetoothGattService getService() {
304 return mService;
305 }
306
307 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800308 * Sets the service associated with this device.
309 * @hide
310 */
311 /*package*/ void setService(BluetoothGattService service) {
312 mService = service;
313 }
314
315 /**
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800316 * Returns the UUID of this characteristic
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800317 *
318 * @return UUID of this characteristic
319 */
320 public UUID getUuid() {
321 return mUuid;
322 }
323
324 /**
325 * Returns the instance ID for this characteristic.
326 *
327 * <p>If a remote device offers multiple characteristics with the same UUID,
328 * the instance ID is used to distuinguish between characteristics.
329 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800330 * @return Instance ID of this characteristic
331 */
332 public int getInstanceId() {
333 return mInstance;
334 }
335
336 /**
337 * Returns the properties of this characteristic.
338 *
339 * <p>The properties contain a bit mask of property flags indicating
340 * the features of this characteristic.
341 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800342 * @return Properties of this characteristic
343 */
344 public int getProperties() {
345 return mProperties;
346 }
347
348 /**
349 * Returns the permissions for this characteristic.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800350 *
351 * @return Permissions of this characteristic
352 */
353 public int getPermissions() {
354 return mPermissions;
355 }
356
357 /**
358 * Gets the write type for this characteristic.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800359 *
360 * @return Write type for this characteristic
361 */
362 public int getWriteType() {
363 return mWriteType;
364 }
365
366 /**
367 * Set the write type for this characteristic
368 *
369 * <p>Setting the write type of a characteristic determines how the
370 * {@link BluetoothGatt#writeCharacteristic} function write this
371 * characteristic.
372 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800373 * @param writeType The write type to for this characteristic. Can be one
374 * of:
375 * {@link #WRITE_TYPE_DEFAULT},
376 * {@link #WRITE_TYPE_NO_RESPONSE} or
377 * {@link #WRITE_TYPE_SIGNED}.
378 */
379 public void setWriteType(int writeType) {
380 mWriteType = writeType;
381 }
382
383 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800384 * Set the desired key size.
385 * @hide
386 */
387 public void setKeySize(int keySize) {
388 mKeySize = keySize;
389 }
390
391 /**
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800392 * Returns a list of descriptors for this characteristic.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800393 *
394 * @return Descriptors for this characteristic
395 */
396 public List<BluetoothGattDescriptor> getDescriptors() {
397 return mDescriptors;
398 }
399
400 /**
401 * Returns a descriptor with a given UUID out of the list of
402 * descriptors for this characteristic.
403 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800404 * @return GATT descriptor object or null if no descriptor with the
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800405 * given UUID was found.
406 */
407 public BluetoothGattDescriptor getDescriptor(UUID uuid) {
408 for(BluetoothGattDescriptor descriptor : mDescriptors) {
409 if (descriptor.getUuid().equals(uuid)) {
410 return descriptor;
411 }
412 }
413 return null;
414 }
415
416 /**
417 * Get the stored value for this characteristic.
418 *
419 * <p>This function returns the stored value for this characteristic as
Matthew Xieddf7e472013-03-01 18:41:02 -0800420 * retrieved by calling {@link BluetoothGatt#readCharacteristic}. The cached
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800421 * value of the characteristic is updated as a result of a read characteristic
422 * operation or if a characteristic update notification has been received.
423 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800424 * @return Cached value of the characteristic
425 */
426 public byte[] getValue() {
427 return mValue;
428 }
429
430 /**
431 * Return the stored value of this characteristic.
432 *
433 * <p>The formatType parameter determines how the characteristic value
434 * is to be interpreted. For example, settting formatType to
435 * {@link #FORMAT_UINT16} specifies that the first two bytes of the
436 * characteristic value at the given offset are interpreted to generate the
437 * return value.
438 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800439 * @param formatType The format type used to interpret the characteristic
440 * value.
441 * @param offset Offset at which the integer value can be found.
442 * @return Cached value of the characteristic or null of offset exceeds
443 * value size.
444 */
445 public Integer getIntValue(int formatType, int offset) {
446 if ((offset + getTypeLen(formatType)) > mValue.length) return null;
447
448 switch (formatType) {
449 case FORMAT_UINT8:
450 return unsignedByteToInt(mValue[offset]);
451
452 case FORMAT_UINT16:
453 return unsignedBytesToInt(mValue[offset], mValue[offset+1]);
454
455 case FORMAT_UINT32:
456 return unsignedBytesToInt(mValue[offset], mValue[offset+1],
457 mValue[offset+2], mValue[offset+3]);
458 case FORMAT_SINT8:
459 return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
460
461 case FORMAT_SINT16:
462 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
463 mValue[offset+1]), 16);
464
465 case FORMAT_SINT32:
466 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
467 mValue[offset+1], mValue[offset+2], mValue[offset+3]), 32);
468 }
469
470 return null;
471 }
472
473 /**
474 * Return the stored value of this characteristic.
475 * <p>See {@link #getValue} for details.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800476 *
477 * @param formatType The format type used to interpret the characteristic
478 * value.
479 * @param offset Offset at which the float value can be found.
480 * @return Cached value of the characteristic at a given offset or null
481 * if the requested offset exceeds the value size.
482 */
483 public Float getFloatValue(int formatType, int offset) {
484 if ((offset + getTypeLen(formatType)) > mValue.length) return null;
485
486 switch (formatType) {
487 case FORMAT_SFLOAT:
488 return bytesToFloat(mValue[offset], mValue[offset+1]);
489
490 case FORMAT_FLOAT:
491 return bytesToFloat(mValue[offset], mValue[offset+1],
492 mValue[offset+2], mValue[offset+3]);
493 }
494
495 return null;
496 }
497
498 /**
499 * Return the stored value of this characteristic.
500 * <p>See {@link #getValue} for details.
Matthew Xieddf7e472013-03-01 18:41:02 -0800501 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800502 * @param offset Offset at which the string value can be found.
503 * @return Cached value of the characteristic
504 */
505 public String getStringValue(int offset) {
506 if (offset > mValue.length) return null;
507 byte[] strBytes = new byte[mValue.length - offset];
508 for (int i=0; i != (mValue.length-offset); ++i) strBytes[i] = mValue[offset+i];
509 return new String(strBytes);
510 }
511
512 /**
513 * Updates the locally stored value of this characteristic.
514 *
515 * <p>This function modifies the locally stored cached value of this
516 * characteristic. To send the value to the remote device, call
517 * {@link BluetoothGatt#writeCharacteristic} to send the value to the
518 * remote device.
519 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800520 * @param value New value for this characteristic
521 * @return true if the locally stored value has been set, false if the
522 * requested value could not be stored locally.
523 */
524 public boolean setValue(byte[] value) {
525 mValue = value;
526 return true;
527 }
528
529 /**
530 * Set the locally stored value of this characteristic.
531 * <p>See {@link #setValue(byte[])} for details.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800532 *
533 * @param value New value for this characteristic
534 * @param formatType Integer format type used to transform the value parameter
535 * @param offset Offset at which the value should be placed
536 * @return true if the locally stored value has been set
537 */
538 public boolean setValue(int value, int formatType, int offset) {
539 int len = offset + getTypeLen(formatType);
540 if (mValue == null) mValue = new byte[len];
541 if (len > mValue.length) return false;
542
543 switch (formatType) {
544 case FORMAT_SINT8:
545 value = intToSignedBits(value, 8);
546 // Fall-through intended
547 case FORMAT_UINT8:
548 mValue[offset] = (byte)(value & 0xFF);
549 break;
550
551 case FORMAT_SINT16:
552 value = intToSignedBits(value, 16);
553 // Fall-through intended
554 case FORMAT_UINT16:
555 mValue[offset++] = (byte)(value & 0xFF);
556 mValue[offset] = (byte)((value >> 8) & 0xFF);
557 break;
558
559 case FORMAT_SINT32:
560 value = intToSignedBits(value, 32);
561 // Fall-through intended
562 case FORMAT_UINT32:
563 mValue[offset++] = (byte)(value & 0xFF);
564 mValue[offset++] = (byte)((value >> 8) & 0xFF);
Andre Eisenbach3f366602013-03-08 18:42:24 -0800565 mValue[offset++] = (byte)((value >> 16) & 0xFF);
566 mValue[offset] = (byte)((value >> 24) & 0xFF);
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800567 break;
568
569 default:
570 return false;
571 }
572 return true;
573 }
574
575 /**
576 * Set the locally stored value of this characteristic.
577 * <p>See {@link #setValue(byte[])} for details.
Matthew Xieddf7e472013-03-01 18:41:02 -0800578 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800579 * @param mantissa Mantissa for this characteristic
580 * @param exponent exponent value for this characteristic
581 * @param formatType Float format type used to transform the value parameter
582 * @param offset Offset at which the value should be placed
583 * @return true if the locally stored value has been set
584 */
585 public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
586 int len = offset + getTypeLen(formatType);
587 if (mValue == null) mValue = new byte[len];
588 if (len > mValue.length) return false;
589
590 switch (formatType) {
591 case FORMAT_SFLOAT:
592 mantissa = intToSignedBits(mantissa, 12);
593 exponent = intToSignedBits(exponent, 4);
594 mValue[offset++] = (byte)(mantissa & 0xFF);
595 mValue[offset] = (byte)((mantissa >> 8) & 0x0F);
596 mValue[offset] += (byte)((exponent & 0x0F) << 4);
597 break;
598
599 case FORMAT_FLOAT:
600 mantissa = intToSignedBits(mantissa, 24);
601 exponent = intToSignedBits(exponent, 8);
602 mValue[offset++] = (byte)(mantissa & 0xFF);
603 mValue[offset++] = (byte)((mantissa >> 8) & 0xFF);
604 mValue[offset++] = (byte)((mantissa >> 16) & 0xFF);
605 mValue[offset] += (byte)(exponent & 0xFF);
606 break;
607
608 default:
609 return false;
610 }
611
612 return true;
613 }
614
615 /**
616 * Set the locally stored value of this characteristic.
617 * <p>See {@link #setValue(byte[])} for details.
Matthew Xieddf7e472013-03-01 18:41:02 -0800618 *
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800619 * @param value New value for this characteristic
620 * @return true if the locally stored value has been set
621 */
622 public boolean setValue(String value) {
623 mValue = value.getBytes();
624 return true;
625 }
626
627 /**
628 * Returns the size of a give value type.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800629 */
630 private int getTypeLen(int formatType) {
631 return formatType & 0xF;
632 }
633
634 /**
635 * Convert a signed byte to an unsigned int.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800636 */
637 private int unsignedByteToInt(byte b) {
638 return b & 0xFF;
639 }
640
641 /**
642 * Convert signed bytes to a 16-bit unsigned int.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800643 */
644 private int unsignedBytesToInt(byte b0, byte b1) {
645 return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
646 }
647
648 /**
649 * Convert signed bytes to a 32-bit unsigned int.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800650 */
651 private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
652 return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
653 + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
654 }
655
656 /**
657 * Convert signed bytes to a 16-bit short float value.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800658 */
659 private float bytesToFloat(byte b0, byte b1) {
660 int mantissa = unsignedToSigned(unsignedByteToInt(b0)
661 + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
662 int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
663 return (float)(mantissa * Math.pow(10, exponent));
664 }
665
666 /**
667 * Convert signed bytes to a 32-bit short float value.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800668 */
669 private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
670 int mantissa = unsignedToSigned(unsignedByteToInt(b0)
671 + (unsignedByteToInt(b1) << 8)
672 + (unsignedByteToInt(b2) << 16), 24);
673 return (float)(mantissa * Math.pow(10, b3));
674 }
675
676 /**
677 * Convert an unsigned integer value to a two's-complement encoded
678 * signed value.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800679 */
680 private int unsignedToSigned(int unsigned, int size) {
681 if ((unsigned & (1 << size-1)) != 0) {
682 unsigned = -1 * ((1 << size-1) - (unsigned & ((1 << size-1) - 1)));
683 }
684 return unsigned;
685 }
686
687 /**
688 * Convert an integer into the signed bits of a given length.
Ganesh Ganapathi Batta99081122013-02-05 15:28:33 -0800689 */
690 private int intToSignedBits(int i, int size) {
691 if (i < 0) {
692 i = (1 << size-1) + (i & ((1 << size-1) - 1));
693 }
694 return i;
695 }
696}