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