/**
 * @file teec_common.h
 * @brief Platform-independent client API interface
 * @author Iaroslav Makarchuk (i.makarchuk@samsung.com)
 * @date Created Oct 3, 2016
 * @par In Samsung Ukraine R&D Center (SURC) under a contract between
 * @par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
 * @par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
 * @par Copyright: (c) Samsung Electronics Co, Ltd 2015. All rights reserved.
 *
 * This software is proprietary of Samsung Electronics.
 * No part of this software, either material or conceptual may be copied
 * or distributed, transmitted, transcribed, stored in a retrieval system
 * or translated into any human or computer language in any form by any means,
 * electronic, mechanical, manual or otherwise, or disclosed to third parties
 * without the express written permission of Samsung Electronics.
 */

#ifndef TEEC_COMMON_H_
#define TEEC_COMMON_H_

#include <stdint.h>
#include <pthread.h>
#include <tee_client_api.h>
#include <mb_list.h>

#define MB_TIMEOUT_INFINITE      ((int32_t)(-1)) /**< Wait infinite for a response of the MC. */
#define MB_TIMEOUT_INTERRUPTIBLE ((int32_t)(-2)) /**< Wait infinite for a response of the MC, exit on signal. */

typedef TEEC_Result (*ClientImplLoadTA)(void *session, const TEEC_UUID *uuid);
typedef TEEC_Result (*ClientImplSendCommand)(void *session, uint32_t command_id,
                                             TEEC_Operation *operation,
                                             uint32_t *return_origin,
                                             int32_t timeout);
typedef TEEC_Result (*ClientImplUnloadTA)(void *session);
typedef uint32_t (*ClientImplMapBuffer)(void *session, void *ptr, size_t size);
typedef void *(*ClientImplAllocateForSession)(void *session, size_t size);
typedef void (*ClientImplFreeForSession)(void *session, void *ptr);
typedef int (*ClientImplSessionCanRelease)(void *session, void *ptr);

typedef struct PlatformClientImplStruct {
  ClientImplLoadTA LoadTA;
  ClientImplUnloadTA UnloadTA;
  ClientImplSendCommand SendCommand;
  ClientImplMapBuffer MapBuffer;
  ClientImplAllocateForSession AllocateBuffer;
  ClientImplFreeForSession FreeBuffer;
  ClientImplSessionCanRelease CanRelease;
} PlatformClientImpl;

typedef struct OperationListStruct {
  struct list_head list;
  TEEC_Operation *oper;
} OperationList;


typedef struct CancelRequestListStruct {
  pthread_mutex_t mtx;
  uint32_t initialized;
  OperationList operation_list;
  uint32_t operations_count;
  uint32_t usage_count;
} CancelRequestList;


PlatformClientImpl *GetPlatformClientImpl(void);
void ClientImplSetParentContext(void *session, void *context);
void* ClientImplGetParentContext(void *session);

size_t GetPlatformClientImplSize(void);
uint8_t IsOperationInCRList(TEEC_Operation *oper);
#endif /* TEEC_COMMON_H_ */
