IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var10& value, const openpal::RSlice& object) { Indent i(*callbacks); { std::ostringstream oss; oss << "kcm: " << KeyChangeMethodToString(value.keyChangeMethod); oss << " op: " << UserOperationToString(value.userOperation); oss << " scsn: " << value.statusChangeSeqNum; oss << " role: " << value.userRole; oss << "exp: " << value.userRoleExpDays; SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); } SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "user name: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.userName, 18, 18); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "pub key: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.userPublicKey, 18, 18); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "cert data: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.certificationData, 18, 18); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var6& value, const openpal::RSlice& object) { Indent i(*callbacks); std::ostringstream oss; oss << "ksq: " << value.keyChangeSeqNum; oss << " user: "******"key data: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.keyWrapData, 18, 18); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var8& value, const openpal::RSlice& object) { Indent i(*callbacks); std::ostringstream oss; oss << "kcm: " << KeyChangeMethodToString(value.keyChangeMethod); oss << " type: " << CertificateTypeToString(value.certificateType); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "certificate: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.certificate, 18, 18); return IINField::Empty(); }
bool LinkSession::OnFrame(const LinkHeaderFields& header, const openpal::RSlice& userdata) { if (this->stack) { this->stack->OnFrame(header, userdata); } else { this->first_frame_timer.Cancel(); this->callbacks->OnFirstFrame(this->session_id, header, *this); if (this->stack) { this->stack->OnLowerLayerUp(); // push the frame into the newly created stack this->stack->OnFrame(header, userdata); } else { SIMPLE_LOG_BLOCK(this->logger, flags::WARN, "No master created. Closing socket."); this->ShutdownImpl(); } } return true; }
std::shared_ptr<IMasterSession> LinkSession::AcceptSession( const std::string& loggerid, std::shared_ptr<opendnp3::ISOEHandler> SOEHandler, std::shared_ptr<opendnp3::IMasterApplication> application, const MasterStackConfig& config) { if (this->stack) { SIMPLE_LOG_BLOCK(this->logger, flags::ERR, "SocketSession already has a master bound"); return nullptr; } // rename the logger id to something meaningful this->logger.Rename(loggerid); this->stack = MasterSessionStack::Create( this->logger, this->channel->executor, SOEHandler, application, shared_from_this(), *this, config ); return stack; }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var1& value, const openpal::RSlice& object) { Indent i(*callbacks); std::ostringstream oss; oss << "csq: " << value.challengeSeqNum; oss << " user: "******" MAC: " << HMACTypeToString(value.hmacAlgo); oss << " reason: " << ChallengeReasonToString(value.challengeReason); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "challenge data: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.challengeData, 18, 18); return IINField::Empty(); }
void LoggingHandler::OnHeaderResult(const HeaderRecord& record, const IINField& result) { if (result.Any()) { Indent i(*callbacks); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "Pretty printing not supported for this type"); } }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var15& value, const openpal::RSlice& object) { Indent i(*callbacks); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "MAC value: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.hmacValue, 18, 18); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var11& value, const openpal::RSlice& object) { Indent i(*callbacks); { std::ostringstream oss; oss << "kcm: " << KeyChangeMethodToString(value.keyChangeMethod); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); } SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "user name: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.userName, 18, 18); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "master challenge data: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.challengeData, 18, 18); return IINField::Empty(); }
bool IMasterTask::ValidateSingleResponse(const APDUResponseHeader& header) { if (header.control.FIR && header.control.FIN) { return true; } else { SIMPLE_LOG_BLOCK(logger, flags::WARN, "Ignoring unexpected response FIR/FIN not set"); return false; } }
void LinkSession::OnWriteComplete(const std::error_code& ec, size_t num) { if (ec) { SIMPLE_LOG_BLOCK(this->logger, flags::WARN, ec.message().c_str()); this->ShutdownImpl(); } else { this->stack->OnTransmitComplete(true); } }
void LinkSession::OnReadComplete(const std::error_code& ec, size_t num) { if (ec) { SIMPLE_LOG_BLOCK(this->logger, flags::WARN, ec.message().c_str()); this->ShutdownImpl(); } else { this->parser.OnRead(static_cast<uint32_t>(num), *this); this->BeginReceive(); } }
void LinkSession::Start() { this->channel->SetCallbacks(shared_from_this()); auto timeout = [self = shared_from_this()]() { SIMPLE_LOG_BLOCK(self->logger, flags::ERR, "Timed out before receving a frame. Closing socket."); self->channel->Shutdown(); }; this->first_frame_timer.Start(this->callbacks->GetFirstFrameTimeout(), timeout); this->BeginReceive(); }
IINField LoggingHandler::ProcessHeader(const FreeFormatHeader& header, const Group120Var7& value, const openpal::RSlice& object) { Indent i(*callbacks); { std::ostringstream oss; oss << "seq: " << value.challengeSeqNum; oss << " user: "******" assoc: " << value.assocId; oss << " error: " << AuthErrorCodeToString(value.errorCode); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); } { std::ostringstream oss; oss << "time of error: " << ToUTCString(value.time); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); } SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, "error text: "); FORMAT_HEX_BLOCK(logger, flags::APP_OBJECT_RX, value.errorText, 18, 18); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const CountHeader& header, const ICollection<Group120Var4>& values) { Indent i(*callbacks); auto print = [this](const Group120Var4 & value) { std::ostringstream oss; oss << "user: " << value.userNum; SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); }; values.ForeachItem(print); return IINField::Empty(); }
IINField LoggingHandler::PrintTimeAndInterval(const ICollection<Indexed<TimeAndInterval>>& values) { Indent i(*callbacks); auto logItem = [this](const Indexed<TimeAndInterval>& item) { std::ostringstream oss; oss << "[" << item.index << "] - startTime: " << ToUTCString(item.value.time); oss << " count: " << item.value.interval; oss << " units: " << IntervalUnitsToString(item.value.GetUnitsEnum()) << " (" << static_cast<int>(item.value.units) << ")"; SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); }; values.ForeachItem(logItem); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const PrefixHeader& header, const ICollection<Indexed<Group122Var2>>& values) { Indent i(*callbacks); auto logItem = [this](const Indexed<Group122Var2>& item) { std::ostringstream oss; oss << "[" << item.index << "] - flags: 0x" << ToHex(item.value.flags); oss << " assoc: " << item.value.assocId; oss << " value: " << item.value.value; oss << " time: " << ToUTCString(item.value.time); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); }; values.ForeachItem(logItem); return IINField::Empty(); }
IINField LoggingHandler::PrintCrob(const ICollection<Indexed<ControlRelayOutputBlock>>& items) { Indent i(*callbacks); auto logItem = [this](const Indexed<ControlRelayOutputBlock>& item) { std::ostringstream oss; oss << "[" << item.index << "] - code: 0x" << ToHex(item.value.rawCode) << " (" << ControlCodeToString(item.value.functionCode) << ")"; oss << " count: " << static_cast<uint32_t>(item.value.count); oss << " on-time: " << static_cast<uint32_t>(item.value.onTimeMS); oss << " off-time: " << static_cast<uint32_t>(item.value.offTimeMS); oss << " status: " << CommandStatusToString(item.value.status); SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); }; items.ForeachItem(logItem); return IINField::Empty(); }
IINField LoggingHandler::ProcessHeader(const PrefixHeader& header, const ICollection<Indexed<AnalogCommandEvent>>& values) { Indent i(*callbacks); const bool HAS_TIME = HasAbsoluteTime(header.enumeration); auto logItem = [this, HAS_TIME](const Indexed<AnalogCommandEvent>& item) { std::ostringstream oss; oss << "[" << item.index << "] - value: " << item.value.value << " status: " << CommandStatusToString(item.value.status); if (HAS_TIME) { oss << " time: " << ToUTCString(item.value.time); } SIMPLE_LOG_BLOCK(logger, flags::APP_OBJECT_RX, oss.str().c_str()); }; values.ForeachItem(logItem); return IINField::Empty(); }
bool LinkLayerParser::ReadHeader() { header.Read(buffer.ReadBuffer()); if (CRC::IsCorrectCRC(buffer.ReadBuffer(), LI_CRC)) { if (ValidateHeaderParameters()) { return true; } else { return false; } } else { ++statistics.numHeaderCrcError; SIMPLE_LOG_BLOCK(logger, flags::WARN, "CRC failure in header"); return false; } }
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; } }
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); } } }