diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2015-04-13 09:21:39 +0200 |
---|---|---|
committer | Michal Kubecek <mkubecek@suse.cz> | 2015-04-13 09:21:39 +0200 |
commit | e2bc6f4153813cc570ae814c8ddb74628009b488 (patch) | |
tree | a40b171be1d859c2232ccc94f758010f9ae54d3c /src/protocol.h | |
download | twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.gz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.lz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.xz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.zip |
initial checkin
Check in contents of upstream 1.4.2 tarball, exclude generated files.
Diffstat (limited to 'src/protocol.h')
-rw-r--r-- | src/protocol.h | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 0000000..a400a6e --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,399 @@ +/* + Copyright (C) 2005-2009 Michel de Boer <michel@twinklephone.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 +*/ + +#ifndef _PROTOCOL_H +#define _PROTOCOL_H + +#include "twinkle_config.h" +#include "parser/hdr_supported.h" + +/** Carriage Return Line Feed */ +#define CRLF "\r\n" + +/** TCP PING packet to be sent on a TCP connection. */ +#define TCP_PING_PACKET CRLF CRLF + +/** Product name */ +#define PRODUCT_NAME "Twinkle" + +/** Product version */ +#define PRODUCT_VERSION VERSION + +/** + * When a SIP message is created, some addresses will be filled in + * by the sender thread as only this thread knows the source IP + * address of an outgoing message. + * The sender thread will look for occurrences of the AUTO_IP4_ADDRESS + * and replace it with the source IP address. + */ +#define AUTO_IP4_ADDRESS "255.255.255.255" + +/** Display name for anonymous calling */ +#define ANONYMOUS_DISPLAY "Anonymous" + +/** SIP-URI for anonymous calling */ +#define ANONYMOUS_URI "sip:anonymous@anonymous.invalid" + +/** Types of failures. */ +enum t_failure { + FAIL_TIMEOUT, /**< Transaction timed out */ + FAIL_TRANSPORT /**< Transport failure */ +}; + +/** Call transfer types */ +enum t_transfer_type { + TRANSFER_BASIC, /**< Basic transfer (blind) */ + TRANSFER_CONSULT, /**< Transfer with consultation (possibly attended) */ + TRANSFER_OTHER_LINE /**< Transfer call to other line */ +}; + +/** State of a call transfer at the referrer. */ +enum t_refer_state { + REFST_NULL, /**< No REFER in progress */ + REFST_W4RESP, /**< REFER sent, waiting for response */ + REFST_W4NOTIFY, /**< Response received, waiting for 1st NOTIFY */ + REFST_PENDING, /**< REFER received, but not granted yet */ + REFST_ACTIVE, /**< Referee granted refer */ +}; + +/** Types of registration requests */ +enum t_register_type { + REG_REGISTER, + REG_QUERY, + REG_DEREGISTER, + REG_DEREGISTER_ALL +}; + +/** + * RFC 3261 Annex A + * SIP timers + */ +enum t_sip_timer { + TIMER_T1, + TIMER_T2, + TIMER_T4, + TIMER_A, + TIMER_B, + TIMER_C, + TIMER_D, + TIMER_E, + TIMER_F, + TIMER_G, + TIMER_H, + TIMER_I, + TIMER_J, + TIMER_K +}; + +// All durations are in msec +#define DURATION_T1 500 +#define DURATION_T2 4000 +#define DURATION_T4 5000 +#define DURATION_A DURATION_T1 +#define DURATION_B (64 * DURATION_T1) +#define DURATION_C 180000 +#define DURATION_D 32000 +#define DURATION_E DURATION_T1 +#define DURATION_F (64 * DURATION_T1) +#define DURATION_G DURATION_T1 +#define DURATION_H (64 * DURATION_T1) +#define DURATION_I DURATION_T4 +#define DURATION_J (64 * DURATION_T1) +#define DURATION_K DURATION_T4 + +/** Time to keep an idle connection open before closing */ +#define DUR_IDLE_CONNECTION (64 * DURATION_T1) + +/** UA (phone) timers */ +enum t_phone_timer { + PTMR_REGISTRATION, /**< Registration (failure) timeout */ + PTMR_NAT_KEEPALIVE, /**< NAT binding refresh timeout for STUN */ + PTMR_TCP_PING, /**< TCP ping interval */ +}; + +/** UA (line) timers */ +enum t_line_timer { + LTMR_ACK_TIMEOUT, /**< Waiting for ACK */ + LTMR_ACK_GUARD, /**< After this timer ACK is lost for good */ + LTMR_INVITE_COMP, /**< After this timer INVITE transiction is considered complete. */ + LTMR_NO_ANSWER, /**< This timer expires if the callee does not answer. The call will be torn down. */ + LTMR_RE_INVITE_GUARD, /**< re-INVITE timeout */ + LTMR_100REL_TIMEOUT, /**< Waiting for PRACK */ + LTMR_100REL_GUARD, /**< After this timer PRACK is lost for good */ + LTMR_GLARE_RETRY, /**< Waiting before retry re-INVITE after glare */ + LTMR_CANCEL_GUARD, /**< Guard for situation where CANCEL has been responded to, but 487 on INVITE is never received. */ +}; + +/** Subscription timers. */ +enum t_subscribe_timer { + STMR_SUBSCRIPTION, /**< Subscription timeout */ +}; + +/** Publication timers. */ +enum t_publish_timer { + PUBLISH_TMR_PUBLICATION, /**< Publication timeout */ +}; + +/** STUN timers. */ +enum t_stun_timer { + STUN_TMR_REQ_TIMEOUT, /**< Waiting for response */ +}; + + +/** No answer timer (ms) */ +#define DUR_NO_ANSWER(u) ((u)->get_timer_noanswer() * 1000) + +/** @name Registration timers */ +//@{ +/** Registration duration (seconds) */ +#define DUR_REGISTRATION(u) ((u)->get_registration_time()) + +/**< Re-register 5 seconds before expiry **/ +#define RE_REGISTER_DELTA 5 + +/** Re-registration interval after reg. failure */ +#define DUR_REG_FAILURE 30 +//@} + +/** NAT keepalive timer (s) default value */ +#define DUR_NAT_KEEPALIVE 30 + +/** Default TCP ping interval (s) */ +#define DUR_TCP_PING 30 + +/** + * re-INVITE guard timer (ms). This timer guards against the situation + * where a UAC has sent a re-INVITE, received a 1XX but never receives + * a final response. No timer for this is defined in RFC 3261 + */ +#define DUR_RE_INVITE_GUARD 10000 + +/** + * Guard for situation where CANCEL has been + * responded to, but 487 on INVITE is never eceived. + * This situation is not defined by RFC 3261 + */ +#define DUR_CANCEL_GUARD (64 * DURATION_T1) + +// MWI timers (s) +#define DUR_MWI(u) ((u)->get_mwi_subscription_time()) +#define DUR_MWI_FAILURE 30 + +// Presence timers (s) +#define DUR_PRESENCE(u) ((u)->get_pres_subscription_time()) +#define DUR_PRESENCE_FAILURE 30 + +// RFC 3261 14.1 +// Maximum values (10th of sec) for timers for retrying a re-INVITE after +// a glare (491 response). +#define MAX_GLARE_RETRY_NOT_OWN 20 +#define MAX_GLARE_RETRY_OWN 40 + +// Calculate the glare retry duration (ms) +#define DUR_GLARE_RETRY_NOT_OWN ((rand() % (MAX_GLARE_RETRY_NOT_OWN + 1)) * 100) +#define DUR_GLARE_RETRY_OWN ((rand() % (MAX_GLARE_RETRY_OWN - \ + MAX_GLARE_RETRY_NOT_OWN) + 1 + MAX_GLARE_RETRY_NOT_OWN)\ + * 100) + +// RFC 3262 +// PRACK timers +#define DUR_100REL_TIMEOUT DURATION_T1 +#define DUR_100REL_GUARD (64 * DURATION_T1) + +// refer subscription timer (s) +// RFC 3515 does not define the length of the timer. +// It should be long enough to notify the result of an INVITE. +#define DUR_REFER_SUBSCRIPTION 60 // Used when refer is always permitted +#define DUR_REFER_SUB_INTERACT 90 // Used when user has to grant permission + +// Minimum duration of a subscription +#define MIN_DUR_SUBSCRIPTION 60 + +// Duration to wait before re-subscribing after termination of +// a subscription +#define DUR_RESUBSCRIBE 30 + +// After an unsubscribe has been sent, a NOTIFY will should come in. +// In case the NOTIFY does not come, this guard timer (ms) will assure +// that the subscription will be cleaned up. +#define DUR_UNSUBSCRIBE_GUARD 4000 + +// RFC 3489 +// STUN retransmission timer intervals (ms) +// The RFC states that the interval should start at 100ms. But that +// seems to short. We start at 200 and do 8 instead of 9 transmissions. +#define DUR_STUN_START_INTVAL 200 +#define DUR_STUN_MAX_INTVAL 1600 + +// Maximum number of transmissions +#define STUN_MAX_TRANSMISSIONS 8 + +// RFC 3261 +#ifndef RFC3261_COOKIE +#define RFC3261_COOKIE "z9hG4bK" +#endif + +// Max forwards RFC 3261 8.1.1.6 +#define MAX_FORWARDS 70 + +// Length of tags in from and to headers +#define TAG_LEN 5 + +// Create a new tag +#define NEW_TAG random_token(TAG_LEN) + +// Length of call-id (before domain) +#define CALL_ID_LEN 15 + +// Create a new call-id +#define NEW_CALL_ID(u) (random_token(CALL_ID_LEN) + '@' + LOCAL_HOSTNAME) + +// Create a new sequence number fo CSeq header +#define NEW_SEQNR rand() % 1000 + 1 + +// Length of cnonce +#define CNONCE_LEN 10 + +// Create a cnonce +#define NEW_CNONCE random_hexstr(CNONCE_LEN) + +/** Length of tuple id in PIDF documents. */ +#define PIDF_TUPLE_ID_LEN 6 + +/** Create a new PIDF tuple id. */ +#define NEW_PIDF_TUPLE_ID random_token(PIDF_TUPLE_ID_LEN) + +/** Character set encoding for outgoing text messages */ +#define MSG_TEXT_CHARSET "utf-8" + +/** @name Definitions for akav1-md5 authentication. */ +#define AKA_RANDLEN 16 +#define AKA_AUTNLEN 16 +#define AKA_CKLEN 16 +#define AKA_IKLEN 16 +#define AKA_AKLEN 6 +#define AKA_OPLEN 16 +#define AKA_RESLEN 8 +#define AKA_SQNLEN 6 +#define AKA_RESHEXLEN 16 +#define AKA_AMFLEN 2 +#define AKA_KLEN 16 + +// Set Allow header with methods that can be handled by the phone +#define SET_HDR_ALLOW(h, u) { (h).add_method(INVITE); \ + (h).add_method(ACK); \ + (h).add_method(BYE); \ + (h).add_method(CANCEL); \ + (h).add_method(OPTIONS); \ + if ((u)->get_ext_100rel() != EXT_DISABLED) {\ + (h).add_method(PRACK);\ + }\ + (h).add_method(REFER); \ + (h).add_method(NOTIFY); \ + (h).add_method(SUBSCRIBE); \ + (h).add_method(INFO); \ + (h).add_method(MESSAGE); \ + } + +// Set Supported header with supported extensions +#define SET_HDR_SUPPORTED(h, u) { if ((u)->get_ext_replaces()) {\ + (h).add_feature(EXT_REPLACES);\ + }\ + (h).add_feature(EXT_NOREFERSUB);\ + } + +// Set Accept header with accepted body types +#define SET_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ + "sdp")); } + +/** + * Check if the content type of an instant message is supported + * @param h [in] A SIP message. + */ +#define MESSAGE_CONTENT_TYPE_SUPPORTED(h)\ + ((h).hdr_content_type.media.type == "application" ||\ + (h).hdr_content_type.media.type == "audio" ||\ + (h).hdr_content_type.media.type == "image" ||\ + (h).hdr_content_type.media.type == "text" ||\ + (h).hdr_content_type.media.type == "video") + +/** + * Set Accept header with accepted body types for instant messaging. + * @param h [inout] A SIP message. + */ +#define SET_MESSAGE_HDR_ACCEPT(h) { (h).add_media(t_media("application/*"));\ + (h).add_media(t_media("audio/*"));\ + (h).add_media(t_media("image/*"));\ + (h).add_media(t_media("text/*"));\ + (h).add_media(t_media("video/*")); } + +/** + * Set Accept header with accepted body types for presence. + * @param h [inout] A SIP message. + */ +#define SET_PRESENCE_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ + "pidf+xml")); } + +/** + * Set Accept header with accepted body types for MWI. + * @param h [inout] A SIP message. + */ +#define SET_MWI_HDR_ACCEPT(h) { (h).add_media(t_media("application",\ + "simple-message-summary")); } + +/** + * Set Accept-Encoding header with accepted encodings. + * @param h [inout] A SIP message. + */ +#define SET_HDR_ACCEPT_ENCODING(h)\ + { (h).add_coding(t_coding("identity")); } + +/** + * Check if content encoding is supported + * @param h [inout] A SIP message. + */ +#define CONTENT_ENCODING_SUPPORTED(ce)\ + (cmp_nocase(ce, "identity") == 0) + +// Set Accept-Language header with accepted languages +#define SET_HDR_ACCEPT_LANGUAGE(h)\ + { (h).add_language(t_language("en")); } + +// Set User-Agent header +#define SET_HDR_USER_AGENT(h) { (h).add_server(t_server(PRODUCT_NAME,\ + PRODUCT_VERSION)); } + +// Set Server header +#define SET_HDR_SERVER(h) { (h).add_server(t_server(PRODUCT_NAME,\ + PRODUCT_VERSION)); } + +// Set Organization header +#define SET_HDR_ORGANIZATION(h, u) { if ((u)->get_organization() != "") {\ + (h).set_name((u)->get_organization()); }} + +// Check if an event is supported by Twinkle +#define SIP_EVENT_SUPPORTED(e) ((e) == SIP_EVENT_REFER ||\ + (e) == SIP_EVENT_MSG_SUMMARY ||\ + (e) == SIP_EVENT_PRESENCE) + +// Add the supported events to the Allow-Events header +#define ADD_SUPPORTED_SIP_EVENTS(h) { (h).add_event_type(SIP_EVENT_REFER);\ + (h).add_event_type(SIP_EVENT_MSG_SUMMARY);\ + (h).add_event_type(SIP_EVENT_PRESENCE); } + +#endif |