/**
 * @brief           User API Wrapper Header
 * @author          AXELL CORPORATION
 * @description     API_WRAPP の API関数部を除く（内部関数他）の定義ヘッダ
 * @note            none
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017 AXELL CORPORATION, all rights reserved.
 */




#ifndef __APIWRAPPER_H__
#define __APIWRAPPER_H__
/* DOM-IGNORE-END */

// *************************************************************************************************
//	include
// *************************************************************************************************
#include	"uhs_config.h"
#include	"usbh_api.h"


// *************************************************************************************************
//	define
// *************************************************************************************************
#define GLOBAL

//	Lower[]の最大数（検索LOOPで使用）
#define USB_ENUMDEV_MAXDEV (USB_MAX_LOWER_DEV+1)


/***********************************************************************
 * ラッパ内部データ構造 (ここから)
 ***********************************************************************/

// リクエスト・コールバック処理タスクがリクエスト発行後のタイムアウト時間
#define USB_TRANS_TIMEOUT               (1500)
#define USB_TRANS_TIMEOUT2              (USB_TRANS_TIMEOUT*2)
#define USB_TRANS_CANCELTIMEOUT         (1500)
#define USB_TRANS_CANCELTIMEOUT2        (USB_TRANS_CANCELTIMEOUT*2)

#define USB_CMPWAIT_ON_DETACH_TIMEOUT   ((USB_TRANS_TIMEOUT/10)+200)


#define USB_REQUEST_NOTABORTED          (0x00<<0)
#define USB_REQUEST_ABORTED             (0x01<<0)

#define	USBWRAP_MAJOR_VERSION			(0x01)									/* USB ラッパ：メジャーバージョン */
#define	USBWRAP_MINOR_VERSION			(0x00)									/* USB ラッパ：マイナーバージョン */


// *************************************************************************************************
//	structure
// *************************************************************************************************

//------------------------------------------------------------------------------
//	API_WRAPPスレッドに対するMessage種別
//------------------------------------------------------------------------------
typedef enum _usb_wrap_msgtype {
    USBWRAP_MSG_NONE,
    USBWRAP_MSG_REQUEST_ISSUE,
    USBWRAP_MSG_REQUEST_ADDED,
    USBWRAP_MSG_REQUEST_COMP,
    USBWRAP_MSG_REQUEST_CANCEL,
    USBWRAP_MSG_RESTARTTASK,
    USBWRAP_MSG_ENDTASK,
    USBWRAP_MSG_ENDTASK_RECEIVE
} usb_wrap_msgtype;

//------------------------------------------------------------------------------
//	API_WRAPPスレッドに対するMessage SUB 種別
//------------------------------------------------------------------------------
typedef enum _usb_wrap_msgsubtype {
    USBWRAP_SUBMSG_NONE,
    USBWRAP_SUBMSG_CTLREQ,
    USBWRAP_SUBMSG_CTLREQ_CANCEL,
    USBWRAP_SUBMSG_BLKREQ,
    USBWRAP_SUBMSG_BLKREQ_CANCEL,
    USBWRAP_SUBMSG_INTREQ,
    USBWRAP_SUBMSG_INTREQ_CANCEL,
    USBWRAP_SUBMSG_ISOREQ,
    USBWRAP_SUBMSG_ISOREQ_CANCEL
} usb_wrap_msgsubtype;

//------------------------------------------------------------------------------
//	USB_HOST全体のステータス？？
//		⇒	現状は、使用されていない！！！！
//------------------------------------------------------------------------------
typedef enum  _usb_host_status{
	USBHSTAT_STARTUP,
	USBHSTAT_INITIAL,
	USBHSTAT_RUN,
	USBHSTAT_TERMINATE,
	USBHSTAT_IDLE
}usb_host_status;




//------------------------------------------------------------------------------
//	付加データ領域の定義
//------------------------------------------------------------------------------
typedef union _usb_wrap_msgdata {
        struct usb_control_block 	* ucb;
        void 						*context;
} usb_wrap_msgdata;


