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);
	}
}
Exemple #2
0
    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;
}
Exemple #4
0
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;
	}
}
Exemple #5
0
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;
	}
}
Exemple #6
0
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));
    }
}
Exemple #7
0
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;
	}
}
Exemple #10
0
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!
}