summaryrefslogtreecommitdiff
path: root/maximus/stationtest/src/test_ether.c
blob: 87a00ecebeff3c8abe725105f8347086e622005f (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
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    test_ether.c
 * \brief   test ether program
 * \ingroup 
 */

#include <cyg/infra/diag.h>
#include <cyg/kernel/kapi.h>
#include <errno.h>
#include "common/std.h"
#include "host/station.h"
#include "hal/hle/ipmbox.h"
#include "hal/hle/defs.h" // for 'HLE_MSG_TYPE_...' and 'ipmbox_msg_hdr_t'
#include "hal/hle/maximus/inc/maximus_ipmbox_ctx.h" // for 'ipmbox_t'
#include "hal/hle/maximus/inc/maximus_interrupts.h" // for 'HAL_HLE_INTERRUPT_IPMBOX'
#include "maximus/common/types/ethernet_types.h" // for 'ETHERNET_TYPE_...'
#include <stdlib.h> // for 'malloc()'

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


void ipmbox_rx_cb (void *user_data, u32 *first_msg, uint length)
{
    diag_write_string("=> ipmbox_rx_cb\n");

    // Reset IT
    maximus_pending_isrs &= (0 << HAL_HLE_INTERRUPT_IPMBOX);

    ipmbox_msg_hdr_t *hdr = (ipmbox_msg_hdr_t *)&ctx->rx.mailbox[0];
    if (HLE_MSG_TYPE_DATA == hdr->type)
    {
        /* When receiving an Ether SCI message of type DATA or MME from Maximus,
         * answer by sending a first Ether SCI message of type DATA,
         * with an Ether SCI message of type BUFFER_RELEASED,
         * and a second one of type MME,
         * with an Ether SCI message of type BUFFER_RELEASED. */

        uint data_length = (uint)(hdr->param >> 1);
        memcpy(ctx->first_buffer->next->data, (u32 *)ctx->rx.mailbox[1], data_length);
        memcpy(ctx->first_buffer->next->next->data, (u32 *)ctx->rx.mailbox[1], data_length);

        // Release allocated buffer
        hdr->type = HLE_MSG_TYPE_SEND_DONE;
        ipmbox_tx (ctx, ctx->rx.mailbox, 2);

        hdr->type = HLE_MSG_TYPE_DATA;
        hdr->param &= 0xFFE;
        ctx->rx.mailbox[1] = (u32)ctx->first_buffer->next->data;
        ipmbox_tx (ctx, ctx->rx.mailbox, ctx->rx.length);

        hdr->param |= 0x001;
        ctx->rx.mailbox[1] = (u32)ctx->first_buffer->next->data;
        ipmbox_tx (ctx, ctx->rx.mailbox, ctx->rx.length);
    }
    else if (HLE_MSG_TYPE_BUFFER_ADD == hdr->type)
    {
        if (2 == hdr->param)
        {
            /* When receiving an Ether SCI message of type INTERFACE_BUFFER_ADD from Maximus,
             * answer by sending an Ether SCI message of type SNIFFER,
             * with an Ether SCI message of type BUFFER_RELEASED. */

            uint data_length = 64;
            char * p_data = malloc(data_length);
            memset(p_data, '\0', data_length);
            strcpy(p_data, "This is a sniffed packet coming from the station");

            maximus_hle_buffer_t *p_buffer = (maximus_hle_buffer_t *)malloc(sizeof(maximus_hle_buffer_t));
            u32 id = ctx->last_buffer->id;
            ctx->last_buffer->next = p_buffer;
            ctx->last_buffer = p_buffer;
            ctx->last_buffer->next = NULL;
            ctx->last_buffer->id = id;
            ctx->last_buffer->data = (u32 *)p_data;

            hdr->type = HLE_MSG_TYPE_INTERFACE;
            hdr->length = 2;
            hdr->param = ((data_length << 8) & 0x7FF00) | 0x00001;
            ctx->rx.mailbox[1] = 0x00000007;
            ctx->rx.mailbox[2] = (u32)p_data;
            ipmbox_tx (ctx, ctx->rx.mailbox, 3);
        }
    }

    return;
}


int init_ether (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
{
    diag_write_string("=> init_ether\n");

    // Initialize the HAL HLE ipmbox
    ctx = ipmbox_init ((void *)&user_data, &ipmbox_rx_cb);

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

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

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

    return 0; 
}


int uninit_ether (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
{
    diag_write_string("=> uninit_ether\n");

    // Uninitialize the HAL HLE ipmbox
    ipmbox_uninit (ctx);

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

    return 0; 
}


int main(void)
{
    station_log_set_level(&my_station, STATION_LOG_DEBUG);
    station_log_set_mask(&my_station, STATION_LOGTYPE_ALL);
    my_station.pipe_log_fd = 1;

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

    return 0;
}