1
/* $Id: sock_qos.h 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#ifndef __PJ_SOCK_QOS_H__
21
#define __PJ_SOCK_QOS_H__
25
* @brief Socket QoS API
34
* @defgroup socket_qos Socket Quality of Service (QoS) API: TOS, DSCP, WMM, IEEE 802.1p
39
\section intro QoS Technologies
41
QoS settings are available for both Layer 2 and 3 of TCP/IP protocols:
43
\subsection intro_ieee8021p Layer 2: IEEE 802.1p for Ethernet
45
IEEE 802.1p tagging will mark frames sent by a host for prioritized
46
delivery using a 3-bit Priority field in the virtual local area network
47
(VLAN) header of the Ethernet frame. The VLAN header is placed inside
48
the Ethernet header, between the Source Address field and either the
49
Length field (for an IEEE 802.3 frame) or the EtherType field (for an
52
\subsection intro_wmm Layer 2: WMM
54
At the Network Interface layer for IEEE 802.11 wireless, the Wi-Fi
55
Alliance certification for Wi-Fi Multimedia (WMM) defines four access
56
categories for prioritizing network traffic. These access categories
57
are (in order of highest to lowest priority) voice, video, best-effort,
58
and background. Host support for WMM prioritization requires that both
59
wireless network adapters and their drivers support WMM. Wireless
60
access points (APs) must have WMM enabled.
62
\subsection intro_dscp Layer 3: DSCP
64
At the Internet layer, you can use Differentiated Services/Diffserv and
65
set the value of the Differentiated Services Code Point (DSCP) in the
66
IP header. As defined in RFC 2474, the DSCP value is the high-order 6 bits
67
of the IP version 4 (IPv4) TOS field and the IP version 6 (IPv6) Traffic
70
\subsection intro_other Layer 3: Other
72
Other mechanisms exist (such as RSVP, IntServ) but this will not be
76
\section availability QoS Availability
78
\subsection linux Linux
80
DSCP is available via IP TOS option.
82
Ethernet 802.1p tagging is done by setting setsockopt(SO_PRIORITY) option
83
of the socket, then with the set_egress_map option of the vconfig utility
84
to convert this to set vlan-qos field of the packet.
86
WMM is not known to be available.
88
\subsection windows Windows and Windows Mobile
92
DSCP is settable with setsockopt() on Windows 2000 or older, but Windows
93
would silently ignore this call on WinXP or later, unless administrator
94
modifies the registry. On Windows 2000, Windows XP, and Windows Server
95
2003, GQoS (Generic QoS) API is the standard API, but this API may not be
96
supported in the future. On Vista and Windows 7, the is a new QoS2 API,
97
also known as Quality Windows Audio-Video Experience (qWAVE).
99
IEEE 802.1p tagging is available via Traffic Control (TC) API, available
100
on Windows XP SP2, but this needs administrator access. For Vista and
101
later, it's in qWAVE.
103
WMM is available for mobile platforms on Windows Mobile 6 platform and
104
Windows Embedded CE 6, via setsockopt(IP_DSCP_TRAFFIC_TYPE). qWAVE
105
supports this as well.
107
\subsection symbian Symbian S60 3rd Ed
109
Both DSCP and WMM is supported via RSocket::SetOpt() with will set both
110
Layer 2 and Layer 3 QoS settings accordingly. Internally, PJLIB sets the
111
DSCP field of the socket, and based on certain DSCP values mapping,
112
Symbian will set the WMM tag accordingly.
114
\section api PJLIB's QoS API Abstraction
116
Based on the above, the following API is implemented.
118
Declare the following "standard" traffic types.
121
typedef enum pj_qos_type
123
PJ_QOS_TYPE_BEST_EFFORT,
124
PJ_QOS_TYPE_BACKGROUND,
131
The traffic classes above will determine how the Layer 2 and 3 QoS
132
settings will be used. The standard mapping between the classes above
133
to the corresponding Layer 2 and 3 settings are as follows:
136
=================================================================
137
PJLIB Traffic Type IP DSCP WMM 802.1p
138
-----------------------------------------------------------------
139
BEST_EFFORT 0x00 BE (Bulk Effort) 0
140
BACKGROUND 0x08 BK (Bulk) 2
141
VIDEO 0x28 VI (Video) 5
142
VOICE 0x30 VO (Voice) 6
143
CONTROL 0x38 VO (Voice) 7
144
=================================================================
147
There are two sets of API provided to manipulate the QoS parameters.
149
\subsection portable_api Portable API
151
The first set of API is:
154
// Set QoS parameters
155
PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
158
// Get QoS parameters
159
PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
163
The API will set the traffic type according to the DSCP class, for both
164
Layer 2 and Layer 3 QoS settings, where it's available. If any of the
165
layer QoS setting is not settable, the API will silently ignore it.
166
If both layers are not setable, the API will return error.
168
The API above is the recommended use of QoS, since it is the most
169
portable across all platforms.
171
\subsection detail_api Fine Grained Control API
173
The second set of API is intended for application that wants to fine
174
tune the QoS parameters.
176
The Layer 2 and 3 QoS parameters are stored in pj_qos_params structure:
179
typedef enum pj_qos_flag
181
PJ_QOS_PARAM_HAS_DSCP = 1,
182
PJ_QOS_PARAM_HAS_SO_PRIO = 2,
183
PJ_QOS_PARAM_HAS_WMM = 4
186
typedef enum pj_qos_wmm_prio
188
PJ_QOS_WMM_PRIO_BULK_EFFORT,
189
PJ_QOS_WMM_PRIO_BULK,
190
PJ_QOS_WMM_PRIO_VIDEO,
191
PJ_QOS_WMM_PRIO_VOICE
194
typedef struct pj_qos_params
196
pj_uint8_t flags; // Determines which values to
197
// set, bitmask of pj_qos_flag
198
pj_uint8_t dscp_val; // The 6 bits DSCP value to set
199
pj_uint8_t so_prio; // SO_PRIORITY value
200
pj_qos_wmm_prio wmm_prio; // WMM priority value
204
The second set of API with more fine-grained control over the parameters
208
// Retrieve QoS params for the specified traffic type
209
PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type,
212
// Set QoS parameters to the socket
213
PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
214
const pj_qos_params *p);
216
// Get QoS parameters from the socket
217
PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
224
The pj_sock_set/get_qos_params() APIs are not portable, and it's probably
225
only going to be implemented on Linux. Application should always try to
226
use pj_sock_set_qos_type() instead.
231
* High level traffic classification.
233
typedef enum pj_qos_type
235
PJ_QOS_TYPE_BEST_EFFORT, /**< Best effort traffic (default value).
236
Any QoS function calls with specifying
237
this value are effectively no-op */
238
PJ_QOS_TYPE_BACKGROUND, /**< Background traffic. */
239
PJ_QOS_TYPE_VIDEO, /**< Video traffic. */
240
PJ_QOS_TYPE_VOICE, /**< Voice traffic. */
241
PJ_QOS_TYPE_CONTROL /**< Control traffic. */
245
* Bitmask flag to indicate which QoS layer setting is set in the
246
* \a flags field of the #pj_qos_params structure.
248
typedef enum pj_qos_flag
250
PJ_QOS_PARAM_HAS_DSCP = 1, /**< DSCP field is set. */
251
PJ_QOS_PARAM_HAS_SO_PRIO = 2, /**< Socket SO_PRIORITY */
252
PJ_QOS_PARAM_HAS_WMM = 4 /**< WMM field is set. */
257
* Standard WMM priorities.
259
typedef enum pj_qos_wmm_prio
261
PJ_QOS_WMM_PRIO_BULK_EFFORT, /**< Bulk effort priority */
262
PJ_QOS_WMM_PRIO_BULK, /**< Bulk priority. */
263
PJ_QOS_WMM_PRIO_VIDEO, /**< Video priority */
264
PJ_QOS_WMM_PRIO_VOICE /**< Voice priority */
269
* QoS parameters to be set or retrieved to/from the socket.
271
typedef struct pj_qos_params
273
pj_uint8_t flags; /**< Determines which values to
274
set, bitmask of pj_qos_flag */
275
pj_uint8_t dscp_val; /**< The 6 bits DSCP value to set */
276
pj_uint8_t so_prio; /**< SO_PRIORITY value */
277
pj_qos_wmm_prio wmm_prio; /**< WMM priority value */
283
* This is the high level and portable API to enable QoS on the specified
284
* socket, by setting the traffic type to the specified parameter.
286
* @param sock The socket.
287
* @param type Traffic type to be set.
289
* @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
290
* successfully set. If both Layer 2 and Layer 3 settings
291
* can't be set, this function will return error.
293
PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
297
* This is the high level and portable API to get the traffic type that has
298
* been set on the socket. On occasions where the Layer 2 or Layer 3 settings
299
* were modified by using low level API, this function may return approximation
300
* of the closest QoS type that matches the settings.
302
* @param sock The socket.
303
* @param p_type Pointer to receive the traffic type of the socket.
305
* @return PJ_SUCCESS if traffic type for the socket can be obtained
308
PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
309
pj_qos_type *p_type);
313
* This is a convenience function to apply QoS to the socket, and print error
314
* logging if the operations failed. Both QoS traffic type and the low level
315
* QoS parameters can be applied with this function.
317
* @param sock The socket handle.
318
* @param qos_type QoS traffic type. The QoS traffic type will be applied
319
* only if the value is not PJ_QOS_TYPE_BEST_EFFORT,
320
* @param qos_params Optional low-level QoS parameters. This will be
321
* applied only if this argument is not NULL and the
322
* flags inside the structure is non-zero. Upon return,
323
* the flags will indicate which parameters have been
324
* applied successfully.
325
* @param log_level This function will print to log at this level upon
326
* encountering errors.
327
* @param log_sender Optional sender name in the log.
328
* @param sock_name Optional name to help identify the socket in the log.
330
* @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
331
* successfully set. If both Layer 2 and Layer 3 settings
332
* can't be set, this function will return error.
334
* @see pj_sock_apply_qos2()
336
PJ_DECL(pj_status_t) pj_sock_apply_qos(pj_sock_t sock,
337
pj_qos_type qos_type,
338
pj_qos_params *qos_params,
340
const char *log_sender,
341
const char *sock_name);
344
* Variant of #pj_sock_apply_qos() where the \a qos_params parameter is
347
* @see pj_sock_apply_qos()
349
PJ_DECL(pj_status_t) pj_sock_apply_qos2(pj_sock_t sock,
350
pj_qos_type qos_type,
351
const pj_qos_params *qos_params,
353
const char *log_sender,
354
const char *sock_name);
357
* Retrieve the standard mapping of QoS params for the specified traffic
360
* @param type The traffic type from which the QoS parameters
361
* are to be retrieved.
362
* @param p_param Pointer to receive the QoS parameters.
364
* @return PJ_SUCCESS on success or the appropriate error code.
366
PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type,
367
pj_qos_params *p_param);
371
* Retrieve the traffic type that matches the specified QoS parameters.
372
* If no exact matching is found, this function will return an
373
* approximation of the closest matching traffic type for the specified
376
* @param param Structure containing QoS parameters to map into
377
* "standard" traffic types.
378
* @param p_type Pointer to receive the traffic type.
380
* @return PJ_SUCCESS on success or the appropriate error code.
382
PJ_DECL(pj_status_t) pj_qos_get_type(const pj_qos_params *param,
383
pj_qos_type *p_type);
387
* This is a low level API to set QoS parameters to the socket.
389
* @param sock The socket.
390
* @param param Structure containing QoS parameters to be applied
391
* to the socket. Upon return, the \a flags field
392
* of this structure will be set with bitmask value
393
* indicating which QoS settings have successfully
394
* been applied to the socket.
396
* @return PJ_SUCCESS if at least one field setting has been
397
* successfully set. If no setting can't be set,
398
* this function will return error.
400
PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
401
pj_qos_params *param);
404
* This is a low level API to get QoS parameters from the socket.
406
* @param sock The socket.
407
* @param p_param Pointer to receive the parameters. Upon returning
408
* successfully, the \a flags field of this structure
409
* will be initialized with the appropriate bitmask
410
* to indicate which fields have been successfully
413
* @return PJ_SUCCESS on success or the appropriate error code.
415
PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
416
pj_qos_params *p_param);
426
#endif /* __PJ_SOCK_QOS_H__ */