aboutsummaryrefslogtreecommitdiffstats
path: root/examples/udp-test.h
blob: 14bbd91cda138ca59a936901e97d2bb44ac28296 (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
#pragma once

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>

#include <osmocom/core/talloc.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <osmocom/core/select.h>
#include <osmocom/netif/datagram.h>

#define MAX_MSG 255
#define NUM_MSG 11
#define DUDP_TEST 0
#define THOST "127.0.0.1"
#define SPORT 15000
#define CPORT 15001

static struct osmo_dgram *conn;
static void *tall_test;
bool please_dont_die = true;

static void sighandler(int foo)
{
	LOGP(DLINP, LOGL_NOTICE, "closing UDP test...\n");
	osmo_dgram_close(conn);
	osmo_dgram_destroy(conn);
	please_dont_die = false;
}

static inline struct msgb *print_recv(struct osmo_dgram *conn)
{
	struct msgb *msg = msgb_alloc(MAX_MSG, "UDP/test");
	int bytes;

	LOGP(DUDP_TEST, LOGL_NOTICE, "received datagram: ");

	if (!msg) {
		LOGPC(DUDP_TEST, LOGL_ERROR, "can't allocate message\n");
		return NULL;
	}

	/* receive message: */
	bytes = osmo_dgram_recv(conn, msg);
	if (bytes < 0) {
		LOGPC(DUDP_TEST, LOGL_ERROR, "can't receive message: %u\n", -bytes);
		msgb_free(msg);
		return NULL;
	}

	/* process message: */
	LOGPC(DUDP_TEST, LOGL_NOTICE, "[%u] %s\n", bytes, msgb_hexdump(msg));

	return msg;
}

static inline bool dgram_init(const char *host, uint16_t lport, uint16_t rport, void *read_cb)
{
	const struct log_info_cat udp_test_cat[] = {
		[DUDP_TEST] = {
			.name = "DUDP_TEST",
			.description = "UDP test",
			.color = "\033[1;35m",
			.enabled = 1, .loglevel = LOGL_NOTICE,
		},
	};

	const struct log_info udp_test_log_info = {
		.filter_fn = NULL,
		.cat = udp_test_cat,
		.num_cat = ARRAY_SIZE(udp_test_cat),
	};

	signal(SIGINT, sighandler);

	tall_test = talloc_named_const(NULL, 1, "udp_test");

	osmo_init_logging(&udp_test_log_info);
	log_set_log_level(osmo_stderr_target, LOGL_NOTICE);

	conn = osmo_dgram_create(tall_test);
	if (!conn) {
		LOGP(DUDP_TEST, LOGL_ERROR, "cannot create UDP socket\n");
		return false;
	}

	osmo_dgram_set_local_addr(conn, host);
	osmo_dgram_set_local_port(conn, lport);
	osmo_dgram_set_remote_addr(conn, host);
	osmo_dgram_set_remote_port(conn, rport);
	osmo_dgram_set_read_cb(conn, read_cb);

	if (osmo_dgram_open(conn) < 0) {
		LOGP(DUDP_TEST, LOGL_ERROR, "cannot open client connection %s:%u -> %s:%u\n", host, lport, host, rport);
		return false;
	}

	return true;
}

static inline void main_loop(const char *host, uint16_t lport, uint16_t rport)
{
	LOGP(DUDP_TEST, LOGL_NOTICE, "Entering main loop: %s:%u -> %s:%u\n", host, lport, host, rport);

	while(please_dont_die)
		osmo_select_main(0);
}

/* Smart message trimmer:
 * for all positive i trims msg to i - 1
 * for i = 0 trims msg to 0
 * for all positive x adds x to msg
*/
/*! Smart message trimmer.
 *  \param[in] msg message buffer
 *  \param[in] i trim value: for all positive i, msg is trimmed to i - 1, otherwise msg is trimmed to 0
 *  \param[in] x message content: for all positive x, x is added to msg, otherwise it's ignored
 */
static inline bool mtrim(struct msgb *msg, uint8_t i, uint8_t x)
{
	if (msgb_trim(msg, i ? i - 1 : i) != 0) {
		LOGP(DLINP, LOGL_ERROR, "failed to trim message by %u\n", i);
		return false;
	}

	if (x)
		msgb_put_u8(msg, x);

	return true;
}