Refactor external transports (#179)
* Refactor stream framing code * Added custom transports API * Renaming serial_io to framing_io * Refactor * Move framing to runtime Update custom callbacks API Fix Minor fixes * Updates * Add test * Update test * Fix Ralph issue * Remove old external transport approach * Revert "Remove old external transport approach" This reverts commit dbd94b632b2fcd4325868d980339b0940b75f33e. * Add deprecation message * Fix leak in test Fix leak in test Fix Fix test * Fix windows test * Minor fix * Update * Remove dead code * Remove old transports approach * Address comments * Update test/transport/custom_comm/CustomComm.cpp Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com> * Update test/transport/custom_comm/CustomComm.hpp Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com> * Update test/transport/custom_comm/CustomComm.hpp Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com> * Update test/transport/custom_comm/CustomComm.hpp Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com> * Address comments * Address comments * Address comments Co-authored-by: Jose Antonio Moral <joseantoniomoralparras@gmail.com>
This commit is contained in:
parent
84bad2defe
commit
22bff80e0f
|
@ -46,6 +46,7 @@ option(UCLIENT_PROFILE_DISCOVERY "Enable discovery profile." ON)
|
|||
option(UCLIENT_PROFILE_UDP "Enable UDP transport." ON)
|
||||
option(UCLIENT_PROFILE_TCP "Enable TCP transport." ON)
|
||||
option(UCLIENT_PROFILE_SERIAL "Enable Serial transport." ON)
|
||||
option(UCLIENT_PROFILE_STREAM_FRAMING "Enable stream framing protocol." ON)
|
||||
set(UCLIENT_MAX_OUTPUT_BEST_EFFORT_STREAMS 1 CACHE STRING "Set the maximum number of output best-effort streams for session.")
|
||||
set(UCLIENT_MAX_OUTPUT_RELIABLE_STREAMS 1 CACHE STRING "Set the maximum number of output reliable streams for session.")
|
||||
set(UCLIENT_MAX_INPUT_BEST_EFFORT_STREAMS 1 CACHE STRING "Set the maximum number of input best-effort streams for session.")
|
||||
|
@ -57,6 +58,9 @@ set(UCLIENT_UDP_TRANSPORT_MTU 512 CACHE STRING "Set the UDP transport MTU.")
|
|||
set(UCLIENT_TCP_TRANSPORT_MTU 512 CACHE STRING "Set the TCP transport MTU.")
|
||||
set(UCLIENT_SERIAL_TRANSPORT_MTU 512 CACHE STRING "Set the Serial transport MTU.")
|
||||
|
||||
option(UCLIENT_PROFILE_CUSTOM_TRANSPORT "Enable Custom transport." ON)
|
||||
set(UCLIENT_CUSTOM_TRANSPORT_MTU 512 CACHE STRING "Set the Custom transport MTU.")
|
||||
|
||||
###############################################################################
|
||||
# Dependencies
|
||||
###############################################################################
|
||||
|
@ -130,43 +134,30 @@ if(UCLIENT_PLATFORM_LINUX OR UCLIENT_PLATFORM_NUTTX OR UCLIENT_PLATFORM_ZEPHYR)
|
|||
set(UCLIENT_PLATFORM_POSIX ON)
|
||||
endif()
|
||||
|
||||
# Check external transport.
|
||||
option(UCLIENT_EXTERNAL_TCP "Enable external serial transport." OFF)
|
||||
option(UCLIENT_EXTERNAL_UDP "Enable external serial transport." OFF)
|
||||
option(UCLIENT_EXTERNAL_SERIAL "Enable external serial transport." OFF)
|
||||
|
||||
# Transport sources.
|
||||
set(_transport_src)
|
||||
|
||||
if(UCLIENT_PROFILE_UDP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport.c)
|
||||
if(UCLIENT_EXTERNAL_UDP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_external.c)
|
||||
else()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_posix.c)
|
||||
elseif(UCLIENT_PLATFORM_POSIX_NOPOLL)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c)
|
||||
elseif(UCLIENT_PLATFORM_WINDOWS)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_windows.c)
|
||||
elseif(UCLIENT_PLATFORM_FREERTOS_PLUS_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_freertos_plus_tcp.c)
|
||||
endif()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_posix.c)
|
||||
elseif(UCLIENT_PLATFORM_POSIX_NOPOLL)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c)
|
||||
elseif(UCLIENT_PLATFORM_WINDOWS)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_windows.c)
|
||||
elseif(UCLIENT_PLATFORM_FREERTOS_PLUS_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/udp/udp_transport_freertos_plus_tcp.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UCLIENT_PROFILE_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport.c)
|
||||
if(UCLIENT_EXTERNAL_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_external.c)
|
||||
else()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_posix.c)
|
||||
elseif(UCLIENT_PLATFORM_WINDOWS)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_windows.c)
|
||||
elseif(UCLIENT_PLATFORM_FREERTOS_PLUS_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_freertos_plus_tcp.c)
|
||||
endif()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_posix.c)
|
||||
elseif(UCLIENT_PLATFORM_WINDOWS)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_windows.c)
|
||||
elseif(UCLIENT_PLATFORM_FREERTOS_PLUS_TCP)
|
||||
list(APPEND _transport_src src/c/profile/transport/ip/tcp/tcp_transport_freertos_plus_tcp.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -175,14 +166,10 @@ set(UCLIENT_PROFILE_SERIAL OFF)
|
|||
endif()
|
||||
|
||||
if(UCLIENT_PROFILE_SERIAL)
|
||||
set(UCLIENT_PROFILE_STREAM_FRAMING ON)
|
||||
list(APPEND _transport_src src/c/profile/transport/serial/serial_transport.c)
|
||||
list(APPEND _transport_src src/c/profile/transport/serial/serial_protocol.c)
|
||||
if(UCLIENT_EXTERNAL_SERIAL)
|
||||
list(APPEND _transport_src src/c/profile/transport/serial/serial_transport_external.c)
|
||||
else()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/serial/serial_transport_posix.c)
|
||||
endif()
|
||||
if(UCLIENT_PLATFORM_POSIX)
|
||||
list(APPEND _transport_src src/c/profile/transport/serial/serial_transport_posix.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -212,6 +199,10 @@ if(UCLIENT_PROFILE_DISCOVERY)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(UCLIENT_PROFILE_CUSTOM_TRANSPORT)
|
||||
list(APPEND _transport_src src/c/profile/transport/custom/custom_transport.c)
|
||||
endif()
|
||||
|
||||
# Other sources
|
||||
set(SRCS
|
||||
src/c/core/session/stream/input_best_effort_stream.c
|
||||
|
@ -235,6 +226,7 @@ set(SRCS
|
|||
src/c/core/session/create_entities_xml.c
|
||||
src/c/core/session/read_access.c
|
||||
src/c/core/session/write_access.c
|
||||
$<$<BOOL:${UCLIENT_PROFILE_STREAM_FRAMING}>:src/c/profile/transport/stream_framing/stream_framing_protocol.c>
|
||||
$<$<OR:$<BOOL:${UCLIENT_VERBOSE_MESSAGE}>,$<BOOL:${UCLIENT_VERBOSE_SERIALIZATION}>>:src/c/core/log/log.c>
|
||||
${_transport_src}
|
||||
)
|
||||
|
@ -376,6 +368,7 @@ if(UCLIENT_BUILD_TESTS)
|
|||
|
||||
add_subdirectory(test/unitary)
|
||||
if(UCLIENT_PLATFORM_LINUX)
|
||||
add_subdirectory(test/transport/custom_comm)
|
||||
add_subdirectory(test/transport/serial_comm)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#cmakedefine UCLIENT_PROFILE_UDP
|
||||
#cmakedefine UCLIENT_PROFILE_TCP
|
||||
#cmakedefine UCLIENT_PROFILE_SERIAL
|
||||
#cmakedefine UCLIENT_PROFILE_CUSTOM_TRANSPORT
|
||||
|
||||
#cmakedefine UCLIENT_PLATFORM_POSIX
|
||||
#cmakedefine UCLIENT_PLATFORM_POSIX_NOPOLL
|
||||
|
@ -54,5 +55,8 @@
|
|||
#ifdef UCLIENT_PROFILE_SERIAL
|
||||
#define UXR_CONFIG_SERIAL_TRANSPORT_MTU @UCLIENT_SERIAL_TRANSPORT_MTU@
|
||||
#endif
|
||||
#ifdef UCLIENT_PROFILE_CUSTOM_TRANSPORT
|
||||
#define UCLIENT_CUSTOM_TRANSPORT_MTU @UCLIENT_CUSTOM_TRANSPORT_MTU@
|
||||
#endif
|
||||
|
||||
#endif // _UXR_CLIENT_CONFIG_H_
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef UXR_CLIENT_CUSTOM_TRANSPORT_H_
|
||||
#define UXR_CLIENT_CUSTOM_TRANSPORT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <uxr/client/core/communication/communication.h>
|
||||
#include <uxr/client/config.h>
|
||||
#include <uxr/client/profile/transport/stream_framing/stream_framing_protocol.h>
|
||||
#include <uxr/client/visibility.h>
|
||||
|
||||
struct uxrCustomTransport;
|
||||
|
||||
typedef bool (*open_custom_func)(struct uxrCustomTransport*);
|
||||
typedef bool (*close_custom_func)(struct uxrCustomTransport*);
|
||||
typedef size_t (*write_custom_func)(struct uxrCustomTransport*, const uint8_t*, size_t, uint8_t*);
|
||||
typedef size_t (*read_custom_func)(struct uxrCustomTransport*, uint8_t*, size_t, int, uint8_t*);
|
||||
|
||||
typedef struct uxrCustomTransport
|
||||
{
|
||||
uint8_t buffer[UCLIENT_CUSTOM_TRANSPORT_MTU];
|
||||
bool framing;
|
||||
uxrFramingIO framing_io;
|
||||
open_custom_func open;
|
||||
close_custom_func close;
|
||||
write_custom_func write;
|
||||
read_custom_func read;
|
||||
uxrCommunication comm;
|
||||
void * args;
|
||||
} uxrCustomTransport;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a Custom transport callbacks.
|
||||
* @param transport The uninitialized transport structure used for managing the transport.
|
||||
* @param open Open callback.
|
||||
* @param close Close callback.
|
||||
* @param write Write callback.
|
||||
* @param read Read callback.
|
||||
*/
|
||||
UXRDLLAPI void uxr_set_custom_transport_callbacks(uxrCustomTransport* transport,
|
||||
bool framing,
|
||||
open_custom_func open,
|
||||
close_custom_func close,
|
||||
write_custom_func write,
|
||||
read_custom_func read);
|
||||
|
||||
/**
|
||||
* @brief Initializes a Custom transport.
|
||||
* @param transport The transport structure used for managing the transport.
|
||||
* Callbacks must be set.
|
||||
* @param open_args Arguments for the open function.
|
||||
* @return `true` in case of successful initialization. `false` in other case.
|
||||
*/
|
||||
UXRDLLAPI bool uxr_init_custom_transport(uxrCustomTransport* transport,
|
||||
void * args);
|
||||
|
||||
/**
|
||||
* @brief Closes a Custom transport.
|
||||
* @param transport The transport structure.
|
||||
* @return `true` in case of successful closing. `false` in other case.
|
||||
*/
|
||||
UXRDLLAPI bool uxr_close_custom_transport(uxrCustomTransport* transport);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UXR_CLIENT_CUSTOM_TRANSPORT_H_
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_
|
||||
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Place here your includes
|
||||
|
||||
typedef struct uxrTCPPlatform
|
||||
{
|
||||
// Place here your platform data
|
||||
} uxrTCPPlatform;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_
|
||||
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Place here your includes
|
||||
|
||||
typedef struct uxrUDPPlatform
|
||||
{
|
||||
// Place here your platform data
|
||||
} uxrUDPPlatform;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_
|
|
@ -21,7 +21,7 @@ extern "C"
|
|||
#endif
|
||||
|
||||
#include <uxr/client/core/communication/communication.h>
|
||||
#include <uxr/client/profile/transport/serial/serial_protocol.h>
|
||||
#include <uxr/client/profile/transport/stream_framing/stream_framing_protocol.h>
|
||||
#include <uxr/client/config.h>
|
||||
#include <uxr/client/visibility.h>
|
||||
#include <uxr/client/transport.h>
|
||||
|
@ -29,7 +29,7 @@ extern "C"
|
|||
typedef struct uxrSerialTransport
|
||||
{
|
||||
uint8_t buffer[UXR_CONFIG_SERIAL_TRANSPORT_MTU];
|
||||
uxrSerialIO serial_io;
|
||||
uxrFramingIO framing_io;
|
||||
uint8_t remote_addr;
|
||||
uxrCommunication comm;
|
||||
struct uxrSerialPlatform platform;
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_
|
||||
#define UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Place here your includes
|
||||
|
||||
typedef struct uxrSerialPlatform
|
||||
{
|
||||
// Place here your platform data
|
||||
} uxrSerialPlatform;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_
|
|
@ -22,15 +22,15 @@ extern "C"
|
|||
|
||||
#include <uxr/client/profile/transport/serial/serial_transport.h>
|
||||
|
||||
bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, const int fd, uint8_t remote_addr, uint8_t local_addr);
|
||||
bool uxr_close_serial_platform(struct uxrSerialPlatform* platform);
|
||||
bool uxr_init_serial_platform(void* args, const int fd, uint8_t remote_addr, uint8_t local_addr);
|
||||
bool uxr_close_serial_platform(void* args);
|
||||
|
||||
size_t uxr_write_serial_data_platform(struct uxrSerialPlatform* platform,
|
||||
uint8_t* buf,
|
||||
size_t uxr_write_serial_data_platform(void* args,
|
||||
const uint8_t* buf,
|
||||
size_t len,
|
||||
uint8_t* errcode);
|
||||
|
||||
size_t uxr_read_serial_data_platform(struct uxrSerialPlatform* platform,
|
||||
size_t uxr_read_serial_data_platform(void* args,
|
||||
uint8_t* buf,
|
||||
size_t len,
|
||||
int timeout,
|
||||
|
|
|
@ -27,18 +27,18 @@ extern "C"
|
|||
|
||||
typedef enum uxrSerialInputState
|
||||
{
|
||||
UXR_SERIAL_UNINITIALIZED,
|
||||
UXR_SERIAL_READING_SRC_ADDR,
|
||||
UXR_SERIAL_READING_DST_ADDR,
|
||||
UXR_SERIAL_READING_LEN_LSB,
|
||||
UXR_SERIAL_READING_LEN_MSB,
|
||||
UXR_SERIAL_READING_PAYLOAD,
|
||||
UXR_SERIAL_READING_CRC_LSB,
|
||||
UXR_SERIAL_READING_CRC_MSB,
|
||||
UXR_FRAMING_UNINITIALIZED,
|
||||
UXR_FRAMING_READING_SRC_ADDR,
|
||||
UXR_FRAMING_READING_DST_ADDR,
|
||||
UXR_FRAMING_READING_LEN_LSB,
|
||||
UXR_FRAMING_READING_LEN_MSB,
|
||||
UXR_FRAMING_READING_PAYLOAD,
|
||||
UXR_FRAMING_READING_CRC_LSB,
|
||||
UXR_FRAMING_READING_CRC_MSB,
|
||||
|
||||
} uxrSerialInputState;
|
||||
|
||||
typedef struct uxrSerialIO
|
||||
typedef struct uxrFramingIO
|
||||
{
|
||||
uxrSerialInputState state;
|
||||
uint8_t local_addr;
|
||||
|
@ -53,7 +53,7 @@ typedef struct uxrSerialIO
|
|||
uint8_t wb[42];
|
||||
uint8_t wb_pos;
|
||||
|
||||
} uxrSerialIO;
|
||||
} uxrFramingIO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -52,4 +52,8 @@
|
|||
#include <uxr/client/profile/transport/serial/serial_transport.h>
|
||||
#endif //UCLIENT_PROFILE_SERIAL
|
||||
|
||||
#ifdef UCLIENT_PROFILE_CUSTOM_TRANSPORT
|
||||
#include <uxr/client/profile/transport/custom/custom_transport.h>
|
||||
#endif //UCLIENT_PROFILE_CUSTOM_TRANSPORT
|
||||
|
||||
#endif // UXR_CLIENT_TRANSPORT_H_
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
#include <uxr/client/profile/transport/custom/custom_transport.h>
|
||||
#include "../stream_framing/stream_framing_protocol.h"
|
||||
#include <uxr/client/util/time.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Static members.
|
||||
*******************************************************************************/
|
||||
static uint8_t error_code;
|
||||
|
||||
/*******************************************************************************
|
||||
* Private function definitions.
|
||||
*******************************************************************************/
|
||||
static bool send_custom_msg(void* instance, const uint8_t* buf, size_t len)
|
||||
{
|
||||
bool rv = false;
|
||||
uxrCustomTransport* transport = (uxrCustomTransport*)instance;
|
||||
|
||||
uint8_t errcode;
|
||||
size_t bytes_written = 0;
|
||||
if (transport->framing)
|
||||
{
|
||||
bytes_written = uxr_write_framed_msg(&transport->framing_io,
|
||||
(uxr_write_cb) transport->write,
|
||||
transport,
|
||||
buf,
|
||||
len,
|
||||
0x00,
|
||||
&errcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_written = transport->write(transport, buf, len, &errcode);
|
||||
}
|
||||
|
||||
if ((0 < bytes_written) && (bytes_written == len))
|
||||
{
|
||||
rv = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_code = errcode;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static bool recv_custom_msg(void* instance, uint8_t** buf, size_t* len, int timeout)
|
||||
{
|
||||
bool rv = false;
|
||||
uxrCustomTransport* transport = (uxrCustomTransport*)instance;
|
||||
|
||||
size_t bytes_read = 0;
|
||||
do
|
||||
{
|
||||
int64_t time_init = uxr_millis();
|
||||
uint8_t remote_addr = 0x00;
|
||||
uint8_t errcode;
|
||||
|
||||
if (transport->framing)
|
||||
{
|
||||
bytes_read = uxr_read_framed_msg(&transport->framing_io,
|
||||
(uxr_read_cb) transport->read,
|
||||
transport,
|
||||
transport->buffer,
|
||||
sizeof(transport->buffer),
|
||||
&remote_addr,
|
||||
timeout,
|
||||
&errcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read = transport->read(transport,
|
||||
transport->buffer,
|
||||
sizeof(transport->buffer),
|
||||
timeout,
|
||||
&errcode);
|
||||
}
|
||||
|
||||
if ((0 < bytes_read) && (remote_addr == 0x00))
|
||||
{
|
||||
*len = bytes_read;
|
||||
*buf = transport->buffer;
|
||||
rv = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_code = errcode;
|
||||
}
|
||||
timeout -= (int)(uxr_millis() - time_init);
|
||||
}
|
||||
while ((0 == bytes_read) && (0 < timeout));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static uint8_t get_custom_error(void)
|
||||
{
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Public function definitions.
|
||||
*******************************************************************************/
|
||||
void uxr_set_custom_transport_callbacks(uxrCustomTransport* transport,
|
||||
bool framing,
|
||||
open_custom_func open,
|
||||
close_custom_func close,
|
||||
write_custom_func write,
|
||||
read_custom_func read)
|
||||
{
|
||||
transport->framing = framing;
|
||||
transport->open = open;
|
||||
transport->close = close;
|
||||
transport->write = write;
|
||||
transport->read = read;
|
||||
}
|
||||
|
||||
bool uxr_init_custom_transport(uxrCustomTransport* transport,
|
||||
void * args)
|
||||
{
|
||||
bool rv = false;
|
||||
if (transport->open == NULL ||
|
||||
transport->close == NULL ||
|
||||
transport->write == NULL ||
|
||||
transport->read == NULL)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
transport->args = args;
|
||||
|
||||
if (transport->open(transport))
|
||||
{
|
||||
if (transport->framing)
|
||||
{
|
||||
/* Init FramingIO. */
|
||||
uxr_init_framing_io(&transport->framing_io, 0x00);
|
||||
}
|
||||
|
||||
/* Setup interface. */
|
||||
transport->comm.instance = (void*)transport;
|
||||
transport->comm.send_msg = send_custom_msg;
|
||||
transport->comm.recv_msg = recv_custom_msg;
|
||||
transport->comm.comm_error = get_custom_error;
|
||||
transport->comm.mtu = UCLIENT_CUSTOM_TRANSPORT_MTU;
|
||||
|
||||
rv = true;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool uxr_close_custom_transport(uxrCustomTransport* transport)
|
||||
{
|
||||
return transport->close(transport);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_external.h>
|
||||
#include "tcp_transport_internal.h"
|
||||
|
||||
// Place here your includes
|
||||
|
||||
bool uxr_init_tcp_platform(
|
||||
struct uxrTCPPlatform* platform,
|
||||
uxrIpProtocol ip_protocol,
|
||||
const char* ip,
|
||||
const char* port)
|
||||
{
|
||||
// Place here your initialization platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
bool uxr_close_tcp_platform(
|
||||
struct uxrTCPPlatform* platform)
|
||||
{
|
||||
// Place here your closing platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
size_t uxr_write_tcp_data_platform(
|
||||
struct uxrTCPPlatform* platform,
|
||||
const uint8_t* buf,
|
||||
size_t len,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
// Place here your writing bytes platform code
|
||||
// Return number of bytes written
|
||||
}
|
||||
|
||||
size_t uxr_read_tcp_data_platform(
|
||||
struct uxrTCPPlatform* platform,
|
||||
uint8_t* buf,
|
||||
size_t len,
|
||||
int timeout,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
// Place here your reading bytes platform code
|
||||
// Return number of bytes read (max bytes: len)
|
||||
}
|
||||
|
||||
void uxr_disconnect_tcp_platform(
|
||||
struct uxrTCPPlatform* platform)
|
||||
{
|
||||
// Place here your disconnection platform code
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#include <uxr/client/profile/transport/ip/udp/udp_transport_external.h>
|
||||
#include "udp_transport_internal.h"
|
||||
|
||||
// Place here your includes
|
||||
|
||||
bool uxr_init_udp_platform(
|
||||
uxrUDPPlatform* platform,
|
||||
uxrIpProtocol ip_protocol,
|
||||
const char* ip,
|
||||
const char* port)
|
||||
{
|
||||
// Place here your initialization platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
bool uxr_close_udp_platform(
|
||||
uxrUDPPlatform* platform)
|
||||
{
|
||||
// Place here your closing platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
size_t uxr_write_udp_data_platform(
|
||||
uxrUDPPlatform* platform,
|
||||
const uint8_t* buf,
|
||||
size_t len,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
// Place here your writing bytes platform code
|
||||
// Return number of bytes written
|
||||
}
|
||||
|
||||
size_t uxr_read_udp_data_platform(
|
||||
uxrUDPPlatform* platform,
|
||||
uint8_t* buf,
|
||||
size_t len,
|
||||
int timeout,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
// Place here your reading bytes platform code
|
||||
// Return number of bytes read (max bytes: len)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>
|
||||
#include "serial_protocol_internal.h"
|
||||
#include "../stream_framing/stream_framing_protocol.h"
|
||||
#include <uxr/client/util/time.h>
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -23,7 +23,7 @@ static bool send_serial_msg(void* instance, const uint8_t* buf, size_t len)
|
|||
uxrSerialTransport* transport = (uxrSerialTransport*)instance;
|
||||
|
||||
uint8_t errcode;
|
||||
size_t bytes_written = uxr_write_serial_msg(&transport->serial_io,
|
||||
size_t bytes_written = uxr_write_framed_msg(&transport->framing_io,
|
||||
uxr_write_serial_data_platform,
|
||||
&transport->platform,
|
||||
buf,
|
||||
|
@ -53,7 +53,7 @@ static bool recv_serial_msg(void* instance, uint8_t** buf, size_t* len, int time
|
|||
int64_t time_init = uxr_millis();
|
||||
uint8_t remote_addr;
|
||||
uint8_t errcode;
|
||||
bytes_read = uxr_read_serial_msg(&transport->serial_io,
|
||||
bytes_read = uxr_read_framed_msg(&transport->framing_io,
|
||||
uxr_read_serial_data_platform,
|
||||
&transport->platform,
|
||||
transport->buffer,
|
||||
|
@ -97,8 +97,8 @@ bool uxr_init_serial_transport(uxrSerialTransport* transport,
|
|||
/* Setup address. */
|
||||
transport->remote_addr = remote_addr;
|
||||
|
||||
/* Init SerialIO. */
|
||||
uxr_init_serial_io(&transport->serial_io, local_addr);
|
||||
/* Init FramingIO. */
|
||||
uxr_init_framing_io(&transport->framing_io, local_addr);
|
||||
|
||||
/* Setup interface. */
|
||||
transport->comm.instance = (void*)transport;
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#include <uxr/client/profile/transport/serial/serial_transport_external.h>
|
||||
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>
|
||||
|
||||
// Place here your includes
|
||||
|
||||
bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, int fd, uint8_t remote_addr, uint8_t local_addr)
|
||||
{
|
||||
// Place here your initialization platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
bool uxr_close_serial_platform(struct uxrSerialPlatform* platform)
|
||||
{
|
||||
// Place here your closing platform code
|
||||
// Return true if success
|
||||
}
|
||||
|
||||
size_t uxr_write_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, uint8_t* errcode)
|
||||
{
|
||||
// Place here your writing bytes platform code
|
||||
// Return number of bytes written
|
||||
}
|
||||
|
||||
size_t uxr_read_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
|
||||
{
|
||||
// Place here your reading bytes platform code
|
||||
// Return number of bytes read (max bytes: len)
|
||||
}
|
|
@ -4,11 +4,13 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, int fd, uint8_t remote_addr, uint8_t local_addr)
|
||||
bool uxr_init_serial_platform(void* args, int fd, uint8_t remote_addr, uint8_t local_addr)
|
||||
{
|
||||
(void) remote_addr;
|
||||
(void) local_addr;
|
||||
|
||||
struct uxrSerialPlatform* platform = (struct uxrSerialPlatform*) args;
|
||||
|
||||
/* Poll setup. */
|
||||
platform->poll_fd.fd = fd;
|
||||
platform->poll_fd.events = POLLIN;
|
||||
|
@ -16,14 +18,16 @@ bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, int fd, uint8_
|
|||
return true;
|
||||
}
|
||||
|
||||
bool uxr_close_serial_platform(struct uxrSerialPlatform* platform)
|
||||
bool uxr_close_serial_platform(void* args)
|
||||
{
|
||||
struct uxrSerialPlatform* platform = (struct uxrSerialPlatform*) args;
|
||||
return (-1 == platform->poll_fd.fd) ? true : (0 == close(platform->poll_fd.fd));
|
||||
}
|
||||
|
||||
size_t uxr_write_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, uint8_t* errcode)
|
||||
size_t uxr_write_serial_data_platform(void* args, const uint8_t* buf, size_t len, uint8_t* errcode)
|
||||
{
|
||||
size_t rv = 0;
|
||||
struct uxrSerialPlatform* platform = (struct uxrSerialPlatform*) args;
|
||||
|
||||
ssize_t bytes_written = write(platform->poll_fd.fd, (void*)buf, (size_t)len);
|
||||
if (-1 != bytes_written)
|
||||
|
@ -38,9 +42,10 @@ size_t uxr_write_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf,
|
|||
return rv;
|
||||
}
|
||||
|
||||
size_t uxr_read_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
|
||||
size_t uxr_read_serial_data_platform(void* args, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
|
||||
{
|
||||
size_t rv = 0;
|
||||
struct uxrSerialPlatform* platform = (struct uxrSerialPlatform*) args;
|
||||
|
||||
int poll_rv = poll(&platform->poll_fd, 1, timeout);
|
||||
if (0 < poll_rv)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "serial_protocol_internal.h"
|
||||
#include <uxr/client/util/time.h>
|
||||
#include "stream_framing_protocol.h"
|
||||
#include <string.h>
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -48,25 +49,25 @@ void uxr_update_crc(uint16_t* crc, const uint8_t data)
|
|||
*crc = (*crc >> 8) ^ crc16_table[(*crc ^ data) & 0xFF];
|
||||
}
|
||||
|
||||
bool uxr_get_next_octet(uxrSerialIO* serial_io, uint8_t* octet)
|
||||
bool uxr_get_next_octet(uxrFramingIO* framing_io, uint8_t* octet)
|
||||
{
|
||||
bool rv = false;
|
||||
*octet = 0;
|
||||
if (serial_io->rb_head != serial_io->rb_tail)
|
||||
if (framing_io->rb_head != framing_io->rb_tail)
|
||||
{
|
||||
if (UXR_FRAMING_ESC_FLAG != serial_io->rb[serial_io->rb_tail])
|
||||
if (UXR_FRAMING_ESC_FLAG != framing_io->rb[framing_io->rb_tail])
|
||||
{
|
||||
*octet = serial_io->rb[serial_io->rb_tail];
|
||||
serial_io->rb_tail = (uint8_t)((size_t)(serial_io->rb_tail + 1) % sizeof(serial_io->rb));
|
||||
*octet = framing_io->rb[framing_io->rb_tail];
|
||||
framing_io->rb_tail = (uint8_t)((size_t)(framing_io->rb_tail + 1) % sizeof(framing_io->rb));
|
||||
rv = (UXR_FRAMING_BEGIN_FLAG != *octet);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t temp_tail = (uint8_t)((size_t)(serial_io->rb_tail + 1) % sizeof(serial_io->rb));
|
||||
if (temp_tail != serial_io->rb_head)
|
||||
uint8_t temp_tail = (uint8_t)((size_t)(framing_io->rb_tail + 1) % sizeof(framing_io->rb));
|
||||
if (temp_tail != framing_io->rb_head)
|
||||
{
|
||||
*octet = serial_io->rb[temp_tail];
|
||||
serial_io->rb_tail = (uint8_t)((size_t)(serial_io->rb_tail + 2) % sizeof(serial_io->rb));
|
||||
*octet = framing_io->rb[temp_tail];
|
||||
framing_io->rb_tail = (uint8_t)((size_t)(framing_io->rb_tail + 2) % sizeof(framing_io->rb));
|
||||
if (UXR_FRAMING_BEGIN_FLAG != *octet)
|
||||
{
|
||||
*octet ^= UXR_FRAMING_XOR_FLAG;
|
||||
|
@ -78,26 +79,26 @@ bool uxr_get_next_octet(uxrSerialIO* serial_io, uint8_t* octet)
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool uxr_add_next_octet(uxrSerialIO* serial_io, uint8_t octet)
|
||||
bool uxr_add_next_octet(uxrFramingIO* framing_io, uint8_t octet)
|
||||
{
|
||||
bool rv = false;
|
||||
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet || UXR_FRAMING_ESC_FLAG == octet)
|
||||
{
|
||||
if ((uint8_t)(serial_io->wb_pos + 1) < sizeof(serial_io->wb))
|
||||
if ((uint8_t)(framing_io->wb_pos + 1) < sizeof(framing_io->wb))
|
||||
{
|
||||
serial_io->wb[serial_io->wb_pos] = UXR_FRAMING_ESC_FLAG;
|
||||
serial_io->wb[serial_io->wb_pos + 1] = octet ^ UXR_FRAMING_XOR_FLAG;
|
||||
serial_io->wb_pos = (uint8_t)(serial_io->wb_pos + 2);
|
||||
framing_io->wb[framing_io->wb_pos] = UXR_FRAMING_ESC_FLAG;
|
||||
framing_io->wb[framing_io->wb_pos + 1] = octet ^ UXR_FRAMING_XOR_FLAG;
|
||||
framing_io->wb_pos = (uint8_t)(framing_io->wb_pos + 2);
|
||||
rv = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serial_io->wb_pos < sizeof(serial_io->wb))
|
||||
if (framing_io->wb_pos < sizeof(framing_io->wb))
|
||||
{
|
||||
serial_io->wb[serial_io->wb_pos] = octet;
|
||||
serial_io->wb_pos = (uint8_t)(serial_io->wb_pos + 1);
|
||||
framing_io->wb[framing_io->wb_pos] = octet;
|
||||
framing_io->wb_pos = (uint8_t)(framing_io->wb_pos + 1);
|
||||
rv = true;
|
||||
}
|
||||
}
|
||||
|
@ -105,15 +106,36 @@ bool uxr_add_next_octet(uxrSerialIO* serial_io, uint8_t octet)
|
|||
return rv;
|
||||
}
|
||||
|
||||
void uxr_init_serial_io(uxrSerialIO* serial_io, uint8_t local_addr)
|
||||
void uxr_init_framing_io(uxrFramingIO* framing_io, uint8_t local_addr)
|
||||
{
|
||||
serial_io->local_addr = local_addr;
|
||||
serial_io->state = UXR_SERIAL_UNINITIALIZED;
|
||||
serial_io->rb_head = 0;
|
||||
serial_io->rb_tail = 0;
|
||||
framing_io->local_addr = local_addr;
|
||||
framing_io->state = UXR_FRAMING_UNINITIALIZED;
|
||||
framing_io->rb_head = 0;
|
||||
framing_io->rb_tail = 0;
|
||||
}
|
||||
|
||||
size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
||||
bool uxr_framing_write_transport(uxrFramingIO* framing_io,
|
||||
uxr_write_cb write_cb,
|
||||
void* cb_arg,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
size_t bytes_written = 0;
|
||||
size_t last_written = 0;
|
||||
|
||||
do {
|
||||
last_written = write_cb(cb_arg, &framing_io->wb[bytes_written], framing_io->wb_pos - bytes_written, errcode);
|
||||
bytes_written += last_written;
|
||||
} while (bytes_written < framing_io->wb_pos && 0 < last_written);
|
||||
|
||||
if (bytes_written == framing_io->wb_pos)
|
||||
{
|
||||
framing_io->wb_pos = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t uxr_write_framed_msg(uxrFramingIO* framing_io,
|
||||
uxr_write_cb write_cb,
|
||||
void* cb_arg,
|
||||
const uint8_t* buf,
|
||||
|
@ -122,14 +144,14 @@ size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
|||
uint8_t* errcode)
|
||||
{
|
||||
/* Buffer being flag. */
|
||||
serial_io->wb[0] = UXR_FRAMING_BEGIN_FLAG;
|
||||
serial_io->wb_pos = 1;
|
||||
framing_io->wb[0] = UXR_FRAMING_BEGIN_FLAG;
|
||||
framing_io->wb_pos = 1;
|
||||
|
||||
/* Buffer header. */
|
||||
uxr_add_next_octet(serial_io, serial_io->local_addr);
|
||||
uxr_add_next_octet(serial_io, remote_addr);
|
||||
uxr_add_next_octet(serial_io, (uint8_t)(len & 0xFF));
|
||||
uxr_add_next_octet(serial_io, (uint8_t)(len >> 8));
|
||||
uxr_add_next_octet(framing_io, framing_io->local_addr);
|
||||
uxr_add_next_octet(framing_io, remote_addr);
|
||||
uxr_add_next_octet(framing_io, (uint8_t)(len & 0xFF));
|
||||
uxr_add_next_octet(framing_io, (uint8_t)(len >> 8));
|
||||
|
||||
/* Write payload. */
|
||||
uint8_t octet = 0;
|
||||
|
@ -139,23 +161,14 @@ size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
|||
while (written_len < len && cond)
|
||||
{
|
||||
octet = *(buf + written_len);
|
||||
if (uxr_add_next_octet(serial_io, octet))
|
||||
if (uxr_add_next_octet(framing_io, octet))
|
||||
{
|
||||
uxr_update_crc(&crc, octet);
|
||||
++written_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bytes_written = write_cb(cb_arg, serial_io->wb, serial_io->wb_pos, errcode);
|
||||
if (0 < bytes_written)
|
||||
{
|
||||
cond = true;
|
||||
serial_io->wb_pos = (uint8_t)(serial_io->wb_pos - bytes_written);
|
||||
}
|
||||
else
|
||||
{
|
||||
cond = false;
|
||||
}
|
||||
cond = uxr_framing_write_transport(framing_io, write_cb, cb_arg, errcode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,45 +180,81 @@ size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
|||
while (written_len < sizeof(tmp_crc) && cond)
|
||||
{
|
||||
octet = *(tmp_crc + written_len);
|
||||
if (uxr_add_next_octet(serial_io, octet))
|
||||
if (uxr_add_next_octet(framing_io, octet))
|
||||
{
|
||||
uxr_update_crc(&crc, octet);
|
||||
++written_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bytes_written = write_cb(cb_arg, serial_io->wb, serial_io->wb_pos, errcode);
|
||||
if (0 < bytes_written)
|
||||
{
|
||||
cond = true;
|
||||
serial_io->wb_pos = (uint8_t)(serial_io->wb_pos - bytes_written);
|
||||
}
|
||||
else
|
||||
{
|
||||
cond = false;
|
||||
}
|
||||
cond = uxr_framing_write_transport(framing_io, write_cb, cb_arg, errcode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flus write buffer. */
|
||||
if (cond && (0 < serial_io->wb_pos))
|
||||
/* Flush write buffer. */
|
||||
if (cond && (0 < framing_io->wb_pos))
|
||||
{
|
||||
size_t bytes_written = write_cb(cb_arg, serial_io->wb, serial_io->wb_pos, errcode);
|
||||
if (0 < bytes_written)
|
||||
{
|
||||
cond = true;
|
||||
serial_io->wb_pos = (uint8_t)(serial_io->wb_pos - bytes_written);
|
||||
}
|
||||
else
|
||||
{
|
||||
cond = false;
|
||||
}
|
||||
cond = uxr_framing_write_transport(framing_io, write_cb, cb_arg, errcode);
|
||||
}
|
||||
|
||||
return cond ? (uint16_t)(len) : 0;
|
||||
}
|
||||
|
||||
size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
||||
size_t uxr_framing_read_transport(uxrFramingIO* framing_io,
|
||||
uxr_read_cb read_cb,
|
||||
void* cb_arg,
|
||||
int * timeout,
|
||||
uint8_t* errcode)
|
||||
{
|
||||
int64_t time_init = uxr_millis();
|
||||
|
||||
/* Compute read-buffer available size. */
|
||||
uint8_t av_len[2] = {0, 0};
|
||||
if (framing_io->rb_head == framing_io->rb_tail)
|
||||
{
|
||||
framing_io->rb_head = 0;
|
||||
framing_io->rb_tail = 0;
|
||||
av_len[0] = sizeof(framing_io->rb) - 1;
|
||||
}
|
||||
else if (framing_io->rb_head > framing_io->rb_tail)
|
||||
{
|
||||
if (0 < framing_io->rb_tail)
|
||||
{
|
||||
av_len[0] = (uint8_t)(sizeof(framing_io->rb) - framing_io->rb_head);
|
||||
av_len[1] = (uint8_t)(framing_io->rb_tail - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
av_len[0] = (uint8_t)(sizeof(framing_io->rb) - framing_io->rb_head - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
av_len[0] = (uint8_t)(framing_io->rb_tail - framing_io->rb_head - 1);
|
||||
}
|
||||
|
||||
/* Read */
|
||||
size_t bytes_read[2] = {0};
|
||||
if (0 < av_len[0])
|
||||
{
|
||||
bytes_read[0] = read_cb(cb_arg, &framing_io->rb[framing_io->rb_head], av_len[0], *timeout, errcode);
|
||||
framing_io->rb_head = (uint8_t)((size_t)(framing_io->rb_head + bytes_read[0]) % sizeof(framing_io->rb));
|
||||
if (0 < bytes_read[0])
|
||||
{
|
||||
if ((bytes_read[0] == av_len[0]) && (0 < av_len[1]))
|
||||
{
|
||||
bytes_read[1] = read_cb(cb_arg, &framing_io->rb[framing_io->rb_head], av_len[1], 0, errcode);
|
||||
framing_io->rb_head = (uint8_t)((size_t)(framing_io->rb_head + bytes_read[1]) % sizeof(framing_io->rb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*timeout -= (int)(uxr_millis() - time_init);
|
||||
*timeout = (0 > *timeout) ? 0 : *timeout;
|
||||
return bytes_read[0] + bytes_read[1];
|
||||
}
|
||||
|
||||
size_t uxr_read_framed_msg(uxrFramingIO* framing_io,
|
||||
uxr_read_cb read_cb,
|
||||
void* cb_arg,
|
||||
uint8_t* buf,
|
||||
|
@ -216,68 +265,29 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
{
|
||||
size_t rv = 0;
|
||||
|
||||
/* Compute read-buffer available size. */
|
||||
uint8_t av_len[2] = {0, 0};
|
||||
if (serial_io->rb_head == serial_io->rb_tail)
|
||||
{
|
||||
serial_io->rb_head = 0;
|
||||
serial_io->rb_tail = 0;
|
||||
av_len[0] = sizeof(serial_io->rb) - 1;
|
||||
}
|
||||
else if (serial_io->rb_head > serial_io->rb_tail)
|
||||
{
|
||||
if (0 < serial_io->rb_tail)
|
||||
{
|
||||
av_len[0] = (uint8_t)(sizeof(serial_io->rb) - serial_io->rb_head);
|
||||
av_len[1] = (uint8_t)(serial_io->rb_tail - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
av_len[0] = (uint8_t)(sizeof(serial_io->rb) - serial_io->rb_head - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
av_len[0] = (uint8_t)(serial_io->rb_tail - serial_io->rb_head - 1);
|
||||
}
|
||||
size_t readed_bytes = uxr_framing_read_transport(framing_io, read_cb, cb_arg, &timeout, errcode);
|
||||
|
||||
/* Read from serial. */
|
||||
size_t bytes_read[2] = {0};
|
||||
if (0 < av_len[0])
|
||||
{
|
||||
bytes_read[0] = read_cb(cb_arg, &serial_io->rb[serial_io->rb_head], av_len[0], timeout, errcode);
|
||||
serial_io->rb_head = (uint8_t)((size_t)(serial_io->rb_head + bytes_read[0]) % sizeof(serial_io->rb));
|
||||
if (0 < bytes_read[0])
|
||||
{
|
||||
if ((bytes_read[0] == av_len[0]) && (0 < av_len[1]))
|
||||
{
|
||||
bytes_read[1] = read_cb(cb_arg, &serial_io->rb[serial_io->rb_head], av_len[1], 0, errcode);
|
||||
serial_io->rb_head = (uint8_t)((size_t)(serial_io->rb_head + bytes_read[1]) % sizeof(serial_io->rb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < (bytes_read[0] + bytes_read[1]) || (serial_io->rb_tail != serial_io->rb_head))
|
||||
if (0 < readed_bytes || (framing_io->rb_tail != framing_io->rb_head))
|
||||
{
|
||||
/* State Machine. */
|
||||
bool exit_cond = false;
|
||||
while (!exit_cond)
|
||||
{
|
||||
uint8_t octet = 0;
|
||||
switch (serial_io->state)
|
||||
switch (framing_io->state)
|
||||
{
|
||||
case UXR_SERIAL_UNINITIALIZED:
|
||||
case UXR_FRAMING_UNINITIALIZED:
|
||||
{
|
||||
octet = 0;
|
||||
while ((UXR_FRAMING_BEGIN_FLAG != octet) && (serial_io->rb_head != serial_io->rb_tail))
|
||||
while ((UXR_FRAMING_BEGIN_FLAG != octet) && (framing_io->rb_head != framing_io->rb_tail))
|
||||
{
|
||||
octet = serial_io->rb[serial_io->rb_tail];
|
||||
serial_io->rb_tail = (uint8_t)((size_t)(serial_io->rb_tail + 1) % sizeof(serial_io->rb));
|
||||
octet = framing_io->rb[framing_io->rb_tail];
|
||||
framing_io->rb_tail = (uint8_t)((size_t)(framing_io->rb_tail + 1) % sizeof(framing_io->rb));
|
||||
}
|
||||
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -285,32 +295,32 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case UXR_SERIAL_READING_SRC_ADDR:
|
||||
case UXR_FRAMING_READING_SRC_ADDR:
|
||||
{
|
||||
if (uxr_get_next_octet(serial_io, &serial_io->src_addr))
|
||||
if (uxr_get_next_octet(framing_io, &framing_io->src_addr))
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_DST_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_DST_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG != serial_io->src_addr)
|
||||
if (UXR_FRAMING_BEGIN_FLAG != framing_io->src_addr)
|
||||
{
|
||||
exit_cond = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UXR_SERIAL_READING_DST_ADDR:
|
||||
if (uxr_get_next_octet(serial_io, &octet))
|
||||
case UXR_FRAMING_READING_DST_ADDR:
|
||||
if (uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
serial_io->state = (octet == serial_io->local_addr) ? UXR_SERIAL_READING_LEN_LSB :
|
||||
UXR_SERIAL_UNINITIALIZED;
|
||||
framing_io->state = (octet == framing_io->local_addr) ? UXR_FRAMING_READING_LEN_LSB :
|
||||
UXR_FRAMING_UNINITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -318,17 +328,17 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case UXR_SERIAL_READING_LEN_LSB:
|
||||
if (uxr_get_next_octet(serial_io, &octet))
|
||||
case UXR_FRAMING_READING_LEN_LSB:
|
||||
if (uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
serial_io->msg_len = octet;
|
||||
serial_io->state = UXR_SERIAL_READING_LEN_MSB;
|
||||
framing_io->msg_len = octet;
|
||||
framing_io->state = UXR_FRAMING_READING_LEN_MSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -336,27 +346,27 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case UXR_SERIAL_READING_LEN_MSB:
|
||||
if (uxr_get_next_octet(serial_io, &octet))
|
||||
case UXR_FRAMING_READING_LEN_MSB:
|
||||
if (uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
serial_io->msg_len = (uint16_t)(serial_io->msg_len + (octet << 8));
|
||||
serial_io->msg_pos = 0;
|
||||
serial_io->cmp_crc = 0;
|
||||
if (len < serial_io->msg_len)
|
||||
framing_io->msg_len = (uint16_t)(framing_io->msg_len + (octet << 8));
|
||||
framing_io->msg_pos = 0;
|
||||
framing_io->cmp_crc = 0;
|
||||
if (len < framing_io->msg_len)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_UNINITIALIZED;
|
||||
framing_io->state = UXR_FRAMING_UNINITIALIZED;
|
||||
exit_cond = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_PAYLOAD;
|
||||
framing_io->state = UXR_FRAMING_READING_PAYLOAD;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -364,24 +374,27 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case UXR_SERIAL_READING_PAYLOAD:
|
||||
case UXR_FRAMING_READING_PAYLOAD:
|
||||
{
|
||||
while ((serial_io->msg_pos < serial_io->msg_len) && uxr_get_next_octet(serial_io, &octet))
|
||||
while ((framing_io->msg_pos < framing_io->msg_len) && uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
buf[(size_t)serial_io->msg_pos] = octet;
|
||||
serial_io->msg_pos = (uint16_t)(serial_io->msg_pos + 1);
|
||||
uxr_update_crc(&serial_io->cmp_crc, octet);
|
||||
buf[(size_t)framing_io->msg_pos] = octet;
|
||||
framing_io->msg_pos = (uint16_t)(framing_io->msg_pos + 1);
|
||||
uxr_update_crc(&framing_io->cmp_crc, octet);
|
||||
}
|
||||
|
||||
if (serial_io->msg_pos == serial_io->msg_len)
|
||||
if (framing_io->msg_pos == framing_io->msg_len)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_CRC_LSB;
|
||||
framing_io->state = UXR_FRAMING_READING_CRC_LSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else if (0 < uxr_framing_read_transport(framing_io, read_cb, cb_arg, &timeout, errcode)){
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -390,17 +403,17 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case UXR_SERIAL_READING_CRC_LSB:
|
||||
if (uxr_get_next_octet(serial_io, &octet))
|
||||
case UXR_FRAMING_READING_CRC_LSB:
|
||||
if (uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
serial_io->msg_crc = octet;
|
||||
serial_io->state = UXR_SERIAL_READING_CRC_MSB;
|
||||
framing_io->msg_crc = octet;
|
||||
framing_io->state = UXR_FRAMING_READING_CRC_MSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -408,15 +421,15 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case UXR_SERIAL_READING_CRC_MSB:
|
||||
if (uxr_get_next_octet(serial_io, &octet))
|
||||
case UXR_FRAMING_READING_CRC_MSB:
|
||||
if (uxr_get_next_octet(framing_io, &octet))
|
||||
{
|
||||
serial_io->msg_crc = (uint16_t)(serial_io->msg_crc + (octet << 8));
|
||||
serial_io->state = UXR_SERIAL_UNINITIALIZED;
|
||||
if (serial_io->cmp_crc == serial_io->msg_crc)
|
||||
framing_io->msg_crc = (uint16_t)(framing_io->msg_crc + (octet << 8));
|
||||
framing_io->state = UXR_FRAMING_UNINITIALIZED;
|
||||
if (framing_io->cmp_crc == framing_io->msg_crc)
|
||||
{
|
||||
*remote_addr = serial_io->src_addr;
|
||||
rv = serial_io->msg_len;
|
||||
*remote_addr = framing_io->src_addr;
|
||||
rv = framing_io->msg_len;
|
||||
}
|
||||
exit_cond = true;
|
||||
}
|
||||
|
@ -424,7 +437,7 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
{
|
||||
if (UXR_FRAMING_BEGIN_FLAG == octet)
|
||||
{
|
||||
serial_io->state = UXR_SERIAL_READING_SRC_ADDR;
|
||||
framing_io->state = UXR_FRAMING_READING_SRC_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
|
@ -12,14 +12,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_PROTOCOL_INTERNAL_H_
|
||||
#define _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_PROTOCOL_INTERNAL_H_
|
||||
#ifndef _SRC_C_PROFILE_TRANSPORT_FRAMING_PROTOCOL_INTERNAL_H_
|
||||
#define _SRC_C_PROFILE_TRANSPORT_FRAMING_PROTOCOL_INTERNAL_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <uxr/client/profile/transport/serial/serial_protocol.h>
|
||||
#include <uxr/client/profile/transport/stream_framing/stream_framing_protocol.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -27,17 +27,16 @@ extern "C"
|
|||
#define UXR_FRAMING_ESC_FLAG 0x7D
|
||||
#define UXR_FRAMING_XOR_FLAG 0x20
|
||||
|
||||
void uxr_init_serial_io(uxrSerialIO* serial_io, uint8_t local_addr);
|
||||
void uxr_init_framing_io(uxrFramingIO* framing_io, uint8_t local_addr);
|
||||
|
||||
void uxr_update_crc(uint16_t* crc, const uint8_t data);
|
||||
bool uxr_get_next_octet(uxrSerialIO* serial_io, uint8_t* octet);
|
||||
bool uxr_add_next_octet(uxrSerialIO* serial_io, uint8_t octet);
|
||||
bool uxr_get_next_octet(uxrFramingIO* framing_io, uint8_t* octet);
|
||||
bool uxr_add_next_octet(uxrFramingIO* framing_io, uint8_t octet);
|
||||
|
||||
struct uxrSerialPlatform;
|
||||
typedef size_t (*uxr_write_cb)(struct uxrSerialPlatform*, uint8_t*, size_t, uint8_t*);
|
||||
typedef size_t (*uxr_read_cb)(struct uxrSerialPlatform*, uint8_t*, size_t, int, uint8_t*);
|
||||
typedef size_t (*uxr_write_cb)(void*, const uint8_t*, size_t, uint8_t*);
|
||||
typedef size_t (*uxr_read_cb)(void*, uint8_t*, size_t, int, uint8_t*);
|
||||
|
||||
size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
||||
size_t uxr_write_framed_msg(uxrFramingIO* framing_io,
|
||||
uxr_write_cb write_cb,
|
||||
void* cb_arg,
|
||||
const uint8_t* buf,
|
||||
|
@ -45,7 +44,7 @@ size_t uxr_write_serial_msg(uxrSerialIO* serial_io,
|
|||
uint8_t remote_addr,
|
||||
uint8_t* errcode);
|
||||
|
||||
size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
||||
size_t uxr_read_framed_msg(uxrFramingIO* framing_io,
|
||||
uxr_read_cb read_cb,
|
||||
void* cb_arg,
|
||||
uint8_t* buf,
|
||||
|
@ -58,4 +57,4 @@ size_t uxr_read_serial_msg(uxrSerialIO* serial_io,
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif //_SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_PROTOCOL_INTERNAL_H_
|
||||
#endif //_SRC_C_PROFILE_TRANSPORT_FRAMING_PROTOCOL_INTERNAL_H_
|
|
@ -0,0 +1,70 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
|
||||
# New project because of the CXX GTest dependency.
|
||||
if(CMAKE_VERSION VERSION_LESS 3.0)
|
||||
project(custom_transport_test C CXX)
|
||||
else()
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(custom_transport_test LANGUAGES C CXX)
|
||||
endif()
|
||||
|
||||
if(NOT UCLIENT_PROFILE_CUSTOM_TRANSPORT)
|
||||
message(WARNING "Can not compile test: The UCLIENT_PROFILE_CUSTOM_TRANSPORT must be enabled.")
|
||||
else()
|
||||
|
||||
set(SRCS CustomComm.cpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRCS})
|
||||
|
||||
set_common_compile_options(${PROJECT_NAME})
|
||||
|
||||
if(MSVC OR MSVC_IDE)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /wd4996)
|
||||
endif()
|
||||
|
||||
add_gtest(${PROJECT_NAME}
|
||||
SOURCES
|
||||
${SRCS}
|
||||
DEPENDENCIES
|
||||
microxrcedds_client
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
microxrcedds_client
|
||||
${GTEST_BOTH_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${PROJECT_SOURCE_DIR}
|
||||
PRIVATE
|
||||
${GTEST_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
CXX_STANDARD
|
||||
11
|
||||
CXX_STANDARD_REQUIRED
|
||||
YES
|
||||
)
|
||||
endif()
|
|
@ -0,0 +1,182 @@
|
|||
#include "CustomComm.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
CustomComm::CustomComm() : buffer(2000)
|
||||
{
|
||||
max_payload = 20;
|
||||
uxr_set_custom_transport_callbacks(&master_, true, open, close, write, read);
|
||||
uxr_init_custom_transport(&master_, this);
|
||||
|
||||
uxr_set_custom_transport_callbacks(&slave_, true, open, close, write, read);
|
||||
uxr_init_custom_transport(&slave_, this);
|
||||
}
|
||||
|
||||
CustomComm::~CustomComm()
|
||||
{
|
||||
uxr_close_custom_transport(&master_);
|
||||
uxr_close_custom_transport(&slave_);
|
||||
}
|
||||
|
||||
bool CustomComm::open(uxrCustomTransport* /*transport*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomComm::close(uxrCustomTransport* /*transport*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t CustomComm::write(uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* /*error*/)
|
||||
{
|
||||
CustomComm* custom_comm = static_cast<CustomComm*>(transport->args);
|
||||
|
||||
size_t written = 0;
|
||||
while (written < len && written < custom_comm->max_payload)
|
||||
{
|
||||
if (0 == custom_comm->buffer.write(buf[written]))
|
||||
{
|
||||
written++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
size_t CustomComm::read(uxrCustomTransport* transport, uint8_t* buf, size_t len, int /*timeout*/, uint8_t* /*error*/)
|
||||
{
|
||||
CustomComm* custom_comm = static_cast<CustomComm*>(transport->args);
|
||||
|
||||
size_t readed = 0;
|
||||
while (readed < len && readed < custom_comm->max_payload)
|
||||
{
|
||||
if (0 == custom_comm->buffer.read(&buf[readed]))
|
||||
{
|
||||
readed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return readed;
|
||||
}
|
||||
|
||||
TEST_F(CustomComm, SingleWriteReadTest)
|
||||
{
|
||||
uint8_t output_msg[3] = {11, 11, 89};
|
||||
uint8_t* input_msg;
|
||||
size_t input_msg_len;
|
||||
|
||||
/* Send message. */
|
||||
ASSERT_TRUE(master_.comm.send_msg(&master_, output_msg, sizeof(output_msg)));
|
||||
|
||||
/* Receive message. */
|
||||
ASSERT_TRUE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10));
|
||||
ASSERT_EQ(memcmp(output_msg, input_msg, sizeof(output_msg)), 0);
|
||||
ASSERT_FALSE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10));
|
||||
}
|
||||
|
||||
TEST_F(CustomComm, MultiWriteReadTest)
|
||||
{
|
||||
uint16_t msgs_size = 1;
|
||||
uint8_t output_msg[3] = {11, 11, 89};
|
||||
uint8_t* input_msg;
|
||||
size_t input_msg_len;
|
||||
|
||||
/* Send messages. */
|
||||
for (int i = 0; i < msgs_size; ++i)
|
||||
{
|
||||
ASSERT_TRUE(master_.comm.send_msg(&master_, output_msg, sizeof(output_msg)));
|
||||
}
|
||||
|
||||
/* Receive messages. */
|
||||
for (int i = 0; i < msgs_size; ++i)
|
||||
{
|
||||
ASSERT_TRUE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10));
|
||||
ASSERT_EQ(memcmp(output_msg, input_msg, sizeof(output_msg)), 0);
|
||||
}
|
||||
ASSERT_FALSE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10));
|
||||
}
|
||||
|
||||
TEST_F(CustomComm, SingleOctetTest)
|
||||
{
|
||||
uint8_t output_msg = 0;
|
||||
uint8_t* input_msg;
|
||||
size_t input_msg_len;
|
||||
|
||||
/* Send messages. */
|
||||
ASSERT_TRUE(master_.comm.send_msg(&master_, &output_msg, 1));
|
||||
|
||||
/* Receive message. */
|
||||
ASSERT_TRUE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10));
|
||||
ASSERT_EQ(input_msg_len, size_t(1));
|
||||
ASSERT_EQ(*input_msg, 0);
|
||||
}
|
||||
|
||||
TEST_F(CustomComm, NoPayloadTest)
|
||||
{
|
||||
uint8_t output_msg = 0;
|
||||
|
||||
/* Send messages. */
|
||||
ASSERT_FALSE(master_.comm.send_msg(&master_, &output_msg, 0));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(CustomComm, WorstStuffingTest)
|
||||
{
|
||||
uint8_t output_msg[UXR_CONFIG_SERIAL_TRANSPORT_MTU];
|
||||
uint8_t* input_msg;
|
||||
size_t input_msg_len;
|
||||
|
||||
memset(output_msg, UXR_FRAMING_BEGIN_FLAG, sizeof(output_msg));
|
||||
ASSERT_TRUE(master_.comm.send_msg(&master_, output_msg, sizeof(output_msg)));
|
||||
|
||||
ASSERT_TRUE(slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 100));
|
||||
ASSERT_EQ(memcmp(output_msg, input_msg, sizeof(output_msg)), 0);
|
||||
}
|
||||
|
||||
TEST_F(CustomComm, FatigueTest)
|
||||
{
|
||||
uint16_t msgs_size = uint16_t(~0);
|
||||
uint16_t sent_counter = 0;
|
||||
uint16_t recv_counter = 0;
|
||||
uint8_t receiver_ratio = 8;
|
||||
uint8_t output_msg[UXR_CONFIG_SERIAL_TRANSPORT_MTU];
|
||||
uint8_t* input_msg;
|
||||
size_t input_msg_len;
|
||||
|
||||
for (size_t i = 0; i < sizeof(output_msg); ++i)
|
||||
{
|
||||
output_msg[i] = uint8_t(i % (std::numeric_limits<uint8_t>::max() + 1));
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < msgs_size; ++i)
|
||||
{
|
||||
size_t output_len = (i % sizeof(output_msg));
|
||||
if (master_.comm.send_msg(&master_, output_msg, output_len))
|
||||
{
|
||||
++sent_counter;
|
||||
}
|
||||
|
||||
if (i % receiver_ratio == 0)
|
||||
{
|
||||
if (slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10))
|
||||
{
|
||||
++recv_counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (slave_.comm.recv_msg(&slave_, &input_msg, &input_msg_len, 10))
|
||||
{
|
||||
++recv_counter;
|
||||
}
|
||||
|
||||
ASSERT_EQ(recv_counter, sent_counter);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _TEST_TRANSPORT_SERIALCOMM_HPP_
|
||||
#define _TEST_TRANSPORT_SERIALCOMM_HPP_
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <uxr/client/client.h>
|
||||
|
||||
class CircularBuffer
|
||||
{
|
||||
public:
|
||||
CircularBuffer(size_t len)
|
||||
: maxlen(len)
|
||||
, head(0)
|
||||
, tail(0)
|
||||
{
|
||||
buffer = static_cast<uint8_t*>(malloc(maxlen));
|
||||
}
|
||||
|
||||
~CircularBuffer()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
int write(uint8_t data)
|
||||
{
|
||||
size_t next;
|
||||
|
||||
next = head + 1;
|
||||
if (next >= maxlen)
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
|
||||
if (next == tail)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer[head] = data;
|
||||
head = next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read(uint8_t *data)
|
||||
{
|
||||
size_t next;
|
||||
|
||||
if (head == tail)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = tail + 1;
|
||||
if(next >= maxlen)
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
|
||||
*data = buffer[tail];
|
||||
tail = next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t * buffer;
|
||||
size_t maxlen;
|
||||
size_t head;
|
||||
size_t tail;
|
||||
};
|
||||
|
||||
class CustomComm : public testing::Test
|
||||
{
|
||||
public:
|
||||
CustomComm();
|
||||
~CustomComm();
|
||||
|
||||
protected:
|
||||
uxrCustomTransport master_;
|
||||
uxrCustomTransport slave_;
|
||||
|
||||
static bool open(uxrCustomTransport * args);
|
||||
static bool close(uxrCustomTransport* transport);
|
||||
static size_t write(uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* error);
|
||||
static size_t read(uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* error);
|
||||
|
||||
CircularBuffer buffer;
|
||||
size_t max_payload;
|
||||
};
|
||||
|
||||
#endif //_TEST_TRANSPORT_SERIALCOMM_HPP_
|
Loading…
Reference in New Issue