aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazumasa Mitsunari <knimitz@witz-inc.co.jp>2018-03-08 12:24:46 +0900
committerKazumasa Mitsunari <knimitz@witz-inc.co.jp>2018-05-11 11:34:02 +0900
commit34e04465bd68dc92a1009c6eaebcace68aadf7c1 (patch)
tree9d9e62cf2342284e605910da62c44355b4ea5110
parent08a28337118f5474b6ce73d3024dbd88d994cb93 (diff)
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 <knimitz@witz-inc.co.jp>
-rw-r--r--src/sm-helper.c26
-rw-r--r--src/sm-helper.h1
-rw-r--r--src/soundmanager.c119
3 files changed, 145 insertions, 1 deletions
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 <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -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 */