blob: fbd7335868071f3e137171048357a32f3772c13a [file] [log] [blame]
Benny Prijono4d79b0f2009-10-25 09:02:07 +00001/* $Id$ */
2/*
3 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/sock_qos.h>
20#include <pj/assert.h>
21#include <pj/errno.h>
22#include <pj/string.h>
23
24/* This is the implementation of QoS with BSD socket's setsockopt(),
25 * using IP_TOS and SO_PRIORITY
26 */
27#if !defined(PJ_QOS_IMPLEMENTATION) || PJ_QOS_IMPLEMENTATION==PJ_QOS_BSD
28
29PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
30 pj_qos_params *param)
31{
32 pj_status_t last_err = PJ_ENOTSUP;
33 pj_status_t status;
34
35 /* No op? */
36 if (!param->flags)
37 return PJ_SUCCESS;
38
39 /* Clear WMM field since we don't support it */
40 param->flags &= ~(PJ_QOS_PARAM_HAS_WMM);
41
42 /* Set TOS/DSCP */
43 if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
Benny Prijono610973a2009-10-25 10:50:17 +000044 /* Value is dscp_val << 2 */
45 int val = (param->dscp_val << 2);
Benny Prijono4d79b0f2009-10-25 09:02:07 +000046 status = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
47 &val, sizeof(val));
48 if (status != PJ_SUCCESS) {
49 param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
50 last_err = status;
51 }
52 }
53
54 /* Set SO_PRIORITY */
Benny Prijono610973a2009-10-25 10:50:17 +000055 if (param->flags & PJ_QOS_PARAM_HAS_SO_PRIO) {
Benny Prijono4d79b0f2009-10-25 09:02:07 +000056 int val = param->so_prio;
57 status = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),
58 &val, sizeof(val));
59 if (status != PJ_SUCCESS) {
Benny Prijono610973a2009-10-25 10:50:17 +000060 param->flags &= ~(PJ_QOS_PARAM_HAS_SO_PRIO);
Benny Prijono4d79b0f2009-10-25 09:02:07 +000061 last_err = status;
62 }
63 }
64
65 return param->flags ? PJ_SUCCESS : last_err;
66}
67
68PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
69 pj_qos_type type)
70{
71 pj_qos_params param;
72 pj_status_t status;
73
74 status = pj_qos_get_params(type, &param);
75 if (status != PJ_SUCCESS)
76 return status;
77
78 return pj_sock_set_qos_params(sock, &param);
79}
80
81
82PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
83 pj_qos_params *p_param)
84{
85 pj_status_t last_err = PJ_ENOTSUP;
86 int val, optlen;
87 pj_status_t status;
88
89 pj_bzero(p_param, sizeof(*p_param));
90
91 /* Get DSCP/TOS value */
92 optlen = sizeof(val);
93 status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
94 &val, &optlen);
95 if (status == PJ_SUCCESS) {
96 p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
Benny Prijono610973a2009-10-25 10:50:17 +000097 p_param->dscp_val = (pj_uint8_t)(val >> 2);
Benny Prijono4d79b0f2009-10-25 09:02:07 +000098 } else {
99 last_err = status;
100 }
101
102 /* Get SO_PRIORITY */
103 optlen = sizeof(val);
104 status = pj_sock_getsockopt(sock, pj_SOL_SOCKET(), pj_SO_PRIORITY(),
105 &val, &optlen);
106 if (status == PJ_SUCCESS) {
Benny Prijono610973a2009-10-25 10:50:17 +0000107 p_param->flags |= PJ_QOS_PARAM_HAS_SO_PRIO;
Benny Prijono4d79b0f2009-10-25 09:02:07 +0000108 p_param->so_prio = (pj_uint8_t)val;
109 } else {
110 last_err = status;
111 }
112
113 /* WMM is not supported */
114
115 return p_param->flags ? PJ_SUCCESS : last_err;
116}
117
118PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
119 pj_qos_type *p_type)
120{
121 pj_qos_params param;
122 pj_status_t status;
123
124 status = pj_sock_get_qos_params(sock, &param);
125 if (status != PJ_SUCCESS)
126 return status;
127
128 return pj_qos_get_type(&param, p_type);
129}
130
131#endif /* PJ_QOS_IMPLEMENTATION */
Benny Prijono610973a2009-10-25 10:50:17 +0000132