hw.c File Reference

This file implements the device signal handler functions. More...

#include "internal.h"
#include "eripc.h"
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
Include dependency graph for hw.c:

Go to the source code of this file.

Functions

static char * fix_name (const char *raw_name)
static void _get_byte_array (DBusMessageIter *iter, eripc_arg_t *arg)
eripc_arg_t_get_args (DBusMessageIter *iter)
static void generic_signal_handler (osso_context_t *osso, DBusMessage *msg, _osso_callback_data_t *data, eripc_bus_t dbus_type)
static eripc_error_t _set_handler (eripc_context_t *context, const char *service, const char *object_path, const char *interface, const char *name, const char *match, const char *sys_match, _osso_handler_f *event_cb, eripc_event_t event_type, eripc_handler_t *user_handler, void *user_data, int handler_id, gboolean call_once_per_handler_id, eripc_bus_t bus_type)
static eripc_error_t compose_match (const eripc_event_info_t *info, char **match)
eripc_error_t eripc_set_signal_handler (eripc_context_t *context, eripc_handler_t *handler, void *user_data, eripc_bus_t bus_type, const char *source, const char *name, int *handler_id)
eripc_error_t eripc_set_message_handler (eripc_context_t *context, eripc_handler_t *handler, void *user_data, eripc_bus_t bus_type, const char *source, const char *name, int *handler_id)
eripc_error_t eripc_set_event_handler (eripc_context_t *context, const eripc_event_info_t *info, eripc_handler_t *handler, void *user_data, int *handler_id)
eripc_error_t eripc_unset_handler (eripc_context_t *context, int handler_id)

Detailed Description

This file implements the device signal handler functions.

Definition in file hw.c.


Function Documentation

static void _get_byte_array ( DBusMessageIter *  iter,
eripc_arg_t arg 
) [static]

Definition at line 55 of file hw.c.

References eripc_arg_t::data, eripc_arg_t::data_len, ERIPC_TYPE_DATA, eripc_arg_t::type, and eripc_arg_t::value.

Referenced by _get_args().

00056 {
00057     arg->type = ERIPC_TYPE_DATA;
00058     dbus_message_iter_get_fixed_array(iter, &(arg->value.data),
00059                                       &(arg->data_len));
00060 }

Here is the caller graph for this function:

static eripc_error_t _set_handler ( eripc_context_t context,
const char *  service,
const char *  object_path,
const char *  interface,
const char *  name,
const char *  match,
const char *  sys_match,
_osso_handler_f event_cb,
eripc_event_t  event_type,
eripc_handler_t user_handler,
void *  user_data,
int  handler_id,
gboolean  call_once_per_handler_id,
eripc_bus_t  bus_type 
) [inline, static]

Definition at line 216 of file hw.c.

References _osso_callback_data_t::bus_type, _eripc_context_t::conn, _osso_callback_data_t::data, ERIPC_BUS_BOTH, ERIPC_BUS_SESSION, ERIPC_BUS_SYSTEM, ERIPC_ERROR, ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, _osso_callback_data_t::event_type, _osso_callback_data_t::interface, _osso_callback_data_t::match_rule, _osso_callback_data_t::name, _osso_callback_data_t::path, _osso_callback_data_t::service, _eripc_context_t::sys_conn, ULOG_ERR_F, _osso_callback_data_t::user_cb, and _osso_callback_data_t::user_data.

Referenced by eripc_set_event_handler().

