summaryrefslogtreecommitdiff
path: root/cesar/maximus/sci/utest/server/src/fake_Station.cpp
blob: 76ea919da7953d4bfa22fbb9a7dabfc424e4732f (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
/* Maximus project {{{
 *
 * Copyright (C) 2012 MStar Semiconductor
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    maximus/sci/utest/server/src/fake_station.cpp
 * \ingroup maximus_sci_utest_server
 *
 */
#include "maximus/interface/station/inc/Station.h"
#include "maximus/utils/inc/Error.h"
#include "maximus/sci/inc/SciServer.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <netinet/in.h>
#include <assert.h>

Station::Station (
    Maximus &ref1,
    const std::string & station_executable,
    const Network_Clock_Tick current_tick_value,
    uint32_t seed):
    interface (ref1),
    fd_sta2max (-1),
    fd_max2sta (-1),
    fd_log (-1),
    mStationStatus (MAXIMUS_STATION_STATUS_IDLE),
    mStationIdleCounter (0)
{
    int fd_socket[PIPE_WAY_NB] = {-1, -1};
    int fd_pipe[PIPE_WAY_NB][PIPE_NB] = {{-1, -1}, {-1, -1}};
    bool is_socket;

    /* station_executable is equal to "pipe" or "socket". */
    is_socket = (0 != station_executable.compare ("pipe") ?
                 true: false);

    if (is_socket)
        socketpair (AF_LOCAL, SOCK_STREAM, 0, fd_socket);
    else
    {
        pipe (fd_pipe[PIPE_STA2MAX]);
        pipe (fd_pipe[PIPE_MAX2STA]);
    }

    mPid = fork ();

    if (mPid == -1)
    {
        Error e (__PRETTY_FUNCTION__, "fork failed", errno);
        e.display ();
        exit (EXIT_FAILURE);
    }
    else if (mPid == 0)
    {
        /* Child process. */
        if (is_socket)
        {
            close (fd_socket[SOCKET_MAXIMUS]);

            /* socket become stdout and stdin. */
            dup2 (fd_socket[SOCKET_STA], 0);
            dup2 (fd_socket[SOCKET_STA], 1);
            close (fd_socket[SOCKET_STA]);
        }
        else
        {
            /* Child read on its stdin(0). */
            close (fd_pipe[PIPE_MAX2STA][PIPE_WRITE]);
            dup2 (fd_pipe[PIPE_MAX2STA][PIPE_READ], 0);
            close (fd_pipe[PIPE_MAX2STA][PIPE_READ]);

            /* Child write on its stdout(1). */
            close (fd_pipe[PIPE_STA2MAX][PIPE_READ]);
            dup2 (fd_pipe[PIPE_STA2MAX][PIPE_WRITE], 1);
            close (fd_pipe[PIPE_STA2MAX][PIPE_WRITE]);
        }

        fd_max2sta = 0;
        fd_sta2max = 1;

        try
        {
            const int header_size = sizeof (struct Sci_Msg_Header);
            char alloc[SCI_MSG_MAX_SIZE];
            struct Sci_Msg_Header *header = (Sci_Msg_Header *) alloc;
            int msg_size;
            int ret;
            size_t nb_message;

            for (nb_message = 0;
                 nb_message < seed;
                 nb_message++)
            {
                ret = read (fd_max2sta, alloc, header_size);
                assert (ret == header_size);

                msg_size = ntohl (header->length);

                if (msg_size != 0)
                {
                    ret = read (fd_max2sta, alloc + header_size, msg_size);
                    assert (ret == msg_size);
                }

                ret = write (fd_sta2max, alloc, msg_size + header_size);
                assert (ret == msg_size + header_size);
            }
        }
        catch (Error &e)
        {
            e.display ();
            exit (EXIT_FAILURE);
        }

        /* Wait the SIGKILL. */
        pause ();
        exit (EXIT_FAILURE);
    }
    else
    {
        /* Parent process. */
        if (is_socket)
        {
            close (fd_socket[SOCKET_STA]);
            fd_sta2max = fd_socket[SOCKET_MAXIMUS];
            fd_max2sta = fd_socket[SOCKET_MAXIMUS];
        }
        else
        {
            close (fd_pipe[PIPE_MAX2STA][PIPE_READ]);
            close (fd_pipe[PIPE_STA2MAX][PIPE_WRITE]);

            fd_sta2max = fd_pipe[PIPE_STA2MAX][PIPE_READ];
            fd_max2sta = fd_pipe[PIPE_MAX2STA][PIPE_WRITE];
        }
    }
}

Station::~Station ()
{
    kill (mPid, SIGKILL);
}

void
Station::decrementStationIdleCounter ()
{
}

bool
Station::hideStation (
    Sci_Msg_Station_Id station_id, bool hidden)
{
    return true;
}