/**
 * @brief           GVD extern I/F Header
 * @author          AXELL CORPORATION
 * @description     GVD 外部I/F定義
 * @note            ここに定義されている関数はアプリケーション側で実装する必要があります.
 * @note            実装例はGVDサンプル または MPSライブラリサンプルを参照してください.
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */

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

#include <stddef.h>
#include <stdbool.h>
#include "gvd_error.h"

/**
 * @brief           GVD メモリ確保インタフェース
 * @param           size [in] メモリ確保サイズ
 * @return          確保したメモリアドレス
 * @retval          NULL メモリ確保失敗
 * @description     GVDのメモリ確保用インタフェースです.
 * @note            動作はアプリケーション側の実装に依存します.
 */
void* gvdMemAlloc(size_t size);
/**
 * @brief           GVD メモリ解放インタフェース
 * @param           blk [in] 確保済みメモリアドレス
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     GVDのメモリ解放用インタフェースです.
 * @note            動作はアプリケーション側の実装に依存します.
 */
gvdError gvdMemFree(void *blk);

typedef int32_t	gvdFilePos;	/** ストリーム位置 */

/** ファイル操作用構造体 */
typedef struct {
	int32_t		*fd;			/** ファイルディスクリプタ */
	gvdFilePos	size;			/** ファイルサイズ */
	gvdFilePos	pos;			/** オフセット */
	bool		error;			/** エラーコード */
	uint32_t	id;				/** ストリームID */
	uint32_t	nal_size;		/** NALサイズ */
	uint32_t	nal_prev;		/** NAL絶対位置（前） */
	uint32_t	nal_next;		/** NAL絶対位置（次） */
} gvdFile[1];

/**
 * @brief           GVD ファイル管理構造体初期化インタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     GVDのファイルストリーマ生成時にコールされます.
 * @note            動作はアプリケーション側の実装に依存します.
 */
gvdError gvdFileInitialize(gvdFile gvdfile);
/**
 * @brief           GVD ファイルオープンインタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @param           filename [in] ファイル名
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     内蔵ファイルストリーマ使用時, デコーダ接続処理中にコールされます.
 * @note            動作はアプリケーション側の実装に依存します.<p>
 *                  GVDライブラリはバイナリモード相当でファイルが開かれることを期待します.
 */
gvdError gvdFileOpen(gvdFile gvdfile, const char *filename);
/**
 * @brief           GVD ファイルリードインタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @param           buf [out] リード先バッファ
 * @param           rdsize [in] リードサイズ
 * @param           actual_rdsize [out] bufへの書き込みサイズ
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     内蔵ファイルストリーマ使用時, ストリーム読み出し時にコールされます.
 * @note            動作はアプリケーション側の実装に依存します.<p>
 *                  内蔵ファイルストリーマ使用時に, 本関数はGVD_Execute関数内でコールされます.<p>
 *                  外部ファイルストリーマ使用時は, 本関数はコールされません.<p>
 *                  エラーコード：GVD_ERR_FILE_OPERATION_TIMEDOUTを返すことで, ファイルストリーマにリトライさせることができます.
 */
gvdError gvdFileRead(gvdFile gvdfile, void *buf, size_t rdsize, size_t *actual_rdsize);
/**
 * @brief           GVD ファイルEOFチェックインタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @return          EOFチェック結果
 * @retval          true ストリーム終端まで読み終えた
 * @retval          false ストリーム終端まで読み終えていない
 * @description     現在のストリーム位置が終端かをチェックします.
 * @note            動作はアプリケーション側の実装に依存します.
 */
bool gvdFileIsEOF(gvdFile gvdfile);
/**
 * @brief           GVD ファイルシークインタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @param           pos [in] ストリームのオフセット位置 [Byte]
 * @return          シーク結果
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_FILE_OPERATION_FAILURE シーク失敗
 * @description     指定された絶対オフセットにシークします.
 * @note            動作はアプリケーション側の実装に依存します.<p>
 *                  GVD_ERR_FILE_OPERATION_FAILUREを返した場合, GVDライブラリは処理を継続することができないため致命的エラー状態となります。
 */
gvdError gvdFileSeekAbs(gvdFile gvdfile, gvdFilePos pos);
/**
 * @brief           GVD ファイルクローズインタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     内蔵ファイルストリーマ使用時, デコーダ切断時にコールされます.
 * @note            動作はアプリケーション側の実装に依存します.
 */
gvdError gvdFileClose(gvdFile gvdfile);
/**
 * @brief           GVD ファイル終了処理インタフェース
 * @param           gvdfile [in,out] GVDファイル管理構造体
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @description     GVDのファイルストリーマ破棄時にコールされます.
 * @note            動作はアプリケーション側の実装に依存します.
 */
gvdError gvdFileFinalize(gvdFile gvdfile);

/**
 * @brief           ミューテックスの初期化
 * @param           pMutex [out] ミューテックスID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 初期化失敗
 * @description     ミューテックスを生成してIDを返します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"acre_mtx"に相当する処理を実装して下さい.
*/
gvdError gvdOsMutexInit(int32_t *pMutex);

