summaryrefslogtreecommitdiff
path: root/lcmodule/source/cnh1606344_ldr_communication_module/source/communication_service.c
blob: e7ccd7399570e43a7b37475a8698826f8a805651 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
/*******************************************************************************
 * Copyright (C) ST-Ericsson SA 2011
 * License terms: 3-clause BSD license
 ******************************************************************************/
/**
 * @addtogroup ldr_communication_serv
 * @{
 */

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <string.h>
#include "error_codes.h"
#include <stdlib.h>
#include <stdio.h>
#include "r_debug.h"
#include "r_debug_macro.h"
#include "r_r15_family.h"
#include "r_r15_transport_layer.h"
#include "r_r15_network_layer.h"
#include "r_communication_service.h"
#include "r_basicdefinitions.h"
#include "r_memory_utils.h"

#ifdef CFG_ENABLE_A2_FAMILY
#include "r_a2_family.h"
#include "r_a2_transport.h"
#endif
#ifndef CFG_ENABLE_LOADER_TYPE
#include "r_protrom_family.h"
#include "r_z_family.h"
#include "r_protrom_transport.h"
#include "r_z_transport.h"
#endif

/*******************************************************************************
 * File scope types, constants and variables
 ******************************************************************************/
#define QUEUE_SIZE 32

Communication_t GlobalCommunication = {0};
Communication_t *GlobalCommunication_p = &GlobalCommunication;

static FamilyDescriptor_t ProtocolFamilies[] = {
    {
        R15_Family_Init,
        R15_Family_Shutdown,
        R15_Transport_Poll,
        R15_Transport_Send,
        R15_SetProtocolTimeouts,
        R15_GetProtocolTimeouts,
        R15_CancelReceiver
    },
    {
#ifdef CFG_ENABLE_A2_FAMILY
        A2_Family_Init,
        A2_Family_Shutdown,
        A2_Transport_Poll,
        A2_Transport_Send,
        NULL,
        NULL,
        A2_CancelReceiver
#else
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
#endif
    },
#ifndef CFG_ENABLE_LOADER_TYPE
    {
        // we do not support TI protocol family
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
    },
    {
        Protrom_Family_Init,
        Protrom_Family_Shutdown,
        Protrom_Transport_Poll,
        Protrom_Transport_Send,
        NULL,
        NULL,
        Protrom_CancelReceiver
    },
    {
        Z_Family_Init,
        Z_Family_Shutdown,
        Z_Transport_Poll,
        Z_Transport_Send,
        NULL,
        NULL,
        Z_CancelReceiver
    }
#endif
};

#define MAX_FAMILY (sizeof(ProtocolFamilies) / sizeof(ProtocolFamilies[0]))

/*******************************************************************************
 * Declaration of internal functions
 ******************************************************************************/

static BuffersInterface_t *CreateBufferInterfaceHelpper(BuffersInterface_t *Buffers_p);
static TimersInterface_t  *CreateTimerInterfaceHelpper(TimersInterface_t *Timers_p);
static QueueInterface_t   *CreateQueueInterfaceHelpper(QueueInterface_t *Queue_p);

static void DestroyBufferInterface(const Communication_t *const Communication_p);
static void DestroyTimerInterface(const Communication_t *const Communication_p);
static void DestroyQueueInterface(const Communication_t *const Communication_p);
FamilyDescriptor_t *GetFamily(Family_t Family);

/*******************************************************************************
 * Definition of external functions
 ******************************************************************************/

/**
 * Initialize an instance of the communication module.
 *
 * Given the initial family, already initialized hash device descriptor
 * and communication device descriptor, a new instance of the
 * communication module is created and bound to use the provided devices.
 *
 * @param [in]     Object_p              Instance which will use initialized communication.
 * @param [in,out] Communication_pp      Communication module context.
 * @param [in]     Family                Initial protocol family.
 * @param [in]     HashDevice_p          The device to use for checksum
 *                                       calculations and verifications.
 * @param [in]     CommunicationDevice_p The device to use for network
 *                                       transmission.
 * @param [in]     CommandCallback_p     Callback function for command handling.
 * @param [in]     Buffers_p             Pointer to buffer handling functions.
 * @param [in]     Timers_p              Pointer to timers handling functions.
 * @param [in]     Queue_p               Pointer to queue handling functions.
 *
 * @retval  E_SUCCESS If the module instance is successfully
 *                    initialized. A protocol family dependent error
 *                    code otherwise.
 */
