Merge "Re-worked hardware_properties to thermal HAL." into nyc-dev
diff --git a/include/hardware/audio_policy.h b/include/hardware/audio_policy.h
index 99cb044..bacb1e5 100644
--- a/include/hardware/audio_policy.h
+++ b/include/hardware/audio_policy.h
@@ -141,14 +141,14 @@
     int (*start_output)(struct audio_policy *pol,
                         audio_io_handle_t output,
                         audio_stream_type_t stream,
-                        int session);
+                        audio_session_t session);
 
     /* indicates to the audio policy manager that the output stops being used
      * by corresponding stream. */
     int (*stop_output)(struct audio_policy *pol,
                        audio_io_handle_t output,
                        audio_stream_type_t stream,
-                       int session);
+                       audio_session_t session);
 
     /* releases the output. */
     void (*release_output)(struct audio_policy *pol, audio_io_handle_t output);
@@ -222,7 +222,7 @@
                            const struct effect_descriptor_s *desc,
                            audio_io_handle_t output,
                            uint32_t strategy,
-                           int session,
+                           audio_session_t session,
                            int id);
 
     int (*unregister_effect)(struct audio_policy *pol, int id);
@@ -367,7 +367,7 @@
 
     /* move effect to the specified output */
     int (*move_effects)(void *service,
-                        int session,
+                        audio_session_t session,
                         audio_io_handle_t src_output,
                         audio_io_handle_t dst_output);
 
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 7772b38..1349114 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -89,8 +89,10 @@
     BT_STATUS_UNHANDLED,
     BT_STATUS_AUTH_FAILURE,
     BT_STATUS_RMT_DEV_DOWN,
-    BT_STATUS_AUTH_REJECTED
-
+    BT_STATUS_AUTH_REJECTED,
+    BT_STATUS_JNI_ENVIRONMENT_ERROR,
+    BT_STATUS_JNI_THREAD_ATTACH_ERROR,
+    BT_STATUS_WAKELOCK_ERROR
 } bt_status_t;
 
 /** Bluetooth PinKey Code */
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index 3ef6d6f..a7df0ee 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -21,21 +21,21 @@
 #include "camera_common.h"
 
 /**
- * Camera device HAL 3.3 [ CAMERA_DEVICE_API_VERSION_3_3 ]
+ * Camera device HAL 3.4 [ CAMERA_DEVICE_API_VERSION_3_4 ]
  *
  * This is the current recommended version of the camera device HAL.
  *
  * Supports the android.hardware.Camera API, and as of v3.2, the
- * android.hardware.camera2 API in LIMITED or FULL modes.
+ * android.hardware.camera2 API as LIMITED or above hardware level.
  *
  * Camera devices that support this version of the HAL must return
- * CAMERA_DEVICE_API_VERSION_3_3 in camera_device_t.common.version and in
+ * CAMERA_DEVICE_API_VERSION_3_4 in camera_device_t.common.version and in
  * camera_info_t.device_version (from camera_module_t.get_camera_info).
  *
- * CAMERA_DEVICE_API_VERSION_3_3:
- *    Camera modules that may contain version 3.3 devices must implement at
- *    least version 2.2 of the camera module interface (as defined by
- *    camera_module_t.common.module_api_version).
+ * CAMERA_DEVICE_API_VERSION_3_3 and above:
+ *    Camera modules that may contain version 3.3 or above devices must
+ *    implement at least version 2.2 of the camera module interface (as defined
+ *    by camera_module_t.common.module_api_version).
  *
  * CAMERA_DEVICE_API_VERSION_3_2:
  *    Camera modules that may contain version 3.2 devices must implement at
@@ -137,6 +137,26 @@
  *
  *   - Addition of camera3 stream configuration operation mode to camera3_stream_configuration_t
  *
+ * 3.4: Minor additions to supported metadata and changes to data_space support
+ *
+ *   - Add ANDROID_SENSOR_OPAQUE_RAW_SIZE static metadata as mandatory if
+ *     RAW_OPAQUE format is supported.
+ *
+ *   - Add ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE static metadata as
+ *     mandatory if any RAW format is supported
+ *
+ *   - Switch camera3_stream_t data_space field to a more flexible definition,
+ *     using the version 0 definition of dataspace encoding.
+ *
+ *   - General metadata additions which are available to use for HALv3.2 or
+ *     newer:
+ *     - ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3
+ *     - ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST
+ *     - ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE
+ *     - ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
+ *     - ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL
+ *     - ANDROID_SENSOR_OPAQUE_RAW_SIZE
+ *     - ANDROID_SENSOR_OPTICAL_BLACK_REGIONS
  */
 
 /**
@@ -1611,11 +1631,19 @@
      *   be HAL_DATASPACE_UNKNOWN, and the appropriate color space, etc, should
      *   be determined from the usage flags and the format.
      *
-     * >= CAMERA_DEVICE_API_VERSION_3_3:
+     * = CAMERA_DEVICE_API_VERSION_3_3:
      *
      *   Always set by the camera service. HAL must use this dataSpace to
      *   configure the stream to the correct colorspace, or to select between
-     *   color and depth outputs if supported.
+     *   color and depth outputs if supported. The dataspace values are the
+     *   legacy definitions in graphics.h
+     *
+     * >= CAMERA_DEVICE_API_VERSION_3_4:
+     *
+     *   Always set by the camera service. HAL must use this dataSpace to
+     *   configure the stream to the correct colorspace, or to select between
+     *   color and depth outputs if supported. The dataspace values are set
+     *   using the V0 dataspace definitions in graphics.h
      */
     android_dataspace_t data_space;
 
@@ -1680,13 +1708,15 @@
     /**
      * >= CAMERA_DEVICE_API_VERSION_3_3:
      *
-     * The operation mode of streams in this configuration, one of the value defined in
-     * camera3_stream_configuration_mode_t.
-     * The HAL can use this mode as an indicator to set the stream property (e.g.,
-     * camera3_stream->max_buffers) appropriately. For example, if the configuration is
-     * CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE, the HAL may want to set aside more
-     * buffers for batch mode operation (see android.control.availableHighSpeedVideoConfigurations
-     * for batch mode definition).
+     * The operation mode of streams in this configuration, one of the value
+     * defined in camera3_stream_configuration_mode_t.  The HAL can use this
+     * mode as an indicator to set the stream property (e.g.,
+     * camera3_stream->max_buffers) appropriately. For example, if the
+     * configuration is
+     * CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE, the HAL may
+     * want to set aside more buffers for batch mode operation (see
+     * android.control.availableHighSpeedVideoConfigurations for batch mode
+     * definition).
      *
      */
     uint32_t operation_mode;
@@ -1933,7 +1963,7 @@
      * available. Subsequent requests are unaffected, and the device remains
      * operational. The frame_number field specifies the request for which the
      * buffer was dropped, and error_stream contains a pointer to the stream
-     * that dropped the frame.u
+     * that dropped the frame.
      */
     CAMERA3_MSG_ERROR_BUFFER = 4,
 
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
index 354d343..a54948c 100644
--- a/include/hardware/gps.h
+++ b/include/hardware/gps.h
@@ -221,9 +221,12 @@
 typedef uint16_t AGpsRefLocationType;
 #define AGPS_REF_LOCATION_TYPE_GSM_CELLID   1
 #define AGPS_REF_LOCATION_TYPE_UMTS_CELLID  2
-#define AGPS_REG_LOCATION_TYPE_MAC          3
+#define AGPS_REF_LOCATION_TYPE_MAC          3
 #define AGPS_REF_LOCATION_TYPE_LTE_CELLID   4
 
+/* Deprecated, to be removed in the next Android release. */
+#define AGPS_REG_LOCATION_TYPE_MAC          3
+
 /** Network types for update_network_state "type" parameter */
 #define AGPS_RIL_NETWORK_TYPE_MOBILE        0
 #define AGPS_RIL_NETWORK_TYPE_WIFI          1
