summaryrefslogtreecommitdiffstats
path: root/README.md
blob: 76abc66ded7afde4cd0911ca64194742ba5d004e (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
# Waltham-receiver

waltham-receiver component is a receiver side implementation for using Waltham
protocol to obtain and process remote output received from remoting-pluging
instantianted/created output by the compositor.

This component is designed to be used for evaluating the functionalities of
waltham-transmitter plugin.

This component also acts as weston client application to display/handle various
requests from actual weston client at transmitter side.

### Architecture

````

				ECU 1                                                                     ECU 2
              +-----------------------------------------------------+                    +----------------------------------------------+
              |        +-----------------+                          |                    |                                              |
              |        | IVI-Application |                          |                    |               +-----------+-----------+      |
              |        +-----------------+                          |                    |               | Gstreamer |           |      |
              |                 ^                                   |    Buffer   -----------------------> (Decode)  |           |      |
              |        wayland  |                         +----------------------/       |               +-----------+           |      |
              |                 v                         |         |    (Ethernet)      |               |     Waltham-receiver  |      |
              |   +----+---------------------+            |         |        ---------------------------->                       |      |
              |   |    |  Transmitter Plugin |<-----------------------------/            |               +-----------------------+      |
              |   |    |                     |            |         |  Waltham-Protocol  |                             ^                |
              |   |    |---------------------|            |         |                    |                     wayland |                |
              |   |    |  (remoting-plugin)  |------------+         |                    |                             v                |
              |   |    |                     |                      |                    |                 +---------------------+      |
              |   |    +-+-------------------+                      |                    |                 |                     |      |
              |   |                          |                      |                    |                 |       compositor    |      |
              |   |         compositor       |                      |                    |                 |                     |      |
              |   +------+-------------------+                      |                    |                 +----------------+----+      |
              |          |                                          |                    |                                  |           |
              |          v                                          |                    |                                  v           |
              |   +------------+                                    |                    |                            +----------+      |
              |   |  Display   |                                    |                    |                            |  Display |      |
              |   |            |                                    |                    |                            |          |      |
              |   +------------+                                    |                    |                            +----------+      |
              +-----------------------------------------------------+                    +----------------------------------------------+

````

### Build Steps (these only apply if building locally)

1. Prerequisite before building

    weston, wayland, waltham and gstreamer should be built and available.

2. In waltham-receiver directory, create build directory

        $ meson -Dprefix=$PREFIX_PATH build/

3. Run ninja

        $ ninja -C build/

4. waltham-receiver binary should be availaible in build directory

### Connection Establishment

1. Connect two board over ethernet.

2. Assign IP to both the boards and check if the simple ping works.

	For example:if transmitter IP: 192.168.2.51 and Waltham-Receiver IP:
	192.168.2.52 then

    $ping 192.168.2.52 (you can also ping vice versa)

3. Make sure that IP address specified in the weston.ini under
   [transmitter-output] matches the Waltham-Receiver IP.

4. Make sure that IP address on the transmitter side match the Waltham-Receiver
   IP.

### Basic test steps with AGL

0. Under AGL platform you should already have the waltham-receiver installed.

1. Start the compositor with the transmitter plugin at the transmitter side,
   use agl-shell-app-id=app_id of the run the application and put it on
   transmitter screen. Setup a shared port between transmitter and receiver.
   Setup the receiver IP address. The transmitter-plugin uses the same section
   syntax as the remoting plugin.

2. Start the compositor at the receiver side

3. Start the receiver using -p <shared_port> -i <app_id>. If not app_id is
   specified the app_id passed by the transmitter will be used. Use -i <app_id>
   if you'd like to have the ability to activate and switch the surface if you
   intended to start multiple application and still be able to send input and
   display the received streamed buffers from the transmitter side.

4. Start the application on the transmitter side and watch it appear on the
   receiver side.
RESS "icipc-sender-receiver" struct event_data { const uint8_t * expected_data; size_t expected_size; int connections; int n_events; GMutex mutex; }; static void wait_for_event (struct event_data *data, int n_events) { while (true) { g_mutex_lock (&data->mutex); if (data->n_events == n_events) { g_mutex_unlock (&data->mutex); break; } g_mutex_unlock (&data->mutex); } } static void sender_state_callback (struct icipc_receiver *self, int sender_fd, enum icipc_receiver_sender_state sender_state, void *p) { struct event_data *data = p; g_assert_nonnull (data); g_mutex_lock (&data->mutex); switch (sender_state) { case ICIPC_RECEIVER_SENDER_STATE_CONNECTED: data->connections++; break; case ICIPC_RECEIVER_SENDER_STATE_DISCONNECTED: data->connections--; break; default: g_assert_not_reached (); break; } data->n_events++; g_mutex_unlock (&data->mutex); } static void reply_callback (struct icipc_sender *self, const uint8_t *buffer, size_t size, void *p) { struct event_data *data = p; g_assert_nonnull (data); g_assert_nonnull (buffer); g_mutex_lock (&data->mutex); g_assert_cmpmem (buffer, size, data->expected_data, data->expected_size); data->n_events++; g_mutex_unlock (&data->mutex); } static void test_icipc_receiver_basic () { struct icipc_receiver *r = icipc_receiver_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (r); /* start and stop */ g_assert_false (icipc_receiver_is_running (r)); g_assert_true (icipc_receiver_start (r)); g_assert_true (icipc_receiver_is_running (r)); icipc_receiver_stop (r); g_assert_false (icipc_receiver_is_running (r)); /* clean up */ icipc_receiver_free (r); } static void test_icipc_sender_basic () { struct icipc_sender *s = icipc_sender_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (s); /* clean up */ icipc_sender_free (s); } static void test_icipc_sender_connect () { static struct icipc_receiver_events events = { .sender_state = sender_state_callback, .handle_message = NULL, }; struct event_data data; g_mutex_init (&data.mutex); data.n_events = 0; data.connections = 0; struct icipc_receiver *r = icipc_receiver_new (TEST_ADDRESS, 16, &events, &data, 0); g_assert_nonnull (r); struct icipc_sender *s = icipc_sender_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (s); /* start receiver */ g_assert_true (icipc_receiver_start (r)); /* connect sender */ g_assert_true (icipc_sender_connect (s)); g_assert_true (icipc_sender_is_connected (s)); wait_for_event (&data, 1); g_assert_cmpint (data.connections, ==, 1); /* disconnect sender */ icipc_sender_disconnect (s); g_assert_false (icipc_sender_is_connected (s)); wait_for_event (&data, 2); g_assert_cmpint (data.connections, ==, 0); /* stop receiver */ icipc_receiver_stop (r); /* clean up */ g_mutex_clear (&data.mutex); icipc_sender_free (s); icipc_receiver_free (r); } static void lost_connection_handler (struct icipc_sender *self, int receiver_fd, void *p) { struct event_data *data = p; g_assert_nonnull (data); g_mutex_lock (&data->mutex); data->n_events++; g_mutex_unlock (&data->mutex); } static void test_icipc_sender_lost_connection () { struct event_data data; g_mutex_init (&data.mutex); struct icipc_receiver *r = icipc_receiver_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (r); struct icipc_sender *s = icipc_sender_new (TEST_ADDRESS, 16, lost_connection_handler, &data, 0); g_assert_nonnull (s); /* connect sender */ g_assert_true (icipc_sender_connect (s)); g_assert_true (icipc_sender_is_connected (s)); /* destroy receiver and make sure the lost connection handler is triggered */ data.n_events = 0; icipc_receiver_free (r); wait_for_event (&data, 1); /* clean up */ g_mutex_clear (&data.mutex); icipc_sender_free (s); } static void test_icipc_sender_send () { struct icipc_receiver *r = icipc_receiver_new (TEST_ADDRESS, 2, NULL, NULL, 0); g_assert_nonnull (r); struct icipc_sender *s = icipc_sender_new (TEST_ADDRESS, 2, NULL, NULL, 0); g_assert_nonnull (s); struct event_data data; g_mutex_init (&data.mutex); data.n_events = 0; /* start receiver */ g_assert_true (icipc_receiver_start (r)); /* connect */ g_assert_true (icipc_sender_connect (s)); g_assert_true (icipc_sender_is_connected (s)); /* send 1 byte message (should not realloc) */ data.n_events = 0; data.expected_data = (const uint8_t *)"h"; data.expected_size = 1; g_assert_true (icipc_sender_send (s, (const uint8_t *)"h1", 1, reply_callback, &data)); wait_for_event (&data, 1); /* send 2 bytes message (should realloc once to 4) */ data.n_events = 0; data.expected_data = (const uint8_t *)"hi"; data.expected_size = 2; g_assert_true (icipc_sender_send (s, (const uint8_t *)"hi", 2, reply_callback, &data)); wait_for_event (&data, 1); /* send 3 bytes message (should not realloc) */ data.n_events = 0; data.expected_data = (const uint8_t *)"hii"; data.expected_size = 3; g_assert_true (icipc_sender_send (s, (const uint8_t *)"hii", 3, reply_callback, &data)); wait_for_event (&data, 1); /* send 28 bytes message (should realloc 3 times: first to 8, then to 16 and finally to 32) */ data.n_events = 0; data.expected_data = (const uint8_t *)"bigger than 16 bytes message"; data.expected_size = 28; g_assert_true (icipc_sender_send (s, (const uint8_t *)"bigger than 16 bytes message", 28, reply_callback, &data)); wait_for_event (&data, 1); /* don't allow empty messages */ data.n_events = 0; g_assert_false (icipc_sender_send (s, (const uint8_t *)"", 0, NULL, NULL)); /* stop receiver */ icipc_receiver_stop (r); /* clean up */ g_mutex_clear (&data.mutex); icipc_sender_free (s); icipc_receiver_free (r); } static void test_icipc_multiple_senders_send () { struct icipc_receiver *r = icipc_receiver_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (r); struct icipc_sender *senders[50]; struct event_data data; g_mutex_init (&data.mutex); data.n_events = 0; /* start receiver */ g_assert_true (icipc_receiver_start (r)); /* create and connect 50 senders */ for (int i = 0; i < 50; i++) { senders[i] = icipc_sender_new (TEST_ADDRESS, 16, NULL, NULL, 0); g_assert_nonnull (senders[i]); g_assert_true (icipc_sender_connect (senders[i])); g_assert_true (icipc_sender_is_connected (senders[i])); } /* send 50 messages (1 per sender) */ data.n_events = 0; data.expected_data = (const uint8_t *)"hello"; data.expected_size = 5; for (int i = 0; i < 50; i++) g_assert_true (icipc_sender_send (senders[i], (const uint8_t *)"hello", 5, reply_callback, &data)); wait_for_event (&data, 50); /* stop receiver */ icipc_receiver_stop (r); /* clean up */ g_mutex_clear (&data.mutex); for (int i = 0; i < 50; i++) icipc_sender_free (senders[i]); icipc_receiver_free (r); } gint main (gint argc, gchar *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/icipc/receiver-basic", test_icipc_receiver_basic); g_test_add_func ("/icipc/sender-basic", test_icipc_sender_basic); g_test_add_func ("/icipc/sender-connect", test_icipc_sender_connect); g_test_add_func ("/icipc/sender-lost-connection", test_icipc_sender_lost_connection); g_test_add_func ("/icipc/sender-send", test_icipc_sender_send); g_test_add_func ("/icipc/multiple-senders-send", test_icipc_multiple_senders_send); return g_test_run (); }