Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
---
title: estos Enhanced Sample Neufeld ASN C Compiler
scope: estos-esnacc
owner_repo: esnacc
entry_for:
- ASN.1 compiler development
- target-language code generation
- protocol documentation generation
purpose: Explain how to build and use the enhanced ASN.1 compiler and its generated targets.
read_when:
- Changing compiler behavior or generated output
- Updating build instructions
- Investigating TypeScript, C++, C, C#, Java, Kotlin, Swift, JSDoc, IDL, or OpenAPI generation
related_docs:
- AGENTS.md
- FAQ.md
- samples/readme.md
- cpp-lib/tests/runtime_correctness_notes.md
---

# estos Enhanced Sample Neufeld ASN C Compiler
This is the estos enhanced sample neufeld asn c compiler.
It is an functional enriched fork of the original enhanced sample neufeld asn c compiler offering:
Expand Down Expand Up @@ -65,8 +45,6 @@ Those two languages offer JSON and BER encoding for the transport layer, a compl
Other languages just offer to get created structures which need to get serialized / deserialized in JSON with other functions of the language.

# Getting started
Agents and contributors: start with [AGENTS.md](AGENTS.md) for repository routing and task-specific documentation entry points.

You need to compile the compiler or use a precompiled version of it.
The samples folder offers examples on the usage for the different supported languages. These folders show some sample asn1 files, the command line and the expected output of the compiler.
See [samples/readme.md](samples/readme.md) for the current TypeScript microservice sample layout and required Node/pnpm setup.
Expand Down
2 changes: 1 addition & 1 deletion cpp-lib/include/SnaccROSEBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,4 +461,4 @@ class SnaccROSEBase : public SnaccROSESender, public SnaccTelemetryCallback
long Send(SNACC::ROSEInvoke* pInvoke, const char* szOperationName, SnaccInvokeContext& ctx, size_t* pstRequestData = nullptr);
};

#endif //_SnaccROSEBase_h_
#endif //_SnaccROSEBase_h_
2 changes: 1 addition & 1 deletion cpp-lib/include/SnaccROSEInterfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,4 @@ class ISnaccROSETransport
virtual long SendBinaryDataBlockEx(const char* lpBytes, size_t size, SnaccInvokeContext& ctx) = 0;
};

#endif //_SnaccROSEInterfaces_h_
#endif //_SnaccROSEInterfaces_h_
8 changes: 2 additions & 6 deletions cpp-lib/include/SnaccTelemetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,11 @@ class SnaccTelemetryData

// Creates the telemetry object in shared ownership so it can be forwarded safely.
static std::shared_ptr<SnaccTelemetryData> Create(Direction direction, unsigned int uiOperationID, const char* szOperationName, size_t stRequestData, std::chrono::steady_clock::time_point chronoCreated = std::chrono::steady_clock::now());
static std::shared_ptr<SnaccTelemetryData> CreateFinalized(Direction direction, unsigned int uiOperationID, const char* szOperationName, size_t stRequestData, Outcome outcome, Stage stage, Reason reason,
long lRoseResult,
std::optional<size_t> stResponseData = std::nullopt, std::shared_ptr<SnaccInvokeContext> pctx = {},
std::chrono::steady_clock::time_point chronoCreated = std::chrono::steady_clock::now());
static std::shared_ptr<SnaccTelemetryData> CreateFinalized(Direction direction, unsigned int uiOperationID, const char* szOperationName, size_t stRequestData, Outcome outcome, Stage stage, Reason reason, long lRoseResult, std::optional<size_t> stResponseData = std::nullopt, std::shared_ptr<SnaccInvokeContext> pctx = {}, std::chrono::steady_clock::time_point chronoCreated = std::chrono::steady_clock::now());

// Finalizes the telemetry data once the local request lifecycle has completed.
// For events pass Outcome::EVENT and leave stResponseData empty.
void finalize(Outcome outcome, Stage stage, Reason reason, std::optional<long> lRoseResult = std::nullopt, std::optional<size_t> stResponseData = std::nullopt,
std::shared_ptr<SnaccInvokeContext> pctx = {});
void finalize(Outcome outcome, Stage stage, Reason reason, std::optional<long> lRoseResult = std::nullopt, std::optional<size_t> stResponseData = std::nullopt, std::shared_ptr<SnaccInvokeContext> pctx = {});

// Immutable request metadata captured when the lifecycle starts.
const Direction m_Direction{};
Expand Down
172 changes: 48 additions & 124 deletions cpp-lib/src/SnaccROSEBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,15 +305,7 @@ const char* SnaccROSEBase::InboundInvokeRejectContext::OperationNameCStr() const

