mirror of https://github.com/FOME-Tech/openblt.git
macos serial port implementation
This commit is contained in:
parent
8321fc6b44
commit
0604c329f5
|
@ -0,0 +1,279 @@
|
|||
/************************************************************************************//**
|
||||
* \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 <assert.h> /* for assertions */
|
||||
#include <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include <unistd.h> /* UNIX standard functions */
|
||||
#include <termios.h> /* POSIX terminal control */
|
||||
#include <fcntl.h> /* file control definitions */
|
||||
#include <sys/ioctl.h> /* 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)
|
||||
{
|
||||
/* Input modes - clear indicated ones giving: no break, no CR to NL,
|
||||
* no parity check, no strip char, no start/stop output (sic) control.
|
||||
*/
|
||||
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||
/* Output modes - clear giving: no post processing such as NL to CR+NL. */
|
||||
options.c_oflag &= ~(OPOST);
|
||||
/* Control modes - set 8 bit chars */
|
||||
options.c_cflag |= (CS8);
|
||||
/* Local modes - clear giving: echoing off, canonical off (no erase with
|
||||
* backspace, ^U,...), no extended functions, no signal chars (^Z,^C).
|
||||
*/
|
||||
options.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||
/* Configure timeouts. */
|
||||
options.c_cc[VMIN] = 0;
|
||||
options.c_cc[VTIME] = 1; /* in units of 1/10th of a second */
|
||||
/* Set the new options for the port. */
|
||||
if (tcsetattr(portHandle, TCSAFLUSH, &options) == -1)
|
||||
{
|
||||
SerialPortClose();
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
/* Turn on DTR. */
|
||||
if (result)
|
||||
{
|
||||
iFlags = TIOCM_DTR;
|
||||
if (ioctl(portHandle, TIOCMBIS, &iFlags) == -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 *******************************/
|
||||
|
|
@ -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 <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include <unistd.h> /* UNIX standard functions */
|
||||
#include <sys/time.h> /* 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 *********************************/
|
||||
|
|
@ -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 <assert.h> /* for assertions */
|
||||
#include <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include <dlfcn.h> /* 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 *******************************/
|
Loading…
Reference in New Issue