/* Read data from a file script The function reads len bytes from the script. The buf argument must be at least of size len. In addition, it must be possible to successfully read len bytes from the file. Otherwise, the function fails and returns an appropriate error code. */ McpBtsSpStatus _MCP_BTS_SP_FsReadScript(McpBtsSpContext *context, void *buf, McpUint len) { McpHalFsStatus fsStatus; McpU32 numRead; /* Read up to len bytes from the file */ fsStatus = MCP_HAL_FS_Read(context->locationData.fileDesc, buf, (McpU32)len, &numRead); if (fsStatus != MCP_HAL_FS_STATUS_SUCCESS) { MCP_LOG_ERROR(("_MCP_BTS_SP_FsReadScript: MCP_HAL_FS_Read Failed (%d)", fsStatus)); return MCP_BTS_SP_STATUS_FFS_ERROR; } /* Verify that we indeed read len bytes and not less */ if (numRead != len) { MCP_LOG_ERROR(("_MCP_BTS_SP_FsReadScript: Expected to read %d bytes, read %d", len, numRead)); return MCP_BTS_SP_STATUS_FFS_ERROR; } /* Update position in file */ context->scriptProcessingPos += numRead; return MCP_BTS_SP_STATUS_SUCCESS; }
McpBtsSpStatus _MCP_BTS_SP_VerifyMagicNumber(McpBtsSpContext *context) { McpBtsSpStatus spStatus; MCP_BTS_SP_ScriptHeader header; /* Read script header */ spStatus = _MCP_BTS_SP_ReadScript(context, &header, sizeof(header)); if (spStatus != MCP_BTS_SP_STATUS_SUCCESS) { MCP_LOG_ERROR(("_MCP_BTS_SP_VerifyMagicNumber: Failed getting script header (%s)", _MCP_BTS_SP_DebugStatusStr(spStatus))); return spStatus; } /* check magic number [ToDo] Consider possible Endianity problems */ if (header.magicNumber != MCP_BTS_SP_FILE_HEADER_MAGIC) { MCP_LOG_ERROR(("_MCP_BTS_SP_VerifyMagicNumber: Invalid Magic Number (%x), Expected (%x)", header.magicNumber, MCP_BTS_SP_FILE_HEADER_MAGIC)); return MCP_BTS_SP_STATUS_INVALID_SCRIPT; } return MCP_BTS_SP_STATUS_SUCCESS; }
/* Opens the script file and obtains its size */ McpBtsSpStatus _MCP_BTS_SP_FsOpenScript(McpBtsSpContext *context, const McpUtf8 *fullFileName) { McpHalFsStatus fsStatus; McpHalFsStat fsStat; /* Get file information */ fsStatus = MCP_HAL_FS_Stat(fullFileName, &fsStat); if (fsStatus != MCP_HAL_FS_STATUS_SUCCESS) { /* Failed to get file information - report and return proper error code */ MCP_LOG_ERROR(("_MCP_BTS_SP_FsOpenScript: MCP_HAL_FS_Stat Failed (%d)", fsStatus)); if (fsStatus == MCP_HAL_FS_STATUS_ERROR_NOTFOUND) { return MCP_BTS_SP_STATUS_FILE_NOT_FOUND; } else { return MCP_BTS_SP_STATUS_FFS_ERROR; } } /* Record the file size*/ context->scriptSize = fsStat.size; /* Open the script file for reading as a binary file */ fsStatus = MCP_HAL_FS_Open(fullFileName, (MCP_HAL_FS_O_RDONLY | MCP_HAL_FS_O_BINARY), &context->locationData.fileDesc); if (fsStatus != MCP_HAL_FS_STATUS_SUCCESS) { MCP_LOG_ERROR(("_MCP_BTS_SP_FsOpenScript: MCP_HAL_FS_Open Failed (%d)", fsStatus)); return MCP_BTS_SP_STATUS_FFS_ERROR; } MCP_LOG_INFO(("_MCP_BTS_SP_FsOpenScript: Successfully opened %s", (char *)fullFileName)); return MCP_BTS_SP_STATUS_SUCCESS; }
/** * \fn ccmaReceiveCb * \brief Receive callback from the BT driver * * The function implements a callback for receiving events from the BT driver * * \note * \param hCcma - handle to CCMA object returned by the HAL ST * \param pkt - received packet * \param len - received packet's length * \param status - Receive's action status * \return RES_OK * \sa CCMA_SendHciCommand */ static EMcpfRes ccmaReceiveCb(handle_t hCcma, McpU8 *pkt, McpU32 len, eHalHciStatus status) { MCPF_UNUSED_PARAMETER(hCcma); MCPF_UNUSED_PARAMETER(pkt); MCPF_UNUSED_PARAMETER(len); MCPF_UNUSED_PARAMETER(status); MCP_FUNC_START("ccmaReceiveCb"); MCP_LOG_ERROR(("ccmaReceiveCb: ERROR - It is unexpected to received RX other than CMD COMPLETE!")); MCP_FUNC_END(); return RES_OK; }
/* Closes the script file */ McpBtsSpStatus _MCP_BTS_SP_FsCloseScript(McpBtsSpContext *context) { McpHalFsStatus fsStatus; if (context->locationData.fileDesc != MCP_HAL_FS_INVALID_FILE_DESC) { fsStatus = MCP_HAL_FS_Close(context->locationData.fileDesc); context->locationData.fileDesc = MCP_HAL_FS_INVALID_FILE_DESC; if (fsStatus != MCP_HAL_FS_STATUS_SUCCESS) { MCP_LOG_ERROR(("_MCP_BTS_SP_FsOpenScriptFile: MCP_HAL_FS_Open Failed (%d)", fsStatus)); return MCP_BTS_SP_STATUS_FFS_ERROR; } } return MCP_BTS_SP_STATUS_SUCCESS; }
/* This function starts the script execution It may return synchronously in the following cases: 1. It detects an error at this phase; Or 2. The script doesn't contain any HCI command or delay (e.g., only comments) Otherwise, the function returns MCP_BTS_SP_STATUS_PENDING and completion will be notified via execCompleteCb */ McpBtsSpStatus MCP_BTS_SP_ExecuteScript(const McpBtsSpScriptLocation *scriptLocation, const McpBtsSpExecuteScriptCbData *cbData, McpBtsSpContext *context) { McpBtsSpStatus status; /* Initialize processing management fields. Applicable fields are initialized from arguments. Others are initialized using default values */ context->locationType = scriptLocation->locationType; context->locationData.fileDesc = MCP_HAL_FS_INVALID_FILE_DESC; context->scriptSize = 0; context->cbData = *cbData; context->asyncExecution = MCP_FALSE; context->processingState = MCP_BTS_SP_PROCESSING_STATE_NONE; context->scriptProcessingPos = 0; context->abortRequested = MCP_FALSE; /* Open the script file */ status = _MCP_BTS_SP_OpenScript(context, scriptLocation); if (status != MCP_BTS_SP_STATUS_SUCCESS) { MCP_LOG_ERROR(("MCP_BTS_SP_ExecuteScript: _MCP_BTS_SP_OpenScript Failed (%s), Exiting", _MCP_BTS_SP_DebugStatusStr(status))); _MCP_BTS_SP_CompleteExecution(context, status); return status; } /* Verify that the magic number i the script header is valid */ status = _MCP_BTS_SP_VerifyMagicNumber(context); if (status != MCP_BTS_SP_STATUS_SUCCESS) { MCP_LOG_ERROR(("MCP_BTS_SP_ExecuteScript: _MCP_BTS_SP_VerifyMagicNumber Failed (%s), Exiting", _MCP_BTS_SP_DebugStatusStr(status))); _MCP_BTS_SP_CompleteExecution(context, status); return status; } /* Start processing script actions */ status = _MCP_BTS_SP_ProcessScriptCommands(context, MCP_BTS_SP_PROCESSING_EVENT_START, NULL); if (status == MCP_BTS_SP_STATUS_SUCCESS) { /* Execution completed successfully */ _MCP_BTS_SP_CompleteExecution(context, MCP_BTS_SP_STATUS_SUCCESS); } else if (status == MCP_BTS_SP_STATUS_PENDING) { /* Do Nothing, Wait for command complete event to continue processing */ } else { /* Commands processing failed, abort and notify failure */ _MCP_BTS_SP_CompleteExecution(context, status); } return status; }
/** * \fn CCMA_SendHciCommand * \brief Send HCI command over transport layer * */ CcmaStatus CCMA_SendHciCommand(CcmaClientHandle hClientHandle, CcmaHciOpcode eHciOpcode, McpU8 *pHciCmdParms, McpU8 uHciCmdParmsLen, McpU8 uEeventType, void *pUserData) { TClientNode *pClient = (TClientNode *)hClientHandle; TCcmaObj *pCcma = (TCcmaObj *)pClient->hCcma; CcmaStatus eStatus; #ifdef MCP_STK_ENABLE eHalHciStatus eResult; #else EMcpfRes eRes; #endif MCP_FUNC_START("CCMA_SendHciCommand"); MCP_UNUSED_PARAMETER(uEeventType); /* Save user's data for future use */ pClient->hClientUserData = pUserData; #ifdef MCP_STK_ENABLE eResult = hal_hci_SendCommand(pCcma->hHalHci, eHciOpcode, pHciCmdParms, uHciCmdParmsLen, clientCmdComplete, hClientHandle); if (eResult != HAL_HCI_STATUS_PENDING) { MCP_LOG_ERROR(("Error writing HCI packet")); eStatus = CCMA_STATUS_FAILED; } else { eStatus = CCMA_STATUS_PENDING; } #else eRes = HCIA_SendCommand(((Tmcpf *)pCcma->hMcpf)->hHcia, (McpU16) eHciOpcode, pHciCmdParms, uHciCmdParmsLen, clientCmdComplete, hClientHandle); if (eRes == RES_OK) { eStatus = CCMA_STATUS_PENDING; } else { eStatus = CCMA_STATUS_FAILED; } #endif MCP_FUNC_END(); return eStatus; }