2023-12-01 09:17:09 +00:00
# pragma once
// Objects IO
//
// created on 2023-03-10
# include <base/utils.h>
# include <base/packet.h>
# include <base/data.h>
# include <functional>
# include <memory>
# include <vector>
# include <thread>
// callback proto
//
// parameters: usb_functionfs_event* - the function event ptr
//
// dyn_mem_ptr - the packet buffer, read-only
//
// uint32_t* - to return how many data in bytes the handler consumed
//
// normally, the value should be sizeof(PACK_BASE) + PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet
//
// when invalid packet, suggest use the entire data
//
// packet_data_base_ptr* - return data_holder or data_source or nullptr
//
// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file'
//
// data_source: the reply content may be a large data (a large file content)
//
// return value of all routines is the reply packet, nullptr if the packet need not reply
//
# define FUNCTION_PROTO_UNHANDLED_EP0 dyn_mem_ptr(struct usb_functionfs_event*)
2023-12-13 06:57:08 +00:00
# define MEM_POOL
2023-12-01 09:17:09 +00:00
class usb_device ;
class async_usb_gadget : public refer
{
volatile bool run_ = true ;
2023-12-14 06:24:15 +00:00
volatile bool cancel_io_ = false ;
2023-12-01 09:17:09 +00:00
usb_device * dev_ = nullptr ;
safe_thread threads_ ;
size_t unit_in_ = 0x200 ;
size_t unit_out_ = 0x200 ;
uint16_t buf_coef_ = 1 ;
MUTEX buf_coef_lock_ ;
2023-12-02 02:15:44 +00:00
volatile bool online_ = false ;
volatile uint32_t session_id_ = 0 ;
platform_event wait_in_ ;
platform_event wait_out_ ;
2023-12-01 09:17:09 +00:00
uint32_t enc_head_ ;
uint32_t enc_payload_ ;
uint8_t enc_data_ ;
2023-12-01 10:03:10 +00:00
int last_err_ = 0 ;
2023-12-01 09:17:09 +00:00
2023-12-09 10:21:05 +00:00
uint8_t statu_in_ = WORKER_STATUS_NOT_START ;
uint32_t want_bytes_in_ = 0 ;
uint8_t statu_out_ = WORKER_STATUS_NOT_START ;
uint8_t statu_task_ = WORKER_STATUS_NOT_START ;
uint32_t want_bytes_task_ = 0 ;
uint32_t task_cmd_ = 0 ;
uint32_t task_packet_id_ = 0 ;
2023-12-25 09:39:34 +00:00
uint64_t host_pid_ = 0 ;
2023-12-13 06:57:08 +00:00
# ifdef MEM_POOL
dyn_mem_pool * io_buf_ = nullptr ;
# else
2023-12-12 01:36:06 +00:00
safe_fifo < dyn_mem_ptr > io_buf_ ;
2023-12-13 06:57:08 +00:00
# endif
2023-12-01 09:17:09 +00:00
safe_fifo < dyn_mem_ptr > cmd_que_ ;
safe_fifo < data_source_ptr > sent_que_ ;
enum
{
EP0_STATUS_IDLE = 0 ,
EP0_STATUS_READ_DATA , // ep0_statu::data is rest data len
EP0_STATUS_READ_INVAL_DATA , // ep0_statu::data is rest data len
EP0_STATUS_HANDLE_CMD ,
} ;
std : : function < FUNCTION_PROTO_COMMAND_HANDLE > handle_cmd_ ;
std : : function < void ( bool ) > dev_connect_ ;
2023-12-12 01:36:06 +00:00
dyn_mem_ptr get_io_buffer ( void ) ;
void free_io_buffer ( dyn_mem_ptr buf ) ;
2023-12-01 09:17:09 +00:00
const char * ep0_status_desc ( int ep0_status , char * unk_buf /*>= 40 bytes*/ ) ;
int wait_fd_event ( int fd , int to_ms = - 1 ) ;
uint16_t get_buf_coefficient ( void ) ;
void set_buf_coefficient ( int coef ) ;
dyn_mem_ptr handle_ctrl_message ( dyn_mem_ptr data ) ;
dyn_mem_ptr handle_ctrl_setup ( dyn_mem_ptr data ) ; // user command ...
2023-12-16 07:27:40 +00:00
int inner_write_bulk_memory ( int fd , uint8_t * buf , uint32_t * len /*in - to sent; out - real sent*/ , uint32_t bulk_size , data_source_ptr prog = nullptr ) ; // return error code
2023-12-13 06:57:08 +00:00
int inner_write_bulk ( int fd , data_source_ptr data , dyn_mem_ptr mem /*to load data in if data was not memory*/ , uint32_t bulk_size ) ; // return error
2023-12-01 09:17:09 +00:00
dyn_mem_ptr handle_bulk_command ( dyn_mem_ptr data , uint32_t * used , packet_data_base_ptr * pkd ) ;
void thread_read_ep0 ( void ) ;
void thread_read_bulk ( int fd ) ;
void thread_write_bulk ( int fd ) ;
void thread_pump_task ( void ) ;
public :
async_usb_gadget ( std : : function < FUNCTION_PROTO_COMMAND_HANDLE > cmd_handler = std : : function < FUNCTION_PROTO_COMMAND_HANDLE > ( )
, std : : function < void ( bool ) > dev_conn = std : : function < void ( bool ) > ( ) ) ;
protected :
~ async_usb_gadget ( ) ;
public :
int stop ( void ) ;
int write_bulk ( data_source_ptr data ) ; // return sent-que length
2023-12-01 10:03:10 +00:00
int last_error ( void ) ;
2024-03-15 06:48:55 +00:00
void get_ep_status ( LPEP0REPLYSTATUS status ) ;
2023-12-01 09:17:09 +00:00
} ;