00230 {
00231         DBusError error;
00232         _osso_callback_data_t *cb_data;
00233 
00234         cb_data = calloc(1, sizeof(_osso_callback_data_t));
00235         if (cb_data == NULL) {
00236                 ULOG_ERR_F("calloc failed");
00237                 return ERIPC_ERROR_OOM;
00238         }
00239 
00240         cb_data->user_cb = user_handler;
00241         cb_data->user_data = user_data;
00242         cb_data->match_rule = match;
00243         cb_data->event_type = event_type;
00244         cb_data->bus_type = bus_type;
00245         cb_data->data = cb_data;
00246 
00247         if (service != NULL) {
00248                 cb_data->service = strdup(service);
00249                 if (cb_data->service == NULL) {
00250                         goto _set_handler_oom4;
00251                 }
00252         }
00253         if (object_path != NULL) {
00254                 cb_data->path = strdup(object_path);
00255                 if (cb_data->path == NULL) {
00256                         goto _set_handler_oom3;
00257                 }
00258         }
00259         if (interface != NULL) {
00260                 cb_data->interface = strdup(interface);
00261                 if (cb_data->interface == NULL) {
00262                         goto _set_handler_oom2;
00263                 }
00264         }
00265         if (name != NULL) {
00266                 cb_data->name = strdup(name);
00267                 if (cb_data->name == NULL) {
00268                         goto _set_handler_oom1;
00269                 }
00270         }
00271 
00272         dbus_error_init(&error);
00273         
00274         if (bus_type == ERIPC_BUS_SYSTEM || bus_type == ERIPC_BUS_BOTH) {
00275                 if (!dbus_connection_get_is_connected(context->sys_conn)) {
00276                         ULOG_ERR_F("connection to system bus is not open");
00277                         goto _set_handler_failed_match;
00278                 }
00279 
00280                 dbus_bus_add_match(context->sys_conn, sys_match, &error);
00281 
00282                 if (dbus_error_is_set(&error)) {
00283                         ULOG_ERR_F("dbus_bus_add_match failed: %s",
00284                                    error.message);
00285                         dbus_error_free(&error);
00286                         goto _set_handler_failed_match;
00287                 }
00288         }
00289 
00290         if (bus_type == ERIPC_BUS_SESSION || bus_type == ERIPC_BUS_BOTH) {
00291                 if (!dbus_connection_get_is_connected(context->conn)) {
00292                         ULOG_ERR_F("connection to session bus is not open");
00293                         goto _set_handler_failed_match;
00294                 }
00295 
00296                 dbus_bus_add_match(context->conn, match, &error);
00297 
00298                 if (dbus_error_is_set(&error)) {
00299                         ULOG_ERR_F("dbus_bus_add_match failed: %s",
00300                                    error.message);
00301                         dbus_error_free(&error);
00302 
00303                         if (bus_type == ERIPC_BUS_BOTH) {
00304                                 dbus_bus_remove_match(context->sys_conn,
00305                                                       match, NULL);
00306                         }
00307 
00308                         goto _set_handler_failed_match;
00309                 }
00310         }
00311 
00312         if (_eripc_set_handler((_eripc_context_t*)context, event_cb,
00313                                cb_data, handler_id,
00314                                call_once_per_handler_id)) {
00315                 return ERIPC_ERROR_SUCCESS;
00316         } else {
00317                 return ERIPC_ERROR;
00318         }
00319 
00320 _set_handler_oom1:
00321         free(cb_data->interface);
00322 _set_handler_oom2:
00323         free(cb_data->path);
00324 _set_handler_oom3:
00325         free(cb_data->service);
00326 _set_handler_oom4:
00327         free(cb_data);
00328         return ERIPC_ERROR_OOM;
00329 
00330 _set_handler_failed_match:
00331         free(cb_data->name);
00332         free(cb_data->interface);
00333         free(cb_data->path);
00334         free(cb_data->service);
00335         free(cb_data);
00336         return ERIPC_ERROR;
00337 }

Here is the caller graph for this function:

static eripc_error_t compose_match ( const eripc_event_info_t info,
char **  match 
) [static]

Definition at line 339 of file hw.c.

References ERIPC_ERROR_OOM, ERIPC_ERROR_SUCCESS, ERIPC_EVENT_ERROR, ERIPC_EVENT_MESSAGE, ERIPC_EVENT_REPLY, ERIPC_EVENT_SIGNAL, ERIPC_MAX_MATCH_SIZE, eripc_event_info_t::event_type, eripc_event_info_t::interface, eripc_event_info_t::name, eripc_event_info_t::path, and eripc_event_info_t::service.

Referenced by eripc_set_event_handler().

00341 {
00342         size_t free_space = ERIPC_MAX_MATCH_SIZE;
00343         char buf[ERIPC_MAX_MATCH_SIZE + 1];
00344         buf[0] = '\0';
00345 
00346         *match = malloc(ERIPC_MAX_MATCH_SIZE + 1);
00347         if (*match == NULL) {
00348                 return ERIPC_ERROR_OOM;
00349         }
00350         (*match)[0] = '\0';
00351 
00352         if (info->service != NULL) {
00353                 snprintf(buf, ERIPC_MAX_MATCH_SIZE, "sender='%s',",
00354                          info->service);
00355                 strncat(*match, buf, free_space);
00356                 free_space -= strlen(buf);
00357         }
00358         
00359         if (info->path != NULL) {
00360                 snprintf(buf, ERIPC_MAX_MATCH_SIZE, "path='%s',", info->path);
00361                 strncat(*match, buf, free_space);
00362                 free_space -= strlen(buf);
00363         }
00364         if (info->interface != NULL) {
00365                 snprintf(buf, ERIPC_MAX_MATCH_SIZE, "interface='%s',",
00366                          info->interface);
00367                 strncat(*match, buf, free_space);
00368                 free_space -= strlen(buf);
00369         }
00370         if (info->name != NULL) {
00371                 snprintf(buf, ERIPC_MAX_MATCH_SIZE, "member='%s',",
00372                          info->name);
00373                 strncat(*match, buf, free_space);
00374                 free_space -= strlen(buf);
00375         }
00376         if (info->event_type != 0) {
00377                 switch(info->event_type)
00378                 {
00379                 case ERIPC_EVENT_MESSAGE:
00380                     snprintf(buf, ERIPC_MAX_MATCH_SIZE, "type='method_call',");
00381                     break;
00382                 case ERIPC_EVENT_SIGNAL:
00383                     snprintf(buf, ERIPC_MAX_MATCH_SIZE, "type='signal',");
00384                     break;
00385                 case ERIPC_EVENT_REPLY:
00386                     snprintf(buf, ERIPC_MAX_MATCH_SIZE, "type='method_reply',");
00387                     break;
00388                 case ERIPC_EVENT_ERROR:
00389                 default:
00390                     snprintf(buf, ERIPC_MAX_MATCH_SIZE, "type='error',");
00391                     break;
00392                 }
00393                 strncat(*match, buf, free_space);
00394                 free_space -= strlen(buf);
00395         }
00396 
00397         if (free_space < ERIPC_MAX_MATCH_SIZE) {
00398                 /* remove the last comma */
00399                 (*match)[strlen(*match) - 1] = '\0';
00400         } else {
00401                 free(*match);
00402                 *match = NULL;
00403         }
00404         
00405         return ERIPC_ERROR_SUCCESS;
00406 }