ErrorCode_e Do_Communication_Initialize(void *Object_p, Communication_t **Communication_pp, Family_t Family, HashDevice_t *HashDevice_p, CommunicationDevice_t *CommunicationDevice_p, Do_CEH_Call_t CommandCallback_p, BuffersInterface_t *Buffers_p, TimersInterface_t *Timers_p, QueueInterface_t *Queue_p)
{
    ErrorCode_e ReturnValue = E_INVALID_INPUT_PARAMETERS;
    Communication_t *Communication_p = NULL;

    VERIFY((NULL != HashDevice_p) && (NULL != CommunicationDevice_p), E_INVALID_INPUT_PARAMETERS);

#ifdef CFG_ENABLE_COMMUNICATION_SINGLETON
    Communication_p = GlobalCommunication_p;
#else
    VERIFY(NULL != Communication_pp, E_INVALID_INPUT_PARAMETERS);

    Communication_p = (Communication_t *)malloc(sizeof(Communication_t));
    VERIFY(NULL != Communication_p, E_ALLOCATE_FAILED);
    memset(Communication_p, 0, sizeof(Communication_t));

    Communication_p->Object_p = Object_p;
    *Communication_pp = Communication_p;
#endif

    Communication_p->Functions_p = (FunctionInterface_t *)malloc(sizeof(FunctionInterface_t));

    VERIFY(NULL != Communication_p->Functions_p, E_ALLOCATE_FAILED);

    /* init buffer functions*/
    Communication_p->Functions_p->BufferFunctions_p = CreateBufferInterfaceHelpper(Buffers_p);

    VERIFY(NULL != Communication_p->Functions_p->BufferFunctions_p, E_FAILED_TO_ALLOCATE_COMM_BUFFER);

    /* init Timer functions*/
    Communication_p->Functions_p->TimerFunctions_p = CreateTimerInterfaceHelpper(Timers_p);

    VERIFY(NULL != Communication_p->Functions_p->TimerFunctions_p, E_FAILED_TO_INTIALIZE_TIMER_FUNCTIONS);

    /* init Queue functions*/
    Communication_p->Functions_p->QueueFunctions_p = CreateQueueInterfaceHelpper(Queue_p);

    VERIFY(NULL != Communication_p->Functions_p->QueueFunctions_p, E_FAILED_TO_INTIALIZE_QUEUE_FUNCTIONS);

    /* TODO: FIFO init can fail, but there's currently no way of detecting it */
    QUEUE(Communication_p, FifoCreate_Fn)(OBJECT_QUEUE(Communication_p), &Communication_p->Inbound_p, QUEUE_SIZE, NULL);
    QUEUE(Communication_p, FifoCreate_Fn)(OBJECT_QUEUE(Communication_p), &Communication_p->Outbound_p, QUEUE_SIZE, NULL);

    Communication_p->CommunicationDevice_p = CommunicationDevice_p;
    Communication_p->HashDevice_p = HashDevice_p;
    Communication_p->HashDevice_p->Object_p = HashDevice_p->Object_p;
    Communication_p->CurrentFamilyHash = HASH_NONE;
    Communication_p->BackupCommBufferSize = 0;

    CommunicationDevice_p->Object_p = Communication_p;

    ReturnValue = Do_Communication_SetFamily(Communication_p, Family, CommandCallback_p);

    C_(printf("#---------------------------------------------------------\n");)
    C_(printf("# Loader Communication Module Started!\n");)
    C_(printf("#---------------------------------------------------------\n");)

ErrorExit:
    return ReturnValue;
}

