blob: 2104c15663fa148107641e15e9f393b5ba3d4faf [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2016-2017, Linaro Limited
*/
#include <pta_socket.h>
#include <string.h>
#include <tee_internal_api.h>
#include <__tee_tcpsocket_defines.h>
#include <__tee_udpsocket_defines.h>
#include "tee_socket_private.h"
static TEE_Result invoke_socket_pta(uint32_t cmd_id, uint32_t param_types,
TEE_Param params[TEE_NUM_PARAMS])
{
static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
static const TEE_UUID socket_uuid = PTA_SOCKET_UUID;
if (sess == TEE_HANDLE_NULL) {
TEE_Result res = TEE_OpenTASession(&socket_uuid,
TEE_TIMEOUT_INFINITE,
0, NULL, &sess, NULL);
if (res != TEE_SUCCESS)
return res;
}
return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id,
param_types, params, NULL);
}
TEE_Result __tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers,
const char *addr, uint16_t port,
uint32_t protocol, uint32_t *handle)
{
TEE_Result res;
uint32_t param_types;
TEE_Param params[TEE_NUM_PARAMS];
param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_OUTPUT);
memset(params, 0, sizeof(params));
switch (ip_vers) {
case TEE_IP_VERSION_DC:
case TEE_IP_VERSION_4:
case TEE_IP_VERSION_6:
params[0].value.a = ip_vers;
break;
default:
return TEE_ERROR_BAD_PARAMETERS;
}
params[0].value.b = port;
if (!addr)
return TEE_ERROR_BAD_PARAMETERS;
params[1].memref.buffer = (void *)addr;
params[1].memref.size = strlen(addr) + 1;
switch (protocol) {
case TEE_ISOCKET_PROTOCOLID_TCP:
case TEE_ISOCKET_PROTOCOLID_UDP:
params[2].value.a = protocol;
break;
default:
return TEE_ERROR_BAD_PARAMETERS;
}
res = invoke_socket_pta(PTA_SOCKET_OPEN, param_types, params);
if (res == TEE_SUCCESS)
*handle = params[3].value.a;
return res;
}
TEE_Result __tee_socket_pta_close(uint32_t handle)
{
uint32_t param_types;
TEE_Param params[TEE_NUM_PARAMS];
param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
memset(params, 0, sizeof(params));
params[0].value.a = handle;
return invoke_socket_pta(PTA_SOCKET_CLOSE, param_types, params);
}
TEE_Result __tee_socket_pta_send(uint32_t handle, const void *buf,
uint32_t *len, uint32_t timeout)
{
TEE_Result res;
uint32_t param_types;
TEE_Param params[TEE_NUM_PARAMS];
param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_VALUE_OUTPUT,
TEE_PARAM_TYPE_NONE);
memset(params, 0, sizeof(params));
params[0].value.a = handle;
params[0].value.b = timeout;
params[1].memref.buffer = (void *)buf;
params[1].memref.size = *len;
res = invoke_socket_pta(PTA_SOCKET_SEND, param_types, params);
*len = params[2].value.a;
return res;
}
TEE_Result __tee_socket_pta_recv(uint32_t handle, void *buf, uint32_t *len,
uint32_t timeout)
{
TEE_Result res;
uint32_t param_types;
TEE_Param params[TEE_NUM_PARAMS];
param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_MEMREF_OUTPUT,
TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
memset(params, 0, sizeof(params));
params[0].value.a = handle;
params[0].value.b = timeout;
params[1].memref.buffer = buf;
params[1].memref.size = *len;
res = invoke_socket_pta(PTA_SOCKET_RECV, param_types, params);
*len = params[1].memref.size;
return res;
}
TEE_Result __tee_socket_pta_ioctl(uint32_t handle, uint32_t command, void *buf,
uint32_t *len)
{
TEE_Result res;
uint32_t param_types;
TEE_Param params[TEE_NUM_PARAMS];
param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_MEMREF_INOUT,
TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
memset(params, 0, sizeof(params));
params[0].value.a = handle;
params[0].value.b = command;
params[1].memref.buffer = buf;
params[1].memref.size = *len;
res = invoke_socket_pta(PTA_SOCKET_IOCTL, param_types, params);
*len = params[1].memref.size;
return res;
}