diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..3b2ac8c6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug", + "program": "${workspaceFolder}/Host/BootCommander", + "args": ["-d=/dev/tty.usbmodem1301", "/Users/matthewkennedy/Downloads/fome_update.srec"], + "cwd": "${workspaceFolder}/Host/" + } + ] +} \ No newline at end of file diff --git a/Host/Source/BootCommander/CMakeLists.txt b/Host/Source/BootCommander/CMakeLists.txt index 1517b0f4..29e945aa 100644 --- a/Host/Source/BootCommander/CMakeLists.txt +++ b/Host/Source/BootCommander/CMakeLists.txt @@ -88,6 +88,8 @@ if(WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_WINDOWS -DPLATFORM_64BIT -D_CRT_SECURE_NO_WARNINGS") endif() endif() +elseif(APPLE) + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") elseif(UNIX) if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_LINUX -DPLATFORM_32BIT -pthread -std=gnu99") diff --git a/Host/Source/LibOpenBLT/CMakeLists.txt b/Host/Source/LibOpenBLT/CMakeLists.txt index 9dc13343..e8445bb0 100644 --- a/Host/Source/LibOpenBLT/CMakeLists.txt +++ b/Host/Source/LibOpenBLT/CMakeLists.txt @@ -63,6 +63,8 @@ option(LINT_ENABLED "Configurable to enable/disable the PC-lint target" OFF) # Set the port directory, which is platform specific if(WIN32) set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/windows) +elseif(APPLE) + set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/macos) elseif(UNIX) set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/linux) endif(WIN32) @@ -100,6 +102,9 @@ if(WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_WINDOWS -DPLATFORM_64BIT -D_CRT_SECURE_NO_WARNINGS") endif() endif() +elseif(APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_MACOS -DPLATFORM_64BIT -DNO_CAN_OR_USB -pthread -std=gnu99") + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") elseif(UNIX) if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_LINUX -DPLATFORM_32BIT -pthread -std=gnu99") @@ -186,7 +191,9 @@ endif(BUILD_STATIC) # "make openblt_shared" to build individually shared library. if(BUILD_SHARED) add_library(openblt_shared SHARED ${LIB_SRCS}) - if(UNIX) + if (APPLE) + # Nothing to do here, but we need the case as UNIX will also be defined + elseif(UNIX) # Under Unix the LibUsb library (http://libusb.info/) is needed for the USB support. # Make sure the libusb-1.0-0 and libusb-1.0-0-dev packages are installed to be able # to build LibOpenBLT. Example under Debian/Ubuntu: @@ -196,7 +203,7 @@ if(BUILD_SHARED) elseif(WIN32) # Link the Winsock library target_link_libraries(openblt_shared ws2_32 winusb setupapi) - endif(UNIX) + endif(APPLE) if(CMAKE_C_COMPILER_ID MATCHES MSVC) # Microsoft Visual Studio does not add "lib" to the name of the DLL, whereas GCC # (including MinGW) does. Correct this here. diff --git a/Host/Source/LibOpenBLT/candriver.c b/Host/Source/LibOpenBLT/candriver.c index bc316d1e..e9f38802 100644 --- a/Host/Source/LibOpenBLT/candriver.c +++ b/Host/Source/LibOpenBLT/candriver.c @@ -26,6 +26,8 @@ * \endinternal ****************************************************************************************/ +#ifndef NO_CAN_OR_USB + /**************************************************************************************** * Include files ****************************************************************************************/ @@ -281,4 +283,5 @@ void CanRegisterEvents(tCanEvents const * events) } /*** end of CanRegisterEvents ***/ +#endif // NO_CAN_OR_USB /*********************************** end of candriver.c ********************************/ diff --git a/Host/Source/LibOpenBLT/openblt.c b/Host/Source/LibOpenBLT/openblt.c index ae0f5fa1..5b94a3dc 100644 --- a/Host/Source/LibOpenBLT/openblt.c +++ b/Host/Source/LibOpenBLT/openblt.c @@ -39,8 +39,10 @@ #include "session.h" /* Communication session module */ #include "xcploader.h" /* XCP loader module */ #include "xcptpuart.h" /* XCP UART transport layer */ +#ifndef NO_CAN_OR_USB #include "xcptpcan.h" /* XCP CAN transport layer */ #include "xcptpusb.h" /* XCP USB transport layer */ +#endif // NO_CAN_OR_USB #include "xcptpnet.h" /* XCP TCP/IP transport layer */ @@ -173,6 +175,7 @@ LIBOPENBLT_EXPORT void BltSessionInit(uint32_t sessionType, xcpLoaderSettings.transport = XcpTpUartGetTransport(); } } +#ifndef NO_CAN_OR_USB else if (transportType == BLT_TRANSPORT_XCP_V10_CAN) { /* Verify transportSettings parameters because the XCP CAN transport layer @@ -210,6 +213,7 @@ LIBOPENBLT_EXPORT void BltSessionInit(uint32_t sessionType, /* Link the transport layer to the XCP loader settings. */ xcpLoaderSettings.transport = XcpTpUsbGetTransport(); } +#endif // NO_CAN_OR_USB else if (transportType == BLT_TRANSPORT_XCP_V10_NET) { /* Verify transportSettings parameters because the XCP NET transport layer diff --git a/Host/Source/LibOpenBLT/port/macos/critutil.c b/Host/Source/LibOpenBLT/port/macos/critutil.c new file mode 100644 index 00000000..cd88a224 --- /dev/null +++ b/Host/Source/LibOpenBLT/port/macos/critutil.c @@ -0,0 +1,126 @@ +/************************************************************************************//** +* \file port/linux/critutil.c +* \brief Critical section utility source file. +* \ingroup Utility +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include /* for assertions */ +#include /* for standard integer types */ +#include /* for boolean type */ +#include /* for posix threads */ +#include "util.h" /* Utility module */ + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief Flag to determine if the critical section object was already initialized. */ +static volatile bool criticalSectionInitialized = false; + +/** \brief Critical section object. */ +static volatile pthread_mutex_t mtxCritSect; + + +/************************************************************************************//** +** \brief Initializes the critical section module. Should be called before the +** Enter/Exit functions are used. It is okay to call this initialization +** multiple times from different modules. +** +****************************************************************************************/ +void UtilCriticalSectionInit(void) +{ + /* Only initialize if not yet done so previously. */ + if (!criticalSectionInitialized) + { + /* Initialize the critical section object. */ + (void)pthread_mutex_init((pthread_mutex_t *)&mtxCritSect, NULL); + /* Set initialized flag. */ + criticalSectionInitialized = true; + } +} /*** end of UtilCriticalSectionInit ***/ + + +/************************************************************************************//** +** \brief Terminates the critical section module. Should be called once critical +** sections are no longer needed. Typically called from another module's +** termination function that also initialized it. It is okay to call this +** termination multiple times from different modules. +** +****************************************************************************************/ +void UtilCriticalSectionTerminate(void) +{ + /* Only terminate if it was initialized. */ + if (criticalSectionInitialized) + { + /* Reset the initialized flag. */ + criticalSectionInitialized = false; + /* Delete the critical section object. */ + (void)pthread_mutex_destroy((pthread_mutex_t *)&mtxCritSect); + } +} /*** end of UtilCriticalSectionTerminate ***/ + + + +/************************************************************************************//** +** \brief Enters a critical section. The functions UtilCriticalSectionEnter and +** UtilCriticalSectionExit should always be used in a pair. +** +****************************************************************************************/ +void UtilCriticalSectionEnter(void) +{ + /* Check initialization. */ + assert(criticalSectionInitialized); + + /* Only continue if actually initialized. */ + if (criticalSectionInitialized) + { + (void)pthread_mutex_lock((pthread_mutex_t *)&mtxCritSect); + } +} /*** end of UtilCriticalSectionEnter ***/ /*lint !e456 !e454 */ + + +/************************************************************************************//** +** \brief Leaves a critical section. The functions UtilCriticalSectionEnter and +** UtilCriticalSectionExit should always be used in a pair. +** +****************************************************************************************/ +void UtilCriticalSectionExit(void) +{ + /* Check initialization. */ + assert(criticalSectionInitialized); + + /* Only continue if actually initialized. */ + if (criticalSectionInitialized) + { + (void)pthread_mutex_unlock((pthread_mutex_t *)&mtxCritSect); /*lint !e455 */ + } +} /*** end of UtilCriticalSectionExit ***/ + + +/*********************************** end of critutil.c *********************************/ + diff --git a/Host/Source/LibOpenBLT/port/macos/dummy/dummy.h b/Host/Source/LibOpenBLT/port/macos/dummy/dummy.h new file mode 100644 index 00000000..e69de29b diff --git a/Host/Source/LibOpenBLT/port/macos/netaccess.c b/Host/Source/LibOpenBLT/port/macos/netaccess.c new file mode 100644 index 00000000..6e08cccf --- /dev/null +++ b/Host/Source/LibOpenBLT/port/macos/netaccess.c @@ -0,0 +1,332 @@ +/************************************************************************************//** +* \file port/linux/netaccess.c +* \brief TCP/IP network access source file. +* \ingroup NetAccess +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include /* for assertions */ +#include /* for standard integer types */ +#include /* for NULL declaration */ +#include /* for boolean type */ +#include /* for string utilities */ +#include /* for close */ +#include /* for socket */ +#include /* for inet_addr */ +#include /* for hostent */ +#include "netaccess.h" /* TCP/IP network access module */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Constant value that indicates that the network socket is invalid. */ +#define NETACCESS_INVALID_SOCKET (-1) + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief The socket that is used as an endpoint for the TCP/IP network + * communication. + */ +static int netAccessSocket; + + +/************************************************************************************//** +** \brief Initializes the network access module. +** +****************************************************************************************/ +void NetAccessInit(void) +{ + /* Invalidate the socket. */ + netAccessSocket = NETACCESS_INVALID_SOCKET; +} /*** end of NetAccessInit ***/ + + +/************************************************************************************//** +** \brief Terminates the network access module. +** +****************************************************************************************/ +void NetAccessTerminate(void) +{ + /* Make sure to disconnect form the server. */ + NetAccessDisconnect(); +} /*** end of NetAccessTerminate ***/ + + +/************************************************************************************//** +** \brief Connects to the TCP/IP server at the specified address and the given port. +** \param address The address of the server. This can be a hostname (such as +** mydomain.com) or an IP address (such as 127.0.0.1). +** \param port The port number on the server to connect to. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool NetAccessConnect(char const * address, uint16_t port) +{ + bool result = false; + struct addrinfo hints = { 0 }; + struct addrinfo * serverinfo = NULL; + struct sockaddr_in serverIPv4 = { 0 }; + struct sockaddr_in6 serverIPv6 = { 0 }; + bool serverIPv4found = false; + bool serverIPv6found = false; + + /* Check parameters. */ + assert(address != NULL); + assert(port > 0); + + /* Start by invalidating the socket. */ + netAccessSocket = NETACCESS_INVALID_SOCKET; + + /* Only continue with valid parameters. */ + if ( (address != NULL) && (port > 0) ) /*lint !e774 */ + { + /* Set result to true and only reset it to false upon detection of a problem. */ + result = true; + + /* Initialize hints structure to aid in hostname resolving. Note that AF_UNSPEC is + * used to support both IPv4 and IPv6. + */ + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = (int)SOCK_STREAM; + hints.ai_flags |= AI_CANONNAME; + + /* Attempt to resolve the hostname. This converts the hostname to an IP address, if + * it wasn't already an IP address. + */ + if (getaddrinfo(address, NULL, &hints, &serverinfo) != 0) + { + /* Could not resolve the hostname. */ + result = false; + } + /* Sanity check on the pointer that should now be initialized and contain data. */ + else + { + if (serverinfo == NULL) + { + result = false; + } + } + /* The serverinfo pointer now points to an array with results of the hostname + * resolving. We only need one, so grab the first valid one. Prefer IPv4 over IPv6. + */ + if (result) + { + /* Point to the first entry. */ + struct addrinfo * entry = serverinfo; + /* Loop over the entries until a valid one was found. */ + while (entry != NULL) + { + /* Does this entry contain an IPv4 address? */ + if (entry->ai_family == AF_INET) + { + /* Copy this one for later usage. */ + memcpy (&serverIPv4, entry->ai_addr, entry->ai_addrlen); + serverIPv4.sin_family = AF_INET; + serverIPv4.sin_port = htons(port); + /* Set flag so we know which socket address variable to use later on. */ + serverIPv4found = true; + /* No need to go over the other entries, since we found a valid one. */ + break; + } + /* Does this entry contain an IPv6 address? */ + if (entry->ai_family == AF_INET6) + { + /* Copy this one for later usage. */ + memcpy (&serverIPv6, entry->ai_addr, entry->ai_addrlen); + serverIPv6.sin6_family = AF_INET6; + serverIPv6.sin6_port = htons(port); + /* Set flag so we know which socket address variable to use later on. */ + serverIPv6found = true; + /* No need to go over the other entries, since we found a valid one. */ + break; + } + /* Move on to the next one. */ + entry = entry->ai_next; + } + } + /* Check that a valid entry was found. */ + if (result) + { + if ( (!serverIPv4found) && (!serverIPv6found) ) + { + result = false; + } + } + /* Create the socket. */ + if (result) + { + /* Create the socket based on the family type. */ + if (serverIPv4found) + { + netAccessSocket = socket(serverIPv4.sin_family, (int)SOCK_STREAM, IPPROTO_TCP); + } + else + { + netAccessSocket = socket(serverIPv6.sin6_family, (int)SOCK_STREAM, IPPROTO_TCP); + } + /* Check the socket. */ + if (netAccessSocket < 0) + { + /* Could not create the socket. */ + netAccessSocket = NETACCESS_INVALID_SOCKET; + result = false; + } + } + /* Connect the socket. */ + if (result) + { + /* Get the socket address pointer based on the family type. */ + struct sockaddr * server_address; + if (serverIPv4found) + { + server_address = (struct sockaddr *)&serverIPv4; /*lint !e740 */ + } + else + { + server_address = (struct sockaddr *)&serverIPv6; /*lint !e740 */ + } + /* Attempt to connect. */ + if (connect(netAccessSocket, server_address, sizeof(struct sockaddr)) < 0) + { + /* Could not connect. Close the socket and negate result value. */ + close(netAccessSocket); + netAccessSocket = NETACCESS_INVALID_SOCKET; + result = false; + } + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of NetAccessConnect ***/ + + +/************************************************************************************//** +** \brief Disconnects from the TCP/IP server. +** +****************************************************************************************/ +void NetAccessDisconnect(void) +{ + /* Close the socket if it is open. */ + if (netAccessSocket >= 0) + { + close(netAccessSocket); + netAccessSocket = NETACCESS_INVALID_SOCKET; + } +} /*** end of NetAccessDisconnect ***/ + + +/************************************************************************************//** +** \brief Sends data to the TCP/IP server. +** \param data Pointer to byte array with data to send. +** \param length Number of bytes to send. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool NetAccessSend(uint8_t const * data, uint32_t length) +{ + bool result = false; + + /* Check parameters. */ + assert(data != NULL); + assert(length > 0); + + /* Only continue with valid parameters. */ + if ( (data != NULL) && (length > 0) ) /*lint !e774 */ + { + /* Only continue with a valid socket. */ + if (netAccessSocket >= 0) + { + /* Attempt to send the data. */ + if (send(netAccessSocket, data, length, 0) >= 0) + { + /* Successfully send the data. */ + result = true; + } + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of NetAccessSend ***/ + + +/************************************************************************************//** +** \brief Receives data from the TCP/IP server in a blocking manner. +** \param data Pointer to byte array to store the received data. +** \param length Holds the max number of bytes that can be stored into the byte +** array. This function also overwrites this value with the number of bytes +** that were actually received. +** \param timeout Timeout in milliseconds for the data reception. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool NetAccessReceive(uint8_t * data, uint32_t * length, uint32_t timeout) +{ + bool result = false; + struct timeval tv; + ssize_t receivedLen; + + /* Check parameters. */ + assert(data != NULL); + assert(length != NULL); + assert(timeout > 0); + + /* Only continue with valid parameters. */ + if ( (data != NULL) && (length != NULL) && (timeout > 0) ) /*lint !e774 */ + { + /* Only continue with a valid socket. */ + if (netAccessSocket >= 0) + { + /* Configure the timeout for the receive operation. */ + tv.tv_sec = (time_t)(timeout / 1000u); + tv.tv_usec = (timeout % 1000u) * 1000u; + if (setsockopt(netAccessSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(struct timeval)) >= 0) + { + /* Attempt to receive data. */ + receivedLen = recv(netAccessSocket, data, *length, 0); + /* Process the result. Everything < 0 indicate that an error occured. A value of + * zero is also treated as an error, since data was expected. + */ + if (receivedLen > 0) + { + /* Store the number of received bytes. */ + *length = (uint32_t)receivedLen; + /* Successfully received data. */ + result = true; + } + } + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of NetAccessReceive ***/ + + +/*********************************** end of netaccess.c ********************************/ + diff --git a/Host/Source/LibOpenBLT/port/macos/serialport.c b/Host/Source/LibOpenBLT/port/macos/serialport.c new file mode 100644 index 00000000..9aa62a21 --- /dev/null +++ b/Host/Source/LibOpenBLT/port/macos/serialport.c @@ -0,0 +1,257 @@ +/************************************************************************************//** +* \file port/linux/serialport.c +* \brief Serial port source file. +* \ingroup SerialPort +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include /* for assertions */ +#include /* for standard integer types */ +#include /* for NULL declaration */ +#include /* for boolean type */ +#include /* UNIX standard functions */ +#include /* POSIX terminal control */ +#include /* file control definitions */ +#include /* system I/O control */ +#include "serialport.h" /* serial port module */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Invalid serial port device handle. */ +#define SERIALPORT_INVALID_HANDLE (-1) + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief Serial port handle. */ +static int32_t portHandle; + + +/**************************************************************************************** +* Local constant declarations +****************************************************************************************/ +/** \brief Lookup table for converting this module's generic baudrate value to a value + * supported by the low level interface. + */ +static const speed_t baudrateLookup[] = +{ + B9600, /**< Index 0 = SERIALPORT_BR9600 */ + B19200, /**< Index 1 = SERIALPORT_BR19200 */ + B38400, /**< Index 2 = SERIALPORT_BR38400 */ + B57600, /**< Index 3 = SERIALPORT_BR57600 */ + B115200 /**< Index 4 = SERIALPORT_BR115200 */ +}; + + +/************************************************************************************//** +** \brief Initializes the serial port module. +** +****************************************************************************************/ +void SerialPortInit(void) +{ + /* Invalidate the port handle. */ + portHandle = SERIALPORT_INVALID_HANDLE; +} /*** end of SerialPortInit ***/ + + +/************************************************************************************//** +** \brief Terminates the serial port module. +** +****************************************************************************************/ +void SerialPortTerminate(void) +{ + /* Make sure the serial port is closed. */ + SerialPortClose(); +} /*** end of SerialPortTerminate ***/ + + +/************************************************************************************//** +** \brief Opens the connection with the serial port configured as 8,N,1 and no flow +** control. +** \param portname The name of the serial port to open, i.e. /dev/ttyUSB0. +** \param baudrate The desired communication speed. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool SerialPortOpen(char const * portname, tSerialPortBaudrate baudrate) +{ + bool result = false; + struct termios options = { 0 }; + int32_t iFlags; + + /* Check parameters. */ + assert(portname != NULL); + + /* Only continue with valid parameters. */ + if (portname != NULL) /*lint !e774 */ + { + /* Assume the result to be okay from here on and only set it to error when a problem + * was detected. + */ + result = true; + /* Open the port. */ + portHandle = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); + /* Check the result */ + if (portHandle == SERIALPORT_INVALID_HANDLE) + { + result = false; + } + + /* Configure the device to block during read operations. */ + if (result) + { + if (fcntl(portHandle, F_SETFL, 0) == -1) + { + SerialPortClose(); + result = false; + } + } + /* Get the current options for the port. */ + if (result) + { + if (tcgetattr(portHandle, &options) == -1) + { + SerialPortClose(); + result = false; + } + } + /* Configure the baudrate. */ + if (result) + { + if (cfsetispeed(&options, baudrateLookup[baudrate]) == -1) + { + SerialPortClose(); + result = false; + } + } + if (result) + { + if (cfsetospeed(&options, baudrateLookup[baudrate]) == -1) + { + SerialPortClose(); + result = false; + } + } + + if (result) + { + options.c_cflag |= ( CLOCAL | CREAD | CS8); // Configure the device : 8 bits, no parity, no control + options.c_iflag |= ( IGNPAR | IGNBRK ); + options.c_cc[VTIME]=0; // Timer unused + options.c_cc[VMIN]=0; // At least on character before satisfy reading + if (tcsetattr(portHandle, TCSANOW, &options) == -1) + { + SerialPortClose(); + result = false; + } + } + } + + /* Give the result back to the caller. */ + return result; +} /*** end of SerialPortOpen ***/ + + +/************************************************************************************//** +** \brief Closes the connection with the serial port. +** +****************************************************************************************/ +void SerialPortClose(void) +{ + /* Close the port handle if valid. */ + if (portHandle != SERIALPORT_INVALID_HANDLE) + { + close(portHandle); + } + /* Invalidate handle. */ + portHandle = SERIALPORT_INVALID_HANDLE; +} /*** end of SerialPortClose ***/ + + +/************************************************************************************//** +** \brief Writes data to the serial port. +** \param data Pointer to byte array with data to write. +** \param length Number of bytes to write. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool SerialPortWrite(uint8_t const * data, uint32_t length) +{ + bool result = false; + + /* Check parameters. */ + assert(data != NULL); + assert(length > 0); + + /* Only continue with valid parameters. */ + if ( (data != NULL) && (length > 0) ) /*lint !e774 */ + { + /* Submit the data for sending. */ + if ((uint32_t)write(portHandle, data, length) == length) + { + result = true; + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of SerialPortWrite ***/ + + +/************************************************************************************//** +** \brief Reads data from the serial port in a blocking manner. +** \param data Pointer to byte array to store read data. +** \param length Number of bytes to read. +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool SerialPortRead(uint8_t * data, uint32_t length) +{ + bool result = false; + + /* Check parameters. */ + assert(data != NULL); + assert(length > 0); + + /* Only continue with valid parameters. */ + if ( (data != NULL) && (length > 0) ) /*lint !e774 */ + { + /* Attempt to read the requested data. */ + if ((uint32_t)read(portHandle, data, length) == length) + { + result = true; + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of SerialPortRead ***/ + + +/*********************************** end of serialport.c *******************************/ + diff --git a/Host/Source/LibOpenBLT/port/macos/timeutil.c b/Host/Source/LibOpenBLT/port/macos/timeutil.c new file mode 100644 index 00000000..8cc0a7a0 --- /dev/null +++ b/Host/Source/LibOpenBLT/port/macos/timeutil.c @@ -0,0 +1,71 @@ +/************************************************************************************//** +* \file port/linux/timeutil.c +* \brief Time utility source file. +* \ingroup Utility +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include /* for standard integer types */ +#include /* for NULL declaration */ +#include /* for boolean type */ +#include /* UNIX standard functions */ +#include /* time definitions */ +#include "util.h" /* Utility module */ + + +/************************************************************************************//** +** \brief Get the system time in milliseconds. +** \return Time in milliseconds. +** +****************************************************************************************/ +uint32_t UtilTimeGetSystemTimeMs(void) +{ + uint32_t result = 0; + struct timeval tv; + + if (gettimeofday(&tv, NULL) == 0) + { + result = (((uint32_t)tv.tv_sec * 1000ul) + ((uint32_t)tv.tv_usec / 1000ul)); + } + /* Give the result back to the caller. */ + return result; +} /*** end of UtilTimeGetSystemTimeMs ***/ + + +/************************************************************************************//** +** \brief Performs a delay of the specified amount of milliseconds. +** \param delay Delay time in milliseconds. +** +****************************************************************************************/ +void UtilTimeDelayMs(uint16_t delay) +{ + (void)usleep(1000u * delay); +} /*** end of UtilTimeDelayMs **/ + + +/*********************************** end of timeutil.c *********************************/ + diff --git a/Host/Source/LibOpenBLT/port/macos/xcpprotect.c b/Host/Source/LibOpenBLT/port/macos/xcpprotect.c new file mode 100644 index 00000000..78aea757 --- /dev/null +++ b/Host/Source/LibOpenBLT/port/macos/xcpprotect.c @@ -0,0 +1,194 @@ +/************************************************************************************//** +* \file port/linux/xcpprotect.c +* \brief XCP Protection module source file. +* \ingroup XcpLoader +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include /* for assertions */ +#include /* for standard integer types */ +#include /* for NULL declaration */ +#include /* for boolean type */ +#include /* for dynamic loading */ +#include "xcpprotect.h" /* XCP protection module */ + + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +/* Seed and key shared library function types. */ +typedef uint32_t ( * tXcpProtectLibComputeKey)(uint8_t resource, uint8_t seedLen, + uint8_t const * seedPtr, + uint8_t * keyLenPtr, uint8_t * keyPtr); +typedef uint32_t ( * tXcpProtectLibGetPrivileges)(uint8_t * resourcePtr); + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief Handle to the dynamically loaded seed and key shared library. It can also be + * used as a flag to determine if the shared library was specified and success- + * fully loaded. + */ +static void * seedNKeyLibraryHandle; + +/** \brief Function pointer to the XCP_ComputeKeyFromSeed shared library function. */ +static tXcpProtectLibComputeKey xcpProtectLibComputeKey; + +/** \brief Function pointer to the XCP_GetAvailablePrivileges shared library function. */ +static tXcpProtectLibGetPrivileges xcpProtectLibGetPrivileges; + + +/************************************************************************************//** +** \brief Initializes the XCP protection module. +** \param seedKeyFile Filename of the seed and key shared library that contains the +** following functions: +** - XCP_ComputeKeyFromSeed() +** - XCP_GetAvailablePrivileges() +** +****************************************************************************************/ +void XcpProtectInit(char const * seedKeyFile) +{ + /* Init locals. */ + seedNKeyLibraryHandle = NULL; + /* Reset library function pointers. */ + xcpProtectLibComputeKey = NULL; + xcpProtectLibGetPrivileges = NULL; + + /* Only load the shared library is a valid file was specified. */ + if (seedKeyFile != NULL) + { + /* Attempt to load the shared library. */ + seedNKeyLibraryHandle = dlopen(seedKeyFile, RTLD_LAZY); + /* Load the function pointers from the shared library. */ + if (seedNKeyLibraryHandle != NULL) + { + xcpProtectLibComputeKey = dlsym(seedNKeyLibraryHandle, + "XCP_ComputeKeyFromSeed"); + xcpProtectLibGetPrivileges = dlsym(seedNKeyLibraryHandle, + "XCP_GetAvailablePrivileges"); + } + } +} /*** end of XcpProtectInit ***/ + + +/************************************************************************************//** +** \brief Terminates the XCP protection module. +** +****************************************************************************************/ +void XcpProtectTerminate(void) +{ + /* Reset library function pointers. */ + xcpProtectLibComputeKey = NULL; + xcpProtectLibGetPrivileges = NULL; + /* Only unload the shared library if one was loaded. */ + if (seedNKeyLibraryHandle != NULL) + { + /* Unload the shared library. */ + (void)dlclose(seedNKeyLibraryHandle); + /* Reset the handle. */ + seedNKeyLibraryHandle = NULL; + } +} /*** end of XcpProtectTerminate ***/ + + +/************************************************************************************//** +** \brief Computes the key for the requested resource. +** \param resource resource for which the unlock key is requested +** \param seedLen length of the seed +** \param seedPtr pointer to the seed data +** \param keyLenPtr pointer where to store the key length +** \param keyPtr pointer where to store the key data +** \return True if successful, false otherwise. +** +****************************************************************************************/ +bool XCPProtectComputeKeyFromSeed(uint8_t resource, uint8_t seedLen, + uint8_t const * seedPtr, uint8_t * keyLenPtr, + uint8_t * keyPtr) +{ + bool result = false; + + /* Check parameters. */ + assert(seedLen > 0); + assert(seedPtr != NULL); + assert(keyLenPtr != NULL); + assert(keyPtr != NULL); + + /* Only continue if the parameters are valid. */ + if ( (seedLen > 0) && (seedPtr != NULL) && (keyLenPtr != NULL) && + (keyPtr != NULL) ) /*lint !e774 */ + { + /* Only continue with a valid function pointer into the shared library. */ + if (xcpProtectLibComputeKey != NULL) + { + /* Call the library function. */ + if (xcpProtectLibComputeKey(resource, seedLen, seedPtr, keyLenPtr, keyPtr) == 0) + { + /* All good so update the result value accordingly. */ + result = true; + } + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of XCPProtectComputeKeyFromSeed ***/ + + +/************************************************************************************//** +** \brief Obtains a bitmask of the resources for which an key algorithm is available. +** \param resourcePtr pointer where to store the supported resources for the key +** computation. +** \return XCP_RESULT_OK on success, otherwise XCP_RESULT_ERROR. +** +****************************************************************************************/ +bool XcpProtectGetPrivileges(uint8_t * resourcePtr) +{ + bool result = false; + + /* Check parameters. */ + assert(resourcePtr != NULL); + + /* Only continue if the parameter is valid. */ + if (resourcePtr != NULL) /*lint !e774 */ + { + /* Only continue with a valid function pointer into the shared library. */ + if (xcpProtectLibGetPrivileges != NULL) + { + /* Call the library function. */ + if (xcpProtectLibGetPrivileges(resourcePtr) == 0) + { + /* All good so update the result value accordingly. */ + result = true; + } + } + } + /* Give the result back to the caller. */ + return result; +} /*** end of XcpProtectGetPrivileges ***/ + + +/*********************************** end of xcpprotect.c *******************************/ diff --git a/Host/Source/LibOpenBLT/xcptpcan.c b/Host/Source/LibOpenBLT/xcptpcan.c index a51f2d4b..d5d37017 100644 --- a/Host/Source/LibOpenBLT/xcptpcan.c +++ b/Host/Source/LibOpenBLT/xcptpcan.c @@ -26,6 +26,8 @@ * \endinternal ****************************************************************************************/ +#ifndef NO_CAN_OR_USB + /**************************************************************************************** * Include files ****************************************************************************************/ @@ -412,4 +414,5 @@ static void XcpTpCanEventMessageReceived(tCanMsg const * msg) } /*** end of XcpTpCanEventMessageReceived ***/ +#endif // NO_CAN_OR_USB /*********************************** end of xcptpcan.c *********************************/ diff --git a/Host/Source/LibOpenBLT/xcptpusb.c b/Host/Source/LibOpenBLT/xcptpusb.c index 69b7931a..dd7ee05d 100644 --- a/Host/Source/LibOpenBLT/xcptpusb.c +++ b/Host/Source/LibOpenBLT/xcptpusb.c @@ -26,6 +26,8 @@ * \endinternal ****************************************************************************************/ +#ifndef NO_CAN_OR_USB + /**************************************************************************************** * Include files ****************************************************************************************/ @@ -226,4 +228,5 @@ static bool XcpTpUsbSendPacket(tXcpTransportPacket const * txPacket, } /*** end of XcpTpUsbSendPacket ***/ +#endif // NO_CAN_OR_USB /*********************************** end of xcptpusb.c *********************************/