From 34e04465bd68dc92a1009c6eaebcace68aadf7c1 Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Thu, 8 Mar 2018 12:24:46 +0900 Subject: Improve: Add stream_open API Add stream_open API. This means registeration of source in soundmanager. The following keys are same as High Level API's argument. audio_role ... is translated to sourceID in soundmanager endpoint_id ... is translated to sinkID and used after in soundmanager endpoint_type ... is not used in soundmanager Change-Id: Id2044b406c9e8f0a20604ce653607aed0140fe19 Signed-off-by: Kazumasa Mitsunari --- src/sm-helper.c | 26 ++++++++++++ src/sm-helper.h | 1 + src/soundmanager.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/src/sm-helper.c b/src/sm-helper.c index f9e7ec3..b598faa 100644 --- a/src/sm-helper.c +++ b/src/sm-helper.c @@ -15,6 +15,7 @@ */ #include "sm-helper.h" +#include "sm-def.h" #include #include #include @@ -93,6 +94,31 @@ REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int3 return REQ_OK; } +REQ_ERROR get_sink_id(const afb_req request, const char* key, uint16_t* out_sink_id){ + AFB_DEBUG(""); + REQ_ERROR result = REQ_FAIL; + const char* requested_sink_str = afb_req_value (request, key); + json_object* test = afb_req_json(request); + AFB_DEBUG("%s", json_object_to_json_string_ext(test, JSON_C_TO_STRING_PRETTY)); + + if(0 == strcmp(requested_sink_str, "default")){ + *out_sink_id = DEFAULT_SINK; + AFB_INFO("sinkID(endpointID) is attached as default sinkID as %d", DEFAULT_SINK); + result = REQ_OK; + } + else{ + result = get_value_uint16(request, key, out_sink_id); + AFB_INFO("sinkID(endpointID) is %d", *out_sink_id); + } + + if(REQ_OK != result){ + AFB_INFO("can't parse %s, result %d", key, result); + afb_req_fail_f(request,"wrong-request","can't parse %s, result: %d", key, result); + return result; + } + return REQ_OK; +} + void sm_add_object_to_json_object(struct json_object* j_obj, int count,...) { va_list args; diff --git a/src/sm-helper.h b/src/sm-helper.h index 8c26049..8c87432 100644 --- a/src/sm-helper.h +++ b/src/sm-helper.h @@ -81,6 +81,7 @@ struct domain_data{ REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uint16_t *out_id); REQ_ERROR get_value_int16(const struct afb_req request, const char *source, int16_t *out_id); REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int32_t *out_id); +REQ_ERROR get_sink_id(const struct afb_req request, const char* key, uint16_t *out_sink_id); void sm_add_object_to_json_object(struct json_object* j_obj, int count, ...); void sm_add_object_to_json_object_func(struct json_object* j_obj, const char* verb_name, int count, ...); int sm_search_event_name_index(const char* value); diff --git a/src/soundmanager.c b/src/soundmanager.c index d8df22e..cf165e3 100644 --- a/src/soundmanager.c +++ b/src/soundmanager.c @@ -55,6 +55,33 @@ static struct afb_event ev_async_connect; static struct afb_event ev_async_disconnect; static struct afb_event ev_async_set_source_state; + +/* Client context */ +typedef struct source { + int sourceID; + int mainConnectionID; +} source; + +typedef struct sink { + int endpointID; + int endpointType; + int sinkID; +} sink; + +typedef struct events { + afb_event asyncSetSourceState; +} events; + +typedef struct smClientCtxt{ + char* appname; + source source; + sink sink; + events events; +} smClientCtxt; + +static void on_client_context_terminated(void *data); +static void create_client_context(afb_req request, guint16 source_id, guint16 sink_id, int endpoint_type); + /* ********** Method of Sound Manager (API) ********** */ @@ -763,8 +790,63 @@ void unsubscribe(struct afb_req request) #ifdef ENABLE_AGL_AHL + void streamOpen(struct afb_req request){ -// TODO : wtite function + AFB_DEBUG("call %s", __FUNCTION__); + // register audio role and endpoint + // get audio_role + const gchar* audio_role = afb_req_value(request, KEY_AHL_AUDIO_ROLE); + if(!audio_role) + { + afb_req_fail(request, "wrong request", "Please input 'audio_role' as key"); + return; + } + // get endpoint + guint16 endpoint_type = ENDPOINT_SOURCE, endpoint_id = 0; + if(REQ_OK != get_sink_id(request, KEY_AHL_ENDPOINT_ID, &endpoint_id)){return;} + get_value_uint16(request, KEY_AHL_ENDPOINT_TYPE, &endpoint_type); + + if(endpoint_type != ENDPOINT_SOURCE){ + AFB_WARNING("register sink from application is not supported"); + afb_req_fail(request,"wrong-request", "register source from application is only supported"); + return; + } + // call registerSource + json_object *jreq = afb_req_json(request); + json_object *response = json_object_new_object(); + json_object_object_add(jreq, KEY_APPNAME, json_object_new_string(audio_role)); + + afb_service_call_sync("soundmanager", "registerSource", jreq, &response); + // jreq is released by afb_service_call_sync then don't release jreq here. + + AFB_DEBUG("request result :%s", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY)); + + json_object *j_resp, *j_sid, *j_err; + int sid = -1, ret = -1; + if(json_object_object_get_ex(response, KEY_RESPONSE, &j_resp)){ + 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. + sid = json_object_get_int(j_sid); + ret = json_object_get_int(j_err); + json_object_put(j_resp); + json_object_put(j_sid); + json_object_put(j_err); + json_object_put(response); + }else { + afb_req_fail(request, NULL, "Failed streamOpen"); + json_object_put(response); + return; + } + + json_object *res = json_object_new_object(); + sm_add_object_to_json_object_func(res, __FUNCTION__, 4, + KEY_ERROR, ret, + KEY_CONNECTION_ID, sid); + char *info = get_response_audiomanager_massage_error(ret); + create_client_context(request, sid, endpoint_id, endpoint_type); + afb_req_success(request, res, info); } void streamClose(struct afb_req request){ @@ -1000,6 +1082,41 @@ static gboolean on_async_set_source_state( * */ +static void on_client_context_terminated(void *data){ + smClientCtxt* ctxt = (smClientCtxt*)data; + if(NULL == ctxt){ + return; + } + AFB_DEBUG("Client %s session is closed", ctxt->appname); + free(ctxt->appname); + free(ctxt); + // TODO : After application is terminated, what should we do? +} + +static void create_client_context(afb_req request, guint16 source_id, guint16 sink_id, int endpoint_type){ + AFB_DEBUG(""); + static int applicationID_debug = 0; + smClientCtxt* ctxt = malloc(sizeof(smClientCtxt)); + ctxt->appname = malloc(MAX_LENGTH_STR * sizeof(char)); + char *appid = afb_req_get_application_id(request); + if(NULL == appid){ + char debug[MAX_LENGTH_STR]; + //char* debug; + snprintf(debug, MAX_LENGTH_STR, "%s%d", "applicationID_debug", ++applicationID_debug); + AFB_INFO("application id is not set. Define as %s", debug); + strncpy(ctxt->appname, debug, MAX_LENGTH_STR); + } + else{ + strncpy(ctxt->appname, appid, MAX_LENGTH_STR); + } + ctxt->source.sourceID = source_id; + 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); +} + static int registerDomain() { /* Default Setting of Sound Manager Domain */ -- cgit 1.2.3-korg