Beispiel #1
0
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();
}
Beispiel #2
0
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();
}
Beispiel #3
0
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();
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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();
}
Beispiel #7
0
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");
	}
}
Beispiel #8
0
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();
}
Beispiel #9
0
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();
}
Beispiel #10
0
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;
	}
}
Beispiel #11
0
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);
	}
}
Beispiel #12
0
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();
	}
}
Beispiel #13
0
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();
}
Beispiel #14
0
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();
}
Beispiel #15
0
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();
}
Beispiel #16
0
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();
}
Beispiel #17
0
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();
}
Beispiel #18
0
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();
}
Beispiel #19
0
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();
}
Beispiel #20
0
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;
	}
}
Beispiel #21
0
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;
	}
}
Beispiel #22
0
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);
        }
    }
}