/*
 * Shutdown an instance of the communication module.
 *
 * Shutdown the initialized protocol family, cancel current transmission and
 * receiving data thru the communication device and shutdown the transport and
 * network layer.
 *
 * @param [in,out] Communication_pp    Communication module context.
 *
 * @retval  E_SUCCESS If the module instance is successfully
 *                    shut down. A protocol family dependent error
 *                    code otherwise.
 */
ErrorCode_e Do_Communication_Shutdown(Communication_t **Communication_pp)
{
    ErrorCode_e ReturnValue = E_SUCCESS;
    Communication_t *Communication_p = NULL;

    VERIFY((NULL != Communication_pp) && (NULL != *Communication_pp), E_INVALID_INPUT_PARAMETERS);

    Communication_p = *Communication_pp;

    (void)Communication_p->CommunicationDevice_p->Cancel(Communication_p->CommunicationDevice_p);
    Communication_p->HashDevice_p->Cancel(OBJECT_HASH(Communication_p), (void **)&Communication_p->HashDevice_p);

    if (NULL != Communication_p->Family_p) {
        ReturnValue = Communication_p->Family_p->FamilyShutdown_fn(Communication_p);
    }

    QUEUE(Communication_p, FifoDestroy_Fn)(OBJECT_QUEUE(Communication_p), &Communication_p->Inbound_p);
    QUEUE(Communication_p, FifoDestroy_Fn)(OBJECT_QUEUE(Communication_p), &Communication_p->Outbound_p);

    DestroyBufferInterface(Communication_p);
    DestroyTimerInterface(Communication_p);
    DestroyQueueInterface(Communication_p);
    free(Communication_p->Functions_p);

    memset(Communication_p, 0, sizeof(Communication_t));

    if (NULL != Communication_p->BackupCommBuffer_p) {
        free(Communication_p->BackupCommBuffer_p);
        Communication_p->BackupCommBuffer_p = NULL;
        Communication_p->BackupCommBufferSize = 0;
    }

    free(Communication_p);
    Communication_p = NULL;
    *Communication_pp = NULL;

ErrorExit:
    return ReturnValue;
}

/*
 * Change the current protocol family.
 *
 * Shuts down the old protocol family and initializes the new one.
 *
 * @param [in] Communication_p  Communication module context.
 * @param [in] Family           New protocol family identifier.
 * @param [in] CEHCallback      Callback that will handle the commands.
 *
 * @retval  E_SUCCESS If the family is successfully changed. A
 *                    protocol family dependent error code otherwise.
 */
ErrorCode_e Do_Communication_SetFamily(Communication_t *Communication_p, Family_t Family, Do_CEH_Call_t CEHCallback)
{
    ErrorCode_e ReturnValue = E_SUCCESS;
    FamilyDescriptor_t *Family_p = GetFamily(Family);

    VERIFY(NULL != Family_p, E_INVALID_INPUT_PARAMETERS);

    if (NULL != Communication_p->Family_p) {
        (void)Communication_p->CommunicationDevice_p->Cancel(Communication_p->CommunicationDevice_p);
        ReturnValue = Communication_p->Family_p->FamilyShutdown_fn(Communication_p);

        VERIFY(E_SUCCESS == ReturnValue, ReturnValue);
    }

    Communication_p->Family_p = Family_p;
    Communication_p->Do_CEH_Call_Fn = CEHCallback;

    ReturnValue = Communication_p->Family_p->FamilyInit_fn(Communication_p);
ErrorExit:
    return ReturnValue;
}


/*
 * Poll the network for inbound packets.
 *
 * When a packet is received it is put on the inbound queue. This
 * function should be called whenever there is time to handle a new
 * packet. It passes all the elements in the queue to the family
 * specific polling function, one by one.
 *
 * @param [in] Communication_p  Communication module context.
 *
 *
 * @retval  E_SUCCESS If all packets are successfully handled. A
 *                    protocol family dependent error code otherwise.
 */
