Version 2 (modified by bennylp, 15 years ago) (diff) |
---|
Support for QoS (TOS/DSCP, WMM, 802.1p)
Table of Contents
This article describes the QoS support in PJSIP and how to use it.
Introduction on QoS
QoS settings are available for both Layer 2 and Layer 3 of TCP/IP protocols:
Layer 2: IEEE 802.1p for Ethernet
IEEE 802.1p tagging will mark frames sent by a host for prioritized delivery using a 3-bit Priority field in the virtual local area network (VLAN) header of the Ethernet frame. The VLAN header is placed inside the Ethernet header, between the Source Address field and either the Length field (for an IEEE 802.3 frame) or the EtherType field (for an Ethernet II frame).
Layer 2: WMM
At the Network Interface layer for IEEE 802.11 wireless, the Wi-Fi Alliance certification for Wi-Fi Multimedia (WMM) defines four access categories for prioritizing network traffic. These access categories are (in order of highest to lowest priority) voice, video, best-effort, and background. Host support for WMM prioritization requires that both wireless network adapters and their drivers support WMM. Wireless access points (APs) must have WMM enabled.
Layer 3: DSCP
At the Internet layer, you can use Differentiated Services/Diffserv? and set the value of the Differentiated Services Code Point (DSCP) in the IP header. As defined in RFC 2472, the DSCP value is the high-order 6 bits of the IP version 4 (IPv4) TOS field and the IP version 6 (IPv6) Traffic Class field.
Layer 3: Other
Other mechanisms exist (such as RSVP, IntServ) but this will not be implemented.
Availability
Linux
DSCP is available via IP TOS option.
Ethernet 802.1p tagging is done by setting setsockopt(SO_PRIORITY) option of the socket, then with the set_egress_map option of the vconfig utility to convert this to set vlan-qos field of the packet.
WMM is not known to be available.
MacOS X
DSCP is available via IP TOS option.
Windows and Windows Mobile
(It's a mess!)
DSCP is settable with setsockopt() on Windows 2000 or older, but Windows would silently ignore this call on WinXP or later, unless administrator modifies the registry. On Windows 2000, Windows XP, and Windows Server 2003, GQoS (Generic QoS) API is the standard API, but this API may not be supported in the future. On Vista and Windows 7, the is a new QoS2 API, also known as Quality Windows Audio-Video Experience (qWAVE).
IEEE 802.1p tagging is available via Traffic Control (TC) API, available on Windows XP SP2, but this needs administrator access. For Vista and later, it's in qWAVE.
WMM is available for mobile platforms on Windows Mobile 6 platform and Windows Embedded CE 6, via setsockopt(IP_DSCP_TRAFFIC_TYPE). qWAVE supports this as well.
Symbian S60 3rd Ed
Both DSCP and WMM is supported via RSocket::SetOpt() with will set both Layer 2 and Layer 3 QoS settings accordingly.
Summary
The following table summarizes the availability/accessability of various QoS settings on platforms that PJSIP supports:
Win2k/older | XP, Vista, WM2003, WM5 | WM6 | Symbian S60 | Linux | MacOS X | iPhone | |
High level API | Yes | No | Yes | Yes | Yes | Yes | Yes |
API backend | qos_bsd.c | qos_dummy.c | qos_wm.c | qos_symbian.cpp | qos_bsd.c | qos_bsd.c | qos_bsd.c |
DSCP is supported | Yes | No | Yes | Yes | Yes | Yes | Yes |
DSCP is user settable | Yes | No | No | Yes | Yes | Yes | Yes |
WMM prio is supported | No | No | Yes | Yes | No | No | No |
WMM prio is user settable | No | No | No | No | No | No | No |
SO_PRIORITY is supported | No | No | No | No | Yes | Yes | Yes |
SO_PRIORITY is settable | No | No | No | No | Yes | Yes | Yes |
Objective
The objective of this ticket is to add new API to PJLIB socket API to enable manipulation of the QoS parameters above in a uniform and portable manner.
Design
Based on the above, the following API is proposed.
Declare the following "standard" traffic types.
typedef enum pj_qos_type { PJ_QOS_TYPE_BEST_EFFORT, PJ_QOS_TYPE_BACKGROUND, PJ_QOS_TYPE_VIDEO, PJ_QOS_TYPE_VOICE, PJ_QOS_TYPE_CONTROL } pj_qos_type;
The traffic classes above will determine how the Layer 2 and 3 QoS settings will be used. The standard mapping between the classes above to the corresponding Layer 2 and 3 settings are as follows:
PJLIB Traffic Type IP DSCP WMM 802.1p BEST_EFFORT 0x00 BE (Bulk Effort) 0 BACKGROUND 0x08 BK (Bulk) 2 VIDEO 0x28 VI (Video) 5 VOICE 0x30 VO (Voice) 6 CONTROL 0x38 VO (Voice) 7
There are two sets of API provided to manipulate the QoS parameters.
Portable High Level API
The first set of API is:
// Set QoS parameters PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock, pj_qos_type val); // Get QoS parameters PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock, pj_qos_type *p_val);
The API will set the traffic type according to the DSCP class, for both Layer 2 and Layer 3 QoS settings, where it's available. If any of the layer QoS setting is not settable, the API will silently ignore it. If both layers are not setable, the API will return error.
The API above is the recommended use of QoS, since it is the most portable across all platforms.
Fine Grained Control API
The second set of API is intended for application that wants to fine tune the QoS parameters.
The Layer 2 and 3 QoS parameters are stored in pj_qos_params structure:
typedef enum pj_qos_flag { PJ_QOS_PARAM_HAS_DSCP = 1, PJ_QOS_PARAM_HAS_802_1_P = 2, PJ_QOS_PARAM_HAS_WMM = 4 } pj_qos_flag; typedef enum pj_qos_wmm_prio { PJ_QOS_WMM_TYPE_BULK_EFFORT_PRIO, PJ_QOS_WMM_TYPE_BULK_PRIO, PJ_QOS_WMM_TYPE_VIDEO_PRIO, PJ_QOS_WMM_TYPE_VOICE_PRIO } pj_qos_wmm_prio; typedef struct pj_qos_params { pj_uint8_t flags; // Determines which values to // set, bitmask of pj_qos_flag pj_uint8_t dscp_val; // DSCP value to set pj_uint8_t so_prio; // SO_PRIORITY value pj_qos_wmm_prio wmm_prio; // WMM priority value } pj_qos_params;
The second set of API with more fine-grained control over the parameters are:
// Retrieve QoS params for the specified traffic type PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type, pj_qos_params *p); // Set QoS parameters to the socket PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock, const pj_qos_params *p); // Get QoS parameters from the socket PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock, pj_qos_params *p);
Important:
The pj_sock_set/get_qos_params() APIs are not portable, and it's probably only going to be implemented on Linux. Application should always try to use pj_sock_set_qos_type() instead.
Limitations
Win32 may not be implemented due to the API mess above.
References
- QoS Support in Windows - good intro for QoS on Windows and in general
- WMM (Wi-Fi Multimedia) (Windows Mobile 6)
- VoIP developer guidelines for S60
- WiFi QoS Support in Windows Vista: WMM part 2