コード例 #1
0
ARNETWORK_RingBuffer_t* ARNETWORK_RingBuffer_NewWithOverwriting(unsigned int numberOfCell, unsigned int cellSize, int isOverwriting)
{
    /* -- Create a new ring buffer -- */

    /* local declarations */
    int err = 0;
    ARNETWORK_RingBuffer_t* ringBuffer = calloc(1, sizeof(ARNETWORK_RingBuffer_t));
    if (ringBuffer == NULL)
        return NULL;

    ringBuffer->numberOfCell = numberOfCell;
    ringBuffer->cellSize = cellSize;
    ringBuffer->indexInput = 0;
    ringBuffer->indexOutput = 0;
    ringBuffer->isOverwriting = isOverwriting;
    err = ARSAL_Mutex_Init(&ringBuffer->mutex);
    if (err != 0)
        goto error;

    ringBuffer->dataBuffer = malloc(cellSize * numberOfCell);
    if (ringBuffer->dataBuffer == NULL)
        goto error;

    return ringBuffer;

error:
    ARNETWORK_RingBuffer_Delete(&ringBuffer);
    return NULL;
}
コード例 #2
0
int ARSTREAM2_H264_AuFifoAddQueue(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoQueue_t *queue)
{
    if ((!fifo) || (!queue))
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer");
        return -1;
    }

    int mutexRet = ARSAL_Mutex_Init(&(queue->mutex));
    if (mutexRet != 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Mutex creation failed (%d)", mutexRet);
        return -1;
    }

    ARSAL_Mutex_Lock(&(fifo->mutex));

    queue->count = 0;
    queue->head = NULL;
    queue->tail = NULL;
    queue->prev = NULL;
    queue->next = fifo->queue;
    if (queue->next)
    {
        queue->next->prev = queue;
    }

    fifo->queue = queue;
    fifo->queueCount++;

    ARSAL_Mutex_Unlock(&(fifo->mutex));

    return 0;
}
コード例 #3
0
int ARSTREAM2_H264_NaluFifoInit(ARSTREAM2_H264_NaluFifo_t *fifo, int maxCount)
{
    int i;
    ARSTREAM2_H264_NaluFifoItem_t* cur;

    if (!fifo)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer");
        return -1;
    }

    if (maxCount <= 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid FIFO size (%d)", maxCount);
        return -1;
    }

    memset(fifo, 0, sizeof(ARSTREAM2_H264_NaluFifo_t));

    int mutexRet = ARSAL_Mutex_Init(&(fifo->mutex));
    if (mutexRet != 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Mutex creation failed (%d)", mutexRet);
        return -1;
    }

    fifo->size = maxCount;
    fifo->pool = malloc(maxCount * sizeof(ARSTREAM2_H264_NaluFifoItem_t));
    if (!fifo->pool)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO allocation failed (size %zu)", maxCount * sizeof(ARSTREAM2_H264_NaluFifoItem_t));
        return -1;
    }
    memset(fifo->pool, 0, maxCount * sizeof(ARSTREAM2_H264_NaluFifoItem_t));

    for (i = 0; i < maxCount; i++)
    {
        cur = &fifo->pool[i];
        if (fifo->free)
        {
            fifo->free->prev = cur;
        }
        cur->next = fifo->free;
        cur->prev = NULL;
        fifo->free = cur;
    }

    return 0;
}
コード例 #4
0
ファイル: ARSTREAM_Reader.c プロジェクト: wicktt/libARStream
ARSTREAM_Reader_t* ARSTREAM_Reader_New (ARNETWORK_Manager_t *manager, int dataBufferID, int ackBufferID, ARSTREAM_Reader_FrameCompleteCallback_t callback, uint8_t *frameBuffer, uint32_t frameBufferSize, uint32_t maxFragmentSize, int32_t maxAckInterval, void *custom, eARSTREAM_ERROR *error)
{
    ARSTREAM_Reader_t *retReader = NULL;
    int ackPacketMutexWasInit = 0;
    int ackSendMutexWasInit = 0;
    int ackSendCondWasInit = 0;
    eARSTREAM_ERROR internalError = ARSTREAM_OK;
    /* ARGS Check */
    if ((manager == NULL) ||
        (callback == NULL) ||
        (frameBuffer == NULL) ||
        (frameBufferSize == 0) ||
        (maxFragmentSize == 0) ||
        (maxAckInterval < -1))
    {
        SET_WITH_CHECK (error, ARSTREAM_ERROR_BAD_PARAMETERS);
        return retReader;
    }

    /* Alloc new reader */
    retReader = malloc (sizeof (ARSTREAM_Reader_t));
    if (retReader == NULL)
    {
        internalError = ARSTREAM_ERROR_ALLOC;
    }

    /* Copy parameters */
    if (internalError == ARSTREAM_OK)
    {
        retReader->manager = manager;
        retReader->dataBufferID = dataBufferID;
        retReader->ackBufferID = ackBufferID;
        retReader->maxFragmentSize = maxFragmentSize;
        retReader->maxAckInterval = maxAckInterval;
        retReader->callback = callback;
        retReader->custom = custom;
        retReader->currentFrameBufferSize = frameBufferSize;
        retReader->currentFrameBuffer = frameBuffer;
    }

    /* Setup internal mutexes/conditions */
    if (internalError == ARSTREAM_OK)
    {
        int mutexInitRet = ARSAL_Mutex_Init (&(retReader->ackPacketMutex));
        if (mutexInitRet != 0)
        {
            internalError = ARSTREAM_ERROR_ALLOC;
        }
        else
        {
            ackPacketMutexWasInit = 1;
        }
    }
    if (internalError == ARSTREAM_OK)
    {
        int mutexInitRet = ARSAL_Mutex_Init (&(retReader->ackSendMutex));
        if (mutexInitRet != 0)
        {
            internalError = ARSTREAM_ERROR_ALLOC;
        }
        else
        {
            ackSendMutexWasInit = 1;
        }
    }
    if (internalError == ARSTREAM_OK)
    {
        int condInitRet = ARSAL_Cond_Init (&(retReader->ackSendCond));
        if (condInitRet != 0)
        {
            internalError = ARSTREAM_ERROR_ALLOC;
        }
        else
        {
            ackSendCondWasInit = 1;
        }
    }

    /* Setup internal variables */
    if (internalError == ARSTREAM_OK)
    {
        int i;
        retReader->currentFrameSize = 0;
        retReader->threadsShouldStop = 0;
        retReader->dataThreadStarted = 0;
        retReader->ackThreadStarted = 0;
        retReader->efficiency_index = 0;
        for (i = 0; i < ARSTREAM_READER_EFFICIENCY_AVERAGE_NB_FRAMES; i++)
        {
            retReader->efficiency_nbTotal [i] = 0;
            retReader->efficiency_nbUseful [i] = 0;
        }
    }

    if ((internalError != ARSTREAM_OK) &&
        (retReader != NULL))
    {
        if (ackPacketMutexWasInit == 1)
        {
            ARSAL_Mutex_Destroy (&(retReader->ackPacketMutex));
        }
        if (ackSendMutexWasInit == 1)
        {
            ARSAL_Mutex_Destroy (&(retReader->ackSendMutex));
        }
        if (ackSendCondWasInit == 1)
        {
            ARSAL_Cond_Destroy (&(retReader->ackSendCond));
        }
        free (retReader);
        retReader = NULL;
    }

    SET_WITH_CHECK (error, internalError);
    return retReader;
}
コード例 #5
0
ARCONTROLLER_Network_t *ARCONTROLLER_Network_New (ARDISCOVERY_Device_t *discoveryDevice, ARCONTROLLER_Network_DisconnectionCallback_t disconnectionCallback, ARDISCOVERY_Device_ConnectionJsonCallback_t sendJsonCallback, ARDISCOVERY_Device_ConnectionJsonCallback_t receiveJsonCallback, void *customData, eARCONTROLLER_ERROR *error)
{
    // -- Create a new Network Controller --

    //local declarations
    eARCONTROLLER_ERROR localError = ARCONTROLLER_OK;
    ARCONTROLLER_Network_t *networkController =  NULL;
    eARDISCOVERY_ERROR dicoveryError = ARDISCOVERY_OK;
    
    // Check parameters
    if (discoveryDevice == NULL)
    {
        localError = ARCONTROLLER_ERROR_BAD_PARAMETER;
    }
    // No Else: the checking parameters sets localError to ARNETWORK_ERROR_BAD_PARAMETER and stop the processing
    
    if (localError == ARCONTROLLER_OK)
    {
        // Create the Network Controller
        networkController = malloc (sizeof (ARCONTROLLER_Network_t));
        if (networkController != NULL)
        {
            // Initialize to default values
            networkController->discoveryDevice = NULL;
            networkController->networkALManager = NULL;
            networkController->networkManager = NULL;
            networkController->rxThread = NULL;
            networkController->txThread = NULL;
            networkController->readerThreads = NULL;
            networkController->readerThreadsData = NULL;
            networkController->state = ARCONTROLLER_NETWORK_STATE_RUNNING;
            
            //video part
            networkController->hasVideo = 0;
            networkController->videoController = NULL;
            
            //Connection callback
            networkController->sendJsonCallback = sendJsonCallback;
            networkController->receiveJsonCallback = receiveJsonCallback;
            networkController->disconnectionCallback = disconnectionCallback;
            networkController->callbacksCustomData = customData;
            
            // init networkConfiguration
            networkController->networkConfig.controllerToDeviceNotAckId = -1;
            networkController->networkConfig.controllerToDeviceAckId = -1;
            networkController->networkConfig.controllerToDeviceHightPriority = -1;
            networkController->networkConfig.controllerToDeviceARStreamAck = -1;
            networkController->networkConfig.deviceToControllerNotAckId = -1;
            networkController->networkConfig.deviceToControllerAckId = -1;
            //networkController->networkConfig.deviceToControllerHightPriority = -1;
            networkController->networkConfig.deviceToControllerARStreamData = -1;
            networkController->networkConfig.numberOfControllerToDeviceParam = 0;
            networkController->networkConfig.controllerToDeviceParams = NULL;
            networkController->networkConfig.numberOfDeviceToControllerParam  = 0;
            networkController->networkConfig.deviceToControllerParams = NULL;
            networkController->networkConfig.pingDelayMs =-1;
            networkController->networkConfig.numberOfDeviceToControllerCommandsBufferIds = 0;
            networkController->networkConfig.deviceToControllerCommandsBufferIds = NULL;
            
            /* Create the mutex/condition */
            if ( (localError == ARCONTROLLER_OK) &&
                 (ARSAL_Mutex_Init (&(networkController->mutex)) != 0))
            {
                localError = ARCONTROLLER_ERROR_INIT_MUTEX;
            }
        }
        else
        {
            localError = ARCONTROLLER_ERROR_ALLOC;
        }
    }
    
    if (localError == ARCONTROLLER_OK)
    {
        // Copy the device
        eARDISCOVERY_ERROR dicoveryError = ARDISCOVERY_OK;
        
        networkController->discoveryDevice = ARDISCOVERY_Device_NewByCopy (discoveryDevice, &dicoveryError);
        if (dicoveryError != ARDISCOVERY_OK)
        {
            localError = ARCONTROLLER_ERROR_INIT_DEVICE_COPY;
        }
    }
    
    // Check if it is a wifi device
    if ((localError == ARCONTROLLER_OK) && 
        (ARDISCOVERY_getProductService (networkController->discoveryDevice->productID) == ARDISCOVERY_PRODUCT_NSNETSERVICE))
    {
        // Add callbacks for the connection json part
        dicoveryError = ARDISCOVERY_Device_WifiAddConnectionCallbacks (networkController->discoveryDevice, ARCONTROLLER_Network_OnSendJson, ARCONTROLLER_Network_OnReceiveJson, networkController);
        if (dicoveryError != ARDISCOVERY_OK)
        {
            localError = ARCONTROLLER_ERROR_INIT_DEVICE_JSON_CALLBACK;
        }
    }
    
    if (localError == ARCONTROLLER_OK)
    {
        // Initialize the network Configuration
        eARDISCOVERY_ERROR dicoveryError = ARDISCOVERY_OK;
        dicoveryError = ARDISCOVERY_Device_InitNetworkConfiguration (networkController->discoveryDevice, &(networkController->networkConfig));
        if (dicoveryError != ARDISCOVERY_OK)
        {
            localError = ARCONTROLLER_ERROR_INIT_NETWORK_CONFIG;
        }
    }
    
    if (localError == ARCONTROLLER_OK)
    {
        // Check if the device has video
        if (networkController->networkConfig.deviceToControllerARStreamData != -1)
        {
            networkController->hasVideo = 1;
            networkController->videoController = ARCONTROLLER_Stream_New (&(networkController->networkConfig), networkController->discoveryDevice, &localError);
        }
        //NO else ; device has not video
    }
    // No else: skipped by an error
    
    if (localError == ARCONTROLLER_OK)
    {
        // Create the NetworkAL
        eARDISCOVERY_ERROR dicoveryError = ARDISCOVERY_OK;
        eARNETWORKAL_ERROR netALError = ARNETWORKAL_OK;
        networkController->networkALManager = ARDISCOVERY_Device_NewARNetworkAL (networkController->discoveryDevice, &dicoveryError, &netALError);
        if (dicoveryError != ARDISCOVERY_OK)
        {
            if (netALError != ARNETWORKAL_OK)
            {
                ARSAL_PRINT (ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "error: %s", ARNETWORKAL_Error_ToString (netALError));
            }
            
            localError = ARCONTROLLER_ERROR_INIT_ARNETWORKAL_MANAGER;
        }
    }
    
    if (localError == ARCONTROLLER_OK)
    {
        // Create the ARNetworkManager.
        eARNETWORK_ERROR netError = ARNETWORK_OK;
        
        networkController->networkManager = ARNETWORK_Manager_New (networkController->networkALManager, networkController->networkConfig.numberOfControllerToDeviceParam, networkController->networkConfig.controllerToDeviceParams, networkController->networkConfig.numberOfDeviceToControllerParam, networkController->networkConfig.deviceToControllerParams, networkController->networkConfig.pingDelayMs, ARCONTROLLER_Network_OnDisconnectNetwork, networkController, &netError);
        if (netError != ARNETWORK_OK)
        {
            localError = ARCONTROLLER_ERROR_INIT_ARNETWORK_MANAGER;
        }
    }

    if (localError == ARCONTROLLER_OK)
    {
        // Create the Network receiver and transmitter Threads
        localError = ARCONTROLLER_Network_CreateNetworkThreads (networkController);
    }
    
    if (localError == ARCONTROLLER_OK)
    {
        // Create the reader Threads
        localError = ARCONTROLLER_Network_CreateReaderThreads (networkController);
    }
    
    // delete the Network Controller if an error occurred
    if (localError != ARCONTROLLER_OK)
    {
        ARSAL_PRINT (ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "error: %s", ARCONTROLLER_Error_ToString (localError));
        ARCONTROLLER_Network_Delete (&networkController);
    }
    // No else: skipped by an error 

    // Return the error
    if (error != NULL)
    {
        *error = localError;
    }
    // No else: error is not returned 

    return networkController;
}
コード例 #6
0
ファイル: ARSAL_Sem.c プロジェクト: jquesnelle/MissionControl
int ARSAL_Sem_Init(ARSAL_Sem_t *sem, int shared, int value)
{
    int result = -1;

    if (NULL == sem)
    {
        errno = EINVAL;
        return result;
    }
    /* No else. */

#if __SAL_USE_POSIX_SEM

    sem_t *psem = (sem_t *) calloc (1, sizeof (sem_t));
    if (NULL != psem)
    {
        result = sem_init(psem, shared, value);
        if (0 == result)
        {
            *sem = (ARSAL_Sem_t)psem;
        }
        else
        {
            free (psem);
            psem = NULL;
        }
    }
    /* No else: if calloc failed, return default value -1. */

#else

    /*
     * Custom init algo:
     * Alloc memory
     * Init mutex / condition
     * Set internal counter to 'value'
     */

    int isMalloc = 0, isMutexInit = 0;
    ARSAL_Sem_CustomImpl_t *psem = (ARSAL_Sem_CustomImpl_t *) malloc (sizeof (ARSAL_Sem_CustomImpl_t));
    if (NULL != psem)
    {
        isMalloc = 1;
        result = ARSAL_Mutex_Init (&(psem->lock));
        ARSAL_SEM_ERRNO_TRANSFORM (result);
        if (0 == result)
        {
            isMutexInit = 1;
            result = ARSAL_Cond_Init (&(psem->cond));
            ARSAL_SEM_ERRNO_TRANSFORM (result);
            psem->count = value;
        }
        /* No else. */
    }
    /* No else. */

    if (0 == result)
    {
        *sem = (ARSAL_Sem_t)psem;
    }
    else
    {
        if (1 == isMutexInit)
        {
            ARSAL_Mutex_Destroy (&(psem->lock));
        }
        /* No else: no need to destroy a mutex that wasn't created. */
        if (1 == isMalloc)
        {
            free (psem);
        }
        /* No else: no need to free memory that wasn't allocated. */
    }

#endif

    return result;
}
コード例 #7
0
int ARSTREAM2_H264_AuFifoInit(ARSTREAM2_H264_AuFifo_t *fifo, int itemMaxCount, int itemNaluMaxCount, int bufferMaxCount,
                              int auBufferSize, int metadataBufferSize, int userDataBufferSize, int videoStatsBufferSize)
{
    int i, ret;
    ARSTREAM2_H264_AuFifoItem_t* curItem;
    ARSTREAM2_H264_AuFifoBuffer_t* curBuffer;

    if (!fifo)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer");
        return -1;
    }
    if (itemMaxCount <= 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid item max count (%d)", itemMaxCount);
        return -1;
    }
    if (bufferMaxCount <= 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid buffer max count (%d)", bufferMaxCount);
        return -1;
    }

    memset(fifo, 0, sizeof(ARSTREAM2_H264_AuFifo_t));

    int mutexRet = ARSAL_Mutex_Init(&(fifo->mutex));
    if (mutexRet != 0)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Mutex creation failed (%d)", mutexRet);
        return -1;
    }

    fifo->itemPoolSize = itemMaxCount;
    fifo->itemPool = malloc(itemMaxCount * sizeof(ARSTREAM2_H264_AuFifoItem_t));
    if (!fifo->itemPool)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO allocation failed (size %zu)", itemMaxCount * sizeof(ARSTREAM2_H264_AuFifoItem_t));
        fifo->itemPoolSize = 0;
        return -1;
    }
    memset(fifo->itemPool, 0, itemMaxCount * sizeof(ARSTREAM2_H264_AuFifoItem_t));

    for (i = 0; i < itemMaxCount; i++)
    {
        curItem = &fifo->itemPool[i];
        ret = ARSTREAM2_H264_AuNaluFifoInit(&curItem->au, itemNaluMaxCount);
        if (ret != 0)
        {
            ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "ARSTREAM2_H264_AuNaluFifoInit() failed (%d)", ret);
            ARSTREAM2_H264_AuFifoFree(fifo);
            return -1;
        }
        if (fifo->itemFree)
        {
            fifo->itemFree->prev = curItem;
        }
        curItem->next = fifo->itemFree;
        curItem->prev = NULL;
        fifo->itemFree = curItem;
    }

    fifo->bufferPoolSize = bufferMaxCount;
    fifo->bufferPool = malloc(bufferMaxCount * sizeof(ARSTREAM2_H264_AuFifoBuffer_t));
    if (!fifo->bufferPool)
    {
        ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO allocation failed (size %zu)", bufferMaxCount * sizeof(ARSTREAM2_H264_AuFifoBuffer_t));
        fifo->bufferPoolSize = 0;
        return -1;
    }
    memset(fifo->bufferPool, 0, bufferMaxCount * sizeof(ARSTREAM2_H264_AuFifoBuffer_t));

    for (i = 0; i < bufferMaxCount; i++)
    {
        curBuffer = &fifo->bufferPool[i];
        if (fifo->bufferFree)
        {
            fifo->bufferFree->prev = curBuffer;
        }
        curBuffer->next = fifo->bufferFree;
        curBuffer->prev = NULL;
        fifo->bufferFree = curBuffer;
    }

    if (auBufferSize > 0)
    {
        for (i = 0; i < bufferMaxCount; i++)
        {
            fifo->bufferPool[i].auBuffer = malloc(auBufferSize);
            if (!fifo->bufferPool[i].auBuffer)
            {
                ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO buffer allocation failed (size %d)", auBufferSize);
                ARSTREAM2_H264_AuFifoFree(fifo);
                return -1;
            }
            fifo->bufferPool[i].auBufferSize = auBufferSize;
        }
    }

    if (metadataBufferSize > 0)
    {
        for (i = 0; i < bufferMaxCount; i++)
        {
            fifo->bufferPool[i].metadataBuffer = malloc(metadataBufferSize);
            if (!fifo->bufferPool[i].metadataBuffer)
            {
                ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO buffer allocation failed (size %d)", metadataBufferSize);
                ARSTREAM2_H264_AuFifoFree(fifo);
                return -1;
            }
            fifo->bufferPool[i].metadataBufferSize = metadataBufferSize;
        }
    }

    if (userDataBufferSize > 0)
    {
        for (i = 0; i < bufferMaxCount; i++)
        {
            fifo->bufferPool[i].userDataBuffer = malloc(userDataBufferSize);
            if (!fifo->bufferPool[i].userDataBuffer)
            {
                ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO buffer allocation failed (size %d)", userDataBufferSize);
                ARSTREAM2_H264_AuFifoFree(fifo);
                return -1;
            }
            fifo->bufferPool[i].userDataBufferSize = userDataBufferSize;
        }
    }

    if (videoStatsBufferSize > 0)
    {
        for (i = 0; i < bufferMaxCount; i++)
        {
            fifo->bufferPool[i].videoStatsBuffer = malloc(videoStatsBufferSize);
            if (!fifo->bufferPool[i].videoStatsBuffer)
            {
                ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "FIFO buffer allocation failed (size %d)", videoStatsBufferSize);
                ARSTREAM2_H264_AuFifoFree(fifo);
                return -1;
            }
            fifo->bufferPool[i].videoStatsBufferSize = videoStatsBufferSize;
        }
    }

    return 0;
}
コード例 #8
0
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;
}