@@ -359,7 +362,7 @@
  * If GNSS is still searching for a satellite, the corresponding state should be
  * set to GNSS_MEASUREMENT_STATE_UNKNOWN(0).
  */
-typedef uint16_t GnssMeasurementState;
+typedef uint32_t GnssMeasurementState;
 #define GNSS_MEASUREMENT_STATE_UNKNOWN                   0
 #define GNSS_MEASUREMENT_STATE_CODE_LOCK             (1<<0)
 #define GNSS_MEASUREMENT_STATE_BIT_SYNC              (1<<1)
@@ -367,6 +370,14 @@
 #define GNSS_MEASUREMENT_STATE_TOW_DECODED           (1<<3)
 #define GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS        (1<<4)
 #define GNSS_MEASUREMENT_STATE_SYMBOL_SYNC           (1<<5)
+#define GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC       (1<<6)
+#define GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED       (1<<7)
+#define GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC       (1<<8)
+#define GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC  (1<<9)
+#define GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK    (1<<10)
+#define GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK (1<<11)
+#define GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC     (1<<12)
+#define GNSS_MEASUREMENT_STATE_SBAS_SYNC             (1<<13)
 
 /* The following typedef together with its constants below are deprecated, and
  * will be removed in the next release. */
@@ -1711,10 +1722,10 @@
      *   this field can be:
      *     Searching       : [ 0       ]   : GNSS_MEASUREMENT_STATE_UNKNOWN
      *     C/A code lock   : [ 0   1ms ]   : GNSS_MEASUREMENT_STATE_CODE_LOCK is set
-     *     Symbol sync    : [ 0  10ms ]   : GNSS_MEASUREMENT_STATE_SYMBOL_SYNC is set
-     *     Bit sync       : [ 0  20ms ]   : GNSS_MEASUREMENT_STATE_BIT_SYNC is set
-     *     String sync     : [ 0    2s ]   :  GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC is set
-     *     Time of day      : [ 0  1day ]   : GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED is set
+     *     Symbol sync     : [ 0  10ms ]   : GNSS_MEASUREMENT_STATE_SYMBOL_SYNC is set
+     *     Bit sync        : [ 0  20ms ]   : GNSS_MEASUREMENT_STATE_BIT_SYNC is set
+     *     String sync     : [ 0    2s ]   : GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC is set
+     *     Time of day     : [ 0  1day ]   : GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED is set
      *
      * For Beidou, this is:
      *   Received Beidou time of week, at the measurement time in nanoseconds.
@@ -1737,7 +1748,7 @@
      *     GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK is set
      *
      *     E1B page    : [ 0    2s ] : GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC is set
-     *     Time of week: [ 0 1week ] : GNSS_MEASUREMENT_STATE_GAL_TOW_DECODED is set
+     *     Time of week: [ 0 1week ] : GNSS_MEASUREMENT_STATE_TOW_DECODED is set
      *
      * For SBAS, this is:
      *   Received SBAS time, at the measurement time in nanoseconds.
@@ -1773,9 +1784,7 @@
      * comment at top of GnssMeasurement struct.)
      *
      * It is mandatory to provide the 'uncorrected' 'pseudorange rate', and provide GpsClock's
-     * 'drift' field as well, and
-     * GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE must be set in 'flags'
-     * field. (When providing the uncorrected pseudorange rate, do not apply the
+     * 'drift' field as well (When providing the uncorrected pseudorange rate, do not apply the
      * corrections described above.)
      *
      * The value includes the 'pseudorange rate uncertainty' in it.
@@ -1843,6 +1852,8 @@
     /**
      * The number of full carrier cycles between the satellite and the receiver.
      * The reference frequency is given by the field 'carrier_frequency_hz'.
+     * Indications of possible cycle slips and resets in the accumulation of
+     * this value can be inferred from the accumulated_delta_range_state flags.
      *
      * If the data is available, 'flags' must contain
      * GNSS_MEASUREMENT_HAS_CARRIER_CYCLES.
@@ -2050,9 +2061,11 @@
      *
      * - For Beidou D2, this refers to the frame number, in the range of 1-120
      *
-     * - For Galileo F/NAV, this refers to the frame number, in the range of 1-N
+     * - For Galileo F/NAV nominal frame structure, this refers to the subframe
+     *   number, in the range of 1-12
      *
-     * - For Galileo I/NAV, this refers to the frame number in the range of 1-N
+     * - For Galileo I/NAV nominal frame structure, this refers to the subframe
+     *   number in the range of 1-24
      */
     int16_t message_id;
 
@@ -2067,9 +2080,9 @@
      * - For Glonass L1 C/A, this refers to the String number, in the range from
      *   1-15
      *
-     * - For Galileo F/NAV, this refers to the subframe number in the range 1-12
+     * - For Galileo F/NAV, this refers to the page type in the range 1-6
      *
-     * - For Galileo I/NAV, this refers to the subframe number in the range 1-24
+     * - For Galileo I/NAV, this refers to the word type in the range 1-10+
      */
     int16_t submessage_id;
 
@@ -2095,13 +2108,13 @@
      *   checksum.  These bits should be fit into 11 bytes, with MSB first (skip
      *   B86-B88), covering a time period of 2 seconds.
      *
-     * - For Galileo F/NAV, each subframe contains 5 238-bit word (sync & tail
-     *   symbols excluded). Each word should be fit into 30-bytes, with MSB
-     *   first (skip B239, B240), covering a time period of 10 seconds.
+     * - For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols
+     *   excluded). Each word should be fit into 30-bytes, with MSB first (skip
+     *   B239, B240), covering a time period of 10 seconds.
      *
-     * - For Galileo I/NAV, each subframe contains 15 114-bit word (sync & tail
-     *   symbols excluded). Each word should be fit into 15-bytes, with MSB
-     *   first (skip B115-B120), covering a time period of 2 seconds.
+     * - For Galileo I/NAV, each page contains 2 page parts, even and odd, with
+     *   a total of 2x114 = 228 bits, (sync & tail excluded) that should be fit
+     *   into 29 bytes, with MSB first (skip B229-B232).
      */
     uint8_t* data;
 
diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h
index 4a080a1..9086d1c 100644
--- a/include/hardware/vehicle.h
+++ b/include/hardware/vehicle.h
@@ -1030,9 +1030,11 @@
     VEHICLE_VALUE_TYPE_ZONED_FLOAT              = 0x30,
     VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2         = 0x31,
     VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3         = 0x32,
+    VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4         = 0x33,
     VEHICLE_VALUE_TYPE_ZONED_INT32              = 0x40,
     VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2         = 0x41,
     VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3         = 0x42,
