aboutsummaryrefslogtreecommitdiffstats
path: root/ahl-binding/ahl-binding.c
diff options
context:
space:
mode:
Diffstat (limited to 'ahl-binding/ahl-binding.c')
-rw-r--r--ahl-binding/ahl-binding.c1276
1 files changed, 0 insertions, 1276 deletions
diff --git a/ahl-binding/ahl-binding.c b/ahl-binding/ahl-binding.c
deleted file mode 100644
index a8b7702..0000000
--- a/ahl-binding/ahl-binding.c
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
- * Copyright (C) 2017 "Audiokinetic Inc"
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "ahl-binding.h"
-#include "ahl-apidef.h" // Generated from JSON OpenAPI
-#include "wrap-json.h"
-#include "ahl-policy.h"
-#include "ahl-json.h"
-
-// Global high-level binding context
-AHLCtxT g_AHLCtx;
-
-static EndpointTypeT EndpointTypeToEnum(char * in_pEndpointTypeStr)
-{
- if (in_pEndpointTypeStr == NULL) {
- return ENDPOINTTYPE_MAXVALUE;
- }
- else if (strcasecmp(in_pEndpointTypeStr,AHL_ENDPOINTTYPE_SOURCE)==0) {
- return ENDPOINTTYPE_SOURCE;
- }
- else if (strcasecmp(in_pEndpointTypeStr,AHL_ENDPOINTTYPE_SINK)==0) {
- return ENDPOINTTYPE_SINK;
- }
- else
- return ENDPOINTTYPE_MAXVALUE;
-}
-
-static StreamStateT StreamStateToEnum(char * in_pStreamStateStr)
-{
- if (in_pStreamStateStr == NULL) {
- return STREAM_STATE_MAXVALUE;
- }
- else if (strcasecmp(in_pStreamStateStr,AHL_STREAM_STATE_IDLE)==0) {
- return STREAM_STATE_IDLE;
- }
- else if (strcasecmp(in_pStreamStateStr,AHL_STREAM_STATE_RUNNING)==0) {
- return STREAM_STATE_RUNNING;
- }
- else if (strcasecmp(in_pStreamStateStr,AHL_STREAM_STATE_PAUSED)==0) {
- return STREAM_STATE_PAUSED;
- }
- else
- return STREAM_STATE_MAXVALUE;
-}
-
-static streamID_t CreateNewStreamID()
-{
- streamID_t newID = g_AHLCtx.nextStreamID;
- g_AHLCtx.nextStreamID++;
- return newID;
-}
-
-static EndpointInfoT * GetEndpointInfoWithRole(endpointID_t in_endpointID, EndpointTypeT in_endpointType, RoleInfoT * in_pRole)
-{
- EndpointInfoT * pEndpointInfo = NULL;
- GPtrArray * pDeviceArray = NULL;
- if (in_endpointType == ENDPOINTTYPE_SOURCE){
- pDeviceArray = in_pRole->pSourceEndpoints;
- }
- else {
- pDeviceArray = in_pRole->pSinkEndpoints;
- }
- g_assert_nonnull(pDeviceArray);
-
- for (int j = 0; j < pDeviceArray->len; j++) {
- EndpointInfoT * pCurEndpointInfo = g_ptr_array_index(pDeviceArray,j);
- g_assert_nonnull(pCurEndpointInfo);
- if (pCurEndpointInfo->endpointID == in_endpointID) {
- pEndpointInfo = pCurEndpointInfo;
- break;
- }
- }
-
- return pEndpointInfo;
-}
-
-static EndpointInfoT * GetEndpointInfo(endpointID_t in_endpointID, EndpointTypeT in_endpointType)
-{
- EndpointInfoT * pEndpointInfo = NULL;
-
- GHashTableIter iter;
- gpointer key, value;
- g_hash_table_iter_init (&iter, g_AHLCtx.policyCtx.pRoleInfo);
- while (pEndpointInfo == NULL && g_hash_table_iter_next (&iter, &key, &value))
- {
- RoleInfoT * pRoleInfo = (RoleInfoT*)value;
- pEndpointInfo = GetEndpointInfoWithRole(in_endpointID,in_endpointType,pRoleInfo);
- }
-
- return pEndpointInfo;
-}
-
-static StreamInfoT * GetStream(streamID_t in_streamID)
-{
- if (g_AHLCtx.policyCtx.pStreams == NULL)
- return NULL;
-
- return g_hash_table_lookup(g_AHLCtx.policyCtx.pStreams,GINT_TO_POINTER(&in_streamID));
-}
-
-static RoleInfoT * GetRole(char * in_pAudioRoleName)
-{
- if (g_AHLCtx.policyCtx.pRoleInfo == NULL)
- return NULL;
-
- return g_hash_table_lookup(g_AHLCtx.policyCtx.pRoleInfo,in_pAudioRoleName);
-}
-
-static int CloseStream(AHLClientCtxT * in_pClientCtx, streamID_t streamID,struct afb_req * pReq) {
- StreamInfoT * pStreamInfo = GetStream(streamID);
- if (pStreamInfo == NULL) {
- AFB_ERROR("Specified stream not currently active stream_id -> %d",streamID);
- return AHL_FAIL;
- }
-
-#ifndef AHL_DISCONNECT_POLICY
- json_object *pPolicyStreamJ = NULL;
- int err = StreamInfoToJSON(pStreamInfo, &pPolicyStreamJ);
- if (err == AHL_POLICY_UTIL_FAIL)
- {
- AFB_ERROR("Audio policy violation, Unable to get JSON object for Policy_CloseStream");
- return AHL_FAIL;
- }
- int policyAllowed = Policy_CloseStream(pPolicyStreamJ);
- if (policyAllowed == AHL_POLICY_REJECT)
- {
- AFB_ERROR("Close stream not allowed in current context");
- return AHL_FAIL;
- }
-#endif
- // Unsubscribe client from stream events
- if (pReq != NULL) {
- char streamEventName[128];
- snprintf(streamEventName,128,"ahl_streamstate_%d",streamID);
- int iValid = afb_event_is_valid(pStreamInfo->streamStateEvent);
- if (iValid) {
- err = afb_req_unsubscribe(*pReq,pStreamInfo->streamStateEvent);
- if (err) {
- AFB_ERROR("Could not unsubscribe state change event for streamID:%i with AudioRole: %s", streamID, pStreamInfo->pRoleName);
- return AHL_FAIL;
- }
- }
- }
-
- // Remove from stream list (if present)
- if (g_AHLCtx.policyCtx.pStreams)
- g_hash_table_remove(g_AHLCtx.policyCtx.pStreams,GINT_TO_POINTER(&pStreamInfo->streamID));
- free(pStreamInfo);
- pStreamInfo = NULL;
-
- // Find index for cases where there are multiple streams per client
- // Remove from client context stream ID and endpoint ID access rights
- if (in_pClientCtx->pStreamAccessList) {
- for (int i = 0; i < in_pClientCtx->pStreamAccessList->len ; i++) {
- streamID_t iID = g_array_index(in_pClientCtx->pStreamAccessList,streamID_t,i);
- if (iID == streamID) {
- g_array_remove_index(in_pClientCtx->pStreamAccessList, i);
- }
- }
- }
-
- return AHL_SUCCESS;
-}
-
-static int CloseAllClientStreams(AHLClientCtxT * in_pClientCtx, struct afb_req * pReq)
-{
- g_assert_nonnull(in_pClientCtx);
- if (in_pClientCtx->pStreamAccessList != NULL) {
- while( in_pClientCtx->pStreamAccessList->len )
- {
- streamID_t streamID = g_array_index(in_pClientCtx->pStreamAccessList,streamID_t,0);
- int err = CloseStream(in_pClientCtx,streamID,pReq);
- if (err) {
- return err;
- }
- }
- }
-
- return AHL_SUCCESS;
-}
-
-static AHLClientCtxT * AllocateClientContext()
-{
- AHLClientCtxT * pClientCtx = malloc(sizeof(AHLClientCtxT));
- pClientCtx->pStreamAccessList = g_array_new(FALSE, TRUE, sizeof(streamID_t));
- return pClientCtx;
-}
-
-static void TerminateClientContext(void * ptr)
-{
- AHLClientCtxT * pClientCtx = (AHLClientCtxT *) ptr;
- if (pClientCtx != NULL) {
- CloseAllClientStreams(pClientCtx,NULL);
-
- if (pClientCtx->pStreamAccessList) {
- g_array_free( pClientCtx->pStreamAccessList, TRUE);
- pClientCtx->pStreamAccessList = NULL;
- }
-
- free(pClientCtx);
- }
-}
-
-static int CheckStreamAccessControl(AHLClientCtxT * pClientCtx, streamID_t streamID)
-{
- int iAccessControl = AHL_ACCESS_CONTROL_DENIED;
- if (pClientCtx && pClientCtx->pStreamAccessList) {
- for (int i = 0; i < pClientCtx->pStreamAccessList->len ; i++) {
- streamID_t iID = g_array_index(pClientCtx->pStreamAccessList,streamID_t,i);
- if (iID == streamID) {
- iAccessControl = AHL_ACCESS_CONTROL_GRANTED;
- }
- }
- }
- return iAccessControl;
-}
-
-static int CreateEvents()
-{
- g_AHLCtx.policyCtx.propertyEvent = afb_daemon_make_event(AHL_ENDPOINT_PROPERTY_EVENT);
- int err = !afb_event_is_valid(g_AHLCtx.policyCtx.propertyEvent);
- if (err) {
- AFB_ERROR("Could not create endpoint property change event");
- return AHL_FAIL;
- }
-
- g_AHLCtx.policyCtx.volumeEvent = afb_daemon_make_event(AHL_ENDPOINT_VOLUME_EVENT);
- err = !afb_event_is_valid(g_AHLCtx.policyCtx.volumeEvent);
- if (err) {
- AFB_ERROR("Could not create endpoint volume change event");
- return AHL_FAIL;
- }
-
- g_AHLCtx.policyCtx.postActionEvent = afb_daemon_make_event(AHL_POST_ACTION_EVENT);
- err = !afb_event_is_valid(g_AHLCtx.policyCtx.postActionEvent);
- if (err) {
- AFB_ERROR("Could not create post action event call event");
- return AHL_FAIL;
- }
-
- return AHL_SUCCESS;
-}
-
-static void AhlBindingTerm()
-{
-#ifndef AHL_DISCONNECT_POLICY
- // Policy termination
- Policy_Term();
-#endif
-
- // Roles
- if (g_AHLCtx.policyCtx.pRoleInfo != NULL) {
- GHashTableIter iter;
- gpointer key, value;
- g_hash_table_iter_init(&iter, g_AHLCtx.policyCtx.pRoleInfo);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- RoleInfoT * pRole = (RoleInfoT *)value;
- if (pRole)
- {
- if(pRole->pRoleName) {
- g_free(pRole->pRoleName);
- pRole->pRoleName = NULL;
- }
- // Actions
- if (pRole->pActionList) {
- for (int i = 0; i < pRole->pActionList->len; i++)
- {
- g_ptr_array_remove_index( pRole->pActionList, i ); // Free char * is called by GLib
- }
- }
- // Source endpoints
- if (pRole->pSourceEndpoints) {
- g_ptr_array_unref(pRole->pSourceEndpoints);
- }
- // Sink endpoints
- if (pRole->pSinkEndpoints) {
- g_ptr_array_unref(pRole->pSinkEndpoints);
- }
- free(pRole);
- }
- }
- g_hash_table_remove_all(g_AHLCtx.policyCtx.pRoleInfo);
- g_hash_table_destroy(g_AHLCtx.policyCtx.pRoleInfo);
- g_AHLCtx.policyCtx.pRoleInfo = NULL;
- }
-
- if (g_AHLCtx.policyCtx.pStreams) {
- GHashTableIter iter;
- gpointer key, value;
- g_hash_table_iter_init (&iter, g_AHLCtx.policyCtx.pStreams);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- if (value)
- free(value);
- }
- g_hash_table_remove_all(g_AHLCtx.policyCtx.pStreams);
- g_hash_table_destroy(g_AHLCtx.policyCtx.pStreams);
- g_AHLCtx.policyCtx.pStreams = NULL;
- }
-
- if (g_AHLCtx.policyCtx.pHALList) {
- g_ptr_array_free(g_AHLCtx.policyCtx.pHALList,TRUE);
- g_AHLCtx.policyCtx.pHALList = NULL;
- }
-
- AFB_INFO("Audio high-level binding termination success");
-}
-
-// Binding initialization
-PUBLIC int AhlBindingInit()
-{
- memset(&g_AHLCtx,0,sizeof(g_AHLCtx));
-
- // Register exit function
- atexit(AhlBindingTerm);
-
- // Create AGL Events
- int err = CreateEvents();
- if(err) {
- // Error messages already reported inside CreateEvents
- return AHL_FAIL;
- }
-
- // Parse high-level binding JSON configuration file (will build device lists)
- err = ParseHLBConfig();
- if(err) {
- // Error messages already reported inside ParseHLBConfig
- return AHL_FAIL;
- }
-
-#ifndef AHL_DISCONNECT_POLICY
- // Policy initialization
- AFB_DEBUG("Audio high-level policy initialization");
- err = Policy_Init();
- if(err == AHL_POLICY_REJECT) {
- //Error messages already reported inside PolicyInit
- return AHL_FAIL;
- }
-
- // Call policy for initalization of all source + sink endpoints for all audio Roles
- GHashTableIter iter;
- gpointer key, value;
- g_hash_table_iter_init (&iter, g_AHLCtx.policyCtx.pRoleInfo);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- RoleInfoT * pRoleInfo = (RoleInfoT*)value;
- if (pRoleInfo->pSourceEndpoints){
- // for all source endpoints
- for (int j = 0; j < pRoleInfo->pSourceEndpoints->len; j++) {
- EndpointInfoT * pCurEndpointInfo = g_ptr_array_index(pRoleInfo->pSourceEndpoints,j);
- g_assert_nonnull(pCurEndpointInfo);
- json_object *pInPolicyEndpointJ = NULL;
- err = EndpointInfoToJSON(pCurEndpointInfo, &pInPolicyEndpointJ);
- if (err) {
- AFB_ERROR("Unable to create source endpoint JSON object from endpoint info for endpoint_id:%d error:%s ",pCurEndpointInfo->endpointID, wrap_json_get_error_string(err));
- return AHL_FAIL;
- }
- else
- {
- json_object * pOutPolicyEndpointJ = NULL;
- err = Policy_Endpoint_Init(pInPolicyEndpointJ,&pOutPolicyEndpointJ);
- if (err == AHL_POLICY_REJECT) {
- AFB_WARNING("Policy source endpoint properties initalization failed for endpoint_id :%d type:%d",pCurEndpointInfo->endpointID, pCurEndpointInfo->type);
- // continue
- }
- json_object_put(pInPolicyEndpointJ);
- err = UpdateEndpointInfo(pCurEndpointInfo,pOutPolicyEndpointJ);
- if (err) {
- AFB_ERROR("Policy source endpoint properties update failed for endpoint_id :%d type:%d",pCurEndpointInfo->endpointID, pCurEndpointInfo->type);
- return AHL_FAIL;
- }
- // json_object_put(pOutPolicyEndpointJ);
- }
- }
- }
-
- if (pRoleInfo->pSinkEndpoints){
- // for all sink endpoints
- for (int j = 0; j < pRoleInfo->pSinkEndpoints->len; j++) {
- EndpointInfoT * pCurEndpointInfo = g_ptr_array_index(pRoleInfo->pSinkEndpoints,j);
- g_assert_nonnull(pCurEndpointInfo);
- json_object *pInPolicyEndpointJ = NULL;
- err = EndpointInfoToJSON(pCurEndpointInfo, &pInPolicyEndpointJ);
- if (err) {
- AFB_ERROR("Unable to create sink endpoint JSON object from endpoint info for endpoint_id:%d error:%s ",pCurEndpointInfo->endpointID, wrap_json_get_error_string(err));
- return AHL_FAIL;
- }
- else
- {
- json_object *pOutPolicyEndpointJ = NULL;
- err = Policy_Endpoint_Init(pInPolicyEndpointJ,&pOutPolicyEndpointJ);
- if (err == AHL_POLICY_REJECT) {
- AFB_WARNING("Policy sink endpoint properties initalization failed for endpoint_id :%d type:%d",pCurEndpointInfo->endpointID, pCurEndpointInfo->type);
- // continue
- }
- json_object_put(pInPolicyEndpointJ);
- err = UpdateEndpointInfo(pCurEndpointInfo,pOutPolicyEndpointJ);
- if (err) {
- AFB_ERROR("Policy sink endpoint properties update failed for endpoint_id :%d type:%d",pCurEndpointInfo->endpointID, pCurEndpointInfo->type);
- return AHL_FAIL;
- }
- //json_object_put(pOutPolicyEndpointJ);
- }
- }
- }
- }
-#endif // AHL_DISCONNECT_POLICY
-
- // Initialize list of active streams
- g_AHLCtx.policyCtx.pStreams = g_hash_table_new(g_int_hash, g_int_equal);
- if(g_AHLCtx.policyCtx.pStreams == NULL)
- {
- AFB_ERROR("Unable to create Active Stream List");
- return AHL_FAIL;
- }
- AFB_DEBUG("Audio high-level binding initialization success");
- return AHL_SUCCESS;
-}
-
-PUBLIC void AhlOnEvent(const char *evtname, json_object *eventJ)
-{
- AFB_DEBUG("AHL received event %s", evtname);
-
- // TODO: Handle event from the policy to update internal information (currently not possible since within the same binding)
-
-#ifndef AHL_DISCONNECT_POLICY
- // Temp: currently forward to policy to handle events (they will be received directly when disconnected into separate binding)
- Policy_OnEvent(evtname, eventJ);
-#endif
-}
-
-PUBLIC void audiohlapi_get_endpoints(struct afb_req req)
-{
- json_object *devicesJ = NULL;
- json_object *deviceJ = NULL;
- json_object *queryJ = NULL;
- char * audioRole = NULL;
- char * pEndpointTypeStr = NULL;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:s}", "audio_role", &audioRole,"endpoint_type",&pEndpointTypeStr);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
- endpointType = EndpointTypeToEnum(pEndpointTypeStr);
-
- RoleInfoT * pRole = GetRole(audioRole);
- if ( pRole == NULL )
- {
- afb_req_fail_f(req, "Invalid arguments", "Requested audio role:%s does not exist in current configuration -> %s", audioRole, json_object_get_string(queryJ));
- return;
- }
- else
- {
- devicesJ = json_object_new_array();
- GPtrArray * pDeviceArray = NULL;
- if (endpointType == ENDPOINTTYPE_SOURCE)
- pDeviceArray = pRole->pSourceEndpoints;
- else
- pDeviceArray = pRole->pSinkEndpoints;
- if (pDeviceArray) {
- int iNumberDevices = pDeviceArray->len;
- for ( int j = 0 ; j < iNumberDevices; j++)
- {
- EndpointInfoT * pEndpointInfo = g_ptr_array_index(pDeviceArray,j);
- if (pEndpointInfo) {
- JSONPublicPackageEndpoint(pEndpointInfo,&deviceJ);
- json_object_array_add(devicesJ, deviceJ);
- }
- }
- }
- }
-
- afb_req_success(req, devicesJ, "List of endpoints");
-}
-
-PUBLIC void audiohlapi_stream_open(struct afb_req req)
-{
- json_object *streamInfoJ = NULL;
- StreamInfoT * pStreamInfo = NULL;
- json_object *queryJ = NULL;
- char * audioRole = NULL;
- char * endpointTypeStr = NULL;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
- endpointID_t endpointID = AHL_UNDEFINED;
- EndpointInfoT * pEndpointInfo = NULL;
- EndpointSelectionModeT endpointSelMode = ENDPOINTSELMODEMAXVALUE;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:s,s?i}", "audio_role", &audioRole, "endpoint_type", &endpointTypeStr, "endpoint_id", &endpointID);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
- endpointType = EndpointTypeToEnum(endpointTypeStr);
-
- // Check if there is already an existing context for this client
- AHLClientCtxT * pClientCtx = afb_req_context_get(req); // Retrieve client-specific data structure
- if (pClientCtx == NULL)
- {
- pClientCtx = AllocateClientContext();
- afb_req_context_set(req, pClientCtx, TerminateClientContext);
- }
-
- RoleInfoT * pRole = GetRole(audioRole);
- if ( pRole == NULL )
- {
- afb_req_fail_f(req, "Invalid audio role", "Audio role was not found in configuration -> %s",audioRole);
- return;
- }
-
- GPtrArray * pDeviceArray = NULL;
- if (endpointType == ENDPOINTTYPE_SOURCE){
- pDeviceArray = pRole->pSourceEndpoints;
- }
- else{
- pDeviceArray = pRole->pSinkEndpoints;
- }
- if (pDeviceArray == NULL || pDeviceArray->len == 0) {
- afb_req_fail_f(req, "No available devices", "No available devices for role:%s and device type:%s",audioRole,endpointTypeStr);
- return;
- }
-
- if (endpointID == AHL_UNDEFINED)
- {
- // Assign a device based on configuration priority (first in the list for requested role and endpoint type)
- pEndpointInfo = g_ptr_array_index(pDeviceArray,0);
- endpointSelMode = ENDPOINTSELMODE_AUTO;
- }
- else{
- endpointSelMode = ENDPOINTSELMODE_MANUAL;
- // Find specified endpoint ID in list of devices
- int iNumberDevices = pDeviceArray->len;
- for ( int j = 0 ; j < iNumberDevices; j++)
- {
- pEndpointInfo = g_ptr_array_index(pDeviceArray,j);
- if (pEndpointInfo && pEndpointInfo->endpointID == endpointID) {
- break;
- }
- pEndpointInfo = NULL;
- }
- }
-
- if (pEndpointInfo == NULL) {
- afb_req_fail_f(req, "Endpoint not available", "Specified endpoint not available for role:%s and device type:%d endpoint id %d",audioRole,endpointType,endpointID);
- return;
- }
-
- pStreamInfo = (StreamInfoT*) malloc(sizeof(StreamInfoT));
- memset(pStreamInfo,0,sizeof(StreamInfoT));
-
- // Create stream
- pStreamInfo->streamID = CreateNewStreamID(); // create new ID
- pStreamInfo->streamState = STREAM_STATE_IDLE;
- pStreamInfo->streamMute = STREAM_UNMUTED;
- pStreamInfo->pEndpointInfo = pEndpointInfo;
- pStreamInfo->endpointSelMode = endpointSelMode;
- // Directly from role config for now, but could be programmatically overriden in the future
- pStreamInfo->pRoleName = pRole->pRoleName;
- pStreamInfo->iPriority = pRole->iPriority;
- pStreamInfo->eInterruptBehavior = pRole->eInterruptBehavior;
-
-#ifndef AHL_DISCONNECT_POLICY
- // Call policy to verify whether creating a new audio stream is allowed in current context and possibly take other actions
- json_object *pPolicyStreamJ = NULL;
- err = StreamInfoToJSON(pStreamInfo,&pPolicyStreamJ);
- if (err)
- {
- afb_req_fail(req, "Cannot convert stream info to JSON", "Unable to get JSON object for Policy_OpenStream");
- return;
- }
-
- int policyAllowed = Policy_OpenStream(pPolicyStreamJ);
- if (policyAllowed == AHL_POLICY_REJECT)
- {
- afb_req_fail_f(req, "Audio policy violation", "Open stream for role: %s on endpoint_id:%d not allowed in current context",pRole->pRoleName,pEndpointInfo->endpointID);
- return;
- }
-#endif
-
- char streamEventName[128];
- snprintf(streamEventName,128,"ahl_streamstate_%d",pStreamInfo->streamID);
-
- pStreamInfo->streamStateEvent = afb_daemon_make_event(streamEventName);
- err = !afb_event_is_valid(pStreamInfo->streamStateEvent);
- if (err) {
- afb_req_fail_f(req, "Stream event creation failure", "Could not create stream specific state change event: %s",streamEventName);
- return;
- }
-
- err = afb_req_subscribe(req,pStreamInfo->streamStateEvent);
- if (err) {
- afb_req_fail_f(req, "Stream event subscription failure", "Could not subscribe to stream specific state change event for event name: %s",streamEventName);
- return;
- }
-
- // Add to client context stream ID access rights
- g_array_append_val(pClientCtx->pStreamAccessList, pStreamInfo->streamID);
-
- // Push stream on active stream list
- if (g_AHLCtx.policyCtx.pStreams)
- g_hash_table_insert( g_AHLCtx.policyCtx.pStreams, GINT_TO_POINTER(&pStreamInfo->streamID), pStreamInfo );
-
- // Package and return stream information to client
- JSONPublicPackageStream(pStreamInfo,&streamInfoJ);
-
- afb_req_success(req, streamInfoJ, "Stream info structure");
-}
-
-PUBLIC void audiohlapi_stream_close(struct afb_req req)
-{
- json_object *queryJ = NULL;
- streamID_t streamID = AHL_UNDEFINED;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s?i}", "stream_id", &streamID);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- // Check if there is already an existing context for this client
- AHLClientCtxT * pClientCtx = afb_req_context_get(req); // Retrieve client-specific data structure
- if (pClientCtx == NULL)
- {
- afb_req_fail(req, "Missing client info context", "No client context associated with the request (is there an opened stream by this client?)");
- return;
- }
-
- if (streamID == AHL_UNDEFINED) {
- AFB_DEBUG("StreamID not specified. Closing all stream for client");
- err = CloseAllClientStreams(pClientCtx,&req);
- if (err) {
- afb_req_fail(req, "Error closing streams", "Streams cannot close");
- return;
- }
- }
- else {
- AFB_DEBUG("Closing streamID:%d",streamID);
- err = CloseStream(pClientCtx,streamID,&req);
- if (err) {
- afb_req_fail_f(req, "Error closing stream", "Specified stream cannot close stream_id -> %d",streamID);
- return;
- }
- }
-
- afb_req_success(req, NULL, "Stream close completed");
-}
-
-static int SetStreamState(AHLClientCtxT * in_pClientCtx,struct afb_req * pReq, streamID_t streamID, char * pStreamStateStr, int iMuteValue) {
-
- StreamInfoT * pStreamInfo = GetStream(streamID);
- if (pStreamInfo == NULL) {
- afb_req_fail_f(*pReq, "Stream not found", "Specified stream not found stream_id -> %d",streamID);
- return AHL_FAIL;
- }
-
- // Verify that this client can control the stream
- int iStreamAccessControl = CheckStreamAccessControl( in_pClientCtx, streamID );
- if (iStreamAccessControl == AHL_ACCESS_CONTROL_DENIED)
- {
- afb_req_fail_f(*pReq, "Access control denied", "Current client is not the owner of streamID:%d", streamID);
- return AHL_FAIL;
- }
-
- if (pStreamStateStr != NULL) {
- StreamStateT streamState = StreamStateToEnum(pStreamStateStr);
-#ifndef AHL_DISCONNECT_POLICY
- json_object *pPolicyStreamJ = NULL;
- int err = StreamInfoToJSON(pStreamInfo, &pPolicyStreamJ);
- if (err == AHL_POLICY_UTIL_FAIL)
- {
- afb_req_fail_f(*pReq, "JSON packaging error", "Unable to create stream JSON object for Policy_SetStreamState for streamID:%d",streamID);
- return AHL_FAIL;
- }
-
- json_object *paramJ= json_object_new_int(streamState);
- json_object_object_add(pPolicyStreamJ, "arg_stream_state", paramJ);
-
- int policyAllowed = Policy_SetStreamState(pPolicyStreamJ);
- if (policyAllowed == AHL_POLICY_REJECT)
- {
- afb_req_fail_f(*pReq, "Audio policy violation", "Change stream state not allowed by policy in current context for streamID:%d",streamID);
- return AHL_FAIL;
- }
-#else
- // Simulate that policy returns target state (accepted)
- pStreamInfo->streamState = streamState;
-#endif
- }
-
-#ifndef AHL_DISCONNECT_POLICY
- json_object *pPolicyStreamJ = NULL;
- int err = StreamInfoToJSON(pStreamInfo, &pPolicyStreamJ);
- if (err == AHL_POLICY_UTIL_FAIL)
- {
- afb_req_fail_f((*pReq), "JSON packaging error", "Unable to create stream JSON object for Policy_SetStreamMute for streamID:%d",streamID);
- return AHL_FAIL;
- }
-
- json_object *paramJ= json_object_new_int(iMuteValue);
- json_object_object_add(pPolicyStreamJ, "mute_state", paramJ);
-
- int policyAllowed = Policy_SetStreamMute(pPolicyStreamJ);
- if (policyAllowed == AHL_POLICY_REJECT)
- {
- afb_req_fail_f(*pReq, "Audio policy violation", "Mute stream not allowed by policy in current context for streamID:%d",streamID);
- return AHL_FAIL;
- }
-#else
- // Simulate that policy returns target state (accepted)
- pStreamInfo->streamMute = (StreamMuteT)(*piMuteValue);
-#endif
-
- return AHL_SUCCESS;
-}
-
- PUBLIC void audiohlapi_set_stream_state(struct afb_req req)
- {
- json_object *queryJ = NULL;
- streamID_t streamID = AHL_UNDEFINED;
- char * streamStateStr = NULL;
- int iMuteValue = 0;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s?i,s?s,s?i}", "stream_id", &streamID,"state",&streamStateStr,"mute",&iMuteValue);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- // Check if there is already an existing context for this client
- AHLClientCtxT * pClientCtx = afb_req_context_get(req); // Retrieve client-specific data structure
- if (pClientCtx == NULL)
- {
- afb_req_fail(req, "Missing client info context", "No client context associated with the request (is there an opened stream by this client?)");
- return;
- }
-
- if (streamID == AHL_UNDEFINED) {
- // All stream for this client
- if (pClientCtx->pStreamAccessList != NULL) {
- for (int i = 0; i < pClientCtx->pStreamAccessList->len; i++)
- {
- streamID_t curStreamID = g_array_index(pClientCtx->pStreamAccessList,streamID_t,i);
- err = SetStreamState(pClientCtx,&req,curStreamID,streamStateStr,iMuteValue);
- if (err) {
- // Error displayed within SetStreamState
- return;
- }
- }
- }
- }
- else {
- err = SetStreamState(pClientCtx,&req,streamID,streamStateStr,iMuteValue);
- if (err) {
- // Error displayed within SetStreamState
- return;
- }
- }
-
- afb_req_success(req, NULL, "Set stream state");
- }
-
- PUBLIC void audiohlapi_get_stream_info(struct afb_req req)
- {
- json_object *queryJ = NULL;
- streamID_t streamID = AHL_UNDEFINED;
- json_object * streamInfoJ = NULL;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:i}", "stream_id", &streamID);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- StreamInfoT * pStreamInfo = GetStream(streamID);
- if (pStreamInfo == NULL) {
- afb_req_fail_f(req, "Stream not found", "Specified stream not currently active stream_id -> %d",streamID);
- return;
- }
-
- JSONPublicPackageStream(pStreamInfo,&streamInfoJ);
-
- afb_req_success(req, streamInfoJ, "Get stream info completed");
- }
-
-PUBLIC void audiohlapi_volume(struct afb_req req)
-{
- json_object *queryJ = NULL;
- endpointID_t endpointID = AHL_UNDEFINED;
- char * pEndpointTypeStr = NULL;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
- char * volumeStr = NULL;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:i,s?s}", "endpoint_type", &pEndpointTypeStr,"endpoint_id",&endpointID,"volume",&volumeStr);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
- endpointType = EndpointTypeToEnum(pEndpointTypeStr);
-
- EndpointInfoT * pEndpointInfo = GetEndpointInfo(endpointID,endpointType);
- if (pEndpointInfo == NULL)
- {
- afb_req_fail_f(req, "Endpoint not found", "Endpoint information not found for endpoint_id:%d type:%d",endpointID,endpointType);
- return;
- }
-
- if (volumeStr != NULL) {
-#ifndef AHL_DISCONNECT_POLICY
- json_object *pPolicyEndpointJ = NULL;
- err = EndpointInfoToJSON(pEndpointInfo, &pPolicyEndpointJ);
- if (err == AHL_POLICY_UTIL_FAIL)
- {
- afb_req_fail_f(req, "JSON packaging error", "Unable to create endpoint JSON object for Policy_SetVolume for endpoint_id:%d type:%d",endpointID,endpointType);
- return;
- }
-
- json_object *paramJ= json_object_new_string(volumeStr);
- json_object_object_add(pPolicyEndpointJ, "arg_volume", paramJ);
-
- json_object * pPolicyVolumeReply = NULL;
- int policyAllowed = Policy_SetVolume(pPolicyEndpointJ,&pPolicyVolumeReply);
- if (!policyAllowed)
- {
- afb_req_fail_f(req, "Audio policy violation", "Set volume not allowed by policy in current context for endpoint_id:%d type:%d",endpointID,endpointType);
- return;
- }
-
- err = wrap_json_unpack(pPolicyVolumeReply,"{s:i}","volume",&pEndpointInfo->iVolume);
- if (err) {
- afb_req_fail_f(req, "Invalid policy reply", "Policy volume change reply for endpoint_id:%d type:%d not a valid JSON object=%s", endpointID,endpointType,json_object_get_string(pPolicyVolumeReply));
- return;
- }
-#else
- // Simulate that policy returns target state (accepted)
- pEndpointInfo->iVolume = atoi(volumeStr);
-#endif
- }
-
- json_object * volumeJ = json_object_new_int(pEndpointInfo->iVolume);
-
- afb_req_success(req, volumeJ, "Set/get volume completed");
-}
-
-PUBLIC void audiohlapi_get_endpoint_info(struct afb_req req)
-{
- json_object *queryJ = NULL;
- endpointID_t endpointID = AHL_UNDEFINED;
- char * pEndpointTypeStr = NULL;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:i}", "endpoint_type", &pEndpointTypeStr,"endpoint_id",&endpointID);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
- endpointType = EndpointTypeToEnum(pEndpointTypeStr);
-
- EndpointInfoT * pEndpointInfo = GetEndpointInfo(endpointID,endpointType);
- if (pEndpointInfo == NULL)
- {
- afb_req_fail_f(req, "Endpoint not found", "Endpoint information not found for id:%d type%d",endpointID,endpointType);
- return;
- }
-
- json_object *endpointInfoJ = NULL;
- EndpointInfoToJSON(pEndpointInfo,&endpointInfoJ);
-
- afb_req_success(req, endpointInfoJ, "Retrieved endpoint information and properties");
-}
-
-PUBLIC void audiohlapi_property(struct afb_req req)
-{
- json_object *queryJ = NULL;
- endpointID_t endpointID = AHL_UNDEFINED;
- char * pEndpointTypeStr = NULL;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
- char * propertyName = NULL;
- json_object * propValueJ = NULL;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:i,s:s,s?o}", "endpoint_type", &pEndpointTypeStr,"endpoint_id",&endpointID,"property_name",&propertyName,"value",&propValueJ);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
- endpointType = EndpointTypeToEnum(pEndpointTypeStr);
-
- EndpointInfoT * pEndpointInfo = GetEndpointInfo(endpointID,endpointType);
- if (pEndpointInfo == NULL)
- {
- afb_req_fail_f(req, "Endpoint not found", "Endpoint information not found for id:%d type:%d",endpointID,endpointType);
- return;
- }
-
- if (propValueJ != NULL) {
- #ifndef AHL_DISCONNECT_POLICY
- json_object *pPolicyEndpointJ = NULL;
- err = EndpointInfoToJSON(pEndpointInfo, &pPolicyEndpointJ);
- if (err == AHL_POLICY_UTIL_FAIL)
- {
- afb_req_fail_f(req, "JSON packaging error", "Unable to create endpoint JSON object for Policy_SetProperty for endpoint_id:%d type:%d",endpointID,endpointType);
- return;
- }
-
- json_object *paramJ= json_object_new_string(propertyName);
- json_object_object_add(pPolicyEndpointJ, "arg_property_name", paramJ);
- json_object_object_add(pPolicyEndpointJ, "arg_property_value", propValueJ);
-
- // Call policy to allow custom policy actions in current context
- json_object * pPropertyReply = NULL;
- int policyAllowed = Policy_SetProperty(pPolicyEndpointJ,&pPropertyReply);
- if (!policyAllowed)
- {
- afb_req_fail_f(req, "Policy violation", "Policy rejected set property control in current context for endpointID: %d type:%d",endpointID,endpointType);
- return;
- }
-
- json_object * pPropReplyValue = NULL;
- err = wrap_json_unpack(pPropertyReply,"{s:o}","value",&pPropReplyValue);
- if (err) {
- afb_req_fail_f(req, "JSON parse error", "Policy returned property value for endpointID:%d type:%d not a valid JSON object=%s", endpointID,endpointType,json_object_get_string(pPropertyReply));
- return;
- }
- if (pEndpointInfo->pPropTable && pPropReplyValue) {
- json_object_get(pPropReplyValue);
- g_hash_table_insert(pEndpointInfo->pPropTable, propertyName, pPropReplyValue);
- }
- #else
- // Simulate that policy returns target state (accepted)
- if (pEndpointInfo->pPropTable && propValueJ)
- json_object_get(propValueJ);
- g_hash_table_insert(pEndpointInfo->pPropTable, propertyName, propValueJ);
- #endif
- }
-
- // Retrieve cached property value
- json_object * propertyValJ = (json_object *)g_hash_table_lookup(pEndpointInfo->pPropTable,propertyName);
- if (propertyValJ == NULL) {
- afb_req_fail_f(req, "Property information not found", "Property information not found for property:%s endpointID:%d type:%d",propertyName,endpointID,endpointType);
- return;
- }
-
- json_object_get(propertyValJ); // Increase ref count so that framework does not free our JSON object
-
- afb_req_success(req, propertyValJ, "Set/get property completed");
-}
-
-PUBLIC void audiohlapi_get_list_actions(struct afb_req req)
-{
- json_object *queryJ = NULL;
- char * audioRole = NULL;
- json_object * roleActionsJ = NULL;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s}", "audio_role",&audioRole);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- // Build and return list of actions for specific audio role
- RoleInfoT * pRole = GetRole(audioRole);
- if ( pRole == NULL )
- {
- afb_req_fail_f(req, "Invalid audio role", "Audio role was not found in configuration -> %s",audioRole);
- return;
- }
-
- roleActionsJ = json_object_new_array();
- if (pRole->pActionList) {
- int iNumberActions = pRole->pActionList->len;
- for ( int i = 0 ; i < iNumberActions; i++)
- {
- char * pActionName = g_ptr_array_index(pRole->pActionList,i);
- json_object * actionJ = json_object_new_string(pActionName);
- json_object_array_add(roleActionsJ, actionJ);
- }
- }
-
- afb_req_success(req, roleActionsJ, "Retrieved action list for audio role");
-}
-
-PUBLIC void audiohlapi_post_action(struct afb_req req)
-{
- json_object *queryJ = NULL;
- char * actionName = NULL;
- char * audioRole = NULL;
- char * mediaName = NULL;
- json_object *actionContext = NULL;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:s,s:s,s?s,s?o}", "action_name", &actionName,"audio_role",&audioRole,"media_name",&mediaName,"action_context",&actionContext);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- // Verify if known action for audio role
- RoleInfoT * pRole = GetRole(audioRole);
- if ( pRole == NULL )
- {
- afb_req_fail_f(req, "Invalid audio role", "Audio role was not found in configuration -> %s",audioRole);
- return;
- }
-
- // Check to find specific action
- int iActionFound = 0;
- if (pRole->pActionList) {
- int iNumberActions = pRole->pActionList->len;
- char * pTargetActionName = NULL;
- for ( int i = 0 ; i < iNumberActions; i++)
- {
- pTargetActionName = g_ptr_array_index(pRole->pActionList,i);
- if ( strcasecmp(pTargetActionName,actionName)==0) {
- iActionFound = 1;
- break;
- }
- }
- }
-
- if (!iActionFound) {
- afb_req_fail_f(req, "Action not found for audio role", "Action -> %s not found for role:%s",actionName,audioRole);
- return;
- }
-
- // Disable this to avoid problems (temporary solution)
-// #ifndef AHL_DISCONNECT_POLICY
-// // Call policy to allow custom policy actions in current context (e.g. cancel playback)
-// json_object * pActionInfo = NULL;
-// err = wrap_json_pack(&pActionInfo, "{s:s,s:s,s?s,s?o}", "action_name", &actionName,"audio_role",&audioRole,"media_name",&mediaName,"action_context",&actionContext);
-// if (err) {
-// afb_req_fail_f(req, "Invalid arguments", "Could not create action JSON object arguments");
-// return;
-// }
-// json_object_get(pActionInfo);
-// int policyAllowed = Policy_PostAction(pActionInfo);
-// if (!policyAllowed)
-// {
-// afb_req_fail_f(req, "Audio policy violation", "Post sound action not allowed by policy in current context for action:%s and audiorole:%s",actionName,audioRole);
-// return;
-// }
-// #endif
-
- afb_req_success(req, NULL, "Posted sound action");
- }
-
-PUBLIC void audiohlapi_event_subscription(struct afb_req req)
-{
- json_object *queryJ = NULL;
- json_object * eventArrayJ = NULL;
- int iSubscribe = 1;
-
- queryJ = afb_req_json(req);
- int err = wrap_json_unpack(queryJ, "{s:o,s:i}", "events", &eventArrayJ,"subscribe",&iSubscribe);
- if (err) {
- afb_req_fail_f(req, "Invalid arguments", "Args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- json_type jType = json_object_get_type(eventArrayJ);
- int iNumEvents = 0;
- if(jType == json_type_array)
- {
- iNumEvents = json_object_array_length(eventArrayJ);
- }
- for (int i = 0; i < iNumEvents; i++)
- {
- char * pEventName = NULL;
- json_object * jEvent = json_object_array_get_idx(eventArrayJ,i);
- pEventName = (char *)json_object_get_string(jEvent);
- if(pEventName == NULL) {
- afb_req_fail(req, "JSON arguments parse error", "Empty event");
- return;
- }
- else if(!strcasecmp(pEventName, AHL_ENDPOINT_PROPERTY_EVENT)) {
- if (iSubscribe)
- afb_req_subscribe(req, g_AHLCtx.policyCtx.propertyEvent);
- else
- afb_req_unsubscribe(req, g_AHLCtx.policyCtx.propertyEvent);
- }
- else if(!strcasecmp(pEventName, AHL_ENDPOINT_VOLUME_EVENT)) {
- if (iSubscribe)
- afb_req_subscribe(req, g_AHLCtx.policyCtx.volumeEvent);
- else
- afb_req_unsubscribe(req, g_AHLCtx.policyCtx.volumeEvent);
- }
- else if(!strcasecmp(pEventName, AHL_POST_ACTION_EVENT)) {
- if (iSubscribe)
- afb_req_subscribe(req, g_AHLCtx.policyCtx.postActionEvent);
- else
- afb_req_unsubscribe(req, g_AHLCtx.policyCtx.postActionEvent);
- }
- else {
- afb_req_fail_f(req, "JSON arguments parse error", "Invalid event:%s",pEventName);
- return;
- }
- }
-
- afb_req_success(req, NULL, "Event subscription update finished");
-}
-
-// Since the policy is currently in the same binding, it cannot raise events on its own
-// This is a first step toward isolation, when policy is migrated in its own binding it can simply raise AGL events
-// This binding will register for these policy events and will execute the code below upon event reception
-PUBLIC void audiohlapi_raise_event(json_object * pEventDataJ)
-{
- char * pEventName = NULL;
-
- int err = wrap_json_unpack(pEventDataJ,"{s:s}","event_name", &pEventName);
- if(err)
- {
- AFB_ERROR("Unable to retrieve event name %s",json_object_get_string(pEventDataJ));
- return;
- }
-
- if(strcasecmp(pEventName, AHL_ENDPOINT_PROPERTY_EVENT)==0) {
- char * pAudioRole = NULL;
- char * pPropertyName = NULL;
- endpointID_t endpointID = AHL_UNDEFINED;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
- json_object * propValueJ = NULL;
- int err = wrap_json_unpack(pEventDataJ,"{s:i,s:i,s:s,s:o,s:s}",
- "endpoint_id", &endpointID,
- "endpoint_type", &endpointType,
- "property_name", &pPropertyName,
- "value",&propValueJ,
- "audio_role", &pAudioRole);
- if(err)
- {
- AFB_ERROR("Unable to unpack property event for event: %s",pEventName);
- return;
- }
- RoleInfoT * pRole = GetRole(pAudioRole);
- if ( pRole == NULL ){
- AFB_ERROR("Requested audio role does not exist in current configuration -> %s", pAudioRole);
- return;
- }
- EndpointInfoT * pEndpointInfo = GetEndpointInfoWithRole(endpointID,endpointType,pRole);
- // update property value
- if ((pEndpointInfo!=NULL) && (pEndpointInfo->pPropTable!=NULL))
- {
- json_type jType = json_object_get_type(propValueJ);
- switch (jType) {
- case json_type_double:
- g_hash_table_insert(pEndpointInfo->pPropTable, pPropertyName, json_object_new_double(json_object_get_double(propValueJ)));
- break;
- case json_type_int:
- g_hash_table_insert(pEndpointInfo->pPropTable, pPropertyName, json_object_new_int(json_object_get_int(propValueJ)));
- break;
- case json_type_string:
- g_hash_table_insert(pEndpointInfo->pPropTable, pPropertyName, json_object_new_string(json_object_get_string(propValueJ)));
- break;
- default:
- AFB_ERROR("Invalid property argument property value not a valid JSON object query=%s", json_object_get_string(propValueJ));
- return ;
- }
- }
- // Remove event name from object
- json_object_object_del(pEventDataJ,"event_name");
- afb_event_push(g_AHLCtx.policyCtx.propertyEvent,pEventDataJ);
- }
- else if(strcasecmp(pEventName, AHL_ENDPOINT_VOLUME_EVENT)==0) {
- char * pAudioRole = NULL;
- endpointID_t endpointID = AHL_UNDEFINED;
- EndpointTypeT endpointType = ENDPOINTTYPE_MAXVALUE;
- int iVolume = 0;
- int err = wrap_json_unpack(pEventDataJ,"{s:i,s:i,s:i,s:s}",
- "endpoint_id", &endpointID,
- "endpoint_type", &endpointType,
- "value",&iVolume,
- "audio_role", &pAudioRole);
- if(err)
- {
- AFB_ERROR("Unable to unpack volume event data");
- return;
- }
- RoleInfoT * pRole = GetRole(pAudioRole);
- if ( pRole == NULL ){
- AFB_ERROR("Requested audio role does not exist in current configuration -> %s", pAudioRole);
- return;
- }
- EndpointInfoT * pEndpointInfo = GetEndpointInfoWithRole(endpointID,endpointType,pRole);
- // update volume value
- if(pEndpointInfo)
- {
- pEndpointInfo->iVolume = iVolume;
- }
- else
- {
- AFB_ERROR("Unable to find endpoint id:%d type:%d for role:%s",endpointID,endpointType,pAudioRole);
- }
- // Remove event name from object
- json_object_object_del(pEventDataJ,"event_name");
- afb_event_push(g_AHLCtx.policyCtx.volumeEvent,pEventDataJ);
- }
- else if(strcasecmp(pEventName, AHL_POST_ACTION_EVENT)==0) {
- // Remove event name from object
- json_object_object_del(pEventDataJ,"event_name");
- // BUG: This crashes...
- afb_event_push(g_AHLCtx.policyCtx.postActionEvent,pEventDataJ);
- }
- else if(strcasecmp(pEventName, AHL_STREAM_STATE_EVENT)==0) {
- streamID_t streamID = AHL_UNDEFINED;
- StreamEventT streamEvent = STREAM_EVENT_MAXVALUE;
- int err = wrap_json_unpack(pEventDataJ,"{s:i,s:i}",
- "stream_id", &streamID,
- "state_event", &streamEvent);
- if(err)
- {
- AFB_ERROR("Unable to unpack stream event data for event %s",pEventName);
- return;
- }
-
- StreamInfoT * pStreamInfo = GetStream(streamID);
- if (pStreamInfo == NULL) {
- AFB_ERROR("Specified stream not currently active stream_id -> %d",streamID);
- return;
- }
-
- // update streamstate value
- switch (streamEvent) {
- case STREAM_EVENT_START:
- pStreamInfo->streamState = STREAM_STATE_RUNNING;
- break;
- case STREAM_EVENT_STOP:
- pStreamInfo->streamState = STREAM_STATE_IDLE;
- break;
- case STREAM_EVENT_PAUSE:
- pStreamInfo->streamState = STREAM_STATE_PAUSED;
- break;
- case STREAM_EVENT_RESUME:
- pStreamInfo->streamState = STREAM_STATE_RUNNING;
- break;
- case STREAM_EVENT_MUTED:
- pStreamInfo->streamMute = STREAM_MUTED;
- break;
- case STREAM_EVENT_UNMUTED:
- pStreamInfo->streamMute = STREAM_UNMUTED;
- break;
- default:
- AFB_ERROR("Unknown stream event");
- }
-
- // Remove event name from object
- json_object_object_del(pEventDataJ,"event_name");
- afb_event_push(pStreamInfo->streamStateEvent,pEventDataJ);
- }
- else {
- AFB_ERROR("Unknown event name %s",pEventName);
- }
-} \ No newline at end of file