// ------------------------------------------------------------------------------------------- // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // This file is part of the AWS CDI-SDK, licensed under the BSD 2-Clause "Simplified" License. // License details at: https://github.com/aws/aws-cdi-sdk/blob/mainline/LICENSE // ------------------------------------------------------------------------------------------- /** * @file * @brief * This file contains the definitions of the functions that comprise the CDI Core SDK's API. */ // Include headers in the following order: Related header, C system headers, other libraries' headers, your project's // headers. #include "cdi_core_api.h" #include "internal.h" #include "internal_rx.h" //********************************************************************************************************************* //***************************************** START OF DEFINITIONS AND TYPES ******************************************** //********************************************************************************************************************* //********************************************************************************************************************* //*********************************************** START OF VARIABLES ************************************************** //********************************************************************************************************************* //********************************************************************************************************************* //******************************************* START OF STATIC FUNCTIONS *********************************************** //********************************************************************************************************************* //********************************************************************************************************************* //******************************************* START OF PUBLIC FUNCTIONS *********************************************** //********************************************************************************************************************* //////////////////////////////////////////////////////////////////////////////// // Doxygen commenting for these functions is in cdi_core_api.h. //////////////////////////////////////////////////////////////////////////////// CdiReturnStatus CdiCoreInitialize(const CdiCoreConfigData* core_config_ptr) { CdiReturnStatus rs = kCdiStatusOk; if (NULL == core_config_ptr) { return kCdiStatusInvalidParameter; } // Set up anything in global context required by CdiGlobalInitialization(). rs = CdiGlobalInitialization(core_config_ptr); return rs; } CdiReturnStatus CdiCoreNetworkAdapterInitialize(CdiAdapterData* adapter_data_ptr, CdiAdapterHandle* ret_handle_ptr) { CdiReturnStatus rs = kCdiStatusOk; if (!cdi_global_context.sdk_initialized) { return kCdiStatusNotInitialized; } // initialize the adapter if (rs == kCdiStatusOk) { rs = AdapterInitializeInternal(adapter_data_ptr, ret_handle_ptr); } return rs; } CdiReturnStatus CdiCoreNetworkAdapterDestroy(CdiAdapterHandle handle) { CdiReturnStatus rs = kCdiStatusOk; if (!IsValidAdapterHandle(handle)) { rs = kCdiStatusInvalidHandle; } if (rs == kCdiStatusOk) { rs = NetworkAdapterDestroyInternal(handle); } return rs; } CdiReturnStatus CdiCoreRxFreeBuffer(const CdiSgList* sgl_ptr) { CdiReturnStatus rs = kCdiStatusOk; if (NULL == sgl_ptr) { return kCdiStatusInvalidParameter; } // Don't process an internally generated empty SGL. if (sgl_ptr->sgl_head_ptr != &cdi_global_context.empty_sgl_entry) { if (!IsValidMemoryHandle(sgl_ptr->internal_data_ptr)) { rs = kCdiStatusInvalidHandle; } else { // Return the packet buffers and SGL entries to the endpoint. rs = RxEnqueueFreeBuffer(sgl_ptr); } } return rs; } int CdiCoreGather(const CdiSgList* sgl_ptr, int offset, void* dest_data, int byte_count) { if (NULL == sgl_ptr) { return -1; } if (NULL == dest_data) { return -1; } return CdiGatherInternal(sgl_ptr, offset, dest_data, byte_count); } CdiReturnStatus CdiCoreStatsReconfigure(CdiConnectionHandle handle, const CdiStatsConfigData* config_ptr) { if (!IsValidConnectionHandle(handle)) { return kCdiStatusInvalidHandle; } // Use false here so settings are only applied if they have changed. return CoreStatsConfigureInternal(handle, config_ptr, false); } CdiReturnStatus CdiCoreConnectionDestroy(CdiConnectionHandle handle) { if (!IsValidConnectionHandle(handle)) { return kCdiStatusInvalidHandle; } ConnectionDestroyInternal(handle); return kCdiStatusOk; } CdiReturnStatus CdiCoreShutdown(void) { return SdkShutdownInternal(); } void CdiCoreGetUtcTime(struct timespec* ret_time_ptr) { CdiOsGetUtcTime(ret_time_ptr); } CdiPtpTimestamp CdiCoreGetPtpTimestamp(CdiPtpTimestamp* ret_ptp_time_ptr) { struct timespec utc_time; CdiCoreGetUtcTime(&utc_time); // The current TAI offset relative to UTC is 37 seconds. Unfortunately at this point there are no trivial methods // for automatically updated leapseconds as they are announced. This is an area of that we are continuing to study. // The next possible leapsecond event June 30th 2021. const CdiPtpTimestamp ptp_timestamp = { .seconds = (uint32_t)utc_time.tv_sec + 37, .nanoseconds = (uint32_t)utc_time.tv_nsec }; if (NULL != ret_ptp_time_ptr) { *ret_ptp_time_ptr = ptp_timestamp; } return ptp_timestamp; } uint64_t CdiCoreGetUtcTimeMicroseconds(void) { struct timespec utc_time; CdiCoreGetUtcTime(&utc_time); return (uint64_t)utc_time.tv_sec * 1000000L + (utc_time.tv_nsec / 1000L); } uint64_t CdiCoreGetTaiTimeMicroseconds(void) { CdiPtpTimestamp ptp_time; CdiCoreGetPtpTimestamp(&ptp_time); return (uint64_t)ptp_time.seconds * 1000000L + (ptp_time.nanoseconds / 1000L); } const char* CdiCoreStatusToString(CdiReturnStatus status) { static const CdiEnumStringKey key_array[] = { { kCdiStatusOk, "OK" }, { kCdiStatusFatal, "fatal error encountered" }, { kCdiStatusNotEnoughMemory, "not enough memory" }, { kCdiStatusNotInitialized, "not initialized" }, { kCdiStatusMaxLatencyExceeded, "maximum latency exceeded" }, { kCdiStatusInvalidHandle, "invalid handle" }, { kCdiStatusInvalidParameter, "invalid parameter" }, { kCdiStatusNotConnected, "not connected" }, { kCdiStatusQueueFull, "queue full" }, { kCdiStatusInvalidConnectionType, "invalid connection type" }, { kCdiStatusRxPayloadError, "receive payload error" }, { kCdiStatusRxWrongProtocolType, "received wrong protocol type" }, { kCdiStatusCreateLogFailed, "failed to create log" }, { kCdiStatusCreateThreadFailed, "failed to create thread" }, { kCdiStatusShuttingDown, "failed to shutdown" }, { kCdiStatusWrongDirection, "wrong endpoint direction" }, { kCdiStatusGetPortFailed, "failed to get port" }, { kCdiStatusNotReady, "connection not ready" }, { kCdiStatusSendFailed, "failed to send a packet" }, { kCdiStatusAllocationFailed, "failed to allocate resource" }, { kCdiStatusOpenFailed, "failed to open a port" }, { kCdiStatusDuplicateConnection, "duplicate connection error" }, { kCdiStatusInvalidSgl, "scatter-gather list is invalid" }, { kCdiStatusEndpointManagerState, "endpoint manager state changed" }, { kCdiStatusBufferOverflow, "buffer overflowed" }, { kCdiStatusArraySizeExceeded, "array size exceeded" }, { kCdiStatusNonFatal, "non-fatal error encountered" }, { kCdiStatusCloudWatchNotEnabled, "CloudWatch SDK not enabled" }, { kCdiStatusCloudWatchThrottling, "CloudWatch throttling - retry" }, { kCdiStatusCloudWatchInvalidCredentials, "CloudWatch invalid credentials" }, { kCdiStatusInternalIdle, "Internal poll thread is idle" }, { kCdiStatusAdapterDuplicateEntry, "Duplicate adapter entry" }, { kCdiStatusProfileNotSupported, "Baseline profile not supported" }, { kCdiStatusProbePacketCrcError, "Probe packet CRC error" }, { kCdiStatusProbePacketInvalidSize, "Probe packet size is invalid" }, { kCdiStatusRxPayloadBackPressure, "Rx back pressure" }, { kCdiStatusDuplicateBaselineVersion, "baseline version already registered"}, { kCdiStatusInvalidPayload, "payload not readable" }, { kCdiStatusLibraryLoadFailed, "Library load failed" }, { kCdiStatusLibrarySymbolNotFound, "Library symbol not found" }, { kCdiStatusLibraryWrongVersion, "Wrong library version" }, { CDI_INVALID_ENUM_VALUE, "" }, }; return CdiUtilityEnumValueToString(key_array, status); } const CdiCoreReadOnlySettings* CdiCoreGetSettings() { static const CdiCoreReadOnlySettings settings = { .tx_retry_timeout_ms = TX_COMMAND_MAX_RETRIES * TX_COMMAND_ACK_TIMEOUT_MSEC, .rx_wait_timeout_ms = RX_PING_MONITOR_TIMEOUT_MSEC, }; return &settings; }