Format some comments including license information.
This commit is contained in:
parent
90e266ce89
commit
2854ea4a44
12 changed files with 513 additions and 593 deletions
|
|
@ -6,21 +6,16 @@
|
|||
* @author Janez Paternoster
|
||||
* @copyright 2021 Janez Paternoster
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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 CO_APPLICATION_H
|
||||
|
|
@ -47,8 +42,7 @@ extern "C" {
|
|||
*
|
||||
* @param [in,out] bitRate Stored CAN bit rate, can be overridden.
|
||||
* @param [in,out] nodeId Stored CANopen NodeId, can be overridden.
|
||||
* @param [out] errInfo Variable may indicate error information - index of
|
||||
* erroneous OD entry.
|
||||
* @param [out] errInfo Variable may indicate error information - index of erroneous OD entry.
|
||||
*
|
||||
* @return @ref CO_ReturnError_t CO_ERROR_NO in case of success.
|
||||
*/
|
||||
|
|
|
|||
46
CO_driver.c
46
CO_driver.c
|
|
@ -7,21 +7,16 @@
|
|||
* @copyright 2004 - 2015 Janez Paternoster, 2017 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -55,7 +50,6 @@ static CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
|
|||
|
||||
static const uint32_t CO_INVALID_COB_ID = 0xffffffff;
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANsetIdentToIndex(
|
||||
uint32_t *lookup,
|
||||
uint32_t index,
|
||||
|
|
@ -85,7 +79,6 @@ void CO_CANsetIdentToIndex(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
static uint32_t CO_CANgetIndexFromIdent(
|
||||
uint32_t *lookup,
|
||||
uint32_t ident)
|
||||
|
|
@ -101,7 +94,7 @@ static uint32_t CO_CANgetIndexFromIdent(
|
|||
#endif /* CO_DRIVER_MULTI_INTERFACE */
|
||||
|
||||
|
||||
/** Disable socketCAN rx ******************************************************/
|
||||
/* Disable socketCAN rx */
|
||||
static CO_ReturnError_t disableRx(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
uint32_t i;
|
||||
|
|
@ -124,7 +117,7 @@ static CO_ReturnError_t disableRx(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/** Set up or update socketCAN rx filters *************************************/
|
||||
/* Set up or update socketCAN rx filters */
|
||||
static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -167,7 +160,6 @@ static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANsetConfigurationMode(void *CANptr)
|
||||
{
|
||||
(void)CANptr;
|
||||
|
|
@ -175,7 +167,6 @@ void CO_CANsetConfigurationMode(void *CANptr)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
CO_ReturnError_t ret;
|
||||
|
|
@ -191,7 +182,6 @@ void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_CANmodule_init(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
void *CANptr,
|
||||
|
|
@ -263,7 +253,7 @@ CO_ReturnError_t CO_CANmodule_init(
|
|||
}
|
||||
|
||||
|
||||
/** enable socketCAN *********************************************************/
|
||||
/* enable socketCAN */
|
||||
#if CO_DRIVER_MULTI_INTERFACE == 0
|
||||
static
|
||||
#endif
|
||||
|
|
@ -320,7 +310,7 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
|
|||
}
|
||||
|
||||
/* enable software time stamp mode (hardware timestamps do not work properly
|
||||
* on all devices)*/
|
||||
* on all devices) */
|
||||
tmp = (SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_RX_SOFTWARE);
|
||||
ret = setsockopt(interface->fd, SOL_SOCKET, SO_TIMESTAMPING, &tmp, sizeof(tmp));
|
||||
|
|
@ -387,7 +377,6 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
uint32_t i;
|
||||
|
|
@ -423,7 +412,6 @@ void CO_CANmodule_disable(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_CANrxBufferInit(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
uint16_t index,
|
||||
|
|
@ -477,7 +465,6 @@ CO_ReturnError_t CO_CANrxBufferInit(
|
|||
|
||||
#if CO_DRIVER_MULTI_INTERFACE > 0
|
||||
|
||||
/******************************************************************************/
|
||||
bool_t CO_CANrxBuffer_getInterface(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
uint16_t ident,
|
||||
|
|
@ -514,7 +501,6 @@ bool_t CO_CANrxBuffer_getInterface(
|
|||
#endif /* CO_DRIVER_MULTI_INTERFACE */
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_CANtx_t *CO_CANtxBufferInit(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
uint16_t index,
|
||||
|
|
@ -550,7 +536,6 @@ CO_CANtx_t *CO_CANtxBufferInit(
|
|||
|
||||
#if CO_DRIVER_MULTI_INTERFACE > 0
|
||||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_CANtxBuffer_setInterface(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
uint16_t ident,
|
||||
|
|
@ -573,7 +558,7 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface(
|
|||
#endif /* CO_DRIVER_MULTI_INTERFACE */
|
||||
#if CO_DRIVER_MULTI_INTERFACE > 0
|
||||
|
||||
/* send CAN message ***********************************************************/
|
||||
/* send CAN message */
|
||||
static CO_ReturnError_t CO_CANCheckSendInterface(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
CO_CANtx_t *buffer,
|
||||
|
|
@ -660,7 +645,6 @@ static CO_ReturnError_t CO_CANCheckSendInterface(
|
|||
CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
|
||||
{
|
||||
CO_ReturnError_t err;
|
||||
|
|
@ -675,7 +659,6 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
|
||||
{
|
||||
uint32_t i;
|
||||
|
|
@ -765,7 +748,6 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
|
|||
#endif /* CO_DRIVER_MULTI_INTERFACE == 0 */
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
(void)CANmodule;
|
||||
|
|
@ -773,7 +755,6 @@ void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANmodule_process(CO_CANmodule_t *CANmodule)
|
||||
{
|
||||
if (CANmodule == NULL || CANmodule->CANinterfaceCount == 0) return;
|
||||
|
|
@ -814,7 +795,7 @@ void CO_CANmodule_process(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/* Read CAN message from socket and verify some errors ************************/
|
||||
/* Read CAN message from socket and verify some errors */
|
||||
static CO_ReturnError_t CO_CANread(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
CO_CANinterface_t *interface,
|
||||
|
|
@ -877,7 +858,7 @@ static CO_ReturnError_t CO_CANread(
|
|||
}
|
||||
|
||||
|
||||
/* find msg inside rxArray and call corresponding CANrx_callback **************/
|
||||
/* find msg inside rxArray and call corresponding CANrx_callback */
|
||||
static int32_t CO_CANrxMsg( /* return index of received message in rxArray or -1 */
|
||||
CO_CANmodule_t *CANmodule,
|
||||
struct can_frame *msg, /* CAN message input */
|
||||
|
|
@ -923,7 +904,6 @@ static int32_t CO_CANrxMsg( /* return index of received message
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule,
|
||||
struct epoll_event *ev,
|
||||
CO_CANrxMsg_t *buffer,
|
||||
|
|
|
|||
|
|
@ -8,21 +8,16 @@
|
|||
* @copyright 2004 - 2020 Janez Paternoster
|
||||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -126,6 +121,15 @@ extern "C" {
|
|||
CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE)
|
||||
#endif
|
||||
|
||||
#define CO_CONFIG_GFC (CO_CONFIG_GFC_ENABLE | \
|
||||
CO_CONFIG_GFC_CONSUMER | \
|
||||
CO_CONFIG_GFC_PRODUCER)
|
||||
|
||||
#define CO_CONFIG_SRDO (CO_CONFIG_SRDO_ENABLE | \
|
||||
CO_CONFIG_SRDO_CHECK_TX | \
|
||||
CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE | \
|
||||
CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
|
||||
|
||||
#ifndef CO_CONFIG_GTW
|
||||
#define CO_CONFIG_GTW (CO_CONFIG_GTW_ASCII | \
|
||||
CO_CONFIG_GTW_ASCII_SDO | \
|
||||
|
|
|
|||
|
|
@ -8,21 +8,16 @@
|
|||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* following macro is necessary for accept4() function call (sockets) */
|
||||
|
|
|
|||
|
|
@ -9,21 +9,16 @@
|
|||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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 CO_EPOLL_INTERFACE_H
|
||||
|
|
@ -122,8 +117,7 @@ typedef struct {
|
|||
* @param ep This object
|
||||
* @param timerInterval_us Timer interval in microseconds
|
||||
*
|
||||
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or
|
||||
* CO_ERROR_SYSCALL.
|
||||
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
|
||||
*/
|
||||
CO_ReturnError_t CO_epoll_create(CO_epoll_t *ep, uint32_t timerInterval_us);
|
||||
|
||||
|
|
@ -258,8 +252,7 @@ typedef struct {
|
|||
* @param socketTimeout_ms Timeout for established socket connection in [ms]
|
||||
* @param localSocketPath File path, if commandInterface is local socket
|
||||
*
|
||||
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or
|
||||
* CO_ERROR_SYSCALL.
|
||||
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
|
||||
*/
|
||||
CO_ReturnError_t CO_epoll_createGtw(CO_epoll_gtw_t *epGtw,
|
||||
int epoll_fd,
|
||||
|
|
@ -302,6 +295,6 @@ void CO_epoll_processGtw(CO_epoll_gtw_t *epGtw,
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CO_EPOLL_INTERFACE_H */
|
||||
|
|
|
|||
32
CO_error.c
32
CO_error.c
|
|
@ -6,21 +6,16 @@
|
|||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -35,7 +30,7 @@
|
|||
#include "301/CO_driver.h"
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Reset CAN interface and set to listen only mode
|
||||
*/
|
||||
static CO_CANinterfaceState_t CO_CANerrorSetListenOnly(
|
||||
|
|
@ -66,7 +61,7 @@ static CO_CANinterfaceState_t CO_CANerrorSetListenOnly(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Clear listen only
|
||||
*/
|
||||
static void CO_CANerrorClearListenOnly(
|
||||
|
|
@ -80,7 +75,7 @@ static void CO_CANerrorClearListenOnly(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Check and handle "bus off" state
|
||||
*/
|
||||
static CO_CANinterfaceState_t CO_CANerrorBusoff(
|
||||
|
|
@ -104,7 +99,7 @@ static CO_CANinterfaceState_t CO_CANerrorBusoff(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Check and handle controller problems
|
||||
*/
|
||||
static CO_CANinterfaceState_t CO_CANerrorCrtl(
|
||||
|
|
@ -165,7 +160,7 @@ static CO_CANinterfaceState_t CO_CANerrorCrtl(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* Check and handle controller problems
|
||||
*/
|
||||
static CO_CANinterfaceState_t CO_CANerrorNoack(
|
||||
|
|
@ -199,7 +194,6 @@ static CO_CANinterfaceState_t CO_CANerrorNoack(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANerror_init(
|
||||
CO_CANinterfaceErrorhandler_t *CANerrorhandler,
|
||||
int fd,
|
||||
|
|
@ -219,7 +213,6 @@ void CO_CANerror_init(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANerror_disable(
|
||||
CO_CANinterfaceErrorhandler_t *CANerrorhandler)
|
||||
{
|
||||
|
|
@ -232,7 +225,6 @@ void CO_CANerror_disable(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_CANerror_rxMsg(
|
||||
CO_CANinterfaceErrorhandler_t *CANerrorhandler)
|
||||
{
|
||||
|
|
@ -248,7 +240,6 @@ void CO_CANerror_rxMsg(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_CANinterfaceState_t CO_CANerror_txMsg(
|
||||
CO_CANinterfaceErrorhandler_t *CANerrorhandler)
|
||||
{
|
||||
|
|
@ -272,7 +263,6 @@ CO_CANinterfaceState_t CO_CANerror_txMsg(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_CANinterfaceState_t CO_CANerror_rxMsgError(
|
||||
CO_CANinterfaceErrorhandler_t *CANerrorhandler,
|
||||
const struct can_frame *msg)
|
||||
|
|
|
|||
22
CO_error.h
22
CO_error.h
|
|
@ -7,21 +7,16 @@
|
|||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -68,8 +63,7 @@ extern "C" {
|
|||
* openlog ("exampleprog", LOG_PID | LOG_PERROR, LOG_USER);
|
||||
* @endcode
|
||||
*
|
||||
* @param priority one of LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING,
|
||||
* LOG_NOTICE, LOG_INFO, LOG_DEBUG
|
||||
* @param priority one of LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG
|
||||
* @param format format string as in printf
|
||||
*/
|
||||
void log_printf(int priority, const char *format, ...);
|
||||
|
|
@ -186,6 +180,6 @@ CO_CANinterfaceState_t CO_CANerror_rxMsgError(
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CO_ERROR_H */
|
||||
|
|
|
|||
|
|
@ -6,21 +6,16 @@
|
|||
* @copyright 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,21 +5,16 @@
|
|||
* @author Janez Paternoster
|
||||
* @copyright 2020 Janez Paternoster
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -406,7 +401,7 @@ int main (int argc, char *argv[]) {
|
|||
CANptr.can_ifindex = if_nametoindex(CANdevice);
|
||||
}
|
||||
|
||||
/* Valid NodeId is 1..127 or 0xFF(unconfigured) in case of LSSslaveEnabled*/
|
||||
/* Valid NodeId is 1..127 or 0xFF(unconfigured) in case of LSSslaveEnabled */
|
||||
if ((nodeIdFromArgs == 0 || nodeIdFromArgs > 127)
|
||||
&& (!CO_isLSSslaveEnabled(CO)
|
||||
|| nodeIdFromArgs != CO_LSS_NODE_ID_ASSIGNMENT)
|
||||
|
|
|
|||
|
|
@ -1,323 +1,318 @@
|
|||
/*
|
||||
* CANopen data storage object for Linux
|
||||
*
|
||||
* @file CO_storageLinux.c
|
||||
* @author Janez Paternoster
|
||||
* @copyright 2021 Janez Paternoster
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CO_storageLinux.h"
|
||||
#include "301/crc16-ccitt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE
|
||||
|
||||
|
||||
/*
|
||||
* Function for writing data on "Store parameters" command - OD object 1010
|
||||
*
|
||||
* For more information see file CO_storage.h, CO_storage_entry_t.
|
||||
*/
|
||||
static ODR_t storeLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule) {
|
||||
ODR_t ret = ODR_OK;
|
||||
uint16_t crc_store;
|
||||
|
||||
/* Create names for temporary and old file */
|
||||
size_t fn_len = strlen(entry->filename) + 5;
|
||||
char *filename_tmp = malloc(fn_len);
|
||||
char *filename_old = malloc(fn_len);
|
||||
if (filename_tmp == NULL || filename_old == NULL) {
|
||||
if (filename_tmp != NULL) free(filename_tmp);
|
||||
if (filename_old != NULL) free(filename_old);
|
||||
ret = ODR_OUT_OF_MEM;
|
||||
}
|
||||
else {
|
||||
strcpy(filename_tmp, entry->filename);
|
||||
strcpy(filename_old, entry->filename);
|
||||
strcat(filename_tmp, ".tmp");
|
||||
strcat(filename_old, ".old");
|
||||
}
|
||||
|
||||
/* Open a temporary file and write data to it */
|
||||
if (ret == ODR_OK) {
|
||||
FILE *fp = fopen(filename_tmp, "w");
|
||||
if (fp == NULL) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
else {
|
||||
CO_LOCK_OD(CANmodule);
|
||||
size_t cnt = fwrite(entry->addr, 1, entry->len, fp);
|
||||
crc_store = crc16_ccitt(entry->addr, entry->len, 0);
|
||||
CO_UNLOCK_OD(CANmodule);
|
||||
cnt += fwrite(&crc_store, 1, sizeof(crc_store), fp);
|
||||
fclose(fp);
|
||||
if (cnt != (entry->len + sizeof(crc_store))) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify data */
|
||||
if (ret == ODR_OK) {
|
||||
uint8_t *buf = NULL;
|
||||
FILE *fp = NULL;
|
||||
size_t cnt = 0;
|
||||
uint16_t crc_verify, crc_read;
|
||||
|
||||
buf = malloc(entry->len + 4);
|
||||
if (buf != NULL) {
|
||||
fp = fopen(filename_tmp, "r");
|
||||
if (fp != NULL) {
|
||||
cnt = fread(buf, 1, entry->len + 4, fp);
|
||||
crc_verify = crc16_ccitt(buf, entry->len, 0);
|
||||
fclose(fp);
|
||||
memcpy(&crc_read, &buf[entry->len], sizeof(crc_read));
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
/* If size or CRC differs, report error */
|
||||
if (buf == NULL || fp == NULL || cnt != (entry->len+sizeof(crc_verify))
|
||||
|| crc_store != crc_verify || crc_store != crc_read
|
||||
) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
|
||||
/* rename existing file to *.old and *.tmp to existing */
|
||||
if (ret == ODR_OK) {
|
||||
rename(entry->filename, filename_old);
|
||||
if (rename(filename_tmp, entry->filename) != 0) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != ODR_OUT_OF_MEM) {
|
||||
free(filename_tmp);
|
||||
free(filename_old);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function for restoring data on "Restore default parameters" command - OD 1011
|
||||
*
|
||||
* For more information see file CO_storage.h, CO_storage_entry_t.
|
||||
*/
|
||||
static ODR_t restoreLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule){
|
||||
(void) CANmodule;
|
||||
ODR_t ret = ODR_OK;
|
||||
|
||||
/* close the file first, if auto storage */
|
||||
if ((entry->attr & CO_storage_auto) != 0 && entry->fp != NULL) {
|
||||
fclose(entry->fp);
|
||||
entry->fp = NULL;
|
||||
}
|
||||
|
||||
/* Rename existing filename to *.old. */
|
||||
char *filename_old = malloc(strlen(entry->filename) + 5);
|
||||
if (filename_old == NULL) {
|
||||
ret = ODR_OUT_OF_MEM;
|
||||
}
|
||||
else {
|
||||
strcpy(filename_old, entry->filename);
|
||||
strcat(filename_old, ".old");
|
||||
rename(entry->filename, filename_old);
|
||||
free(filename_old);
|
||||
}
|
||||
|
||||
/* create an empty file and write "-\n" to it. */
|
||||
if (ret == ODR_OK) {
|
||||
FILE *fp = fopen(entry->filename, "w");
|
||||
if (fp == NULL) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
else {
|
||||
fputs("-\n", fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
|
||||
CO_CANmodule_t *CANmodule,
|
||||
OD_entry_t *OD_1010_StoreParameters,
|
||||
OD_entry_t *OD_1011_RestoreDefaultParam,
|
||||
CO_storage_entry_t *entries,
|
||||
uint8_t entriesCount,
|
||||
uint32_t *storageInitError)
|
||||
{
|
||||
CO_ReturnError_t ret;
|
||||
|
||||
/* verify arguments */
|
||||
if (storage == NULL || entries == NULL || entriesCount == 0
|
||||
|| storageInitError == NULL
|
||||
) {
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
storage->enabled = false;
|
||||
|
||||
/* initialize storage and OD extensions */
|
||||
ret = CO_storage_init(storage,
|
||||
CANmodule,
|
||||
OD_1010_StoreParameters,
|
||||
OD_1011_RestoreDefaultParam,
|
||||
storeLinux,
|
||||
restoreLinux,
|
||||
entries,
|
||||
entriesCount);
|
||||
if (ret != CO_ERROR_NO) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialize entries */
|
||||
*storageInitError = 0;
|
||||
for (uint8_t i = 0; i < entriesCount; i++) {
|
||||
CO_storage_entry_t *entry = &entries[i];
|
||||
bool_t dataCorrupt = false;
|
||||
char *writeFileAccess = "w";
|
||||
|
||||
/* verify arguments */
|
||||
if (entry->addr == NULL || entry->len == 0 || entry->subIndexOD < 2
|
||||
|| strlen(entry->filename) == 0
|
||||
) {
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Open file, check existence and create temporary buffer */
|
||||
uint8_t *buf = NULL;
|
||||
FILE * fp = fopen(entry->filename, "r");
|
||||
if (fp == NULL) {
|
||||
dataCorrupt = true;
|
||||
ret = CO_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
else {
|
||||
buf = malloc(entry->len + sizeof(uint16_t));
|
||||
if (buf == NULL) {
|
||||
fclose(fp);
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read data into temporary buffer first. Then verify and copy to addr*/
|
||||
if (!dataCorrupt) {
|
||||
size_t cnt = fread(buf, 1, entry->len + sizeof(uint16_t), fp);
|
||||
|
||||
/* If file is empty, just skip loading, default values will be used,
|
||||
* no error. Otherwise verify length and crc and copy data. */
|
||||
if (!(cnt == 2 && buf[0] == '-')) {
|
||||
uint16_t crc1, crc2;
|
||||
crc1 = crc16_ccitt(buf, entry->len, 0);
|
||||
memcpy(&crc2, &buf[entry->len], sizeof(crc2));
|
||||
|
||||
if (crc1 == crc2 && cnt == (entry->len + sizeof(crc2))) {
|
||||
memcpy(entry->addr, buf, entry->len);
|
||||
entry->crc = crc1;
|
||||
writeFileAccess = "r+";
|
||||
}
|
||||
else {
|
||||
dataCorrupt = true;
|
||||
ret = CO_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* additional info in case of error */
|
||||
if (dataCorrupt) {
|
||||
uint32_t errorBit = entry->subIndexOD;
|
||||
if (errorBit > 31) errorBit = 31;
|
||||
*storageInitError |= ((uint32_t) 1) << errorBit;
|
||||
}
|
||||
|
||||
/* open file for auto storage, if set so */
|
||||
if ((entry->attr & CO_storage_auto) != 0) {
|
||||
entry->fp = fopen(entry->filename, writeFileAccess);
|
||||
if (entry->fp == NULL) {
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
} /* for (entries) */
|
||||
|
||||
storage->enabled = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
|
||||
bool_t closeFiles)
|
||||
{
|
||||
uint32_t storageError = 0;
|
||||
|
||||
/* verify arguments */
|
||||
if (storage == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* loop through entries */
|
||||
for (uint8_t i = 0; i < storage->entriesCount; i++) {
|
||||
CO_storage_entry_t *entry = &storage->entries[i];
|
||||
|
||||
if ((entry->attr & CO_storage_auto) == 0 || entry->fp == NULL)
|
||||
continue;
|
||||
|
||||
/* If CRC of the current data differs, save the file */
|
||||
uint16_t crc = crc16_ccitt(entry->addr, entry->len, 0);
|
||||
if (crc != entry->crc) {
|
||||
size_t cnt;
|
||||
rewind(entry->fp);
|
||||
CO_LOCK_OD(storage->CANmodule);
|
||||
cnt = fwrite(entry->addr, 1, entry->len, entry->fp);
|
||||
CO_UNLOCK_OD(storage->CANmodule);
|
||||
cnt += fwrite(&crc, 1, sizeof(crc), entry->fp);
|
||||
fflush(entry->fp);
|
||||
if (cnt == (entry->len + sizeof(crc))) {
|
||||
entry->crc = crc;
|
||||
}
|
||||
else {
|
||||
/* error with save */
|
||||
uint32_t errorBit = entry->subIndexOD;
|
||||
if (errorBit > 31) errorBit = 31;
|
||||
storageError |= ((uint32_t) 1) << errorBit;
|
||||
}
|
||||
}
|
||||
|
||||
if (closeFiles) {
|
||||
fclose(entry->fp);
|
||||
entry->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return storageError;
|
||||
}
|
||||
|
||||
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
|
||||
/*
|
||||
* CANopen data storage object for Linux
|
||||
*
|
||||
* @file CO_storageLinux.c
|
||||
* @author Janez Paternoster
|
||||
* @copyright 2021 Janez Paternoster
|
||||
*
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CO_storageLinux.h"
|
||||
#include "301/crc16-ccitt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE
|
||||
|
||||
|
||||
/*
|
||||
* Function for writing data on "Store parameters" command - OD object 1010
|
||||
*
|
||||
* For more information see file CO_storage.h, CO_storage_entry_t.
|
||||
*/
|
||||
static ODR_t storeLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule) {
|
||||
ODR_t ret = ODR_OK;
|
||||
uint16_t crc_store;
|
||||
|
||||
/* Create names for temporary and old file */
|
||||
size_t fn_len = strlen(entry->filename) + 5;
|
||||
char *filename_tmp = malloc(fn_len);
|
||||
char *filename_old = malloc(fn_len);
|
||||
if (filename_tmp == NULL || filename_old == NULL) {
|
||||
if (filename_tmp != NULL) free(filename_tmp);
|
||||
if (filename_old != NULL) free(filename_old);
|
||||
ret = ODR_OUT_OF_MEM;
|
||||
}
|
||||
else {
|
||||
strcpy(filename_tmp, entry->filename);
|
||||
strcpy(filename_old, entry->filename);
|
||||
strcat(filename_tmp, ".tmp");
|
||||
strcat(filename_old, ".old");
|
||||
}
|
||||
|
||||
/* Open a temporary file and write data to it */
|
||||
if (ret == ODR_OK) {
|
||||
FILE *fp = fopen(filename_tmp, "w");
|
||||
if (fp == NULL) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
else {
|
||||
CO_LOCK_OD(CANmodule);
|
||||
size_t cnt = fwrite(entry->addr, 1, entry->len, fp);
|
||||
crc_store = crc16_ccitt(entry->addr, entry->len, 0);
|
||||
CO_UNLOCK_OD(CANmodule);
|
||||
cnt += fwrite(&crc_store, 1, sizeof(crc_store), fp);
|
||||
fclose(fp);
|
||||
if (cnt != (entry->len + sizeof(crc_store))) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify data */
|
||||
if (ret == ODR_OK) {
|
||||
uint8_t *buf = NULL;
|
||||
FILE *fp = NULL;
|
||||
size_t cnt = 0;
|
||||
uint16_t crc_verify, crc_read;
|
||||
|
||||
buf = malloc(entry->len + 4);
|
||||
if (buf != NULL) {
|
||||
fp = fopen(filename_tmp, "r");
|
||||
if (fp != NULL) {
|
||||
cnt = fread(buf, 1, entry->len + 4, fp);
|
||||
crc_verify = crc16_ccitt(buf, entry->len, 0);
|
||||
fclose(fp);
|
||||
memcpy(&crc_read, &buf[entry->len], sizeof(crc_read));
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
/* If size or CRC differs, report error */
|
||||
if (buf == NULL || fp == NULL || cnt != (entry->len+sizeof(crc_verify))
|
||||
|| crc_store != crc_verify || crc_store != crc_read
|
||||
) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
|
||||
/* rename existing file to *.old and *.tmp to existing */
|
||||
if (ret == ODR_OK) {
|
||||
rename(entry->filename, filename_old);
|
||||
if (rename(filename_tmp, entry->filename) != 0) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != ODR_OUT_OF_MEM) {
|
||||
free(filename_tmp);
|
||||
free(filename_old);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function for restoring data on "Restore default parameters" command - OD 1011
|
||||
*
|
||||
* For more information see file CO_storage.h, CO_storage_entry_t.
|
||||
*/
|
||||
static ODR_t restoreLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule){
|
||||
(void) CANmodule;
|
||||
ODR_t ret = ODR_OK;
|
||||
|
||||
/* close the file first, if auto storage */
|
||||
if ((entry->attr & CO_storage_auto) != 0 && entry->fp != NULL) {
|
||||
fclose(entry->fp);
|
||||
entry->fp = NULL;
|
||||
}
|
||||
|
||||
/* Rename existing filename to *.old. */
|
||||
char *filename_old = malloc(strlen(entry->filename) + 5);
|
||||
if (filename_old == NULL) {
|
||||
ret = ODR_OUT_OF_MEM;
|
||||
}
|
||||
else {
|
||||
strcpy(filename_old, entry->filename);
|
||||
strcat(filename_old, ".old");
|
||||
rename(entry->filename, filename_old);
|
||||
free(filename_old);
|
||||
}
|
||||
|
||||
/* create an empty file and write "-\n" to it. */
|
||||
if (ret == ODR_OK) {
|
||||
FILE *fp = fopen(entry->filename, "w");
|
||||
if (fp == NULL) {
|
||||
ret = ODR_HW;
|
||||
}
|
||||
else {
|
||||
fputs("-\n", fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
|
||||
CO_CANmodule_t *CANmodule,
|
||||
OD_entry_t *OD_1010_StoreParameters,
|
||||
OD_entry_t *OD_1011_RestoreDefaultParam,
|
||||
CO_storage_entry_t *entries,
|
||||
uint8_t entriesCount,
|
||||
uint32_t *storageInitError)
|
||||
{
|
||||
CO_ReturnError_t ret;
|
||||
|
||||
/* verify arguments */
|
||||
if (storage == NULL || entries == NULL || entriesCount == 0
|
||||
|| storageInitError == NULL
|
||||
) {
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
storage->enabled = false;
|
||||
|
||||
/* initialize storage and OD extensions */
|
||||
ret = CO_storage_init(storage,
|
||||
CANmodule,
|
||||
OD_1010_StoreParameters,
|
||||
OD_1011_RestoreDefaultParam,
|
||||
storeLinux,
|
||||
restoreLinux,
|
||||
entries,
|
||||
entriesCount);
|
||||
if (ret != CO_ERROR_NO) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialize entries */
|
||||
*storageInitError = 0;
|
||||
for (uint8_t i = 0; i < entriesCount; i++) {
|
||||
CO_storage_entry_t *entry = &entries[i];
|
||||
bool_t dataCorrupt = false;
|
||||
char *writeFileAccess = "w";
|
||||
|
||||
/* verify arguments */
|
||||
if (entry->addr == NULL || entry->len == 0 || entry->subIndexOD < 2
|
||||
|| strlen(entry->filename) == 0
|
||||
) {
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Open file, check existence and create temporary buffer */
|
||||
uint8_t *buf = NULL;
|
||||
FILE * fp = fopen(entry->filename, "r");
|
||||
if (fp == NULL) {
|
||||
dataCorrupt = true;
|
||||
ret = CO_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
else {
|
||||
buf = malloc(entry->len + sizeof(uint16_t));
|
||||
if (buf == NULL) {
|
||||
fclose(fp);
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read data into temporary buffer first. Then verify and copy to addr */
|
||||
if (!dataCorrupt) {
|
||||
size_t cnt = fread(buf, 1, entry->len + sizeof(uint16_t), fp);
|
||||
|
||||
/* If file is empty, just skip loading, default values will be used,
|
||||
* no error. Otherwise verify length and crc and copy data. */
|
||||
if (!(cnt == 2 && buf[0] == '-')) {
|
||||
uint16_t crc1, crc2;
|
||||
crc1 = crc16_ccitt(buf, entry->len, 0);
|
||||
memcpy(&crc2, &buf[entry->len], sizeof(crc2));
|
||||
|
||||
if (crc1 == crc2 && cnt == (entry->len + sizeof(crc2))) {
|
||||
memcpy(entry->addr, buf, entry->len);
|
||||
entry->crc = crc1;
|
||||
writeFileAccess = "r+";
|
||||
}
|
||||
else {
|
||||
dataCorrupt = true;
|
||||
ret = CO_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* additional info in case of error */
|
||||
if (dataCorrupt) {
|
||||
uint32_t errorBit = entry->subIndexOD;
|
||||
if (errorBit > 31) errorBit = 31;
|
||||
*storageInitError |= ((uint32_t) 1) << errorBit;
|
||||
}
|
||||
|
||||
/* open file for auto storage, if set so */
|
||||
if ((entry->attr & CO_storage_auto) != 0) {
|
||||
entry->fp = fopen(entry->filename, writeFileAccess);
|
||||
if (entry->fp == NULL) {
|
||||
*storageInitError = i;
|
||||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
} /* for (entries) */
|
||||
|
||||
storage->enabled = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
|
||||
bool_t closeFiles)
|
||||
{
|
||||
uint32_t storageError = 0;
|
||||
|
||||
/* verify arguments */
|
||||
if (storage == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* loop through entries */
|
||||
for (uint8_t i = 0; i < storage->entriesCount; i++) {
|
||||
CO_storage_entry_t *entry = &storage->entries[i];
|
||||
|
||||
if ((entry->attr & CO_storage_auto) == 0 || entry->fp == NULL)
|
||||
continue;
|
||||
|
||||
/* If CRC of the current data differs, save the file */
|
||||
uint16_t crc = crc16_ccitt(entry->addr, entry->len, 0);
|
||||
if (crc != entry->crc) {
|
||||
size_t cnt;
|
||||
rewind(entry->fp);
|
||||
CO_LOCK_OD(storage->CANmodule);
|
||||
cnt = fwrite(entry->addr, 1, entry->len, entry->fp);
|
||||
CO_UNLOCK_OD(storage->CANmodule);
|
||||
cnt += fwrite(&crc, 1, sizeof(crc), entry->fp);
|
||||
fflush(entry->fp);
|
||||
if (cnt == (entry->len + sizeof(crc))) {
|
||||
entry->crc = crc;
|
||||
}
|
||||
else {
|
||||
/* error with save */
|
||||
uint32_t errorBit = entry->subIndexOD;
|
||||
if (errorBit > 31) errorBit = 31;
|
||||
storageError |= ((uint32_t) 1) << errorBit;
|
||||
}
|
||||
}
|
||||
|
||||
if (closeFiles) {
|
||||
fclose(entry->fp);
|
||||
entry->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return storageError;
|
||||
}
|
||||
|
||||
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
|
||||
|
|
|
|||
|
|
@ -1,108 +1,99 @@
|
|||
/**
|
||||
* CANopen data storage object for Linux
|
||||
*
|
||||
* @file CO_storageLinux.h
|
||||
* @ingroup CO_storageLinux
|
||||
* @author Janez Paternoster
|
||||
* @copyright 2021 Janez Paternoster
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
*
|
||||
* 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 CO_STORAGE_LINUX_H
|
||||
#define CO_STORAGE_LINUX_H
|
||||
|
||||
#include "storage/CO_storage.h"
|
||||
|
||||
#if ((CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_storageLinux Data storage with Linux
|
||||
* Data initialize, store and restore functions with Linux.
|
||||
*
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
* See also @ref CO_storage.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize data storage object (Linux specific)
|
||||
*
|
||||
* This function should be called by application after the program startup,
|
||||
* before @ref CO_CANopenInit(). This function initializes storage object,
|
||||
* OD extensions on objects 1010 and 1011, reads data from file, verifies them
|
||||
* and writes data to addresses specified inside entries. This function
|
||||
* internally calls @ref CO_storage_init().
|
||||
*
|
||||
* @param storage This object will be initialized. It must be defined by
|
||||
* application and must exist permanently.
|
||||
* @param CANmodule CAN device, used for @ref CO_LOCK_OD() macro.
|
||||
* @param OD_1010_StoreParameters OD entry for 0x1010 -"Store parameters".
|
||||
* Entry is optional, may be NULL.
|
||||
* @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default
|
||||
* parameters". Entry is optional, may be NULL.
|
||||
* @param entries Pointer to array of storage entries, see @ref CO_storage_init.
|
||||
* @param entriesCount Count of storage entries
|
||||
* @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT,
|
||||
* then this variable contains a bit mask from subIndexOD values, where data
|
||||
* was not properly initialized. If other error, then this variable contains
|
||||
* index or erroneous entry.
|
||||
*
|
||||
* @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized,
|
||||
* CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY.
|
||||
*/
|
||||
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
|
||||
CO_CANmodule_t *CANmodule,
|
||||
OD_entry_t *OD_1010_StoreParameters,
|
||||
OD_entry_t *OD_1011_RestoreDefaultParam,
|
||||
CO_storage_entry_t *entries,
|
||||
uint8_t entriesCount,
|
||||
uint32_t *storageInitError);
|
||||
|
||||
|
||||
/**
|
||||
* Automatically save data if differs from previous call.
|
||||
*
|
||||
* Should be called cyclically by program. Each interval it verifies, if crc
|
||||
* checksum of data differs from previous checksum. If it does, data are saved
|
||||
* into pre-opened file.
|
||||
*
|
||||
* @param storage This object
|
||||
* @param closeFiles If true, then all files will be closed. Use on end of the
|
||||
* program.
|
||||
*
|
||||
* @return 0 on success or bit mask from subIndexOD values, where data was not
|
||||
* able to be saved.
|
||||
*/
|
||||
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
|
||||
bool_t closeFiles);
|
||||
|
||||
/** @} */ /* CO_storageLinux */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
|
||||
|
||||
#endif /* CO_STORAGE_LINUX_H */
|
||||
/**
|
||||
* CANopen data storage object for Linux
|
||||
*
|
||||
* @file CO_storageLinux.h
|
||||
* @ingroup CO_storageLinux
|
||||
* @author Janez Paternoster
|
||||
* @copyright 2021 Janez Paternoster
|
||||
*
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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 CO_STORAGE_LINUX_H
|
||||
#define CO_STORAGE_LINUX_H
|
||||
|
||||
#include "storage/CO_storage.h"
|
||||
|
||||
#if ((CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_storageLinux Data storage with Linux
|
||||
* Data initialize, store and restore functions with Linux.
|
||||
*
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
* See also @ref CO_storage.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize data storage object (Linux specific)
|
||||
*
|
||||
* This function should be called by application after the program startup,
|
||||
* before @ref CO_CANopenInit(). This function initializes storage object,
|
||||
* OD extensions on objects 1010 and 1011, reads data from file, verifies them
|
||||
* and writes data to addresses specified inside entries. This function
|
||||
* internally calls @ref CO_storage_init().
|
||||
*
|
||||
* @param storage This object will be initialized. It must be defined by application and must exist permanently.
|
||||
* @param CANmodule CAN device, used for @ref CO_LOCK_OD() macro.
|
||||
* @param OD_1010_StoreParameters OD entry for 0x1010 -"Store parameters". Entry is optional, may be NULL.
|
||||
* @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default
|
||||
* parameters". Entry is optional, may be NULL.
|
||||
* @param entries Pointer to array of storage entries, see @ref CO_storage_init.
|
||||
* @param entriesCount Count of storage entries
|
||||
* @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT,
|
||||
* then this variable contains a bit mask from subIndexOD values, where data
|
||||
* was not properly initialized. If other error, then this variable contains
|
||||
* index or erroneous entry.
|
||||
*
|
||||
* @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized,
|
||||
* CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY.
|
||||
*/
|
||||
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
|
||||
CO_CANmodule_t *CANmodule,
|
||||
OD_entry_t *OD_1010_StoreParameters,
|
||||
OD_entry_t *OD_1011_RestoreDefaultParam,
|
||||
CO_storage_entry_t *entries,
|
||||
uint8_t entriesCount,
|
||||
uint32_t *storageInitError);
|
||||
|
||||
|
||||
/**
|
||||
* Automatically save data if differs from previous call.
|
||||
*
|
||||
* Should be called cyclically by program. Each interval it verifies, if crc
|
||||
* checksum of data differs from previous checksum. If it does, data are saved
|
||||
* into pre-opened file.
|
||||
*
|
||||
* @param storage This object
|
||||
* @param closeFiles If true, then all files will be closed. Use on end of the program.
|
||||
*
|
||||
* @return 0 on success or bit mask from subIndexOD values, where data was not able to be saved.
|
||||
*/
|
||||
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
|
||||
bool_t closeFiles);
|
||||
|
||||
/** @} */ /* CO_storageLinux */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
|
||||
|
||||
#endif /* CO_STORAGE_LINUX_H */
|
||||
|
|
|
|||
|
|
@ -5,21 +5,16 @@
|
|||
* @author Janez Paternoster
|
||||
* @copyright 2020 Janez Paternoster
|
||||
*
|
||||
* This file is part of CANopenNode, an opensource CANopen Stack.
|
||||
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
|
||||
* For more information on CANopen see <http://www.can-cia.org/>.
|
||||
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -101,14 +96,14 @@ static int printReply(int fd_gtw) {
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
ssize_t nRead = read(fd_gtw, &replyBuf[count], BUF_SIZE); /* blocking*/
|
||||
ssize_t nRead = read(fd_gtw, &replyBuf[count], BUF_SIZE); /* blocking */
|
||||
|
||||
if(nRead > 0) {
|
||||
count += nRead;
|
||||
replyBuf[count] = 0;
|
||||
|
||||
if (firstPass == 1) {
|
||||
/* check for response type. Only response value goes to stdout*/
|
||||
/* check for response type. Only response value goes to stdout */
|
||||
if (strstr(replyBuf, "] ERROR:") != NULL
|
||||
&& strstr(replyBuf, "\r\n") != NULL
|
||||
) {
|
||||
|
|
@ -198,7 +193,6 @@ static int printReply(int fd_gtw) {
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
int main (int argc, char *argv[]) {
|
||||
/* configurable options */
|
||||
enum {out_all, out_data, out_flat} outputType = out_all;
|
||||
|
|
@ -357,7 +351,7 @@ int main (int argc, char *argv[]) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else { // addrFamily == AF_UNIX
|
||||
else { /* addrFamily == AF_UNIX */
|
||||
fd_gtw = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(fd_gtw == -1) {
|
||||
perror("Socket creation failed");
|
||||
|
|
@ -429,14 +423,14 @@ int main (int argc, char *argv[]) {
|
|||
size_t len = strlen(commBuf);
|
||||
if (len < 1) continue;
|
||||
|
||||
// send command
|
||||
/* send command */
|
||||
if (write(fd_gtw, commBuf, len) != len) { /* blocking function */
|
||||
perror("Socket write failed");
|
||||
free(commBuf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// print reply, if command is complete
|
||||
/* print reply, if command is complete */
|
||||
if (commBuf[len - 1] == '\n') {
|
||||
if (printReply(fd_gtw) == EXIT_FAILURE) {
|
||||
ret = EXIT_FAILURE;
|
||||
|
|
@ -489,7 +483,7 @@ int main (int argc, char *argv[]) {
|
|||
if (len < BUF_SIZE-2 && lastChar != '\n')
|
||||
continue;
|
||||
|
||||
// send command
|
||||
/* send command */
|
||||
if (write(fd_gtw, commBuf, len) != len) { /* blocking f. */
|
||||
perror("Socket write failed");
|
||||
free(commBuf);
|
||||
|
|
@ -513,14 +507,14 @@ int main (int argc, char *argv[]) {
|
|||
size_t len = strlen(commBuf);
|
||||
if (len < 1) continue;
|
||||
|
||||
// send command
|
||||
/* send command */
|
||||
if (write(fd_gtw, commBuf, len) != len) { /* blocking function */
|
||||
perror("Socket write failed");
|
||||
free(commBuf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// print reply, if command is complete
|
||||
/* print reply, if command is complete */
|
||||
if (commBuf[len - 1] == '\n') {
|
||||
if (printReply(fd_gtw) == EXIT_FAILURE) {
|
||||
ret = EXIT_FAILURE;
|
||||
|
|
|
|||
Loading…
Reference in a new issue