//------------------------------------------------------------------------------
//	API_WRAPPスレッドに送信するMessageフォーマットの定義。
//------------------------------------------------------------------------------
typedef struct _usb_wrap_msg {
    usb_wrap_msgtype 				msgtype;									//	Message種別
    usb_wrap_msgsubtype 			msgsubtype;									//	Message SUB 種別
    usb_wrap_msgdata 				data;										//	付加データのポインタ（ucbか、contextのポインタ）
} usb_wrap_msg;


//------------------------------------------------------------------------------
//	クラスドライバの登録情報	（API_WRAPPで管理するクラスドライバ情報）
//------------------------------------------------------------------------------
typedef struct _usb_wrap_drvinfo {

    /* クラスドライバ情報 */
    void							* drvreginfo;								// クラスドライバ側のドライバ登録情報		（上位からのデータそのまま）
    struct class_driver_reginfo		* core_drvreginfo;							// コア側のドライバ登録情報					（COREに登録したデータ、アタッチCBがAPI_WRAPPに差替え）
    udi_ubit8_t 					device_num;									// 現在、このドライバで動作中のデバイス数

} usb_wrap_drvinfo;


//------------------------------------------------------------------------------
//	API_WRAPPスレッドに対するリクエスト種別
//------------------------------------------------------------------------------
typedef enum _usb_wrap_reqtype {

    USBWRAP_REQ_NONE,

    USBWRAP_REQ_CTL_OTHER,
    USBWRAP_REQ_CTL_GET_STATUS,
    USBWRAP_REQ_CTL_CLEAR_FEATURE,
    USBWRAP_REQ_CTL_SET_FEATURE,
    USBWRAP_REQ_CTL_SET_ADDRESS,
    USBWRAP_REQ_CTL_GET_DESC,
    USBWRAP_REQ_CTL_SET_DESC,
    USBWRAP_REQ_CTL_GET_CONFIG,
    USBWRAP_REQ_CTL_SET_CONFIG,
    USBWRAP_REQ_CTL_GET_INTERFACE,
    USBWRAP_REQ_CTL_SET_INTERFACE,
    USBWRAP_REQ_CTL_SYNCH_FRAME,

    USBWRAP_REQ_BULK,
    USBWRAP_REQ_INTERRUPT,
    USBWRAP_REQ_ISOCHRONOUS

} usb_wrap_reqtype;


//------------------------------------------------------------------------------
//	キャンセル種別
//		⇒	今は未使用。
//------------------------------------------------------------------------------
typedef enum _usb_wrap_canceltype {
    USBWRAP_CANCELTYPE_NONE,
    USBWRAP_CANCELTYPE_NOTCANCELED,
    USBWRAP_CANCELTYPE_CANCELED,
    USBWRAP_CANCELTYPE_ABORTED
} usb_wrap_canceltype;


//------------------------------------------------------------------------------
//	上位からのリクエストをAPI_WRAPPで処理する為の構造体。
//	mallocで確保して、devinfoのLISTに追加していく。
//------------------------------------------------------------------------------
typedef struct _req_ucb_info {
    void 						* class_driver_request;							// クラスドライバのリクエスト		※クラスドライバからの要求をそのまま保存。（転送完了Messageにて、このポインタのCB関数を呼び出す、）
    struct usb_control_block 	ucb;											// USB コントロールブロック			※API_WRAPPのCB関数に差替え用（COREに渡すのは、こっち）
																				//	※あくまで実体

    usb_wrap_reqtype 			reqtype;										// リクエストタイプ
    udi_ubit32_t  				timeout;										// 残り時間
    udi_ubit32_t  				reqrecpttime;									// 受信時刻
    uhs_boolean_t 				is_timeout;										// タイムアウトしたか？
} requcb_info;


