Exemplo n.º 1
0
static void CAReceiveMessage(int fd)
{
    // #1. get remote device information from file descriptor.
    size_t index = 0;
    CATCPSessionInfo_t *svritem = CAGetSessionInfoFromFD(fd, &index);
    if (!svritem)
    {
        OIC_LOG(ERROR, TAG, "there is no connection information in list");
        return;
    }

    // #2. get already allocated memory size.
    size_t bufSize = (svritem->totalDataLen == 0) ? TCP_MAX_HEADER_LEN : svritem->totalDataLen;
    if (!svritem->recvData)
    {
        svritem->recvData = (unsigned char *) OICCalloc(1, bufSize);
        if (!svritem->recvData)
        {
            OIC_LOG(ERROR, TAG, "out of memory");
            CADisconnectTCPSession(svritem, index);
            return;
        }
    }

    // #3. receive data from remote device.
    ssize_t recvLen = recv(fd, svritem->recvData + svritem->recvDataLen,
                           bufSize - svritem->recvDataLen, 0);
    if (recvLen <= 0)
    {
        if(EWOULDBLOCK != errno)
        {
            OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
            CADisconnectTCPSession(svritem, index);
        }
        return;
    }
    svritem->recvDataLen += recvLen;

    // #4. get actual data length from coap over tcp header.
    if (!svritem->totalDataLen)
    {
        coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
                ((unsigned char *) svritem->recvData)[0] >> 4);

        size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
        if (svritem->recvDataLen >= headerLen)
        {
            svritem->totalDataLen = CAGetTotalLengthFromHeader(
                    (unsigned char *) svritem->recvData);
            bufSize = svritem->totalDataLen;
            unsigned char *newBuf = OICRealloc(svritem->recvData, bufSize);
            if (!newBuf)
            {
                OIC_LOG(ERROR, TAG, "out of memory");
                CADisconnectTCPSession(svritem, index);
                return;
            }
            svritem->recvData = newBuf;
        }
    }
Exemplo n.º 2
0
static CAResult_t CAReceiveMessage()
{
    uint32_t length = u_arraylist_length(caglobals.tcp.svrlist);

    size_t i = 0;
    unsigned char *recvBuffer = NULL;
    CATCPServerInfo_t *svritem = NULL;
    for (i = 0; i < length; i++)
    {
        svritem = (CATCPServerInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i);
        if (svritem->u4tcp.fd < 0)
        {
            continue;
        }

        size_t bufSize = TCP_MAX_HEADER_LEN;
        recvBuffer = (unsigned char *) OICCalloc(1, bufSize);
        if (!recvBuffer)
        {
            OIC_LOG(ERROR, TAG, "out of memory");
            goto exit;
        }

        bool isHeaderChecked = false;
        size_t totalLen = 0;
        size_t totalReceivedLen = 0;
        do
        {
            ssize_t recvLen = recv(svritem->u4tcp.fd, recvBuffer + totalReceivedLen,
                                   bufSize - totalReceivedLen, 0);
            if (recvLen <= 0)
            {
                if(EWOULDBLOCK != errno)
                {
                    OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
                    goto exit;
                }
                // if received data length is zero, we are breaking loop.
                // because we use non-blocking socket to receive data from remote device.
                if (!totalReceivedLen)
                {
                    break;
                }
                continue;
            }

            totalReceivedLen += recvLen;
            if (!isHeaderChecked && totalReceivedLen)
            {
                coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
                        ((unsigned char *)recvBuffer)[0] >> 4);
                size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
                if (totalReceivedLen >= headerLen)
                {
                    // get actual data length from coap over tcp header
                    totalLen = CAGetTotalLengthFromHeader((unsigned char *) recvBuffer);
                    bufSize = totalLen;
                    unsigned char *newBuf = OICRealloc(recvBuffer, bufSize);
                    if (NULL == newBuf)
                    {
                        OIC_LOG(ERROR, TAG, "out of memory");
                        goto exit;
                    }
                    recvBuffer = newBuf;
                    isHeaderChecked = true;
                }
            }
            if (totalLen == totalReceivedLen)
            {
                CAEndpoint_t ep = { .adapter = CA_ADAPTER_TCP,
                                    .port = svritem->u4tcp.port };
                strncpy(ep.addr, svritem->addr, sizeof(ep.addr));

                if (g_packetReceivedCallback)
                {
                    g_packetReceivedCallback(&ep, recvBuffer, totalLen);
                }
                OIC_LOG_V(DEBUG, TAG, "received data len:%d", totalLen);
                break;
            }
        } while (!totalLen || totalLen > totalReceivedLen);

        OICFree(recvBuffer);
    }