ErrorCode_e Do_Communication_Poll(Communication_t *Communication_p)
{
    ErrorCode_e ReturnValue = E_GENERAL_COMMUNICATION_ERROR;

    VERIFY(NULL != Communication_p->Family_p, ReturnValue);

    ReturnValue = Communication_p->Family_p->Process_fn(Communication_p);

ErrorExit:
    return ReturnValue;
}

/*
 * Function for sending packet.
 *
 * @param [in]  Communication_p Communication module context.
 * @param [in]  InputData_p     Pointer to the data for transmission.
 *
 * @retval E_SUCCESS                        After successful execution.
 * @retval E_FAILED_TO_ALLOCATE_COMM_BUFFER Failed to allocate communication
 *                                          buffer.
 */
ErrorCode_e Do_Communication_Send(Communication_t *Communication_p, void *InputData_p)
{
    ErrorCode_e ReturnValue = E_GENERAL_COMMUNICATION_ERROR;

    VERIFY(NULL != Communication_p->Family_p, ReturnValue);

    (void)Communication_p->Family_p->Send_fn(Communication_p, InputData_p);

    ReturnValue = E_SUCCESS;

ErrorExit:
    return ReturnValue;
}

/*
 * Function for setting the timeouts in the protocols.
 *
 * Timeouts that should be set depend of the protocol family. Some protocol
 * family do not have timeouts.
 *
 * @param [in]  Communication_p Communication module context.
 * @param [in]  TimeoutData_p   Pointer to the data with all timeouts.
 *
 * @retval E_SUCCESS            After successful execution.
 */
ErrorCode_e Do_Communication_SetProtocolTimeouts(Communication_t *Communication_p, void *TimeoutData_p)
{
    ErrorCode_e ReturnValue = E_GENERAL_COMMUNICATION_ERROR;

    VERIFY(NULL != Communication_p->Family_p, ReturnValue);

    (void)Communication_p->Family_p->SetProtocolTimeouts_fn(Communication_p, TimeoutData_p);

    ReturnValue = E_SUCCESS;

ErrorExit:
    return ReturnValue;
}

/*
 * Function for getting the timeouts in the protocols.
 *
 * Timeouts that should be get depend of the protocol family. Some protocol
 * family do not have timeouts.
 *
 * @param [in]  Communication_p  Communication module context.
 * @param [out] TimeoutData_p    Return data with all timeouts.
 *
 * @retval E_SUCCESS             After successful execution.
 */
ErrorCode_e Do_Communication_GetProtocolTimeouts(Communication_t *Communication_p, void *TimeoutData_p)
{
    ErrorCode_e ReturnValue = E_GENERAL_COMMUNICATION_ERROR;

    VERIFY(NULL != Communication_p->Family_p, ReturnValue);

    (void)Communication_p->Family_p->GetProtocolTimeouts_fn(Communication_p, TimeoutData_p);

    ReturnValue = E_SUCCESS;

ErrorExit:
    return ReturnValue;
}

/*
 * Function for getting the communication device for the given LCM instance.
 *
 * If communication is Singleton the function can be called with NULL pointer
 * for Communication_p.
 *
 * @param [in]  Communication_p        Communication module context.
 * @param [out] CommunicationDevice_pp Pointer to the initialized communication
 *                                     device for the given LCM context.
 *
 * @retval E_SUCCESS                 After successful execution.
 * @retval E_INVALID_INPUT_PARAMTERS In case when communication is not Singleton
 *                                   and Communication_p is NULL pointer.
 */
ErrorCode_e Do_Communication_GetCommunicationDevice(Communication_t *Communication_p, CommunicationDevice_t **CommunicationDevice_pp)
{
    ErrorCode_e ReturnValue = E_SUCCESS;
    VERIFY(NULL != Communication_p && CommunicationDevice_pp != NULL, E_INVALID_INPUT_PARAMETERS);

    *CommunicationDevice_pp = Communication_p->CommunicationDevice_p;

ErrorExit:
    return ReturnValue;
}

