/** * Copyright (c) 2017 - 2022 by Ambient Noise, LLC. * * This software is copyrighted by and is the sole property of Ambient Noise, LLC. * All rights, title, ownership, or other interests in the software remain the * property of Ambient Noise, LLC. * This software may only be used in accordance with the corresponding license agreement. * Any unauthorized use, duplication, transmission, distribution, or disclosure of * this software is expressly forbidden. * * This Copyright notice may not be removed or modified without prior * written consent of Ambient Noise, LLC. * * Ambient Noise, LLC. reserves the right to modify this software without notice. * *****************************************************************************************/ /** * @file HostTalker_transact.cpp * @author Yair Raz * @brief The Meridian Audio Engine Audio TCP/IP host interface implementation * file. * * This file is based on a C example created by DSP Concepts, Inc. It provides * the implementation of the transact() method. */ #include "HostTalker.h" #include "Errors.h" #include #include namespace meridian { namespace audio { namespace MAE { /* * transact(const uint32_t * pMessage, uint32_t * pReply) */ int32_t HostTalker::transact(const uint32_t * pMessage, uint32_t * pReply) { int32_t bRetVal = E_COMMUNICATIONS_ERROR; if (pTalker) { uint32_t txLen = pMessage[0] >> 16; // Get the length in bytes uint32_t txLenBytes = txLen * sizeof(uint32_t); // Iterate for all retries void * pData = nullptr; int len = 0; for (uint32_t retries = 0; retries < 3; ++retries) { std::string reply; bRetVal = pTalker->SendBinaryMessage(ipAddress.c_str(), // server to send to static_cast(sendPort), // port to send on reinterpret_cast(&pMessage[0]), // message to send static_cast(txLenBytes), // length of message reply, // reply message pData, // reply data len, // reply length tcpTimeout, // delay true); // force if (bRetVal == -9999) { // Timed out. fprintf(stderr, "transact(): TIMEOUT, try again\n"); bRetVal = E_MSG_TIMEOUT; continue; } if (bRetVal < 0) { // Error, done. fprintf(stderr, "transact(): Error %d\n", bRetVal); break; } if (len < 0) { len = static_cast(COMMAND_BUFFER_LENGTH * sizeof(uint32_t)); } if (len > static_cast(COMMAND_BUFFER_LENGTH * sizeof(uint32_t))) { len = static_cast(COMMAND_BUFFER_LENGTH * sizeof(uint32_t)); } memcpy(&pReply[0], pData, static_cast(len)); uint32_t repLen = pReply[0] >> 16; if (len != static_cast(repLen * sizeof(uint32_t)) ) { fprintf(stderr, "transact(): Reply length %d does not match packet header length %lu\n", len, repLen * sizeof(uint32_t)); bRetVal = E_MESSAGE_LENGTH_TOO_LONG; break; } // Check for valid packet uint32_t dwCS = verifyChecksum(pReply); if (dwCS != 0) { fprintf(stderr, "transact(): Target IO 0x%08X - 0x%08X - CHECKSUM ERROR\n", pMessage[0], pReply[0]); bRetVal = E_CRC_ERROR; continue; } // Success bRetVal = E_SUCCESS; break; } } if (bRetVal != E_SUCCESS) { fprintf(stderr, "transact(): Target IO FAILED: ret = %d\n", bRetVal); } return bRetVal; } } // namespace MAE } // namespace audio } // namespace meridian