void SnaccROSEBase::EmitInboundDecodeFailureTelemetry(unsigned long ulMessageSize, unsigned int uiOperationID, const char* szOperationName, SnaccTelemetryData::Outcome outcome, long lTelemetryResult)
{
OnInvokeProcessed(SnaccTelemetryData::CreateFinalized(
SnaccTelemetryData::Direction::INBOUND,
uiOperationID,
szOperationName,
ulMessageSize,
outcome,
SnaccTelemetryData::Stage::INBOUND_DECODE,
SnaccTelemetryData::Reason::DECODE_FAILED,
lTelemetryResult));
OnInvokeProcessed(SnaccTelemetryData::CreateFinalized(SnaccTelemetryData::Direction::INBOUND, uiOperationID, szOperationName, ulMessageSize, outcome, SnaccTelemetryData::Stage::INBOUND_DECODE, SnaccTelemetryData::Reason::DECODE_FAILED, lTelemetryResult));
}

void SnaccROSEBase::EmitInboundGenericDecodeFailureTelemetry(unsigned long ulMessageSize)
Expand Down Expand Up @@ -348,8 +340,7 @@ SnaccROSEBase::InboundDecodeFailureResult SnaccROSEBase::HandleInboundRoseDecode
reject.reject->invokeProblem = new InvokeProblem(SNACC::InvokeProblem::mistypedArgument);
reject.details = UTF8String::CreateNewFromASCII(strRejectDetails.c_str());

auto pRejectCtx = SnaccInvokeContext::Create(
SnaccInvokeContextInit(SnaccInvokeDirection::INBOUND, nullptr, rejectCtx->OperationNameCStr()));
auto pRejectCtx = SnaccInvokeContext::Create(SnaccInvokeContextInit(SnaccInvokeDirection::INBOUND, nullptr, rejectCtx->OperationNameCStr()));
const long lRejectResult = SendRejectEx(&reject, *pRejectCtx);
if (lRejectResult == ROSE_NOERROR)
{
Expand All @@ -361,17 +352,7 @@ SnaccROSEBase::InboundDecodeFailureResult SnaccROSEBase::HandleInboundRoseDecode
return result;
}

