summaryrefslogtreecommitdiff
path: root/pjlib/src/pj
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-10-25 09:02:07 +0000
committerBenny Prijono <bennylp@teluu.com>2009-10-25 09:02:07 +0000
commitfdc0f2ecdb18b9176f87f55ee17f054ce107e8c7 (patch)
tree768b9507e60426fcabcc8b4ce2540ae727cf7ffa /pjlib/src/pj
parent2053af19e76b9c13e8bdebb13669cf915dc49981 (diff)
Initial commit for ticket #950: QoS support:
- implementation: - PJLIB (sock_qos*.*) - added QoS support in: - SIP UDP transport, - SIP TCP transport, - media UDP transport (done in pjsua-lib), - pjnath ICE stream transport, - pjnath STUN socket, - pjnath TURN client - added QoS options in pjsua-lib: - QoS fields in pjsua_transport_config - added "--set-qos" parameter in pjsua Notes: - QoS in TLS transport is not yet implemented, waiting for #957 - build ok on VS6, VS2005 (multiple targets), Carbide, and Mingw - no run-time testing yet git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2966 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj')
-rw-r--r--pjlib/src/pj/sock_bsd.c14
-rw-r--r--pjlib/src/pj/sock_common.c5
-rw-r--r--pjlib/src/pj/sock_qos_bsd.c130
-rw-r--r--pjlib/src/pj/sock_qos_common.c154
-rw-r--r--pjlib/src/pj/sock_qos_dummy.c76
-rw-r--r--pjlib/src/pj/sock_qos_symbian.cpp91
-rw-r--r--pjlib/src/pj/sock_qos_wm.c103
-rw-r--r--pjlib/src/pj/sock_symbian.cpp1
8 files changed, 570 insertions, 4 deletions
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
index 6cf24fe2..36761bce 100644
--- a/pjlib/src/pj/sock_bsd.c
+++ b/pjlib/src/pj/sock_bsd.c
@@ -63,7 +63,7 @@ const pj_uint16_t PJ_SOL_IP = SOL_IP;
#elif defined(PJ_WIN32) && PJ_WIN32
const pj_uint16_t PJ_SOL_IP = IPPROTO_IP;
#else
-const pj_uint16_t PJ_SOL_IP = 0xFFFF;
+const pj_uint16_t PJ_SOL_IP = 0;
#endif /* SOL_IP */
#if defined(SOL_TCP)
@@ -73,7 +73,7 @@ const pj_uint16_t PJ_SOL_TCP = IPPROTO_TCP;
#elif defined(PJ_WIN32) && PJ_WIN32
const pj_uint16_t PJ_SOL_TCP = IPPROTO_TCP;
#else
-const pj_uint16_t PJ_SOL_TCP = 0xFFFF;
+const pj_uint16_t PJ_SOL_TCP = 6;
#endif /* SOL_TCP */
#ifdef SOL_UDP
@@ -83,7 +83,7 @@ const pj_uint16_t PJ_SOL_UDP = IPPROTO_UDP;
#elif defined(PJ_WIN32) && PJ_WIN32
const pj_uint16_t PJ_SOL_UDP = IPPROTO_UDP;
#else
-const pj_uint16_t PJ_SOL_UDP = 0xFFFF;
+const pj_uint16_t PJ_SOL_UDP = 17;
#endif /* SOL_UDP */
#ifdef SOL_IPV6
@@ -95,7 +95,7 @@ const pj_uint16_t PJ_SOL_IPV6 = SOL_IPV6;
const pj_uint16_t PJ_SOL_IPV6 = 41;
# endif
#else
-const pj_uint16_t PJ_SOL_IPV6 = 0xFFFF;
+const pj_uint16_t PJ_SOL_IPV6 = 41;
#endif /* SOL_IPV6 */
/* IP_TOS */
@@ -135,6 +135,12 @@ const pj_uint16_t PJ_SO_RCVBUF = SO_RCVBUF;
const pj_uint16_t PJ_SO_SNDBUF = SO_SNDBUF;
const pj_uint16_t PJ_TCP_NODELAY= TCP_NODELAY;
const pj_uint16_t PJ_SO_REUSEADDR= SO_REUSEADDR;
+#if defined(SO_PRIORITY)
+const pj_uint16_t PJ_SO_PRIORITY = SO_PRIORITY;
+#else
+/* This is from Linux, YMMV */
+const pj_uint16_t PJ_SO_PRIORITY = 12;
+#endif
/* Multicasting is not supported e.g. in PocketPC 2003 SDK */
#ifdef IP_MULTICAST_IF
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 0e098c48..64fc9d47 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -1072,6 +1072,11 @@ PJ_DEF(pj_uint16_t) pj_SO_REUSEADDR(void)
return PJ_SO_REUSEADDR;
}
+PJ_DEF(pj_uint16_t) pj_SO_PRIORITY(void)
+{
+ return PJ_SO_PRIORITY;
+}
+
PJ_DEF(pj_uint16_t) pj_IP_MULTICAST_IF(void)
{
return PJ_IP_MULTICAST_IF;
diff --git a/pjlib/src/pj/sock_qos_bsd.c b/pjlib/src/pj/sock_qos_bsd.c
new file mode 100644
index 00000000..32b2828e
--- /dev/null
+++ b/pjlib/src/pj/sock_qos_bsd.c
@@ -0,0 +1,130 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/sock_qos.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+
+/* This is the implementation of QoS with BSD socket's setsockopt(),
+ * using IP_TOS and SO_PRIORITY
+ */
+#if !defined(PJ_QOS_IMPLEMENTATION) || PJ_QOS_IMPLEMENTATION==PJ_QOS_BSD
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ pj_qos_params *param)
+{
+ pj_status_t last_err = PJ_ENOTSUP;
+ pj_status_t status;
+
+ /* No op? */
+ if (!param->flags)
+ return PJ_SUCCESS;
+
+ /* Clear WMM field since we don't support it */
+ param->flags &= ~(PJ_QOS_PARAM_HAS_WMM);
+
+ /* Set TOS/DSCP */
+ if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+ int val = param->dscp_val;
+ status = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
+ &val, sizeof(val));
+ if (status != PJ_SUCCESS) {
+ param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
+ last_err = status;
+ }
+ }
+
+ /* Set SO_PRIORITY */
+ if (param->flags & PJ_QOS_PARAM_HAS_802_1_P) {
+ int val = param->so_prio;
+ status = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),
+ &val, sizeof(val));
+ if (status != PJ_SUCCESS) {
+ param->flags &= ~(PJ_QOS_PARAM_HAS_802_1_P);
+ last_err = status;
+ }
+ }
+
+ return param->flags ? PJ_SUCCESS : last_err;
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type type)
+{
+ pj_qos_params param;
+ pj_status_t status;
+
+ status = pj_qos_get_params(type, &param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return pj_sock_set_qos_params(sock, &param);
+}
+
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p_param)
+{
+ pj_status_t last_err = PJ_ENOTSUP;
+ int val, optlen;
+ pj_status_t status;
+
+ pj_bzero(p_param, sizeof(*p_param));
+
+ /* Get DSCP/TOS value */
+ optlen = sizeof(val);
+ status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
+ &val, &optlen);
+ if (status == PJ_SUCCESS) {
+ p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
+ p_param->dscp_val = (pj_uint8_t)val;
+ } else {
+ last_err = status;
+ }
+
+ /* Get SO_PRIORITY */
+ optlen = sizeof(val);
+ status = pj_sock_getsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),
+ &val, &optlen);
+ if (status == PJ_SUCCESS) {
+ p_param->flags |= PJ_QOS_PARAM_HAS_802_1_P;
+ p_param->so_prio = (pj_uint8_t)val;
+ } else {
+ last_err = status;
+ }
+
+ /* WMM is not supported */
+
+ return p_param->flags ? PJ_SUCCESS : last_err;
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_type)
+{
+ pj_qos_params param;
+ pj_status_t status;
+
+ status = pj_sock_get_qos_params(sock, &param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return pj_qos_get_type(&param, p_type);
+}
+
+#endif /* PJ_QOS_IMPLEMENTATION */
diff --git a/pjlib/src/pj/sock_qos_common.c b/pjlib/src/pj/sock_qos_common.c
new file mode 100644
index 00000000..a59b606b
--- /dev/null
+++ b/pjlib/src/pj/sock_qos_common.c
@@ -0,0 +1,154 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/sock_qos.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/string.h>
+
+#define THIS_FILE "sock_qos_common.c"
+#define ALL_FLAGS (PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_802_1_P | \
+ PJ_QOS_PARAM_HAS_WMM)
+
+/* "Standard" mapping between traffic type and QoS params */
+static const pj_qos_params qos_map[] =
+{
+ /* flags dscp prio wmm_prio */
+ {ALL_FLAGS, 0x00, 0, PJ_QOS_WMM_PRIO_BULK_EFFORT}, /* BE */
+ {ALL_FLAGS, 0x08, 2, PJ_QOS_WMM_PRIO_BULK}, /* BK */
+ {ALL_FLAGS, 0x28, 5, PJ_QOS_WMM_PRIO_VIDEO}, /* VI */
+ {ALL_FLAGS, 0x30, 6, PJ_QOS_WMM_PRIO_VOICE}, /* VO */
+ {ALL_FLAGS, 0x38, 7, PJ_QOS_WMM_PRIO_VOICE} /* CO */
+};
+
+
+/* Retrieve the mapping for the specified type */
+PJ_DEF(pj_status_t) pj_qos_get_params(pj_qos_type type,
+ pj_qos_params *p_param)
+{
+ PJ_ASSERT_RETURN(type<=PJ_QOS_TYPE_CONTROL && p_param, PJ_EINVAL);
+ pj_memcpy(p_param, &qos_map[type], sizeof(*p_param));
+ return PJ_SUCCESS;
+}
+
+/* Get the matching traffic type */
+PJ_DEF(pj_status_t) pj_qos_get_type( const pj_qos_params *param,
+ pj_qos_type *p_type)
+{
+ unsigned dscp_type = PJ_QOS_TYPE_BEST_EFFORT,
+ prio_type = PJ_QOS_TYPE_BEST_EFFORT,
+ wmm_type = PJ_QOS_TYPE_BEST_EFFORT;
+ unsigned i, count=0;
+
+ PJ_ASSERT_RETURN(param && p_type, PJ_EINVAL);
+
+ if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+ for (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {
+ if (param->dscp_val >= qos_map[i].dscp_val)
+ dscp_type = (pj_qos_type)i;
+ }
+ ++count;
+ }
+
+ if (param->flags & PJ_QOS_PARAM_HAS_802_1_P) {
+ for (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {
+ if (param->so_prio >= qos_map[i].so_prio)
+ prio_type = (pj_qos_type)i;
+ }
+ ++count;
+ }
+
+ if (param->flags & PJ_QOS_PARAM_HAS_WMM) {
+ for (i=0; i<=PJ_QOS_TYPE_CONTROL; ++i) {
+ if (param->wmm_prio >= qos_map[i].wmm_prio)
+ wmm_type = (pj_qos_type)i;
+ }
+ ++count;
+ }
+
+ if (count)
+ *p_type = (pj_qos_type)((dscp_type + prio_type + wmm_type) / count);
+ else
+ *p_type = PJ_QOS_TYPE_BEST_EFFORT;
+
+ return PJ_SUCCESS;
+}
+
+/* Apply QoS */
+PJ_DEF(pj_status_t) pj_sock_apply_qos( pj_sock_t sock,
+ pj_qos_type qos_type,
+ pj_qos_params *qos_params,
+ unsigned log_level,
+ const char *log_sender,
+ const char *sock_name)
+{
+ char fmt[60];
+ pj_status_t qos_type_rc = PJ_SUCCESS,
+ qos_params_rc = PJ_SUCCESS;
+
+ if (!log_sender)
+ log_sender = THIS_FILE;
+ if (!sock_name)
+ sock_name = "socket";
+
+ if (qos_type != PJ_QOS_TYPE_BEST_EFFORT) {
+ qos_type_rc = pj_sock_set_qos_type(sock, qos_type);
+
+ if (qos_type_rc != PJ_SUCCESS) {
+ pj_ansi_snprintf(fmt, sizeof(fmt),
+ "Error setting QoS type %d to %s",
+ qos_type, sock_name);
+ pj_perror(log_level, log_sender, qos_type_rc, fmt, 0);
+ }
+ }
+
+ if (qos_params && qos_params->flags) {
+ qos_params_rc = pj_sock_set_qos_params(sock, qos_params);
+ if (qos_params_rc != PJ_SUCCESS) {
+ pj_ansi_snprintf(fmt, sizeof(fmt),
+ "Error setting QoS params (flags=%d) to %s",
+ qos_params->flags, sock_name);
+ pj_perror(log_level, log_sender, qos_params_rc, fmt, 0);
+ if (qos_type_rc != PJ_SUCCESS)
+ return qos_params_rc;
+ }
+ } else if (qos_type_rc != PJ_SUCCESS)
+ return qos_type_rc;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_sock_apply_qos2( pj_sock_t sock,
+ pj_qos_type qos_type,
+ const pj_qos_params *qos_params,
+ unsigned log_level,
+ const char *log_sender,
+ const char *sock_name)
+{
+ pj_qos_params qos_params_buf, *qos_params_copy = NULL;
+
+ if (qos_params) {
+ pj_memcpy(&qos_params_buf, qos_params, sizeof(*qos_params));
+ qos_params_copy = &qos_params_buf;
+ }
+
+ return pj_sock_apply_qos(sock, qos_type, qos_params_copy,
+ log_level, log_sender, sock_name);
+}
diff --git a/pjlib/src/pj/sock_qos_dummy.c b/pjlib/src/pj/sock_qos_dummy.c
new file mode 100644
index 00000000..946b26bc
--- /dev/null
+++ b/pjlib/src/pj/sock_qos_dummy.c
@@ -0,0 +1,76 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/sock_qos.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+
+/* Dummy implementation of QoS API.
+ * (this is controlled by pjlib's config.h)
+ */
+#if defined(PJ_QOS_IMPLEMENTATION) && PJ_QOS_IMPLEMENTATION==PJ_QOS_DUMMY
+
+#define THIS_FILE "sock_qos_dummy.c"
+
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ pj_qos_params *param)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(param);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_set_qos_params() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type type)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(type);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_set_qos_type() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p_param)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(p_param);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_get_qos_params() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_type)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(p_type);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_get_qos_type() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+#endif /* PJ_QOS_DUMMY */
diff --git a/pjlib/src/pj/sock_qos_symbian.cpp b/pjlib/src/pj/sock_qos_symbian.cpp
new file mode 100644
index 00000000..59912ece
--- /dev/null
+++ b/pjlib/src/pj/sock_qos_symbian.cpp
@@ -0,0 +1,91 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/sock_qos.h>
+#include "os_symbian.h"
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ pj_qos_params *param)
+{
+ CPjSocket *pjsock = (CPjSocket*)sock;
+ RSocket & rsock = pjsock->Socket();
+ pj_status_t last_err = PJ_ENOTSUP;
+
+ /* SO_PRIORITY and WMM are not supported */
+ param->flags &= ~(PJ_QOS_PARAM_HAS_802_1_P | PJ_QOS_PARAM_HAS_WMM);
+
+ if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+ TInt err;
+
+ err = rsock.SetOpt(KSoIpTOS, KProtocolInetIp,
+ (param->dscp_val << 2));
+ if (err != KErrNone) {
+ last_err = PJ_RETURN_OS_ERROR(err);
+ param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
+ }
+ }
+
+ return param->flags ? PJ_SUCCESS : last_err;
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type type)
+{
+ pj_qos_params param;
+ pj_status_t status;
+
+ status = pj_qos_get_params(type, &param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return pj_sock_set_qos_params(sock, &param);
+}
+
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p_param)
+{
+ CPjSocket *pjsock = (CPjSocket*)sock;
+ RSocket & rsock = pjsock->Socket();
+ TInt err, dscp;
+
+ pj_bzero(p_param, sizeof(*p_param));
+
+ err = rsock.GetOpt(KSoIpTOS, KProtocolInetIp, dscp);
+ if (err == KErrNone) {
+ p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
+ p_param->dscp_val = (dscp >> 2);
+ return PJ_SUCCESS;
+ } else {
+ return PJ_RETURN_OS_ERROR(err);
+ }
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_type)
+{
+ pj_qos_params param;
+ pj_status_t status;
+
+ status = pj_sock_get_qos_params(sock, &param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return pj_qos_get_type(&param, p_type);
+}
+
diff --git a/pjlib/src/pj/sock_qos_wm.c b/pjlib/src/pj/sock_qos_wm.c
new file mode 100644
index 00000000..ecdf2ed2
--- /dev/null
+++ b/pjlib/src/pj/sock_qos_wm.c
@@ -0,0 +1,103 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/sock_qos.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+
+#include <winsock.h>
+
+/* QoS implementation for Windows Mobile 6, must be enabled explicitly
+ * (this is controlled by pjlib's config.h)
+ */
+#if defined(PJ_QOS_IMPLEMENTATION) && PJ_QOS_IMPLEMENTATION==PJ_QOS_WM
+
+#define THIS_FILE "sock_qos_wm.c"
+
+/* Mapping between our traffic type and WM's DSCP traffic types */
+static const int dscp_map[] =
+{
+ DSCPBestEffort,
+ DSCPBackground,
+ DSCPVideo,
+ DSCPAudio,
+ DSCPControl
+};
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+ pj_qos_params *param)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(param);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_set_qos_params() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+ pj_qos_type type)
+{
+ int value;
+
+ PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(dscp_map), PJ_EINVAL);
+
+ value = dscp_map[type];
+ return pj_sock_setsockopt(sock, IPPROTO_IP, IP_DSCP_TRAFFIC_TYPE,
+ &value, sizeof(value));
+}
+
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+ pj_qos_params *p_param)
+{
+ PJ_UNUSED_ARG(sock);
+ PJ_UNUSED_ARG(p_param);
+
+ PJ_LOG(4,(THIS_FILE, "pj_sock_get_qos_params() is not implemented "
+ "for this platform"));
+ return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+ pj_qos_type *p_type)
+{
+ pj_status_t status;
+ int value, optlen;
+ unsigned i;
+
+ optlen = sizeof(value);
+ value = 0;
+ status = pj_sock_getsockopt(sock, IPPROTO_IP, IP_DSCP_TRAFFIC_TYPE,
+ &value, &optlen);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ *p_type = PJ_QOS_TYPE_BEST_EFFORT;
+ for (i=0; i<PJ_ARRAY_SIZE(dscp_map); ++i) {
+ if (value == dscp_map[i]) {
+ *p_type = (pj_qos_type)i;
+ break;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJ_QOS_IMPLEMENTATION */
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index 138ee867..b1697642 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -64,6 +64,7 @@ const pj_uint16_t PJ_IPTOS_MINCOST = 0;
/* Misc */
const pj_uint16_t PJ_TCP_NODELAY = 0xFFFF;
const pj_uint16_t PJ_SO_REUSEADDR = 0xFFFF;
+const pj_uint16_t PJ_SO_PRIORITY = 0xFFFF;
/* ioctl() is also not supported. */
const pj_uint16_t PJ_SO_TYPE = 0xFFFF;