Sound Manager
soundmanager.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <unistd.h>
23 #include <json-c/json.h>
24 //#include <search.h>
25 #include <pthread.h>
26 #include <afb/afb-binding.h>
27 #include "sm-helper.h"
28 #include <glib.h>
29 #include "dbus/audio_manager_interface.h"
30 
31 #define AM_NAME "org.genivi.audiomanager"
32 #define AM_CMD_PATH "/org/genivi/audiomanager/commandinterface"
33 #define AM_ROUTE_PATH "/org/genivi/audiomanager/routinginterface"
34 #define SOUND_MANAGER_NAME "org.soundmanager.genivi.routingsend"
35 #define SOUND_MANAGER_PATH "org/soundmanager/genivi/routingsend"
36 
37 #define COMMAND_EVENT_NUM 10
38 #define ROUTING_EVENT_NUM 10
39 #define MAX_LEN_STR 100
40 
41 const static struct afb_binding_interface *afbitf;
42 static AudiomanagerCommandinterface *am_cmd_bus;
43 static AudiomanagerRoutinginterface *am_route_bus;
44 static OrgSoundmanagerGeniviRoutingsend *sm_adapter;
45 static OrgSoundmanagerGeniviRoutingsendIface* sm_itf;
46 
47 static GMainLoop *loop = NULL;
48 /* To Do hash table is better */
49 struct event{
50  char* name;
51  struct afb_event* event;
52  };
53 static struct event command_event_list[COMMAND_EVENT_NUM];
54 static struct event routing_event_list[ROUTING_EVENT_NUM];
55 
56 static struct afb_event ev_new_connection;
57 static struct afb_event ev_removed_main_connection;
58 static struct afb_event ev_volume_changed;
59 static struct afb_event ev_sink_mute_state_changed;
60 static struct afb_event ev_main_connection_state_changed;
61 
62 /* Routing interface event */
63 static struct afb_event ev_set_routing_ready;
64 static struct afb_event ev_set_routing_rundown;
65 static struct afb_event ev_async_connect;
66 static struct afb_event ev_async_set_source_state;
67 
68 static const char _sourceid[] = "sourceID";
69 static const char _sinkid[] = "sinkID" ;
70 static const char _main_connection_id[] = "mainConnectionID";
71 static const char _delay[] = "delay";
72 static const char _connectionState[] = "connectionState";
73 static const char _connectionID[] = "connectionID";
74 static const char _volume[] = "volume";
75 static const char _volumeStep[] = "volumeStep";
76 static const char _muteState[] = "muteState";
77 
78 static const char _handle[] = "handle";
79 static const char _appname[] = "appname";
80 static const char _ramp[] = "ramp";
81 static const char _time[] = "time";
82 static const char _sourceState[] = "sourceState";
83 static const char _sourceClassID[] = "sourceClassID";
84 static const char _error[] = "error";
85 static const char _sinkData[] = "sinkData";
86 static const char _sourceData[] = "sourceData";
87 static const char _interruptState[] = "interruptState";
88 static const char _availability[] = "availability";
89 static const char _domainID[] = "domainID";
90 static const char _listvolumes[] = "listvolumes";
91 static const char _payload[] = "payload";
92 static const char _connectionFormat[] = "connectionFormat";
93 /*
94 ********** Method of Sound Manager (API) **********
95 */
96 
97 /* call "connect" function of Audio Manager*/
98 static void connect (struct afb_req request)
99 {
100  DEBUG(afbitf,"call connect");
101  guint16 source_id, sink_id;
102  guint16 main_connectionID = 0;
103  gint16 ret;
104  REQ_ERROR req_err1, req_err2;
105  GError *err = NULL;
106  /* ToDo select appname or sourceID(sinkID) */
107 
108  req_err1 = getid_uint16(request, _sourceid, &source_id);
109  req_err2 = getid_uint16(request, _sinkid, &sink_id);
110 
111  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
112  {
113  DEBUG(afbitf, "getid_uint16 source ret = %d,sink ret = %d", source_id, sink_id);
114  NOTICE(afbitf,"wrong request");
115  afb_req_fail(request,"wrong-request",NULL);
116  return;
117  }
118 
119  audiomanager_commandinterface_call_connect_sync(
120  am_cmd_bus,
121  source_id,
122  sink_id,
123  &ret,
124  &main_connectionID,
125  NULL, &err);
126 
127  if(err != NULL)
128  {
129  afb_req_fail(request, "failed", "Unable to call connect");
130  return;
131  }
132 
133  /* ToDo Remember appname(key) and tie to sourceID(value) */
134 
135  /*create response json object*/
136  struct json_object *res = json_object_new_object();
137  sm_add_object_to_json_object_func(res, __FUNCTION__, 4,
138  "error", ret,
139  _main_connection_id, main_connectionID);
140  char *info;
141  get_response_audiomanager_massage_error(ret,&info);
142  afb_req_success(request, res, info);
143 }
144 
145 /* call "disconnect" function of Audio Manager*/
146 static void disconnect (struct afb_req request)
147 {
148  DEBUG(afbitf,"call disconnect");
149 
150  guint16 id;
151  gint16 ret;
152  REQ_ERROR req_err;
153  GError *err = NULL;
154 
155  req_err = getid_uint16(request, _main_connection_id, &id);
156  DEBUG(afbitf, "requested %s = %d", _main_connection_id, id);
157 
158  if(req_err != REQ_OK)
159  {
160  afb_req_fail(request,"wrong-request",afb_req_value (request, _main_connection_id));
161  return;
162  }
163  audiomanager_commandinterface_call_disconnect_sync(
164  am_cmd_bus,
165  id,
166  &ret,
167  NULL, &err);
168  DEBUG(afbitf, "ret = %d", ret);
169 
170  if(err != NULL)
171  {
172  afb_req_fail(request, "failed", "Unable to call getListMainConnections");
173  return;
174  }
175 
176  struct json_object* res_obj = json_object_new_object();
177  sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
178  "error", ret);
179  char *info;
180  get_response_audiomanager_massage_error(ret,&info);
181 
182  afb_req_success(request, res_obj, info); /* return error num as status */
183 }
184 
185 static void setVolume (struct afb_req request)
186 {
187  DEBUG(afbitf,"call setVolume");
188 
189  guint16 sink_id, vol;
190  gint16 ret;
191  REQ_ERROR req_err1, req_err2;
192  GError *err = NULL;
193 
194  req_err1 = getid_uint16(request, _sinkid, &sink_id);
195  req_err2 = getid_int16(request, _volume, &vol);
196  DEBUG(afbitf, "requested %s = %d, %s = %d",_sinkid, sink_id, _volume, vol);
197  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
198  {
199  afb_req_fail(request,"wrong-request", NULL);
200  return;
201  }
202 
203  audiomanager_commandinterface_call_set_volume_sync(
204  am_cmd_bus,
205  sink_id,
206  vol,
207  &ret,
208  NULL, &err);
209  DEBUG(afbitf, "ret = %d", ret);
210 
211  if(err != NULL)
212  {
213  afb_req_fail(request, "failed", "Unable to call setVolume");
214  return;
215  }
216 
217  struct json_object* res_obj = json_object_new_object();
218  sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
219  "error", ret);
220  char *info;
221  get_response_audiomanager_massage_error(ret,&info);
222 
223  afb_req_success(request, res_obj, info); /* return error num as status */
224 }
225 
226 static void volumeStep (struct afb_req request)
227 {
228  DEBUG(afbitf,"call volumeStep");
229 
230  guint16 sink_id, vol;
231  gint16 ret;
232  REQ_ERROR req_err1, req_err2;
233  GError *err = NULL;
234 
235  req_err1 = getid_uint16(request, _sinkid, &sink_id);
236  req_err2 = getid_int16(request, _volumeStep, &vol);
237  DEBUG(afbitf, "requested %s = %d, %s = %d",_sinkid, sink_id, _volumeStep, vol);
238  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
239  {
240  afb_req_fail(request,"wrong-request", NULL);
241  return;
242  }
243 
244  audiomanager_commandinterface_call_volume_step_sync(
245  am_cmd_bus,
246  sink_id,
247  vol,
248  &ret,
249  NULL, &err);
250  DEBUG(afbitf, "ret = %d", ret);
251 
252  if(err != NULL)
253  {
254  afb_req_fail(request, "failed", "Unable to call volumeStep");
255  return;
256  }
257 
258  struct json_object* res_obj = json_object_new_object();
259  sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
260  "error", ret);
261  char *info;
262  get_response_audiomanager_massage_error(ret,&info);
263 
264  afb_req_success(request, res_obj, info); /* return error num as status */
265 }
266 
267 /* 1 means mute, 2 means unmute */
268 static void setSinkMuteState(struct afb_req request)
269 {
270  DEBUG(afbitf,"call setSinkMuteStete");
271 
272  guint16 sink_id, mute;
273  gint16 ret;
274  REQ_ERROR req_err1, req_err2;
275  GError *err = NULL;
276 
277  req_err1 = getid_uint16(request, _sinkid, &sink_id);
278  req_err2 = getid_int16(request, _muteState, &mute);
279  DEBUG(afbitf, "requested %s = %d, %s = %d",_sinkid, sink_id, _muteState, mute);
280  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
281  {
282  afb_req_fail(request,"wrong-request", NULL);
283  return;
284  }
285 
286  audiomanager_commandinterface_call_set_sink_mute_state_sync(
287  am_cmd_bus,
288  sink_id,
289  mute,
290  &ret,
291  NULL, &err);
292  DEBUG(afbitf, "ret = %d", ret);
293 
294  if(err != NULL)
295  {
296  afb_req_fail(request, "failed", "Unable to call setSinkMuteStete");
297  return;
298  }
299 
300  struct json_object* res_obj = json_object_new_object();
301  sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
302  "error", ret);
303  char *info;
304  get_response_audiomanager_massage_error(ret,&info);
305 
306  afb_req_success(request, res_obj, info); /* return error num as status */
307 }
308 
309 /* call "getListMainConnections" function of Audio Manager */
310 static void getListMainConnections(struct afb_req request)
311 {
312  DEBUG(afbitf,"call getListMainConnections");
313  guint16 ret;
314  GVariant* mainConnectionList;
315  GError *err = NULL;
316 
317  audiomanager_commandinterface_call_get_list_main_connections_sync(
318  am_cmd_bus,
319  &ret,
320  &mainConnectionList,
321  NULL,
322  &err
323  );
324  DEBUG(afbitf,"ret = %d, mainConnectionList pointer = %p", ret, &mainConnectionList);
325 
326  if(err != NULL)
327  {
328  afb_req_fail(request, "failed", "Unable to call getListMainConnections");
329  return;
330  }
331 
332  /* create response */
333  struct json_object *array_res = json_object_new_array();
334  gsize size = g_variant_n_children(mainConnectionList);
335  DEBUG(afbitf, "mainConnectionList size is %u",(uint16_t)size);
336  struct json_object *verb_obj = json_object_new_object();
337  sm_add_object_to_json_object_func(verb_obj, __FUNCTION__, 0);
338  json_object_array_add(array_res, verb_obj);
339  if(size <= 0)
340  {
341  NOTICE(afbitf, "mainConnectionList size is 0");
342  }
343  else{
344  for(int i = 0; i < size; ++i)
345  {
346  guint16 mcid, srcid, sinkid;
347  gint16 delay, constate;
348  g_variant_get_child(
349  mainConnectionList,i,"(qqqnn)",
350  &mcid, &srcid, &sinkid, &delay, &constate
351  );
352 
353  struct json_object* res_obj = json_object_new_object();
354  sm_add_object_to_json_object_func(res_obj,__FUNCTION__,10,
355  _main_connection_id, mcid,
356  _sourceid, srcid,
357  _sinkid, sinkid,
358  _delay, delay,
359  _connectionState, constate
360  );
361  json_object_array_add(array_res,res_obj);
362  }
363  }
364  DEBUG(afbitf,"json object :%s:",json_object_to_json_string(array_res));
365  afb_req_success(request, array_res, "Success to get main connection list");
366 }
367 
368 /*
369 *
370 ****** Routing Interface method(API) ***********
371 *
372 */
373 static void ackConnect(struct afb_req request)
374 {
375  /* This function will be deprecated */
376  DEBUG(afbitf,"call %s", __FUNCTION__);
377  guint16 handle, connection_id, error;
378  REQ_ERROR req_err1, req_err2 , req_err3;
379  GError *err = NULL;
380 
381  req_err1 = getid_uint16(request, _handle, &handle);
382  req_err2 = getid_uint16(request, _connectionID, &connection_id);
383  req_err3 = getid_uint16(request, _error, &error);
384 
385  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK) || (req_err3 != REQ_OK))
386  {
387  afb_req_fail(request,"wrong-request", NULL);
388  return;
389  }
390  if(connection_id == 0)
391  {
392  afb_req_fail(request,"wrong-request", "connectionID is more than 0");
393  return;
394  }
395 
396 
397  audiomanager_routinginterface_call_ack_connect_sync(
398  am_route_bus,
399  handle,
400  connection_id,
401  error,
402  NULL, &err);
403 
404  if(err != NULL)
405  {
406  afb_req_fail(request, "failed", "Unable to call ackConnect");
407  return;
408  }
409  afb_req_success(request, NULL, NULL);
410 }
411 static void ackDisconnect(struct afb_req request)
412 {
413  /* This function will be deprecated */
414  DEBUG(afbitf,"call %s", __FUNCTION__);
415  guint16 handle, connection_id, error;
416  REQ_ERROR req_err1, req_err2 , req_err3;
417  GError *err = NULL;
418 
419  req_err1 = getid_uint16(request, _handle, &handle);
420  req_err2 = getid_uint16(request, _connectionID, &connection_id);
421  req_err3 = getid_uint16(request, _error, &error);
422 
423  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK) || (req_err3 != REQ_OK))
424  {
425  afb_req_fail(request,"wrong-request", "connectionID is more than 0");
426  return;
427  }
428  if(connection_id == 0)
429  {
430  afb_req_fail(request,"wrong-request", "connectionID is more than 0");
431  return;
432  }
433 
434  audiomanager_routinginterface_call_ack_disconnect_sync(
435  am_route_bus,
436  handle,
437  connection_id,
438  error,
439  NULL, &err);
440 
441  if(err != NULL)
442  {
443  afb_req_fail(request, "failed", "Unable to call ackDisconnect");
444  return;
445  }
446  afb_req_success(request, NULL, NULL);
447 }
448 static void ackSetSourceState(struct afb_req request)
449 {
450  /* This function will be deprecated */
451  /* This function will be deprecated */
452  DEBUG(afbitf,"call %s", __FUNCTION__);
453  guint16 handle, error;
454  REQ_ERROR req_err1, req_err2;
455  GError *err = NULL;
456 
457  req_err1 = getid_uint16(request, _handle, &handle);
458  req_err2 = getid_uint16(request, _error, &error);
459 
460  if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
461  {
462  NOTICE(afbitf,"wrong request");
463  afb_req_fail(request,"wrong-request", NULL);
464  return;
465  }
466 
467  audiomanager_routinginterface_call_ack_set_source_state_sync(
468  am_route_bus,
469  handle,
470  error,
471  NULL, &err);
472 
473  if(err != NULL)
474  {
475  afb_req_fail(request, "failed", "Unable to call ackDisconnect");
476  return;
477  }
478  afb_req_success(request, NULL, NULL);
479 }
480 static void registerSink(struct afb_req request)
481 {
482  /* This function will be deprecated because application will not register function*/
483 }
484 static void deregisterSink(struct afb_req request)
485 {
486  /* This function will be deprecated because application will not register function*/
487 }
488 
489 /* This function will be modified to abstract argument */
490 static void registerSource(struct afb_req request)
491 {
492  DEBUG(afbitf,"call %s", __FUNCTION__);
493  GError *err = NULL;
494 
495  guint16 source_id; /* q 0 is for dynamic id*/
496  guint16 domain_id; /* q */
497  guint16 source_class_id; /* q */
498  gint32 source_state = 1; /* i SS_ON */
499  gint16 volume; /* n */
500 
501  if(REQ_OK != getid_uint16(request, _sourceid, &source_id)){
502  source_id = 0; /* if 0, dynamic source id will be attached */
503  }
504  if( REQ_OK != getid_uint16(request, _domainID, &domain_id)){
505  afb_req_fail(request,"wrong-request", "domainID should be more than 0");
506  return;
507  }
508  if(domain_id == 0)
509  {
510  afb_req_fail(request,"wrong-request", "domainID should be more than 0");
511  return;
512  }
513  const gchar* name = afb_req_value(request, _appname); /* s */
514  if(!name)
515  {
516  char* info = "Must specify the name. Please input json arg such as {\"appname\":\"radio\"}";
517  afb_req_fail(request, NULL, info);
518  return;
519  }
520  if(REQ_OK != getid_uint16(request, _sourceClassID, &source_class_id)){
521  source_class_id = 0; /* BASE */
522  }
523  if(REQ_OK != getid_uint16(request, _sourceState, &source_state)){
524  source_state = 0;
525  }
526  if(REQ_OK != getid_int16(request, _volume, &volume)){
527  volume = 3000;
528  }
529  gboolean visible = TRUE; /* b */
530  struct availability_s available; /* (ii) */
531  available.availability = 1; /* A_UNKNOWN */
532  available.avalilable_reason = 0; /* AR_UNKNOWN */
533  guint16 interrupt = 1; /* q IS_OFF */
534 
535  struct sound_property_s sound_property_list; /* a(in) */
536  sound_property_list.type = 0;
537  sound_property_list.value = 0; /* in reality, this is array of struct */
538 
539  gint32 connection_format_list = 0; /* ai */
540  struct main_sound_property_s main_property_list; /* a(in) */
541  main_property_list.type = 0;
542  main_property_list.value = 0;
543 
544  struct notification_config_s nconf_routing;
545  struct notification_config_s nconf_command; /* a(iin)a(iin) */
546  nconf_routing.type = 0;
547  nconf_routing.status = 0;
548  nconf_routing.parameter = 0;
549 
550  nconf_command.type = 0;
551  nconf_command.status = 0;
552  nconf_command.parameter = 0;
553 
554  /* acuire data */
555  guint16 acquire_source_id;
556  guint16 error;
557 
558  GVariant* sourceData = create_source_data (source_id, domain_id, name, source_class_id,
559  source_state, volume, visible, available, interrupt,
560  sound_property_list, connection_format_list, main_property_list,
561  nconf_routing, nconf_command, afbitf);
562 
563  GVariant* input = g_variant_ref_sink(sourceData);
564  audiomanager_routinginterface_call_register_source_sync(
565  am_route_bus,
566  input,
567  &acquire_source_id,
568  &error,
569  NULL, &err);
570  g_variant_unref(input);
571 
572  if(err != NULL)
573  {
574  afb_req_fail(request, "failed", "Unable to call registerSource");
575  return;
576  }
577 
578  /*create response json object*/
579  struct json_object *res = json_object_new_object();
580  sm_add_object_to_json_object_func(res, __FUNCTION__, 4,
581  _error, error,
582  _sourceid, acquire_source_id);
583  char *info;
584  get_response_audiomanager_massage_error(error,&info);
585  afb_req_success(request, res, info);
586 }
587 
588 static void deregisterSource(struct afb_req request)
589 {
590  guint16 source_id;
591  guint16 error;
592 
593  GError *err = NULL;
594 
595  if(REQ_OK != getid_uint16(request, _sourceid, &source_id)){
596  afb_req_fail(request, "wrong-request", NULL);
597  }
598  audiomanager_routinginterface_call_deregister_source_sync(
599  am_route_bus,
600  source_id,
601  &error,
602  NULL, &err
603  );
604  if(err != NULL)
605  {
606  afb_req_fail(request, "failed", "Unable to call deregisterSource");
607  return;
608  }
609  /*create response json object*/
610  struct json_object *res = json_object_new_object();
611  sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
612  _error, error);
613  char *info;
614  get_response_audiomanager_massage_error(error,&info);
615  afb_req_success(request, res, info);
616 
617 }
618 
619 static void confirmRoutingReady(struct afb_req request)
620 {
621  /* This function will be deprecated because application will not register function*/
622 }
623 static void confirmRoutingRundown(struct afb_req request)
624 {
625  /* This function will be deprecated because application will not register function*/
626 }
627 static void ackSetVolumes(struct afb_req request)
628 {
629  /* This function will be deprecated */
630 }
631 static void ackSinkNotificationConfiguration(struct afb_req request)
632 {
633  /* This function will be deprecated */
634 }
635 static void ackSourceNotificationConfiguration(struct afb_req request)
636 {
637  /* This function will be deprecated */
638 }
639 
640 
641 static void subscribe(struct afb_req request)
642 {
643  const char *value = afb_req_value(request, "event");
644  char *info;
645  DEBUG(afbitf, "value is %s", value);
646  if(value) {
647  int index = sm_search_event_name_index(value);
648  if(index < 0)
649  {
650  index = sm_search_routing_event_name_index(value);
651  if(index < 0)
652  {
653  ERROR(afbitf, "dedicated event doesn't exist");
654  }
655  else
656  {
657  afb_req_subscribe(request, *routing_event_list[index].event);
658  }
659  }
660  else
661  {
662  afb_req_subscribe(request, *command_event_list[index].event);
663  }
664  }
665  else{
666  ERROR(afbitf, "Please input event name");
667  }
668  afb_req_success(request, NULL, NULL);
669 }
670 
671 static void unsubscribe(struct afb_req request)
672 {
673  const char *value = afb_req_value(request, "event");
674  char *info;
675  DEBUG(afbitf, "value is %s", value);
676  if(value) {
677  int index = sm_search_event_name_index(value);
678  if(index < 0)
679  {
680  index = sm_search_routing_event_name_index(value);
681  if(index < 0)
682  {
683  ERROR(afbitf, "dedicated event doesn't exist");
684  }
685  else
686  {
687  afb_req_unsubscribe(request, *routing_event_list[index].event);
688  }
689  }
690  else
691  {
692  afb_req_unsubscribe(request, *command_event_list[index].event);
693  }
694  }
695  else{
696  ERROR(afbitf, "Please input event name");
697  }
698  afb_req_success(request, NULL, NULL);
699 }
700 
701 /*
702 ********** Callback Function invoked by Audio Manager **********
703 */
704 
705 static void on_new_main_connection(AudiomanagerCommandinterface* interface,
706  GVariant* mainConnection)
707 {
708  DEBUG(afbitf,"%s is called",__FUNCTION__);
709 
710  guint16 mcid, srcid, sinkid;
711  gint16 delay, constate;
712  g_variant_get(
713  mainConnection,"(qqqnn)", &mcid, &srcid, &sinkid, &delay, &constate);
714 
715  struct json_object* res_obj = json_object_new_object();
716  sm_add_object_to_json_object(res_obj,10,
717  _main_connection_id, mcid,
718  _sourceid, srcid,
719  _sinkid, sinkid,
720  _delay, delay,
721  _connectionState, constate
722  );
723  DEBUG(afbitf,"json object :%s:",json_object_to_json_string(res_obj));
724 
725  afb_event_push(ev_new_connection, res_obj);
726 }
727 
728 static void on_removed_main_connection(
729  AudiomanagerCommandinterface* interface, guint16 mainConnectionID)
730 {
731  DEBUG(afbitf,"%s is called",__FUNCTION__);
732 
733  struct json_object* res_obj = json_object_new_object();
734  sm_add_object_to_json_object(res_obj, 2,
735  _main_connection_id, mainConnectionID);
736  afb_event_push(ev_removed_main_connection, res_obj);
737 }
738 
739 static void on_main_connection_state_changed(
740  AudiomanagerCommandinterface* interface, guint16 connectionID, gint16 connectionState)
741 {
742  DEBUG(afbitf,"%s is called",__FUNCTION__);
743 
744  struct json_object* res_obj = json_object_new_object();
745  sm_add_object_to_json_object(res_obj, 4,
746  _connectionID, connectionID,
747  _connectionState, connectionState);
748  afb_event_push(ev_main_connection_state_changed, res_obj);
749 }
750 
751 static void on_volume_changed(
752  AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 volume)
753 {
754  DEBUG(afbitf,"%s is called",__FUNCTION__);
755  struct json_object* res_obj = json_object_new_object();
756  sm_add_object_to_json_object(res_obj, 4,
757  _sinkid, sinkID,
758  _volume, volume);
759  afb_event_push(ev_volume_changed, res_obj);
760 }
761 
762 static void on_sink_mute_state_changed(
763  AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 mute)
764 {
765  DEBUG(afbitf,"%s is called",__FUNCTION__);
766  struct json_object* res_obj = json_object_new_object();
767  sm_add_object_to_json_object(res_obj, 4,
768  _sinkid, sinkID,
769  _muteState, mute);
770  afb_event_push(ev_sink_mute_state_changed, res_obj);
771 }
772 
773 /*
774 ********** Callback Function invoked by Audio Manager Routing Interface**********
775 */
776 static void on_set_routing_ready(
777  AudiomanagerRoutinginterface* interface)
778 {
779  DEBUG(afbitf,"%s is called",__FUNCTION__);
780  afb_event_push(ev_set_routing_ready, NULL);
781 }
782 
783 static void on_set_routing_rundown(
784  AudiomanagerRoutinginterface* interface)
785 {
786  DEBUG(afbitf,"%s is called",__FUNCTION__);
787  afb_event_push(ev_set_routing_ready, NULL);
788 }
789 
790 
791 
792 /*
793 ********** Callback Function invoked by Sound Manager Adapter Interface**********
794 *
795 * For now, there may be no need to send events to applications from these invocation.
796 * Sound Manager just sends ack to Audio Manager in charge of applications.
797 * If event is needed, make events in initialize function in this source, and
798 * write afb_event_push in the invocations.
799 * Events should be pushed in this source.(I teseted to push events in other code, but can't)
800 *
801 */
802 
803 
804 static gboolean on_async_abort(
805  OrgSoundmanagerGeniviRoutingsend *object,
806  GDBusMethodInvocation *invocation,
807  guint16 arg_handle)
808 {
809  DEBUG(afbitf, "%s called", __FUNCTION__);
810  /* Nothing To Do. If it is better to implement something, I will implement */
811  return TRUE;
812 }
813 
814 static gboolean on_async_connect(
815  OrgSoundmanagerGeniviRoutingsend *object,
816  GDBusMethodInvocation *invocation,
817  guint16 arg_handle,
818  guint16 arg_connectionID,
819  guint16 arg_sourceID,
820  guint16 arg_sinkID,
821  gint arg_connectionFormat)
822 {
823  DEBUG(afbitf, "%s called", __FUNCTION__);
824  GError* err;
825  struct json_object* res_obj = json_object_new_object();
826  sm_add_object_to_json_object(res_obj, 10,
827  _handle, arg_handle,
828  _connectionID, arg_connectionID,
829  _sourceid, arg_sourceID,
830  _sinkid, arg_sinkID,
831  _connectionFormat, arg_connectionFormat);
832  afb_event_push(ev_async_connect, res_obj);
833  audiomanager_routinginterface_call_ack_connect_sync(
834  am_route_bus,
835  arg_handle,
836  arg_connectionID,
837  NULL,
838  NULL, &err);
839  if(err != NULL)
840  {
841  ERROR(afbitf, "Can't create sound manager adapter");
842  return FALSE;
843  }
844  return TRUE;
845 }
846 
847 static gboolean on_async_disconnect(
848  OrgSoundmanagerGeniviRoutingsend *object,
849  GDBusMethodInvocation *invocation,
850  guint16 arg_handle,
851  guint16 arg_connectionID)
852 {
853  DEBUG(afbitf, "%s called", __FUNCTION__);
854  GError* err;
855  audiomanager_routinginterface_call_ack_disconnect_sync(
856  am_route_bus,
857  arg_handle,
858  arg_connectionID,
859  NULL,
860  NULL, &err);
861  if(err != NULL)
862  {
863  ERROR(afbitf, "Can't create sound manager adapter");
864  return FALSE;
865  }
866  return TRUE;
867 }
868 
869 static gboolean on_async_set_sink_volume(
870  OrgSoundmanagerGeniviRoutingsend *object,
871  GDBusMethodInvocation *invocation,
872  guint16 arg_handle,
873  guint16 arg_sinkID,
874  gint16 arg_volume,
875  gint16 arg_ramp,
876  guint16 arg_time)
877 {
878  DEBUG(afbitf, "%s called", __FUNCTION__);
879  /* Nothing To Do. If it is better to implement something, I will implement */
880  return TRUE;
881 }
882 
883 static gboolean on_async_set_source_state(
884  OrgSoundmanagerGeniviRoutingsend *object,
885  GDBusMethodInvocation *invocation,
886  guint16 arg_handle,
887  guint16 arg_sourceID,
888  gint arg_sourceState)
889 {
890  DEBUG(afbitf, "%s called", __FUNCTION__);
891  GError* err;
892  struct json_object* res_obj = json_object_new_object();
893  sm_add_object_to_json_object(res_obj, 6,
894  _handle, arg_handle,
895  _sourceid, arg_sourceID,
896  _sourceState, arg_sourceState);
897  afb_event_push(ev_async_set_source_state, res_obj);
898  /* Applications should return ackSetSourceState, then Sound Manager doen't return ackSetSourceState */
899  /*audiomanager_routinginterface_call_ack_set_source_state_sync(
900  am_route_bus,
901  arg_handle,
902  NULL,
903  NULL, &err);*/
904  if(err != NULL)
905  {
906  ERROR(afbitf, "Can't create sound manager adapter");
907  return FALSE;
908  }
909  return TRUE;
910 }
911 
912 static gboolean init_sound_manager_adapter(GDBusServer *server, GDBusConnection *conn, gpointer data)
913 {
914  DEBUG(afbitf, "%s called", __FUNCTION__);
915  sm_adapter = org_soundmanager_genivi_routingsend_skeleton_new();
916  sm_itf = ORG_SOUNDMANAGER_GENIVI_ROUTINGSEND_GET_IFACE(sm_adapter);
917  /* initialize sound manager adapter */
918  sm_itf->handle_async_abort = on_async_abort;
919  sm_itf->handle_async_connect = on_async_connect;
920  sm_itf->handle_async_disconnect = on_async_disconnect;
921  sm_itf->handle_async_set_sink_volume = on_async_set_sink_volume;
922  sm_itf->handle_async_set_source_state = on_async_set_source_state;
923  gboolean ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(sm_adapter), conn, SOUND_MANAGER_PATH, NULL);
924  if(!ret)
925  {
926  ERROR(afbitf, "Can't create sound manager adapter");
927  return FALSE;
928  }
929  return TRUE;
930 }
931 
932 /*
933  * array of the verbs exported to afb-daemon
934  */
935 static const struct afb_verb_desc_v1 binding_verbs[]= {
936 /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */
937 { .name = "connect", .session = AFB_SESSION_NONE, .callback = connect, .info = "Connect source id and sink id" },
938 { .name = "disconnect", .session = AFB_SESSION_NONE, .callback = disconnect, .info = "Disconnect source id and sink id" },
939 { .name = "setVolume", .session = AFB_SESSION_NONE, .callback = setVolume, .info = "Set volume value" }, /* it is better to show the range*/
940 { .name = "volumeStep", .session = AFB_SESSION_NONE, .callback = volumeStep, .info = "Set volume step range" },
941 { .name = "setSinkMuteState", .session = AFB_SESSION_NONE, .callback = setSinkMuteState, .info = "Set Mute state: 1 means mute, 2 means umute. Others are invalid" },
942 { .name = "getListMainConnections", .session = AFB_SESSION_NONE, .callback = getListMainConnections, .info = "Get MainConnection List" },
943 /* Routing Interface */
944 { .name = "registerSource", .session = AFB_SESSION_NONE, .callback = registerSource, .info = "Register Application" },
945 { .name = "deregisterSource", .session = AFB_SESSION_NONE, .callback = deregisterSource, .info = "Deregister Application" },
946 { .name = "ackConnect", .session = AFB_SESSION_NONE, .callback = ackConnect, .info = "Acknowledge of asyncConnect" },
947 { .name = "ackDisconnect", .session = AFB_SESSION_NONE, .callback = ackDisconnect, .info = "Acknowledge of asyncConnect" },
948 { .name = "ackSetSourceState", .session = AFB_SESSION_NONE, .callback = ackSetSourceState, .info = "Acknowledge of asyncSetSourceState" },
949 { .name = "subscribe", .session = AFB_SESSION_NONE, .callback = subscribe, .info = "Subscribe event" },
950 { .name = "unsubscribe", .session = AFB_SESSION_NONE, .callback = unsubscribe, .info = "Unsubscribe event" },
951 { .name = NULL } /* marker for end of the array */
952 };
953 
954 static const struct afb_binding binding_description =
955 {
956  .type = AFB_BINDING_VERSION_1,
957  .v1 = {
958  .info = "Sound Manager" ,
959  .prefix = "soundmanager" ,
960  .verbs = binding_verbs
961  }
962 };
963 
964 static void *dbus_event_loop_run(void *args)
965 {
966  loop = g_main_loop_new(NULL, FALSE);
967  g_main_loop_run(loop);
968 }
969 
970 static void free_dbus()
971 {
972  ERROR(afbitf, "free dbus");
973  if(am_cmd_bus)
974  {
975  free(am_cmd_bus);
976  }
977  if(am_route_bus)
978  {
979  free(am_route_bus);
980  }
981 }
982 
983 static int init()
984 {
985  int ret;
986  INFO(afbitf,"Initialize Dbus object");
987  /* Initialize Dbus interface */
988  if(am_cmd_bus || am_route_bus)
989  {
990  ERROR(afbitf, "Dbus object to Audio Manager is already created");
991  goto out;
992  }
993  am_cmd_bus = audiomanager_commandinterface_proxy_new_for_bus_sync(
994  G_BUS_TYPE_SYSTEM,
995  G_DBUS_PROXY_FLAGS_NONE,
996  AM_NAME,
997  AM_CMD_PATH,
998  NULL,
999  NULL
1000  );
1001  am_route_bus = audiomanager_routinginterface_proxy_new_for_bus_sync(
1002  G_BUS_TYPE_SYSTEM,
1003  G_DBUS_PROXY_FLAGS_NONE,
1004  AM_NAME,
1005  AM_ROUTE_PATH,
1006  NULL,
1007  NULL
1008  );
1009 
1010  if(!am_cmd_bus || !am_route_bus)
1011  {
1012  goto out;
1013  }
1014 
1015  INFO(afbitf, "Finish Initialize");
1016  return 0;
1017 out:
1018  ERROR(afbitf,"Failed to initialize");
1019  free_dbus();
1020  return -1;
1021 }
1022 
1023 static int sm_event_init()
1024 {
1025  INFO(afbitf,"Initialize event receive setting");
1026  int ret;
1027  /* Initialize make event */
1028  size_t size = sizeof cmd_evlist / sizeof *cmd_evlist;
1029 
1030  /*create event*/
1031  /*ToDo Hash table is better. And event should be created in the loop
1032  I would like to change */
1033  ev_volume_changed = afb_daemon_make_event(afbitf->daemon, cmd_evlist[0]);
1034  ev_new_connection = afb_daemon_make_event(afbitf->daemon, cmd_evlist[1]);
1035  ev_removed_main_connection = afb_daemon_make_event(afbitf->daemon, cmd_evlist[2]);
1036  ev_sink_mute_state_changed = afb_daemon_make_event(afbitf->daemon, cmd_evlist[3]);
1037  ev_main_connection_state_changed = afb_daemon_make_event(afbitf->daemon, cmd_evlist[4]);
1038  command_event_list[0].name = cmd_evlist[0];
1039  command_event_list[0].event = &ev_volume_changed;
1040  command_event_list[1].name = cmd_evlist[1];
1041  command_event_list[1].event = &ev_new_connection;
1042  command_event_list[2].name = cmd_evlist[2];
1043  command_event_list[2].event = &ev_removed_main_connection;
1044  command_event_list[3].name = cmd_evlist[3];
1045  command_event_list[3].event = &ev_sink_mute_state_changed;
1046  command_event_list[4].name = cmd_evlist[4];
1047  command_event_list[4].event = &ev_main_connection_state_changed;
1048 
1049  /* create routing event */
1050  ev_set_routing_ready = afb_daemon_make_event(afbitf->daemon, route_evlist[0]);
1051  ev_set_routing_rundown = afb_daemon_make_event(afbitf->daemon, route_evlist[1]);
1052  ev_async_connect = afb_daemon_make_event(afbitf->daemon, route_evlist[2]);
1053  ev_async_set_source_state = afb_daemon_make_event(afbitf->daemon, route_evlist[3]);
1054  routing_event_list[0].name = route_evlist[0];
1055  routing_event_list[0].event = &ev_set_routing_ready;
1056  routing_event_list[1].name = route_evlist[1];
1057  routing_event_list[1].event = &ev_set_routing_rundown;
1058  routing_event_list[2].name = route_evlist[1];
1059  routing_event_list[2].event = &ev_async_connect;
1060  routing_event_list[3].name = route_evlist[1];
1061  routing_event_list[3].event = &ev_async_set_source_state;
1062  /*for(size_t i = 0; i < size; ++i)
1063  {
1064  struct afb_event afbev = afb_daemon_make_event(afbitf->daemon, cmd_evlist[i]));
1065  size_t afbev_size = sizeof afbev;
1066  size_t key_size = sizeof cmd_evlist[i];
1067 
1068  struct event ev = {cmd_evlist[i],afbev};
1069  command_event_list[i] = malloc(key_size + afbev_size);
1070  command_event_list[i] = ev;
1071  search_result = hsearch(entry, FIND);
1072  if(search_result)
1073  DEBUG(afbitf, "event name is %s", search_result->key);
1074  }*/
1075 
1076  /* Initialize dbus event thread */
1077  if(!am_cmd_bus || !am_route_bus)
1078  {
1079  goto ev_init_out;
1080  }
1081  pthread_t thread_id;
1082  ret = pthread_create(&thread_id, NULL, dbus_event_loop_run, NULL);
1083  if(ret != 0)
1084  {
1085  goto ev_init_out;
1086  }
1087  /* initialize signal from audio manager command interface */
1088  g_signal_connect(am_cmd_bus,
1089  "volume_changed",
1090  G_CALLBACK(on_volume_changed),
1091  NULL);
1092  g_signal_connect(am_cmd_bus,
1093  "new_main_connection",
1094  G_CALLBACK(on_new_main_connection),
1095  NULL);
1096  g_signal_connect(am_cmd_bus,
1097  "removed_main_connection",
1098  G_CALLBACK(on_removed_main_connection),
1099  NULL);
1100  g_signal_connect(am_cmd_bus,
1101  "sink_mute_state_changed",
1102  G_CALLBACK(on_sink_mute_state_changed),
1103  NULL);
1104  g_signal_connect(am_cmd_bus,
1105  "main_connection_state_changed",
1106  G_CALLBACK(on_main_connection_state_changed),
1107  NULL);
1108  g_signal_connect(am_route_bus,
1109  "set_routing_ready",
1110  G_CALLBACK(on_set_routing_ready),
1111  NULL);
1112  g_signal_connect(am_route_bus,
1113  "set_routing_rundown",
1114  G_CALLBACK(on_set_routing_rundown),
1115  NULL);
1116 
1117  /* Get soundmanager adapter bus */
1118  g_bus_own_name(G_BUS_TYPE_SYSTEM, SOUND_MANAGER_NAME, G_BUS_NAME_OWNER_FLAGS_NONE,
1119  NULL, init_sound_manager_adapter, NULL, NULL, NULL);
1120 
1121  INFO(afbitf,"Finish Initialize event receive setting");
1122  return 0;
1123 
1124 ev_init_out:
1125  if(loop != NULL)
1126  {
1127  g_main_loop_unref(loop);
1128  }
1129  free_dbus();
1130  ERROR(afbitf, "DBus connection is not created");
1131  return -1;
1132 }
1133 
1134 /*
1135  * activation function for registering the binding called by afb-daemon
1136  */
1137 const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf)
1138 {
1139  afbitf = itf; // records the interface for accessing afb-daemon
1140 
1141  int ret = init(); // Set Dbus communication with audio mangaer
1142  return (ret == 0) ? &binding_description : NULL;
1143 }
1144 
1145 int afbBindingV1ServiceInit(struct afb_service service)
1146 {
1147  DEBUG(afbitf, "Initializing Audio Manager Notification \n");
1148  int ret = sm_event_init();
1149  return ret;
1150 }
struct afb_event * event
Definition: soundmanager.c:51
#define AM_CMD_PATH
Definition: soundmanager.c:32
#define AM_NAME
Definition: soundmanager.c:31
#define AM_ROUTE_PATH
Definition: soundmanager.c:33
const struct afb_binding * afbBindingV1Register(const struct afb_binding_interface *itf)
int afbBindingV1ServiceInit(struct afb_service service)
#define ROUTING_EVENT_NUM
Definition: soundmanager.c:38
#define SOUND_MANAGER_PATH
Definition: soundmanager.c:35
#define SOUND_MANAGER_NAME
Definition: soundmanager.c:34
#define COMMAND_EVENT_NUM
Definition: soundmanager.c:37
char * name
Definition: soundmanager.c:50