summaryrefslogtreecommitdiff
path: root/examples/device/mtp/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-09-22 12:26:03 +0700
committerhathach <[email protected]>2025-09-22 13:10:22 +0700
commit6fa5268a9c013c9d38fc71649400d9ecc8c2dddf (patch)
tree756ed521d3804fce5e7edc3b6c0d1f7c0c1a28b9 /examples/device/mtp/src
parent4c818998d499a5a22c27ddfafc618e04ddcb823f (diff)
implement get object, close session
Diffstat (limited to 'examples/device/mtp/src')
-rw-r--r--examples/device/mtp/src/mtp_fs_example.c165
1 files changed, 47 insertions, 118 deletions
diff --git a/examples/device/mtp/src/mtp_fs_example.c b/examples/device/mtp/src/mtp_fs_example.c
index 20d09508f..a1c45c6e4 100644
--- a/examples/device/mtp/src/mtp_fs_example.c
+++ b/examples/device/mtp/src/mtp_fs_example.c
@@ -30,10 +30,10 @@
#define MTPD_VOLUME_IDENTIFIER "volume"
//--------------------------------------------------------------------+
-// Device Info
+// Dataset
//--------------------------------------------------------------------+
-// device info string (including terminating null)
+//------------- device info -------------//
#define DEV_INFO_MANUFACTURER "TinyUSB"
#define DEV_INFO_MODEL "MTP Example"
#define DEV_INFO_VERSION "1.0"
@@ -41,6 +41,14 @@
#define DEV_PROP_FRIENDLY_NAME "TinyUSB MTP"
+//------------- storage info -------------//
+#define STORAGE_DESCRIPTRION { 'd', 'i', 's', 'k', 0 }
+#define VOLUME_IDENTIFIER { 'v', 'o', 'l', 0 }
+
+typedef MTP_STORAGE_INFO_STRUCT(TU_ARRAY_SIZE((uint16_t[]) STORAGE_DESCRIPTRION),
+ TU_ARRAY_SIZE(((uint16_t[])VOLUME_IDENTIFIER))
+) storage_info_t;
+
//--------------------------------------------------------------------+
// RAM FILESYSTEM
//--------------------------------------------------------------------+
@@ -77,12 +85,7 @@ static fs_object_info_t fs_objects[FS_MAX_NODES] = {
};
//------------- Storage Info -------------//
-#define STORAGE_DESCRIPTRION { 'd', 'i', 's', 'k', 0 }
-#define VOLUME_IDENTIFIER { 'v', 'o', 'l', 0 }
-typedef MTP_STORAGE_INFO_STRUCT(TU_ARRAY_SIZE((uint16_t[]) STORAGE_DESCRIPTRION),
- TU_ARRAY_SIZE(((uint16_t[])VOLUME_IDENTIFIER))
-) storage_info_t;
storage_info_t storage_info = {
.storage_type = MTP_STORAGE_TYPE_FIXED_RAM,
@@ -105,6 +108,7 @@ enum {
SUPPORTED_STORAGE_ID = 0x00010001u // physical = 1, logical = 1
};
+static bool is_session_opened = false;
//--------------------------------------------------------------------+
// OPERATING STATUS
@@ -160,14 +164,9 @@ unsigned int fs_get_object_count(void) {
int32_t tud_mtp_data_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;
- // switch (cmd_header->code) {
- // default: break;
- // }
resp_block->len = MTP_CONTAINER_HEADER_LENGTH;
resp_block->code = (xfer_result == XFER_RESULT_SUCCESS) ? MTP_RESP_OK : MTP_RESP_GENERAL_ERROR;
-
tud_mtp_response_send(resp_block);
-
return 0;
}
@@ -195,7 +194,24 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
}
case MTP_OP_OPEN_SESSION:
- out_block->code = MTP_RESP_OK;
+ if (is_session_opened) {
+ //return MTP_RESP_SESSION_ALREADY_OPEN;
+ out_block->code = MTP_RESP_SESSION_ALREADY_OPEN;
+ }else {
+ out_block->code = MTP_RESP_OK;
+ }
+ is_session_opened = true;
+ tud_mtp_response_send(out_block);
+ break;
+
+ case MTP_OP_CLOSE_SESSION:
+ if (!is_session_opened) {
+ // return MTP_RESP_SESSION_NOT_OPEN;
+ out_block->code = MTP_RESP_SESSION_NOT_OPEN;
+ } else {
+ out_block->code = MTP_RESP_OK;
+ }
+ is_session_opened = false;
tud_mtp_response_send(out_block);
break;
@@ -272,13 +288,12 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
}
case MTP_OP_GET_OBJECT_INFO: {
- const uint32_t object_handle = cmd_block->data[0];
- fs_object_info_t* obj = fs_object_get_from_handle(object_handle);
+ const uint32_t obj_handle = cmd_block->data[0];
+ fs_object_info_t* obj = fs_object_get_from_handle(obj_handle);
if (obj == NULL) {
- TU_LOG1("ERR: Object with handle %ld does not exist\r\n", object_handle);
return MTP_RESP_INVALID_OBJECT_HANDLE;
}
- mtp_object_info_header_t object_info_header = {
+ mtp_object_info_header_t obj_info_header = {
.storage_id = SUPPORTED_STORAGE_ID,
.object_format = MTP_OBJ_FORMAT_TEXT,
.protection_status = MTP_PROTECTION_STATUS_NO_PROTECTION,
@@ -295,7 +310,7 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
.association_desc = 0,
.sequence_number = 0
};
- mtp_container_add_raw(out_block, &object_info_header, sizeof(object_info_header));
+ mtp_container_add_raw(out_block, &obj_info_header, sizeof(obj_info_header));
mtp_container_add_cstring(out_block, obj->name);
mtp_container_add_cstring(out_block, obj->created);
mtp_container_add_cstring(out_block, obj->modified);
@@ -305,6 +320,18 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
break;
}
+ case MTP_OP_GET_OBJECT: {
+ const uint32_t obj_handle = cmd_block->data[0];
+ fs_object_info_t* obj = fs_object_get_from_handle(obj_handle);
+ if (obj == NULL) {
+ return MTP_RESP_INVALID_OBJECT_HANDLE;
+ }
+
+ mtp_container_add_raw(out_block, obj->data, obj->size);
+ tud_mtp_data_send(out_block);
+ break;
+ }
+
default: return MTP_RESP_OPERATION_NOT_SUPPORTED;
}
@@ -314,22 +341,12 @@ int32_t tud_mtp_command_received_cb(uint8_t idx, mtp_generic_container_t* cmd_bl
//--------------------------------------------------------------------+
// API
//--------------------------------------------------------------------+
-mtp_response_t tud_mtp_storage_close_session(uint32_t session_id) {
- if (session_id != _fs_operation.session_id) {
- TU_LOG1("ERR: Session %ld not open\r\n", session_id);
- return MTP_RESP_SESSION_NOT_OPEN;
- }
- _fs_operation.session_id = 0;
- TU_LOG1("Session closed\r\n");
- return MTP_RESP_OK;
-}
-
mtp_response_t tud_mtp_storage_format(uint32_t storage_id) {
if (_fs_operation.session_id == 0) {
TU_LOG1("ERR: Session not open\r\n");
return MTP_RESP_SESSION_NOT_OPEN;
}
- if (storage_id != STORAGE_ID(0x0001, 0x0001)) {
+ if (storage_id != SUPPORTED_STORAGE_ID) {
TU_LOG1("ERR: Unexpected storage id %ld\r\n", storage_id);
return MTP_RESP_INVALID_STORAGE_ID;
}
@@ -341,45 +358,6 @@ mtp_response_t tud_mtp_storage_format(uint32_t storage_id) {
return MTP_RESP_OK;
}
-mtp_response_t tud_mtp_storage_association_get_object_handle(uint32_t storage_id, uint32_t parent_object_handle,
- uint32_t* next_child_handle) {
- fs_object_info_t* obj;
-
- if (_fs_operation.session_id == 0) {
- TU_LOG1("ERR: Session not open\r\n");
- return MTP_RESP_SESSION_NOT_OPEN;
- }
- // We just have one storage, same reply if querying all storages
- if (storage_id != 0xFFFFFFFF && storage_id != STORAGE_ID(0x0001, 0x0001)) {
- TU_LOG1("ERR: Unexpected storage id %ld\r\n", storage_id);
- return MTP_RESP_INVALID_STORAGE_ID;
- }
-
- // Request for objects with no parent (0xFFFFFFFF) are considered root objects
- // Note: implementation may pass 0 as parent_object_handle
- if (parent_object_handle == 0xFFFFFFFF)
- parent_object_handle = 0;
-
- if (parent_object_handle != _fs_operation.traversal_parent) {
- _fs_operation.traversal_parent = parent_object_handle;
- _fs_operation.traversal_index = 0;
- }
-
- for (unsigned int i = _fs_operation.traversal_index; i < FS_MAX_NODES; i++) {
- obj = &fs_objects[i];
- if (obj->allocated && obj->parent == parent_object_handle) {
- _fs_operation.traversal_index = i + 1;
- *next_child_handle = obj->handle;
- TU_LOG1("Association %ld -> child %ld\r\n", parent_object_handle, obj->handle);
- return MTP_RESP_OK;
- }
- }
- TU_LOG1("Association traversal completed\r\n");
- _fs_operation.traversal_index = 0;
- *next_child_handle = 0;
- return MTP_RESP_OK;
-}
-
mtp_response_t tud_mtp_storage_object_write_info(uint32_t storage_id, uint32_t parent_object,
uint32_t* new_object_handle, const mtp_object_info_header_t* info) {
fs_object_info_t* obj = NULL;
@@ -389,7 +367,7 @@ mtp_response_t tud_mtp_storage_object_write_info(uint32_t storage_id, uint32_t p
return MTP_RESP_SESSION_NOT_OPEN;
}
// Accept command on default storage
- if (storage_id != 0xFFFFFFFF && storage_id != STORAGE_ID(0x0001, 0x0001)) {
+ if (storage_id != 0xFFFFFFFF && storage_id != SUPPORTED_STORAGE_ID) {
TU_LOG1("ERR: Unexpected storage id %ld\r\n", storage_id);
return MTP_RESP_INVALID_STORAGE_ID;
}
@@ -480,55 +458,6 @@ mtp_response_t tud_mtp_storage_object_write(uint32_t object_handle, const uint8_
return MTP_RESP_OK;
}
-mtp_response_t tud_mtp_storage_object_size(uint32_t object_handle, uint32_t* size) {
- const fs_object_info_t* obj;
- obj = fs_object_get_from_handle(object_handle);
- if (obj == NULL) {
- TU_LOG1("ERR: Object with handle %ld does not exist\r\n", object_handle);
- return MTP_RESP_INVALID_OBJECT_HANDLE;
- }
- *size = obj->size;
- return MTP_RESP_OK;
-}
-
-mtp_response_t tud_mtp_storage_object_read(uint32_t object_handle, void* buffer, uint32_t buffer_size,
- uint32_t* read_count) {
- const fs_object_info_t* obj;
-
- obj = fs_object_get_from_handle(object_handle);
-
- if (obj == NULL) {
- TU_LOG1("ERR: Object with handle %ld does not exist\r\n", object_handle);
- return MTP_RESP_INVALID_OBJECT_HANDLE;
- }
- // It's not a requirement that this command is preceded by a read info
- if (object_handle != _fs_operation.read_handle) {
- TU_LOG1("ERR: Object %ld not open for read\r\n", object_handle);
- _fs_operation.read_handle = object_handle;
- _fs_operation.read_pos = 0;
- }
-
- if (obj->size - _fs_operation.read_pos > buffer_size) {
- TU_LOG1("Read object %ld: %ld bytes at offset %ld\r\n", object_handle, buffer_size, _fs_operation.read_pos);
- *read_count = buffer_size;
- if (_fs_operation.read_pos + buffer_size < FS_MAX_NODE_BYTES) {
- memcpy(buffer, &obj->data[_fs_operation.read_pos], *read_count);
- }
- _fs_operation.read_pos += *read_count;
- } else {
- TU_LOG1("Read object %ld: %ld bytes at offset %ld\r\n", object_handle, obj->size - _fs_operation.read_pos,
- _fs_operation.read_pos);
- *read_count = obj->size - _fs_operation.read_pos;
- if (_fs_operation.read_pos + *read_count < FS_MAX_NODE_BYTES) {
- memcpy(buffer, &obj->data[_fs_operation.read_pos], *read_count);
- }
- // Read operation completed
- _fs_operation.read_handle = 0;
- _fs_operation.read_pos = 0;
- }
- return MTP_RESP_OK;
-}
-
mtp_response_t tud_mtp_storage_object_move(uint32_t object_handle, uint32_t new_parent_object_handle) {
fs_object_info_t* obj;