////
/// Copyright(C) 2020 Micronet Co. All Rights Reserved.
//
/*------------------------------------------------------------------------------
概要: RT-edge RTCD関連機能API ヘッダーファイル
注意: 本ファイルは全プロジェクト(INtime/NTX/Win)で使用される共通ファイルです。
履歴: 2019.08.08 新規作成
      2019.12.09 RTCD経過秒 32bit→64bitに変更
--------------------------------------------------------------------------------*/

#pragma once
#ifdef __INTIME__
	#include <sys/time.h>
	#include <rttypes.h>
#else
	#include <windows.h>
#endif

#ifdef __cplusplus
extern "C"
{
#endif

#ifdef __INTIME__	// INtimeネイティブ
#ifdef  egRTCD_EXPORTS
#define egRTCD_API
#else
#define egRTCD_API __declspec(dllimport)
#endif
#else				// Windows
#ifdef _USE_NTX_	// INtime有り(NTX使用)
#ifdef egRTCDNtx_EXPORTS
#define egRTCD_API
#else
#define egRTCD_API __declspec(dllimport)
#endif  
#else				// INtime無し
#ifdef egRTCDWin_EXPORTS
#define egRTCD_API
#else
#define egRTCD_API __declspec(dllimport)
#endif  
#endif
#endif

// RTCDHANDLE type
typedef unsigned long long OBJHANDLE;

// RTCDノードカタログ名
static const char* EGRTCDNODE = "EGRTCDNODE";		// RTCDノード判定用カタログ名

//------------------------------------------------------------------------------
// エラーコード
//------------------------------------------------------------------------------
#define EDGE_SUCCESS							0x00000000	// 正常終了
#define EDGE_LOCATION_ERROR						0x80000001	// ロケーションハンドル取得エラー
#define EDGE_KERNEL_NOT_RUNNING					0x80000002	// カーネルが起動していません
#define EDGE_ROOTPROCESS_ERROR					0x80000003	// ルートプロセス取得エラー
#define EDGE_PARAM_INVALID						0x80000004	// パラメータが不正です

// RTCD関連
#define EDGE_RTCD_NAME_INVALID					0x80000100	// RTCD名称が不正です
#define EDGE_RTCD_NAME_LENGTH_ERROR				0x80000101	// RTCD名称の文字数エラー
#define EDGE_RTCD_RECORD_LENGTH_ERROR			0x80000102	// レコード長エラー
#define EDGE_RTCD_RECORD_NUM_ERROR				0x80000103	// レコード数エラー
#define EDGE_RTCD_WRITE_MODE_ERROR				0x80000105	// 書込みモードエラー
#define EDGE_RTCD_EXIST_ERROR					0x80000106	// 既に同じRTCDが存在します
#define EDGE_RTCD_NOT_EXIST_ERROR				0x80000107	// RTCDが存在しません
#define EDGE_RTCD_NAME_EXIST_ERROR				0x80000108	// 既に同じ名前が使われています
#define EDGE_RTCD_ALLOCATE_ERROR				0x80000109	// メモリ確保失敗
#define EDGE_RTCD_FREE_ERROR					0x8000010A	// メモリ解放失敗
#define EDGE_RTCD_CREATE_MEM_HANDLE_ERROR		0x8000010B	// メモリハンドル生成失敗
#define EDGE_RTCD_DELETE_MEM_HANDLE_ERROR		0x8000010C	// メモリハンドル削除失敗
#define EDGE_RTCD_CATALOG_ERROR					0x8000010D	// カタログ失敗
#define EDGE_RTCD_UNCATALOG_ERROR				0x8000010E	// アンカタログ失敗
#define EDGE_RTCD_LOOKUP_ERROR					0x8000010F	// ルックアップ失敗
#define EDGE_RTCD_MAPPING_ERROR					0x80000110	// マッピング失敗
#define EDGE_RTCD_UNMAPPING_ERROR				0x80000111	// アンマッピング失敗
#define EDGE_RTCD_ACCESS_MODE_ERROR				0x80000112	// アクセスモードエラー
#define EDGE_RTCD_ALREADY_OPEN_READ_ERROR		0x80000113	// 既に読込みアクセスでオープンされています
#define EDGE_RTCD_ALREADY_OPEN_WRITE_ERROR		0x80000114	// 既に書込みアクセスでオープンされています(シングルモード時)
#define EDGE_RTCD_MEMINFO_INVALID				0x80000115	// RTCDメモリ情報が不正です
#define EDGE_RTCD_HANDLE_INVALID				0x80000116	// ハンドルが不正です
#define EDGE_RTCD_BUFFER_INVALID				0x80000117	// バッファが不正です
#define EDGE_RTCD_BUFFER_SIZE_INVALID			0x80000118	// バッファサイズが不正です
#define EDGE_RTCD_WRITE_SIZE_INVALID			0x80000119	// 書込みサイズが不正です
#define EDGE_RTCD_RECORD_HEADER_INVALID			0x8000011A	// RTCDヘッダーが不正です
#define EDGE_RTCD_INFO_INVALID					0x8000011B	// RTCD情報が不正です
#define EDGE_RTCD_NO_UPDATE						0x8000011C	// データ更新がありません
#define EDGE_RTCD_BUFFER_FULL_ERROR				0x8000011D	// バッファフルエラー

#define EDGE_RTCD_CREATE_SEMAPHORE1_ERROR		0x80000200	// セマフォ生成エラー(排他用セマフォ)
#define EDGE_RTCD_CREATE_SEMAPHORE2_ERROR		0x80000201	// セマフォ生成エラー(書込通知用セマフォ)
#define EDGE_RTCD_DELETE_SEMAPHORE1_ERROR		0x80000202	// セマフォ削除エラー(排他用セマフォ)
#define EDGE_RTCD_DELETE_SEMAPHORE2_ERROR		0x80000203	// セマフォ削除エラー(書込通知用セマフォ)
#define EDGE_RTCD_CATALOG_SEMAPHORE1_ERROR		0x80000204	// セマフォカタログエラー(排他用セマフォ)
#define EDGE_RTCD_CATALOG_SEMAPHORE2_ERROR		0x80000205	// セマフォカタログエラー(書込通知用セマフォ)
#define EDGE_RTCD_SEMAPHORE_TIMEOUT				0x80000206	// セマフォ取得タイムアウト
#define EDGE_RTCD_WAIT_SEMAPHORE_ERROR			0x80000207	// セマフォ取得エラー
#define EDGE_RTCD_RELEASE_SEMAPHORE_ERROR		0x80000208	// セマフォ解放エラー
#define EDGE_RTCD_OPEN_SEMAPHORE1_ERROR			0x80000209	// セマフォオープンエラー(排他用セマフォ)
#define EDGE_RTCD_OPEN_SEMAPHORE2_ERROR			0x8000020A	// セマフォオープンエラー(書込通知用セマフォ)
#define EDGE_RTCD_NOT_EXIST_SEMAPHORE_ERROR		0x8000020B	// セマフォが存在しません
#define EDGE_RTCD_LOOKUP_SEMAPHORE_ERROR		0x8000020C	// セマフォルックアップエラー
#define EDGE_RTCD_SEMAPHORE1_EXIST_ERROR		0x8000020D	// 既に同じセマフォが存在します(排他用セマフォ)
#define EDGE_RTCD_SEMAPHORE1_NAME_EXIST_ERROR	0x8000020E	// 既に同じ名前が使われています(排他用セマフォ)
#define EDGE_RTCD_SEMAPHORE2_EXIST_ERROR		0x8000020F	// 既に同じセマフォが存在します(書込通知用セマフォ)
#define EDGE_RTCD_SEMAPHORE2_NAME_EXIST_ERROR	0x80000210	// 既に同じ名前が使われています(書込通知用セマフォ)

#define EDGE_RTCD_CREATE_MEMFILE_ERROR			0x80000300	// メモリマップトファイル生成エラー
#define EDGE_RTCD_CREATE_FILEMAPPING_ERROR		0x80000301	// ファイルマッピング生成エラー
#define EDGE_RTCD_OPEN_FILEMAPPING_ERROR		0x80000302	// ファイルマッピングオープンエラー
#define EDGE_RTCD_MAP_VIEW_ERROR				0x80000303	// ビューマップエラー
#define EDGE_RTCD_UNMAP_VIEW_ERROR				0x80000304	// ビューアンマップエラー


//------------------------------------------------------------------------------
// API用定数
//------------------------------------------------------------------------------
// RTCD書込みモード
#define RTCD_WRITE_SINGLE	0x00000001	// 書込みシングルモード
#define RTCD_WRITE_MULTI	0x00000002	// 書込みマルチモード
// RTCDアクセスモード
#define RTCD_READ			0x00000001	// 読込みアクセス
#define RTCD_WRITE			0x00000002	// 書込みアクセス
#define RTCD_READWRITE		0x00000003	// 読書きアクセス


//------------------------------------------------------------------------------
// 構造体定義
//------------------------------------------------------------------------------
#pragma pack(push,1)

// RTCDヘッダー (256バイト) +12
typedef union
{
	struct {
		DWORD record_num;				// レコード数
		DWORD record_size;				// レコードサイズ(バイト数)
		DWORD read_pos;					// 読込み位置
		DWORD write_pos;				// 書込み位置
		DWORD write_mode;				// 書込みモード 1:シングル 2:マルチ
		DWORD read_open_count;			// 読込みモードオープンカウンタ
		DWORD write_open_count;			// 書込みモードオープンカウンタ
		DWORD lost_count;				// 欠落カウンタ
		OBJHANDLE mem_handle;			// RTCDメモリハンドル値
		OBJHANDLE lock_sem_handle;		// 排他用セマフォハンドル値
		OBJHANDLE notify_sem_handle;	// 書込通知用セマフォハンドル値
		char name[12];					// RTCD名称(最大10文字まで)
	};
    BYTE reserve[256];				// 予備
} EDGE_RTCD_HEADER;

// RTCDメモリ情報 (28バイト) +12
typedef union
{
	struct {
		BYTE *pRtcd;					// RTCDメモリポインタ(本体)
		OBJHANDLE mem_handle;			// RTCDメモリハンドル
		OBJHANDLE sem1_handle;			// 排他用セマフォハンドル
		OBJHANDLE sem2_handle;			// 書込通知用セマフォハンドル
		char name[12];					// RTCD名称(最大10文字まで)
	};
	BYTE reserve[28];
} EDGE_RTCD_MEM_INFO, RTCDMEMINFO;

// RTCDハンドル (28バイト)
typedef union
{
	struct {
		DWORD  code;					// RTCDハンドル識別コード
		EDGE_RTCD_HEADER *pRtcdHeader;	// RTCDヘッダーのポインタ
		BYTE *pRtcdData;				// RTCDデータのポインタ
		void *pMem_handle;				// RTCDメモリハンドル
		void *pSem1_handle;				// 排他用セマフォハンドル
		void *pSem2_handle;				// 書込通知用セマフォハンドル
		DWORD  access;					// アクセスモード
	};
	BYTE reserved[28];
} EDGE_RTCD_HANDLE, RTCDHANDLE;

// ファイルハンドル (264バイト)
typedef struct
{
    char  path[256];				// ファイルパス
    void* pHandle;					// スレッドハンドル
    DWORD mode;						// アクセスモード
} EDGE_FILE_HANDLE, RTFHANDLE;

// RTCDレコードヘッダー (32バイト)
typedef struct
{
    unsigned long long time;		// 書込み日時 (1970年1月1日からの経過秒)
    WORD millisecond;				// 書込み日時 ミリ秒
    WORD microsecond;				// 書込み日時 マイクロ秒
	DWORD size;						// データサイズ(bytes)
    WORD lost_count;				// 欠落カウンタ
	BYTE reserve[14];				// 予備
} EDGE_RECORD_HEADER;

// タイムスタンプ情報 (12バイト)
typedef struct
{
    unsigned long long time;		// 現在日時 1970年1月1日からの経過秒
    WORD millisecond;				// 現在日時 ミリ秒
    WORD microsecond;				// 現在日時 マイクロ秒
} EDGE_TIME_STAMP;

// タイムスタンプ情報 (12バイト)
typedef struct
{
	unsigned long long time;		// 現在日時 1970年1月1日からの経過秒
	unsigned long microsecond;		// 現在日時 マイクロ秒
} EDGE_TIME_VAL;

#pragma pack(pop)


//------------------------------------------------------------------------------
// RT-edge API定義
//------------------------------------------------------------------------------
// RTCD機能
egRTCD_API int edgeCreateRTCD(const char *pName, DWORD dwMode, DWORD dwLength, DWORD dwNum, RTCDMEMINFO *pRtcdInfo);
egRTCD_API int edgeDeleteRTCD(RTCDMEMINFO *pRtcdInfo);
egRTCD_API int edgeOpenRTCD(const char *pName, DWORD dwAccess, RTCDHANDLE *pHandle);
egRTCD_API int edgeCloseRTCD(RTCDHANDLE *pHandle);
egRTCD_API int edgeWriteRTCD(RTCDHANDLE *pHandle, void *pBuffer, DWORD dwSize);
egRTCD_API int edgeWriteRTCD4Mbox(RTCDHANDLE *pHandle, void *pBuffer1, DWORD dwSize1, void *pBuffer2, DWORD dwSize2);
egRTCD_API int edgeReadRTCD(RTCDHANDLE *pHandle, void *pBuffer, DWORD dwBufferSize, EDGE_RECORD_HEADER *pDataTime, DWORD dwTimeout);
egRTCD_API int edgeReadRTCD4Mbox(RTCDHANDLE *pHandle, void *pBuffer1, DWORD dwBufferSize1, void *pBuffer2, DWORD dwBufferSize2, EDGE_RECORD_HEADER *pDataTime, DWORD dwTimeout);
egRTCD_API int edgeGetRTCDInfo(RTCDHANDLE *pHandle, EDGE_RTCD_HEADER *pInfo);
egRTCD_API int edgeClearRTCDCounter(const char *pName, DWORD dwAccess);
egRTCD_API int edgeIsRTCDHandle(RTCDHANDLE *pHandle);

// メッセージ通信機能
egRTCD_API int edgeCreateMailbox(const char *pName, DWORD dwLength, DWORD dwNum, RTCDMEMINFO *pRtcdInfo);
egRTCD_API int edgeDeleteMailbox(RTCDMEMINFO *pRtcdInfo);
egRTCD_API int edgeOpenMailbox(const char *pName, DWORD dwAccess, RTCDHANDLE *pHandle);
egRTCD_API int edgeCloseMailbox(RTCDHANDLE *pHandle);
egRTCD_API int edgeSendData(RTCDHANDLE *pHandle, void *pBuffer, DWORD dwSize);
egRTCD_API int edgeSendData4Mbox(RTCDHANDLE *pHandle, void *pBuffer1, DWORD dwSize1, void *pBuffer2, DWORD dwSize2);
egRTCD_API int edgeReceiveData(RTCDHANDLE *pHandle, void *pBuffer, DWORD dwBufferSize, DWORD dwTimeout);
egRTCD_API int edgeReceiveData4Mbox(RTCDHANDLE *pHandle, void *pBuffer1, DWORD dwBufferSize1, void *pBuffer2, DWORD dwBufferSize2, DWORD dwTimeout);
egRTCD_API int edgeHandleCheck(RTCDHANDLE *pHandle); // ハンドルチェック

// 時刻サービス機能
egRTCD_API int edgeGetTimestamp(EDGE_TIME_STAMP *pTime);
egRTCD_API int edgeGetTimeVal(EDGE_TIME_VAL *pTime);

#ifdef __cplusplus
}
#endif
