aboutsummaryrefslogtreecommitdiffstats
path: root/src/soundmanager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soundmanager.c')
-rw-r--r--src/soundmanager.c149
1 files changed, 131 insertions, 18 deletions
diff --git a/src/soundmanager.c b/src/soundmanager.c
index 1d10a1e..cb2815d 100644
--- a/src/soundmanager.c
+++ b/src/soundmanager.c
@@ -26,12 +26,15 @@
#include "sm-def.h"
#include "sm-error.h"
#include "sm-helper.h"
+#include "sm-pending.h"
struct event{
char* name;
struct afb_event* event;
};
+static struct pending* pending_list = NULL;
+
static int SOUNDMANAGER_DOMAIN_ID;
static struct event command_event_list[COMMAND_EVENT_NUM];
static struct event routing_event_list[ROUTING_EVENT_NUM];
@@ -48,7 +51,7 @@ static struct afb_event ev_set_routing_rundown;
static struct afb_event ev_async_connect;
static struct afb_event ev_async_disconnect;
static struct afb_event ev_async_set_source_state;
-
+static struct afb_event ev_stream_state_event;
/* Client context */
typedef struct source {
@@ -531,8 +534,8 @@ void registerSource(struct afb_req request)
const gchar* name = afb_req_value(request, KEY_APPNAME); /* s */
if(!name)
{
- char* info = "Must specify the name. Please input json arg such as {\"appname\":\"radio\"}";
- afb_req_fail(request, NULL, info);
+ char* info = "Must specify the name. Please input json arg such as {\"audio_role\":\"radio\"}";
+ afb_req_fail(request, "wrong-request", info);
return;
}
if(REQ_OK != get_value_uint16(request, KEY_SOURCE_CLASS_ID, &source_class_id)){
@@ -698,7 +701,7 @@ void unsubscribe(struct afb_req request)
#ifdef ENABLE_AGL_AHL
-void streamOpen(struct afb_req request){
+void stream_open(struct afb_req request){
AFB_DEBUG("call %s", __FUNCTION__);
// register audio role and endpoint
// get audio_role
@@ -734,7 +737,7 @@ void streamOpen(struct afb_req request){
AFB_DEBUG("Get response success: %s", json_object_to_json_string_ext(j_resp, JSON_C_TO_STRING_PRETTY));
json_object_object_get_ex(j_resp, KEY_SOURCE_ID, &j_sid);
json_object_object_get_ex(j_resp, KEY_ERROR, &j_err);
- // requestSurface must return sourceID and error then I don't check whether sid and ret is in json_object.
+ // registerSource must return sourceID and error then I don't check whether sid and ret is in json_object.
sid = json_object_get_int(j_sid);
ret = json_object_get_int(j_err);
json_object_put(j_resp);
@@ -742,7 +745,7 @@ void streamOpen(struct afb_req request){
json_object_put(j_err);
json_object_put(response);
}else {
- afb_req_fail(request, NULL, "Failed streamOpen");
+ afb_req_fail(request, "unknown-error", "Failed stream_open");
json_object_put(response);
return;
}
@@ -753,22 +756,112 @@ void streamOpen(struct afb_req request){
KEY_AHL_REP_STREAM_ID, sid);
const char* info = get_response_audiomanager_massage_error(ret);
create_client_context(request, sid, endpoint_id, endpoint_type);
+ int index = sm_search_routing_event_name_index(SM_EVENT_STREAM_STATE_EVENT);
+ afb_req_subscribe(request, *routing_event_list[index].event);
afb_req_success(request, res, info);
}
-void streamClose(struct afb_req request){
-// TODO : wtite function
-/* smClientCtxt* ctxt = afb_req_context_get(request);
+void stream_close(struct afb_req request){
+ ErrorCode ec;
+ gint16 source_id = 0;
+ smClientCtxt* ctxt = afb_req_context_get(request);
+ if(NULL == ctxt){
+ AFB_ERROR("Context is not registered");
+ afb_req_fail(request, "wrong-request", "call stream_open at first");
+ return;
+ }
+ if(REQ_OK != get_value_uint16(request, KEY_SOURCE_ID, &source_id)){
+ if(REQ_OK != get_value_uint16(request, KEY_AHL_REP_STREAM_ID, &source_id)){
+ afb_req_fail(request, "wrong-request", "Unable to find sourceID");
+ return;
+ }
+ }
+ if(source_id != ctxt->source.sourceID){
+ AFB_ERROR("requested sourceID is %d, but your sourceID is %d", source_id, ctxt->source.sourceID);
+ afb_req_fail(request, "wrong-request", "sourceID is not yours");
+ return;
+ }
if(ctxt->source.mainConnectionID > 0){
- json_object* jreq = json_object_new_object();
- json_object_object_add(jreq, KEY_MAIN_CONNECTION_ID, ctxt->source.mainConnectionID);
- afb_service_call_sync("soundmanager", "disconnect", jreq, &response);
- json_object_object_get_ex(response, KEY_RESPONSE, &j_resp);
- } */
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_disconnect(ctxt->source.mainConnectionID);
+ if(!SEND_RESULT(ec, request)) {
+ del_pending(pending_list, source_id);
+ return;
+ }
+ ctxt->source.mainConnectionID = -1;
+ }
+ else{
+ AFB_NOTICE("Stream %d doesn't have connection. Ignore disconnect", ctxt->source.sourceID);
+ return;
+ }
+ /*create response json object*/
+ struct json_object *res = json_object_new_object();
+ sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
+ afb_req_success(request, res, info);
}
-void setStreamState(struct afb_req request){
-// TODO : wtite function
+void set_stream_state(struct afb_req request){
+ gint16 source_id = 0;
+ int main_connection_id = -1;
+ ErrorCode ec = OK;
+ int mute_state;
+ smClientCtxt* ctxt = afb_req_context_get(request);
+ if(NULL == ctxt){
+ AFB_ERROR("Context is not registered");
+ afb_req_fail(request, "wrong-request", "call stream_open at first");
+ return;
+ }
+
+ // get sourceID from request
+ if(REQ_OK != get_value_uint16(request, KEY_SOURCE_ID, &source_id)){
+ if(REQ_OK != get_value_uint16(request, KEY_AHL_REP_STREAM_ID, &source_id)){
+ afb_req_fail(request, "wrong-request", "Unable to find sourceID");
+ return;
+ }
+ }
+ if(source_id != ctxt->source.sourceID){
+ AFB_ERROR("requested sourceID is %d, but your sourceID is %d", source_id, ctxt->source.sourceID);
+ afb_req_fail(request, "wrong-request", "sourceID is not yours");
+ return;
+ }
+ if(REQ_OK != get_value_int32(request, KEY_AHL_MUTE, &mute_state)){
+ mute_state = AHL_STREAM_UNMUTE;
+ AFB_INFO("Mute state is not set. Set mute state %d(unmute) as default.", mute_state);
+ }
+ AFB_INFO("souceID: %d , mute : %d", source_id, mute_state);
+
+ if(AHL_STREAM_MUTE == mute_state){
+ if(ctxt->source.mainConnectionID > 0){
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_disconnect(ctxt->source.mainConnectionID);
+ if(!SEND_RESULT(ec, request)){
+ del_pending(pending_list, source_id);
+ return;
+ }
+ ctxt->source.mainConnectionID = -1;
+ }
+ else{
+ AFB_NOTICE("Stream %d doesn't have connection. Ignore disconnect", ctxt->source.sourceID);
+ ec = ACTION_IMPOSSIBLE;
+ }
+ }
+ else{
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_connect(source_id, ctxt->sink.sinkID, &main_connection_id);
+ ctxt->source.mainConnectionID = main_connection_id;
+ if(!SEND_RESULT(ec, request)) {
+ del_pending(pending_list, source_id);
+ return;
+ }
+ }
+ /*create response json object*/
+ struct json_object *res = json_object_new_object();
+ sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
+ afb_req_success(request, res, info);
}
#endif
@@ -909,13 +1002,27 @@ static void on_async_set_sink_volume(int handle, int sinkID,
static void on_async_set_source_state(int handle, int sourceID, int sourceState)
{
- AFB_DEBUG( "%s called", __FUNCTION__);
+ AFB_INFO( "%s called. handle : %d, sourceID: %d, state: %s", __FUNCTION__, handle, sourceID, get_source_state_key(sourceState));
struct json_object* ev_obj = json_object_new_object();
const char* ss_key = get_source_state_key(sourceState);
sm_add_object_to_json_object(ev_obj, 4,
KEY_HANDLE, handle,
KEY_SOURCE_ID, sourceID);
json_object_object_add(ev_obj, KEY_SOURCE_STATE, json_object_new_string(ss_key));
+#ifdef ENABLE_AGL_AHL
+ struct pending* pd = get_pending(pending_list, sourceID);
+ if(pd != NULL){
+ int ack_ok = 0;
+ am_proxy_ack_set_source_state(handle, ack_ok);
+ pending_list = del_pending(pending_list, sourceID);
+ }
+ json_object_object_add(ev_obj, KEY_AHL_EVENT_NAME, json_object_new_string(AHL_EVENT_NAME));
+ sm_add_object_to_json_object(ev_obj, 4,
+ KEY_AHL_REP_STREAM_ID, sourceID,
+ KEY_AHL_STATE_EVENT, sourceState);
+ json_object_get(ev_obj);
+ afb_event_push(ev_stream_state_event, ev_obj);
+#endif
afb_event_push(ev_async_set_source_state, ev_obj);
/* Applications must return ackSetSourceState to look sourceID, then Sound Manager doen't return ackSetSourceState */
/*audiomanager_routinginterface_call_ack_set_source_state_sync(
@@ -962,7 +1069,6 @@ static void create_client_context(afb_req request, guint16 source_id, guint16 si
ctxt->sink.endpointID = sink_id;
ctxt->sink.sinkID = sink_id;
ctxt->sink.endpointType = endpoint_type;
- ctxt->events.asyncSetSourceState = afb_daemon_make_event("asyncSetSourceState");
afb_req_context_set(request, ctxt, on_client_context_terminated);
}
@@ -1045,6 +1151,9 @@ int sm_init()
ev_async_connect = afb_daemon_make_event(route_evlist[2]);
ev_async_set_source_state = afb_daemon_make_event(route_evlist[3]);
ev_async_disconnect = afb_daemon_make_event(route_evlist[4]);
+#ifdef ENABLE_AGL_AHL
+ ev_stream_state_event = afb_daemon_make_event(route_evlist[5]);
+#endif
routing_event_list[0].name = strdup(route_evlist[0]);
routing_event_list[0].event = &ev_set_routing_ready;
@@ -1056,6 +1165,10 @@ int sm_init()
routing_event_list[3].event = &ev_async_set_source_state;
routing_event_list[4].name = strdup(route_evlist[4]);
routing_event_list[4].event = &ev_async_disconnect;
+#ifdef ENABLE_AGL_AHL
+ routing_event_list[5].name = strdup(route_evlist[5]);
+ routing_event_list[5].event = &ev_stream_state_event;
+#endif
am_event callback = {
.on_new_main_connection = on_new_main_connection,