summaryrefslogtreecommitdiff
path: root/cp/msg/src/field/msg_field_cspec.c
blob: e148597300fdc6c77bddabbf5400968d5ab351a3 (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
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}}
 * \file    msg_field_cspec.c
 * \brief   This file provides management functions for CSPEC (Connection Specification) field.
 * \ingroup cp/msg
 *
 */

#include "common/std.h"
#include "lib/swap.h"
#include "cp/msg/inc/msg_cm_conn.h"


/**
 * Initialize the CSPEC (Connection Specification) structure.
 * \param	cspec	Pointer of the data to be initialized.
 * 
 */
void
msg_field_cspec_init(cspec_t* cspec)
{
    cspec->len = 0;
    msg_field_cinfo_init( &(cspec->cinfo_forward) );
    msg_field_cinfo_init( &(cspec->cinfo_reverse) );
    msg_field_qmp_init(   &(cspec->qmp_forward)   );
    cspec->qmp_forward.forward_or_reverse = QMP_FORWARD;
    msg_field_qmp_init(   &(cspec->qmp_reverse)   );
    cspec->qmp_reverse.forward_or_reverse = QMP_REVERSE;
}


/**
 * Get CSPEC field from a stream.
 * \param	stream	Source Stream.
 * \param	cspec	Destination.
 * \return			Length of the CSPEC data.
 *
 */
len_t
msg_field_cspec_get_from_stream(u8* stream, cspec_t* cspec)
{
    u8* local_stream = stream;
    u8* stream_end;
    
    dbg_assert_ptr( stream );
    dbg_assert_ptr( cspec );
    
    cspec->len = ntohs (*(u16*)local_stream); local_stream += 2;
    stream_end = stream + cspec->len;
    
    local_stream += msg_field_cinfo_get_from_stream(local_stream, &(cspec->cinfo_forward) );
    local_stream += msg_field_cinfo_get_from_stream(local_stream, &(cspec->cinfo_reverse) );
    
    if(cspec->cinfo_forward.valid == CINFO_VALID)
        local_stream += msg_field_qmp_get_from_stream(local_stream, stream_end, &(cspec->qmp_forward), QMP_FORWARD);
    
    if(cspec->cinfo_reverse.valid == CINFO_VALID)
        msg_field_qmp_get_from_stream(local_stream, stream_end, &(cspec->qmp_reverse), QMP_REVERSE);
    
    cp_dbg_cspec(*cspec);
    
    return cspec->len;
    
}




/**
 * Set CSPEC on stream.
 * \param	stream	Data destination.
 * \param	cspec	Data source.
 * \return			Length of the data copied.
 * 
 */
len_t
msg_field_cspec_set_on_stream(u8 * stream, cspec_t* cspec)
{
    u8 * local_stream = stream;
    
    dbg_assert_ptr(stream);
    dbg_assert_ptr(cspec);
    cp_dbg_cspec(*cspec);
    
    //cspec_len
    local_stream += 2;
    
    // copy cinfo_forward
    local_stream += msg_field_cinfo_set_on_stream( local_stream, &(cspec->cinfo_forward));
    
    // copy cinfo_reverse
    local_stream += msg_field_cinfo_set_on_stream( local_stream, &(cspec->cinfo_reverse));
    
    // copy qmp_forward
    if (cspec->cinfo_forward.valid == CINFO_VALID)
    {
        local_stream += msg_field_qmp_set_on_stream( local_stream, &(cspec->qmp_forward));
    }
    
    // copy qmp_reverse
    if (cspec->cinfo_reverse.valid == CINFO_VALID)
    {
        local_stream += msg_field_qmp_set_on_stream( local_stream, &(cspec->qmp_reverse));
    }
    
    // copy cspec_len
    *(u16*)stream = htons(local_stream-stream);
    return local_stream - stream;
}