From 4f8835183378264d6f358632ad2da9ab10dc5cea Mon Sep 17 00:00:00 2001 From: "Hongkuk, Son" Date: Thu, 14 Dec 2017 17:56:51 +0900 Subject: [PATCH] Update snapshot(2017-12-14) Signed-off-by: Hongkuk, Son Change-Id: Iec053ef8f5cc87812aec9c884b1e811f85682de7 --- build_common/tizen/SConscript | 2 +- packaging/snapshot_history.txt | 6 +++++ .../connectivity/src/bt_le_adapter/caleadapter.c | 30 +++++++++++++--------- .../src/bt_le_adapter/tizen/caleclient.c | 4 +-- .../src/bt_le_adapter/tizen/caleserver_vd.c | 5 ++-- resource/csdk/connectivity/src/camessagehandler.c | 12 ++++----- .../csdk/connectivity/src/ip_adapter/caipadapter.c | 7 +++++ .../connectivity/src/tcp_adapter/catcpadapter.c | 25 ++++++------------ .../connectivity/src/tcp_adapter/catcpserver.c | 2 +- .../bt_le_manager/tizen/caleconnectionmanager.c | 7 ----- resource/csdk/logger/src/logger.c | 2 +- resource/csdk/stack/include/payload_logging.h | 4 +-- resource/csdk/stack/src/ocstack.c | 18 +------------ service/notification/SConscript | 5 ++-- .../notification/src/provider/NSProviderResource.c | 1 - .../src/serverBuilder/src/RCSResourceObject.cpp | 3 +++ 16 files changed, 61 insertions(+), 72 deletions(-) diff --git a/build_common/tizen/SConscript b/build_common/tizen/SConscript index aa2c212..4de8577 100644 --- a/build_common/tizen/SConscript +++ b/build_common/tizen/SConscript @@ -22,7 +22,7 @@ env.AppendUnique(CFLAGS = ['-std=gnu99']) env.AppendUnique(CCFLAGS = ['-Wextra', '-fPIC']) env.AppendUnique(LIBS = ['dl', 'pthread']) -env.AppendUnique(CCFLAGS = ['-D__TIZEN__', '-D_GNU_SOURCE', '-DTIZEN_DEBUG_ENABLE']) +env.AppendUnique(CCFLAGS = ['-D__TIZEN__', '-D_GNU_SOURCE', '-DTIZEN_DEBUG_ENABLE','-fstack-protector-strong','-Wl,-z,relro','-D_FORTIFY_SOURCE=2']) env.ParseConfig("pkg-config dlog --cflags --libs") if env.get('OIC_SUPPORT_TIZEN_TRACE') == 'True': env.ParseConfig("pkg-config ttrace --cflags --libs") diff --git a/packaging/snapshot_history.txt b/packaging/snapshot_history.txt index e659868..11e92e7 100755 --- a/packaging/snapshot_history.txt +++ b/packaging/snapshot_history.txt @@ -1,3 +1,9 @@ +http://suprem.sec.samsung.net/jira/browse/CONPRO-1163 + +commit_info_2017-12-14.txt + +commit_id: c9b22a75b21235bbf7174a40f2f658b9becd1117 +---------------------------------------------------------------------------------------------------------------------------------- http://suprem.sec.samsung.net/jira/browse/CONPRO-1155 commit_info_2017-12-06.txt diff --git a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c index 6c9d09e..5f4904c 100755 --- a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c @@ -170,7 +170,7 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL; static CAErrorHandleCallback g_errorHandler = NULL; #ifdef __WITH_DTLS__ -static void CALESecureReceiveDataCB(const CASecureEndpoint_t *endpoint, +static CAResult_t CALESecureReceiveDataCB(const CASecureEndpoint_t *endpoint, const void *data, size_t dataLength); static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, @@ -1245,8 +1245,8 @@ static void CALEServerSendDataThread(void *threadData) "CAGenerateVariableForFragmentation failed, result [%d]", result); if (g_errorHandler) { - g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); - } + g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); + } return; } @@ -1519,7 +1519,7 @@ static void CALEClientSendDataThread(void *threadData) CALEADAPTER_TAG, "CALEClientSendNegotiationMessage has failed, result [%d]", res); - if (g_errorHandler) + if (g_errorHandler) { g_errorHandler(bleData->remoteEndpoint, bleData->data, @@ -1725,7 +1725,7 @@ static void CALEClientSendDataThread(void *threadData) CALEADAPTER_TAG, "Update characteristics failed, result [%d]", result); - if (g_errorHandler) + if (g_errorHandler) { g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); } @@ -2653,13 +2653,13 @@ static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, const void *data, si return ret; } -void CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data, +CAResult_t CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data, size_t dataLen) { OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); - VERIFY_NON_NULL_VOID(sep, CALEADAPTER_TAG, "sep is NULL"); - VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "data is NULL"); + VERIFY_NON_NULL(sep, CALEADAPTER_TAG, "sep is NULL"); + VERIFY_NON_NULL(data, CALEADAPTER_TAG, "data is NULL"); OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Secure Data Receive - decrypted datalen = %d", dataLen); @@ -2667,11 +2667,12 @@ void CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data, if (dataLen <= 0) { OIC_LOG(ERROR, CALEADAPTER_TAG, "incorrect dataLen, derecypt fail !"); - return; + return CA_STATUS_INVALID_PARAM; } OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen); + CAResult_t res = CA_STATUS_OK; if (g_networkPacketReceivedCallback) { OIC_LOG_V(DEBUG, CALEADAPTER_TAG, @@ -2679,8 +2680,13 @@ void CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data, sep->endpoint.flags, sep->endpoint.flags); OIC_LOG(DEBUG, CALEADAPTER_TAG, "[CALESecureReceiveDataCB] Received data up !"); - g_networkPacketReceivedCallback(sep, data, dataLen); + res = g_networkPacketReceivedCallback(sep, data, dataLen); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Error parsing CoAP data, res = %d", res); + } } + return res; } #endif @@ -3002,7 +3008,7 @@ static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, g_dataType = dataType; oc_mutex_unlock(g_bleIsServerMutex); - result = CAencryptSsl(endpoint, data, dataLen); + result = CAencryptSsl(endpoint, (void *)data, dataLen); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!"); @@ -3044,7 +3050,7 @@ static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, g_dataType = dataType; oc_mutex_unlock(g_bleIsServerMutex); - result = CAencryptSsl(endpoint, data, dataLen); + result = CAencryptSsl(endpoint, (void *)data, dataLen); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!"); diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c index 06582b5..a829960 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c @@ -603,7 +603,7 @@ void CAStopLEGattClient() } if (context_event_loop) { - OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop); + OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %p", (void *)context_event_loop); g_main_context_wakeup(context_event_loop); // Kill g main loops and kill threads. @@ -955,7 +955,7 @@ CAResult_t CALEGattDisConnect(const char *remoteAddress) if (BT_ERROR_NONE != ret) { - OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%d] ", + OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%s] ", CALEGetErrorMsg(ret)); return CA_STATUS_FAILED; } diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c index e5a71d3..272f9c1 100755 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c @@ -27,6 +27,7 @@ #include "oic_string.h" #include "oic_malloc.h" #include "caleutil.h" +#include "caadapterutils.h" /** * Logging tag for module name @@ -433,7 +434,7 @@ CAResult_t CAStopLEGattServer() if (context_event_loop) { - OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop); + OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %p", (void *)context_event_loop); g_main_context_wakeup(context_event_loop); // Kill g main loops and kill threads @@ -752,7 +753,7 @@ CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath) VERIFY_NON_NULL(svcPath, TAG, "svcPath"); - OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath); + OIC_LOG_V(DEBUG, TAG, "svcPath: %s", (char *)svcPath); int ret = bt_gatt_server_register_service(g_gattServer, svcPath); if (0 != ret) diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index 2abb152..d9be889 100755 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -923,7 +923,7 @@ static void CAConnectionStateChangedCallback(const CAEndpoint_t *info, bool isCo { CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread, CAClearQueueEndpointDataContext, - info); + (void *)info); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Could not clear the send queue"); @@ -1686,15 +1686,15 @@ static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu) } size_t payloadLen = (pdu->data) ? (unsigned char *) pdu->hdr + pdu->length - pdu->data : 0; - OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Message Full Size = [%lu]", pdu->length); + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Message Full Size = [%u]", pdu->length); OIC_LOG(INFO, ANALYZER_TAG, "CoAP Header (+ 0xFF)"); OIC_LOG_BUFFER(INFO, ANALYZER_TAG, (const uint8_t *) pdu->transport_hdr, pdu->length - payloadLen); - OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Header size = [%lu]", pdu->length - payloadLen); + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Header size = [%" PRIuPTR "]", (size_t) pdu->length - payloadLen); OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload"); OIC_LOG_BUFFER(INFO_PRIVATE, ANALYZER_TAG, pdu->data, payloadLen); - OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload Size = [%lu]", payloadLen); + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload Size = [%" PRIuPTR "]", payloadLen); OIC_LOG(INFO, ANALYZER_TAG, "================================================="); // samsung log @@ -1735,7 +1735,7 @@ static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu) if (NULL != data->remoteEndpoint) { int i = 0; - while (NULL != data->remoteEndpoint->addr[i]) + while (data->remoteEndpoint->addr[i]) { g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->addr[i]; i++; @@ -1790,7 +1790,7 @@ static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu) if (info->resourceUri) { size_t i = 0; - while (NULL != info->resourceUri[i]) + while (info->resourceUri[i]) { g_headerBuffer[g_headerIndex++] = info->resourceUri[i]; i++; diff --git a/resource/csdk/connectivity/src/ip_adapter/caipadapter.c b/resource/csdk/connectivity/src/ip_adapter/caipadapter.c index 3df9ca6..d6b1b89 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipadapter.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipadapter.c @@ -30,7 +30,11 @@ #include "caadapterutils.h" #ifdef __WITH_DTLS__ #include "ca_adapter_net_ssl.h" +#ifdef WITH_TCP +#include "catcpinterface.h" #endif +#endif + #include "octhread.h" #include "uarraylist.h" #include "caremotehandler.h" @@ -160,6 +164,9 @@ void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status) } #ifdef __WITH_DTLS__ +#ifdef WITH_TCP + CATCPCloseInProgressConnections(); +#endif OIC_LOG(DEBUG, TAG, "close all ssl session"); CAcloseSslConnectionAll(CA_ADAPTER_IP); #endif diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c index 45c8ab9..8056418 100644 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c @@ -467,20 +467,19 @@ static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx CAResult_t CATCPDisconnectSession(const CAEndpoint_t *endpoint) { - CAResult_t res = CA_STATUS_OK; + CAResult_t res = CAQueueingThreadClearContextData(g_sendQueueHandle, + CAClearQueueEndpointDataContext, + endpoint); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "failed to clear context data"); + } + #ifdef __WITH_TLS__ res = CAcloseSslConnection(endpoint); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "failed to close TLS session"); - res = CAQueueingThreadClearContextData(g_sendQueueHandle, - CAClearQueueEndpointDataContext, - endpoint); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "failed to clear context data"); - } - return res; } #endif @@ -491,14 +490,6 @@ CAResult_t CATCPDisconnectSession(const CAEndpoint_t *endpoint) OIC_LOG(ERROR, TAG, "failed to close TCP session"); } - res = CAQueueingThreadClearContextData(g_sendQueueHandle, - CAClearQueueEndpointDataContext, - endpoint); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "failed to clear context data"); - } - return res; } diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c index d998ad6..8551650 100644 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@ -614,10 +614,10 @@ static void CAReceiveMessage(int fd) { if (CA_STATUS_OK != CATCPDisconnectSession(&svritem->sep.endpoint)) { + CASearchAndDeleteTCPSession(&svritem->sep.endpoint); OIC_LOG(ERROR, TAG, "Failed to disconnect TCP session"); } - CASearchAndDeleteTCPSession(&svritem->sep.endpoint); return; } } diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/tizen/caleconnectionmanager.c b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/tizen/caleconnectionmanager.c index d0f13bb..e831d56 100644 --- a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/tizen/caleconnectionmanager.c +++ b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/tizen/caleconnectionmanager.c @@ -31,13 +31,6 @@ #define TAG "OIC_CA_MANAGER_TZ_LE" -static CAAdapterStateChangedCB g_adapterStateCB = NULL; -static CAConnectionStateChangedCB g_connStateCB = NULL; - -static void CAManagerAdapterMonitorHandler(const CAEndpoint_t *info, CANetworkStatus_t status); -static void CAManagerConnectionMonitorHandler(CATransportAdapter_t adapter, - const char *remoteAddress, bool connected); - void CASetLENetworkMonitorCallbacks(CAAdapterStateChangedCB adapterStateCB, CAConnectionStateChangedCB connStateCB) { diff --git a/resource/csdk/logger/src/logger.c b/resource/csdk/logger/src/logger.c index 6758d09..155b2b6 100644 --- a/resource/csdk/logger/src/logger.c +++ b/resource/csdk/logger/src/logger.c @@ -72,7 +72,7 @@ static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 static const uint16_t S_LINE_BUFFER_SIZE = (50 * 2) + 50 + 1; // Show 50 bytes, 2 chars/byte, spaces between bytes, null termination #endif //defined(_MSC_VER) -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__TIZEN__) #elif defined __linux__ || defined __APPLE__ || defined _WIN32 || defined(__TIZENRT__) static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO, OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL}; diff --git a/resource/csdk/stack/include/payload_logging.h b/resource/csdk/stack/include/payload_logging.h index 9b86e38..59696c3 100644 --- a/resource/csdk/stack/include/payload_logging.h +++ b/resource/csdk/stack/include/payload_logging.h @@ -67,7 +67,7 @@ INLINE_API void OCPayloadLogRepValues(LogLevel level, OCRepPayloadValue* val) OIC_LOG_V(level, PL_TAG, "\t\t%s: NULL", val->name); break; case OCREP_PROP_INT: - OIC_LOG_V(level, PL_TAG, "\t\t%s(int):%zd", val->name, val->i); + OIC_LOG_V(level, PL_TAG, "\t\t%s(int):%" PRId64, val->name, val->i); break; case OCREP_PROP_DOUBLE: OIC_LOG_V(level, PL_TAG, "\t\t%s(double):%f", val->name, val->d); @@ -99,7 +99,7 @@ INLINE_API void OCPayloadLogRepValues(LogLevel level, OCRepPayloadValue* val) OIC_LOG(level, PL_TAG, "\t\t Values:"); for (size_t i = 0; i < val->arr.dimensions[0]; i++) { - OIC_LOG_V(level, PL_TAG, "\t\t\t %zd", val->arr.iArray[i]); + OIC_LOG_V(level, PL_TAG, "\t\t\t %" PRId64, val->arr.iArray[i]); } break; case OCREP_PROP_DOUBLE: diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index a0e4029..f588187 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -431,15 +431,6 @@ static void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bo */ static void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected); -/** - * Register network monitoring callback. - * Network status changes are delivered these callback. - * @param adapterHandler Adapter state monitoring callback. - * @param connectionHandler Connection state monitoring callback. - */ -static void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, - CAConnectionStateChangedCB connectionHandler); - //----------------------------------------------------------------------------- // Internal functions //----------------------------------------------------------------------------- @@ -1547,6 +1538,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp } else { + OICFree((void *)response.resourceUri); response.resourceUri = OICStrdup(cbNode->requestUri); } } @@ -5433,14 +5425,6 @@ void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isCon } } -void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, - CAConnectionStateChangedCB connectionHandler) -{ - OIC_LOG(DEBUG, TAG, "OCSetNetworkMonitorHandler"); - g_adapterHandler = adapterHandler; - g_connectionHandler = connectionHandler; -} - OCStackResult OCGetDeviceId(OCUUIdentity *deviceId) { OicUuid_t oicUuid; diff --git a/service/notification/SConscript b/service/notification/SConscript index ab2dcf9..cd7f017 100755 --- a/service/notification/SConscript +++ b/service/notification/SConscript @@ -81,9 +81,8 @@ if target_os == 'tizen': notification_env.AppendUnique(CPPDEFINES = ['__TIZEN__']) # notification_env.ParseConfig('pkg-config --cflags --libs sqlite3') -if target_os == 'ios': - if 'CLIENT' in notification_env.get('RD_MODE'): - notification_env.AppendUnique(CPPDEFINES = ['RD_CLIENT']) +if 'CLIENT' in notification_env.get('RD_MODE'): + notification_env.AppendUnique(CPPDEFINES = ['RD_CLIENT']) if env.get('WITH_CLOUD') == True: notification_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD']) diff --git a/service/notification/src/provider/NSProviderResource.c b/service/notification/src/provider/NSProviderResource.c index c4d2b58..494b670 100644 --- a/service/notification/src/provider/NSProviderResource.c +++ b/service/notification/src/provider/NSProviderResource.c @@ -46,7 +46,6 @@ OCStackApplicationResult NSHandlePublishCb(void *ctx, OCDoHandle handle, NSResult NSPublishResourceToCloud(char *serverAddress) { - NS_LOG(DEBUG, "NSPublishResourceToCloud - IN"); NS_LOG_V(INFO_PRIVATE, "Remote Server Address: %s", serverAddress); diff --git a/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp b/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp index f45ab77..cecfb1d 100644 --- a/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp +++ b/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp @@ -34,6 +34,9 @@ #include "logger.h" #include "OCPlatform.h" +#ifdef LOG_TAG +#undef LOG_TAG +#endif #define LOG_TAG "RCSResourceObject" namespace -- 2.7.4