Here is the caller graph for this function:

static char* fix_name ( const char *  raw_name  )  [static]

Copyright (C) 2008 iRex Technologies B.V. All rights reserved.

Based on code found in libosso library by Kimmo Hämäläinen <kimmo.hamalainen@nokia.com>

Definition at line 37 of file hw.c.

References name, and ULOG_CRIT_F.

Referenced by eripc_set_message_handler(), and eripc_set_signal_handler().

00038 {
00039     char *name = strdup(raw_name);
00040     if (name == NULL) {
00041         ULOG_CRIT_F("fix_name failed: out of memory");
00042         return NULL;
00043     }
00044     
00045     // replace dashes (-) with underscores (_) as dbus chokes on dashes
00046     unsigned int i;
00047     for (i=0; i<strlen(name); i++)
00048     {
00049         if (name[i] == '-')
00050             name[i] = '_';
00051     }
00052     return name;
00053 }    

Here is the caller graph for this function:

static void generic_signal_handler ( osso_context_t osso,
DBusMessage *  msg,
_osso_callback_data_t data,
eripc_bus_t  dbus_type 
) [static]

Definition at line 145 of file hw.c.

References _get_args(), _make_id(), eripc_event_info_t::args, eripc_event_info_t::bus_type, eripc_event_info_t::error, osso_af_context_t::error_dummy, _osso_callback_data_t::event_type, eripc_event_info_t::event_type, eripc_event_info_t::interface, MAX_MSGID_LEN, eripc_event_info_t::message_id, eripc_event_info_t::name, eripc_event_info_t::path, osso_af_context_t::reply_dummy, eripc_event_info_t::service, ULOG_DEBUG_F, ULOG_WARN_F, _osso_callback_data_t::user_cb, and _osso_callback_data_t::user_data.

Referenced by eripc_set_event_handler().

00149 {
00150     eripc_event_info_t info;
00151     DBusMessageIter iter;
00152     eripc_handler_t *cb;
00153     char id_buf[MAX_MSGID_LEN + 1];
00154 
00155     ULOG_DEBUG_F("entered");
00156     assert(osso != NULL && data != NULL);
00157 
00158     memset(&info, 0, sizeof(info));
00159 
00160     info.service = dbus_message_get_sender(msg);
00161     info.path = dbus_message_get_path(msg);
00162     info.interface = dbus_message_get_interface(msg);
00163     info.name = dbus_message_get_member(msg);
00164     info.event_type = data->event_type;
00165     info.bus_type = dbus_type;
00166 
00167     /* create a dummy reply message for later use (workaround for
00168      * D-Bus library API) */
00169     if (osso->reply_dummy == NULL &&
00170         dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
00171         DBusMessage *reply;
00172         reply = dbus_message_new_method_return(msg);
00173         if (reply == NULL) {
00174             ULOG_WARN_F("could not create reply_dummy");
00175         } else {
00176             osso->reply_dummy = reply;
00177         }
00178     }
00179     if (osso->error_dummy == NULL &&
00180         dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
00181         DBusMessage *reply;
00182         reply = dbus_message_new_error(msg, "org.foo.dummy", NULL);
00183         if (reply == NULL) {
00184             ULOG_WARN_F("could not create error_dummy");
00185         } else { 
00186             osso->error_dummy = reply;
00187         }
00188     }
00189 
00190     if ((dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL
00191         && !dbus_message_get_no_reply(msg)) ||
00192         dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
00193             _make_id(dbus_type, dbus_message_get_sender(msg),
00194                            dbus_message_get_serial(msg), id_buf);
00195             info.message_id = id_buf;
00196     }
00197 
00198     if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) {
00199             info.error = dbus_message_get_error_name(msg);
00200     }
00201 
00202     if (dbus_message_iter_init(msg, &iter)) {
00203             info.args = _get_args(&iter);
00204     }
00205 
00206     cb = data->user_cb;
00207     (*cb)((eripc_context_t*)osso, &info, data->user_data);
00208 
00209     if (info.args != NULL) {
00210             free((void*) info.args);
00211             info.args = NULL;
00212     }
00213 }

Here is the call graph for this function:

Here is the caller graph for this function:

Generated by  doxygen 1.6.2-20100208