Skip to content

Commit af4d4a5

Browse files
authored
TCP/IP Bundle Unix (#34)
* first sketch of tcp/ip bundle on unix * fixed bug in bundle and added errors * factoring out encoding and decoding of protobuf * working state with extra function to toggle blocking vs non-blocking * code cleanup * adding nanopb as a proper git submodule * exclude protobuf generated files from checks * fixing ci
1 parent 7b42427 commit af4d4a5

27 files changed

+499
-36
lines changed

.clang-tidy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ Checks: '
99
cert-*,
1010
-readability-else-after-return,
1111
-clang-analyzer-core.CallAndMessage,
12-
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling'
12+
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
13+
-modernize-macro-to-enum
14+
'
1315
WarningsAsErrors: true
1416
HeaderFilterRegex: ''
1517
AnalyzeTemporaryDtors: false
16-
FormatStyle: none
18+
FormatStyle: none

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "external/Unity"]
22
path = external/Unity
33
url = https://github.com/ThrowTheSwitch/Unity.git
4+
[submodule "external/nanopb"]
5+
path = external/nanopb
6+
url = https://github.com/nanopb/nanopb.git

CMakeLists.txt

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.9)
22
project(reactor-uc LANGUAGES C)
33

44
# Command line options for the build
5+
set(BUILD_EXAMPLES ON CACHE BOOL "Build examples")
56
set(BUILD_TESTS OFF CACHE BOOL "Build all tests")
67
set(BUILD_LF_TESTS OFF CACHE BOOL "Build lf tests")
78
set(BUILD_UNIT_TESTS OFF CACHE BOOL "Build unit tests")
@@ -38,19 +39,39 @@ if(BUILD_TESTS)
3839
endif()
3940
endif()
4041

41-
# TODO: Explicitly name all the sources.
42-
file(GLOB SOURCES "src/*.c")
43-
message(${SOURCES})
42+
file(GLOB SOURCES "src/*.c" "src/generated/*.c")
43+
44+
# you maybe think this is stupid, but the nanopb cmake-package exports only cpp functions & libraries
45+
add_library(nanopb
46+
external/nanopb/pb_decode.c
47+
external/nanopb/pb_encode.c
48+
external/nanopb/pb_decode.c
49+
external/nanopb/pb_common.c
50+
)
51+
52+
set_target_properties(nanopb PROPERTIES C_CLANG_TIDY "") # Disable clang-tidy for this external lib.
53+
set_source_files_properties("external/nanopb/*.c" PROPERTIES SKIP_LINTING ON)
54+
set_source_files_properties(src/generated/message.pb.c include/reactor-uc/generated/message.pb.h PROPERTIES SKIP_LINTING ON)
4455

4556
if (PLATFORM STREQUAL "POSIX")
4657
add_library(reactor-uc STATIC ${SOURCES})
47-
target_compile_definitions(reactor-uc PUBLIC PLATFORM_POSIX)
48-
target_link_libraries(reactor-uc PRIVATE pthread)
58+
add_compile_definitions(PLATFORM_POSIX)
59+
target_include_directories(reactor-uc PUBLIC external/)
60+
target_link_libraries(reactor-uc PRIVATE pthread nanopb)
61+
62+
if(BUILD_EXAMPLES)
63+
add_subdirectory(examples/posix)
64+
endif ()
65+
4966
elseif (PLATFORM STREQUAL "ZEPHYR")
5067
zephyr_library_named(reactor-uc)
5168
zephyr_library_sources(${SOURCES})
5269
zephyr_library_link_libraries(kernel)
5370
add_compile_definitions(PLATFORM_ZEPHYR)
71+
72+
if(BUILD_EXAMPLES)
73+
add_subdirectory(examples/zephyr)
74+
endif ()
5475
else ()
5576
message(FATAL_ERROR "No valid platform specified")
5677
endif ()

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,18 @@ asan:
3030
make test -C build
3131

3232
# Format the code base
33-
SRC_FILES := $(shell find src -name '*.c')
34-
HDR_FILES := $(shell find include -name '*.h')
33+
SRC_FILES := $(shell find ./src -path ./src/generated -prune -o -name '*.c' -print)
34+
HDR_FILES := $(shell find ./include -path ./include/reactor-uc/generated -prune -o -name '*.h' -print)
35+
3536
format:
3637
clang-format -i -style=file $(SRC_FILES) $(HDR_FILES)
3738

3839
# Check that the code base is formatted
3940
format-check:
4041
clang-format --dry-run --Werror -style=file $(SRC_FILES) $(HDR_FILES)
4142

42-
4343
# Run the entire CI flow
4444
ci: clean test coverage format-check
4545

46-
4746
clean:
4847
rm -rf build

examples/CMakeLists.txt

Whitespace-only changes.

examples/posix/CMakeLists.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
cmake_minimum_required(VERSION 3.20.0)
22
set(PLATFORM "POSIX" CACHE STRING "Platform to target")
33

4-
project(timer-ex)
4+
add_executable(timer_ex timer_ex.c)
5+
target_link_libraries(timer_ex PRIVATE reactor-uc)
56