void SnaccROSEBase::HandleInboundEnvelopeSnaccDecodeFailure(
SNACC::TransportEncoding transportEncoding,
SNACC::TransportEncoding hookEncoding,
const char* lpBytes,
unsigned long ulMessageSize,
bool& bLogTransportData,
const SNACC::SnaccException& ex,
const std::optional<InboundInvokeRejectContext>& rejectCtx,
bool bSendReject,
bool bRejectDetailsFromPrettyJson,
const char* szMethod)
void SnaccROSEBase::HandleInboundEnvelopeSnaccDecodeFailure(SNACC::TransportEncoding transportEncoding, SNACC::TransportEncoding hookEncoding, const char* lpBytes, unsigned long ulMessageSize, bool& bLogTransportData, const SNACC::SnaccException& ex, const std::optional<InboundInvokeRejectContext>& rejectCtx, bool bSendReject, bool bRejectDetailsFromPrettyJson, const char* szMethod)
{
if (bLogTransportData)
bLogTransportData = LogTransportData(false, transportEncoding, nullptr, lpBytes, ulMessageSize, nullptr, nullptr);
Expand All @@ -389,13 +370,7 @@ void SnaccROSEBase::HandleInboundEnvelopeSnaccDecodeFailure(
EmitInboundDecodeFailureTelemetry(ulMessageSize, failure.uiOperationID, failure.szOperationName, failure.outcome, failure.lTelemetryResult);
}

void SnaccROSEBase::HandleInboundJsonParseDecodeFailure(
SNACC::TransportEncoding transportEncoding,
const char* lpBytes,
unsigned long ulMessageSize,
bool& bLogTransportData,
const std::string& parseError,
const char* szMethod)
void SnaccROSEBase::HandleInboundJsonParseDecodeFailure(SNACC::TransportEncoding transportEncoding, const char* lpBytes, unsigned long ulMessageSize, bool& bLogTransportData, const std::string& parseError, const char* szMethod)
{
if (bLogTransportData)
bLogTransportData = LogTransportData(false, transportEncoding, nullptr, lpBytes, ulMessageSize, nullptr, nullptr);
Expand Down Expand Up @@ -831,17 +806,7 @@ bool SnaccROSEBase::OnBinaryDataBlockResult(const char* lpBytes, unsigned long l
}
catch (const SnaccException& ex)
{
HandleInboundEnvelopeSnaccDecodeFailure(
m_eTransportEncoding,
SNACC::TransportEncoding::BER,
lpBytes,
lSize,
bLogTransportData,
ex,
rejectCtx,
false,
false,
__FUNCTION__);
HandleInboundEnvelopeSnaccDecodeFailure(m_eTransportEncoding, SNACC::TransportEncoding::BER, lpBytes, lSize, bLogTransportData, ex, rejectCtx, false, false, __FUNCTION__);
return true;
}
break;
Expand Down Expand Up @@ -869,29 +834,13 @@ bool SnaccROSEBase::OnBinaryDataBlockResult(const char* lpBytes, unsigned long l
}
catch (const SnaccException& ex)
{
HandleInboundEnvelopeSnaccDecodeFailure(
m_eTransportEncoding,
m_eTransportEncoding,
lpBytes,
lSize,
bLogTransportData,
ex,
rejectCtx,
false,
true,
__FUNCTION__);
HandleInboundEnvelopeSnaccDecodeFailure(m_eTransportEncoding, m_eTransportEncoding, lpBytes, lSize, bLogTransportData, ex, rejectCtx, false, true, __FUNCTION__);
return true;
}
}
else
{
HandleInboundJsonParseDecodeFailure(
m_eTransportEncoding,
lpBytes,
lSize,
bLogTransportData,
reader.getFormattedErrorMessages(),
__FUNCTION__);
HandleInboundJsonParseDecodeFailure(m_eTransportEncoding, lpBytes, lSize, bLogTransportData, reader.getFormattedErrorMessages(), __FUNCTION__);
}
break;
}
Expand Down Expand Up @@ -1019,17 +968,7 @@ void SnaccROSEBase::OnBinaryDataBlock(const char* lpBytes, unsigned long ulSize,
}
catch (const SnaccException& ex)
{
HandleInboundEnvelopeSnaccDecodeFailure(
m_eTransportEncoding,
SNACC::TransportEncoding::BER,
lpBytes,
ulSize,
bLogTransportData,
ex,
rejectCtx,
true,
false,
__FUNCTION__);
HandleInboundEnvelopeSnaccDecodeFailure(m_eTransportEncoding, SNACC::TransportEncoding::BER, lpBytes, ulSize, bLogTransportData, ex, rejectCtx, true, false, __FUNCTION__);
}
break;
}
Expand All @@ -1055,28 +994,12 @@ void SnaccROSEBase::OnBinaryDataBlock(const char* lpBytes, unsigned long ulSize,
}
catch (const SnaccException& ex)
{
HandleInboundEnvelopeSnaccDecodeFailure(
m_eTransportEncoding,
m_eTransportEncoding,
lpBytes,
ulSize,
bLogTransportData,
ex,
rejectCtx,
true,
true,
__FUNCTION__);
HandleInboundEnvelopeSnaccDecodeFailure(m_eTransportEncoding, m_eTransportEncoding, lpBytes, ulSize, bLogTransportData, ex, rejectCtx, true, true, __FUNCTION__);
}
}
else
{
HandleInboundJsonParseDecodeFailure(
m_eTransportEncoding,
lpBytes,
ulSize,
bLogTransportData,
reader.getFormattedErrorMessages(),
__FUNCTION__);
HandleInboundJsonParseDecodeFailure(m_eTransportEncoding, lpBytes, ulSize, bLogTransportData, reader.getFormattedErrorMessages(), __FUNCTION__);
}
break;
}
Expand Down Expand Up @@ -1108,47 +1031,47 @@ bool SnaccROSEBase::OnROSEMessage(std::unique_ptr<SNACC::ROSEMessage> pMessage,
switch (pMessage->choiceId)
{
case ROSEMessage::invokeCid:
{
auto& invoke = *pMessage->invoke;
if (bAllowAllInvokes || m_multithreadInvokeIDs.find(invoke.operationID) != m_multithreadInvokeIDs.end())
{
if (invoke.operationName && invoke.operationID == 0)
invoke.operationID = SnaccRoseOperationLookup::LookUpID(invoke.operationName->getASCII().c_str());
auto& invoke = *pMessage->invoke;
if (bAllowAllInvokes || m_multithreadInvokeIDs.find(invoke.operationID) != m_multithreadInvokeIDs.end())
{
if (invoke.operationName && invoke.operationID == 0)
invoke.operationID = SnaccRoseOperationLookup::LookUpID(invoke.operationName->getASCII().c_str());

if (invoke.operationID || invoke.operationName)
OnInvokeMessage(std::move(pMessage), ulMessageSize);
if (invoke.operationID || invoke.operationName)
OnInvokeMessage(std::move(pMessage), ulMessageSize);

bProcessed = true;
bProcessed = true;
}
break;
}
break;
}
case ROSEMessage::resultCid:
{
const int invokeID = pMessage->result->invokeID;
OnResultMessage(*pMessage->result, ulMessageSize);
CompletePendingOperation(invokeID, std::move(pMessage), ulMessageSize);
return true;
}
{
const int invokeID = pMessage->result->invokeID;
OnResultMessage(*pMessage->result, ulMessageSize);
CompletePendingOperation(invokeID, std::move(pMessage), ulMessageSize);
return true;
}
case ROSEMessage::errorCid:
{
const int invokeID = pMessage->error->invokedID;
OnErrorMessage(*pMessage->error, ulMessageSize);
CompletePendingOperation(invokeID, std::move(pMessage), ulMessageSize);
return true;
}
case ROSEMessage::rejectCid:
{
auto& reject = *pMessage->reject;
OnRejectMessage(reject, ulMessageSize);
if (reject.invokedID.choiceId == ROSERejectChoice::invokedIDCid && reject.invokedID.invokedID != nullptr)
{
const int invokeID = *reject.invokedID.invokedID;
const int invokeID = pMessage->error->invokedID;
OnErrorMessage(*pMessage->error, ulMessageSize);
CompletePendingOperation(invokeID, std::move(pMessage), ulMessageSize);
return true;
}
bProcessed = true;
break;
}
case ROSEMessage::rejectCid:
{
auto& reject = *pMessage->reject;
OnRejectMessage(reject, ulMessageSize);
if (reject.invokedID.choiceId == ROSERejectChoice::invokedIDCid && reject.invokedID.invokedID != nullptr)
{
const int invokeID = *reject.invokedID.invokedID;
CompletePendingOperation(invokeID, std::move(pMessage), ulMessageSize);
return true;
}
bProcessed = true;
break;
}
default:
break;
}
Expand Down Expand Up @@ -1474,6 +1397,10 @@ long SnaccROSEBase::Send(SNACC::ROSEInvoke* pInvoke, const char* szOperationName
}
else
{
// You need to specify the transport encoding when the connection is setup
// The connection is no longer defaulting to BER. This needs to be set explicit.
// Inbound connections adopt the encoding as soon as the first payload is received
ASSERT(0);
throw std::runtime_error("invalid m_eTransportEncoding");
}

Expand All @@ -1483,16 +1410,13 @@ long SnaccROSEBase::Send(SNACC::ROSEInvoke* pInvoke, const char* szOperationName
long SnaccROSEBase::SendEvent(SNACC::ROSEInvoke* pInvoke, const char* szOperationName, std::shared_ptr<SnaccInvokeContext> pCtx /*= {}*/)
{
const auto chronoCreated = std::chrono::steady_clock::now();
const char* szResolvedOperationName = SnaccRoseOperationLookup::LookUpName(pInvoke->operationID);
if (!pCtx)
{
SnaccInvokeContextInit init(SnaccInvokeDirection::OUTBOUND, pInvoke, szResolvedOperationName ? szResolvedOperationName : szOperationName);
pCtx = CreateInvokeContext(init);
}
pCtx = CreateInvokeContext(SnaccInvokeContextInit(SnaccInvokeDirection::OUTBOUND, pInvoke, szOperationName));
auto& ctx = *pCtx;

size_t stRequestData = 0;
const long lRoseResult = IsProcessingAllowed() ? Send(pInvoke, szOperationName, ctx, &stRequestData) : ROSE_TE_SHUTDOWN;
auto telemetry = SnaccTelemetryData::Create(SnaccTelemetryData::Direction::OUTBOUND, pInvoke->operationID, szResolvedOperationName, stRequestData, chronoCreated);
auto telemetry = SnaccTelemetryData::Create(SnaccTelemetryData::Direction::OUTBOUND, pInvoke->operationID, szOperationName, stRequestData, chronoCreated);
telemetry->finalize(lRoseResult == ROSE_NOERROR ? SnaccTelemetryData::Outcome::EVENT : SnaccTelemetryData::Outcome::UNHANDLED, SnaccTelemetryData::Stage::OUTBOUND_SEND, lRoseResult == ROSE_NOERROR ? SnaccTelemetryData::Reason::LOCAL_EVENT : GetUnhandledReasonFromResult(lRoseResult), lRoseResult, std::nullopt, pCtx);
OnInvokeProcessed(telemetry);
return lRoseResult;
Expand Down
6 changes: 3 additions & 3 deletions version.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef VERSION_H
#define VERSION_H

#define VERSION "7.0.6"
#define VERSION_RC 7, 0, 6
#define RELDATE "07.07.2026"
#define VERSION "7.0.7"
#define VERSION_RC 7, 0, 7
#define RELDATE "13.07.2026"

#endif // VERSION_H
Loading