312 lines
9.1 KiB
C
312 lines
9.1 KiB
C
/**
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2018 Infineon Technologies AG
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE
|
|
*
|
|
*
|
|
* \file DtlsTransportLayer.c
|
|
*
|
|
* \brief This file provides APIs for the transport layer functionalities.
|
|
*
|
|
* \addtogroup grOCP
|
|
* @{
|
|
*
|
|
*/
|
|
|
|
#include "optiga/dtls/DtlsTransportLayer.h"
|
|
#include "optiga/common/MemoryMgmt.h"
|
|
|
|
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
|
|
|
|
/// @cond hidden
|
|
|
|
/// @endcond
|
|
/**
|
|
* This API initialises transport layer communication structure.
|
|
*
|
|
* \param[in,out] PpsTL Pointer to the transport layer communication structure
|
|
*
|
|
* \return #OCP_TL_OK on successful execution
|
|
* \return #OCP_TL_ERROR on failure
|
|
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
|
|
* \return #E_COMMS_UDP_ALLOCATE_FAILURE on failure to allocate memory
|
|
*/
|
|
int32_t DtlsTL_Init(sTL_d* PpsTL)
|
|
{
|
|
int32_t i4Status = (int32_t)OCP_TL_ERROR;
|
|
do
|
|
{
|
|
//NULL check
|
|
if((NULL == PpsTL) || (NULL == PpsTL->pzIpAddress))
|
|
{
|
|
i4Status = (int32_t)OCP_TL_NULL_PARAM;
|
|
break;
|
|
}
|
|
|
|
//Allocate the memory for the ethernet communication structure
|
|
PpsTL->phTLHdl = (pal_socket_t*)OCP_MALLOC(sizeof(pal_socket_t));
|
|
if(NULL == PpsTL->phTLHdl)
|
|
{
|
|
i4Status = (int32_t)OCP_TL_MALLOC_FAILURE;
|
|
break;
|
|
}
|
|
/// @cond hidden
|
|
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
|
|
/// @endcond
|
|
|
|
PS_COMMS_HANDLE->wPort = PpsTL->wPort;
|
|
|
|
//Converting IP address from string format to hex format
|
|
i4Status = pal_socket_assign_ip_address(PpsTL->pzIpAddress,&(PS_COMMS_HANDLE->sIPAddress));
|
|
if(i4Status != E_COMMS_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//Assigning the timeout value
|
|
PS_COMMS_HANDLE->wTimeout = PpsTL->wTimeout ;
|
|
|
|
//Non Blockage receive mode
|
|
PS_COMMS_HANDLE->bMode = (uint8_t)PpsTL->eCallType;
|
|
|
|
//Add logging
|
|
LOG_TRANSPORTMSG("Initializing UDP Connection",eInfo);
|
|
|
|
//Initialize the communication handle with the parameters
|
|
i4Status = pal_socket_init(PS_COMMS_HANDLE);
|
|
if(E_COMMS_SUCCESS != i4Status)
|
|
{
|
|
break;
|
|
}
|
|
i4Status = (int32_t)OCP_TL_OK;
|
|
}while(FALSE);
|
|
if(OCP_TL_OK != i4Status)
|
|
{
|
|
if((NULL != PpsTL)&& (NULL != PpsTL->phTLHdl))
|
|
{
|
|
OCP_FREE(PpsTL->phTLHdl);
|
|
PpsTL->phTLHdl = NULL;
|
|
}
|
|
}
|
|
/// @cond hidden
|
|
#undef PS_COMMS_HANDLE
|
|
/// @endcond
|
|
return i4Status;
|
|
}
|
|
|
|
/**
|
|
* This API creates client port
|
|
*
|
|
* \param[in,out] PpsTL Pointer to the transport layer communication structure
|
|
*
|
|
* \return #OCP_TL_OK on successful execution
|
|
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
|
|
* \return #E_COMMS_UDP_BINDING_FAILURE on port binding failure
|
|
* \return #OCP_TL_ERROR on failure
|
|
*/
|
|
int32_t DtlsTL_Connect(sTL_d* PpsTL)
|
|
{
|
|
int32_t i4Status = (int32_t)OCP_TL_ERROR;
|
|
do
|
|
{
|
|
//NULL check
|
|
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl))
|
|
{
|
|
i4Status = (int32_t)OCP_TL_NULL_PARAM;
|
|
break;
|
|
}
|
|
/// @cond hidden
|
|
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
|
|
/// @endcond
|
|
//Logging
|
|
LOG_TRANSPORTMSG("Connecting to UDP",eInfo);
|
|
|
|
//Open the client port with the port number initialised
|
|
i4Status = pal_socket_connect(PS_COMMS_HANDLE, PS_COMMS_HANDLE->wPort);
|
|
if(E_COMMS_SUCCESS != i4Status)
|
|
{
|
|
LOG_TRANSPORTMSG("Error connecting to UDP",eError);
|
|
break;
|
|
}
|
|
|
|
PpsTL->eIsConnected = eConnected;
|
|
i4Status = (int32_t)OCP_TL_OK;
|
|
}while(FALSE);
|
|
/// @cond hidden
|
|
#undef PS_COMMS_HANDLE
|
|
/// @endcond
|
|
return i4Status;
|
|
}
|
|
|
|
/**
|
|
* This API transmits the data to the server.
|
|
*
|
|
* \param[in,out] PpsTL Pointer to the transport layer communication structure
|
|
* \param[in] PpbBuffer Pointer to buffer containing data to be transmitted
|
|
* \param[in] PdwLen Length of the data to be transmitted
|
|
*
|
|
* \return #OCP_TL_OK on successful execution
|
|
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
|
|
* \return #E_COMMS_UDP_NO_DATA_TO_SEND on no date present to send
|
|
* \return #E_COMMS_INSUFFICIENT_MEMORY on out of memory failure
|
|
* \return #E_COMMS_UDP_ROUTING_FAILURE on failure to route the UDP packet
|
|
* \return #E_COMMS_UDP_DEALLOCATION_FAILURE on failure to deallocate
|
|
* \return #OCP_TL_ERROR on failure
|
|
*/
|
|
int32_t DtlsTL_Send(const sTL_d* PpsTL,uint8_t* PpbBuffer,uint16_t PdwLen)
|
|
{
|
|
int32_t i4Status = (int32_t)OCP_TL_ERROR;
|
|
|
|
do
|
|
{
|
|
//NULL check
|
|
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl) ||(NULL == PpbBuffer))
|
|
{
|
|
i4Status = (int32_t)OCP_TL_NULL_PARAM;
|
|
break;
|
|
}
|
|
|
|
LOG_TRANSPORTDBARY("Sending Data over UDP", PpbBuffer, PdwLen, eInfo);
|
|
|
|
//Send the data over IP address and Port initialized
|
|
/// @cond hidden
|
|
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
|
|
/// @endcond
|
|
i4Status = pal_socket_send(PS_COMMS_HANDLE, PpbBuffer, PdwLen);
|
|
if (E_COMMS_SUCCESS != i4Status)
|
|
{
|
|
LOG_TRANSPORTMSG("Error while sending data",eError);
|
|
break;
|
|
}
|
|
i4Status = (int32_t)OCP_TL_OK;
|
|
}while(FALSE);
|
|
/// @cond hidden
|
|
#undef PS_COMMS_HANDLE
|
|
/// @endcond
|
|
return i4Status;
|
|
}
|
|
|
|
/**
|
|
* This API receives the data from the server
|
|
*
|
|
* \param[in] PpsTL Pointer to the transport layer communication structure
|
|
* \param[in,out] PpbBuffer Pointer to buffer where data is to be received
|
|
* \param[in,out] PpdwLen Length of the buffer/Length of the received data
|
|
*
|
|
* \return #OCP_TL_OK on successful execution
|
|
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
|
|
* \return #OCP_TL_NO_DATA on no data received from the target
|
|
* \return #E_COMMS_INSUFFICIENT_BUF_SIZE on insufficient buffer size
|
|
* \return #OCP_TL_ERROR on failure
|
|
*/
|
|
int32_t DtlsTL_Recv(const sTL_d* PpsTL,uint8_t* PpbBuffer,uint16_t* PpdwLen)
|
|
{
|
|
int32_t i4Status = (int32_t)OCP_TL_ERROR;
|
|
uint32_t dwRecvLen;
|
|
|
|
do
|
|
{
|
|
//NULL check
|
|
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl) || (NULL == PpbBuffer))
|
|
{
|
|
i4Status = (int32_t)OCP_TL_NULL_PARAM;
|
|
break;
|
|
}
|
|
//logging
|
|
LOG_TRANSPORTMSG("Receiving over UDP",eInfo);
|
|
/// @cond hidden
|
|
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
|
|
/// @endcond
|
|
|
|
PS_COMMS_HANDLE->wTimeout = PpsTL->wTimeout;
|
|
|
|
dwRecvLen = *PpdwLen;
|
|
|
|
//Listen the server port and receive the data
|
|
i4Status = pal_socket_listen(PS_COMMS_HANDLE, PpbBuffer, &dwRecvLen);
|
|
if ((int32_t)E_COMMS_UDP_NO_DATA_RECEIVED == i4Status)
|
|
{
|
|
i4Status = (int32_t)OCP_TL_NO_DATA;
|
|
LOG_TRANSPORTMSG("No data received over UDP",eError);
|
|
break;
|
|
}
|
|
|
|
if (E_COMMS_SUCCESS != i4Status)
|
|
{
|
|
LOG_TRANSPORTMSG("Error while receiving data over UDP",eError);
|
|
break;
|
|
}
|
|
|
|
LOG_TRANSPORTMSG("Received Data",eInfo);
|
|
LOG_TRANSPORTDBARY("Received Data over UDP", PpbBuffer, dwRecvLen, eInfo);
|
|
|
|
*PpdwLen = (uint16_t)dwRecvLen;
|
|
|
|
i4Status = (int32_t)OCP_TL_OK;
|
|
}while(FALSE);
|
|
/// @cond hidden
|
|
#undef PS_COMMS_HANDLE
|
|
/// @endcond
|
|
return i4Status;
|
|
}
|
|
|
|
/**
|
|
* This API closes the UDP communication and releases all the resources
|
|
*
|
|
* \param[in,out] PpsTL Pointer to the transport layer communication structure
|
|
*
|
|
* \return None
|
|
*/
|
|
Void DtlsTL_Disconnect(sTL_d* PpsTL)
|
|
{
|
|
|
|
//NULL check
|
|
if(NULL != PpsTL)
|
|
{
|
|
if(NULL != PpsTL->phTLHdl)
|
|
{
|
|
//logging
|
|
LOG_TRANSPORTMSG("Closing UDP Connection",eInfo);
|
|
/// @cond hidden
|
|
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
|
|
/// @endcond
|
|
|
|
//Close the UDP connection
|
|
pal_socket_close(PS_COMMS_HANDLE);
|
|
|
|
//Free the allocated memory for ethernet structure
|
|
OCP_FREE(PS_COMMS_HANDLE);
|
|
|
|
PpsTL->phTLHdl = NULL;
|
|
|
|
PpsTL->eIsConnected = eDisconnected;
|
|
/// @cond hidden
|
|
#undef PS_COMMS_HANDLE
|
|
/// @endcond
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/
|