//------------------------------------------------------------------------------
//	API_WRAPPでの、デバイス管理情報		（接続デバイス毎に割り当てる。）
//		アタッチ時　⇒　malloc
//		デタッチ時　⇒　free
//------------------------------------------------------------------------------
typedef struct _usb_wrap_devinfo {

    kernel_context_t semid;														// 本構造体の同期用セマフォ

    kernel_context_t req_semid;													// リクエスト管理用セマフォ			// add req_ sem

    /* クラスドライバ側情報 */
    usb_wrap_drvinfo *drvinfo;													// 対応するドライバ登録情報

    /* USB HOST スタック側情報 */
    struct usbd_usb_deviceinfo* usbdev;											// USBデバイス情報

    uhs_list_node_t requcb_list;												// リクエストリスト。処理中のリクエストを保持
																				//	ここに、requcb_info をつなげる。

	//	OS リソース情報
	//^^^^^^^^^^^^^^^^^^^^^
    kernel_context_t reqtaskid;													// リクエスト処理タスクID
    kernel_context_t cmptaskid;													// 完了処理タスクID
    kernel_context_t reqmsgid;													// リクエスト処理 スク用MessageQue ID
    kernel_context_t cmpmsgid;													// 完了処理タスク用MessageQue ID

    udi_ubit32_t  proc_reqnum;													// 処理中のリクエスト数(現実装では最大1)

    uhs_boolean_t  is_connected;												// デバイスのコネクト状況(TRUE: 接続、FALSE: 切断)

} usb_wrap_devinfo;


//------------------------------------------------------------------------------
//	USB_HOSTの初期化済み状態。
//		⇒	現状は、Usbh_Init(~)内で、クラスドライバの登録も、その他初期あkも
//			合わせて行われるので、この情報自体には大した意味は無い。
//			初期化済みかどうかだけ。。。
//------------------------------------------------------------------------------
typedef enum _usb_wrap_status {
    USBWRAP_STAT_INIT_NOT_START,												//	未初期化状態
    USBWRAP_STAT_CNFSFT_INITCOMP,												//	API_WRAPP=初期化済み／CORE=未初期化		※この時点は仮LISTに登録
    USBWRAP_STAT_USBD_INITCOMP													//	API_WRAPP=初期化済み／CORE=初期化済み	※この時点は本LISTに登録
   } usb_wrap_status;


//------------------------------------------------------------------------------
//	USB BUS 状態
//------------------------------------------------------------------------------
typedef enum _usb_bus_status {
    USBWRAP_STAT_USBBUS_NON_ACTIVE,
    USBWRAP_STAT_USBBUS_ACTIVE,
    USBWRAP_STAT_USBBUS_SUSPEND
} usb_bus_status;


//------------------------------------------------------------------------------
//	API_WRAPP で管理する全体情報
//------------------------------------------------------------------------------
typedef struct _usb_wrap_info {
																				//	アクセス同期用セマフォ
																				//	usb_wrap_drvinfo, usb_wrap_devinfo, tmp_drvlist, apiwrap_stat をアクセスするときに使用
    kernel_context_t drvinfo_semid;

																				//	本登録用クラスドライバリスト(usb_wrap_drvinfo 構造体のリスト)
    uhs_list_node_t usb_wrap_drvinfo_list;

																				//	未登録デバイス用ドライバ
    usb_wrap_drvinfo unknowndev_driver;

																				//	API_WRAPPで、アタッチされたデバイスのLIST
    uhs_list_node_t usb_wrap_devinfo_list;

																				//	仮登録用クラスドライバリスト(USBS_CNFSFT_NOTIFICATION 構造体のリスト)
																				//	 USBH_USBD_Init 実行前はクラスドライバ登録はラッパ内部で保持しておく。
																				//	 登録後はリストにつないだデータを破棄すること。
    uhs_list_node_t tmp_drvlist;
    
																				//	apiラッパのステータス
																				//	 USBWRAP_STAT_CNFSFT_INITCOMP: 
																				//	   USBH_CNFSFT_Init() 実行済み、USBH_USBD_Init実行前
																				//	 USBWRAP_STAT_USBD_INITCOMP:
																				//	   USBH_CNFSFT_Init() 実行済み、USBH_USBD_Init実行済み
    usb_wrap_status apiwrap_stat;
    
																				//	USB バスのステート
    usb_bus_status bus_stat;

																				//	apiラッパ用メモリプール
    kernel_context_t mpl_osc;
    
																				//	過電流コールバック
    usb_common_callback_t 		overload_callback;
    usb_common_callback_t		split_err_notify_callback;

} usb_wrap_info;


/***********************************************************************
 * ラッパ内部データ構造 (ここまで)
 ***********************************************************************/

