stream << SmartIndent(CB_LOG_DEF);
}
+void CBodyGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER);
+}
+
void CBodyGeneratorBase::GenBaseDefinition(std::ofstream& stream) {
stream << SmartIndent(CB_BASE_DEF);
}
void GenIncludeHeader(std::ofstream& stream);
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
void GenBaseDefinition(std::ofstream& stream);
const std::string& GetParcelType(const BaseType& type);
#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__c_cb";
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__c_cb(
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+)__c_cb";
+
constexpr const char CB_BASE_DEF[] =
R"__c_cb(
#ifndef nullptr
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_PROXY"));
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
GenBaseDefinition(stream);
GenInterfaceDelegateCallback(stream);
GenStructureDefs(stream);
void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
int res_;
if (h == nullptr<METHOD_PARAMS_CHECK>) {
return;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%d\", [Sequence] %d", TIDL_VERSION, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
<METHOD_PARCEL_WRITE>
<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int recv_seq_num_ = -1;
+ char *tag_ = nullptr;
+ bool done_ = false;
int res_;
<RETURN_TYPE>ret_ = <ERROR_VALUE>;
<METHOD_ARGS>
return ret_;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
<METHOD_PARCEL_WRITE>
break;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ if (tag_ && tag_[0] != '\0') {
+ _W("[Version] %s", tag_);
+ rpc_port_parcel_header_get_seq_num(header_, &recv_seq_num_);
+ if (recv_seq_num_ != seq_num_) {
+ _E("Invalid protocol. %d", recv_seq_num_);
+ free(tag_);
+ rpc_port_parcel_destroy(parcel_);
+ continue;
+ }
+ }
+ done_ = true;
+ free(tag_);
+
<METHOD_PARCEL_READ>
rpc_port_parcel_destroy(parcel_);
- } while (0);
+ } while (!done_);
g_rec_mutex_unlock(&h->mutex);
set_last_result(res_);
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_STUB"));
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
GenBaseDefinition(stream);
GenThreadEnableDefinition(stream);
GenInterfaceMethodHandlerType(stream);
static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, void *user_data)
{
<PREFIX>_<NAME>_context_h context_ = user_data;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
rpc_port_h callback_port_;
int ret_;
<METHOD_HANDLER_ARGS_DECL>
goto out;
}
+ rpc_port_parcel_get_header(parcel, &header_);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Sequence] %d", seq_num_);
+
<METHOD_HANDLER_PARCEL_READ>
<METHOD_HANDLER_CALLBACK_INVOKE>
<METHOD_HANDLER_PARCEL_WRITE>
goto out;
}
+rpc_port_parcel_get_header(parcel_, &header_);
+rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+rpc_port_parcel_header_set_seq_num(header_, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, RPC_PORT_STUB_<UPPERCASE_NAME>_METHOD_RESULT_);
)__c_cb";
stream << CB_LOG_DEF;
}
+void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION_DEF, "[VERSION]", FULLVER);
+}
+
} // namespace tidl
std::string GetParameters(const Parameters& ps);
void GenLogTag(std::ofstream& stream, std::string id);
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
private:
void GenSetter(std::ofstream& stream, const Element& ele);
#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__cpp_cb";
+/**
+ * [VERSION] Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__cpp_cb(
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "[VERSION]"
+#endif
+)__cpp_cb";
+
#endif // IDLC_CPP_GEN_CPP_GEN_BASE_CB_H_
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_PROXY");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
}
stream << AddIndent(TAB_SIZE, m) << NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- stream << Tab(1) << "rpc_port_parcel_h parcel_received;" << NLine(1);
- stream << Tab(1) << "do ";
- GenBrace(stream, TAB_SIZE, [&]() {
- stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
- << NLine(2);
- if (!l.empty())
- stream << AddIndent(TAB_SIZE * 2, l);
- stream << CB_INVOCATION_MID << NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- stream << Tab(2) << "// Receive" << NLine(1);
- stream << Tab(2)
- << "ConsumeCommand(&parcel_received, port_);" << NLine(1);
- }
- }, false, false);
- stream << " while (false);" << NLine(1);
+ stream << Tab(1) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+ << NLine(1);
+
+ if (!l.empty())
+ stream << AddIndent(TAB_SIZE, l);
+
+ stream << CB_INVOCATION_MID;
// Deserialize
if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
return;
}
- stream << CB_INVOCATION_RECEIVE << NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) {
- continue;
- }
-
- std::string c = ConvertTypeToDeserializer(
- i->GetParameterType().GetBaseType(),
- i->GetID(), "parcel_received", false);
- if (c != "")
- stream << AddIndent(TAB_SIZE, c);
- }
-
- if (decl.GetType().ToString() != "void") {
- stream << AddIndent(TAB_SIZE,
- ConvertTypeToDeserializer(decl.GetType(),
- "ret", "parcel_received"));
- }
+ auto parcel_read = [&]() -> std::string {
+ std::string code;
+ for (auto& i : decl.GetParameters().GetParams()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN)
+ continue;
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), i->GetID(),
+ "parcel_received", false);
+ if (c != "")
+ code += AddIndent(TAB_SIZE * 2, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ code += AddIndent(TAB_SIZE * 2,
+ ConvertTypeToDeserializer(decl.GetType(), "ret",
+ "parcel_received"));
+ }
+
+ return code;
+ };
+ stream << ReplaceAll(CB_INVOCATION_RECEIVE, "[PARCEL_READ]", parcel_read());
stream << CB_INVOCATION_END;
}
rpc_port_parcel_h p;
rpc_port_parcel_create(&p);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(p, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
)__cpp_cb";
const char CB_INVOCATION_MID[] =
R"__cpp_cb(
- // Send
- int r = rpc_port_parcel_send(p, port_);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Failed to send parcel. result(%d)", r);
- rpc_port_parcel_destroy(p);
- throw InvalidIOException();
- }
+ // Send
+ int r = rpc_port_parcel_send(p, port_);
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. result(%d)", r);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
)__cpp_cb";
+/**
+ * [PARCEL_READ] The implementation to read the data from the parcel.
+ */
const char CB_INVOCATION_RECEIVE[] =
R"__cpp_cb(
- if (parcel_received == nullptr) {
- _E("Invalid protocol");
- throw InvalidProtocolException();
- }
+ bool done_ = false;
+ do {
+ rpc_port_parcel_h parcel_received = nullptr;
+ // Receive
+ ConsumeCommand(&parcel_received, port_);
+ if (parcel_received == nullptr) {
+ _E("Invalid protocol");
+ throw InvalidProtocolException();
+ }
+
+ rpc_port_parcel_get_header(parcel_received, &header_);
+ char* tag_ = nullptr;
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ std::unique_ptr<char, decltype(std::free)*> tag_auto_(tag_, std::free);
+ if (tag_ && tag_[0] != '\0') {
+ _W("[Version] %s", tag_);
+ int seq_num_received_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_received_);
+ if (seq_num_received_ != seq_num_) {
+ _E("Invalid protocol. %d", seq_num_received_);
+ rpc_port_parcel_destroy(parcel_received);
+ continue;
+ }
+ }
+ done_ = true;
+
+[PARCEL_READ]
+ rpc_port_parcel_destroy(parcel_received);
+ } while (!done_);
)__cpp_cb";
const char CB_INVOCATION_END[] =
R"__cpp_cb(
rpc_port_parcel_destroy(p);
- rpc_port_parcel_destroy(parcel_received);
return ret;
)__cpp_cb";
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_STUB");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
return iface.GetID();
});
} else {
- GenTemplate(CB_ON_RECEIVED_CB_FRONT, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ std::string code = ReplaceAll(CB_ON_RECEIVED_CB_FRONT, "[NAME]",
+ iface.GetID());
+ stream << code;
}
for (auto& i : iface.GetDeclarations().GetDecls()) {
)__cpp_cb";
+/**
+ * [NAME] The name of the interface.
+ */
const char CB_ON_RECEIVED_CB_FRONT[] =
R"__cpp_cb(
-int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+int [NAME]::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
{
- auto* cxt = static_cast<$$*>(data);
+ auto* cxt = static_cast<[NAME]*>(data);
rpc_port_parcel_h p;
rpc_port_parcel_h result;
+ rpc_port_parcel_h header;
+ int seq_num = -1;
int cmd;
int ret;
std::shared_ptr<ServiceBase> b;
return ret;
}
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+ _W("[Sequence] %d", seq_num);
+
rpc_port_parcel_create(&result);
+ rpc_port_parcel_get_header(result, &header);
+ rpc_port_parcel_header_set_tag(header, TIDL_VERSION);
+ rpc_port_parcel_header_set_seq_num(header, seq_num);
+
rpc_port_parcel_read_int32(p, &cmd);
switch (cmd) {
stream << Tab(2) << "public class " << iface.GetID()
<< " : ProxyBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenCallbacks(stream, iface, true);
GenDelegateId(stream, iface);
GenMethodId(stream, iface);
st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- st += Tab(5) + "Parcel parcelReceived;" + NLine(1);
st += Tab(5) + "lock (_lock)" + NLine(1);
st += Tab(5) + "{" + NLine(1);
- if (!l.empty())
- st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
- st += CB_INVOCATION_MID + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- st += Tab(6) + "// Receive" + NLine(1);
- st += Tab(6)
- + "ConsumeCommand(out parcelReceived, Port);" + NLine(1);
- }
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+ st += CB_INVOCATION_MID + NLine(1);
st += Tab(5) + "}";
// Deserialize
return st;
}
- const char* receive_block =
- "if (parcelReceived == null)\n" \
- "{\n" \
- " throw new InvalidProtocolException();\n" \
- "}\n";
- st += NLine(1) + AddIndent(TAB_SIZE * 5, receive_block) + NLine(1);
+ st += NLine(1) + AddIndent(TAB_SIZE * 5, CB_INVOCATION_RECEIVE);
+ st += NLine(1);
for (auto& i : decl.GetParameters().GetParams()) {
if (i->GetParameterType().GetDirection() ==
#ifndef IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
#define IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( public event EventHandler Connected;
public event EventHandler Disconnected;
public event EventHandler Rejected;
+ private static readonly string _tidlVersion = "<VERSION>";
private bool _online = false;
private string _appId;
private Object _lock = new Object();
using (Parcel p = new Parcel())
{
+ ParcelHeader header = p.GetHeader();
+ header.SetTag(_tidlVersion);
$$
}
)__cs_cb";
p.Send(Port);
)__cs_cb";
+const char CB_INVOCATION_RECEIVE[] =
+R"__cs_cb(
+Parcel parcelReceived;
+bool done = false;
+do
+{
+ lock (_lock)
+ {
+ // Receive
+ ConsumeCommand(out parcelReceived, Port);
+ }
+
+ if (parcelReceived == null)
+ {
+ throw new InvalidProtocolException();
+ }
+
+ ParcelHeader headerReceived = parcelReceived.GetHeader();
+ if (!string.IsNullOrEmpty(headerReceived.GetTag()))
+ {
+ if (headerReceived.GetSequenceNumber() != header.GetSequenceNumber())
+ {
+ parcelReceived.Dispose();
+ parcelReceived = null;
+ }
+ }
+
+ if (parcelReceived != null)
+ done = true;
+}
+while (!done);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
stream << Tab(2) << "public sealed class " << iface.GetID()
<< " : StubBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenServiceBase(stream, iface);
GenCallbacks(stream, iface, false);
GenDelegateId(stream, iface);
return;
cnt = 0;
- m = "result.WriteInt((int)MethodId.__Result);\n";
+ m = CB_INVOCATION_RESULT_PRE;
for (auto& i : decl.GetParameters().GetParams()) {
auto& pt = i->GetParameterType();
cnt++;
#ifndef IDLC_CS_GEN_CS_STUB_GEN_CB_H_
#define IDLC_CS_GEN_CS_STUB_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( private List<ServiceBase> _services = new List<ServiceBase>();
private Type _serviceType;
+ private static readonly string _tidlVersion = "<VERSION>";
)__cs_cb";
const char CB_SERVICE_BASE_FRONT[] =
}
)__cs_cb";
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__cs_cb(
+ParcelHeader header = p.GetHeader();
+ParcelHeader resultHeader = result.GetHeader();
+resultHeader.SetTag(_tidlVersion);
+resultHeader.SetSequenceNumber(header.GetSequenceNumber());
+result.WriteInt((int)MethodId.__Result);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_STUB_GEN_CB_H_