メソッド呼び出し内で、dbus (g_dbus_connection_emit_signal) でシグナルを送信しようとしています。dbus を使用してサーバー プログラムと通信するクライアント プログラムがあります。サーバー側でメソッドを呼び出すと、そのメソッド関数にリダイレクトされ、そのメソッドの実行中に信号が送信されます。しかし、そのメソッドの完了後にシグナルを受信しています。それは非常に遅いです。
これが dbus メソッド呼び出し内で発生している理由がわかりません。
問題は、両方のシグナルがクライアント側で同時にヒットしていることです。
以下のコード -> _apply_ota() は、クライアントによって呼び出されるメソッドです。
**
* Handle all method calls
* */
static void handle_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
#if DBG_SRV_METHOD
fprintf(stdout,"method_call - %s %s\r\n", method_name,g_variant_get_type_string (parameters));
#endif
char *response = NULL;
/*
* Get Config
* */
if (g_strcmp0(method_name, "apply_ota") == 0) {
cJSON * config = NULL;
ERROR_CODE status = _apply_ota();
}else{
g_dbus_method_invocation_return_dbus_error (invocation,SERVICE_ERROR,"SNAP ! Unhandled Method ..");
}
/*Send the response*/
if(response != NULL){
g_dbus_method_invocation_return_value(invocation,g_variant_new("(s)", response));
if (response != NULL)
free(response);
}else{
g_dbus_method_invocation_return_dbus_error (invocation,SERVICE_ERROR,"NULL Response");
}
}
/*
* Echo Signal Handlers
* */
static void service_signal_handler (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
#if DBG_SRV_SIGNALS
printf("ECHO Signal - %s%s\r\n",signal_name,g_variant_get_type_string(parameters));
#endif
/*
* You are hearing your own signals
* Echo the signals to WEB Clients
* */
cJSON * msg = NULL;
msg = cJSON_CreateObject();
if (msg != NULL) {
cJSON_AddItemToObject(msg, KEY_MSG_TYPE,
cJSON_CreateString(VAL_SIGNAL));
cJSON_AddItemToObject(msg, KEY_SERVICE_NAME,
cJSON_CreateString(SERVICE_NAME));
cJSON_AddItemToObject(msg, KEY_MESSAGE,
cJSON_CreateString(signal_name));
/*
* Check if there are parameters
* We only expect one parameter in signal
* */
if (g_strcmp0(g_variant_get_type_string(parameters), "(s)") == 0) {
const gchar * param_json_str;
g_variant_get(parameters, "(&s)", ¶m_json_str);
if (param_json_str != NULL) {
cJSON * param_json = NULL;
param_json = cJSON_Parse(param_json_str);
if (param_json != NULL) {
cJSON_AddItemToObject(msg, KEY_ARG, param_json);
} else {
fprintf(stderr, "Failed to parse signal parameters \r\n");
}
}
}
/*Broadcast cast signal to WEB Clients*/
if (!ws_send_brodcast(msg)) {
fprintf(stderr, "Failed to send broadcast!\r\n");
}
cJSON_Delete(msg);
}
}
bool service_emit_json_signal(char * signal_name, cJSON * msg_json){
#if DBG_SRV_SIGNALS
printf("service_emit_json_signal - %s \r\n", signal_name);
printf_json(msg_json,"msg = \r\n");
#endif
bool status = false;
GError *error = NULL;
GDBusConnection *c = NULL;
GVariant * parameters;
char* msg = NULL;
c = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if(c!= NULL){
msg = cJSON_PrintUnformatted(msg_json);
parameters = g_variant_new("(s)",msg);
if (parameters != NULL){
parameters = g_variant_ref_sink (parameters);
if(parameters != NULL){
/*Ready to send Signal*/
status = g_dbus_connection_emit_signal(c,
NULL,
MAIN_INTERFACE,
SERVICE_NAME,
signal_name,
parameters,
NULL);
if(!status){
fprintf(stderr,"Error Sending Signal - %s\r\n", error->message);
}
}
}
}else {
/*Failed to connect to the DBUS*/
fprintf(stderr, "Error connecting to BUS - %s\r\n", error->message);
}
/*Clean UP*/
if (error != NULL)
g_error_free(error);
if (msg != NULL)
free(msg);
if (parameters != NULL)
g_variant_unref(parameters);
if (c != NULL)
g_object_unref(c);
return status;
}
bool emit_ota_updating_signal(OTA_STATUS status){
bool ret = false;
cJSON * signal_json = cJSON_CreateObject();
if(signal_json != NULL){
cJSON_AddItemToObject(signal_json, KEY_OTA, cJSON_CreateNumber(status));
ret = service_emit_json_signal(SIG_OTA_UPDATING,signal_json);
cJSON_Delete(signal_json);
}
return ret;
}
ERROR_CODE _apply_ota(){
if(emit_ota_downloading_signal(OTA_DOWNLOADING)){
dcc_download_ota_file(ota->ota_file_url);
}else{
goto exit;
}
if(emit_ota_updating_signal(OTA_UPDATING)){
dcc_run_ota_update_script();
}else{
goto exit;
}
return ret;
}
.