summaryrefslogtreecommitdiff
path: root/cesar/maximus/stationtest/src/test_log.c
blob: 1329144d9f92e991e29995cc8aa909b785a829d7 (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
/* Cesar project {{{
 *
 * Copyright (C) 2012 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    test_station.c
 * \brief   station executable used for the test station program
 * \ingroup
 */

#include "common/std.h"
#include "common/defs/homeplugAV.h"
#include "host/station/station.h" /* for 'station_ctx_t' */
#include "hal/ipmbox/ipmbox.h"
#include "hal/ipmbox/maximus/inc/maximus_ipmbox_ctx.h" /* for 'ipmbox_t' */
#include "hal/ipmbox/maximus/inc/maximus_interrupts.h" /* for
    'HAL_IPMBOX_..._INTERRUPT' */
#include "maximus/common/types/ethernet_types.h" /* for 'ETHERNET_TYPE_...' */
#include "common/ipmbox/msg.h"
#include <cyg/infra/diag.h>
#include <stdio.h>

#define RESULT_SUCCESS 0x00
#define CM_SET_KEY_REQ_MMTYPE 0x6008

/* DRV_STA_....CNF MMENTRY only contains 1 byte: Result */
#define DRV_STA_CNF_LEN (HPAV_MME_HEADER + 1)

/* CM_SET_KEY.CNF MMENTRY contains:
 - 1 byte: Result
 - 4 bytes: My Nonce
 - 4 bytes: Your Nonce
 - 1 byte: PID
 - 2 bytes: PRN
 - 1 byte: PMN
 - 1 byte: CCo Capability
 => 14 bytes in total */
#define CM_SET_KEY_CNF_LEN (HPAV_MME_HEADER + 14)

extern station_ctx_t my_station;
ipmbox_t *ctx;
int user_data = 123;

void
rx_cb_mbx (void *user_data, u32 *first_msg, uint length)
{
    /* Reset IT. */
    maximus_pending_isrs &= ~(1 << HAL_IPMBOX_RX_INTERRUPT);

    ipmbox_msg_mbx_t *msg_mbx = (ipmbox_msg_mbx_t *) ctx->rx_mbx.mailbox;

    /* When receiving an Ether SCI message of type MME REQ from Maximus,
     * send the answer (an Ether SCI message of type MME CNF)
     * with an Ether SCI message of type BUFFER_RELEASED. */

    /* REQ data length. */
    uint data_length = ipmbox_msg_get_mme_priv_length (msg_mbx->header);

    /* REQ data. */
    u32 buffer_addr;
    if (1 != ipmbox_empty_buf_get (ctx, &buffer_addr, 1))
    {
        station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_ETHER,
                     "%s: cannot get empty buf", __FUNCTION__);
    }
    memcpy ((u32 *) buffer_addr, (u32 *) msg_mbx->buffer_addr, data_length);

    /* CNF data. */
    char *cnf_data = (char *) buffer_addr;
    /* REQ => CNF */
    *(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME)) =
        *(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME)) + 1;
    *(cnf_data + HPAV_MME_HEADER) = RESULT_SUCCESS;

    /* CNF data length. */
    uint cnf_data_length = 0;
    u16 mmtype = (
        (u16) (*(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME) + 1) << 8)
        | (u16) (*(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME))));
    if (CM_SET_KEY_REQ_MMTYPE == mmtype)
    {
        cnf_data_length = CM_SET_KEY_CNF_LEN;
    }
    else /* mmtype = DRV_STA_....REQ */
    {
        cnf_data_length = DRV_STA_CNF_LEN;
    }

	/* Tx. */
    msg_mbx->header = ipmbox_msg_create_header_mme_priv (cnf_data_length);
    msg_mbx->buffer_addr = buffer_addr;
    ipmbox_tx_mbx (ctx, (u32 *) msg_mbx, 2);

    return;
}

void
rx_cb_data (void *user_data, u32 *first_msg, uint length)
{
    /* Reset IT. */
    maximus_pending_isrs &= ~(1 << HAL_IPMBOX_RX_INTERRUPT);

    /* In this test, we should not receive an Ether SCI message of type DATA
     * from Maximus. */
    station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_ETHER,
                 "%s: rx cb data should not be called", __FUNCTION__);

    return;
}

void
empty_buf_cb (void *user_data)
{
    /* Reset IT. */
    maximus_pending_isrs &= ~(1 << HAL_IPMBOX_BUF_INTERRUPT);

    /* When receiving an Ether SCI message of type BUFFER_ADD from Maximus,
     * do nothing: just keep the allocated buffer for future Tx DATA / MME. */
}

int
uninit_ether (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg,
              void *data)
{
    /* Uninitialize the HAL ipmbox. */
    ipmbox_uninit (ctx);

    /* Now make the return parameter list. */
    fcall_param_reset (*param);

    return 0;
}

#define MIN_LEN 2
#define MAX_LEN STATION_MAX_LOG_SIZE
#define BIG_LEN (STATION_MAX_LOG_SIZE + 1)

int test_log (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg,
              void *data)
{
    char min[MIN_LEN];
    memset (min, 'm', MIN_LEN - 1);
    min[MIN_LEN - 1]='\0';

    char max[MAX_LEN];
    memset (max, 'm', MAX_LEN - 1);
    min[MAX_LEN - 1]='\0';

    char big[BIG_LEN];
    memset (big, 'b', BIG_LEN - 1);
    big[BIG_LEN - 1]='\0';

    station_log_set_level(&my_station, STATION_LOG_WARNING);
    station_log_set_mask(&my_station, STATION_LOGTYPE_ALL);
    my_station.pipe_log_fd = 1;

    station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_STATION,
                 "%s", min);
    station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_STATION,
                 "%s", max);
    station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_STATION,
                 "%s", big);

    /* now make the return parameter list */
    fcall_param_reset(*param);

    return 0;
}

int main (void)
{
    /* Initialize the HAL ipmbox. */
    ctx = ipmbox_init ();
    ipmbox_register_rx_data_cb (ctx, (void *) &user_data, &rx_cb_data);
    ipmbox_register_rx_mbx_cb (ctx, (void *) &user_data, &rx_cb_mbx);
    ipmbox_register_empty_buf_cb (ctx, (void *) &user_data,
                                  &empty_buf_cb);

    /* Enable assertions on warnings. */
    ctx->warning_assert = true;

    /* Activate ipmbox interruptions. */
    ipmbox_activate (ctx, true);

    fcall_register (my_station.fcall, "uninit_ether", (void*) &uninit_ether,
                    NULL);
    fcall_register(my_station.fcall, "test_log", (void*) &test_log, NULL);

    return 0;
}