aboutsummaryrefslogtreecommitdiffstats
path: root/4a-hal-utilities/4a-hal-utilities-data.c
blob: 420354eaae2f57659c591e2f5ea9f01d90cfb579 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#######################################################################################
# Script sed for migrating from AFB_BINDING_VERSION 2 to AFB_BINDING_VERSION 3
# See http://docs.automotivelinux.org/docs/apis_services/en/dev/reference/af-binder/afb-migration-to-ibinding-v3.html
#######################################################################################
# update the version
# ------------------
s:\(\<AFB_BINDING_VERSION[[:blank:]]\{1,\}\)2\>:\13:

# update common types
# -------------------
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_req\>:afb_req_t:g
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_event\>:afb_event_t:g
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_verb_v2\>:afb_verb_t:g
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_binding_v2\>:afb_binding_t:g

# update common names
# -------------------
s:\<afbBindingV2\>:afbBindingExport:g

# very special
# ------------
s:( *afb_req_t *) *{ *NULL *, *NULL *}:NULL:g

# special dynapi
# --------------
s:\(\<AFB_BINDING_VERSION[[:blank:]]\{1,\}\)0\>:\13:
/^[[:blank:]]*# *define *\<AFB_BINDING_WANT_DYNAPI\>/d
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_dynapi\>\([[:blank:]]*\)\*:afb_api_t\2:g
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_request\>\([[:blank:]]*\)\*:afb_req_t\2:g
s:\<\(struct[[:blank:]]\{1,\}\)\{0,1\}afb_eventid\>\([[:blank:]]*\)\*:afb_event_t\2:g
s:\<afb_request_:afb_req_:g
s:\<afb_dynapi_:afb_api_:g
s:\<afb_eventid_:afb_event_:g
s:\<AFB_DYNAPI_:AFB_API_:g
s:\<AFB_REQUEST_:AFB_REQ_:g
s:\<afbBindingVdyn\>:afbBindingV3entry:g
s:\<dynapi\>:api:g
s:\<eventid\>:event:g
s:\<afb_api_make_eventid\>:afb_api_make_event:g
s:\<afb_api_new_api\>:-!&:g
s:\<afb_api_sub_verb\>:afb_api_del_verb:g

# update legacy calls
# ------------------
s:\<afb_req_subcall\(_req\)\>:afb_req_subcall_legacy:g
s:\<afb_req_subcall_sync\>:afb_req_subcall_sync_legacy:g
s:\<afb_api_call\>:afb_api_call_legacy:g
s:\<afb_api_call_sync\>:afb_api_call_sync_legacy:g
s:\<afb_req_store\>:afb_req_addref:g
s:\<afb_req_unstore\> *( *\(.*\) *):\1:g

