123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- /*
- * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
- * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
- *
- * 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
- */
- #ifndef __PJ_SOCK_QOS_H__
- #define __PJ_SOCK_QOS_H__
- /**
- * @file sock_qos.h
- * @brief Socket QoS API
- */
- #include <pj/sock.h>
- PJ_BEGIN_DECL
- /**
- * @defgroup socket_qos Socket Quality of Service (QoS) API: TOS, DSCP, WMM, IEEE 802.1p
- * @ingroup PJ_SOCK
- * @{
- \section intro QoS Technologies
- QoS settings are available for both Layer 2 and 3 of TCP/IP protocols:
- \subsection intro_ieee8021p 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).
- \subsection intro_wmm 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.
- \subsection intro_dscp 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 2474, 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.
- \subsection intro_other Layer 3: Other
- Other mechanisms exist (such as RSVP, IntServ) but this will not be
- implemented.
- \section availability QoS Availability
- \subsection linux 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.
- \subsection windows 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.
- \subsection symbian 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. Internally, PJLIB sets the
- DSCP field of the socket, and based on certain DSCP values mapping,
- Symbian will set the WMM tag accordingly.
- \section api PJLIB's QoS API Abstraction
- Based on the above, the following API is implemented.
- Declare the following "standard" traffic types.
- \code
- 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_SIGNALLING
- } pj_qos_type;
- \endcode
- 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:
- \code
- =================================================================
- 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
- SIGNALLING 0x28 VI (Video) 5
- =================================================================
- \endcode
- There are two sets of API provided to manipulate the QoS parameters.
- \subsection portable_api Portable API
- The first set of API is:
- \code
- // 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);
- \endcode
- 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.
- \subsection detail_api 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:
- \code
- typedef enum pj_qos_flag
- {
- PJ_QOS_PARAM_HAS_DSCP = 1,
- PJ_QOS_PARAM_HAS_SO_PRIO = 2,
- PJ_QOS_PARAM_HAS_WMM = 4
- } pj_qos_flag;
- typedef enum pj_qos_wmm_prio
- {
- PJ_QOS_WMM_PRIO_BULK_EFFORT,
- PJ_QOS_WMM_PRIO_BULK,
- PJ_QOS_WMM_PRIO_VIDEO,
- PJ_QOS_WMM_PRIO_VOICE
- } 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; // The 6 bits DSCP value to set
- pj_uint8_t so_prio; // SO_PRIORITY value
- pj_qos_wmm_prio wmm_prio; // WMM priority value
- } pj_qos_params;
- \endcode
- The second set of API with more fine-grained control over the parameters
- are:
- \code
- // 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);
- \endcode
- 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.
- */
- /**
- * High level traffic classification.
- */
- typedef enum pj_qos_type
- {
- PJ_QOS_TYPE_BEST_EFFORT, /**< Best effort traffic (default value).
- Any QoS function calls with specifying
- this value are effectively no-op */
- PJ_QOS_TYPE_BACKGROUND, /**< Background traffic. */
- PJ_QOS_TYPE_VIDEO, /**< Video traffic. */
- PJ_QOS_TYPE_VOICE, /**< Voice traffic. */
- PJ_QOS_TYPE_CONTROL, /**< Control traffic. */
- PJ_QOS_TYPE_SIGNALLING /**< Signalling traffic. */
- } pj_qos_type;
- /**
- * Bitmask flag to indicate which QoS layer setting is set in the
- * \a flags field of the #pj_qos_params structure.
- */
- typedef enum pj_qos_flag
- {
- PJ_QOS_PARAM_HAS_DSCP = 1, /**< DSCP field is set. */
- PJ_QOS_PARAM_HAS_SO_PRIO = 2, /**< Socket SO_PRIORITY */
- PJ_QOS_PARAM_HAS_WMM = 4 /**< WMM field is set. */
- } pj_qos_flag;
- /**
- * Standard WMM priorities.
- */
- typedef enum pj_qos_wmm_prio
- {
- PJ_QOS_WMM_PRIO_BULK_EFFORT, /**< Bulk effort priority */
- PJ_QOS_WMM_PRIO_BULK, /**< Bulk priority. */
- PJ_QOS_WMM_PRIO_VIDEO, /**< Video priority */
- PJ_QOS_WMM_PRIO_VOICE /**< Voice priority */
- } pj_qos_wmm_prio;
- /**
- * QoS parameters to be set or retrieved to/from the socket.
- */
- typedef struct pj_qos_params
- {
- pj_uint8_t flags; /**< Determines which values to
- set, bitmask of pj_qos_flag */
- pj_uint8_t dscp_val; /**< The 6 bits DSCP value to set */
- pj_uint8_t so_prio; /**< SO_PRIORITY value */
- pj_qos_wmm_prio wmm_prio; /**< WMM priority value */
- } pj_qos_params;
- /**
- * This is the high level and portable API to enable QoS on the specified
- * socket, by setting the traffic type to the specified parameter.
- *
- * @param sock The socket.
- * @param type Traffic type to be set.
- *
- * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
- * successfully set. If both Layer 2 and Layer 3 settings
- * can't be set, this function will return error.
- */
- PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
- pj_qos_type type);
- /**
- * This is the high level and portable API to get the traffic type that has
- * been set on the socket. On occasions where the Layer 2 or Layer 3 settings
- * were modified by using low level API, this function may return approximation
- * of the closest QoS type that matches the settings.
- *
- * @param sock The socket.
- * @param p_type Pointer to receive the traffic type of the socket.
- *
- * @return PJ_SUCCESS if traffic type for the socket can be obtained
- * or approximated..
- */
- PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
- pj_qos_type *p_type);
- /**
- * This is a convenience function to apply QoS to the socket, and print error
- * logging if the operations failed. Both QoS traffic type and the low level
- * QoS parameters can be applied with this function.
- *
- * @param sock The socket handle.
- * @param qos_type QoS traffic type. The QoS traffic type will be applied
- * only if the value is not PJ_QOS_TYPE_BEST_EFFORT,
- * @param qos_params Optional low-level QoS parameters. This will be
- * applied only if this argument is not NULL and the
- * flags inside the structure is non-zero. Upon return,
- * the flags will indicate which parameters have been
- * applied successfully.
- * @param log_level This function will print to log at this level upon
- * encountering errors.
- * @param log_sender Optional sender name in the log.
- * @param sock_name Optional name to help identify the socket in the log.
- *
- * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is
- * successfully set. If both Layer 2 and Layer 3 settings
- * can't be set, this function will return error.
- *
- * @see pj_sock_apply_qos2()
- */
- PJ_DECL(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);
- /**
- * Variant of #pj_sock_apply_qos() where the \a qos_params parameter is
- * const.
- *
- * @see pj_sock_apply_qos()
- */
- PJ_DECL(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);
- /**
- * Retrieve the standard mapping of QoS params for the specified traffic
- * type.
- *
- * @param type The traffic type from which the QoS parameters
- * are to be retrieved.
- * @param p_param Pointer to receive the QoS parameters.
- *
- * @return PJ_SUCCESS on success or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type,
- pj_qos_params *p_param);
- /**
- * Retrieve the traffic type that matches the specified QoS parameters.
- * If no exact matching is found, this function will return an
- * approximation of the closest matching traffic type for the specified
- * QoS parameters.
- *
- * @param param Structure containing QoS parameters to map into
- * "standard" traffic types.
- * @param p_type Pointer to receive the traffic type.
- *
- * @return PJ_SUCCESS on success or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pj_qos_get_type(const pj_qos_params *param,
- pj_qos_type *p_type);
- /**
- * This is a low level API to set QoS parameters to the socket.
- *
- * @param sock The socket.
- * @param param Structure containing QoS parameters to be applied
- * to the socket. Upon return, the \a flags field
- * of this structure will be set with bitmask value
- * indicating which QoS settings have successfully
- * been applied to the socket.
- *
- * @return PJ_SUCCESS if at least one field setting has been
- * successfully set. If no setting can't be set,
- * this function will return error.
- */
- PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
- pj_qos_params *param);
- /**
- * This is a low level API to get QoS parameters from the socket.
- *
- * @param sock The socket.
- * @param p_param Pointer to receive the parameters. Upon returning
- * successfully, the \a flags field of this structure
- * will be initialized with the appropriate bitmask
- * to indicate which fields have been successfully
- * retrieved.
- *
- * @return PJ_SUCCESS on success or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
- pj_qos_params *p_param);
- /**
- * @}
- */
- PJ_END_DECL
- #endif /* __PJ_SOCK_QOS_H__ */
|