6-
add_executable(timer_ex)
7-
target_sources(timer_ex PRIVATE timer_ex.c)
8-
add_subdirectory(../../ reactor-uc)
9-
target_link_libraries(timer_ex PRIVATE reactor-uc)
7+
add_executable(tcp_ip_bundle_server testing_posix_tcp_ip_bundle_server.c)
8+
target_link_libraries(tcp_ip_bundle_server PUBLIC reactor-uc)
9+
10+
add_executable(tcp_ip_bundle_client testing_posix_tcp_ip_bundle_client.c)
11+
target_link_libraries(tcp_ip_bundle_client PUBLIC reactor-uc)
12+
13+
add_executable(nanopb_test testing_nanopb.c)
14+
target_link_libraries(nanopb_test PRIVATE reactor-uc nanopb)

examples/posix/testing_nanopb.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
#include "../../../reactor-uc/include/reactor-uc/generated/message.pb.h"
5+
#include "../../../reactor-uc/include/reactor-uc/encoding.h"
6+
7+
#define BUFFER_SIZE 1024
8+
#define MSG_ID 42
9+
10+
int main() {
11+
12+
PortMessage original_message;
13+
PortMessage deserialized_message;
14+
unsigned char buffer[BUFFER_SIZE];
15+
unsigned char * message = NULL;
16+
int message_size = 0;
17+
18+
original_message.connection_number = MSG_ID;
19+
const char* text = "Hello World1234";
20+
memcpy(original_message.message, text, sizeof("Hello World1234")); // NOLINT
21+
22+
message = buffer;
23+
message_size = encode_protobuf(&original_message, buffer, BUFFER_SIZE);
24+
if (message_size < 0) {
25+
printf("encoding failed!\n");
26+
exit(1);
27+
}
28+
29+
int remaining_bytes = decode_protobuf(&deserialized_message, message, message_size);
30+
31+
if (remaining_bytes < 0) {
32+
printf("decoding failed!\n");
33+
exit(1);
34+
}
35+
36+
printf("o: %i d: %i\n", original_message.connection_number, deserialized_message.connection_number);
37+
printf("o: %s d: %s\n", original_message.message, deserialized_message.message);
38+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "reactor-uc/reactor-uc.h"
2+
#include "reactor-uc/platform/posix/tcp_ip_bundle.h"
3+
#include <sys/socket.h>
4+
#include <unistd.h>
5+
6+
#include "reactor-uc/generated/message.pb.h"
7+
8+
int main() {
9+
TcpIpBundle bundle;
10+
11+
// server address
12+
const char* host = "127.0.0.1";
13+
unsigned short port = 8900; // NOLINT
14+
15+
// message for server
16+
PortMessage port_message;
17+
port_message.connection_number = 42; // NOLINT
18+
const char* message = "Hello World1234";
19+
memcpy(port_message.message, message, sizeof("Hello World1234")); // NOLINT
20+
21+
// creating a server that listens on loopback device on port 8900
22+
TcpIpBundle_ctor(&bundle, host, port, AF_INET);
23+
24+
// binding to that address
25+
bundle.connect(&bundle);
26+
27+
// change the bundle to non-blocking
28+
bundle.change_block_state(&bundle, false);
29+
30+
// sending message
31+
bundle.send(&bundle, &port_message);
32+
33+
// waiting for reply
34+
PortMessage* received_message = NULL;
35+
do {
36+
received_message = bundle.receive(&bundle);
37+
} while (received_message == NULL);
38+
39+
printf("Received message with connection number %i and content %s\n", received_message->connection_number, received_message->message);
40+
41+
bundle.close(&bundle);
42+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "reactor-uc/reactor-uc.h"
2+
#include "reactor-uc/platform/posix/tcp_ip_bundle.h"
3+
#include <sys/socket.h>
4+
#include <unistd.h>
5+
6+
int main() {
7+
TcpIpBundle bundle;
8+
9+
const char* host = "127.0.0.1";
10+
unsigned short port = 8900; // NOLINT
11+
12+
// creating a server that listens on loopback device on port 8900
13+
TcpIpBundle_ctor(&bundle, host, port, AF_INET);
14+
15+
// binding to that address
16+
bundle.bind(&bundle);
17+
18+
// change the bundle to non-blocking
19+
bundle.change_block_state(&bundle, false);
20+
21+
// accept one connection
22+
bool new_connection;
23+
do {
24+
new_connection = bundle.accept(&bundle);
25+
} while (!new_connection);
26+
27+
// waiting for messages from client
28+
PortMessage* message = NULL;
29+
do {
30+
message = bundle.receive(&bundle);
31+
sleep(1);
32+
} while (message == NULL);
33+
34+
printf("Received message with connection number %i and content %s\n", message->connection_number, message->message);
35+
36+
bundle.send(&bundle, message);
37+
38+
bundle.close(&bundle);
39+
}

external/nanopb

Submodule nanopb added at 736ac3a

0 commit comments

Comments
 (0)