#include "sense4.h"

/*
	ELドングルを選択して接続します 
	Parameters:
		index[in]    : デバイスインデックス
		pstS4Ctx[out]: ELコンテクストへのポインタ
		
	Return: 
		成功時 TRUE、それ以外はFALSE

	Remarks:
		none.
*/
unsigned long OpenS4ByIndex(unsigned long index,PSENSE4_CONTEXT pstS4Ctx)
{
	PSENSE4_CONTEXT pstS4CtxList = NULL;
	unsigned long dwCtxListSize = 0;
	unsigned long dwResult = 0;
	unsigned long dwDeviceNum = 0;

	if (NULL == pstS4Ctx) 
	{
		printf("Invalid pointer!\n");
		return 0;
	}
	/*
		S4Enum(...)で接続中ドングルを列挙
		最初の引数として NULL を渡すと第2引数に ELコンテキストに必要なメモリサイズを返します。
		dwCtxListSize は 0(ドングル未接続)か 0以外
		dwCtxListSize/sizeof(SENSE4_CONTEXT) で接続ドングル数)のどちらかになります
	*/
	dwResult = S4Enum(NULL, &dwCtxListSize);
	if (dwResult != S4_SUCCESS && dwResult != S4_INSUFFICIENT_BUFFER)
	{
		printf("Enumerate Elite EL failed! \n", dwResult);
		return 0;
	}

	if (0 == dwCtxListSize)
	{
		printf("Elite EL not found!\n");
		return 0;
	}

	// ELコンテキスとの配列用のメモリ割り当て
	pstS4CtxList = (PSENSE4_CONTEXT)malloc(dwCtxListSize);
	if (NULL == pstS4CtxList) 
	{
		printf("Not enough memory! \n");
		return 0;
	}
	
	dwDeviceNum = dwCtxListSize/sizeof(SENSE4_CONTEXT);
	if(index+1 > dwDeviceNum)
	{
		printf("Invalid index! \n",dwDeviceNum-1);
		free(pstS4CtxList);
		pstS4CtxList = NULL;
		return 0;
	}

	/*
		必要分の EL コンテキストを用意できたので、実際に接続ドングルのコンテキストを取得
	*/
	dwResult = S4Enum(pstS4CtxList, &dwCtxListSize);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Enumerate Elite EL failed! \n", dwResult);
		free(pstS4CtxList);
		pstS4CtxList = NULL;
		return 0;
	}

	// 指定位置のデバイスを選択 
	memcpy(pstS4Ctx, pstS4CtxList+index, sizeof(SENSE4_CONTEXT));

	free(pstS4CtxList);
	pstS4CtxList = NULL;

	// 選択ドングルに接続
	dwResult = S4Open(pstS4Ctx);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Open Elite EL failed! \n", dwResult);
		return 0;
	}
	return 1;
}

/*
	ELドングルのリセットと接続切断
	Parameters:
		pstS4Ctx[out]:  EL コンテキストへのポインタ
		
	Return: 
		none.	

	Remarks:
		接続切断には S4Close() ではなくこの関数を使ってください
		開発者 PINでS4VerifyPIN が成功すると、デバイスを抜き取る、
		リセットする、ユーザPINを確認しないかぎり、開発者PINが有効
		のままになります
*/
void ResetAndCloseS4(PSENSE4_CONTEXT pstS4Ctx)
{
	S4Control(pstS4Ctx, S4_RESET_DEVICE, NULL, 0, NULL, 0, NULL);
	S4Close(pstS4Ctx);
	return ;
}