# optional but activated by default
# ---------------------------------
s:\<afb_daemon_get_\(event_loop\|user_bus\|system_bus\)[ \t]*(:afb_api_get_\1(afbBindingV3root:g
s:\<afb_daemon_\([a-z_0-9]* *(\):afb_api_\1afbBindingV3root, :g
s:\<afb_service_call_\([a-z_0-9]*\)\( *(\):afb_api_\1_legacy\2afbBindingV3root, :g
s:\<afb_service_\([a-z_0-9]* *(\):afb_api_\1afbBindingV3root, :g
s:\<AFB_\(\(ERROR\|WARNING\|NOTICE\|INFO\|DEBUG\)\> *(\):AFB_API_\1afbBindingV3root, :g

# special app-controller
# ----------------------
s:\<_\(AFB_SYSLOG_LEVEL_[A-Z]*\)_\>:\1:g

# UNSAFES (uncomment it if optimistic)
# --------------
#s:\<afb_req_fail\(_[fv]\)\{0,1\}\>\( *([^,]*\):afb_req_reply\1\2, NULL:g
#s:\<afb_req_success\(_[fv]\)\{0,1\}\>\( *([^,]*,[^,]*\):afb_req_reply\1\2, NULL:g
#
#s:\<afb_api_add_verb\>
/*
 * Copyright (C) 2018 "IoT.bzh"
 * Author Jonathan Aillet <jonathan.aillet@iot.bzh>
 *
 * 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.
 */

#define _GNU_SOURCE

#include <stdio.h>
#include <string.h>

#include <wrap-json.h>

#include <afb/afb-binding.h>

#include "4a-hal-utilities-data.h"
#include "4a-hal-utilities-alsa-data.h"

/*******************************************************************************
 *		Specfic Hal controller streams data handling functions	       *
 ******************************************************************************/

struct CtlHalMixerData *HalUtlAddMixerDataToMixerDataList(struct CtlHalMixerData **firstMixerData)
{
	struct CtlHalMixerData *currentMixerData;

	if(! firstMixerData)
		return NULL;

	currentMixerData = *firstMixerData;

	if(! currentMixerData) {
		currentMixerData = (struct CtlHalMixerData *) calloc(1, sizeof(struct CtlHalMixerData));
		if(! currentMixerData)
			return NULL;

		*firstMixerData = currentMixerData;
	}
	else {
		while(currentMixerData->next)
			currentMixerData = currentMixerData->next;

		currentMixerData->next = calloc(1, sizeof(struct CtlHalMixerData));
		if(! currentMixerData)
			return NULL;

		currentMixerData = currentMixerData->next;
	}

	return currentMixerData;
}

int8_t HalUtlRemoveSelectedMixerData(struct CtlHalMixerData **firstMixerData, struct CtlHalMixerData *mixerDataToRemove)
{
	struct CtlHalMixerData *currentMixerData, *matchingMixerData;

	if(! firstMixerData || ! mixerDataToRemove)
		return -1;

	currentMixerData = *firstMixerData;

	if(currentMixerData == mixerDataToRemove) {
		*firstMixerData = currentMixerData->next;
		matchingMixerData = currentMixerData;
	}
	else {
		while(currentMixerData && currentMixerData->next != mixerDataToRemove)
			currentMixerData = currentMixerData->next;

		if(currentMixerData) {
			matchingMixerData = currentMixerData->next;
			currentMixerData->next = currentMixerData->next->next;
		}
		else {
			return -2;
		}
	}

	free(matchingMixerData->verb);
	free(matchingMixerData->verbToCall);
	free(matchingMixerData->streamCardId);

	free(matchingMixerData);

	return 0;
}

int64_t HalUtlRemoveAllMixerData(struct CtlHalMixerData **firstMixerData)
{
	int8_t ret;
	int64_t mixerDataRemoved = 0;

	while(*firstMixerData) {
		ret = HalUtlRemoveSelectedMixerData(firstMixerData, *firstMixerData);
		if(ret)
			return (int64_t) ret;

		mixerDataRemoved++;
	}

	return mixerDataRemoved;
}

int64_t HalUtlGetNumberOfMixerDataInList(struct CtlHalMixerData **firstMixerData)
{
	int64_t numberOfMixerData = 0;
	struct CtlHalMixerData *currentMixerData;

	if(! firstMixerData)
		return -1;

	currentMixerData = *firstMixerData;

	while(currentMixerData) {
		currentMixerData = currentMixerData->next;
		numberOfMixerData++;
	}

	return numberOfMixerData;
}

struct CtlHalMixerData *HalUtlSearchMixerDataByProperties(struct CtlHalMixerData **firstMixerData, char *verb, char *verbToCall, char *streamCardId)
{
	struct CtlHalMixerData *currentMixerData;

	if(! firstMixerData || ! verb)
		return NULL;

	currentMixerData = *firstMixerData;

	while(currentMixerData) {
		if((! strcmp(verb, currentMixerData->verb)) &&
		   (! strcmp(verbToCall, currentMixerData->verbToCall)) &&
		   (! strcmp(streamCardId, currentMixerData->streamCardId)))
			return currentMixerData;

		currentMixerData = currentMixerData->next;
	}

	return NULL;
}

/*******************************************************************************
 *		Specfic Hal data handling functions			       *
 ******************************************************************************/

struct SpecificHalData *HalUtlAddHalApiToHalList(struct SpecificHalData **firstHalData)
{
	struct SpecificHalData *currentApi;

	if(! firstHalData)
		return NULL;

	currentApi = *firstHalData;

	if(! currentApi) {
		currentApi = (struct SpecificHalData *) calloc(1, sizeof(struct SpecificHalData));
		if(! currentApi)
			return NULL;

		*firstHalData = currentApi;
	}
	else {
		while(currentApi->next)
			currentApi = currentApi->next;

		currentApi->next = calloc(1, sizeof(struct SpecificHalData));
		if(! currentApi)
			return NULL;

		currentApi = currentApi->next;
	}

	return currentApi;
}

int8_t HalUtlRemoveSelectedHalFromList(struct SpecificHalData **firstHalData, struct SpecificHalData *apiToRemove)
{
	struct SpecificHalData *currentApi, *matchingApi;

	if(! firstHalData || ! apiToRemove)
		return -1;

	currentApi = *firstHalData;

	if(currentApi == apiToRemove) {
		*firstHalData = currentApi->next;
		matchingApi = currentApi;
	}
	else {
		while(currentApi && currentApi->next != apiToRemove)
			currentApi = currentApi->next;

		if(currentApi) {
			matchingApi = currentApi->next;
			currentApi->next = currentApi->next->next;
		}
		else {
			return -2;
		}
	}

	free(matchingApi->apiName);
	free(matchingApi->sndCardPath);
	free(matchingApi->info);
	free(matchingApi->author);
	free(matchingApi->version);
	free(matchingApi->date);

	if(matchingApi->internal) {
		HalUtlRemoveAllMixerData(&matchingApi->ctlHalSpecificData->ctlHalStreamsData);
		HalUtlRemoveAllMixerData(&matchingApi->ctlHalSpecificData->ctlHalPlaybacksData);
		HalUtlRemoveAllMixerData(&matchingApi->ctlHalSpecificData->ctlHalCapturesData);

		HalUtlFreeAlsaCtlsMap(matchingApi->ctlHalSpecificData->ctlHalAlsaMapT);

		free(matchingApi->ctlHalSpecificData);
	}

	free(matchingApi);

	return 0;
}

int64_t HalUtlRemoveAllHalFromList(struct SpecificHalData **firstHalData)
{
	int8_t ret;
	int64_t CtlHalApiRemoved = 0;

	while(*firstHalData) {
		ret = HalUtlRemoveSelectedHalFromList(firstHalData, *firstHalData);
		if(ret)
			return (int64_t) ret;

		CtlHalApiRemoved++;
	}

	return CtlHalApiRemoved;
}

int64_t HalUtlGetNumberOfHalInList(struct SpecificHalData **firstHalData)
{
	int64_t numberOfCtlHal = 0;
	struct SpecificHalData *currentApi;

	if(! firstHalData)
		return -1;

	currentApi = *firstHalData;

	while(currentApi) {
		currentApi = currentApi->next;
		numberOfCtlHal++;
	}

	return numberOfCtlHal;
}

struct SpecificHalData *HalUtlSearchHalDataByApiName(struct SpecificHalData **firstHalData, char *apiName)
{
	struct SpecificHalData *currentApi;

	if(! firstHalData || ! apiName)
		return NULL;

	currentApi = *firstHalData;

	while(currentApi) {
		if(! strcmp(apiName, currentApi->apiName))
			return currentApi;

		currentApi = currentApi->next;
	}

	return NULL;
}


struct SpecificHalData *HalUtlSearchReadyHalDataByCarId(struct SpecificHalData **firstHalData, int cardId)
{
	struct SpecificHalData *currentApi;

	if(! firstHalData)
		return NULL;

	currentApi = *firstHalData;
	while(currentApi) {
		if(currentApi->status == HAL_STATUS_READY && currentApi->sndCardId == cardId)
			return currentApi;

		currentApi = currentApi->next;
	}

	return NULL;
}

/*******************************************************************************
 *		Hal Manager data handling functions			       *
 ******************************************************************************/

uint8_t HalUtlInitializeHalMgrData(afb_api_t apiHandle, struct HalMgrData *HalMgrGlobalData, char *apiName, char *info)
{
	if(! apiHandle || ! HalMgrGlobalData || ! apiName || ! info)
		return -1;

	// Allocate and fill apiName and info strings
	HalMgrGlobalData->apiName = strdup(apiName);
	if(! HalMgrGlobalData->apiName)
		return -2;

	HalMgrGlobalData->info = strdup(info);
	if(! HalMgrGlobalData->apiName)
		return -3;

	HalMgrGlobalData->apiHandle = apiHandle;

	return 0;
}

void HalUtlRemoveHalMgrData(struct HalMgrData *HalMgrGlobalData)
{
	if(! HalMgrGlobalData)
		return;

	if(HalMgrGlobalData->first)
		HalUtlRemoveAllHalFromList(&HalMgrGlobalData->first);

	free(HalMgrGlobalData->apiName);
	free(HalMgrGlobalData->info);

	free(HalMgrGlobalData);
}