source: rtems-libbsd/testsuite/loopback01/test_main.c @ 5ddce1f

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 5ddce1f was 5ddce1f, checked in by Sebastian Huber <sebastian.huber@…>, on 10/22/13 at 09:06:19

loopback01: Initialize via IFCONFIG(8)

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 *  This is the body of the test. It does not do much except ensure
3 *  that the target is alive after initializing the TCP/IP stack.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8
9#include <rtems/bsd/sys/param.h>
10#include <sys/socket.h>
11#include <netinet/in.h>
12
13#define TEST_NAME "LIBBSD LOOPBACK 1"
14
15#include <rtems/error.h>
16#include <assert.h>
17#include <stdio.h>
18#include <stdarg.h>
19#include <stdlib.h>
20#include <string.h>
21#include <errno.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <sysexits.h>
25
26#include <machine/rtems-bsd-commands.h>
27
28#include <rtems.h>
29
30/*
31 * Thread-safe output routines
32 */
33static rtems_id printMutex;
34static void printSafe(const char *fmt, ...)
35{
36    va_list args;
37    va_start(args, fmt);
38    rtems_semaphore_obtain(printMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
39    vprintf(fmt, args);
40    rtems_semaphore_release(printMutex);
41    va_end(args);
42}
43#define printf printSafe
44
45/*
46 * Spawn a task
47 */
48static void spawnTask(rtems_task_entry entryPoint, rtems_task_priority priority, rtems_task_argument arg)
49{
50    rtems_status_code sc;
51    rtems_id tid;
52
53    sc = rtems_task_create(rtems_build_name('t','a','s','k'),
54            priority,
55            RTEMS_MINIMUM_STACK_SIZE+(8*1024),
56            RTEMS_PREEMPT|RTEMS_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
57            RTEMS_FLOATING_POINT|RTEMS_LOCAL,
58            &tid);
59    if (sc != RTEMS_SUCCESSFUL)
60        rtems_panic("Can't create task: %s", rtems_status_text(sc));
61    sc = rtems_task_start(tid, entryPoint, arg);
62    if (sc != RTEMS_SUCCESSFUL)
63        rtems_panic("Can't start task: %s", rtems_status_text(sc));
64}
65
66/*
67 * Server subtask
68 */
69static rtems_task workerTask(rtems_task_argument arg)
70{
71    int s = arg;
72    char msg[80];
73    char reply[100];
74    int i;
75
76    for (;;) {
77        if ((i = read(s, msg, sizeof msg)) < 0) {
78            printf("Server couldn't read message from client: %s\n", strerror(errno));
79            break;
80        }
81        if (i == 0)
82            break;
83        rtems_task_wake_after(20); /* Simulate some processing delay */
84        i = sprintf(reply, "Server received %d (%s)", i, msg);
85        if ((i = write(s, reply, i+1)) < 0) {
86            printf("Server couldn't write message to client: %s\n", strerror(errno));
87            break;
88        }
89    }
90    if (close(s) < 0)
91        printf("Can't close worker task socket: %s\n", strerror(errno));
92    printf("Worker task terminating.\n");
93    rtems_task_delete(RTEMS_SELF);
94}
95
96/*
97 * Server Task
98 */
99static rtems_task serverTask(rtems_task_argument arg)
100{
101    int s, s1;
102    socklen_t addrlen;
103  struct sockaddr_in myAddr, farAddr;
104    rtems_task_priority myPriority;
105
106  printf("Create socket.\n");
107  s = socket(AF_INET, SOCK_STREAM, 0);
108  if (s < 0)
109    rtems_panic("Can't create socket: %s\n", strerror(errno));
110    memset(&myAddr, 0, sizeof myAddr);
111  myAddr.sin_family = AF_INET;
112  myAddr.sin_port = htons(1234);
113  myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
114  printf("Bind socket.\n");
115  if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
116    rtems_panic("Can't bind socket: %s\n", strerror(errno));
117  if (listen(s, 5) < 0)
118    printf("Can't listen on socket: %s\n", strerror(errno));
119    rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &myPriority);
120    for(;;) {
121        addrlen = sizeof farAddr;
122        s1 = accept(s, (struct sockaddr *)&farAddr, &addrlen);
123        if (s1 < 0)
124            rtems_panic("Can't accept connection: %s", strerror(errno));
125        else
126            printf("ACCEPTED:%lX\n", ntohl(farAddr.sin_addr.s_addr));
127        spawnTask(workerTask, myPriority, s1);
128    }
129}
130
131/*
132 * The real part of the client
133 */
134static rtems_task clientWorker(int arg)
135{
136  int s;
137  struct sockaddr_in myAddr, farAddr;
138  char cbuf[50];
139  int i;
140
141  s = socket(AF_INET, SOCK_STREAM, 0);
142  if (s < 0) {
143    printf("Can't create client socket: %s\n", strerror(errno));
144    return;
145  }
146  memset(&myAddr, 0, sizeof myAddr);
147  myAddr.sin_family = AF_INET;
148  myAddr.sin_port = htons(0);
149  myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
150  if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
151    printf("Can't bind socket: %s\n", strerror(errno));
152    goto close;
153  }
154
155  memset(&farAddr, 0, sizeof farAddr);
156  farAddr.sin_family = AF_INET;
157  farAddr.sin_port = htons(1234);
158  farAddr.sin_addr.s_addr = htonl(INADDR_ANY);
159  printf("Connect to server.\n");
160  if (connect(s, (struct sockaddr *)&farAddr, sizeof farAddr) < 0) {
161    printf("Can't connect to server: %s\n", strerror(errno));
162        goto close;
163    }
164    rtems_task_wake_after(20); /* Simulate client delay */
165    i = sprintf(cbuf, "Hi there, server (%d).", arg);
166    i++;    /* Send the '\0', too */
167    printf("Write %d-byte message to server.\n", i);
168    if (write(s, cbuf, i) < 0) {
169      printf("Can't write to server: %s\n", strerror(errno));
170      goto close;
171    }
172    if ((i = read(s, cbuf, sizeof cbuf)) < 0) {
173      printf("Can't read from server: %s\n", strerror(errno));
174      goto close;
175    }
176    printf("Read %d from server: %.*s\n", i, i, cbuf);
177    rtems_task_wake_after(20); /* Simulate client delay */
178  close:
179    printf("Client closing connection.\n");
180    if (close(s) < 0)
181        printf("Can't close client task socket: %s\n", strerror(errno));
182}
183
184/*
185 * Client Task
186 */
187static rtems_task clientTask(rtems_task_argument arg)
188{
189    clientWorker(arg);
190    printf("Client task terminating.\n");
191    rtems_task_delete( RTEMS_SELF );
192}
193
194/*
195 * RTEMS Startup Task
196 */
197static void test_main(void)
198{
199  rtems_status_code    sc;
200  rtems_task_priority  old;
201  int                  exit_code;
202  char *lo0[] = {
203    "ifconfig",
204    "lo0",
205    "inet",
206    "127.0.0.1",
207    "netmask",
208    "255.255.255.0",
209    NULL
210  };
211
212  sc = rtems_semaphore_create(
213    rtems_build_name('P','m','t','x'),
214    1,
215    RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|
216      RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
217    0,
218    &printMutex
219  );
220  if (sc != RTEMS_SUCCESSFUL)
221    rtems_panic("Can't create printf mutex:", rtems_status_text(sc));
222
223  sc = rtems_task_set_priority( RTEMS_SELF, 50, &old );
224  if (sc != RTEMS_SUCCESSFUL)
225    rtems_panic("Can't create printf mutex:", rtems_status_text(sc));
226
227  /*
228   *  Network is initialized when we get her
229   */
230
231  printf("Try running client with no server present.\n");
232  printf("Should fail with `connection refused'.\n");
233  clientWorker(0);
234
235  exit_code = rtems_bsd_command_ifconfig(nitems(lo0) - 1, lo0);
236  assert(exit_code == EX_OK);
237
238  printf("\nStart server.\n");
239  spawnTask(serverTask, 150, 0);
240
241  printf("\nTry running client with server present.\n");
242  spawnTask(clientTask, 120, 1);
243  rtems_task_wake_after(500);
244
245  printf("\nTry running two clients.\n");
246  spawnTask(clientTask, 120, 2);
247  spawnTask(clientTask, 120, 3);
248  rtems_task_wake_after(500);
249
250  printf("\nTry running three clients.\n");
251  spawnTask(clientTask, 120, 4);
252  spawnTask(clientTask, 120, 5);
253  spawnTask(clientTask, 120, 6);
254
255  rtems_task_wake_after(500);
256  puts( "*** END OF " TEST_NAME " TEST ***" );
257  exit( 0 );
258}
259
260#include <rtems/bsd/test/default-init.h>
Note: See TracBrowser for help on using the repository browser.