diff options
Diffstat (limited to 'src/soundmanager.c')
-rw-r--r-- | src/soundmanager.c | 149 |
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, |