/*
 * Copyright (C) 2020 iopsys Software Solutions AB
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation
 *
 *	Author: Yalu Zhang, yalu.zhang@iopsys.eu
 */

#include "servicesvoiceservicecapabilities.h"
#include "common.h"

/*************************************************************
* ENTRY METHOD
**************************************************************/
static int browseServicesVoiceServiceCapabilitiesCodecInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
	int i;
	char *inst = NULL;
	struct dm_data data = {0};

	if (codecs_num <= 0)
		init_supported_codecs();

	for (i = 0; i < codecs_num; i++) {
		inst = handle_instance_without_section(dmctx, parent_node, i+1);
		data.additional_data = (void *)&supported_codecs[i];
		if (DM_LINK_INST_OBJ(dmctx, parent_node, &data, inst) == DM_STOP)
			break;
	}

	return 0;
}

/*************************************************************
* GET & SET PARAM
**************************************************************/
static int get_ServicesVoiceServiceCapabilities_MaxLineCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	db_get_value_string("hw", "board", "VoicePorts", value);
	if ((*value)[0] == '\0')
		*value = dmstrdup("-1");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_MaxSessionsPerLine(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("2");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_MaxSessionsPerExtension(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("2");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_MaxSessionCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("4");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_NetworkConnectionModes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("SIP/2.0");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_UserConnectionModes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("FXS");
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_FacilityActions(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	int i = 0;
	char buf[1024], *pos = buf, *end = buf + sizeof(buf);

	buf[0] = 0;

	while (FacilityAction[i] && pos < end) {
		pos += snprintf(pos, end - pos, "%s,", FacilityAction[i]);
		i++;
	}

	if (buf[0] != '\0')
		buf[strlen(buf) - 1] = 0;

	*value = dmstrdup(buf);
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_MaxCallLogCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmuci_get_option_value_fallback_def("asterisk", "cdr_options", "csv_max_row", "100");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_Extensions(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("OPTIONS,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH,MESSAGE");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_URISchemes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("sip");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_TLSAuthenticationProtocols(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	// Reference to https://en.wikipedia.org/wiki/OpenSSL#Algorithms
	*value = dmstrdup("MD5,SHA-1,SHA-2");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_TLSAuthenticationKeySizes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("128,160,256");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_TLSEncryptionProtocols(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("AES,Camellia,3DES");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_TLSEncryptionKeySizes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("256,256,168");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesSIPClient_TLSKeyExchangeProtocols(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("RSA");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesPOTS_DialType(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("Tone");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesPOTS_ClipGeneration(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("1");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesPOTS_ChargingPulse(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	*value = dmstrdup("0");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesCodec_Codec(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	if (data) {
		struct dm_data *p = (struct dm_data *)data;
		struct codec_info *codec = (struct codec_info *)(p->additional_data);
		*value = dmstrdup(codec->codec);
	}
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesCodec_BitRate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	if (data) {
		struct dm_data *p = (struct dm_data *)data;
		struct codec_info *codec = (struct codec_info *)(p->additional_data);
		dmasprintf(value, "%d", codec->bit_rate);
	} else
		*value = dmstrdup("0");
	return 0;
}

static int get_ServicesVoiceServiceCapabilitiesCodec_PacketizationPeriod(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	if (data) {
		struct dm_data *p = (struct dm_data *)data;
		struct codec_info *codec = (struct codec_info *)(p->additional_data);
		*value = dmstrdup(codec->packetization_period);
	}
	return 0;
}

static int get_ServicesVoiceServiceCapabilities_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
	return get_Alias_value_by_name(refparam, ctx, data, instance, value, "Capabilities", "Capabilities_inst");
}

static int set_ServicesVoiceServiceCapabilities_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
	return set_Alias_value_by_name(refparam, ctx, data, instance, value, action, "Capabilities", "Capabilities_inst");
}

/**********************************************************************************************************************************
*                                            OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/* *** Device.Services.VoiceService.{i}.Capabilities. *** */
DMOBJ tServicesVoiceServiceCapabilitiesObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj nextdynamicobj, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"SIP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesSIPObj, NULL, NULL, BBFDM_BOTH},
{"POTS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesPOTSParams, NULL, BBFDM_BOTH},
{"Codec", &DMREAD, NULL, NULL, NULL, browseServicesVoiceServiceCapabilitiesCodecInst, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesCodecParams, NULL, BBFDM_BOTH, NULL},
{0}
};

DMLEAF tServicesVoiceServiceCapabilitiesParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"MaxLineCount", &DMREAD, DMT_INT, get_ServicesVoiceServiceCapabilities_MaxLineCount, NULL, BBFDM_BOTH},
{"MaxSessionsPerLine", &DMREAD, DMT_INT, get_ServicesVoiceServiceCapabilities_MaxSessionsPerLine, NULL, BBFDM_BOTH},
{"MaxSessionsPerExtension", &DMREAD, DMT_INT, get_ServicesVoiceServiceCapabilities_MaxSessionsPerExtension, NULL, BBFDM_BOTH},
{"MaxSessionCount", &DMREAD, DMT_INT, get_ServicesVoiceServiceCapabilities_MaxSessionCount, NULL, BBFDM_BOTH},
{"NetworkConnectionModes", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilities_NetworkConnectionModes, NULL, BBFDM_BOTH},
{"UserConnectionModes", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilities_UserConnectionModes, NULL, BBFDM_BOTH},
{"FacilityActions", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilities_FacilityActions, NULL, BBFDM_BOTH},
{"MaxCallLogCount", &DMREAD, DMT_INT, get_ServicesVoiceServiceCapabilities_MaxCallLogCount, NULL, BBFDM_BOTH},
{0}
};

/* *** Device.Services.VoiceService.{i}.Capabilities.SIP. *** */
DMOBJ tServicesVoiceServiceCapabilitiesSIPObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Client", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesSIPClientParams, NULL, BBFDM_BOTH},
{0}
};

/* *** Device.Services.VoiceService.{i}.Capabilities.SIP.Client. *** */
DMLEAF tServicesVoiceServiceCapabilitiesSIPClientParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Extensions", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_Extensions, NULL, BBFDM_BOTH},
{"URISchemes", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_URISchemes, NULL, BBFDM_BOTH},
{"TLSAuthenticationProtocols", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_TLSAuthenticationProtocols, NULL, BBFDM_BOTH},
{"TLSAuthenticationKeySizes", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_TLSAuthenticationKeySizes, NULL, BBFDM_BOTH},
{"TLSEncryptionProtocols", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_TLSEncryptionProtocols, NULL, BBFDM_BOTH},
{"TLSEncryptionKeySizes", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_TLSEncryptionKeySizes, NULL, BBFDM_BOTH},
{"TLSKeyExchangeProtocols", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesSIPClient_TLSKeyExchangeProtocols, NULL, BBFDM_BOTH},
{0}
};

/* *** Device.Services.VoiceService.{i}.Capabilities.POTS. *** */
DMLEAF tServicesVoiceServiceCapabilitiesPOTSParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"DialType", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesPOTS_DialType, NULL, BBFDM_BOTH},
{"ClipGeneration", &DMREAD, DMT_BOOL, get_ServicesVoiceServiceCapabilitiesPOTS_ClipGeneration, NULL, BBFDM_BOTH},
{"ChargingPulse", &DMREAD, DMT_BOOL, get_ServicesVoiceServiceCapabilitiesPOTS_ChargingPulse, NULL, BBFDM_BOTH},
{0}
};

/* *** Device.Services.VoiceService.{i}.Capabilities.Codec.{i}. *** */
DMLEAF tServicesVoiceServiceCapabilitiesCodecParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Codec", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesCodec_Codec, NULL, BBFDM_BOTH},
{"BitRate", &DMREAD, DMT_UNINT, get_ServicesVoiceServiceCapabilitiesCodec_BitRate, NULL, BBFDM_BOTH},
{"PacketizationPeriod", &DMREAD, DMT_STRING, get_ServicesVoiceServiceCapabilitiesCodec_PacketizationPeriod, NULL, BBFDM_BOTH},
{"Alias", &DMWRITE, DMT_STRING, get_ServicesVoiceServiceCapabilities_Alias, set_ServicesVoiceServiceCapabilities_Alias, BBFDM_BOTH},
{0}
};

