00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00031 #include <ws_dbus.h>
00032
00033
00034 struct _WSDBusMethodData
00035 {
00036 GQuark id;
00037 gchar *name;
00038 gpointer handler;
00039 gpointer user_data;
00040 gchar* data_types;
00041 };
00042
00043
00044 typedef struct _WSDBusMethodData WSDBusMethodData;
00045
00046 static gchar* ws_dbus_get_ptr2method (GArray *methods, gchar* name );
00047 static void ws_dbus_libosso_errors (osso_return_t result);
00048 static void ws_dbus_fill_message (DBusMessage *msg, void *data);
00049
00053 static gchar* ws_dbus_get_ptr2method (GArray *methods, gchar* name)
00054 {
00055 guint i;
00056 gchar* temp;
00057
00058 g_debug ("%d", methods->len);
00059
00060 return NULL;
00061
00062 for (i = 0; i < methods->len; i+=2)
00063 {
00064 temp = g_array_index (methods, gchar *,i);
00065
00066 if (strcmp (name, temp) == 0) {
00067 temp = g_array_index (methods, gchar *,i+1);
00068 g_debug ("\nData types: %s\n", temp);
00069 return temp;
00070 }
00071 };
00072
00073 return NULL;
00074 };
00075
00076 static void ws_dbus_libosso_errors (osso_return_t result)
00077 {
00078 switch (result)
00079 {
00080 case OSSO_OK:
00081 g_debug ("All OK\n");
00082 break;
00083 case OSSO_ERROR:
00084 g_debug ("Ordinary Error\n");
00085 break;
00086 case OSSO_INVALID:
00087 g_debug ("At least one parameter is invalid\n");
00088 break;
00089 case OSSO_RPC_ERROR:
00090 g_debug ("Osso RPC method returned an error\n");
00091 break;
00092 case OSSO_ERROR_NAME:
00093 g_debug ("Error Name\n");
00094 break;
00095 case OSSO_ERROR_NO_STATE:
00096 g_debug ("No state file found to read\n");
00097 break;
00098 case OSSO_ERROR_STATE_SIZE:
00099 g_debug("The size of the given structure"
00100 " is different from the saved size\n");
00101 break;
00102 };
00103 };
00104
00105
00106 static WSDBusStatus ws_dbus_run_cb( WSDBusMethodData *method_data,
00107 gpointer data )
00108 {
00109 g_debug ( "%s: Running cb for method %s\n",
00110 __FUNCTION__,
00111 method_data->name);
00112
00113 ws_dbus_cb cb;
00114 osso_rpc_t osso_data;
00115 GArray *args = (GArray *) data;
00116
00117 cb = (ws_dbus_cb) method_data->handler;
00118 g_debug ("cb pointer address %p\n", cb);
00119
00120 if (cb != NULL)
00121 {
00122 if (args->len == 0)
00123 {
00124 osso_data.type = WS_DBUS_TYPE_STRING;
00125 osso_data.value.s = NULL;
00126 g_array_append_val (args, osso_data);
00127 }
00128
00129 cb (NULL, data, method_data->user_data);
00130 return OSSO_OK;
00131 }
00132 else
00133 {
00134 g_debug ("DBUS: No callback defined for this function\n");
00135 return OSSO_ERROR;
00136 };
00137 };
00138
00139
00140 static gint ws_dbus_cb_handler (const gchar * interface,
00141 const gchar * method,
00142 GArray * arguments,
00143 gpointer data,
00144 osso_rpc_t * retval)
00145 {
00146 WSDBusMethodData *method_data;
00147 GArray *dbus_method_data;
00148 GQuark temp;
00149 guint i;
00150 dbus_method_data = (GArray *) data;
00151 retval = NULL;
00152 g_debug ("DBUS: Method: %s\n", method);
00153
00154
00155 temp = g_quark_try_string (method);
00156 if (temp != 0)
00157 {
00158
00159
00160
00161 for (i=0; i < dbus_method_data->len; ++i)
00162 {
00163 method_data = g_array_index( dbus_method_data,
00164 WSDBusMethodData*,
00165 i );
00166
00167 if (method_data->id == temp)
00168 {
00169 g_debug( "DBUS: Running callback for %s\n",
00170 method);
00171 ws_dbus_run_cb (method_data, arguments);
00172 };
00173 };
00174 }
00175 else
00176 {
00177 g_debug( "Error in function %s, couldn't find the signal %s\n",
00178 __FUNCTION__,
00179 method );
00180 return OSSO_ERROR;
00181 };
00182
00183 return OSSO_OK;
00184 };
00185
00186
00191 static void ws_dbus_fill_message (DBusMessage *msg, void *data)
00192 {
00193 guint i;
00194 osso_rpc_t *data_unit;
00195 GArray *data_bundle;
00196 gpointer buffer;
00197
00198 data_bundle = (GArray *) data;
00199
00200 g_debug ("%s, number of fields: %d", __FUNCTION__, data_bundle->len);
00201
00202 if (data_bundle->len > 255)
00203 {
00204 g_debug ("DBUS: Number of fields in message exceeds 255\n");
00205 }
00206
00207 for (i = 0; ((i < data_bundle->len) && (i < 255)); ++i)
00208 {
00209 data_unit = g_array_index (data_bundle, osso_rpc_t *, i);
00210 g_debug ("%s, type: %c, value: ", __FUNCTION__, data_unit->type);
00211
00212 switch (data_unit->type)
00213 {
00214 case DBUS_TYPE_STRING:
00215 buffer = &data_unit->value.s;
00216 g_debug ("%s", data_unit->value.s);
00217 break;
00218 case DBUS_TYPE_INT32:
00219 buffer = &data_unit->value.i;
00220 g_debug ("%d", data_unit->value.i);
00221 break;
00222 case DBUS_TYPE_DOUBLE:
00223 buffer = &data_unit->value.d;
00224 g_debug ("%f", data_unit->value.d);
00225 break;
00226 case DBUS_TYPE_BOOLEAN:
00227 buffer = &data_unit->value.b;
00228 g_debug ("%d", data_unit->value.b);
00229 break;
00230 };
00231
00232 if (data_unit->value.s != NULL) {
00233 dbus_message_append_args( msg,
00234 data_unit->type,
00235 buffer,
00236 DBUS_TYPE_INVALID );
00237 }
00238 else
00239 {
00240 if (data_bundle->len > 1)
00241 {
00242 g_debug ("One argument ommited");
00243 }
00244 }
00245 };
00246
00247 g_debug ("DBUS: Added %d words\n", i);
00248 };
00249
00256 void ws_dbus_add_remote_methods (GError *error,
00257 gpointer data,
00258 gpointer user_data)
00259 {
00260 WSDBusData *ws_dbus_data = (WSDBusData *) user_data;
00261 GArray *methods_list = (GArray *) data;
00262 guint i=0;
00263
00264 osso_rpc_t *temp;
00265
00266 for (i = 0; i < methods_list->len; ++i)
00267 {
00268 temp = g_array_index (methods_list, osso_rpc_t *, i);
00269 g_array_append_val( ws_dbus_data->remote_method_data,
00270 temp->value );
00271 };
00272
00273 return;
00274 };
00275
00283 WSDBusData * ws_dbus_create (gchar *name, gchar *version)
00284 {
00285 WSDBusData *temp;
00286 temp = (gpointer) g_try_malloc (sizeof (WSDBusData));
00287 g_debug ("\nDBUS: ");
00288
00289 if (temp == NULL)
00290 {
00291 g_debug ("Error in function %s - cannot allocate memory\n",
00292 __FUNCTION__);
00293 g_assert_not_reached();
00294 }
00295 else
00296 {
00297 g_debug ("Memory allocation successful\n");
00298 }
00299
00300 temp->name = g_strconcat (name, NULL);
00301 temp->version = g_strconcat (version, NULL);
00302
00303 temp->method_data = g_array_new( TRUE,
00304 TRUE,
00305 sizeof(WSDBusMethodData *) );
00306 return temp;
00307 };
00308
00319 WSDBusStatus ws_dbus_config (WSDBusData * ws_dbus_data,
00320 WSDBusConfig field,
00321 gchar *value)
00322 {
00323 if (ws_dbus_data == NULL)
00324 {
00325 g_debug ("DBUS: Error in function %s - ws_dbus_data is NULL\n",
00326 __FUNCTION__);
00327 return WS_DBUS_STATUS_ERROR;
00328 };
00329
00330 switch (field)
00331 {
00332 case WS_DBUS_CONFIG_SERVICE :
00333 ws_dbus_data->service = g_strconcat(value, NULL);
00334 break;
00335 case WS_DBUS_CONFIG_OBJECT :
00336 ws_dbus_data->object = g_strconcat(value, NULL);
00337 break;
00338 case WS_DBUS_CONFIG_IFACE :
00339 ws_dbus_data->iface = g_strconcat(value, NULL);
00340 break;
00341 case WS_DBUS_CONFIG_REMOTE_SERVICE :
00342 ws_dbus_data->remote_service = g_strconcat(value, NULL);
00343 break;
00344 case WS_DBUS_CONFIG_REMOTE_OBJECT :
00345 ws_dbus_data->remote_object = g_strconcat(value, NULL);
00346 break;
00347 case WS_DBUS_CONFIG_REMOTE_IFACE :
00348 ws_dbus_data->remote_iface = g_strconcat(value, NULL);
00349 break;
00350 };
00351
00352 return WS_DBUS_STATUS_OK;
00353 };
00354
00365 WSDBusStatus ws_dbus_connect (WSDBusData * ws_dbus_data)
00366 {
00367 osso_return_t result;
00368
00369 ws_dbus_data->context = osso_initialize (ws_dbus_data->name,
00370 ws_dbus_data->version,
00371 FALSE,
00372 NULL);
00373 osso_rpc_set_timeout (ws_dbus_data->context, 100);
00374
00375
00376
00377 result = osso_rpc_set_cb_f(ws_dbus_data->context,
00378 ws_dbus_data->service,
00379 ws_dbus_data->object,
00380 ws_dbus_data->iface,
00381 ws_dbus_cb_handler,
00382 ws_dbus_data->method_data);
00383
00384 g_debug ("\nSending method data\n");
00385
00386
00387
00388 if (result == OSSO_OK)
00389 {
00390 return WS_DBUS_STATUS_OK;
00391 }
00392 else
00393 {
00394 return WS_DBUS_STATUS_ERROR;
00395 }
00396 };
00397
00404 void ws_dbus_destroy (WSDBusData * ws_dbus_data)
00405 {
00406 guint i;
00407
00408 if (ws_dbus_data == NULL)
00409 {
00410 g_debug ("DBUS: Error in fun %s - cannot free osso_context\n",
00411 __FUNCTION__);
00412 g_free (ws_dbus_data);
00413 g_assert_not_reached();
00414 };
00415
00416 g_debug( "DBUS deinitialization by %s:\n---------------------------\n",
00417 ws_dbus_data->service);
00418 osso_deinitialize (ws_dbus_data->context);
00419 g_debug ("| Deinitializing osso context |\n");
00420 if (ws_dbus_data->method_data != NULL)
00421 {
00422 for (i = 0; i < ws_dbus_data->method_data->len; ++i)
00423 {
00424 WSDBusMethodData *temp =
00425 g_array_index(ws_dbus_data->method_data,
00426 WSDBusMethodData *, i);
00427 g_free (temp->data_types);
00428 g_free (temp->name);
00429 g_free (temp);
00430 };
00431
00432 g_array_free (ws_dbus_data->method_data, TRUE);
00433 g_debug ("| Freeing callback pointers list |\n");
00434 };
00435
00436 g_free (ws_dbus_data->name);
00437 g_free (ws_dbus_data->version);
00438 g_free (ws_dbus_data->service);
00439 g_free (ws_dbus_data->object);
00440 g_free (ws_dbus_data->iface);
00441
00442 g_free (ws_dbus_data->remote_service);
00443 g_free (ws_dbus_data->remote_object);
00444 g_free (ws_dbus_data->remote_iface);
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 g_free (ws_dbus_data);
00460 g_debug ("| Freeing WSDBusData structure |\n----------------------\n");
00461 };
00462
00463
00474 WSDBusStatus ws_dbus_set_cb (WSDBusData * ws_dbus_data,
00475 gchar * method,
00476 gpointer c_func,
00477 gpointer user_data)
00478 {
00479 WSDBusMethodData *method_data;
00480 GQuark temp;
00481 guint i;
00482
00483
00484 temp = g_quark_try_string (method);
00485
00486 if (temp == 0)
00487 {
00488 g_debug ("DBUS:%s- method not defined or invalid method name\n",
00489 method);
00490 return WS_DBUS_STATUS_ERROR;
00491 }
00492 else
00493 {
00494 for (i = 0; i < ws_dbus_data->method_data->len; ++i)
00495 {
00496 method_data = g_array_index (ws_dbus_data->method_data,
00497 WSDBusMethodData *,
00498 i);
00499
00500
00501
00502 if (method_data->id == temp)
00503 {
00504 method_data->handler = c_func;
00505 method_data->user_data = user_data;
00506 g_array_insert_val(ws_dbus_data->method_data,
00507 i, method_data);
00508 g_array_remove_index (ws_dbus_data->method_data,
00509 i+1);
00510 };
00511 };
00512 };
00513
00514
00515 return WS_DBUS_STATUS_OK;
00516 };
00517
00526 WSDBusStatus ws_dbus_add_method (WSDBusData * ws_dbus_data, gchar *method, ...)
00527 {
00528 WSDBusMethodData *method_data;
00529 WSDBusDataType data_type;
00530 GQuark temp;
00531 gchar *buffer;
00532 va_list arglist;
00533
00534
00535 temp = g_quark_try_string (method);
00536
00537 if (temp != 0)
00538 {
00539 g_debug( "DBUS:\"%s\"- method has already been registered\n",
00540 method );
00541 return WS_DBUS_STATUS_ERROR;
00542 }
00543
00544 method_data = g_try_malloc (sizeof (WSDBusMethodData));
00545 if (method_data != NULL)
00546 {
00547 va_start (arglist, method);
00548
00549 method_data->id = g_quark_from_string (method);
00550 method_data->name = g_strdup (method);
00551 data_type = va_arg (arglist, WSDBusDataType);
00552 method_data->data_types = g_strdup("");
00553
00554
00555 while (data_type != WS_DBUS_TYPE_INVALID)
00556 {
00557 buffer = method_data->data_types;
00558
00559 method_data->data_types =
00560 g_strdup_printf( "%s%c",
00561 method_data->data_types,
00562 (gchar) data_type );
00563 g_free (buffer);
00564 data_type = va_arg (arglist, WSDBusDataType);
00565 };
00566
00567 g_debug( "%d, %s, %s\n",
00568 method_data->id,
00569 method_data->name,
00570 method_data->data_types );
00571 va_end (arglist);
00572 g_array_append_val( ws_dbus_data->method_data,
00573 method_data );
00574 }
00575 else
00576 {
00577 g_debug( "DBUS: Failed to allocate memory for method data");
00578 return WS_DBUS_STATUS_ERROR;
00579 }
00580
00581 return WS_DBUS_STATUS_OK;
00582 };
00583
00590 WSDBusStatus ws_dbus_add_garray (GArray *data_bundle, GArray *strings)
00591 {
00592 osso_rpc_t *temp;
00593 guint i;
00594
00595 if (strings != NULL)
00596 {
00597 for (i = 0; i < strings->len; ++i)
00598 {
00599 temp = g_try_malloc (sizeof (osso_rpc_t));
00600 temp->type = WS_DBUS_TYPE_STRING;
00601 temp->value.s = g_array_index (strings, gchar *, i);
00602 g_debug ("%d, %s", temp->type, temp->value.s);
00603 g_array_append_val (data_bundle, temp);
00604 };
00605 return WS_DBUS_STATUS_OK;
00606 }
00607 else
00608 {
00609 printf ("\n%s - Error - GArray is NULL", __FUNCTION__);
00610 return WS_DBUS_STATUS_ERROR;
00611 };
00612 };
00613
00624 WSDBusStatus ws_dbus_call_method (WSDBusData * ws_dbus_data, gchar *method, ...)
00625 {
00626 va_list arglist;
00627 GArray *data_to_send;
00628 osso_rpc_t *temp, *retval;
00629 osso_return_t result;
00630 GArray *temp_garray;
00631
00632 data_to_send = g_array_new (TRUE, TRUE, sizeof (osso_rpc_t *));
00633 va_start (arglist, method);
00634
00635
00636 while (TRUE)
00637 {
00638 temp = g_try_malloc (sizeof (osso_rpc_t));
00639 temp->type = va_arg (arglist, WSDBusDataType);
00640
00641 if (temp->type == WS_DBUS_TYPE_INVALID)
00642 {
00643 break;
00644 }
00645
00646 switch (temp->type)
00647 {
00648 case WS_DBUS_TYPE_STRING:
00649 temp->value.s = va_arg (arglist, gchar *);
00650 g_debug ("Value: %s\n", temp->value.s);
00651 break;
00652 case WS_DBUS_TYPE_INT:
00653 temp->value.i = va_arg (arglist, gint);
00654 g_debug ("Value: %d\n", temp->value.i);
00655 break;
00656 case WS_DBUS_TYPE_UINT:
00657 temp->value.u = va_arg (arglist, guint);
00658 g_debug ("Value: %d\n", temp->value.u);
00659 break;
00660 case WS_DBUS_TYPE_DOUBLE:
00661 temp->value.d = va_arg (arglist, gdouble);
00662 g_debug ("Value: %f\n", temp->value.d);
00663 break;
00664 case WS_DBUS_TYPE_BOOLEAN:
00665 temp->value.b = va_arg (arglist, gboolean);
00666 g_debug ("Value: %d\n", temp->value.b);
00667 break;
00668 case WS_DBUS_TYPE_GARRAY:
00669 temp_garray = va_arg (arglist, GArray *);
00670 ws_dbus_add_garray (data_to_send,
00671 temp_garray);
00672 g_debug ("Value: GArray of strings");
00673 break;
00674 };
00675 g_debug ("Type: %c %d", temp->type, temp->value.i);
00676
00677 if (temp->type != WS_DBUS_TYPE_GARRAY)
00678 {
00679 g_array_append_val (data_to_send, temp);
00680 }
00681 };
00682
00683 va_end (arglist);
00684 g_debug( "%s, method %s, added %d arguments",
00685 __FUNCTION__,
00686 method, data_to_send->len);
00687
00688
00689 retval = g_try_malloc (sizeof (osso_rpc_t));
00690 if (retval == NULL)
00691 {
00692 g_debug("DBUS: Error in function %s:",__FUNCTION__);
00693 g_debug("Couldn't allocate memory for message return value\n");
00694 };
00695
00696 result = osso_rpc_run_with_argfill (ws_dbus_data->context,
00697 ws_dbus_data->remote_service,
00698 ws_dbus_data->remote_object,
00699 ws_dbus_data->remote_iface,
00700 method,
00701 retval,
00702 ws_dbus_fill_message,
00703 data_to_send);
00704
00705 g_debug ("\nDBUS: %s: ", __FUNCTION__);
00706 ws_dbus_libosso_errors (result);
00707
00708 guint i;
00709 for (i = 0; i < data_to_send->len; ++i)
00710 {
00711 g_free (g_array_index(data_to_send, osso_rpc_t*,i));
00712 };
00713
00714 g_array_free (data_to_send, TRUE);
00715 if (result != OSSO_OK)
00716 {
00717 g_debug ("Error message: %s\n", retval->value.s);
00718 osso_rpc_free_val (retval);
00719 g_free (retval);
00720 return WS_DBUS_STATUS_ERROR;
00721 };
00722
00723 osso_rpc_free_val (retval);
00724 g_free (retval);
00725 return WS_DBUS_STATUS_OK;
00726 };
00727
00731 WSDBusStatus ws_dbus_call_registered_method (WSDBusData * ws_dbus_data,
00732 gchar *method, ...)
00733 {
00734 va_list arglist;
00735 guint i;
00736 GArray *data_to_send;
00737 osso_rpc_t *temp;
00738 osso_return_t result;
00739 osso_rpc_t *retval;
00740
00741 gchar* data_types = ws_dbus_get_ptr2method (
00742 ws_dbus_data->remote_method_data,
00743 method );
00744 g_debug ("\n%s\n", data_types);
00745
00746 data_to_send = g_array_new (TRUE, TRUE, sizeof (osso_rpc_t *));
00747
00748 va_start (arglist, method);
00749
00750 for (i = 0; i < strlen (data_types); ++i)
00751 {
00752 temp = g_try_malloc (sizeof (osso_rpc_t));
00753
00754 switch ((char) data_types[i])
00755 {
00756 case WS_DBUS_TYPE_STRING:
00757 temp->value.s = va_arg (arglist, gchar *);
00758 break;
00759 case WS_DBUS_TYPE_INT:
00760 temp->value.i = va_arg (arglist, gint);
00761 break;
00762 case WS_DBUS_TYPE_UINT:
00763 temp->value.u = va_arg (arglist, guint);
00764 break;
00765 case WS_DBUS_TYPE_DOUBLE:
00766 temp->value.d = va_arg (arglist, gdouble);
00767 break;
00768 case WS_DBUS_TYPE_BOOLEAN:
00769 temp->value.b = va_arg (arglist, gboolean);
00770 break;
00771 };
00772 g_array_append_val (data_to_send, temp);
00773 };
00774 va_end (arglist);
00775
00776 retval = g_try_malloc (sizeof (osso_rpc_t));
00777
00778 if (retval == NULL)
00779 {
00780 g_debug("DBUS: Error in function %s:",__FUNCTION__);
00781 g_debug("Couldn't allocate memory for message return value\n");
00782 };
00783
00784 result = osso_rpc_run_with_argfill (ws_dbus_data->context,
00785 ws_dbus_data->remote_service,
00786 ws_dbus_data->remote_object,
00787 ws_dbus_data->remote_iface,
00788 method,
00789 retval,
00790 ws_dbus_fill_message,
00791 data_to_send);
00792 g_debug ("\nDBUS: %s: ", __FUNCTION__);
00793
00794 ws_dbus_libosso_errors (result);
00795
00796 if (result != OSSO_OK)
00797 {
00798 g_debug ("Error message: %s\n", retval->value.s);
00799 osso_rpc_free_val (retval);
00800 g_free (retval);
00801 return WS_DBUS_STATUS_ERROR;
00802 };
00803
00804 osso_rpc_free_val (retval);
00805 g_free (retval);
00806 return WS_DBUS_STATUS_OK;
00807 };
00808