mirror of
https://github.com/hathach/tinyusb.git
synced 2025-10-14 01:58:41 +08:00
implement get device properties value
This commit is contained in:
@@ -34,50 +34,12 @@
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// device info string (including terminating null)
|
||||
static const uint16_t dev_info_manufacturer[] = { 'T', 'i', 'n', 'y', 'U', 'S', 'B', 0 };
|
||||
static const uint16_t dev_info_model[] = { 'M', 'T', 'P', ' ', 'E', 'x', 'a', 'm', 'p', 'l', 'e', 0 };
|
||||
static const uint16_t dev_info_version[] = { '1', '.', '0', 0 };
|
||||
static const uint16_t dev_info_serial[] = { '1', '2', '3', '4', '5', '6', 0 };
|
||||
#define DEV_INFO_MANUFACTURER "TinyUSB"
|
||||
#define DEV_INFO_MODEL "MTP Example"
|
||||
#define DEV_INFO_VERSION "1.0"
|
||||
#define DEV_INFO_SERIAL "123456"
|
||||
|
||||
static const uint16_t supported_operations[] = {
|
||||
MTP_OP_GET_DEVICE_INFO,
|
||||
MTP_OP_OPEN_SESSION,
|
||||
MTP_OP_CLOSE_SESSION,
|
||||
MTP_OP_GET_STORAGE_IDS,
|
||||
MTP_OP_GET_STORAGE_INFO,
|
||||
MTP_OP_GET_NUM_OBJECTS,
|
||||
MTP_OP_GET_OBJECT_HANDLES,
|
||||
MTP_OP_GET_OBJECT_INFO,
|
||||
MTP_OP_GET_OBJECT,
|
||||
MTP_OP_DELETE_OBJECT,
|
||||
MTP_OP_SEND_OBJECT_INFO,
|
||||
MTP_OP_SEND_OBJECT,
|
||||
MTP_OP_FORMAT_STORE,
|
||||
MTP_OP_RESET_DEVICE,
|
||||
MTP_OP_GET_DEVICE_PROP_DESC,
|
||||
MTP_OP_GET_DEVICE_PROP_VALUE,
|
||||
MTP_OP_SET_DEVICE_PROP_VALUE
|
||||
};
|
||||
|
||||
static const uint16_t supported_events[] = {
|
||||
MTP_EVENT_OBJECT_ADDED,
|
||||
};
|
||||
|
||||
static const uint16_t supported_device_properties[] = {
|
||||
MTP_DEV_PROP_DEVICE_FRIENDLY_NAME,
|
||||
};
|
||||
|
||||
static const uint16_t capture_formats[] = {
|
||||
MTP_OBJ_FORMAT_UNDEFINED,
|
||||
MTP_OBJ_FORMAT_ASSOCIATION,
|
||||
MTP_OBJ_FORMAT_TEXT,
|
||||
};
|
||||
|
||||
static const uint16_t playback_formats[] = {
|
||||
MTP_OBJ_FORMAT_UNDEFINED,
|
||||
MTP_OBJ_FORMAT_ASSOCIATION,
|
||||
MTP_OBJ_FORMAT_TEXT,
|
||||
};
|
||||
#define DEV_PROP_FRIENDLY_NAME "TinyUSB MTP"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// RAM FILESYSTEM
|
||||
@@ -139,6 +101,10 @@ storage_info_t storage_info = {
|
||||
}
|
||||
};
|
||||
|
||||
enum {
|
||||
SUPPORTED_STORAGE_ID = 0x00010001u // physical = 1, logical = 1
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OPERATING STATUS
|
||||
@@ -205,15 +171,24 @@ int32_t tud_mtp_data_complete_cb(uint8_t idx, mtp_container_header_t* cmd_header
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tud_mtp_response_complete_cb(uint8_t idx, mtp_container_header_t* cmd_header, mtp_generic_container_t* resp_block, tusb_xfer_result_t xfer_result, uint32_t xferred_bytes) {
|
||||
(void) idx;
|
||||
(void) cmd_header;
|
||||
(void) resp_block;
|
||||
(void) xfer_result;
|
||||
(void) xferred_bytes;
|
||||
return 0; // nothing to do
|
||||
}
|
||||
|
||||
int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_block, mtp_generic_container_t* out_block) {
|
||||
(void)idx;
|
||||
switch (cmd_block->code) {
|
||||
case MTP_OP_GET_DEVICE_INFO: {
|
||||
// Device info is already prepared up to playback formats. Application only need to add string fields
|
||||
mtp_container_add_string(out_block, TU_ARRAY_SIZE(dev_info_manufacturer), dev_info_manufacturer);
|
||||
mtp_container_add_string(out_block, TU_ARRAY_SIZE(dev_info_model), dev_info_model);
|
||||
mtp_container_add_string(out_block, TU_ARRAY_SIZE(dev_info_version), dev_info_version);
|
||||
mtp_container_add_string(out_block, TU_ARRAY_SIZE(dev_info_serial), dev_info_serial);
|
||||
mtp_container_add_cstring(out_block, DEV_INFO_MANUFACTURER);
|
||||
mtp_container_add_cstring(out_block, DEV_INFO_MODEL);
|
||||
mtp_container_add_cstring(out_block, DEV_INFO_VERSION);
|
||||
mtp_container_add_cstring(out_block, DEV_INFO_SERIAL);
|
||||
|
||||
tud_mtp_data_send(out_block);
|
||||
break;
|
||||
@@ -225,13 +200,14 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
|
||||
break;
|
||||
|
||||
case MTP_OP_GET_STORAGE_IDS: {
|
||||
uint32_t storage_ids [] = { 0x00010001u }; // physical = 1, logical = 1
|
||||
uint32_t storage_ids [] = { SUPPORTED_STORAGE_ID }; // physical = 1, logical = 1
|
||||
mtp_container_add_auint32(out_block, 1, storage_ids);
|
||||
tud_mtp_data_send(out_block);
|
||||
break;
|
||||
}
|
||||
|
||||
case MTP_OP_GET_STORAGE_INFO: {
|
||||
TU_VERIFY(SUPPORTED_STORAGE_ID == cmd_block->data[0], -1);
|
||||
// update storage info with current free space
|
||||
storage_info.free_space_in_objects = FS_MAX_NODES - fs_get_object_count();
|
||||
storage_info.free_space_in_bytes = storage_info.free_space_in_objects * FS_MAX_NODE_BYTES;
|
||||
@@ -240,6 +216,20 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
|
||||
break;
|
||||
}
|
||||
|
||||
case MTP_OP_GET_DEVICE_PROP_VALUE: {
|
||||
const uint16_t dev_prop_code = (uint16_t) cmd_block->data[0];
|
||||
switch (dev_prop_code) {
|
||||
case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME:
|
||||
mtp_container_add_cstring(out_block, DEV_PROP_FRIENDLY_NAME);
|
||||
tud_mtp_data_send(out_block);
|
||||
break;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
|
||||
|
@@ -782,17 +782,30 @@ typedef struct TU_ATTR_PACKED {
|
||||
// - datetime_wstring date_modified;
|
||||
// - wstring keywords;
|
||||
|
||||
// DevicePropDesc Dataset
|
||||
// Device property desc up to get/set
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
uint16_t device_property_code;
|
||||
uint16_t datatype;
|
||||
uint8_t get_set;
|
||||
} mtp_device_prop_desc_t;
|
||||
} mtp_device_prop_desc_header_t;
|
||||
|
||||
// The following fields will be dynamically added to the struct at runtime:
|
||||
// - wstring factory_def_value;
|
||||
// - wstring current_value_len;
|
||||
// - uint8_t form_flag;
|
||||
|
||||
// no form
|
||||
#define MTP_DEVICE_PROPERTIES_TYPEDEF(_type) \
|
||||
struct TU_ATTR_PACKED { \
|
||||
uint16_t device_property_code; \
|
||||
uint16_t datatype; \
|
||||
uint8_t get_set; \
|
||||
_type factory_default; \
|
||||
_type current_value; \
|
||||
uint8_t form_flag; /* 0: none, 1: range, 2: enum */ \
|
||||
};
|
||||
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
uint16_t wLength;
|
||||
uint16_t code;
|
||||
@@ -832,15 +845,28 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_field(mtp_generic
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_string(mtp_generic_container_t* p_container, uint8_t count, uint16_t* utf16) {
|
||||
const uint32_t prev_len = p_container->len;
|
||||
uint8_t* container8 = (uint8_t*) p_container;
|
||||
*(container8 + p_container->len) = count;
|
||||
p_container->len += 1;
|
||||
container8[p_container->len] = count;
|
||||
p_container->len++;
|
||||
|
||||
memcpy(container8 + p_container->len, utf16, 2 * count);
|
||||
p_container->len += 2 * count;
|
||||
|
||||
return p_container->len - prev_len;
|
||||
return 1 + 2 * count;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_cstring(mtp_generic_container_t* p_container, const char* str) {
|
||||
uint8_t* container8 = (uint8_t*) p_container;
|
||||
const uint8_t len = (uint8_t) (strlen(str) + 1); // include null
|
||||
container8[p_container->len] = len;
|
||||
p_container->len++;
|
||||
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
container8[p_container->len] = str[i];
|
||||
container8[p_container->len + 1] = 0;
|
||||
p_container->len += 2;
|
||||
}
|
||||
return 1 + 2 * len;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint8(mtp_generic_container_t* p_container, uint8_t data) {
|
||||
|
@@ -466,11 +466,12 @@ mtp_phase_type_t mtpd_handle_cmd(mtpd_interface_t* p_mtp) {
|
||||
|
||||
case MTP_OP_GET_DEVICE_PROP_DESC:
|
||||
TU_LOG_DRV(" MTP command: MTP_OP_GET_DEVICE_PROP_DESC\n");
|
||||
return mtpd_handle_cmd_get_device_prop_desc();
|
||||
break;
|
||||
|
||||
case MTP_OP_GET_DEVICE_PROP_VALUE:
|
||||
TU_LOG_DRV(" MTP command: MTP_OP_GET_DEVICE_PROP_VALUE\n");
|
||||
return mtpd_handle_cmd_get_device_prop_value();
|
||||
break;
|
||||
|
||||
case MTP_OP_SEND_OBJECT_INFO:
|
||||
TU_LOG_DRV(" MTP command: MTP_OP_SEND_OBJECT_INFO\n");
|
||||
return mtpd_handle_cmd_send_object_info();
|
||||
@@ -673,11 +674,11 @@ mtp_phase_type_t mtpd_handle_cmd_get_device_prop_desc(void)
|
||||
{
|
||||
case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME:
|
||||
{
|
||||
TU_VERIFY_STATIC(sizeof(mtp_device_prop_desc_t) < MTP_MAX_PACKET_SIZE, "mtp_device_info_t shall fit in MTP_MAX_PACKET_SIZE");
|
||||
TU_VERIFY_STATIC(sizeof(mtp_device_prop_desc_header_t) < MTP_MAX_PACKET_SIZE, "mtp_device_info_t shall fit in MTP_MAX_PACKET_SIZE");
|
||||
p_container->type = MTP_CONTAINER_TYPE_DATA_BLOCK;
|
||||
p_container->code = MTP_OP_GET_DEVICE_PROP_DESC;
|
||||
p_container->len = MTP_CONTAINER_HEADER_LENGTH + sizeof(mtp_device_prop_desc_t);
|
||||
mtp_device_prop_desc_t *d = (mtp_device_prop_desc_t *)p_container->data;
|
||||
p_container->len = MTP_CONTAINER_HEADER_LENGTH + sizeof(mtp_device_prop_desc_header_t);
|
||||
mtp_device_prop_desc_header_t *d = (mtp_device_prop_desc_header_t *)p_container->data;
|
||||
d->device_property_code = (uint16_t)(device_prop_code);
|
||||
d->datatype = MTP_DATA_TYPE_STR;
|
||||
d->get_set = MTP_MODE_GET;
|
||||
|
Reference in New Issue
Block a user