+    VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4         = 0x43,
 };
 
 /**
@@ -1061,30 +1063,6 @@
 };
 
 /**
- * Error code used in HAL implemnentation. Follows utils/Errors.h
- */
-enum vehicle_error_code {
-    VEHICLE_NO_ERROR    = 0x0,
-    VEHICLE_ERROR_UNKNOWN       = (-2147483647 - 1), // INT32_MIN value
-    VEHICLE_ERROR_NO_MEMORY           = -12, //ENOMEM
-    VEHICLE_ERROR_INVALID_OPERATION   = -38, //ENOSYS
-    VEHICLE_ERROR_BAD_VALUE           = -22, //EINVAL
-    VEHICLE_ERROR_BAD_TYPE            = (VEHICLE_ERROR_UNKNOWN + 1),
-    VEHICLE_ERROR_NAME_NOT_FOUND      = -2, //ENOENT
-    VEHICLE_ERROR_PERMISSION_DENIED   = -1, //EPERM
-    VEHICLE_ERROR_NO_INIT             = -19, //ENODEV
-    VEHICLE_ERROR_ALREADY_EXISTS      = -17, //EEXIST
-    VEHICLE_ERROR_DEAD_OBJECT         = -32, //EPIPE
-    VEHICLE_ERROR_FAILED_TRANSACTION  = (VEHICLE_ERROR_UNKNOWN + 2),
-    VEHICLE_ERROR_BAD_INDEX           = -75, //EOVERFLOW
-    VEHICLE_ERROR_NOT_ENOUGH_DATA     = -61, //ENODATA
-    VEHICLE_ERROR_WOULD_BLOCK         = -11, //EWOULDBLOCK
-    VEHICLE_ERROR_TIMED_OUT           = -110, //ETIMEDOUT
-    VEHICLE_ERROR_UNKNOWN_TRANSACTION = -74, //EBADMSG
-    VEHICLE_FDS_NOT_ALLOWED     = (VEHICLE_ERROR_UNKNOWN + 7),
-};
-
-/**
  * This describes how value of property can change.
  */
 enum vehicle_prop_change_mode {
@@ -1287,52 +1265,6 @@
  */
 typedef vehicle_str_t vehicle_bytes_t;
 
-typedef struct vehicle_zoned_int32 {
-    union {
-        int32_t zone;
-        int32_t seat;
-        int32_t window;
-    };
-    int32_t value;
-} vehicle_zoned_int32_t;
-
-typedef struct vehicle_zoned_int32_array {
-    union {
-        int32_t zone;
-        int32_t seat;
-        int32_t window;
-    };
-    int32_t values[3];
-} vehicle_zoned_int32_array_t;
-
-typedef struct vehicle_zoned_float {
-    union {
-        int32_t zone;
-        int32_t seat;
-        int32_t window;
-    };
-    float value;
-} vehicle_zoned_float_t;
-
-typedef struct vehicle_zoned_float_array {
-    union {
-        int32_t zone;
-        int32_t seat;
-        int32_t window;
-    };
-    float values[3];
-} vehicle_zoned_float_array_t;
-
-typedef struct vehicle_zoned_boolean {
-    union {
-        int32_t zone;
-        int32_t seat;
-        int32_t window;
-    };
-    vehicle_boolean_t value;
-} vehicle_zoned_boolean_t;
-
-
 typedef struct vehicle_prop_config {
     int32_t prop;
 
@@ -1358,17 +1290,13 @@
      * Define necessary permission model to access the data.
      */
     int32_t permission_model;
+
     /**
      * Some of the properties may have associated zones (such as hvac), in these
      * cases the config should contain an ORed value for the associated zone.
      */
     union {
         /**
-         * For generic configuration information
-         */
-        int32_t config_flags;
-
-        /**
          * The value is derived by ORing one or more of enum vehicle_zone members.
          */
         int32_t vehicle_zone_flags;
@@ -1376,7 +1304,16 @@
         int32_t vehicle_seat_flags;
         /** The value is derived by ORing one or more of enum vehicle_window members. */
         int32_t vehicle_window_flags;
+    };
 
+    /**
+     * Property specific configuration information. Usage of this will be defined per each property.
+     */
+    union {
+        /**
+         * For generic configuration information
+         */
+        int32_t config_flags;
         /** The number of presets that are stored by the radio module. Pass 0 if
          * there are no presets available. The range of presets is defined to be
          * from 1 (see VEHICLE_RADIO_PRESET_MIN_VALUE) to vehicle_radio_num_presets.
@@ -1419,6 +1356,8 @@
      *      array should be set to NULL.
      *   2. All zones having separate min / max value: *_min/max_values array should be populated
      *      and its length should be the same as number of active zones specified by *_zone_flags.
+     *
+     * Should be NULL if each zone does not have separate max values.
      */
     union {
         float* float_min_values;
@@ -1428,6 +1367,8 @@
 
     /**
      * Array of max values for zoned properties. See above for its usage.
+     * Should be NULL if each zone does not have separate max values.
+     * If not NULL, length of array should match that of min_values.
      */
     union {
         float* float_max_values;
@@ -1457,59 +1398,30 @@
  * below). We define these properties outside in global scope so that HAL
  * implementation and HAL users (JNI) can typecast vehicle_hvac correctly.
  */
-typedef vehicle_zoned_int32_t vehicle_hvac_fan_speed_t;
-
-typedef vehicle_zoned_int32_t vehicle_hvac_fan_direction_t;
-
-typedef vehicle_zoned_float_t vehicle_hvac_zone_temperature_t;
-
-//TODO Typical seat heat/cooling is done in fixed steps. Needs better definition.
-//typedef struct vehicle_hvac_seat_temperature {
-//    // Value should be one of enum vehicle_seat.
-//    int32_t seat;
-//    float temperature;
-//} vehicle_hvac_heated_seat_temperature_t;
-
-typedef vehicle_zoned_boolean_t vehicle_hvac_defrost_on_t;
-
-typedef vehicle_zoned_boolean_t vehicle_hvac_ac_on_t;
-
-typedef vehicle_boolean_t vehicle_hvac_max_ac_on_t;
-
-typedef vehicle_boolean_t vehicle_hvac_max_defrost_on_t;
-
-typedef vehicle_boolean_t vehicle_hvac_recirc_on_t;
-
-typedef vehicle_boolean_t vehicle_hvac_dual_on_t;
-
 typedef struct vehicle_hvac {
     /**
      * Define one structure for each possible HVAC property.
      * NOTES:
-     * a) Zone is defined in enum vehicle_zone.
-     * b) Fan speed is a number from (0 - 6) where 6 is the highest speed. (TODO define enum)
-     * c) Temperature is a floating point Celcius scale.
-     * d) Direction is defined in enum vehicle_fan_direction.
+     * a) Fan speed is a number from (0 - 6) where 6 is the highest speed. (TODO define enum)
+     * b) Temperature is a floating point Celcius scale.
+     * c) Direction is defined in enum vehicle_fan_direction.
      *
      * The HAL should create #entries number of vehicle_hvac_properties and
      * assign it to "properties" variable below.
      */
     union {
-        vehicle_hvac_fan_speed_t fan_speed;
-        vehicle_hvac_fan_direction_t fan_direction;
-        vehicle_hvac_ac_on_t ac_on;
-        vehicle_hvac_max_ac_on_t max_ac_on;
-        vehicle_hvac_max_defrost_on_t max_defrost_on;
-        vehicle_hvac_recirc_on_t recirc_on;
-        vehicle_hvac_dual_on_t dual_on;
+        int32_t fan_speed;
+        int32_t fan_direction;
+        vehicle_boolean_t ac_on;
+        vehicle_boolean_t max_ac_on;
+        vehicle_boolean_t max_defrost_on;
+        vehicle_boolean_t recirc_on;
+        vehicle_boolean_t dual_on;
 
-        vehicle_hvac_zone_temperature_t temperature_current;
-        vehicle_hvac_zone_temperature_t temperature_set;
+        float temperature_current;
+        float temperature_set;
 
-        //TODO Heated seat.
-        //vehicle_hvac_heated_seat_t heated_seat;
-
-        vehicle_hvac_defrost_on_t defrost_on;
+        vehicle_boolean_t defrost_on;
     };
 } vehicle_hvac_t;
 
@@ -1540,11 +1452,6 @@
     vehicle_str_t str_value;
     vehicle_bytes_t bytes_value;
     vehicle_boolean_t boolean_value;
-    vehicle_zoned_int32_t zoned_int32_value;
-    vehicle_zoned_int32_array_t zoned_int32_array;
-    vehicle_zoned_float_t zoned_float_value;
-    vehicle_zoned_float_array_t zoned_float_array;
-    vehicle_zoned_boolean_t zoned_boolean_value;
 
     // Vehicle Information.
     vehicle_str_t info_vin;
@@ -1615,6 +1522,15 @@
     /** time is elapsed nanoseconds since boot */
     int64_t timestamp;
 
+    /**
+     * Zone information for zoned property. For non-zoned property, this should be ignored.
+     */
+    union {
+        int32_t zone;
+        int32_t seat;
+        int32_t window;
+    };
+
     vehicle_value_t value;
 } vehicle_prop_value_t;
 
@@ -1645,11 +1561,10 @@
 };
 
 /*
- * Suggests that an error condition has occured. error_code should be one of
- * enum vehicle_error_code.
+ * Suggests that an error condition has occurred.
  *
- * @param error_code Error code. It should be one of enum vehicle_error_code.
- *                   See error code for details.
+ * @param error_code Error code. error_code should be standard error code with
+ *                negative value like -EINVAL.
  * @parm property Note a property where error has happened. If this is generic error, property
  *                should be VEHICLE_PROPERTY_INVALID.
  * @param operation Represent the operation where the error has happened. Should be one of
@@ -1703,14 +1618,29 @@
      * Caller will set data->prop, data->value_type, and optionally zone value for zoned property.
      * But HAL implementation needs to fill all entries properly when returning.
      * For pointer type, HAL implementation should allocate necessary memory and caller is
-     * responsible for freeing memory for the pointer.
+     * responsible for calling release_memory_from_get, which allows HAL to release allocated
+     * memory.
      * For VEHICLE_PROP_CHANGE_MODE_STATIC type of property, get should return the same value
      * always.
      * For VEHICLE_PROP_CHANGE_MODE_ON_CHANGE type of property, it should return the latest value.
+     * If there is no data available yet, which can happen during initial stage, this call should
+     * return immediately with error code of -EAGAIN.
      */
     int (*get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data);
 
     /**
+     * Release memory allocated to data in previous get call. get call for byte or string involves
+     * allocating necessary memory from vehicle hal.
+     * To be safe, memory allocated by vehicle hal should be released by vehicle hal and vehicle
+     * network service will call this when data from vehicle hal is no longer necessary.
+     * vehicle hal implementation should only release member of vehicle_prop_value_t like
+     * data->str_value.data or data->bytes_value.data but not data itself as data itself is
+     * allocated from vehicle network service. Once memory is freed, corresponding pointer should
+     * be set to NULL bu vehicle hal.
+     */
+    void (*release_memory_from_get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data);
+
+    /**
      * Set a vehicle property value.  data should be allocated properly and not
      * NULL.
      * The caller of the API OWNS the data field.
diff --git a/modules/radio/Android.mk b/modules/radio/Android.mk
index e7647b2..221424f 100644
--- a/modules/radio/Android.mk
+++ b/modules/radio/Android.mk
@@ -17,17 +17,21 @@
 # Stub radio HAL module, used for tests
 include $(CLEAR_VARS)
 
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
 LOCAL_MODULE := radio.fm.default
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := radio_hw.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils libradio_metadata
 LOCAL_MODULE_TAGS := optional
-LOCAL_32_BIT_ONLY := true
 
 include $(BUILD_SHARED_LIBRARY)
 
 # Stub radio tool that can be run in native.
 include $(CLEAR_VARS)
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
 LOCAL_MODULE := radio_hal_tool
 LOCAL_SRC_FILES := radio_hal_tool.c
 LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
diff --git a/modules/radio/radio_hal_tool.c b/modules/radio/radio_hal_tool.c
index f5c7637..05d872e 100644
--- a/modules/radio/radio_hal_tool.c
+++ b/modules/radio/radio_hal_tool.c
@@ -151,7 +151,7 @@
             case RADIO_METADATA_TYPE_CLOCK:
                 printf("UTC Epoch: %lld\n"
                        "UTC Offset: %d\n",
-                       ((radio_metadata_clock_t *) value)->utc_seconds_since_epoch,
+                       (long long)((radio_metadata_clock_t *) value)->utc_seconds_since_epoch,
                        ((radio_metadata_clock_t *) value)->timezone_offset_in_minutes);
         }
     }
diff --git a/modules/soundtrigger/Android.mk b/modules/soundtrigger/Android.mk
index 325980c..bb58053 100644
--- a/modules/soundtrigger/Android.mk
+++ b/modules/soundtrigger/Android.mk
@@ -22,6 +22,5 @@
 LOCAL_SRC_FILES := sound_trigger_hw.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_MODULE_TAGS := optional
-LOCAL_32_BIT_ONLY := true
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/soundtrigger/sound_trigger_hw.c b/modules/soundtrigger/sound_trigger_hw.c
index c7739cc..dadad82 100644
--- a/modules/soundtrigger/sound_trigger_hw.c
+++ b/modules/soundtrigger/sound_trigger_hw.c
@@ -24,8 +24,8 @@
  *
  * Commands include:
  * ls : Lists all models that have been loaded.
- * trig <index> : Sends a recognition event for the model at the given index.
- * update <index> : Sends a model update event for the model at the given index.
+ * trig <uuid> : Sends a recognition event for the model at the given uuid
+ * update <uuid> : Sends a model update event for the model at the given uuid.
  * close : Closes the network connection.
  *
  * To enable this file, you can make with command line parameter
@@ -86,6 +86,7 @@
 struct recognition_context {
     // Sound Model information, added in method load_sound_model
     sound_model_handle_t model_handle;
+    sound_trigger_uuid_t model_uuid;
     sound_trigger_sound_model_type_t model_type;
     sound_model_callback_t model_callback;
     void *model_cookie;
@@ -115,25 +116,78 @@
     int next_sound_model_id;
 };
 
+static bool check_uuid_equality(sound_trigger_uuid_t uuid1, sound_trigger_uuid_t uuid2) {
+    if (uuid1.timeLow != uuid2.timeLow ||
+        uuid1.timeMid != uuid2.timeMid ||
+        uuid1.timeHiAndVersion != uuid2.timeHiAndVersion ||
+        uuid1.clockSeq != uuid2.clockSeq) {
+        return false;
+    }
+    for (int i = 0; i < 6; i++) {
+        if(uuid1.node[i] != uuid2.node[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool str_to_uuid(char* uuid_str, sound_trigger_uuid_t* uuid) {
+    if (uuid_str == NULL) {
+        ALOGI("Invalid str_to_uuid input.");
+        return false;
+    }
+
+    int tmp[10];
+    if (sscanf(uuid_str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+               tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        ALOGI("Invalid UUID, got: %s", uuid_str);
+        return false;
+    }
+    uuid->timeLow = (unsigned int)tmp[0];
+    uuid->timeMid = (unsigned short)tmp[1];
+    uuid->timeHiAndVersion = (unsigned short)tmp[2];
+    uuid->clockSeq = (unsigned short)tmp[3];
+    uuid->node[0] = (unsigned char)tmp[4];
+    uuid->node[1] = (unsigned char)tmp[5];
+    uuid->node[2] = (unsigned char)tmp[6];
+    uuid->node[3] = (unsigned char)tmp[7];
+    uuid->node[4] = (unsigned char)tmp[8];
+    uuid->node[5] = (unsigned char)tmp[9];
+    return true;
+}
+
 // Returns model at the given index, null otherwise (error, doesn't exist, etc).
 // Note that here index starts from zero.
-struct recognition_context* fetch_model_at_index(
-        struct stub_sound_trigger_device* stdev, int index) {
+struct recognition_context* fetch_model_with_handle(
+        struct stub_sound_trigger_device* stdev, sound_model_handle_t* model_handle) {
     ALOGI("%s", __func__);
     struct recognition_context *model_context = NULL;
     struct recognition_context *last_model_context = stdev->root_model_context;
-    unsigned int model_index = 0;
     while(last_model_context) {
-        if (model_index == index) {
+        if (last_model_context->model_handle == *model_handle) {
             model_context = last_model_context;
             break;
         }
         last_model_context = last_model_context->next;
-        model_index++;
     }
     return model_context;
 }
 
+// Returns the first model that matches the sound model UUID.
+static sound_model_handle_t* get_model_handle_with_uuid(struct stub_sound_trigger_device* stdev,
+                                                        sound_trigger_uuid_t uuid) {
+    sound_model_handle_t* model_handle_str = NULL;
+    struct recognition_context *last_model_context = stdev->root_model_context;
+    while(last_model_context) {
+        if (check_uuid_equality(last_model_context->model_uuid, uuid)) {
+            model_handle_str = &last_model_context->model_handle;
+            break;
+        }
+        last_model_context = last_model_context->next;
+    }
+    return model_handle_str;
+}
+
 /* Will reuse ids when overflow occurs */
 static sound_model_handle_t generate_sound_model_handle(const struct sound_trigger_hw_device *dev) {
     struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
@@ -232,57 +286,73 @@
     write(conn_socket, tmp_write_buffer, num);
 }
 
-void send_recognition_event(int conn_socket, char* buffer, struct stub_sound_trigger_device* stdev,
-                            int recognition_status) {
+static void print_uuid(sound_trigger_uuid_t uuid) {
+    ALOGI("%s %x-%x-%x-%x-%x%x%x%x%x%x", __func__, uuid.timeLow, uuid.timeMid,
+          uuid.timeHiAndVersion, uuid.clockSeq, uuid.node[0], uuid.node[1], uuid.node[2],
+          uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
+static void write_uuid(int conn_socket, sound_trigger_uuid_t uuid) {
+    write_vastr(conn_socket, "%d-%x-%x-%x-%x%x%x%x%x%x\n", uuid.timeLow, uuid.timeMid,
+                uuid.timeHiAndVersion, uuid.clockSeq, uuid.node[0], uuid.node[1], uuid.node[2],
+                uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
+void send_recognition_event_with_handle(int conn_socket, sound_model_handle_t* model_handle_str,
+                                        struct stub_sound_trigger_device* stdev,
+                                        int recognition_status) {
     ALOGI("%s", __func__);
-    char* model_handle_str = strtok(NULL, " ");
     if (model_handle_str == NULL) {
-        write_string(conn_socket, "Bad sound model id.\n");
-        return;
-    }
-    int index = -1;
-    if (sscanf(model_handle_str, "%d", &index) <= 0) {
-        write_vastr(conn_socket, "Unable to parse sound model index: %s\n", model_handle_str);
+        ALOGI("%s Bad sound model handle.", __func__);
+        write_string(conn_socket, "Bad sound model handle.\n");
         return;
     }
 
-    if (index < (int)hw_properties.max_sound_models) {
-        ALOGI("Going to send trigger for model index #%d", index );
-        struct recognition_context *model_context = fetch_model_at_index(stdev, index);
-        if (model_context) {
-            if (model_context->recognition_callback == NULL) {
-                ALOGI("%s No matching callback for handle %d", __func__,
-                      model_context->model_handle);
-                return;
+    ALOGI("Going to send trigger for model");
+    struct recognition_context *model_context = fetch_model_with_handle(stdev, model_handle_str);
+    if (model_context) {
+        if (model_context->recognition_callback == NULL) {
+            ALOGI("%s No matching callback for handle %d", __func__,
+                  model_context->model_handle);
+            return;
+        }
+
+        if (model_context->model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
+            struct sound_trigger_phrase_recognition_event *event;
+            event = (struct sound_trigger_phrase_recognition_event *)
+                    sound_trigger_keyphrase_event_alloc(model_context->model_handle,
+                                                        model_context->config,
+                                                        recognition_status);
+            if (event) {
+                model_context->recognition_callback(event, model_context->recognition_cookie);
+                free(event);
             }
-
-            if (model_context->model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
-                struct sound_trigger_phrase_recognition_event *event;
-                event = (struct sound_trigger_phrase_recognition_event *)
-                        sound_trigger_keyphrase_event_alloc(model_context->model_handle,
-                                                            model_context->config,
-                                                            recognition_status);
-                if (event) {
-                    model_context->recognition_callback(event, model_context->recognition_cookie);
-                    free(event);
-                }
-            } else if (model_context->model_type == SOUND_MODEL_TYPE_GENERIC) {
-                struct sound_trigger_generic_recognition_event *event;
-                event = (struct sound_trigger_generic_recognition_event *)
-                        sound_trigger_generic_event_alloc(model_context->model_handle,
-                                                          model_context->config,
-                                                          recognition_status);
-                if (event) {
-                    model_context->recognition_callback(event, model_context->recognition_cookie);
-                    free(event);
-                }
-            } else {
-                ALOGI("Unknown Sound Model Type, No Event to Send");
+        } else if (model_context->model_type == SOUND_MODEL_TYPE_GENERIC) {
+            struct sound_trigger_generic_recognition_event *event;
+            event = (struct sound_trigger_generic_recognition_event *)
+                    sound_trigger_generic_event_alloc(model_context->model_handle,
+                                                      model_context->config,
+                                                      recognition_status);
+            if (event) {
+                model_context->recognition_callback(event, model_context->recognition_cookie);
+                free(event);
             }
         } else {
-            ALOGI("Sound Model Does Not Exist at this Index: %d", index);
-            write_string(conn_socket, "Sound Model Does Not Exist at given Index.\n");
+            ALOGI("Unknown Sound Model Type, No Event to Send");
         }
+    } else {
+        ALOGI("No model for this handle");
+    }
+}
+
+static void send_recognition_event(int conn_socket, struct stub_sound_trigger_device* stdev,
+                                   int recognition_status) {
+    char* model_uuid_str = strtok(NULL, " \r\n");
+    sound_trigger_uuid_t model_uuid;
+    if (str_to_uuid(model_uuid_str, &model_uuid)) {
+        sound_model_handle_t* model_handle_str = get_model_handle_with_uuid(stdev, model_uuid);
+        send_recognition_event_with_handle(conn_socket, model_handle_str, stdev,
+                                           recognition_status);
     }
 }
 
@@ -362,7 +432,7 @@
         ALOGE("Opening socket");
         self_socket = socket(AF_INET, SOCK_STREAM, 0);
         if (self_socket < 0) {
-            ALOGE("Error on socket creation");
+            ALOGE("Error on socket creation: %s", strerror(errno));
             exit = true;
         } else {
             ALOGI("Socket created");
@@ -416,25 +486,25 @@
     }
     while (last_model_context) {
         write_vastr(conn_socket, "Model Index: %d\n", model_index);
-        ALOGI("Model Index: %d\n", model_index);
-        write_vastr(conn_socket, "Model handle: %d\n",
-                    last_model_context->model_handle);
-        ALOGI("Model handle: %d\n", last_model_context->model_handle);
+        ALOGI("Model Index: %d", model_index);
+        write_vastr(conn_socket, "Model handle: %d\n", last_model_context->model_handle);
+        ALOGI("Model handle: %d", last_model_context->model_handle);
+        write_uuid(conn_socket, last_model_context->model_uuid);
+        print_uuid(last_model_context->model_uuid);
         sound_trigger_sound_model_type_t model_type = last_model_context->model_type;
 
         if (model_type == SOUND_MODEL_TYPE_KEYPHRASE) {
             write_string(conn_socket, "Keyphrase sound Model.\n");
-            ALOGI("Keyphrase sound Model.\n");
+            ALOGI("Keyphrase sound Model.");
         } else if (model_type == SOUND_MODEL_TYPE_GENERIC) {
             write_string(conn_socket, "Generic sound Model.\n");
-            ALOGI("Generic sound Model.\n");
+            ALOGI("Generic sound Model.");
         } else {
-            write_vastr(conn_socket, "Unknown sound model type: %d\n",
-                        model_type);
-            ALOGI("Unknown sound model type: %d\n", model_type);
+            write_vastr(conn_socket, "Unknown sound model type: %d\n", model_type);
+            ALOGI("Unknown sound model type: %d", model_type);
         }
         write_string(conn_socket, "----\n\n");
-        ALOGI("----\n\n");
+        ALOGI("----");
         last_model_context = last_model_context->next;
         model_index++;
     }
@@ -448,24 +518,17 @@
         write_string(conn_socket, "Bad sound model id.\n");
         return;
     }
-    int index = -1;
-    if (sscanf(model_handle_str, "%d", &index) <= 0) {
-        write_vastr(conn_socket, "Unable to parse sound model index: %s\n", model_handle_str);
-        return;
-    }
 
-    if (index < (int)hw_properties.max_sound_models) {
-        ALOGI("Going to model event for model index #%d", index );
-        struct recognition_context *model_context = fetch_model_at_index(stdev, index);
-        if (model_context) {
+    ALOGI("Going to model event for model index #%d", index );
+    struct recognition_context *model_context = fetch_model_with_handle(stdev, model_handle_str);
+    if (model_context) {
 
-            send_model_event(model_context->model_handle,
-                             model_context->model_callback,
-                             model_context->model_cookie);
-        } else {
-            ALOGI("Sound Model Does Not Exist at this Index: %d", index);
-            write_string(conn_socket, "Sound Model Does Not Exist at given Index.\n");
-        }
+        send_model_event(model_context->model_handle,
+                         model_context->model_callback,
+                         model_context->model_cookie);
+    } else {
+        ALOGI("Sound Model Does Not Exist with this handle");
+        write_string(conn_socket, "Sound Model Does Not Exist with this handle.\n");
     }
 }
 
@@ -494,17 +557,17 @@
     while(!input_done) {
         if (fgets(buffer, PARSE_BUF_LEN, input_fp) != NULL) {
             pthread_mutex_lock(&stdev->lock);
-            char* command = strtok(buffer, "  \n");
+            char* command = strtok(buffer, " \r\n");
             if (command == NULL) {
                 write_bad_command_error(conn_socket, command);
             } else if (strncmp(command, COMMAND_LS, 2) == 0) {
                 list_models(conn_socket, buffer, stdev);
             } else if (strcmp(command, COMMAND_RECOGNITION_TRIGGER) == 0) {
-                send_recognition_event(conn_socket, buffer, stdev, RECOGNITION_STATUS_SUCCESS);
+                send_recognition_event(conn_socket, stdev, RECOGNITION_STATUS_SUCCESS);
             } else if (strcmp(command, COMMAND_RECOGNITION_ABORT) == 0) {
-                send_recognition_event(conn_socket, buffer, stdev, RECOGNITION_STATUS_ABORT);
+                send_recognition_event(conn_socket, stdev, RECOGNITION_STATUS_ABORT);
             } else if (strcmp(command, COMMAND_RECOGNITION_FAILURE) == 0) {
-                send_recognition_event(conn_socket, buffer, stdev, RECOGNITION_STATUS_FAILURE);
+                send_recognition_event(conn_socket, stdev, RECOGNITION_STATUS_FAILURE);
             } else if (strcmp(command, COMMAND_UPDATE) == 0) {
                 process_send_model_event(conn_socket, buffer, stdev);
             } else if (strncmp(command, COMMAND_CLOSE, 5) == 0) {
@@ -561,11 +624,9 @@
                                   sound_model_callback_t callback,
                                   void *cookie,
                                   sound_model_handle_t *handle) {
-    ALOGI("load_sound_model.");
     struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
-    int status = 0;
-
     ALOGI("%s stdev %p", __func__, stdev);
+    int status = 0;
     pthread_mutex_lock(&stdev->lock);
 
     if (handle == NULL || sound_model == NULL) {
@@ -613,6 +674,7 @@
     char *data = (char *)sound_model + sound_model->data_offset;
     ALOGI("%s data size %d data %d - %d", __func__,
           sound_model->data_size, data[0], data[sound_model->data_size - 1]);
+    model_context->model_uuid = sound_model->uuid;
     model_context->model_callback = callback;
     model_context->model_cookie = cookie;
     model_context->config = NULL;
@@ -628,9 +690,9 @@
 static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
                                     sound_model_handle_t handle) {
     // If recognizing, stop_recognition must be called for a sound model before unload_sound_model
+    ALOGI("%s", __func__);
     struct stub_sound_trigger_device *stdev = (struct stub_sound_trigger_device *)dev;
     int status = 0;
-    ALOGI("unload_sound_model.");
     pthread_mutex_lock(&stdev->lock);
 
     struct recognition_context *model_context = NULL;
diff --git a/modules/vehicle/vehicle.c b/modules/vehicle/vehicle.c
index 564630c..d8aa2cb 100644
--- a/modules/vehicle/vehicle.c
+++ b/modules/vehicle/vehicle.c
@@ -245,6 +245,21 @@
     return 0;
 }
 
+static void vdev_release_memory_from_get(struct vehicle_hw_device* device UNUSED,
+        vehicle_prop_value_t *data) {
+    switch (data->value_type) {
+        case VEHICLE_VALUE_TYPE_STRING:
+        case VEHICLE_VALUE_TYPE_BYTES:
+            free(data->value.str_value.data);
+            data->value.str_value.data = NULL;
+            break;
+        default:
+            ALOGW("release_memory_from_get for property 0x%x which is not string or bytes type 0x%x"
+                    , data->prop, data->value_type);
+            break;
+    }
+}
+
 static int vdev_set(vehicle_hw_device_t* device UNUSED, const vehicle_prop_value_t* data) {
     ALOGD("vdev_set.");
     // Just print what data will be setting here.
@@ -377,7 +392,7 @@
                     return;
                 }
                 if (sub->impl->error_fn_ != NULL) {
-                    sub->impl->error_fn_(VEHICLE_ERROR_UNKNOWN, VEHICLE_PROPERTY_INVALID,
+                    sub->impl->error_fn_(-EINVAL, VEHICLE_PROPERTY_INVALID,
                             VEHICLE_OPERATION_GENERIC);
                 } else {
                     ALOGE("Error function is null");
@@ -538,6 +553,7 @@
     vdev->vehicle_device.init = vdev_init;
     vdev->vehicle_device.release = vdev_release;
     vdev->vehicle_device.get = vdev_get;
+    vdev->vehicle_device.release_memory_from_get = vdev_release_memory_from_get;
     vdev->vehicle_device.set = vdev_set;
     vdev->vehicle_device.subscribe = vdev_subscribe;
     vdev->vehicle_device.unsubscribe = vdev_unsubscribe;
diff --git a/tests/vehicle/vehicle-hal-tool.c b/tests/vehicle/vehicle-hal-tool.c
index 8cc8476..3c3922f 100755
--- a/tests/vehicle/vehicle-hal-tool.c
+++ b/tests/vehicle/vehicle-hal-tool.c
@@ -89,6 +89,121 @@
     }
 }
 
+static void print_property(const vehicle_prop_value_t *data) {
+    switch (data->value_type) {
+        case VEHICLE_VALUE_TYPE_STRING:
+            printf("Value type: STRING\n Size: %d\n", data->value.str_value.len);
+            // This implementation only supports ASCII.
+            char *ascii_out = (char *) malloc((data->value.str_value.len + 1) * sizeof(char));
+            memcpy(ascii_out, data->value.str_value.data, data->value.str_value.len);
+            ascii_out[data->value.str_value.len] = '\0';
+            printf("Value Type: STRING %s\n", ascii_out);
+            break;
+        case VEHICLE_VALUE_TYPE_BYTES:
+            printf("Value type: BYTES\n Size: %d", data->value.bytes_value.len);
+            for (int i = 0; i < data->value.bytes_value.len; i++) {
+                if ((i % 16) == 0) {
+                    printf("\n %04X: ", i);
+                }
+                printf("%02X ", data->value.bytes_value.data[i]);
+            }
+            printf("\n");
+            break;
+        case VEHICLE_VALUE_TYPE_BOOLEAN:
+            printf("Value type: BOOLEAN\nValue: %d\n", data->value.boolean_value);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
+            printf("Value type: ZONED_BOOLEAN\nZone: %d\n", data->zone);
+            printf("Value: %d\n", data->value.boolean_value);
+            break;
+        case VEHICLE_VALUE_TYPE_INT64:
+            printf("Value type: INT64\nValue: %" PRId64 "\n", data->value.int64_value);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT:
+            printf("Value type: FLOAT\nValue: %f\n", data->value.float_value);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
+            printf("Value type: FLOAT_VEC2\nValue[0]: %f ", data->value.float_array[0]);
+            printf("Value[1]: %f\n", data->value.float_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
+            printf("Value type: FLOAT_VEC3\nValue[0]: %f ", data->value.float_array[0]);
+            printf("Value[1]: %f ", data->value.float_array[1]);
+            printf("Value[2]: %f\n", data->value.float_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC4:
+            printf("Value type: FLOAT_VEC4\nValue[0]: %f ", data->value.float_array[0]);
+            printf("Value[1]: %f ", data->value.float_array[1]);
+            printf("Value[2]: %f ", data->value.float_array[2]);
+            printf("Value[3]: %f\n", data->value.float_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_INT32:
+            printf("Value type: INT32\nValue: %d\n", data->value.int32_value);
+            break;
+        case VEHICLE_VALUE_TYPE_INT32_VEC2:
+            printf("Value type: INT32_VEC2\nValue[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d\n", data->value.int32_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_INT32_VEC3:
+            printf("Value type: INT32_VEC3\nValue[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d ", data->value.int32_array[1]);
+            printf("Value[2]: %d\n", data->value.int32_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_INT32_VEC4:
+            printf("Value type: INT32_VEC4\nValue[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d ", data->value.int32_array[1]);
+            printf("Value[2]: %d ", data->value.int32_array[2]);
+            printf("Value[3]: %d\n", data->value.int32_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
+            printf("Value type: ZONED_FLOAT\nZone: %d ", data->zone);
+            printf("Value: %f\n", data->value.float_value);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
+            printf("Value type: ZONED_FLOAT_VEC2\nZone: %d ", data->zone);
+            printf("Value[0]: %f", data->value.float_array[0]);
+            printf("Value[1]: %f\n", data->value.float_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
+            printf("Value type: ZONED_FLOAT_VEC3\nZone: %d ", data->zone);
+            printf("Value[0]: %f ", data->value.float_array[0]);
+            printf("Value[1]: %f ", data->value.float_array[1]);
+            printf("Value[2]: %f\n", data->value.float_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
+            printf("Value type: ZONED_FLOAT_VEC4\nZone: %d ", data->zone);
+            printf("Value[0]: %f ", data->value.float_array[0]);
+            printf("Value[1]: %f ", data->value.float_array[1]);
+            printf("Value[2]: %f ", data->value.float_array[2]);
+            printf("Value[3]: %f\n", data->value.float_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32:
+            printf("Value type: ZONED_INT32\nZone: %d ", data->zone);
+            printf("Value: %d\n", data->value.int32_value);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
+            printf("Value type: ZONED_INT32_VEC2\nZone: %d ", data->zone);
+            printf("Value[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d\n", data->value.int32_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
+            printf("Value type: ZONED_INT32_VEC3\nZone: %d ", data->zone);
+            printf("Value[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d ", data->value.int32_array[1]);
+            printf("Value[2]: %d\n", data->value.int32_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
+            printf("Value type: ZONED_INT32_VEC4\nZone: %d ", data->zone);
+            printf("Value[0]: %d ", data->value.int32_array[0]);
+            printf("Value[1]: %d ", data->value.int32_array[1]);
+            printf("Value[2]: %d ", data->value.int32_array[2]);
+            printf("Value[3]: %d\n", data->value.int32_array[3]);
+            break;
+        default:
+            printf("Value type not yet handled: %d.\n", data->value_type);
+    }
+}
+
 void get_property(
     vehicle_hw_device_t *device, int32_t property, int32_t type, char *value_string) {
     vehicle_prop_value_t *data = (vehicle_prop_value_t *) malloc (sizeof(vehicle_prop_value_t));
@@ -122,45 +237,7 @@
     // We simply convert the data into the type mentioned by the result of the
     // get call.
     printf("Get output\n------------\n");
-    switch (data->value_type) {
-        case VEHICLE_VALUE_TYPE_FLOAT:
-            printf("Value type: FLOAT\nValue: %f\n", data->value.float_value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32:
-            printf("Value type: INT32\nValue: %d\n", data->value.int32_value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT64:
-            printf("Value type: INT64\nValue: %" PRId64 "\n", data->value.int64_value);
-            break;
-        case VEHICLE_VALUE_TYPE_BOOLEAN:
-            printf("Value type: BOOLEAN\nValue: %d\n", data->value.boolean_value);
-            break;
-        case VEHICLE_VALUE_TYPE_STRING:
-            printf("Value type: STRING\n Size: %d\n", data->value.str_value.len);
-            // This implementation only supports ASCII.
-            char *ascii_out = (char *) malloc((data->value.str_value.len + 1) * sizeof(char));
-            memcpy(ascii_out, data->value.str_value.data, data->value.str_value.len);
-            ascii_out[data->value.str_value.len] = '\0';
-            printf("Value: %s\n", ascii_out);
-            break;
-        case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
-            printf("Value type: ZONED_FLOAT\nZone: %d\n", data->value.zoned_float_value.zone);
-            printf("Value type: ZONED_FLOAT\nValue: %f\n", data->value.zoned_float_value.value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32_VEC3:
-            printf("Value type: INT32_VEC3\nValue[0]: %d\n", data->value.int32_array[0]);
-            printf("Value type: INT32_VEC3\nValue[1]: %d\n", data->value.int32_array[1]);
-            printf("Value type: INT32_VEC3\nValue[2]: %d\n", data->value.int32_array[2]);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32_VEC4:
-            printf("Value type: INT32_VEC4\nValue[0]: %d\n", data->value.int32_array[0]);
-            printf("Value type: INT32_VEC4\nValue[1]: %d\n", data->value.int32_array[1]);
-            printf("Value type: INT32_VEC4\nValue[2]: %d\n", data->value.int32_array[2]);
-            printf("Value type: INT32_VEC4\nValue[3]: %d\n", data->value.int32_array[3]);
-            break;
-        default:
-            printf("Value type not yet handled: %d.\n", data->value_type);
-    }
+    print_property(data);
     free(data);
 }
 
@@ -174,18 +251,6 @@
     int32_t zone = 0;
     float value = 0.0;
     switch (type) {
-        case VEHICLE_VALUE_TYPE_FLOAT:
-            vehicle_data.value.float_value = atof(data);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32:
-            vehicle_data.value.int32_value = atoi(data);
-            break;
-        case VEHICLE_VALUE_TYPE_INT64:
-            vehicle_data.value.int64_value = atoi(data);
-            break;
-        case VEHICLE_VALUE_TYPE_BOOLEAN:
-            vehicle_data.value.boolean_value = atoi(data);
-            break;
         case VEHICLE_VALUE_TYPE_STRING:
             // TODO: Make the code generic to UTF8 characters.
             vehicle_data.value.str_value.len = strlen(data);
@@ -193,45 +258,117 @@
                 (uint8_t *) malloc (strlen(data) * sizeof(uint8_t));
             memcpy(vehicle_data.value.str_value.data, data, strlen(data) + 1);
             break;
-        case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
-            sscanf(data, "%d %f", &zone, &value);
-            vehicle_data.value.zoned_float_value.zone = zone;
-            vehicle_data.value.zoned_float_value.value = value;
-            printf("Value type: ZONED_FLOAT\nZone: %d\n", vehicle_data.value.zoned_float_value.zone);
-            printf("Value type: ZONED_FLOAT\nValue: %f\n", vehicle_data.value.zoned_float_value.value);
+        case VEHICLE_VALUE_TYPE_BYTES: {
+                int len = strlen(data);
+                int numBytes = (len + 1) / 3;
+                uint8_t *buf = calloc(numBytes, sizeof(uint8_t));
+                char *byte = strtok(data, " ");
+                for (int i = 0; byte != NULL && i < numBytes; i++) {
+                    buf[i] = strtol(data, NULL, 16);
+                    byte = strtok(NULL, " ");
+                }
+                vehicle_data.value.bytes_value.len = numBytes;
+                vehicle_data.value.bytes_value.data = buf;
+            }
+            break;
+        case VEHICLE_VALUE_TYPE_BOOLEAN:
+            vehicle_data.value.boolean_value = atoi(data);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
+            sscanf(data, "%d %d", &vehicle_data.zone,
+                &vehicle_data.value.boolean_value);
+            break;
+        case VEHICLE_VALUE_TYPE_INT64:
+            vehicle_data.value.int64_value = atoi(data);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT:
+            vehicle_data.value.float_value = atof(data);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
+            sscanf(data, "%f %f", &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
+            sscanf(data, "%f %f %f", &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1],
+                &vehicle_data.value.float_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_FLOAT_VEC4:
+            sscanf(data, "%f %f %f %f", &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1],
+                &vehicle_data.value.float_array[2],
+                &vehicle_data.value.float_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_INT32:
+            vehicle_data.value.int32_value = atoi(data);
             break;
         case VEHICLE_VALUE_TYPE_INT32_VEC2:
             sscanf(data, "%d %d", &vehicle_data.value.int32_array[0],
                 &vehicle_data.value.int32_array[1]);
-            printf("Setting: Value type INT32_VEC2: %d %d\n",
-                vehicle_data.value.int32_array[0],
-                vehicle_data.value.int32_array[1]);
             break;
         case VEHICLE_VALUE_TYPE_INT32_VEC3:
             sscanf(data, "%d %d %d", &vehicle_data.value.int32_array[0],
                 &vehicle_data.value.int32_array[1],
                 &vehicle_data.value.int32_array[2]);
-            printf("Setting: Value type INT32_VEC3: %d %d %d\n",
-                vehicle_data.value.int32_array[0],
-                vehicle_data.value.int32_array[1],
-                vehicle_data.value.int32_array[2]);
             break;
         case VEHICLE_VALUE_TYPE_INT32_VEC4:
             sscanf(data, "%d %d %d %d", &vehicle_data.value.int32_array[0],
                 &vehicle_data.value.int32_array[1],
                 &vehicle_data.value.int32_array[2],
                 &vehicle_data.value.int32_array[3]);
-            printf("Setting: Value type INT32_VEC4: %d %d %d %d\n",
-                vehicle_data.value.int32_array[0],
-                vehicle_data.value.int32_array[1],
-                vehicle_data.value.int32_array[2],
-                vehicle_data.value.int32_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
+            sscanf(data, "%d %f", &zone, &value);
+            vehicle_data.zone = zone;
+            vehicle_data.value.float_value = value;
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
+            sscanf(data, "%d %f %f", &vehicle_data.zone,
+                &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
+            sscanf(data, "%d %f %f %f", &vehicle_data.zone,
+                &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1],
+                &vehicle_data.value.float_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
+            sscanf(data, "%d %f %f %f %f", &vehicle_data.zone,
+                &vehicle_data.value.float_array[0],
+                &vehicle_data.value.float_array[1],
+                &vehicle_data.value.float_array[2],
+                &vehicle_data.value.float_array[3]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32:
+            sscanf(data, "%d %d", &vehicle_data.zone,
+                &vehicle_data.value.int32_value);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
+            sscanf(data, "%d %d %d", &vehicle_data.zone,
+                &vehicle_data.value.int32_array[0],
+                &vehicle_data.value.int32_array[1]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
+            sscanf(data, "%d %d %d %d", &vehicle_data.zone,
+                &vehicle_data.value.int32_array[0],
+                &vehicle_data.value.int32_array[1],
+                &vehicle_data.value.int32_array[2]);
+            break;
+        case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
+            sscanf(data, "%d %d %d %d %d", &vehicle_data.zone,
+                &vehicle_data.value.int32_array[0],
+                &vehicle_data.value.int32_array[1],
+                &vehicle_data.value.int32_array[2],
+                &vehicle_data.value.int32_array[3]);
             break;
         default:
             printf("set_property: Value type not yet handled: %d\n", type);
             exit(1);
     }
-    printf("Property id: %d\n", vehicle_data.prop);
+    printf("Setting Property id: %d\n", vehicle_data.prop);
+    print_property(&vehicle_data);
+
     int ret_code = device->set(device, &vehicle_data);
     if (ret_code != 0) {
         printf("Cannot set property: %d\n", ret_code);
@@ -243,57 +380,16 @@
     // Print what we got.
     printf("Got some value from callback property: %d\n", event_data->prop);
     printf("Timestamp: %" PRId64 "\n", event_data->timestamp);
-    char *ascii_out;
-    switch (event_data->value_type) {
-        case VEHICLE_VALUE_TYPE_FLOAT:
-            printf("Float value: %f\n", event_data->value.float_value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32:
-            printf("int32 value: %d\n", event_data->value.int32_value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT64:
-            printf("int64 value: %" PRId64 "\n", event_data->value.int64_value);
-            break;
-        case VEHICLE_VALUE_TYPE_BOOLEAN:
-            printf("bool value: %d\n", event_data->value.boolean_value);
-            break;
-        case VEHICLE_VALUE_TYPE_STRING:
-            // TODO: Make the code generic to UTF8 characters.
-            ascii_out = (char *) malloc ((event_data->value.str_value.len + 1) * sizeof(char));
-            memcpy(ascii_out, event_data->value.str_value.data, event_data->value.str_value.len);
-            ascii_out[event_data->value.str_value.len] = '\0';
-            printf("Ascii value: %s\n", ascii_out);
-            break;
-        case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
-            printf("Value type: ZONED_FLOAT\nZone: %d\n", event_data->value.zoned_float_value.zone);
-            printf("Value type: ZONED_FLOAT\nValue: %f\n", event_data->value.zoned_float_value.value);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32_VEC2:
-            printf("Value type: INT32_VEC2\nValue[0]: %d Value[1] %d\n",
-                  event_data->value.int32_array[0], event_data->value.int32_array[1]);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32_VEC3:
-            printf("Value type: INT32_VEC3\nValue[0]: %d Value[1] %d Value[2] %d\n",
-                  event_data->value.int32_array[0], event_data->value.int32_array[1],
-                  event_data->value.int32_array[2]);
-            break;
-        case VEHICLE_VALUE_TYPE_INT32_VEC4:
-            printf("Value type: INT32_VEC4\nValue[0]: %d Value[1] %d Value[2] %d Value[3] %d\n",
-                  event_data->value.int32_array[0], event_data->value.int32_array[1],
-                  event_data->value.int32_array[2], event_data->value.int32_array[3]);
-            break;
-        default:
-            printf("vehicle_event_callback: Value type not yet handled: %d\n",
-                    event_data->value_type);
-            exit(1);
-    }
+    print_property(event_data);
     return 0;
 }
+
 int vehicle_error_callback(int32_t error_code, int32_t property, int32_t operation) {
     // Print what we got.
     printf("Error code obtained: %d\n", error_code);
     return 0;
 }
+
 void subscribe_to_property(
     vehicle_hw_device_t *device,
     int32_t prop,
@@ -364,7 +460,6 @@
     char int_array_string[1000]; int_array_string[0] = '\0';
 
     int opt;
-    //TODO allow passing zone
     while ((opt = getopt(argc, argv, "lm:p:t:v:w:s:")) != -1) {
         switch (opt) {
             case 'l':