/*
 * Function for setting the communication device for the given LCM instance.
 *
 * If communication is Singleton the function can be called with NULL pointer
 * for Communication_p.
 *
 * @param [in]  Communication_p        Communication module context.
 * @param [out] CommunicationDevice_p  Pointer to the initialized communication
 *                                     device to be set for the given LCM context.
 *
 * @retval E_SUCCESS                 After successful execution.
 * @retval E_INVALID_INPUT_PARAMTERS In case when communication is not Singleton
 *                                   and Communication_p is NULL pointer.
 */
ErrorCode_e Do_Communication_SetCommunicationDevice(Communication_t *Communication_p, CommunicationDevice_t *CommunicationDevice_p)
{
    ErrorCode_e ReturnValue = E_SUCCESS;
    VERIFY(NULL != Communication_p && CommunicationDevice_p != NULL, E_INVALID_INPUT_PARAMETERS);

    Communication_p->CommunicationDevice_p = CommunicationDevice_p;

ErrorExit:
    return ReturnValue;
}

/*
 * Cancel Receiving new packets
 *
 * @param [in] Communication_p  Communication module context.
 * @param [in] PacketsBeforeReceiverStop  Number of packets to be send before stopping the receiver.
 *
 * @retval  E_SUCCESS If all packets are successfully handled. A
 *                    protocol family dependant error code otherwise.
 */
ErrorCode_e Do_Communication_Cancel_Receiver(Communication_t *Communication_p, uint8 PacketsBeforeReceiverStop)
{
    ErrorCode_e ReturnValue = E_GENERAL_COMMUNICATION_ERROR;

    VERIFY(NULL != Communication_p->Family_p, ReturnValue);

    ReturnValue = Communication_p->Family_p->CancelReceiver_fn(Communication_p, PacketsBeforeReceiverStop);

ErrorExit:
    return ReturnValue;
}

void Do_CommunicationInternalErrorHandler(const ErrorCode_e IntError)
{
#ifndef PRINT_A_
    IDENTIFIER_NOT_USED(IntError);
#endif
    A_(printf("# Error Code: 0x%X !\n", IntError);)
    A_(printf("# Loader stopped!\n");)
    A_(printf("#---------------------------------------------------------\n");)

    /* coverity[no_escape] */
    while (1);
}

/*******************************************************************************
 * Definition of internal functions
 ******************************************************************************/
static BuffersInterface_t *CreateBufferInterfaceHelpper(BuffersInterface_t *Buffers_p)
{
    BuffersInterface_t *BufferFunctions_p = (BuffersInterface_t *)malloc(sizeof(BuffersInterface_t));

    if (NULL == BufferFunctions_p) {
        return NULL;
    }

    BufferFunctions_p->BuffersInit_Fn = Buffers_p->BuffersInit_Fn;
    BufferFunctions_p->BufferAllocate_Fn = Buffers_p->BufferAllocate_Fn;
    BufferFunctions_p->BufferRelease_Fn = Buffers_p->BufferRelease_Fn;
    BufferFunctions_p->BuffersAvailable_Fn = Buffers_p->BuffersAvailable_Fn;
    BufferFunctions_p->BuffersDeinit_Fn = Buffers_p->BuffersDeinit_Fn;
#ifndef CFG_ENABLE_LOADER_TYPE
    BufferFunctions_p->Object_p = Buffers_p->Object_p;
#endif

    return BufferFunctions_p;
}

static TimersInterface_t *CreateTimerInterfaceHelpper(TimersInterface_t *Timers_p)
{
    TimersInterface_t *TimerFunctions_p = (TimersInterface_t *)malloc(sizeof(TimersInterface_t));

    if (NULL == TimerFunctions_p) {
        return NULL;
    }

    TimerFunctions_p->TimersInit_Fn = Timers_p->TimersInit_Fn;
    TimerFunctions_p->TimerGet_Fn = Timers_p->TimerGet_Fn;
    TimerFunctions_p->TimerRelease_Fn = Timers_p->TimerRelease_Fn;
    TimerFunctions_p->ReadTime_Fn = Timers_p->ReadTime_Fn;
    TimerFunctions_p->GetSystemTime_Fn = Timers_p->GetSystemTime_Fn;
#ifndef CFG_ENABLE_LOADER_TYPE
    TimerFunctions_p->Object_p = Timers_p->Object_p;
#endif

    return TimerFunctions_p;
}

