ARNETWORK_Receiver_t* ARNETWORK_Receiver_New (ARNETWORKAL_Manager_t *networkALManager, unsigned int numberOfOutputBuff, ARNETWORK_IOBuffer_t **outputBufferPtrArr, ARNETWORK_IOBuffer_t **outputBufferPtrMap)
{
    /** -- Create a new receiver -- */

    /** local declarations */
    ARNETWORK_Receiver_t *receiverPtr = NULL;
    eARNETWORK_ERROR error = ARNETWORK_OK;

    /** Create the receiver */
    receiverPtr =  malloc (sizeof (ARNETWORK_Receiver_t));

    if (receiverPtr)
    {
        if(networkALManager != NULL)
        {
            receiverPtr->networkALManager = networkALManager;
        }
        else
        {
            error = ARNETWORK_ERROR_BAD_PARAMETER;
        }

        if(error == ARNETWORK_OK)
        {
            receiverPtr->isAlive = 1;
            receiverPtr->senderPtr = NULL;

            receiverPtr->numberOfOutputBuff = numberOfOutputBuff;
            receiverPtr->outputBufferPtrArr = outputBufferPtrArr;

            receiverPtr->outputBufferPtrMap = outputBufferPtrMap;
#ifdef ENABLE_MONITOR_INCOMING_DATA
            receiverPtr->inputEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
#endif
        }

        /** delete the receiver if an error occurred */
        if (error != ARNETWORK_OK)
        {
            ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_RECEIVER_TAG,"error: %s", ARNETWORK_Error_ToString (error));
            ARNETWORK_Receiver_Delete (&receiverPtr);
        }
    }

    return receiverPtr;
}
Example #2
0
void* ARSTREAM_Reader_RunDataThread (void *ARSTREAM_Reader_t_Param)
{
    uint8_t *recvData = NULL;
    int recvSize;
    uint16_t previousFNum = UINT16_MAX;
    int skipCurrentFrame = 0;
    int packetWasAlreadyAck = 0;
    ARSTREAM_Reader_t *reader = (ARSTREAM_Reader_t *)ARSTREAM_Reader_t_Param;
    ARSTREAM_NetworkHeaders_DataHeader_t *header = NULL;
    int recvDataLen = reader->maxFragmentSize + sizeof (ARSTREAM_NetworkHeaders_DataHeader_t);

    /* Parameters check */
    if (reader == NULL)
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while starting %s, bad parameters", __FUNCTION__);
        return (void *)0;
    }

    /* Alloc and check */
    recvData = malloc (recvDataLen);
    if (recvData == NULL)
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while starting %s, can not alloc memory", __FUNCTION__);
        return (void *)0;
    }
    header = (ARSTREAM_NetworkHeaders_DataHeader_t *)recvData;

    ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Stream reader thread running");
    reader->dataThreadStarted = 1;

    while (reader->threadsShouldStop == 0)
    {
        eARNETWORK_ERROR err = ARNETWORK_Manager_ReadDataWithTimeout (reader->manager, reader->dataBufferID, recvData, recvDataLen, &recvSize, ARSTREAM_READER_DATAREAD_TIMEOUT_MS);
        if (ARNETWORK_OK != err)
        {
            if (ARNETWORK_ERROR_BUFFER_EMPTY != err)
            {
                ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while reading stream data: %s", ARNETWORK_Error_ToString (err));
            }
        }
        else
        {
            int cpIndex, cpSize, endIndex;
            ARSAL_Mutex_Lock (&(reader->ackPacketMutex));
            if (header->frameNumber != reader->ackPacket.frameNumber)
            {
                reader->efficiency_index ++;
                reader->efficiency_index %= ARSTREAM_READER_EFFICIENCY_AVERAGE_NB_FRAMES;
                reader->efficiency_nbTotal [reader->efficiency_index] = 0;
                reader->efficiency_nbUseful [reader->efficiency_index] = 0;
                skipCurrentFrame = 0;
                reader->currentFrameSize = 0;
                reader->ackPacket.frameNumber = header->frameNumber;
#ifdef DEBUG
                uint32_t nackPackets = ARSTREAM_NetworkHeaders_AckPacketCountNotSet (&(reader->ackPacket), header->fragmentsPerFrame);
                if (nackPackets != 0)
                {
                    ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Dropping a frame (missing %d fragments)", nackPackets);
                }
#endif
                ARSTREAM_NetworkHeaders_AckPacketResetUpTo (&(reader->ackPacket), header->fragmentsPerFrame);
            }
            packetWasAlreadyAck = ARSTREAM_NetworkHeaders_AckPacketFlagIsSet (&(reader->ackPacket), header->fragmentNumber);
            ARSTREAM_NetworkHeaders_AckPacketSetFlag (&(reader->ackPacket), header->fragmentNumber);

            reader->efficiency_nbTotal [reader->efficiency_index] ++;
            if (packetWasAlreadyAck == 0)
            {
                reader->efficiency_nbUseful [reader->efficiency_index] ++;
            }

            ARSAL_Mutex_Unlock (&(reader->ackPacketMutex));

            ARSAL_Mutex_Lock (&(reader->ackSendMutex));
            ARSAL_Cond_Signal (&(reader->ackSendCond));
            ARSAL_Mutex_Unlock (&(reader->ackSendMutex));


            cpIndex = reader->maxFragmentSize * header->fragmentNumber;
            cpSize = recvSize - sizeof (ARSTREAM_NetworkHeaders_DataHeader_t);
            endIndex = cpIndex + cpSize;
            while ((endIndex > reader->currentFrameBufferSize) &&
                   (skipCurrentFrame == 0) &&
                   (packetWasAlreadyAck == 0))
            {
                uint32_t nextFrameBufferSize = reader->maxFragmentSize * header->fragmentsPerFrame;
                uint32_t dummy;
                uint8_t *nextFrameBuffer = reader->callback (ARSTREAM_READER_CAUSE_FRAME_TOO_SMALL, reader->currentFrameBuffer, reader->currentFrameSize, 0, 0, &nextFrameBufferSize, reader->custom);
                if (nextFrameBufferSize >= reader->currentFrameSize && nextFrameBufferSize > 0)
                {
                    memcpy (nextFrameBuffer, reader->currentFrameBuffer, reader->currentFrameSize);
                }
                else
                {
                    skipCurrentFrame = 1;
                }
                //TODO: Add "SKIP_FRAME"
                reader->callback (ARSTREAM_READER_CAUSE_COPY_COMPLETE, reader->currentFrameBuffer, reader->currentFrameSize, 0, skipCurrentFrame, &dummy, reader->custom);
                reader->currentFrameBuffer = nextFrameBuffer;
                reader->currentFrameBufferSize = nextFrameBufferSize;
            }

            if (skipCurrentFrame == 0)
            {
                if (packetWasAlreadyAck == 0)
                {
                    memcpy (&(reader->currentFrameBuffer)[cpIndex], &recvData[sizeof (ARSTREAM_NetworkHeaders_DataHeader_t)], recvSize - sizeof (ARSTREAM_NetworkHeaders_DataHeader_t));
                }

                if (endIndex > reader->currentFrameSize)
                {
                    reader->currentFrameSize = endIndex;
                }

                ARSAL_Mutex_Lock (&(reader->ackPacketMutex));
                if (ARSTREAM_NetworkHeaders_AckPacketAllFlagsSet (&(reader->ackPacket), header->fragmentsPerFrame))
                {
                    if (header->frameNumber != previousFNum)
                    {
                        int nbMissedFrame = 0;
                        int isFlushFrame = ((header->frameFlags & ARSTREAM_NETWORK_HEADERS_FLAG_FLUSH_FRAME) != 0) ? 1 : 0;
                        ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Ack all in frame %d (isFlush : %d)", header->frameNumber, isFlushFrame);
                        if (header->frameNumber != previousFNum + 1)
                        {
                            nbMissedFrame = header->frameNumber - previousFNum - 1;
                            ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Missed %d frames !", nbMissedFrame);
                        }
                        previousFNum = header->frameNumber;
                        skipCurrentFrame = 1;
                        reader->currentFrameBuffer = reader->callback (ARSTREAM_READER_CAUSE_FRAME_COMPLETE, reader->currentFrameBuffer, reader->currentFrameSize, nbMissedFrame, isFlushFrame, &(reader->currentFrameBufferSize), reader->custom);
                    }
                }
                ARSAL_Mutex_Unlock (&(reader->ackPacketMutex));
            }
        }
    }

    free (recvData);

    reader->callback (ARSTREAM_READER_CAUSE_CANCEL, reader->currentFrameBuffer, reader->currentFrameSize, 0, 0, &(reader->currentFrameBufferSize), reader->custom);

    ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Stream reader thread ended");
    reader->dataThreadStarted = 0;
    return (void *)0;
}
void *ARCONTROLLER_Network_ReaderRun (void *data)
{
    // -- Read and decode one input network buffer --
    
    eARCONTROLLER_ERROR error = ARCONTROLLER_OK;
    
    ARCONTROLLER_Network_t *networkController = NULL;
    int readerBufferId = -1;
    
    // Allocate some space for incoming data.
    const size_t maxLength = 128 * 1024;
    void *readData = malloc (maxLength);
    if (readData == NULL)
    {
        error = ARCONTROLLER_ERROR_ALLOC;
    }
    
    if (error == ARCONTROLLER_OK)
    {
        if (data != NULL)
        {
            //get thread data
            networkController = ((ARCONTROLLER_NETWORK_THREAD_DATA_t *) data)->networkController;
            readerBufferId = ((ARCONTROLLER_NETWORK_THREAD_DATA_t *) data)->readerBufferId;
            
            if (networkController == NULL)
            {
                error = ARCONTROLLER_ERROR_BAD_PARAMETER;
            }
        }
        else
        {
            error = ARCONTROLLER_ERROR_BAD_PARAMETER;
        }
    }
    
    if (error == ARCONTROLLER_OK)
    {
        while (networkController->state != ARCONTROLLER_NETWORK_STATE_STOPPED)
        {
            if (networkController->state == ARCONTROLLER_NETWORK_STATE_RUNNING)
            {
                eARNETWORK_ERROR netError = ARNETWORK_OK;
                int length = 0;
                int skip = 0;
                
                //read data
                netError = ARNETWORK_Manager_ReadDataWithTimeout (networkController->networkManager, readerBufferId, readData, maxLength, &length, ARCONTROLLER_NETWORK_READING_TIMEOUT_MS);
                if (netError != ARNETWORK_OK)
                {
                    if (netError != ARNETWORK_ERROR_BUFFER_EMPTY)
                    {
                        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "ARNETWORK_Manager_ReadDataWithTimeout () failed : %s", ARNETWORK_Error_ToString(netError));
                    }
                    skip = 1;
                }
                
                if (!skip)
                {
                    // Forward data to the CommandsManager
                    eARCOMMANDS_DECODER_ERROR cmdError = ARCOMMANDS_DECODER_OK;
                    cmdError = ARCOMMANDS_Decoder_DecodeBuffer ((uint8_t *)readData, length);
                    if ((cmdError != ARCOMMANDS_DECODER_OK) && (cmdError != ARCOMMANDS_DECODER_ERROR_NO_CALLBACK))
                    {
                        char msg[128];
                        ARCOMMANDS_Decoder_DescribeBuffer ((uint8_t *)readData, length, msg, sizeof(msg));
                        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "ARCOMMANDS_Decoder_DecodeBuffer () failed : %d %s", cmdError, msg);
                    }
                }
                //NO ELSE ; no data read
            }
            else
            {
                //sleep
                sleep (1); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! replace by signal 
            }
        }
    }
    
    // Print Error
    if (error != ARCONTROLLER_OK)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "error: %s", ARCONTROLLER_Error_ToString (error));
    }
    
    // cleanup
    if (readData != NULL)
    {
        free (readData);
        readData = NULL;
    }
    
    return NULL;
}
int ARSTREAM_Reader_TestBenchMain (int argc, char *argv[])
{
    int retVal = 0;
    appName = argv[0];
    if (argc > 3)
    {
        ARSTREAM_ReaderTb_printUsage ();
        return 1;
    }

    char *ip = __IP;
    char *outPath = NULL;

    if (argc >= 2)
    {
        ip = argv[1];
    }
    if (argc >= 3)
    {
        outPath = argv[2];
    }

    ARSAL_PRINT (ARSAL_PRINT_WARNING, __TAG__, "IP = %s", ip);

    int nbInBuff = 1;
    ARNETWORK_IOBufferParam_t inParams;
    ARSTREAM_Reader_InitStreamAckBuffer (&inParams, ACK_BUFFER_ID);
    int nbOutBuff = 1;
    ARNETWORK_IOBufferParam_t outParams;
    ARSTREAM_Reader_InitStreamDataBuffer (&outParams, DATA_BUFFER_ID, ARSTREAM_TB_FRAG_SIZE, ARSTREAM_TB_MAX_NB_FRAG);

    eARNETWORK_ERROR error;
    eARNETWORKAL_ERROR specificError = ARNETWORKAL_OK;
    ARNETWORKAL_Manager_t *osspecificManagerPtr = ARNETWORKAL_Manager_New(&specificError);

    if(specificError == ARNETWORKAL_OK)
    {
        specificError = ARNETWORKAL_Manager_InitWifiNetwork(osspecificManagerPtr, ip, SENDING_PORT, READING_PORT, 1000);
    }
    else
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, __TAG__, "Error during ARNETWORKAL_Manager_New call : %s", ARNETWORKAL_Error_ToString(specificError));
    }

    if(specificError == ARNETWORKAL_OK)
    {
        g_Manager = ARNETWORK_Manager_New(osspecificManagerPtr, nbInBuff, &inParams, nbOutBuff, &outParams, READER_PING_DELAY, NULL, NULL, &error);
    }
    else
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, __TAG__, "Error during ARNETWORKAL_Manager_InitWifiNetwork call : %s", ARNETWORKAL_Error_ToString(specificError));
        error = ARNETWORK_ERROR;
    }

    if ((g_Manager == NULL) ||
        (error != ARNETWORK_OK))
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, __TAG__, "Error during ARNETWORK_Manager_New call : %s", ARNETWORK_Error_ToString(error));
        return 1;
    }

    pthread_t netsend, netread;
    pthread_create (&netsend, NULL, ARNETWORK_Manager_SendingThreadRun, g_Manager);
    pthread_create (&netread, NULL, ARNETWORK_Manager_ReceivingThreadRun, g_Manager);

    retVal = ARSTREAM_ReaderTb_StartStreamTest (g_Manager, outPath);

    ARNETWORK_Manager_Stop (g_Manager);

    pthread_join (netread, NULL);
    pthread_join (netsend, NULL);

    ARNETWORK_Manager_Delete (&g_Manager);
    ARNETWORKAL_Manager_CloseWifiNetwork(osspecificManagerPtr);
    ARNETWORKAL_Manager_Delete(&osspecificManagerPtr);

    return retVal;
}
void* ARNETWORK_Receiver_ThreadRun (void *data)
{
    /** -- Manage the reception of the data on the Receiver' socket. -- */

    /** local declarations */
    ARNETWORK_Receiver_t *receiverPtr = data;
    ARNETWORKAL_Frame_t frame ;
    ARNETWORK_IOBuffer_t* outBufferPtrTemp = NULL;
    eARNETWORK_ERROR error = ARNETWORK_OK;
    eARNETWORKAL_MANAGER_RETURN result = ARNETWORKAL_MANAGER_RETURN_DEFAULT;
    uint8_t ackSeqNumData = 0;
    struct timespec now;

    while (receiverPtr->isAlive)
    {
        /** wait a receipt */
        if (receiverPtr->networkALManager->receive(receiverPtr->networkALManager) == ARNETWORKAL_MANAGER_RETURN_DEFAULT)
        {
            /** for each frame present in the receiver buffer */
            result = receiverPtr->networkALManager->popFrame(receiverPtr->networkALManager, &frame);
            while (result == ARNETWORKAL_MANAGER_RETURN_DEFAULT)
            {
                /* Special handling of internal frames */
                if (frame.id < ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_MAX)
                {
                    switch (frame.id)
                    {
                    case ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PING:
                        /* Ping, send the corresponding pong */
                    {
                        ARNETWORK_Sender_SendPong (receiverPtr->senderPtr, frame.dataPtr, frame.size - offsetof(ARNETWORKAL_Frame_t, dataPtr));
                    }
                    break;
                    case ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PONG:
                        /* Pong, tells the sender that we got a response */
                    {
                        struct timespec dataTime;
                        memcpy (&dataTime, frame.dataPtr, sizeof (struct timespec));
                        ARSAL_Time_GetTime(&now);
                        ARNETWORK_Sender_GotPingAck (receiverPtr->senderPtr, &dataTime, &now);
                    }
                    break;
                    default:
                        /* Do nothing as we don't know how to handle it */
                        break;
                    }
                }

                /** management by the command type */
                switch (frame.type)
                {
                case ARNETWORKAL_FRAME_TYPE_ACK:

                    /** get the acknowledge sequence number from the data */
                    memcpy (&ackSeqNumData, frame.dataPtr, sizeof(uint8_t));
                    ARSAL_PRINT (ARSAL_PRINT_VERBOSE, ARNETWORK_RECEIVER_TAG, "[%p] - TYPE: ARNETWORKAL_FRAME_TYPE_ACK | SEQ:%d | ID:%d | SEQ ACK : %d", receiverPtr, receiverPtr, frame.seq, frame.id, ackSeqNumData);
                    /** transmit the acknowledgement to the sender */
                    error = ARNETWORK_Sender_AckReceived (receiverPtr->senderPtr, ARNETWORK_Manager_IDAckToIDInput (receiverPtr->networkALManager, frame.id), ackSeqNumData);
                    if (error != ARNETWORK_OK)
                    {
                        switch (error)
                        {
                        case ARNETWORK_ERROR_IOBUFFER_BAD_ACK:
                            ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARNETWORK_RECEIVER_TAG, "[%p] Bad acknowledge, error: %s", receiverPtr, ARNETWORK_Error_ToString (error));
                            break;

                        default:
                            ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_RECEIVER_TAG, "[%p] Acknowledge received, error: %s", receiverPtr, ARNETWORK_Error_ToString (error));
                            break;
                        }
                    }
                    break;

                case ARNETWORKAL_FRAME_TYPE_DATA:
                    ARSAL_PRINT (ARSAL_PRINT_VERBOSE, ARNETWORK_RECEIVER_TAG, "[%p] - TYPE: ARNETWORKAL_FRAME_TYPE_DATA | SEQ:%d | ID:%d", receiverPtr, frame.seq, frame.id);

                    /** push the data received in the output buffer targeted */
                    outBufferPtrTemp = receiverPtr->outputBufferPtrMap[frame.id];

                    if (outBufferPtrTemp != NULL)
                    {
                        /** lock the IOBuffer */
                        error = ARNETWORK_IOBuffer_Lock(outBufferPtrTemp);
                        if(error == ARNETWORK_OK)
                        {
                            int accept = ARNETWORK_IOBuffer_ShouldAcceptData (outBufferPtrTemp, frame.seq);
                            if (accept > 0)
                            {
                                error = ARNETWORK_Receiver_CopyDataRecv(receiverPtr, outBufferPtrTemp, &frame);
                            }
                            else if (accept == 0)
                            {
                                ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARNETWORK_RECEIVER_TAG, "[%p] Received a retry for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }
                            else
                            {
                                ARSAL_PRINT (ARSAL_PRINT_WARNING, ARNETWORK_RECEIVER_TAG, "[%p] Received an old frame for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }

                            /** unlock the IOBuffer */
                            ARNETWORK_IOBuffer_Unlock(outBufferPtrTemp);

                            if(error != ARNETWORK_OK)
                            {
                                ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_RECEIVER_TAG, "[%p] data received, error: %s", receiverPtr, ARNETWORK_Error_ToString (error));
                            }
                        }
                    }
                    break;

                case ARNETWORKAL_FRAME_TYPE_DATA_LOW_LATENCY:
                    ARSAL_PRINT (ARSAL_PRINT_VERBOSE, ARNETWORK_RECEIVER_TAG, "[%p] - TYPE: ARNETWORKAL_FRAME_TYPE_DATA_LOW_LATENCY | SEQ:%d | ID:%d", receiverPtr, frame.seq, frame.id);

                    /** push the data received in the output buffer targeted */
                    outBufferPtrTemp = receiverPtr->outputBufferPtrMap[frame.id];

                    if (outBufferPtrTemp != NULL)
                    {
                        /** lock the IOBuffer */
                        error = ARNETWORK_IOBuffer_Lock(outBufferPtrTemp);
                        if(error == ARNETWORK_OK)
                        {
                            int accept = ARNETWORK_IOBuffer_ShouldAcceptData (outBufferPtrTemp, frame.seq);
                            if (accept > 0)
                            {
                                error = ARNETWORK_Receiver_CopyDataRecv(receiverPtr, outBufferPtrTemp, &frame);
                            }
                            else if (accept == 0)
                            {
                                ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARNETWORK_RECEIVER_TAG, "[%p] Received a retry for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }
                            else
                            {
                                ARSAL_PRINT (ARSAL_PRINT_WARNING, ARNETWORK_RECEIVER_TAG, "[%p] Received an old frame for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }

                            /** unlock the IOBuffer */
                            ARNETWORK_IOBuffer_Unlock(outBufferPtrTemp);

                            if(error != ARNETWORK_OK)
                            {
                                ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_RECEIVER_TAG, "[%p] data received, error: %s", receiverPtr, ARNETWORK_Error_ToString (error));
                            }
                        }
                    }
                    break;

                case ARNETWORKAL_FRAME_TYPE_DATA_WITH_ACK:
                    ARSAL_PRINT (ARSAL_PRINT_VERBOSE, ARNETWORK_RECEIVER_TAG, "[%p] - TYPE: ARNETWORKAL_FRAME_TYPE_DATA_WITH_ACK | SEQ:%d | ID:%d", receiverPtr, frame.seq, frame.id);
                    /**
                     * push the data received in the output buffer targeted,
                     * save the sequence of the command and return an acknowledgement
                     */
                    outBufferPtrTemp = receiverPtr->outputBufferPtrMap[frame.id];

                    if (outBufferPtrTemp != NULL)
                    {
                        /** lock the IOBuffer */
                        error = ARNETWORK_IOBuffer_Lock(outBufferPtrTemp);
                        if(error == ARNETWORK_OK)
                        {
                            /** OutBuffer->seqWaitAck used to save the last seq */
                            int accept = ARNETWORK_IOBuffer_ShouldAcceptData (outBufferPtrTemp, frame.seq);
                            if (accept > 0)
                            {
                                error = ARNETWORK_Receiver_CopyDataRecv(receiverPtr, outBufferPtrTemp, &frame);
                            }
                            else if (accept == 0)
                            {
                                ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARNETWORK_RECEIVER_TAG, "[%p] Received a retry for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }
                            else
                            {
                                ARSAL_PRINT (ARSAL_PRINT_WARNING, ARNETWORK_RECEIVER_TAG, "[%p] Received an old frame for buffer %d", receiverPtr, outBufferPtrTemp->ID);
                            }

                            /** unlock the IOBuffer */
                            ARNETWORK_IOBuffer_Unlock(outBufferPtrTemp);

                            // data are copied to the IOBuffer, send ACK
                            if (error == ARNETWORK_OK)
                            {
                                 /** sending ack even if the seq is not correct */
                                 error = ARNETWORK_Receiver_ReturnACK(receiverPtr, frame.id, frame.seq);
                                 if(error != ARNETWORK_OK)
                                 {
                                     int level = ARSAL_PRINT_ERROR;
                                     if (error == ARNETWORK_ERROR_BUFFER_SIZE)
                                     {
                                         level = ARSAL_PRINT_DEBUG;
                                     }
                                     ARSAL_PRINT(level, ARNETWORK_RECEIVER_TAG, "[%p] ReturnACK, error: %s", receiverPtr, ARNETWORK_Error_ToString(error));
                                 }
                            }
                            else
                            {
                                ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_RECEIVER_TAG, "[%p] data with ack received, error: %s", receiverPtr, ARNETWORK_Error_ToString (error));
                            }
                        }
                    }
                    break;

                default:
                    ARSAL_PRINT (ARSAL_PRINT_WARNING, ARNETWORK_RECEIVER_TAG, "[%p] !!! command type: %d not known  !!!", receiverPtr, frame.type);
                    break;
                }

                /** get the next frame*/
                result = receiverPtr->networkALManager->popFrame(receiverPtr->networkALManager, &frame);
            }
        }
    }

    return NULL;
}
void ARNETWORK_Sender_SendPong (ARNETWORK_Sender_t *senderPtr, uint8_t *data, int dataSize)
{
    ARNETWORK_IOBuffer_t *inputBufferPtrTemp;
    eARNETWORK_ERROR err = ARNETWORK_OK;
    inputBufferPtrTemp = senderPtr->inputBufferPtrMap[ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PONG];
    err = ARNETWORK_IOBuffer_Lock (inputBufferPtrTemp);
    if (err != ARNETWORK_OK) {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_SENDER_TAG, "ARNETWORK_IOBuffer_Lock() failed; error: %s", ARNETWORK_Error_ToString (err));
        return;
    }

    ARNETWORK_IOBuffer_AddData (inputBufferPtrTemp, data, dataSize, NULL, NULL, 1);
    ARNETWORK_IOBuffer_Unlock (inputBufferPtrTemp);
}
void* ARNETWORK_Sender_ThreadRun (void* data)
{
    /** -- Manage the sending of the data on the sender' -- */

    /** local declarations */
    ARNETWORK_Sender_t *senderPtr = data;
    int inputBufferIndex = 0;
    ARNETWORK_IOBuffer_t *inputBufferPtrTemp = NULL; /**< pointer of the input buffer in processing */
    eARNETWORK_ERROR error = ARNETWORK_OK;
    int waitTimeMs = 0;
    struct timespec now;
    struct timespec sleepStart;
    int sleepDurationMs = 0;
    int timeDiffMs;

    while (senderPtr->isAlive)
    {
        waitTimeMs = 500;
        for (inputBufferIndex = 0; inputBufferIndex < senderPtr->numberOfInputBuff && waitTimeMs > 0; ++inputBufferIndex)
        {
            inputBufferPtrTemp = senderPtr->inputBufferPtrArr[inputBufferIndex];
            error = ARNETWORK_IOBuffer_Lock(inputBufferPtrTemp);
            switch (inputBufferPtrTemp->dataType)
            {
                // Low latency : no wait if any data available
            case ARNETWORKAL_FRAME_TYPE_DATA_LOW_LATENCY:
                if ((error == ARNETWORK_OK) &&
                    (!ARNETWORK_RingBuffer_IsEmpty (inputBufferPtrTemp->dataDescriptorRBuffer)))
                {
                    waitTimeMs = 0;
                }
                break;
                // Acknowledged buffer :
                //  - If waiting an ack, wait time = time before ack timeout
                //  - If not waiting an ack and not empty, wait time = time before next send
            case ARNETWORKAL_FRAME_TYPE_DATA_WITH_ACK:
                if (error == ARNETWORK_OK)
                {
                    if (ARNETWORK_IOBuffer_IsWaitAck(inputBufferPtrTemp))
                    {
                        if (inputBufferPtrTemp->ackWaitTimeCount < waitTimeMs)
                        {
                            waitTimeMs = inputBufferPtrTemp->ackWaitTimeCount;
                        }
                    }
                    else if (!ARNETWORK_RingBuffer_IsEmpty (inputBufferPtrTemp->dataDescriptorRBuffer))
                    {
                        if (inputBufferPtrTemp->waitTimeCount < waitTimeMs)
                        {
                            waitTimeMs = inputBufferPtrTemp->waitTimeCount;
                        }
                    }
                }
                break;
                // All non Ack buffers
                //  - 
            default:
                if ((error == ARNETWORK_OK) &&
                    (!ARNETWORK_RingBuffer_IsEmpty (inputBufferPtrTemp->dataDescriptorRBuffer)))
                {
                    if (inputBufferPtrTemp->waitTimeCount < waitTimeMs)
                    {
                        waitTimeMs = inputBufferPtrTemp->waitTimeCount;
                    }
                }
                break;
            }
            ARNETWORK_IOBuffer_Unlock(inputBufferPtrTemp);
        }
        // Force a minimum wait time after an ARNetworkAL Overflow
        if ((senderPtr->hadARNetworkALOverflowOnPreviousRun > 0) &&
            (waitTimeMs < ARNETWORK_SENDER_WAIT_TIME_ON_ARNETWORKAL_OVERFLOW_MS))
        {
            waitTimeMs = ARNETWORK_SENDER_WAIT_TIME_ON_ARNETWORKAL_OVERFLOW_MS;
        }
        senderPtr->hadARNetworkALOverflowOnPreviousRun = 0;

        ARSAL_Time_GetTime(&sleepStart);
        if (waitTimeMs > 0)
        {
            if (waitTimeMs < senderPtr->minimumTimeBetweenSendsMs)
            {
                waitTimeMs = senderPtr->minimumTimeBetweenSendsMs;
            }
            ARSAL_Mutex_Lock (&(senderPtr->nextSendMutex));
            ARSAL_Cond_Timedwait (&(senderPtr->nextSendCond), &(senderPtr->nextSendMutex), waitTimeMs);
            ARSAL_Mutex_Unlock (&(senderPtr->nextSendMutex));
        }

        /** Process internal input buffers */
        ARSAL_Time_GetTime(&now);
        sleepDurationMs = ARSAL_Time_ComputeTimespecMsTimeDiff (&sleepStart, &now);
        ARSAL_Mutex_Lock (&(senderPtr->pingMutex));
        timeDiffMs = ARSAL_Time_ComputeTimespecMsTimeDiff (&(senderPtr->pingStartTime), &now);
        /* Send only new pings if ping function is active (min time > 0) */
        if (senderPtr->minTimeBetweenPings > 0)
        {
            int maxWaitTime = senderPtr->minTimeBetweenPings;
            if (ARNETWORK_SENDER_PING_TIMEOUT_MS > maxWaitTime)
            {
                maxWaitTime = ARNETWORK_SENDER_PING_TIMEOUT_MS;
            }

            /* Send new ping if :
             *  -> DT > minTimeBetweenPings AND we're not waiting for a ping
             *  -> DT > maxWaitTime
             */
            if (((senderPtr->isPingRunning == 0) &&
                 (timeDiffMs > senderPtr->minTimeBetweenPings)) ||
                (timeDiffMs > maxWaitTime))
            {
                if (timeDiffMs > ARNETWORK_SENDER_PING_TIMEOUT_MS)
                {
                    senderPtr->lastPingValue = -1;
                }
                inputBufferPtrTemp = senderPtr->inputBufferPtrMap[ARNETWORK_MANAGER_INTERNAL_BUFFER_ID_PING];
                error = ARNETWORK_IOBuffer_Lock (inputBufferPtrTemp);
                if (error == ARNETWORK_OK) {
                    ARNETWORK_IOBuffer_AddData (inputBufferPtrTemp, (uint8_t *)&now, sizeof (now), NULL, NULL, 1);
                    ARNETWORK_IOBuffer_Unlock (inputBufferPtrTemp);
                } else {
                    ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_SENDER_TAG, "ARNETWORK_IOBuffer_Lock() failed; error: %s", ARNETWORK_Error_ToString (error));
                }
                senderPtr->pingStartTime.tv_sec = now.tv_sec;
                senderPtr->pingStartTime.tv_nsec = now.tv_nsec;
                senderPtr->isPingRunning = 1;
            }
        }

        ARSAL_Mutex_Unlock (&(senderPtr->pingMutex));

        for (inputBufferIndex = 0; inputBufferIndex < senderPtr->networkALManager->maxIds ; inputBufferIndex++)
        {
            inputBufferPtrTemp = senderPtr->inputBufferPtrMap[inputBufferIndex];
            if (inputBufferPtrTemp != NULL)
            {
                ARNETWORK_Sender_ProcessBufferToSend (senderPtr, inputBufferPtrTemp, (waitTimeMs > 0) ? sleepDurationMs : 0);
            }
        }

        senderPtr->networkALManager->send(senderPtr->networkALManager);
    }

    return NULL;
}
ARNETWORK_Sender_t* ARNETWORK_Sender_New (ARNETWORKAL_Manager_t *networkALManager, unsigned int numberOfInputBuffer, ARNETWORK_IOBuffer_t **inputBufferPtrArr, unsigned int numberOfInternalInputBuffer, ARNETWORK_IOBuffer_t **internalInputBufferPtrArr, ARNETWORK_IOBuffer_t **inputBufferPtrMap, int pingDelayMs)
{
    /** -- Create a new sender -- */

    /** local declarations */
    ARNETWORK_Sender_t* senderPtr =  NULL;
    eARNETWORK_ERROR error = ARNETWORK_OK;

    /** Create the sender */
    senderPtr =  malloc (sizeof (ARNETWORK_Sender_t));

    if (senderPtr)
    {
        if(networkALManager != NULL)
        {
            senderPtr->networkALManager = networkALManager;
        }
        else
        {
            error = ARNETWORK_ERROR_BAD_PARAMETER;
        }

        if(error == ARNETWORK_OK)
        {
            senderPtr->isAlive = 1;
            senderPtr->numberOfInputBuff = numberOfInputBuffer;
            senderPtr->inputBufferPtrArr = inputBufferPtrArr;
            senderPtr->numberOfInternalInputBuff = numberOfInternalInputBuffer;
            senderPtr->internalInputBufferPtrArr = internalInputBufferPtrArr;
            senderPtr->inputBufferPtrMap = inputBufferPtrMap;
            senderPtr->minimumTimeBetweenSendsMs = ARNETWORK_SENDER_MILLISECOND;
            senderPtr->isPingRunning = 0;
            senderPtr->hadARNetworkALOverflowOnPreviousRun = 0;
            if (pingDelayMs == 0)
            {
                senderPtr->minTimeBetweenPings = ARNETWORK_SENDER_MINIMUM_TIME_BETWEEN_PINGS_MS;
            }
            else
            {
                senderPtr->minTimeBetweenPings = pingDelayMs;
            }
            ARSAL_Time_GetTime(&(senderPtr->pingStartTime));
        }

        /* Create the mutex/condition */
        if ( (error == ARNETWORK_OK) &&
             (ARSAL_Mutex_Init (&(senderPtr->nextSendMutex)) != 0))
        {
            error = ARNETWORK_ERROR_NEW_BUFFER;
        }

        if ( (error == ARNETWORK_OK) &&
             (ARSAL_Cond_Init (&(senderPtr->nextSendCond)) != 0))
        {
            error = ARNETWORK_ERROR_NEW_BUFFER;
        }

        if ( (error == ARNETWORK_OK) &&
             (ARSAL_Mutex_Init (&(senderPtr->pingMutex)) != 0))
        {
            error = ARNETWORK_ERROR_NEW_BUFFER;
        }

        /** delete the sender if an error occurred */
        if (error != ARNETWORK_OK)
        {
            ARSAL_PRINT (ARSAL_PRINT_ERROR, ARNETWORK_SENDER_TAG, "error: %s", ARNETWORK_Error_ToString (error));
            ARNETWORK_Sender_Delete (&senderPtr);
        }
    }

    return senderPtr;
}
Example #9
0
int sendLanding(BD_MANAGER_t *deviceManager)
{
    int sentStatus = 1;
    u_int8_t cmdBuffer[128];
    int32_t cmdSize = 0;
    eARCOMMANDS_GENERATOR_ERROR cmdError;
    eARNETWORK_ERROR netError = ARNETWORK_ERROR;
    
    ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- Send landing");
    
    // Send landing command
    cmdError = ARCOMMANDS_Generator_GenerateARDrone3PilotingLanding(cmdBuffer, sizeof(cmdBuffer), &cmdSize);
    if (cmdError == ARCOMMANDS_GENERATOR_OK)
    {
		printf("send Landing\n");
        netError = ARNETWORK_Manager_SendData(deviceManager->netManager, BD_NET_CD_ACK_ID, cmdBuffer, cmdSize, NULL, &(arnetworkCmdCallback), 1);
		printf("Landing sent\n");
    }
    
    if ((cmdError != ARCOMMANDS_GENERATOR_OK) || (netError != ARNETWORK_OK))
    {
		printf("Landing error\n");
        ARSAL_PRINT(ARSAL_PRINT_WARNING, TAG, "Failed to send landing command. cmdError:%d netError:%s", cmdError, ARNETWORK_Error_ToString(netError));
        sentStatus = 0;
    }
    
    return sentStatus;
}