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':