void SerialIOHandler::TryOpen(const openpal::TimeDuration& timeout) { auto port = std::make_shared<asiopal::SerialChannel>(executor); std::error_code ec; port->Open(settings, ec); if (ec) { FORMAT_LOG_BLOCK(this->logger, openpal::logflags::WARN, "Error Connecting: %s", ec.message().c_str()); ++this->statistics.numOpenFail; auto callback = [this, timeout]() { this->TryOpen(this->retry.NextDelay(timeout)); }; this->retrytimer.Start(timeout, callback); } else { this->OnNewChannel(port); } }
void LogHeader(openpal::Logger& logger, int32_t flags, const APDUResponseHeader& header) { #ifndef OPENPAL_STRIP_LOGGING FORMAT_LOG_BLOCK(logger, flags, "FIR: %i FIN: %i CON: %i UNS: %i SEQ: %i FUNC: %s IIN: [0x%02x, 0x%02x]", header.control.FIR, header.control.FIN, header.control.CON, header.control.UNS, header.control.SEQ, FunctionCodeToString(header.function), header.IIN.LSB, header.IIN.MSB); #endif }
bool LinkLayerParser::ValidateHeaderParameters() { if(!header.ValidLength()) { ++statistics.numBadLength; FORMAT_LOG_BLOCK(logger, flags::ERR, "LENGTH out of range [5,255]: %i", header.GetLength()); return false; } //Now make sure that the function code is known and that the FCV is appropriate if (!this->ValidateFunctionCode()) { return false; } uint8_t user_data_length = header.GetLength() - LPDU_MIN_LENGTH; frameSize = LinkFrame::CalcFrameSize(user_data_length); LinkFunction func = header.GetFuncEnum(); const bool has_payload = user_data_length > 0; const bool should_have_payload = (func == LinkFunction::PRI_CONFIRMED_USER_DATA || func == LinkFunction::PRI_UNCONFIRMED_USER_DATA); // make sure that the presence/absence of user data matches the function code if(should_have_payload && !has_payload) { ++statistics.numBadLength; FORMAT_LOG_BLOCK(logger, flags::ERR, "User data with no payload. FUNCTION: %s", LinkFunctionToString(func)); return false; } if (!should_have_payload && has_payload) { ++statistics.numBadLength; FORMAT_LOG_BLOCK(logger, flags::ERR, "Unexpected LENGTH in frame: %i with FUNCTION: %s", user_data_length, LinkFunctionToString(func)); return false; } // calculate the total frame size frameSize = LinkFrame::CalcFrameSize(user_data_length); return true; }
bool IMasterTask::ValidateNoObjects(const openpal::RSlice& objects) { if (objects.IsEmpty()) { return true; } else { FORMAT_LOG_BLOCK(logger, flags::WARN, "Received unexpected response object headers for task: %s", this->Name()); return false; } }
bool IMasterTask::ValidateInternalIndications(const APDUResponseHeader& header) { if (header.IIN.HasRequestError()) { FORMAT_LOG_BLOCK(logger, flags::WARN, "Task was explicitly rejected via response with error IIN bit(s): %s", this->Name()); return false; } else { return true; } }
void TLSClient::LogVerifyCallback(bool preverified, asio::ssl::verify_context& ctx) { const int MAX_SUBJECT_NAME = 512; int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle()); // lookup the subject name X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); char subjectName[MAX_SUBJECT_NAME]; X509_NAME_oneline(X509_get_subject_name(cert), subjectName, MAX_SUBJECT_NAME); if (preverified) { FORMAT_LOG_BLOCK(this->logger, flags::INFO, "Verified certificate at depth: %d subject: %s", depth, subjectName); } else { const int err = X509_STORE_CTX_get_error(ctx.native_handle()); FORMAT_LOG_BLOCK(this->logger, flags::WARN, "Error verifying certificate at depth: %d subject: %s error: %d:%s", depth, subjectName, err, X509_verify_cert_error_string(err)); } }
IINField LoggingHandler::PrintOctets(const ICollection<Indexed<OctetString>>& items) { Indent i(*callbacks); auto logItem = [this](const Indexed<OctetString>& item) { auto slice = item.value.ToRSlice(); FORMAT_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "[%u] value: (length = %u)", item.index, slice.Size()); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, slice, 18, 18); }; items.ForeachItem(logItem); return IINField::Empty(); }
LinkLayerParser::State LinkLayerParser::ParseSync() { if (this->buffer.NumBytesRead() >= 10)// && buffer.Sync()) { uint32_t skipCount = 0; const auto synced = buffer.Sync(skipCount); if (skipCount > 0) { FORMAT_LOG_BLOCK(logger, flags::WARN, "Skipped %u bytes seaching for start bytes", skipCount); } return synced ? State::ReadHeader : State::FindSync; } else { return State::FindSync; } }
bool LinkLayerParser::ValidateBody() { uint32_t len = header.GetLength() - LPDU_MIN_LENGTH; if (LinkFrame::ValidateBodyCRC(buffer.ReadBuffer() + LPDU_HEADER_SIZE, len)) { FORMAT_LOG_BLOCK(logger, flags::LINK_RX, "Function: %s Dest: %u Source: %u Length: %u", LinkFunctionToString(header.GetFuncEnum()), header.GetDest(), header.GetSrc(), header.GetLength()); FORMAT_HEX_BLOCK(logger, flags::LINK_RX_HEX, buffer.ReadBuffer().Take(frameSize), 10, 18); return true; } else { ++this->statistics.numBodyCrcError; SIMPLE_LOG_BLOCK(logger, flags::ERR, "CRC failure in body"); return false; } }
bool LinkLayerParser::ValidateFunctionCode() { //Now make sure that the function code is known and that the FCV is appropriate if(header.IsPriToSec()) { bool fcv_set = false; switch(header.GetFuncEnum()) { case(LinkFunction::PRI_CONFIRMED_USER_DATA): case(LinkFunction::PRI_TEST_LINK_STATES): fcv_set = true; break; case(LinkFunction::PRI_REQUEST_LINK_STATUS): case(LinkFunction::PRI_RESET_LINK_STATES): case(LinkFunction::PRI_UNCONFIRMED_USER_DATA): break; default: { ++statistics.numBadFunctionCode; FORMAT_LOG_BLOCK(logger, flags::WARN, "Unknown PriToSec FUNCTION: %s", LinkFunctionToString(header.GetFuncEnum())); return false; } } //now check the fcv if(fcv_set != header.IsFcvDfcSet()) { ++statistics.numBadFCV; FORMAT_LOG_BLOCK(logger, flags::WARN, "Bad FCV for FUNCTION: %s", LinkFunctionToString(header.GetFuncEnum())); return false; } //if fcv isn't expected to be set, fcb can be either 1 or 0, doesn't matter } else // SecToPri - just validate the function codes and that FCB is 0 { switch(header.GetFuncEnum()) { case(LinkFunction::SEC_ACK): case(LinkFunction::SEC_NACK): case(LinkFunction::SEC_LINK_STATUS): case(LinkFunction::SEC_NOT_SUPPORTED): break; default: { ++statistics.numBadFunctionCode; FORMAT_LOG_BLOCK(logger, flags::ERR, "Unknown SecToPri FUNCTION: %s", LinkFunctionToString(header.GetFuncEnum())); return false; } } //now check the fcb, it should always be zero if(header.IsFcbSet()) { ++statistics.numBadFCB; FORMAT_LOG_BLOCK(logger, flags::ERR, "FCB set for SecToPri FUNCTION: %s", LinkFunctionToString(header.GetFuncEnum())); return false; } } return true; //valid! }