FD_SET(caglobals.tcp.TYPE.fd, FDS); \
}
-/**
- * Read length amount of data from socket item->fd
- * Can read less data length then requested
- * Actual read length added to item->len variable
- *
- * @param[in/out] item - used socket, buffer and to update received message length
- * @param[in] length - length of data required to read
- * @param[in] flags - additional info about socket
- * @return - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CARecv(CATCPSessionInfo_t *item, size_t length, int flags)
-{
- if (NULL == item)
- {
- return CA_STATUS_INVALID_PARAM;
- }
-
- //skip read operation if requested zero length
- if (0 == length)
- {
- return CA_STATUS_OK;
- }
-
- unsigned char *buffer = item->data + item->len;
-
- int len = recv(item->fd, buffer, length, flags);
-
- if (len < 0)
- {
- OIC_LOG_V(ERROR, TAG, "recv failed %s", strerror(errno));
- return CA_RECEIVE_FAILED;
- }
- else if (0 == len)
- {
- OIC_LOG(INFO, TAG, "Received disconnect from peer. Close connection");
- item->state = DISCONNECTED;
- return CA_DESTINATION_DISCONNECTED;
- }
-
- OIC_LOG_V(DEBUG, TAG, "recv len = %d", len);
- OIC_LOG_BUFFER(DEBUG, TAG, buffer, len);
-
- item->len += len;
-
- return CA_STATUS_OK;
-}
-
static void CATCPDestroyMutex()
{
if (g_mutexObjectList)
return CA_STATUS_OK;
}
-/**
- * Read message header from socket item->fd
- *
- * @param[in/out] item - used socket, buffer, current received message length and protocol
- * @return - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CAReadHeader(CATCPSessionInfo_t *svritem)
-{
- CAResult_t res = CA_STATUS_OK;
-
- if (NULL == svritem)
- {
- return CA_STATUS_INVALID_PARAM;
- }
-
- if (NULL == svritem->data)
- {
- // allocate memory for message header (CoAP header size because it is bigger)
- svritem->data = (unsigned char *) OICCalloc(1, COAP_MAX_HEADER_SIZE);
- if (NULL == svritem->data)
- {
- OIC_LOG(ERROR, TAG, "OICCalloc - out of memory");
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-
- //read data (assume TLS header) from remote device.
- //use TLS_HEADER_SIZE - svritem->len because even header can be read partially
- res = CARecv(svritem, TLS_HEADER_SIZE - svritem->len, 0);
-
- //return if any error occurs
- if (CA_STATUS_OK != res)
- {
- return res;
- }
-
- //if not enough data received - read them on next CAReceiveMessage() call
- if (svritem->len < TLS_HEADER_SIZE)
- {
- OIC_LOG(DEBUG, TAG, "Header received partially. Wait for rest header data");
- return CA_STATUS_OK;
- }
-
- //if enough data received - parse header
-#ifdef __WITH_TLS__
- if (CAIsTlsMessage(svritem->data, svritem->len))
- {
- svritem->protocol = TLS;
-
- //[3][4] bytes in tls header are tls payload length
- unsigned int message_length = (unsigned int)((svritem->data[3] << 8) | svritem->data[4]);
- OIC_LOG_V(DEBUG, TAG, "%s: message_length = %d", __func__, message_length);
-
- svritem->totalLen = message_length + TLS_HEADER_SIZE;
- }
- else
-#endif
- {
- svritem->protocol = COAP;
-
- //seems CoAP data received. read full coap header.
- coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(svritem->data[0] >> 4);
-
- size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
-
- if (svritem->len < headerLen)
- {
- //read required bytes to have full CoAP header
- //it should be 1 byte (COAP_MAX_HEADER_SIZE - TLS_HEADER_SIZE)
- res = CARecv(svritem, headerLen - svritem->len, 0);
-
- //return if any error occurs
- if (CA_STATUS_OK != res)
- {
- return res;
- }
-
- //if not enough data received - read them on next CAReceiveMessage() call
- if (svritem->len < headerLen)
- {
- OIC_LOG(DEBUG, TAG, "CoAP header received partially. Wait for rest header data");
- return CA_STATUS_OK;
- }
- }
-
- //calculate CoAP message length
- svritem->totalLen = CAGetTotalLengthFromHeader(svritem->data);
- }
-
- unsigned char *buffer = OICRealloc(svritem->data, svritem->totalLen);
- if (NULL == buffer)
- {
- OIC_LOG(ERROR, TAG, "OICRealloc - out of memory");
- return CA_MEMORY_ALLOC_FAILED;
- }
- svritem->data = buffer;
-
- return CA_STATUS_OK;
-}
-
-/**
- * Read message payload from socket item->fd
-
- *
- * @param[in/out] item - used socket, buffer and to update received message length
- * @return - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CAReadPayload(CATCPSessionInfo_t *svritem)
-{
- if (NULL == svritem)
- {
- return CA_STATUS_INVALID_PARAM;
- }
-
- return CARecv(svritem, svritem->totalLen - svritem->len, 0);
-}
-
-/**
- * Pass received data to app layer depending on protocol
- *
- * @param[in/out] item - used buffer, received message length and protocol
- */
-static void CAExecuteRequest(CATCPSessionInfo_t *svritem)
-{
- if (NULL == svritem)
- {
- return;
- }
-
- switch(svritem->protocol)
- {
- case COAP:
- {
- if (g_packetReceivedCallback)
- {
- g_packetReceivedCallback(&svritem->sep, svritem->data, svritem->len);
- }
- }
- break;
- case TLS:
-#ifdef __WITH_TLS__
- {
- int ret = CAdecryptSsl(&svritem->sep, (uint8_t *)svritem->data, svritem->len);
-
- OIC_LOG_V(DEBUG, TAG, "%s: CAdecryptSsl returned %d", __func__, ret);
- }
- break;
-#endif
- case UNKNOWN: /* pass through */
- default:
- OIC_LOG(ERROR, TAG, "unknown application protocol. Ignore it");
- break;
- }
-}
-
static void CAReceiveMessage(int fd)
{
CAResult_t res = CA_STATUS_OK;