/**
 * @brief           ミューテックスのロック
 * @param           pMutex [in] ミューテックスID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH ロック失敗
 * @description     ミューテックスをロックします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"loc_mtx"に相当する処理を実装して下さい.
*/
gvdError gvdOsMutexLock(int32_t *pMutex);

/**
 * @brief           ミューテックスのロック（ポーリング）
 * @param           pMutex [in] ミューテックスID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH ロック失敗
 * @description     ミューテックスをロックします（ポーリング）.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"pol_mtx"又は"tloc_mtx(timeout=0)"に相当する処理を実装して下さい.
*/
gvdError gvdOsMutexTryLock(int32_t *pMutex);

/**
 * @brief           ミューテックスのロック解除
 * @param           pMutex [in] ミューテックスID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH ロック解除失敗
 * @description     ミューテックスのロックを解除します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"unl_mtx"に相当する処理を実装して下さい.
*/
gvdError gvdOsMutexUnlock(int32_t *pMutex);

/**
 * @brief           ミューテックスの削除
 * @param           pMutex [in] ミューテックスID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 削除失敗
 * @description     ミューテックスを削除します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"del_mtx"に相当する処理を実装して下さい.
*/
gvdError gvdOsMutexDestroy(int32_t *pMutex);

/**
 * @brief           イベントフラグの初期化
 * @param           pEvent [out] イベントフラグID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 初期化失敗
 * @description     イベントフラグを生成してIDを返します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"acre_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsEventInit(int32_t *pEvent);

/**
 * @brief           イベントフラグのセット
 * @param           pEvent [in] イベントフラグID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH セット失敗
 * @description     イベントフラグをセットします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"set_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsEventSignal(int32_t *pEvent);

/**
 * @brief           イベントフラグのセット（割り込みからの呼び出し）
 * @param           pEvent [in] イベントフラグID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH セット失敗
 * @description     （割り込み内から）イベントフラグをセットします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"iset_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsIntEventSignal(int32_t *pEvent);

/**
 * @brief           イベントフラグ待ち
 * @param           pEvent [in] イベントフラグID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 待ち失敗
 * @description     イベントフラグ待ちします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"wai_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsEventWait(int32_t *pEvent);

/**
 * @brief           イベントフラグ待ち（タイムアウト付き）
 * @param           pEvent [in] イベントフラグID
 * @param           msec [in] タイムアウト時間 [ms]
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 待ち失敗
 * @description     タイムアウト付きでイベントフラグ待ちします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"twai_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsEventTimedWait(int32_t *pEvent, uint32_t msec);

/**
 * @brief           イベントフラグの削除
 * @param           pEvent [in] イベントフラグID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 削除失敗
 * @description     イベントフラグを削除します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"del_flg"に相当する処理を実装して下さい.
*/
gvdError gvdOsEventDestroy(int32_t* pEvent);

/**
 * @brief           割込みハンドラの生成
 * @param           intno [in] 割込み番号
 * @param           hdlr [out] ハンドラID
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 初期化失敗
 * @description     割込みハンドラを生成してIDを返します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"acre_isr"に相当する処理を実装して下さい.
 *                  INT Manager を使用時は AG903_INTMgrSetHandler が該当します.
*/
void gvdOsHandlerCreate(int intno, void* hdlr);

/**
 * @brief           割込みハンドラの削除
 * @param           intno [in] 割込み番号
 * @return          GVDのエラーコード
 * @retval          GVD_ERR_SUCCESS 正常終了
 * @retval          GVD_ERR_RESOURCE_NOT_ENOUGH 初期化失敗
 * @description     割込みハンドラを削除します.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"del_isr"に相当する処理を実装して下さい.
 *                  INT Manager を使用時は AG903_INTMgrDeleteHandler が該当します.
*/
void gvdOsHandlerDelete(int intno);

/**
 * @brief           割込みの初期化
 * @param           intno [in] 割込み番号
 * @return          none
 * @description     割込みの初期化（優先度設定）をします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  割込みに対する初期化処理が必要な場合に実装して下さい.
 *                  INT Manager を使用時は AG903_INTMgrSetPriority による優先度設定等を実装します.
*/
void gvdIntrInit(int intno);

/**
 * @brief           割込みの許可
 * @param           intno [in] 割込み番号
 * @return          none
 * @description     割込みの許可設定をします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"ena_int"に相当する処理を実装して下さい.
 *                  INT Manager を使用時は AG903_INTMgrEnableInt が該当します.
*/
void gvdIntrEnable(int intno);

/**
 * @brief           割込みの禁止
 * @param           intno [in] 割込み番号
 * @return          none
 * @description     割込みの禁止設定をします.
 * @note            本関数はアプリケーション側で実装する必要があります.<p>
 *                  uITRON準拠OSのシステムコール"dis_int"に相当する処理を実装して下さい.
 *                  INT Manager を使用時は AG903_INTMgrDisableInt が該当します.
*/
void gvdIntrDisable(int intno);

#endif
