diff options
| -rw-r--r-- | .clang-format | 45 | ||||
| -rw-r--r-- | .clang-tidy | 19 | ||||
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | compile_flags.txt | 8 | ||||
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | makefile | 26 | ||||
| -rw-r--r-- | src/main.c | 89 |
7 files changed, 191 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b32bad6 --- /dev/null +++ b/.clang-format | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | --- | ||
| 2 | AccessModifierOffset: -4 | ||
| 3 | AlignConsecutiveAssignments: 'true' | ||
| 4 | AlignConsecutiveDeclarations: 'true' | ||
| 5 | AlignEscapedNewlines: Left | ||
| 6 | AlignTrailingComments: 'true' | ||
| 7 | AlwaysBreakAfterReturnType: TopLevelDefinitions | ||
| 8 | BreakBeforeBraces: Stroustrup | ||
| 9 | BreakConstructorInitializers: BeforeComma | ||
| 10 | BreakInheritanceList: BeforeComma | ||
| 11 | ColumnLimit: '0' | ||
| 12 | CompactNamespaces: 'false' | ||
| 13 | Cpp11BracedListStyle: 'false' | ||
| 14 | FixNamespaceComments: 'true' | ||
| 15 | IncludeBlocks: Regroup | ||
| 16 | IncludeCategories: | ||
| 17 | - Regex: '^.*(precomp|pch|stdafx)' | ||
| 18 | Priority: -1 | ||
| 19 | - Regex: '^<.*>' | ||
| 20 | Priority: 1 | ||
| 21 | - Regex: '^".*"' | ||
| 22 | Priority: 2 | ||
| 23 | - Regex: '.*' | ||
| 24 | Priority: 3 | ||
| 25 | IndentCaseLabels: 'false' | ||
| 26 | IndentPPDirectives: AfterHash | ||
| 27 | IndentWidth: '4' | ||
| 28 | IndentWrappedFunctionNames: 'false' | ||
| 29 | KeepEmptyLinesAtTheStartOfBlocks: 'false' | ||
| 30 | PointerAlignment: Right | ||
| 31 | SortIncludes: 'true' | ||
| 32 | SpaceAfterCStyleCast: 'true' | ||
| 33 | SpaceAfterTemplateKeyword: 'false' | ||
| 34 | SpaceBeforeAssignmentOperators: 'true' | ||
| 35 | SpaceBeforeParens: ControlStatements | ||
| 36 | SpaceBeforeRangeBasedForLoopColon: 'false' | ||
| 37 | SpaceInEmptyParentheses: 'false' | ||
| 38 | SpacesInAngles: 'false' | ||
| 39 | SpacesInCStyleCastParentheses: 'false' | ||
| 40 | SpacesInConditionalStatement: 'true' | ||
| 41 | SpacesInParentheses: 'false' | ||
| 42 | Standard: Auto | ||
| 43 | TabWidth: '4' | ||
| 44 | UseTab: ForIndentation | ||
| 45 | ... | ||
diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..0bceb5b --- /dev/null +++ b/.clang-tidy | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | --- | ||
| 2 | Checks: "*, | ||
| 3 | -abseil-*, | ||
| 4 | -altera-*, | ||
| 5 | -android-*, | ||
| 6 | -fuchsia-*, | ||
| 7 | -google-*, | ||
| 8 | -llvm*, | ||
| 9 | -modernize-use-trailing-return-type, | ||
| 10 | -zircon-*, | ||
| 11 | -readability-else-after-return, | ||
| 12 | -readability-static-accessed-through-instance, | ||
| 13 | -readability-avoid-const-params-in-decls, | ||
| 14 | -cppcoreguidelines-non-private-member-variables-in-classes, | ||
| 15 | -misc-non-private-member-variables-in-classes, | ||
| 16 | " | ||
| 17 | WarningsAsErrors: '' | ||
| 18 | HeaderFilterRegex: '' | ||
| 19 | FormatStyle: none | ||
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd42ee3 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | bin/ | ||
| 2 | obj/ | ||
diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..8e3330c --- /dev/null +++ b/compile_flags.txt | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | -Wall | ||
| 2 | -Werror | ||
| 3 | -Wextra | ||
| 4 | -Wconversion | ||
| 5 | -Wdouble-promotion | ||
| 6 | -pedantic | ||
| 7 | -std=c17 | ||
| 8 | -Iinclude | ||
diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..8ca0709 --- /dev/null +++ b/config.mk | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | CFLAGS=-Wall -Werror -Wextra -Wconversion -Wdouble-promotion -pedantic -std=c17 -Iinclude | ||
| 2 | LDFLAGS=-lmosquitto | ||
diff --git a/makefile b/makefile new file mode 100644 index 0000000..7fada65 --- /dev/null +++ b/makefile | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | include config.mk | ||
| 2 | |||
| 3 | BINARY=bin/client | ||
| 4 | |||
| 5 | SRC_FILES=$(wildcard src/*.c) | ||
| 6 | OBJ_FILES=$(patsubst src/%.c,obj/%.o,$(SRC_FILES)) | ||
| 7 | |||
| 8 | release: $(BINARY) | ||
| 9 | release: CFLAGS+=-DNDEBUG -O2 | ||
| 10 | |||
| 11 | debug: $(BINARY) | ||
| 12 | debug: CFLAGS+=-g | ||
| 13 | |||
| 14 | $(BINARY): $(OBJ_FILES) | bin | ||
| 15 | cc $(LDFLAGS) $^ -o $@ | ||
| 16 | |||
| 17 | obj/%.o: src/%.c | obj | ||
| 18 | cc $(CFLAGS) -c $< -o $@ | ||
| 19 | |||
| 20 | bin obj: | ||
| 21 | mkdir -p $@ | ||
| 22 | |||
| 23 | clean: | ||
| 24 | rm -rf bin obj | ||
| 25 | |||
| 26 | .PHONY: release debug clean | ||
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..9579568 --- /dev/null +++ b/src/main.c | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | // Standard C | ||
| 2 | #include <signal.h> | ||
| 3 | #include <stdbool.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | |||
| 7 | // System | ||
| 8 | #include <unistd.h> | ||
| 9 | |||
| 10 | // Project | ||
| 11 | #include <mosquitto.h> | ||
| 12 | |||
| 13 | #define CLIENT_ID "my-client-id" | ||
| 14 | #define HOST "192.168.77.2" | ||
| 15 | #define PORT 1883 | ||
| 16 | #define USERNAME "zigbee2mqtt" | ||
| 17 | #define PASSWORD "xoorei2uk2booSudies4Numoek1uot" | ||
| 18 | #define TOPIC "zigbee2mqtt/Kontaktsensor" | ||
| 19 | #define KEEPALIVE 10 | ||
| 20 | #define WAIT_UNTIL_RECONNECT 10 | ||
| 21 | |||
| 22 | static volatile bool terminate = false; // NOLINT | ||
| 23 | |||
| 24 | void | ||
| 25 | handler(int signal) | ||
| 26 | { | ||
| 27 | if ( signal == SIGINT ) { | ||
| 28 | terminate = true; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | static void | ||
| 33 | message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) | ||
| 34 | { | ||
| 35 | (void) obj; | ||
| 36 | (void) mosq; | ||
| 37 | printf("message '%.*s' for topic '%s'\n", | ||
| 38 | message->payloadlen, (const char *) message->payload, | ||
| 39 | message->topic); | ||
| 40 | } | ||
| 41 | |||
| 42 | int | ||
| 43 | main(void) | ||
| 44 | { | ||
| 45 | (void) signal(SIGINT, handler); | ||
| 46 | |||
| 47 | mosquitto_lib_init(); | ||
| 48 | |||
| 49 | struct mosquitto *client = mosquitto_new(CLIENT_ID, true, NULL); | ||
| 50 | if ( client == NULL ) { | ||
| 51 | (void) fprintf(stderr, "error on new client...\n"); | ||
| 52 | return EXIT_FAILURE; | ||
| 53 | } | ||
| 54 | |||
| 55 | int err = mosquitto_username_pw_set(client, USERNAME, PASSWORD); | ||
| 56 | if ( err != MOSQ_ERR_SUCCESS ) { | ||
| 57 | (void) fprintf(stderr, "error: %s\n", mosquitto_strerror(err)); | ||
| 58 | mosquitto_destroy(client); | ||
| 59 | return EXIT_FAILURE; | ||
| 60 | } | ||
| 61 | |||
| 62 | mosquitto_message_callback_set(client, message_callback); | ||
| 63 | |||
| 64 | err = mosquitto_connect(client, HOST, PORT, KEEPALIVE); | ||
| 65 | if ( err != MOSQ_ERR_SUCCESS ) { | ||
| 66 | (void) fprintf(stderr, "error: %s\n", mosquitto_strerror(err)); | ||
| 67 | mosquitto_destroy(client); | ||
| 68 | return EXIT_FAILURE; | ||
| 69 | } | ||
| 70 | |||
| 71 | mosquitto_subscribe(client, NULL, TOPIC, 0); | ||
| 72 | |||
| 73 | while ( !terminate ) { | ||
| 74 | err = mosquitto_loop(client, -1, 1); | ||
| 75 | if ( !terminate && err ) { | ||
| 76 | (void) fprintf(stderr, "connection error: %s\n", mosquitto_strerror(err)); | ||
| 77 | sleep(WAIT_UNTIL_RECONNECT); // NOLINT | ||
| 78 | mosquitto_reconnect(client); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | printf("cleanup...\n"); | ||
| 83 | mosquitto_disconnect(client); | ||
| 84 | mosquitto_destroy(client); | ||
| 85 | |||
| 86 | mosquitto_lib_cleanup(); | ||
| 87 | |||
| 88 | return EXIT_SUCCESS; | ||
| 89 | } | ||
