bool YModem::SendFile(const std::string &path, YModem::SPort &out) { if (path.size() == 0 || not out.is_open()) return false; std::fstream firm_str(path.c_str()); if (not firm_str.is_open()) return false; firm_str.seekg(0, firm_str.end); const size_t kFileSize = firm_str.tellg(); firm_str.seekg(0, firm_str.beg); // ожидание запроса WaitForResponse(out, Packet::kRequest); Packet::Sequence seq(&out); // инициализация соединения char buf[24]; snprintf(buf, 24, "%u", (unsigned)kFileSize); const std::string kMsgs[] = {path, buf}; SendInitialPkt(seq, kMsgs, 2); if (not IsResponse(out, Packet::kRequest)) { firm_str.close(); return false; } // передача файла Array frame(NewFrame()); size_t was_send = 0; size_t last_percent = 0; do { firm_str.sync(); firm_str.read((char*)frame.get(), kFrameSize); const size_t kWasRead = firm_str.gcount(); if (kWasRead != kFrameSize) { memset(frame.get() + kWasRead, 0, kFrameSize - kWasRead); } seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)); was_send += kWasRead; if (not IsResponse(out, Packet::kACK)) { std::cout << "\t ! Ошибка передачи данных" << std::endl; break; } const size_t kPercent = was_send * 100 / kFileSize; if (kPercent > last_percent) { ShowPercentage("\t * Прогресс", kPercent); last_percent = kPercent; } } while (was_send < kFileSize); std::cout << std::endl; seq.Send(Packet(Packet::kEOT)); IsResponse(out, Packet::kACK); seq.Send(Packet(Packet::kEOT)); IsResponse(out, Packet::kACK); IsResponse(out, Packet::kRequest); SendClosingPkt(seq); firm_str.close(); return true; }
bool YModem::WaitForResponse(SPort &port, const char expect) const { for (uint8_t tries = 0; tries < 255; tries++) { if (IsResponse(port, expect)) return true; } return false; }
/*=========================================================================== METHOD: GetResult (Public Method) DESCRIPTION: Return contents of mandatory result content PARAMETERS: returnCode [ I ] - The return code (should be eQMIResultCode) errorCode [ I ] - The error code (should be eQMIErrorCode) RETURN VALUE: bool ===========================================================================*/ bool sQMIServiceBuffer::GetResult( ULONG & returnCode, ULONG & errorCode ) { if (IsResponse() == false) { return false; } std::map <ULONG, const sQMIRawContentHeader *>::const_iterator pIter; pIter = mContents.find( QMI_TLV_ID_RESULT ); if (pIter == mContents.end()) { return false; } const sQMIRawContentHeader * pContent = pIter->second; if (pContent == 0) { ASSERT( 0 ); return false; } if (pContent->mLength != 4) { return false; } const WORD * pData = (const WORD *)(++pContent); returnCode = (ULONG)*pData++; errorCode = (ULONG)*pData; return true; }
void HttpClientSocket::OnFirst() { if (!IsResponse()) { Handler().LogError(this, "OnFirst", 0, "Response expected but not received - aborting", LOG_LEVEL_FATAL); SetCloseAndDelete(); } m_content = GetHttpVersion() + " " + GetStatus() + " " + GetStatusText() + "\r\n"; }
/*=========================================================================== METHOD: DecodeRxData (Internal Method) DESCRIPTION: Decode incoming data into QMI indications/responses PARAMETERS: bytesReceived [ I ] - Number of bytes to decoded rspIdx [ O ] - Log index of last valid response (not used) bAbortTx [ O ] - Response aborts current transmission? (not used) SEQUENCING: None (must be called from protocol server thread) RETURN VALUE: bool - Was a response received? ===========================================================================*/ bool cQMIProtocolServer::DecodeRxData( ULONG bytesReceived, ULONG & rspIdx, bool & bAbortTx ) { // Assume failure bool bRC = false; rspIdx = INVALID_LOG_INDEX; bAbortTx = false; // Something to decode from? if (bytesReceived == 0) { return bRC; } // Set protocol type (we have to be dealing with a valid QMI service) eProtocolType pt = MapQMIServiceToProtocol( mService, false ); if (pt == ePROTOCOL_ENUM_BEGIN) { return bRC; } sSharedBuffer * pTmp = 0; pTmp = new sSharedBuffer( mpRxBuffer, bytesReceived, pt ); if (pTmp != 0) { sQMIServiceBuffer tmpBuf( pTmp ); if (tmpBuf.IsValid() == true) { rspIdx = mLog.AddBuffer( tmpBuf ); if (IsResponse( tmpBuf ) == true) { bRC = true; } else { rspIdx = INVALID_LOG_INDEX; } } } return bRC; }
bool YModem::SendInitialPkt(Packet::Sequence &seq, const std::string *msg, size_t amount) { if (msg == 0 || amount == 0) return false; Array frame(NewFrame()); size_t total = 0; for (size_t msg_i = 0; msg_i < amount; msg_i++) { size_t i = 0; const std::string &kMsg = msg[msg_i]; for (; i < kMsg.size(); i++) { frame.get()[i] = kMsg[i]; } total += i; frame.get()[total] = 0; total++; } return (seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)) && IsResponse(*seq.get_port(), Packet::kACK)); }
bool YModem::SendClosingPkt(Packet::Sequence &seq) { seq.Reset(); Array frame(NewFrame()); return (seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)) && IsResponse(*seq.get_port(), Packet::kACK)); }
cs_int32 TrackerRecvLoop(void *ThreadData) { cs_int32 err; cs_int32 size,total,payload_size,offset,varint_size; cs_int32 RelevantMessage; cs_uchar *NewBuffer; cs_int32 NewSize; cs_uchar MessageHeader[CS_DCT_MSG_HEADERSIZE]; cs_RecvThreadData *lpRecvThreadData; lpRecvThreadData=(cs_RecvThreadData*)ThreadData; err= CS_ERR_NOERROR; offset=0; while(!(lpRecvThreadData->m_StopFlag)) { size=g_Connection->GetSize(); while(size<CS_DCT_MSG_HEADERSIZE) // Waiting to new message { err=g_Connection->Recv(); if(err) { return err; } size=g_Connection->GetSize(); } memcpy(MessageHeader,g_Connection->GetData(CS_DCT_MSG_HEADERSIZE),CS_DCT_MSG_HEADERSIZE); payload_size=(cs_int32)cs_GetUInt64LittleEndian(MessageHeader+16,4); RelevantMessage=0; if(g_ProcessMessage) // if g_ProcessMessage==0 all messages are ignored.g_ProcessMessage is set by sending thread { RelevantMessage=IsResponse(MessageHeader); } if(RelevantMessage) { // Reallocation if(offset+CS_DCT_MSG_HEADERSIZE+payload_size>g_State->m_ResponseMessageAllocSize) { NewSize=cs_AllocSize(offset+CS_DCT_MSG_HEADERSIZE+payload_size,65536,1); NewBuffer=(cs_uchar*)cs_New(NewSize,NULL,CS_ALT_DEFAULT); if(NewBuffer == NULL) { g_ErrorCode=CS_ERR_ALLOCATION; RelevantMessage=0; g_ProcessMessage=0; } else { if(g_State->m_ResponseMessage) { if(offset) { memcpy(NewBuffer,g_State->m_ResponseMessage,offset); } cs_Delete(g_State->m_ResponseMessage,NULL,CS_ALT_DEFAULT); } g_State->m_ResponseMessage=NULL; } g_State->m_ResponseMessageAllocSize=NewSize; g_State->m_ResponseMessage=NewBuffer; } memcpy(g_State->m_ResponseMessage+offset,MessageHeader,CS_DCT_MSG_HEADERSIZE); } total=0; while(total<payload_size) // Reading message { size=g_Connection->GetSize(); if(total+size>payload_size) { size=payload_size-total; } if(RelevantMessage) // Storing message { memcpy(g_State->m_ResponseMessage+offset+CS_DCT_MSG_HEADERSIZE+total,g_Connection->GetData(size),size); // cs_MemoryDump(g_State->m_ResponseMessage+offset,0,size+CS_DCT_MSG_HEADERSIZE+total); if(RelevantMessage==-1) { if(total+size>0) { varint_size=bitcoin_get_varint_size(g_State->m_ResponseMessage[offset+CS_DCT_MSG_HEADERSIZE]); if(varint_size>0) { if(total+size>=1+varint_size) { RelevantMessage=cs_GetUInt64LittleEndian(g_State->m_ResponseMessage+offset+CS_DCT_MSG_HEADERSIZE+1,varint_size); } } else { RelevantMessage=g_State->m_ResponseMessage[offset+CS_DCT_MSG_HEADERSIZE]; } } } } else // Irrelevant message is skipped, GetData shifts internal pointer { g_Connection->GetData(size); } total+=size; if(total<payload_size) // If only part of the message is received - wait for the nest chunk { err=g_Connection->Recv(); if(err) { g_ProcessMessage=0; g_ErrorCode=err; return err; } } } if(RelevantMessage) { offset+=CS_DCT_MSG_HEADERSIZE+payload_size; } if(g_ProcessMessage) { if(RelevantMessage) // Decrementing g_ProcessMessage { cs_LogMessage(g_Log,CS_LOG_MINOR,"C-0003","Bitcoin message response: ",(cs_char*)MessageHeader+4); g_ProcessMessage-=RelevantMessage; if(g_ProcessMessage==0) { offset=0; } } else { cs_LogMessage(g_Log,CS_LOG_MINOR,"C-0004","Bitcoin message ignored: ",(cs_char*)MessageHeader+4); } } } return CS_ERR_NOERROR; }
bool IMessage::IsRequest() const { return !IsResponse(); }
void DecoderImpl::DecodeAPDU(const openpal::RSlice& data) { Indent i(*callbacks); FORMAT_HEX_BLOCK(this->logger, flags::APP_HEX_RX, data, 18, 18); if (IsResponse(data)) { const auto result = APDUHeaderParser::ParseResponse(data, &logger); if (result.success) { logging::LogHeader(this->logger, flags::APP_HEADER_RX, result.header); if ((result.header.IIN.LSB & 0x01) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.0 - All stations"); if ((result.header.IIN.LSB & 0x02) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.1 - Class 1 events"); if ((result.header.IIN.LSB & 0x04) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.2 - Class 2 events"); if ((result.header.IIN.LSB & 0x08) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.3 - Class 3 events"); if ((result.header.IIN.LSB & 0x10) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.4 - Need time"); if ((result.header.IIN.LSB & 0x20) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.5 - Local control"); if ((result.header.IIN.LSB & 0x40) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.6 - Device trouble"); if ((result.header.IIN.LSB & 0x80) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN1.7 - Device restart"); if ((result.header.IIN.MSB & 0x01) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.0 - Function code not supported"); if ((result.header.IIN.MSB & 0x02) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.1 - Object unknown"); if ((result.header.IIN.MSB & 0x04) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.2 - Parameter error"); if ((result.header.IIN.MSB & 0x08) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.3 - Event buffer overflow"); if ((result.header.IIN.MSB & 0x10) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.4 - Already executing"); if ((result.header.IIN.MSB & 0x20) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.5 - Configuration corrupt"); if ((result.header.IIN.MSB & 0x40) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.6 - Reserved 1"); if ((result.header.IIN.MSB & 0x80) != 0) SIMPLE_LOG_BLOCK(this->logger, flags::APP_HEADER_RX, "IIN2.7 - Reserved 2"); Indent i(*callbacks); LoggingHandler handler(logger, *callbacks); APDUParser::ParseSinglePass(result.objects, &logger, &handler, nullptr, ParserSettings::Default()); } } else { const auto result = APDUHeaderParser::ParseRequest(data, &logger); if (result.success) { logging::LogHeader(this->logger, flags::APP_HEADER_RX, result.header); Indent i(*callbacks); LoggingHandler handler(logger, *callbacks); auto settings = (result.header.function == FunctionCode::READ) ? ParserSettings::NoContents() : ParserSettings::Default(); APDUParser::ParseSinglePass(result.objects, &logger, &handler, nullptr, settings); } } }