summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2014-03-06 19:04:58 +0000
committerJonathan Rose <jrose@digium.com>2014-03-06 19:04:58 +0000
commitf0b8590c14d9f5b899f5edc1158ee90200ace6dc (patch)
tree063c716258cf99944cc6c5eedefda5f2a909da17 /res
parent3f730662f7906027c302896abd549a32123ec848 (diff)
pjsip configuration: Make transport TOS values consistent with endpoints
Transport TOS values were interpreted as DSCP values without being documented as such. Endpoint TOS values (tos_audio/tos_video) behaved normally as TOS values have historically. This patch makes the transport TOS values behave as TOS values and makes all TOS values readable as string values (e.g. AF11). In addition, alembic scripts have been updated to use the proper field types for all TOS/COS values. (issue ASTERISK-23235) Reported by: George Joseph Review: https://reviewboard.asterisk.org/r/3304/ ........ Merged revisions 410028 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410029 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip/config_transport.c39
-rw-r--r--res/res_pjsip/pjsip_configuration.c43
2 files changed, 78 insertions, 4 deletions
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 3c11dcc70..58d0f1577 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -121,9 +121,11 @@ static void *transport_alloc(const char *name)
static void set_qos(struct ast_sip_transport *transport, pj_qos_params *qos)
{
+ int tos_as_dscp = transport->tos >> 2;
+
if (transport->tos) {
qos->flags |= PJ_QOS_PARAM_HAS_DSCP;
- qos->dscp_val = transport->tos;
+ qos->dscp_val = tos_as_dscp;
}
if (transport->cos) {
qos->flags |= PJ_QOS_PARAM_HAS_SO_PRIO;
@@ -448,6 +450,39 @@ static int localnet_to_str(const void *obj, const intptr_t *args, char **buf)
return 0;
}
+/*! \brief Custom handler for TOS setting */
+static int transport_tos_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+ struct ast_sip_transport *transport = obj;
+ unsigned int value;
+
+ if (ast_str2tos(var->value, &value)) {
+ ast_log(LOG_ERROR, "Error configuring transport '%s' - Could not "
+ "interpret 'tos' value '%s'\n",
+ ast_sorcery_object_get_id(transport), var->value);
+ return -1;
+ }
+
+ if (value % 4) {
+ value = value >> 2;
+ value = value << 2;
+ ast_log(LOG_WARNING,
+ "transport '%s' - 'tos' value '%s' uses bits that are "
+ "discarded when converted to DSCP. Using equivalent %d instead.\n",
+ ast_sorcery_object_get_id(transport), var->value, value);
+ }
+
+ transport->tos = value;
+ return 0;
+}
+
+static int tos_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+ const struct ast_sip_transport *transport = obj;
+ ast_tos2str_buf(transport->tos, buf);
+ return 0;
+}
+
static struct ao2_container *cli_get_container(void)
{
RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
@@ -581,7 +616,7 @@ int ast_sip_initialize_sorcery_transport(void)
ast_sorcery_object_field_register_custom(sorcery, "transport", "method", "", transport_tls_method_handler, tls_method_to_str, 0, 0);
ast_sorcery_object_field_register_custom(sorcery, "transport", "cipher", "", transport_tls_cipher_handler, transport_tls_cipher_to_str, 0, 0);
ast_sorcery_object_field_register_custom(sorcery, "transport", "local_net", "", transport_localnet_handler, localnet_to_str, 0, 0);
- ast_sorcery_object_field_register(sorcery, "transport", "tos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, tos));
+ ast_sorcery_object_field_register_custom(sorcery, "transport", "tos", "0", transport_tos_handler, tos_to_str, 0, 0);
ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));
ast_sip_register_endpoint_formatter(&endpoint_transport_formatter);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index deb374e6e..994987b7a 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -758,6 +758,45 @@ static int t38udptl_ec_to_str(const void *obj, const intptr_t *args, char **buf)
return 0;
}
+static int tos_handler(const struct aco_option *opt,
+ struct ast_variable *var, void *obj)
+{
+ struct ast_sip_endpoint *endpoint = obj;
+ unsigned int value;
+
+ if (ast_str2tos(var->value, &value)) {
+ ast_log(LOG_ERROR, "Error configuring endpoint '%s' - Could not "
+ "interpret '%s' value '%s'\n",
+ ast_sorcery_object_get_id(endpoint), var->name, var->value);
+ return -1;
+ }
+
+ if (!strcmp(var->name, "tos_audio")) {
+ endpoint->media.tos_audio = value;
+ } else if (!strcmp(var->name, "tos_video")) {
+ endpoint->media.tos_video = value;
+ } else {
+ /* If we reach this point, someone called the tos_handler when they shouldn't have. */
+ ast_assert(0);
+ return -1;
+ }
+ return 0;
+}
+
+static int tos_audio_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+ const struct ast_sip_endpoint *endpoint = obj;
+ ast_tos2str_buf(endpoint->media.tos_audio, buf);
+ return 0;
+}
+
+static int tos_video_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+ const struct ast_sip_endpoint *endpoint = obj;
+ ast_tos2str_buf(endpoint->media.tos_video, buf);
+ return 0;
+}
+
static int set_var_handler(const struct aco_option *opt,
struct ast_variable *var, void *obj)
{
@@ -1586,8 +1625,8 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_transfer", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowtransfer));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_owner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpowner));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_session", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpsession));
- ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.tos_audio));
- ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.tos_video));
+ ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "tos_audio", "0", tos_handler, tos_audio_to_str, 0, 0);
+ ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "tos_video", "0", tos_handler, tos_video_to_str, 0, 0);
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.cos_audio));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.cos_video));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_subscribe", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, subscription.allow));