/**
 * @file session_manager.c
 * @brief Simple TA session mamger for separating session contexts
 * implementation
 * @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.
 */

#include <session_manager.h>

static int g_sessions_count = 0;
static int g_session_list_initialized = 0;
static TeeSession g_session_list;

TEE_Result SessionManagerAddSession(TeeSession *session) {
  if (!session) {
    return TEE_ERROR_BAD_PARAMETERS;
  }

  if (!g_session_list_initialized) {
    g_session_list_initialized++;
    INIT_LIST_HEAD(&g_session_list.list);
  }

  list_add_tail(&session->list, &g_session_list.list);
  g_sessions_count++;

  return TEE_SUCCESS;
}

TEE_Result SessionManagerRemoveSession(TeeSession *session) {
  struct list_head *pos, *q;

  if (!session) {
    return TEE_ERROR_BAD_PARAMETERS;
  }

  if (!g_session_list_initialized) {
    return TEE_ERROR_ITEM_NOT_FOUND;
  }

  list_for_each_safe(pos, q, &g_session_list.list) {
    TeeSession *node = list_entry(pos, TeeSession, list);
    if (node == session) {
      list_del(pos);
      g_sessions_count--;

      return TEE_SUCCESS;
    }
  }
 
  return TEE_ERROR_ITEM_NOT_FOUND; 
}

TEE_Result SessionManagerGetSession(void *handle, TeeSession **session) {
  struct list_head *pos, *q;

  if (!handle || !session) {
    return TEE_ERROR_BAD_PARAMETERS;
  }

  if (!g_session_list_initialized) {
    return TEE_ERROR_ITEM_NOT_FOUND;
  }

  list_for_each_safe(pos, q, &g_session_list.list) {
    TeeSession *node = list_entry(pos, TeeSession, list);
    if (node->handle == handle) {
      *session = node;
      return TEE_SUCCESS;
    }
  }
 
  return TEE_ERROR_ITEM_NOT_FOUND; 
}