extern usb_wrap_info g_apiwrap_info;


// *************************************************************************************************
//	内部関数プロトタイプ宣言
// *************************************************************************************************
// クラスドライバ登録
uhs_status_t Usbh_RegistAppCallback( app_callback_info* app_cb );
uhs_status_t Usbh_InitClassDriver( usbh_regist_info init );
uhs_status_t Usbh_DriverRegister( void * class_driver_reg );
//static uhs_status_t Usbh_DriverRegisterForSpecificDevice( void * class_driver_reg );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_DriverRegisterForUnknownDevice( void * class_driver_reg );	/* [warning] never defined ⇒ .cへ移動 */
uhs_status_t Usbh_DriverUnRegister( void * class_driver_reg );
void Usbh_RegistOverCurrentCallback( usb_common_callback_t callback );
void		Usbh_RegistSplitErrNotifyCallback( usb_common_callback_t callback );
void Usbh_UnRegistAllAppCallback( void );

void         Usbh_EnableRegisteredDriver( void );

// デバイス接続・切断
//static int  Usbh_DevAttached( int mod_id, int callback_id, void* context );			/* [warning] never defined ⇒ .cへ移動 */
int         Usbh_DevDetached( int mod_id, int callback_id, void* context );
//static uhs_status_t  Usbh_PrepareDeviceTask( usb_wrap_devinfo* wrap_devinfo );		/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t  Usbh_FinishDeviceTask( usb_wrap_devinfo* wrap_devinfo );			/* [warning] never defined ⇒ .cへ移動 */

uhs_boolean_t Usbh_UnknownDevAttached( struct usbd_usb_deviceinfo* usbdev );

// リクエスト処理
uhs_status_t Usbh_ProcSyncRequest( struct usb_control_block* ucb, usb_wrap_msgsubtype msgsubtype );
//static uhs_status_t Usbh_UsbRequestIssue( usb_wrap_devinfo* devinfo, struct uhs_mbxbuf* usbc_message );	/* [warning] never defined ⇒ .cへ移動 */
//static int          Usbh_UsbRequestIssue_Completion( int mod_id, int callback_id, void* context );		/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_UsbRequestComp( usb_wrap_devinfo* devinfo, struct uhs_mbxbuf* usbc_message );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_ProcUsbRequestTmout( usb_wrap_devinfo *devinfo, requcb_info* requcb );			/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_CancelRequestInPipe( usb_wrap_devinfo *devinfo, struct usb_control_block* ucb );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_AbortAllRequest( usb_wrap_devinfo *devinfo );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_Callback( void *req );							/* [warning] never defined ⇒ .cへ移動 */
void Usbh_CallbackTask( void *context );
//static uhs_status_t Usbh_CallbackCanceledRequest( usb_wrap_devinfo *devinfo, void *req, uhs_status_t status );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_Control_Request( usb_wrap_devinfo* devinfo, void * class_driver_request );		/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_Bulk_Request( usb_wrap_devinfo* devinfo, void * class_driver_request );			/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_Interrupt_Request( usb_wrap_devinfo* devinfo, void * class_driver_request );		/* [warning] never defined ⇒ .cへ移動 */
//#ifdef USB_ENABLE_SET_CFG
//static uhs_status_t Usbh_Set_Configuration_Completion( struct usbd_usb_deviceinfo* usbdev, void * class_driver_request );	/* [warning] never defined ⇒ .cへ移動 */
//#endif
//#ifdef USB_ENABLE_SET_IF
//static uhs_status_t Usbh_Set_Interface_Completion( struct usbd_usb_deviceinfo* usbdev, void * class_driver_request );		/* [warning] never defined ⇒ .cへ移動 */
//#endif

void         Usbh_ReqProcTask( void* context );
void         Usbh_ReqCmpTask( void* context );


// メッセージ
uhs_status_t Usbh_SendRequest( void* class_driver_request, const uhs_ubit8_t address, const usb_wrap_msgtype msgtype, const usb_wrap_msgsubtype msgsubtype );
void         Usbh_SignalTask( kernel_context_t* taskmsgid, usb_wrap_msgtype msgtype, void* context );

