namespace tidl {
namespace version2 {
+constexpr const char CB_LEM_PROXY_BASE_DEF[] =
+R"__c_cb(
+typedef void (*rpc_port_stub_LEM_init)(rpc_port_stub_LEM_callback_s *cb);
+char *__proxy_appid;
+
+)__c_cb";
constexpr const char CB_DELEGATE_DEFS[] =
R"__c_cb(
<PREFIX>_<NAME>_callback_s callback;
void *user_data;
GList *delegates;
+ bool is_LEM;
+ bool is_LEM_connected;
+ rpc_port_stub_LEM_callback_s lem_cb;
+ char *lem_instance_id;
GRecMutex mutex;
} <PREFIX>_<NAME>_t;
+
+<PREFIX>_<NAME>_h __<PREFIX>_<NAME>_handle;
)__c_cb";
/**
rpc_port_delegate_destroy(delegate);
}
+static int __<PREFIX>_<NAME>_LEM_received(const char *endpoint, const char *port_name, rpc_port_unit_map_h map, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, map);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
static void __<PREFIX>_<NAME>_received(const char *endpoint, const char *port_name, void *data)
{
<PREFIX>_<NAME>_h h = data;
__<PREFIX>_<NAME>_process_received_event(&h->delegates, map);
rpc_port_unit_map_destroy(map);
}
-
)__c_cb";
/**
}
)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_LEM_RECEIVE_CALLBACK[] =
+R"__c_cb(cb->send = __<PREFIX>_<NAME>_LEM_received;
+)__c_cb";
+
/**
* <PREFIX> The prefix of the interface.
* <NAME> The name of the interface.
<PREFIX>_<NAME>_h h = data;
_I("endpoint(%s), port_name(%s)", endpoint, port_name);
- h->port = port;
- rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port);
+ if(h->is_LEM) {
+ h->is_LEM_connected = true;
+ } else {
+ h->port = port;
+ rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port);
+ }
h->callback.connected(h, h->user_data);
}
<PREFIX>_<NAME>_h h = data;
_W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->is_LEM_connected = false;
h->port = nullptr;
h->callback.disconnected(h, h->user_data);
}
h->callback.rejected(h, h->user_data);
}
+static gboolean __<PREFIX>_<NAME>_LEM_connected(gpointer user_data) {
+ __<PREFIX>_<NAME>_connected(__proxy_appid, "<NAME>", nullptr, user_data);
+ return FALSE;
+}
+
+EXPORT_API void <PREFIX>_<NAME>_LEM_init(rpc_port_proxy_LEM_callback_s *cb) {
+ cb->connect = __<PREFIX>_<NAME>_connected;
+ cb->disconnect = __<PREFIX>_<NAME>_disconnected;
+ cb->is_LEM = __<PREFIX>_<NAME>_handle->is_LEM;
+ cb->user_data = __<PREFIX>_<NAME>_handle;
+ <DELEGATE_LEM_RECEIVE_CALLBACK>
+}
+
int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
{
<PREFIX>_<NAME>_t *handle;
int ret;
+ rpc_port_stub_LEM_init lem_init;
if (stub_appid == nullptr || callback == nullptr || h == nullptr) {
_E("Invalid parameter");
<DELEGATE_REGISTER_EVENT>
*h = handle;
+ __<PREFIX>_<NAME>_handle = handle;
+
+ void *plugin_handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
+ if (plugin_handle == NULL)
+ return RPC_PORT_ERROR_NONE;
+
+ lem_init = dlsym(plugin_handle, "<PREFIX_REVERSE>_<NAME>_LEM_init");
+ if (lem_init == NULL)
+ return RPC_PORT_ERROR_NONE;
+
+ lem_init(&handle->lem_cb);
+
return RPC_PORT_ERROR_NONE;
}
if (h->stub_appid)
free(h->stub_appid);
+ if (h->is_LEM && h->is_LEM_connected) {
+ _I("LEM destroy (%s)", __proxy_appid);
+ h->is_LEM_connected = false;
+ h->lem_cb.disconnect(__proxy_appid, h->lem_instance_id, nullptr);
+ }
+
free(h);
return RPC_PORT_ERROR_NONE;
int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h)
{
- int ret;
+ int ret = RPC_PORT_ERROR_NONE;
+ char instance_id[512];
if (h == nullptr || h->proxy == nullptr) {
_E("Invalid parameter");
return RPC_PORT_ERROR_INVALID_PARAMETER;
}
- ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, "<NAME>");
+ if (__proxy_appid == nullptr)
+ app_get_id(&__proxy_appid);
+
+ if (__proxy_appid != nullptr && !strcmp(__proxy_appid, h->stub_appid)) {
+ if (h->lem_cb.is_listen != nullptr)
+ h->is_LEM = h->lem_cb.is_listen();
+
+ _I("LEM appid (%s) (%d)", __proxy_appid, h->is_LEM);
+ }
+
+ if (h->is_LEM) {
+ snprintf(instance_id, sizeof(instance_id), "LEM_<NAME>@%s", __proxy_appid);
+
+ h->lem_instance_id = strdup(instance_id);
+ h->lem_cb.connect(__proxy_appid, h->lem_instance_id ? h->lem_instance_id : "LEM_<NAME>", &ret);
+
+ if (ret == RPC_PORT_ERROR_NONE)
+ g_idle_add(__<PREFIX>_<NAME>_LEM_connected, h);
+
+ } else {
+ ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, "<NAME>");
+ }
+
if (ret != RPC_PORT_ERROR_NONE) {
_E("Failed to connect to stub. error(%d)", ret);
return ret;
int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h)
{
- int ret;
+ int ret = RPC_PORT_ERROR_NONE;
+ char instance_id[512];
if (h == nullptr || h->proxy == nullptr) {
_E("Invalid parameter");
return RPC_PORT_ERROR_INVALID_PARAMETER;
}
- ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "<NAME>");
+ if (__proxy_appid == nullptr)
+ app_get_id(&__proxy_appid);
+
+ if (__proxy_appid != nullptr && !strcmp(__proxy_appid, h->stub_appid)) {
+ if (h->lem_cb.is_listen != nullptr)
+ h->is_LEM = h->lem_cb.is_listen();
+
+ _I("LEM appid (%s) (%d)", __proxy_appid, h->is_LEM);
+ }
+
+ if (h->is_LEM) {
+ snprintf(instance_id, sizeof(instance_id), "LEM_<NAME>@%s", __proxy_appid);
+
+ h->lem_instance_id = strdup(instance_id);
+ h->lem_cb.connect(__proxy_appid, h->lem_instance_id ? h->lem_instance_id : "LEM_<NAME>", &ret);
+ } else {
+ ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "<NAME>");
+ }
+
if (ret != RPC_PORT_ERROR_NONE) {
_E("Failed to connect to stub. error(%d)", ret);
return ret;
{
int ret;
- if (h == nullptr || h->proxy == nullptr) {
+ if (h == nullptr ) {
_E("Invalid parameter");
return RPC_PORT_ERROR_INVALID_PARAMETER;
}
- ret = rpc_port_disconnect(h->port);
- if (ret != RPC_PORT_ERROR_NONE) {
- _E("Failed to disconnect from stub. error(%d)", ret);
- return ret;
+ if (h->proxy == nullptr && h->is_LEM_connected == false) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->is_LEM) {
+ _I("LEM disconnect (%s)", __proxy_appid);
+ h->is_LEM_connected = false;
+ h->lem_cb.disconnect(__proxy_appid, h->lem_instance_id, nullptr);
+ } else {
+ ret = rpc_port_disconnect(h->port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect from stub. error(%d)", ret);
+ return ret;
+ }
}
return RPC_PORT_ERROR_NONE;
rpc_port_unit_map_h map_;
int seq_num_ = -1;
int res_;
+ rpc_port_result_s stub_result;
if (h == nullptr<METHOD_PARAMS_CHECK>) {
_E("Invalid parameter");
return;
}
- if (h->port == nullptr) {
+ if (h->port == nullptr && h->is_LEM_connected == false) {
_E("Not connected");
set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
return;
rpc_port_unit_map_destroy(map_);
g_rec_mutex_lock(&h->mutex);
- res_ = rpc_port_parcel_send(parcel_, h->port);
+ if (h->is_LEM_connected) {
+ stub_result = h->lem_cb.send(__proxy_appid, h->lem_instance_id, parcel_, nullptr);
+ res_ = stub_result.ret;
+ } else {
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ }
+
rpc_port_parcel_destroy(parcel_);
if (res_ != RPC_PORT_ERROR_NONE)
_E("Failed to send parcel. error(%d)", res_);
rpc_port_unit_map_h map_;
int seq_num_ = -1;
int res_;
+ rpc_port_result_s stub_result;
<RETURN_TYPE>ret_ = <ERROR_VALUE>;
<METHOD_ARGS>
return ret_;
}
- if (h->port == nullptr) {
+ if (h->port == nullptr && h->is_LEM_connected == false) {
_E("Not connected");
set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
return ret_;
g_rec_mutex_lock(&h->mutex);
- res_ = rpc_port_parcel_send(parcel_, h->port);
+ if (h->is_LEM_connected) {
+ stub_result = h->lem_cb.send(__proxy_appid, h->lem_instance_id, parcel_, nullptr);
+ res_ = stub_result.ret;
+ } else {
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ }
rpc_port_parcel_destroy(parcel_);
if (res_ != RPC_PORT_ERROR_NONE) {
_E("Failed to send parcel. error(%d)", res_);
do {
map_ = nullptr;
- __<PREFIX>_<NAME>_consume_command(h->port, seq_num_, &map_);
- if (parcel_ == nullptr) {
+ if (h->is_LEM_connected) {
+ map_ = stub_result.lem_ret;
+ } else {
+ __<PREFIX>_<NAME>_consume_command(h->port, seq_num_, &map_);
+ }
+ if (map_ == nullptr) {
_E("Invalid protocol");
res_ = RPC_PORT_ERROR_IO_ERROR;
break;
#include <package_manager.h>
)__c_cb";
+
+constexpr const char CB_LEM_STUB_BASE_DEF[] =
+R"__c_cb(
+typedef void (*rpc_port_proxy_LEM_init)(rpc_port_proxy_LEM_callback_s *cb);
+char *__stub_appid;
+
+)__c_cb";
+
constexpr const char CB_DELEGATE_DEFS[] =
R"__c_cb(
typedef struct rpc_port_delegate_s {
constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
R"__c_cb(
-typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data);
+typedef rpc_port_result_s (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data);
)__c_cb";
/**
void *user_data;
app_info_h app_info;
GHashTable *privileges;
+ rpc_port_proxy_LEM_callback_s lem_cb;
#ifdef TIDL_THREAD_ENABLE
GThread *thread;
GQueue *queue;
constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK_DEF[] =
R"__c_cb(
static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance);
)__c_cb";
/**
int seq_id;
bool once;
bool valid;
+ char *lem_instance;
} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
)__c_cb";
rpc_port_parcel_destroy(result_parcel);
}
-static int __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
+static rpc_port_result_s __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
{
- int ret = RPC_PORT_ERROR_NONE;
int cmd = -1;
rpc_port_unit_map_h map;
bool sync = false;
+ rpc_port_result_s stub_result = { 0, };
map = rpc_port_unit_map_create();
if (map == nullptr) {
_E("Failed to create unit map");
- return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ stub_result.ret = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ return stub_result;
}
rpc_port_parcel_read(parcel, &map->parcelable, map);
rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
if (cmd > 1 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
- if (h->app_info && __<NAME>_privilege_checkers[cmd]) {
- ret = __<NAME>_privilege_checkers[cmd](h, &sync);
- if (ret != RPC_PORT_ERROR_NONE) {
+ if (h->lem_cb.is_LEM == false && h->app_info && __<NAME>_privilege_checkers[cmd]) {
+ stub_result.ret = __<NAME>_privilege_checkers[cmd](h, &sync);
+ if (stub_result.ret != RPC_PORT_ERROR_NONE) {
rpc_port_unit_map_destroy(map);
if (sync)
- __<PREFIX>_<NAME>_throw_remote_exception(h->port, parcel, ret, "Permission denied");
+ __<PREFIX>_<NAME>_throw_remote_exception(h->port, parcel, stub_result.ret, "Permission denied");
- return RPC_PORT_ERROR_NONE;
+ stub_result.ret = RPC_PORT_ERROR_NONE;
+ return stub_result;
}
}
if (__<NAME>_method_table[cmd])
- ret = __<NAME>_method_table[cmd](h->port, parcel, map, h);
+ stub_result = __<NAME>_method_table[cmd](h->port, parcel, map, h);
} else {
_W("Invalid protocol. cmd(%d)", cmd);
- ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ stub_result.ret = RPC_PORT_ERROR_INVALID_PARAMETER;
}
rpc_port_unit_map_destroy(map);
- return ret;
+ return stub_result;
}
#ifdef TIDL_THREAD_ENABLE
return ret;
}
-static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_context_create(const char *sender, const char *instance, rpc_port_h callback_port)
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_context_create(const char *sender, const char *instance, rpc_port_h callback_port, rpc_port_proxy_LEM_callback_s *lem_cb)
{
<PREFIX>_<NAME>_context_t *handle;
- if (sender == nullptr || instance == nullptr || callback_port == nullptr) {
+ if (sender == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ if (lem_cb->is_LEM == false && callback_port == nullptr) {
_E("Invalid parameter");
return nullptr;
}
}
#endif /* TIDL_THREAD_ENABLE */
+ handle->lem_cb = *lem_cb;
handle->callback_port = callback_port;
handle->callback = __<NAME>.callback;
handle->user_data = __<NAME>.user_data;
return handle;
}
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance)
+{
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!strcmp(context->instance, instance)) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return context;
+ }
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return nullptr;
+}
+
+static void __<PREFIX>_<NAME>_add_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_append(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_remove_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_remove(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_clear_context(gpointer data)
+{
+ <PREFIX>_<NAME>_context_h context = data;
+
+ if (context->lem_cb.is_LEM) {
+ _I("LEM disconnect %s:<NAME>", __stub_appid);
+ context->lem_cb.disconnect(__stub_appid, "<NAME>", context->lem_cb.user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ }
+ __<PREFIX>_<NAME>_context_destroy(context);
+}
+
int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag)
{
if (context == nullptr) {
int <PREFIX>_<NAME>_context_disconnect(<PREFIX>_<NAME>_context_h context)
{
- int ret;
+ int ret = RPC_PORT_ERROR_NONE;
if (context == nullptr) {
_E("Invalid parameter");
g_rec_mutex_lock(&__<NAME>.mutex);
- ret = rpc_port_disconnect(context->callback_port);
- if (ret != RPC_PORT_ERROR_NONE)
- _E("Failed to disconnect. error(%d)", ret);
-
- g_rec_mutex_unlock(&__<NAME>.mutex);
-
- return ret;
-}
-
-static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance)
-{
- <PREFIX>_<NAME>_context_h context;
- GList *iter;
-
- g_rec_mutex_lock(&__<NAME>.mutex);
- iter = __<NAME>.contexts;
- while (iter) {
- context = iter->data;
- if (!strcmp(context->instance, instance)) {
- g_rec_mutex_unlock(&__<NAME>.mutex);
- return context;
- }
-
- iter = g_list_next(iter);
+ if (context->lem_cb.is_LEM) {
+ _I("LEM disconnect %s:<NAME>", __stub_appid);
+ context->lem_cb.disconnect(__stub_appid, "<NAME>", context->lem_cb.user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
+ } else {
+ ret = rpc_port_disconnect(context->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ _E("Failed to disconnect. error(%d)", ret);
}
g_rec_mutex_unlock(&__<NAME>.mutex);
- return nullptr;
-}
-
-static void __<PREFIX>_<NAME>_add_context(<PREFIX>_<NAME>_context_h context)
-{
- g_rec_mutex_lock(&__<NAME>.mutex);
- __<NAME>.contexts = g_list_append(__<NAME>.contexts, context);
- g_rec_mutex_unlock(&__<NAME>.mutex);
+ return ret;
}
-static void __<PREFIX>_<NAME>_remove_context(<PREFIX>_<NAME>_context_h context)
-{
- g_rec_mutex_lock(&__<NAME>.mutex);
- __<NAME>.contexts = g_list_remove(__<NAME>.contexts, context);
- g_rec_mutex_unlock(&__<NAME>.mutex);
-}
)__c_cb";
/**
_W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ if (h->lem_instance)
+ free(h->lem_instance);
+
free(h);
return RPC_PORT_ERROR_NONE;
(*clone)->port = h->port;
+ if (h->lem_instance) {
+ (*clone)->lem_instance = strdup(h->lem_instance);
+ if ((*clone)->lem_instance == nullptr) {
+ _E("Out of memory");
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(*clone);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
return ret;
}
rpc_port_parcel_h parcel_;
int ret_;
rpc_port_unit_map_h map_;
+ <PREFIX>_<NAME>_context_h context = nullptr;
- if (h == nullptr || h->port == nullptr<DELEGATE_PARAMS_CHECK>) {
+ if (h == nullptr <DELEGATE_PARAMS_CHECK>) {
_E("Invalid parameter");
return RPC_PORT_ERROR_INVALID_PARAMETER;
}
- if (!__<PREFIX>_<NAME>_exist_callback_port(h->port)) {
- _E("Not connected");
- return RPC_PORT_ERROR_INVALID_PARAMETER;
+ if (h->lem_instance) {
+ context = __<PREFIX>_<NAME>_find_context(h->lem_instance);
+ if (context == nullptr) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ if (h->port == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+ if (!__<PREFIX>_<NAME>_exist_callback_port(h->port)) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
}
if (h->once && !h->valid) {
rpc_port_unit_map_write_delegate(map_, "delegate", (rpc_port_delegate_h)h);
<DELEGATE_UNIT_MAP_WRITE>
- rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ if (context && context->lem_cb.is_LEM) {
+ ret_ = context->lem_cb.send("endpoint", "Message", map_, context->lem_cb.user_data);
+ } else {
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ ret_ = rpc_port_parcel_send(parcel_, h->port);
+ }
rpc_port_unit_map_destroy(map_);
- ret_ = rpc_port_parcel_send(parcel_, h->port);
rpc_port_parcel_destroy(parcel_);
h->valid = false;
_E("Failed to read delegate. error(%d)", ret_);
goto out;
}
-<PREFIX>_<TYPE_NAME>_set_port(<ARG>, callback_port_);
+if (context_->lem_cb.is_LEM) {
+ <ARG>->lem_instance = strdup(context_->instance);
+ if (<ARG>->lem_instance == nullptr) {
+ _E("Failed to duplicate sender");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+} else {
+ <PREFIX>_<TYPE_NAME>_set_port(<ARG>, callback_port_);
+}
)__c_cb";
*/
constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
R"__c_cb(
-static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *user_data)
+static rpc_port_result_s __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, 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_;
+ int ret_ = RPC_PORT_ERROR_NONE;
+ rpc_port_result_s stub_result_ = { 0, };
<METHOD_HANDLER_ARGS_DECL>
- ret_ = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_);
- if (ret_ != RPC_PORT_ERROR_NONE) {
- _E("Failed to get callback port. error(%d)", ret_);
- goto out;
+ if (context_->lem_cb.is_LEM == false) {
+ ret_ = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret_);
+ goto out;
+ }
}
rpc_port_parcel_get_header(parcel, &header_);
out:
<METHOD_HANDLER_ARGS_FREE>
- return ret_;
+ stub_result_.ret = ret_;
+ return stub_result_;
}
)__c_cb";
if (__<PREFIX>_<NAME>_remote_exception != nullptr)
rpc_port_unit_map_write_<NAME>_remote_exception(map_, "[REMOTE_EXCEPTION]", __<PREFIX>_<NAME>_remote_exception);
-rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
-rpc_port_unit_map_destroy(map_);
+ if (context_->lem_cb.is_LEM) {
+ stub_result_.lem_ret = map_;
+} else {
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ rpc_port_unit_map_destroy(map_);
-ret_ = rpc_port_parcel_send(parcel_, port);
-rpc_port_parcel_destroy(parcel_);
+ ret_ = rpc_port_parcel_send(parcel_, port);
+ rpc_port_parcel_destroy(parcel_);
+}
)__c_cb";
<PREFIX>_<NAME>_context_h context;
rpc_port_h callback_port = nullptr;
int ret;
-
+ rpc_port_proxy_LEM_callback_s lem_cb = { 0, };
+ rpc_port_proxy_LEM_init lem_init;
+
+ if (__stub_appid == nullptr)
+ app_get_id(&__stub_appid);
+
+ if (__stub_appid != nullptr) {
+ if (!strcmp(__stub_appid, sender)) {
+ void *plugin_handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
+ if (plugin_handle) {
+ lem_init = dlsym(plugin_handle, "<PREFIX_REVERSE>_<NAME>_LEM_init");
+ if (lem_init)
+ lem_init(&lem_cb);
+ }
+ }
+ }
_W("sender(%s), instance(%s)", sender, instance);
- ret = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
- if (ret != RPC_PORT_ERROR_NONE) {
- _E("Failed to get callback port. error(%d)", ret);
- return;
+ if (lem_cb.is_LEM == false) {
+ ret = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret);
+ return;
+ }
}
- context = __<PREFIX>_<NAME>_context_create(sender, instance, callback_port);
- if (context == nullptr)
+ context = __<PREFIX>_<NAME>_context_create(sender, instance, callback_port, &lem_cb);
+ if (context == nullptr) {
+ if (lem_cb.is_LEM)
+ *((int *)user_data) = RPC_PORT_ERROR_IO_ERROR;
return;
+ }
__<PREFIX>_<NAME>_add_context(context);
- __<PREFIX>_<NAME>_add_callback_port(context->callback_port);
+
+ if (lem_cb.is_LEM == false)
+ __<PREFIX>_<NAME>_add_callback_port(context->callback_port);
+
context->callback.create(context, context->user_data);
+
+ if (lem_cb.is_LEM)
+ *((int *)user_data) = RPC_PORT_ERROR_NONE;
}
static void __<PREFIX>_<NAME>_disconnected_event_cb(const char *sender, const char *instance, void *user_data)
if (context == nullptr)
return;
- __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+ if (context->lem_cb.is_LEM == false)
+ __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+
context->callback.terminate(context, context->user_data);
__<PREFIX>_<NAME>_remove_context(context);
__<PREFIX>_<NAME>_context_destroy(context);
<PREFIX>_<NAME>_context_h context;
rpc_port_parcel_h parcel;
int ret;
+ rpc_port_result_s stub_result = { 0, };
_W("sender(%s), instance(%s)", sender, instance);
context = __<PREFIX>_<NAME>_find_context(instance);
}
#ifdef TIDL_THREAD_ENABLE
- ret = __<PREFIX>_<NAME>_context_push(context, parcel);
+ stub_result.ret = __<PREFIX>_<NAME>_context_push(context, parcel);
#else
- ret = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+ stub_result = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
rpc_port_parcel_destroy(parcel);
#endif /* TIDL_THREAD_ENABLE */
- return ret;
+ return stub_result.ret;
+}
+
+rpc_port_result_s __<PREFIX>_<NAME>_LEM_received_event_cb(const char *sender, const char *instance, rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_result_s stub_result = { 0, };
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr) {
+ _E("Failed to find context. instance(%s)", instance);
+ stub_result.ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ return stub_result;
+ }
+
+ stub_result = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+
+ return stub_result;
+}
+
+static bool __<PREFIX>_<NAME>_received_event_cb_is_listen() {
+ return __<NAME>.stub != NULL;
+}
+
+EXPORT_API void <PREFIX>_<NAME>_LEM_init(rpc_port_stub_LEM_callback_s *cb) {
+ cb->connect = __<PREFIX>_<NAME>_connected_event_cb;
+ cb->disconnect = __<PREFIX>_<NAME>_disconnected_event_cb;
+ cb->send = __<PREFIX>_<NAME>_LEM_received_event_cb;
+ cb->is_listen = __<PREFIX>_<NAME>_received_event_cb_is_listen;
}
static int __<PREFIX>_<NAME>_set_access_control(void)
g_rec_mutex_clear(&__<NAME>.mutex);
if (__<NAME>.contexts) {
- g_list_free_full(__<NAME>.contexts, __<PREFIX>_<NAME>_context_destroy);
+ g_list_free_full(__<NAME>.contexts, __<PREFIX>_<NAME>_clear_context);
__<NAME>.contexts = nullptr;
}