static QueueInterface_t *CreateQueueInterfaceHelpper(QueueInterface_t *Queue_p)
{
    QueueInterface_t *QueueFunctions_p = (QueueInterface_t *)malloc(sizeof(QueueInterface_t));

    if (NULL == QueueFunctions_p) {
        return NULL;
    }

    QueueFunctions_p->FifoCreate_Fn = Queue_p->FifoCreate_Fn;
    QueueFunctions_p->FifoDestroy_Fn = Queue_p->FifoDestroy_Fn;
    QueueFunctions_p->FifoEnqueue_Fn = Queue_p->FifoEnqueue_Fn;
    QueueFunctions_p->FifoDequeue_Fn = Queue_p->FifoDequeue_Fn;
    QueueFunctions_p->Fifo_SetCallback_Fn = Queue_p->Fifo_SetCallback_Fn;
    QueueFunctions_p->Fifo_IsEmpty_Fn = Queue_p->Fifo_IsEmpty_Fn;
    QueueFunctions_p->Fifo_IsMember_Fn = Queue_p->Fifo_IsMember_Fn;
    QueueFunctions_p->Fifo_GetNrOfElements_Fn = Queue_p->Fifo_GetNrOfElements_Fn;

    QueueFunctions_p->RFifoCreate_Fn = Queue_p->RFifoCreate_Fn;
    QueueFunctions_p->RFifoDestroy_Fn = Queue_p->RFifoDestroy_Fn;
    QueueFunctions_p->RFifoEnqueue_Fn = Queue_p->RFifoEnqueue_Fn;
    QueueFunctions_p->RFifoDequeue_Fn = Queue_p->RFifoDequeue_Fn;
    QueueFunctions_p->RFifo_SetCallback_Fn = Queue_p->RFifo_SetCallback_Fn;
    QueueFunctions_p->RFifo_IsEmpty_Fn = Queue_p->RFifo_IsEmpty_Fn;
    QueueFunctions_p->RFifo_IsMember_Fn = Queue_p->RFifo_IsMember_Fn;
    QueueFunctions_p->RFifo_GetNrOfElements_Fn = Queue_p->RFifo_GetNrOfElements_Fn;

#ifndef CFG_ENABLE_LOADER_TYPE
    QueueFunctions_p->Object_p = Queue_p->Object_p;
#endif
    return QueueFunctions_p;
}

static void  DestroyBufferInterface(const Communication_t *const Communication_p)
{
    if (NULL != Communication_p->Functions_p->BufferFunctions_p) {
        free(Communication_p->Functions_p->BufferFunctions_p);
        Communication_p->Functions_p->BufferFunctions_p = NULL;
    }
}

static void DestroyTimerInterface(const Communication_t *const Communication_p)
{
    if (NULL != Communication_p->Functions_p->TimerFunctions_p) {
        free(Communication_p->Functions_p->TimerFunctions_p);
        Communication_p->Functions_p->TimerFunctions_p = NULL;
    }
}

static void DestroyQueueInterface(const Communication_t *const Communication_p)
{
    if (NULL != Communication_p->Functions_p->QueueFunctions_p) {
        free(Communication_p->Functions_p->QueueFunctions_p);
        Communication_p->Functions_p->QueueFunctions_p = NULL;
    }
}

FamilyDescriptor_t *GetFamily(Family_t Family)
{
    uint32 IntFamily = (uint32)Family;

    if (IntFamily > (MAX_FAMILY - 1)) {
        return NULL;
    }

    return (FamilyDescriptor_t *)&ProtocolFamilies[Family];
}

/** @}*/