• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package android.bluetooth;
17 
18 import android.compat.annotation.UnsupportedAppUsage;
19 import android.os.Parcel;
20 import android.os.ParcelUuid;
21 import android.os.Parcelable;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.UUID;
26 
27 /**
28  * Represents a Bluetooth GATT Characteristic
29  *
30  * <p>A GATT characteristic is a basic data element used to construct a GATT service,
31  * {@link BluetoothGattService}. The characteristic contains a value as well as
32  * additional information and optional GATT descriptors, {@link BluetoothGattDescriptor}.
33  */
34 public class BluetoothGattCharacteristic implements Parcelable {
35 
36     /**
37      * Characteristic proprty: Characteristic is broadcastable.
38      */
39     public static final int PROPERTY_BROADCAST = 0x01;
40 
41     /**
42      * Characteristic property: Characteristic is readable.
43      */
44     public static final int PROPERTY_READ = 0x02;
45 
46     /**
47      * Characteristic property: Characteristic can be written without response.
48      */
49     public static final int PROPERTY_WRITE_NO_RESPONSE = 0x04;
50 
51     /**
52      * Characteristic property: Characteristic can be written.
53      */
54     public static final int PROPERTY_WRITE = 0x08;
55 
56     /**
57      * Characteristic property: Characteristic supports notification
58      */
59     public static final int PROPERTY_NOTIFY = 0x10;
60 
61     /**
62      * Characteristic property: Characteristic supports indication
63      */
64     public static final int PROPERTY_INDICATE = 0x20;
65 
66     /**
67      * Characteristic property: Characteristic supports write with signature
68      */
69     public static final int PROPERTY_SIGNED_WRITE = 0x40;
70 
71     /**
72      * Characteristic property: Characteristic has extended properties
73      */
74     public static final int PROPERTY_EXTENDED_PROPS = 0x80;
75 
76     /**
77      * Characteristic read permission
78      */
79     public static final int PERMISSION_READ = 0x01;
80 
81     /**
82      * Characteristic permission: Allow encrypted read operations
83      */
84     public static final int PERMISSION_READ_ENCRYPTED = 0x02;
85 
86     /**
87      * Characteristic permission: Allow reading with person-in-the-middle protection
88      */
89     public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
90 
91     /**
92      * Characteristic write permission
93      */
94     public static final int PERMISSION_WRITE = 0x10;
95 
96     /**
97      * Characteristic permission: Allow encrypted writes
98      */
99     public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
100 
101     /**
102      * Characteristic permission: Allow encrypted writes with person-in-the-middle
103      * protection
104      */
105     public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
106 
107     /**
108      * Characteristic permission: Allow signed write operations
109      */
110     public static final int PERMISSION_WRITE_SIGNED = 0x80;
111 
112     /**
113      * Characteristic permission: Allow signed write operations with
114      * person-in-the-middle protection
115      */
116     public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
117 
118     /**
119      * Write characteristic, requesting acknoledgement by the remote device
120      */
121     public static final int WRITE_TYPE_DEFAULT = 0x02;
122 
123     /**
124      * Write characteristic without requiring a response by the remote device
125      */
126     public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
127 
128     /**
129      * Write characteristic including authentication signature
130      */
131     public static final int WRITE_TYPE_SIGNED = 0x04;
132 
133     /**
134      * Characteristic value format type uint8
135      */
136     public static final int FORMAT_UINT8 = 0x11;
137 
138     /**
139      * Characteristic value format type uint16
140      */
141     public static final int FORMAT_UINT16 = 0x12;
142 
143     /**
144      * Characteristic value format type uint32
145      */
146     public static final int FORMAT_UINT32 = 0x14;
147 
148     /**
149      * Characteristic value format type sint8
150      */
151     public static final int FORMAT_SINT8 = 0x21;
152 
153     /**
154      * Characteristic value format type sint16
155      */
156     public static final int FORMAT_SINT16 = 0x22;
157 
158     /**
159      * Characteristic value format type sint32
160      */
161     public static final int FORMAT_SINT32 = 0x24;
162 
163     /**
164      * Characteristic value format type sfloat (16-bit float)
165      */
166     public static final int FORMAT_SFLOAT = 0x32;
167 
168     /**
169      * Characteristic value format type float (32-bit float)
170      */
171     public static final int FORMAT_FLOAT = 0x34;
172 
173 
174     /**
175      * The UUID of this characteristic.
176      *
177      * @hide
178      */
179     protected UUID mUuid;
180 
181     /**
182      * Instance ID for this characteristic.
183      *
184      * @hide
185      */
186     @UnsupportedAppUsage
187     protected int mInstance;
188 
189     /**
190      * Characteristic properties.
191      *
192      * @hide
193      */
194     protected int mProperties;
195 
196     /**
197      * Characteristic permissions.
198      *
199      * @hide
200      */
201     protected int mPermissions;
202 
203     /**
204      * Key size (default = 16).
205      *
206      * @hide
207      */
208     protected int mKeySize = 16;
209 
210     /**
211      * Write type for this characteristic.
212      * See WRITE_TYPE_* constants.
213      *
214      * @hide
215      */
216     protected int mWriteType;
217 
218     /**
219      * Back-reference to the service this characteristic belongs to.
220      *
221      * @hide
222      */
223     @UnsupportedAppUsage
224     protected BluetoothGattService mService;
225 
226     /**
227      * The cached value of this characteristic.
228      *
229      * @hide
230      */
231     protected byte[] mValue;
232 
233     /**
234      * List of descriptors included in this characteristic.
235      */
236     protected List<BluetoothGattDescriptor> mDescriptors;
237 
238     /**
239      * Create a new BluetoothGattCharacteristic.
240      *
241      * @param uuid The UUID for this characteristic
242      * @param properties Properties of this characteristic
243      * @param permissions Permissions for this characteristic
244      */
BluetoothGattCharacteristic(UUID uuid, int properties, int permissions)245     public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
246         initCharacteristic(null, uuid, 0, properties, permissions);
247     }
248 
249     /**
250      * Create a new BluetoothGattCharacteristic
251      *
252      * @hide
253      */
BluetoothGattCharacteristic(BluetoothGattService service, UUID uuid, int instanceId, int properties, int permissions)254     /*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
255             UUID uuid, int instanceId,
256             int properties, int permissions) {
257         initCharacteristic(service, uuid, instanceId, properties, permissions);
258     }
259 
260     /**
261      * Create a new BluetoothGattCharacteristic
262      *
263      * @hide
264      */
BluetoothGattCharacteristic(UUID uuid, int instanceId, int properties, int permissions)265     public BluetoothGattCharacteristic(UUID uuid, int instanceId,
266             int properties, int permissions) {
267         initCharacteristic(null, uuid, instanceId, properties, permissions);
268     }
269 
initCharacteristic(BluetoothGattService service, UUID uuid, int instanceId, int properties, int permissions)270     private void initCharacteristic(BluetoothGattService service,
271             UUID uuid, int instanceId,
272             int properties, int permissions) {
273         mUuid = uuid;
274         mInstance = instanceId;
275         mProperties = properties;
276         mPermissions = permissions;
277         mService = service;
278         mValue = null;
279         mDescriptors = new ArrayList<BluetoothGattDescriptor>();
280 
281         if ((mProperties & PROPERTY_WRITE_NO_RESPONSE) != 0) {
282             mWriteType = WRITE_TYPE_NO_RESPONSE;
283         } else {
284             mWriteType = WRITE_TYPE_DEFAULT;
285         }
286     }
287 
288     @Override
describeContents()289     public int describeContents() {
290         return 0;
291     }
292 
293     @Override
writeToParcel(Parcel out, int flags)294     public void writeToParcel(Parcel out, int flags) {
295         out.writeParcelable(new ParcelUuid(mUuid), 0);
296         out.writeInt(mInstance);
297         out.writeInt(mProperties);
298         out.writeInt(mPermissions);
299         out.writeInt(mKeySize);
300         out.writeInt(mWriteType);
301         out.writeTypedList(mDescriptors);
302     }
303 
304     public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattCharacteristic> CREATOR =
305             new Parcelable.Creator<BluetoothGattCharacteristic>() {
306         public BluetoothGattCharacteristic createFromParcel(Parcel in) {
307             return new BluetoothGattCharacteristic(in);
308         }
309 
310         public BluetoothGattCharacteristic[] newArray(int size) {
311             return new BluetoothGattCharacteristic[size];
312         }
313     };
314 
BluetoothGattCharacteristic(Parcel in)315     private BluetoothGattCharacteristic(Parcel in) {
316         mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
317         mInstance = in.readInt();
318         mProperties = in.readInt();
319         mPermissions = in.readInt();
320         mKeySize = in.readInt();
321         mWriteType = in.readInt();
322 
323         mDescriptors = new ArrayList<BluetoothGattDescriptor>();
324 
325         ArrayList<BluetoothGattDescriptor> descs =
326                 in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
327         if (descs != null) {
328             for (BluetoothGattDescriptor desc : descs) {
329                 desc.setCharacteristic(this);
330                 mDescriptors.add(desc);
331             }
332         }
333     }
334 
335     /**
336      * Returns the desired key size.
337      *
338      * @hide
339      */
getKeySize()340     public int getKeySize() {
341         return mKeySize;
342     }
343 
344     /**
345      * Adds a descriptor to this characteristic.
346      *
347      * @param descriptor Descriptor to be added to this characteristic.
348      * @return true, if the descriptor was added to the characteristic
349      */
addDescriptor(BluetoothGattDescriptor descriptor)350     public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
351         mDescriptors.add(descriptor);
352         descriptor.setCharacteristic(this);
353         return true;
354     }
355 
356     /**
357      * Get a descriptor by UUID and isntance id.
358      *
359      * @hide
360      */
getDescriptor(UUID uuid, int instanceId)361     /*package*/  BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
362         for (BluetoothGattDescriptor descriptor : mDescriptors) {
363             if (descriptor.getUuid().equals(uuid)
364                     && descriptor.getInstanceId() == instanceId) {
365                 return descriptor;
366             }
367         }
368         return null;
369     }
370 
371     /**
372      * Returns the service this characteristic belongs to.
373      *
374      * @return The asscociated service
375      */
getService()376     public BluetoothGattService getService() {
377         return mService;
378     }
379 
380     /**
381      * Sets the service associated with this device.
382      *
383      * @hide
384      */
385     @UnsupportedAppUsage
setService(BluetoothGattService service)386     /*package*/ void setService(BluetoothGattService service) {
387         mService = service;
388     }
389 
390     /**
391      * Returns the UUID of this characteristic
392      *
393      * @return UUID of this characteristic
394      */
getUuid()395     public UUID getUuid() {
396         return mUuid;
397     }
398 
399     /**
400      * Returns the instance ID for this characteristic.
401      *
402      * <p>If a remote device offers multiple characteristics with the same UUID,
403      * the instance ID is used to distuinguish between characteristics.
404      *
405      * @return Instance ID of this characteristic
406      */
getInstanceId()407     public int getInstanceId() {
408         return mInstance;
409     }
410 
411     /**
412      * Force the instance ID.
413      *
414      * @hide
415      */
setInstanceId(int instanceId)416     public void setInstanceId(int instanceId) {
417         mInstance = instanceId;
418     }
419 
420     /**
421      * Returns the properties of this characteristic.
422      *
423      * <p>The properties contain a bit mask of property flags indicating
424      * the features of this characteristic.
425      *
426      * @return Properties of this characteristic
427      */
getProperties()428     public int getProperties() {
429         return mProperties;
430     }
431 
432     /**
433      * Returns the permissions for this characteristic.
434      *
435      * @return Permissions of this characteristic
436      */
getPermissions()437     public int getPermissions() {
438         return mPermissions;
439     }
440 
441     /**
442      * Gets the write type for this characteristic.
443      *
444      * @return Write type for this characteristic
445      */
getWriteType()446     public int getWriteType() {
447         return mWriteType;
448     }
449 
450     /**
451      * Set the write type for this characteristic
452      *
453      * <p>Setting the write type of a characteristic determines how the
454      * {@link BluetoothGatt#writeCharacteristic} function write this
455      * characteristic.
456      *
457      * @param writeType The write type to for this characteristic. Can be one of: {@link
458      * #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
459      */
setWriteType(int writeType)460     public void setWriteType(int writeType) {
461         mWriteType = writeType;
462     }
463 
464     /**
465      * Set the desired key size.
466      *
467      * @hide
468      */
469     @UnsupportedAppUsage
setKeySize(int keySize)470     public void setKeySize(int keySize) {
471         mKeySize = keySize;
472     }
473 
474     /**
475      * Returns a list of descriptors for this characteristic.
476      *
477      * @return Descriptors for this characteristic
478      */
getDescriptors()479     public List<BluetoothGattDescriptor> getDescriptors() {
480         return mDescriptors;
481     }
482 
483     /**
484      * Returns a descriptor with a given UUID out of the list of
485      * descriptors for this characteristic.
486      *
487      * @return GATT descriptor object or null if no descriptor with the given UUID was found.
488      */
getDescriptor(UUID uuid)489     public BluetoothGattDescriptor getDescriptor(UUID uuid) {
490         for (BluetoothGattDescriptor descriptor : mDescriptors) {
491             if (descriptor.getUuid().equals(uuid)) {
492                 return descriptor;
493             }
494         }
495         return null;
496     }
497 
498     /**
499      * Get the stored value for this characteristic.
500      *
501      * <p>This function returns the stored value for this characteristic as
502      * retrieved by calling {@link BluetoothGatt#readCharacteristic}. The cached
503      * value of the characteristic is updated as a result of a read characteristic
504      * operation or if a characteristic update notification has been received.
505      *
506      * @return Cached value of the characteristic
507      */
getValue()508     public byte[] getValue() {
509         return mValue;
510     }
511 
512     /**
513      * Return the stored value of this characteristic.
514      *
515      * <p>The formatType parameter determines how the characteristic value
516      * is to be interpreted. For example, settting formatType to
517      * {@link #FORMAT_UINT16} specifies that the first two bytes of the
518      * characteristic value at the given offset are interpreted to generate the
519      * return value.
520      *
521      * @param formatType The format type used to interpret the characteristic value.
522      * @param offset Offset at which the integer value can be found.
523      * @return Cached value of the characteristic or null of offset exceeds value size.
524      */
getIntValue(int formatType, int offset)525     public Integer getIntValue(int formatType, int offset) {
526         if ((offset + getTypeLen(formatType)) > mValue.length) return null;
527 
528         switch (formatType) {
529             case FORMAT_UINT8:
530                 return unsignedByteToInt(mValue[offset]);
531 
532             case FORMAT_UINT16:
533                 return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
534 
535             case FORMAT_UINT32:
536                 return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
537                         mValue[offset + 2], mValue[offset + 3]);
538             case FORMAT_SINT8:
539                 return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
540 
541             case FORMAT_SINT16:
542                 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
543                         mValue[offset + 1]), 16);
544 
545             case FORMAT_SINT32:
546                 return unsignedToSigned(unsignedBytesToInt(mValue[offset],
547                         mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
548         }
549 
550         return null;
551     }
552 
553     /**
554      * Return the stored value of this characteristic.
555      * <p>See {@link #getValue} for details.
556      *
557      * @param formatType The format type used to interpret the characteristic value.
558      * @param offset Offset at which the float value can be found.
559      * @return Cached value of the characteristic at a given offset or null if the requested offset
560      * exceeds the value size.
561      */
getFloatValue(int formatType, int offset)562     public Float getFloatValue(int formatType, int offset) {
563         if ((offset + getTypeLen(formatType)) > mValue.length) return null;
564 
565         switch (formatType) {
566             case FORMAT_SFLOAT:
567                 return bytesToFloat(mValue[offset], mValue[offset + 1]);
568 
569             case FORMAT_FLOAT:
570                 return bytesToFloat(mValue[offset], mValue[offset + 1],
571                         mValue[offset + 2], mValue[offset + 3]);
572         }
573 
574         return null;
575     }
576 
577     /**
578      * Return the stored value of this characteristic.
579      * <p>See {@link #getValue} for details.
580      *
581      * @param offset Offset at which the string value can be found.
582      * @return Cached value of the characteristic
583      */
getStringValue(int offset)584     public String getStringValue(int offset) {
585         if (mValue == null || offset > mValue.length) return null;
586         byte[] strBytes = new byte[mValue.length - offset];
587         for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
588         return new String(strBytes);
589     }
590 
591     /**
592      * Updates the locally stored value of this characteristic.
593      *
594      * <p>This function modifies the locally stored cached value of this
595      * characteristic. To send the value to the remote device, call
596      * {@link BluetoothGatt#writeCharacteristic} to send the value to the
597      * remote device.
598      *
599      * @param value New value for this characteristic
600      * @return true if the locally stored value has been set, false if the requested value could not
601      * be stored locally.
602      */
setValue(byte[] value)603     public boolean setValue(byte[] value) {
604         mValue = value;
605         return true;
606     }
607 
608     /**
609      * Set the locally stored value of this characteristic.
610      * <p>See {@link #setValue(byte[])} for details.
611      *
612      * @param value New value for this characteristic
613      * @param formatType Integer format type used to transform the value parameter
614      * @param offset Offset at which the value should be placed
615      * @return true if the locally stored value has been set
616      */
setValue(int value, int formatType, int offset)617     public boolean setValue(int value, int formatType, int offset) {
618         int len = offset + getTypeLen(formatType);
619         if (mValue == null) mValue = new byte[len];
620         if (len > mValue.length) return false;
621 
622         switch (formatType) {
623             case FORMAT_SINT8:
624                 value = intToSignedBits(value, 8);
625                 // Fall-through intended
626             case FORMAT_UINT8:
627                 mValue[offset] = (byte) (value & 0xFF);
628                 break;
629 
630             case FORMAT_SINT16:
631                 value = intToSignedBits(value, 16);
632                 // Fall-through intended
633             case FORMAT_UINT16:
634                 mValue[offset++] = (byte) (value & 0xFF);
635                 mValue[offset] = (byte) ((value >> 8) & 0xFF);
636                 break;
637 
638             case FORMAT_SINT32:
639                 value = intToSignedBits(value, 32);
640                 // Fall-through intended
641             case FORMAT_UINT32:
642                 mValue[offset++] = (byte) (value & 0xFF);
643                 mValue[offset++] = (byte) ((value >> 8) & 0xFF);
644                 mValue[offset++] = (byte) ((value >> 16) & 0xFF);
645                 mValue[offset] = (byte) ((value >> 24) & 0xFF);
646                 break;
647 
648             default:
649                 return false;
650         }
651         return true;
652     }
653 
654     /**
655      * Set the locally stored value of this characteristic.
656      * <p>See {@link #setValue(byte[])} for details.
657      *
658      * @param mantissa Mantissa for this characteristic
659      * @param exponent exponent value for this characteristic
660      * @param formatType Float format type used to transform the value parameter
661      * @param offset Offset at which the value should be placed
662      * @return true if the locally stored value has been set
663      */
setValue(int mantissa, int exponent, int formatType, int offset)664     public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
665         int len = offset + getTypeLen(formatType);
666         if (mValue == null) mValue = new byte[len];
667         if (len > mValue.length) return false;
668 
669         switch (formatType) {
670             case FORMAT_SFLOAT:
671                 mantissa = intToSignedBits(mantissa, 12);
672                 exponent = intToSignedBits(exponent, 4);
673                 mValue[offset++] = (byte) (mantissa & 0xFF);
674                 mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
675                 mValue[offset] += (byte) ((exponent & 0x0F) << 4);
676                 break;
677 
678             case FORMAT_FLOAT:
679                 mantissa = intToSignedBits(mantissa, 24);
680                 exponent = intToSignedBits(exponent, 8);
681                 mValue[offset++] = (byte) (mantissa & 0xFF);
682                 mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
683                 mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
684                 mValue[offset] += (byte) (exponent & 0xFF);
685                 break;
686 
687             default:
688                 return false;
689         }
690 
691         return true;
692     }
693 
694     /**
695      * Set the locally stored value of this characteristic.
696      * <p>See {@link #setValue(byte[])} for details.
697      *
698      * @param value New value for this characteristic
699      * @return true if the locally stored value has been set
700      */
setValue(String value)701     public boolean setValue(String value) {
702         mValue = value.getBytes();
703         return true;
704     }
705 
706     /**
707      * Returns the size of a give value type.
708      */
getTypeLen(int formatType)709     private int getTypeLen(int formatType) {
710         return formatType & 0xF;
711     }
712 
713     /**
714      * Convert a signed byte to an unsigned int.
715      */
unsignedByteToInt(byte b)716     private int unsignedByteToInt(byte b) {
717         return b & 0xFF;
718     }
719 
720     /**
721      * Convert signed bytes to a 16-bit unsigned int.
722      */
unsignedBytesToInt(byte b0, byte b1)723     private int unsignedBytesToInt(byte b0, byte b1) {
724         return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
725     }
726 
727     /**
728      * Convert signed bytes to a 32-bit unsigned int.
729      */
unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3)730     private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
731         return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
732                 + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
733     }
734 
735     /**
736      * Convert signed bytes to a 16-bit short float value.
737      */
bytesToFloat(byte b0, byte b1)738     private float bytesToFloat(byte b0, byte b1) {
739         int mantissa = unsignedToSigned(unsignedByteToInt(b0)
740                 + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
741         int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
742         return (float) (mantissa * Math.pow(10, exponent));
743     }
744 
745     /**
746      * Convert signed bytes to a 32-bit short float value.
747      */
bytesToFloat(byte b0, byte b1, byte b2, byte b3)748     private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
749         int mantissa = unsignedToSigned(unsignedByteToInt(b0)
750                 + (unsignedByteToInt(b1) << 8)
751                 + (unsignedByteToInt(b2) << 16), 24);
752         return (float) (mantissa * Math.pow(10, b3));
753     }
754 
755     /**
756      * Convert an unsigned integer value to a two's-complement encoded
757      * signed value.
758      */
unsignedToSigned(int unsigned, int size)759     private int unsignedToSigned(int unsigned, int size) {
760         if ((unsigned & (1 << size - 1)) != 0) {
761             unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
762         }
763         return unsigned;
764     }
765 
766     /**
767      * Convert an integer into the signed bits of a given length.
768      */
intToSignedBits(int i, int size)769     private int intToSignedBits(int i, int size) {
770         if (i < 0) {
771             i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
772         }
773         return i;
774     }
775 }
776