diff --git a/.bazelrc b/.bazelrc index a32f912..d368fbb 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,3 +1,4 @@ +common --enable_platform_specific_config build --strip=never build --incompatible_enable_cc_toolchain_resolution @@ -20,6 +21,5 @@ test:ppc --run_under="qemu-ppc -L /usr/powerpc-linux-gnu/ " test:ppc64 --run_under="qemu-ppc64 -L /usr/powerpc64-linux-gnu/ " test:ppc64le --run_under="qemu-ppc64le -L /usr/powerpc64le-linux-gnu/ " - # parallel tests break on a single vcan interface -test: --local_test_jobs=1 --test_output=all \ No newline at end of file +test: --local_test_jobs=1 --test_output=all diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7e8e12..1d48733 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,6 @@ on: jobs: build: - runs-on: ubuntu-latest steps: @@ -22,4 +21,13 @@ jobs: - name: run unit tests run: bazel test //test:all --test_tag_filters=-vcan + build-windows: + runs-on: windows-latest + + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: run unit tests + run: bazel test //test:all --verbose_failures --test_output=all diff --git a/amalgamate.py b/amalgamate.py index 60dff98..df17a23 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -19,7 +19,7 @@ def strip_includes(src): return re.sub(r'#include ".*', "", src, flags=re.MULTILINE) isotp_c_wrapped_c = "#if defined(UDS_ISOTP_C)\n" + \ - strip_includes(open("src/tp/isotp-c/isotp.c").read()) + \ + strip_includes(open("src/tp/isotp-c/isotp.c", encoding="utf-8").read()) + \ "#endif\n" isotp_c_wrapped_h = "#if defined(UDS_ISOTP_C)\n" + \ @@ -30,7 +30,7 @@ def strip_includes(src): ]]) + \ "#endif\n" -with open(args.out_c, "w") as f: +with open(args.out_c, "w", encoding="utf-8") as f: f.write("#include \"iso14229.h\"\n") for src in [ "src/client.c", @@ -46,15 +46,16 @@ def strip_includes(src): f.write("#ifdef UDS_LINES\n") f.write(f'#line 1 "{src}"' + "\n") f.write("#endif\n") - with open(src) as src_file: - f.write(strip_includes(src_file.read())) + with open(src, "r", encoding="utf-8") as src_file: + stripped = strip_includes(src_file.read()) + f.write(stripped) f.write("\n") f.write(isotp_c_wrapped_c) f.write("\n") -with open(args.out_h, "w") as f: +with open(args.out_h, "w", encoding="utf-8") as f: f.write("#ifndef ISO14229_H\n") f.write("#define ISO14229_H\n") f.write("\n") @@ -77,8 +78,9 @@ def strip_includes(src): "src/server.h", ]: f.write("\n") - with open(src) as src_file: - f.write(strip_includes(src_file.read())) + with open(src, "r", encoding="utf-8") as src_file: + stripped = strip_includes(src_file.read()) + f.write(stripped) f.write("\n") f.write(isotp_c_wrapped_h) @@ -106,4 +108,4 @@ def strip_includes(src): # os.chmod(iso14229_c, 0o444) if __name__ == "__main__": - print(f"amalgamated source files written to {args.out_c} and {args.out_h}") \ No newline at end of file + print(f"amalgamated source files written to {args.out_c} and {args.out_h}") diff --git a/run_clang_format.sh b/run_clang_format.sh index 8a1e8af..c482ef5 100755 --- a/run_clang_format.sh +++ b/run_clang_format.sh @@ -1,4 +1,4 @@ -#! /bin/bash +#!/bin/bash files=`find src -type f \( -name '*.c' -o -name '*.h' \) -not -path "src/tp/isotp-c/*"` diff --git a/src/config.h b/src/config.h index 5382f53..52229df 100644 --- a/src/config.h +++ b/src/config.h @@ -23,7 +23,7 @@ #define UDS_CLIENT_DEFAULT_P2_STAR_MS (1500U) #endif -_Static_assert(UDS_CLIENT_DEFAULT_P2_STAR_MS > UDS_CLIENT_DEFAULT_P2_MS, ""); +static_assert(UDS_CLIENT_DEFAULT_P2_STAR_MS > UDS_CLIENT_DEFAULT_P2_MS, ""); #ifndef UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS #define UDS_SERVER_DEFAULT_POWER_DOWN_TIME_MS (10) @@ -41,10 +41,10 @@ _Static_assert(UDS_CLIENT_DEFAULT_P2_STAR_MS > UDS_CLIENT_DEFAULT_P2_MS, ""); #define UDS_SERVER_DEFAULT_S3_MS (3000) #endif -_Static_assert(0 < UDS_SERVER_DEFAULT_P2_MS && - UDS_SERVER_DEFAULT_P2_MS < UDS_SERVER_DEFAULT_P2_STAR_MS && - UDS_SERVER_DEFAULT_P2_STAR_MS < UDS_SERVER_DEFAULT_S3_MS, - ""); +static_assert(0 < UDS_SERVER_DEFAULT_P2_MS && + UDS_SERVER_DEFAULT_P2_MS < UDS_SERVER_DEFAULT_P2_STAR_MS && + UDS_SERVER_DEFAULT_P2_STAR_MS < UDS_SERVER_DEFAULT_S3_MS, + ""); // Amount of time to wait after boot before accepting 0x27 requests. #ifndef UDS_SERVER_0x27_BRUTE_FORCE_MITIGATION_BOOT_DELAY_MS diff --git a/src/sys_unix.h b/src/sys_unix.h index 6222363..fa4576b 100644 --- a/src/sys_unix.h +++ b/src/sys_unix.h @@ -2,6 +2,7 @@ #if UDS_SYS == UDS_SYS_UNIX +#include #include #include #include diff --git a/src/sys_win32.h b/src/sys_win32.h index 0bf3d94..f39b4a4 100644 --- a/src/sys_win32.h +++ b/src/sys_win32.h @@ -1,8 +1,20 @@ #pragma once -#if UDS_SYS == UDS_SYS_WIN32 +#if UDS_SYS == UDS_SYS_WINDOWS +#include +#include +#include +#include +#include +#include +#include #include typedef SSIZE_T ssize_t; +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + #endif diff --git a/src/tp/isotp_sock.c b/src/tp/isotp_sock.c index fde9c9b..c19f7d6 100644 --- a/src/tp/isotp_sock.c +++ b/src/tp/isotp_sock.c @@ -147,18 +147,18 @@ static int LinuxSockBind(const char *if_name, uint32_t rxid, uint32_t txid, bool perror("setsockopt"); return -1; } - + struct can_isotp_options opts; memset(&opts, 0, sizeof(opts)); // configure socket to wait for tx completion to catch FC frame timeouts opts.flags |= CAN_ISOTP_WAIT_TX_DONE; - + if (functional) { printf("configuring fd: %d as functional\n", fd); // configure the socket as listen-only to avoid sending FC frames opts.flags |= CAN_ISOTP_LISTEN_MODE; } - + if (setsockopt(fd, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)) < 0) { perror("setsockopt (isotp_options):"); return -1; diff --git a/test/BUILD b/test/BUILD index c6594fe..23b5729 100644 --- a/test/BUILD +++ b/test/BUILD @@ -9,15 +9,24 @@ cc_library( ], deps = [ "@cmocka" ], defines = [ - "UDS_TP_ISOTP_C_SOCKETCAN", - "UDS_TP_ISOTP_SOCK", "UDS_TP_MOCK", "UDS_CUSTOM_MILLIS", "UDS_ENABLE_DBG_PRINT", "UDS_ENABLE_ASSERT", # "UDS_LINES", - ], - copts = [ "-g", ], + ] + select({ + "//conditions:default": [ + "UDS_TP_ISOTP_C_SOCKETCAN", + "UDS_TP_ISOTP_SOCK", + ], + "@bazel_tools//src/conditions:windows": [ + ], + }), + copts = select({ + "//conditions:default": ["-g"], + "@bazel_tools//src/conditions:windows": [ + ], + }), ) TEST_SRCS = [ @@ -53,7 +62,11 @@ TEST_NAMES = [ src.split(".c")[0] for src in TEST_SRCS ] deps=[":env"], size = "small", env = { "UDS_TP_TYPE": "0", }, - copts = ["-g"], + copts = select({ + "//conditions:default": ["-g"], + "@bazel_tools//src/conditions:windows": [ + ], + }), tags = [ "exclusive", ], ) for name, src in zip(TEST_NAMES, TEST_SRCS) ] @@ -67,6 +80,7 @@ TEST_NAMES = [ src.split(".c")[0] for src in TEST_SRCS ] env = { "UDS_TP_TYPE": "1"}, copts = ["-g"], tags = [ "exclusive", "vcan", "isotp_sock"], + target_compatible_with = ["@platforms//os:linux"], ) for name, src in zip(TEST_NAMES, TEST_SRCS) ] @@ -79,6 +93,7 @@ TEST_NAMES = [ src.split(".c")[0] for src in TEST_SRCS ] env = { "UDS_TP_TYPE": "2"}, copts = ["-g"], tags = [ "exclusive", "vcan"], + target_compatible_with = ["@platforms//os:linux"], ) for name, src in zip(TEST_NAMES, TEST_SRCS) ] @@ -115,8 +130,10 @@ sh_test( args = ["$(locations //:iso14229)"], size = "small", - # Not exactly right. It's to prevent this test from being run under qemu - target_compatible_with = ["@platforms//cpu:x86_64"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], ) cc_library( diff --git a/test/cmocka.BUILD b/test/cmocka.BUILD index 0d0fbc4..a314492 100644 --- a/test/cmocka.BUILD +++ b/test/cmocka.BUILD @@ -10,7 +10,13 @@ cc_library( ], copts = [ "-DHAVE_SIGNAL_H", - ], + ] + select({ + "@bazel_tools//src/conditions:windows": [ + "-DHAVE__SNPRINTF_S", + "-DHAVE__VSNPRINTF_S", + ], + "//conditions:default": [], + }), includes = [ "include", ], diff --git a/test/env.c b/test/env.c index f70c8d3..6430d9d 100644 --- a/test/env.c +++ b/test/env.c @@ -4,7 +4,6 @@ #include #include #include -#include static UDSServer_t *registeredServer = NULL; static UDSClient_t *registeredClient = NULL; @@ -72,7 +71,13 @@ void ENV_RegisterClient(UDSClient_t *client) { registeredClient = client; } uint32_t UDSMillis() { return TimeNowMillis; } // actually sleep for milliseconds -void msleep(int ms) { usleep(ms * 1000); } +void msleep(int ms) { +#ifdef _WIN32 + Sleep(ms); +#else + usleep(ms * 1000); +#endif +} static bool IsNetworkedTransport(int tp_type) { return tp_type == ENV_TP_TYPE_ISOTP_SOCK || tp_type == ENV_TP_TYPE_ISOTPC; @@ -113,6 +118,7 @@ UDSTpHandle_t *ENV_TpNew(const char *name) { tp = TPMockNew("server", TPMOCK_DEFAULT_SERVER_ARGS); break; case ENV_TP_TYPE_ISOTP_SOCK: { +#ifdef UDS_TP_ISOTP_SOCK UDSTpIsoTpSock_t *isotp = malloc(sizeof(UDSTpIsoTpSock_t)); strcpy(isotp->tag, "server"); assert(UDS_OK == UDSTpIsoTpSockInitServer(isotp, opts.ifname, opts.srv_src_addr, @@ -120,8 +126,12 @@ UDSTpHandle_t *ENV_TpNew(const char *name) { opts.srv_src_addr_func)); tp = (UDSTpHandle_t *)isotp; break; +#endif + printf("isotp_sock not supported\n"); + return NULL; } case ENV_TP_TYPE_ISOTPC: { +#ifdef UDS_TP_ISOTP_C_SOCKETCAN UDSTpISOTpC_t *isotp = malloc(sizeof(UDSTpISOTpC_t)); strcpy(isotp->tag, "server"); @@ -129,6 +139,9 @@ UDSTpHandle_t *ENV_TpNew(const char *name) { opts.srv_target_addr, opts.srv_src_addr_func, 0)); tp = (UDSTpHandle_t *)isotp; break; +#endif + printf("isotp_c_socketcan not supported\n"); + return NULL; } default: printf("unknown TP type: %d\n", opts.tp_type); @@ -140,6 +153,7 @@ UDSTpHandle_t *ENV_TpNew(const char *name) { tp = TPMockNew("client", TPMOCK_DEFAULT_CLIENT_ARGS); break; case ENV_TP_TYPE_ISOTP_SOCK: { +#ifdef UDS_TP_ISOTP_SOCK UDSTpIsoTpSock_t *isotp = malloc(sizeof(UDSTpIsoTpSock_t)); strcpy(isotp->tag, "client"); assert(UDS_OK == UDSTpIsoTpSockInitClient(isotp, opts.ifname, opts.cli_src_addr, @@ -147,14 +161,21 @@ UDSTpHandle_t *ENV_TpNew(const char *name) { opts.cli_tgt_addr_func)); tp = (UDSTpHandle_t *)isotp; break; +#endif + printf("isotp_sock not supported\n"); + return NULL; } case ENV_TP_TYPE_ISOTPC: { +#ifdef UDS_TP_ISOTP_C_SOCKETCAN UDSTpISOTpC_t *isotp = malloc(sizeof(UDSTpISOTpC_t)); strcpy(isotp->tag, "client"); assert(UDS_OK == UDSTpISOTpCInit(isotp, opts.ifname, opts.cli_src_addr, opts.cli_target_addr, 0, opts.cli_tgt_addr_func)); tp = (UDSTpHandle_t *)isotp; break; +#endif + printf("isotp_c_socketcan not supported\n"); + return NULL; } default: printf("unknown TP type: %d\n", opts.tp_type); @@ -174,11 +195,15 @@ void ENV_TpFree(UDSTpHandle_t *tp) { TPMockFree(tp); break; case ENV_TP_TYPE_ISOTP_SOCK: +#ifdef UDS_TP_ISOTP_SOCK UDSTpIsoTpSockDeinit((UDSTpIsoTpSock_t *)tp); +#endif break; case ENV_TP_TYPE_ISOTPC: +#ifdef UDS_TP_ISOTP_C_SOCKETCAN UDSTpISOTpCDeinit((UDSTpISOTpC_t *)tp); free(tp); +#endif break; } }