// その他
//static usb_bus_status Usbh_check_usbbus( void );		/* [warning] never defined ⇒ .cへ移動 */
void           Usbh_Rh_Set_PortPower( const udi_ubit8_t port_num );
void           Usbh_Rh_Clear_PortPower( const udi_ubit8_t port_num );

void Usbh_call_overload_callback( const uhs_ubit8_t kind , struct usbd_usb_deviceinfo *usbhub, const uhs_ubit8_t port_num );
void	Usbh_call_split_err_notify_callback( struct	usbd_usb_spliterrinfo *ucb );


// ユーティリティ
//static struct class_driver_reginfo * Usbh_CreateClassDriverReginfo( void * class_driver_reg, usb_wrap_drvinfo * wrap_drvinfo );	/* [warning] never defined ⇒ .cへ移動 */
//static void         Usbh_ReleaseClassDriverReginfo( struct class_driver_reginfo * );						/* [warning] never defined ⇒ .cへ移動 */
//static requcb_info* Usbh_AllocReqUcbInfo( void * class_driver_request );									/* [warning] never defined ⇒ .cへ移動 */
//static void         Usbh_ReleaseReqUcbInfo( requcb_info* requcb );										/* [warning] never defined ⇒ .cへ移動 */
//static requcb_info* Usbh_GetRequcbInfo( usb_wrap_devinfo* devinfo, void * class_driver_request );			/* [warning] never defined ⇒ .cへ移動 */
//static requcb_info* Usbh_GetRequcbInfoByUcb( usb_wrap_devinfo* devinfo, struct usb_control_block* ucb );	/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_AddRequestToRequestList( usb_wrap_devinfo *devinfo, void *req );					/* [warning] never defined ⇒ .cへ移動 */
//static uhs_status_t Usbh_DelRequestFromRequestList( usb_wrap_devinfo *devinfo, void *req );				/* [warning] never defined ⇒ .cへ移動 */
//static udi_ubit32_t Usbh_GetMinTimeoutFromReqList( usb_wrap_devinfo* devinfo );							/* [warning] never defined ⇒ .cへ移動 */
//static requcb_info* Usbh_GetReqMinTimeoutFromReqList( usb_wrap_devinfo* devinfo );						/* [warning] never defined ⇒ .cへ移動 */
//static void         Usbh_UpdateLeftTime( requcb_info* requcb );											/* [warning] never defined ⇒ .cへ移動 */
//static uhs_ubit32_t Usbh_getCurrentTime( void );															/* [warning] never defined ⇒ .cへ移動 */
//static usb_wrap_msgtype    Usbh_GetMsgType( struct uhs_mbxbuf* usbc_message );							/* [warning] never defined ⇒ .cへ移動 */
//static usb_wrap_msgsubtype Usbh_GetMsgSubType( struct uhs_mbxbuf* usbc_message );							/* [warning] never defined ⇒ .cへ移動 */
//static void*        Usbh_GetMsgData( struct uhs_mbxbuf* usbc_message );									/* [warning] never defined ⇒ .cへ移動 */
void         Usbh_Setup_Ucb( struct usb_control_block* ucb, void* data_buf, const uhs_ubit32_t data_len, usb_device_request_t* setup_data, const usb_common_callback_t complete_func, const uhs_ubit32_t time_out );
//static void         Usbh_decreqnum( udi_ubit32_t *reqnum );			/* [warning] never defined ⇒ .cへ移動 */
//static struct uhs_mbxbuf*  Usbh_AllocMsg( void );						/* [warning] never defined ⇒ .cへ移動 */
//static void         Usbh_FreeMsg( struct uhs_mbxbuf* usbc_message );	/* [warning] never defined ⇒ .cへ移動 */
usb_device_request_t* Usbh_AllocDevReqInfo( void );
void         Usbh_FreeDevReqInfo( usb_device_request_t* devreq );
//static udi_sbit32_t Usbh_trans_statuscode( udi_sbit32_t statuscode );	/* [warning] never defined ⇒ .cへ移動 */
//static usb_wrap_devinfo* Usbh_GetDevInfo( udi_ubit8_t devicenum );	/* [warning] never defined ⇒ .cへ移動 */

#endif // __APIWRAPPER_H__

