summaryrefslogtreecommitdiff
path: root/cleopatre/plcdrv/gidel/src/processing.c
blob: 6ff7917505de257dd35f4ae738e169fe32152772 (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
/* Cesar project {{{
 *
 * Copyright (C) 2008 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    processing.c
 * \brief   Processing layer for the PLC driver.
 * \ingroup Cleopatre - Isis
 *
 * this layer is used to check every packet received by CESAR or TUN/TAP
 * and sometime drop it.
 */

#define DEBUG 1

#include "common.h"
#include "processing.h"
#include <stdio.h>
#ifndef _UTESTS_
#include "mailbox.h"
#include "plc_drv.h"
#else
#include "mailbox_stub.h"
#include "plc_drv_stub.h"
#endif

#define ETH_SRC_ADDR_OFFSET     0
#define ETH_SRC_ADDR_SIZE       6
#define ETH_DST_ADDR_OFFSET     ETH_SRC_ADDR_SIZE
#define ETH_DST_ADDR_SIZE       6
#define ETH_TYPE_OFFSET         ETH_DST_ADDR_OFFSET + ETH_DST_ADDR_SIZE
#define ETH_TYPE_SIZE           2
#define ETH_MME_VERSION_OFFSET  ETH_TYPE_OFFSET + ETH_TYPE_SIZE
#define ETH_MME_VERSION_SIZE    1
#define ETH_MME_TYPE_OFFSET     ETH_MME_VERSION_OFFSET + ETH_MME_VERSION_SIZE
#define ETH_MME_TYPE_SIZE       2
#define ETH_MME_FMI_OFFSET      ETH_MME_TYPE_OFFSET + ETH_MME_TYPE_SIZE
#define ETH_MME_FMI_SIZE        2

#define ETH_MME_HPAV_TYPE       0x88E1
#define MME_HPAV_TYPE_FCALL     0xABCD

/**
 * Find the Ethernet source Address.
 */
void get_eth_src_addr(uint8_t* eth_frame, uint8_t source[6])
{
    uint8_t i;
    for(i=0;i<ETH_SRC_ADDR_SIZE;i++)
    {
        source[ETH_SRC_ADDR_SIZE - 1 - i] = *(eth_frame + i + ETH_SRC_ADDR_OFFSET);
    }
}

/**
 * Find the Ethernet source Address.
 */
void get_eth_dst_addr(uint8_t* eth_frame, uint8_t dest[6])
{
    uint8_t i;
    for(i=0;i<ETH_DST_ADDR_SIZE;i++)
    {
        dest[ETH_DST_ADDR_OFFSET -1 - i] = *(eth_frame + i + ETH_DST_ADDR_OFFSET);
    }
}

/**
 * Find the Ethernet type.
 */
uint16_t get_eth_type(uint8_t* eth_frame)
{
    uint16_t type = 0;
    type = (*(eth_frame + ETH_TYPE_OFFSET) << 8);
    type |= *(eth_frame + ETH_TYPE_OFFSET + 1);
    return type;
}

/**
 * Find the Ethernet MME version.
 */
uint8_t get_eth_mme_version(uint8_t* eth_frame)
{
    return *(eth_frame + ETH_TYPE_OFFSET);
}

/**
 * Find the Ethernet MME type.
 */
uint16_t get_eth_mme_type(uint8_t* eth_frame)
{
    uint16_t type = 0;
    type = (*(eth_frame + ETH_MME_TYPE_OFFSET + 1) << 8);
    type |= *(eth_frame + ETH_MME_TYPE_OFFSET);
    return type;
}

/**
 * Find the Ethernet MME type.
 */
uint16_t get_eth_mme_fmi(uint8_t* eth_frame)
{
    uint16_t fmi = 0;
    fmi = (*(eth_frame + ETH_MME_FMI_OFFSET) << 8);
    fmi |= *(eth_frame + ETH_MME_FMI_OFFSET + 1);
    return fmi;
}


/** 
 * Initialize the processing layer.
 *
 * \param  init  user information.
 */
void processing_init (struct init_info *init)
{
    //Init lower layers
    mailbox_init(init);
}

/** 
 * UnInitialize the processing layer.
 */
void processing_uninit (void)
{
    //Uninit lower layers
    mailbox_uninit();
}

/**
 * Processing procedure for a A->L message.
 *
 * \param  pointer  packet pointer.
 * \param  length  length of the packet pointed.
 * \return  status queue.
 */
int processing_send (void *pointer, int length)
{
    int result;

    //TODO:if frame not ok drop it (for Gidel : do nothing)

    //Check which type of frame is it and send it
    if(get_eth_type((uint8_t*)pointer) == ETH_MME_HPAV_TYPE)
    {
        if(get_eth_mme_type((uint8_t*)pointer) == MME_HPAV_TYPE_FCALL)
        {
            TRACE("In the processing_send : INTERFACE\n");
            result = mailbox_send(pointer, length, INTERFACE);
        }
        else
        {
            TRACE("In the processing_send : MME\n");
            result = mailbox_send(pointer, length, MME);
        }
    }
    else
    {
        TRACE("In the processing_send : DATA\n");
        result = mailbox_send(pointer, length, DATA);
    }
    return result;
}

/**
 * Processing procedure for a L->A message
 *
 * \param  pointer  packet pointer.
 * \param  length  length of the packet pointed.
 * \param  type  type of message.
 * \return  error code.
 */
int processing_receive (void *pointer, int length, enum buffer_type type)
{
    //TODO:Check which type of frame is it

    //TODO:if frame not ok drop it (for Gidel : do nothing)
    
    //TODO:Send the packet to the TX part with processing_send(pointer, length)


    if(type == INTERFACE)
    {
        TRACE("In the processing_receive : INTERFACE\n");
    }
    else if(type == MME)
    {
        TRACE("In the processing_receive : MME\n");
    }
    else if(type == DATA)
    {
        TRACE("In the processing_receive : DATA\n");
    }


    //Or Send packet to the upper layers
    return plcdrv_rx(pointer, length);
}