/*
Copyright (C) 2005-2007 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"
#define CRLF "\r\n"
// Name and version of the softphone
#define PRODUCT_NAME "Twinkle"
#define PRODUCT_VERSION VERSION
// Anonymous calling
#define ANONYMOUS_DISPLAY "Anonymous"
#define ANONYMOUS_URI "sip:anonymous@anonymous.invalid"
// 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
/** UA (phone) timers */
enum t_phone_timer {
PTMR_REGISTRATION, /**< Registration (failure) timeout */
PTMR_NAT_KEEPALIVE, /**< NAT binding refresh timeout for STUN */
};
/** 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)
// Registration timers (s)
// Registration duration (seconds)
#define DUR_REGISTRATION(u) ((u)->get_registration_time())
#define RE_REGISTER_DELTA 5 // Re-register 5 seconds before expiry
#define DUR_REG_FAILURE 30 // Re-registration interval after reg. failure
// NAT keepalive timer (s) default value
#define DUR_NAT_KEEPALIVE 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) + '@' + USER_HOST(u))
// 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"
// 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")); }
/** Set Accept header with accepted body types for messaging. */
#define SET_MESSAGE_HDR_ACCEPT(h) { (h).add_media(t_media("text", "plain"));\
(h).add_media(t_media("text", "html")); }
/** Set Accept header with accepted body types for presence. */
#define SET_PRESENCE_HDR_ACCEPT(h) { (h).add_media(t_media("application",\
"pidf+xml")); }
/** Set Accept header with accepted body types for MWI. */
#define SET_MWI_HDR_ACCEPT(h) { (h).add_media(t_media("application",\
"simple-message-summary")); }
/** Set Accept-Encoding header with accepted encodings. */
#define SET_HDR_ACCEPT_ENCODING(h)\
{ (h).add_coding(t_coding("identity")); }
/** Check if content encoding is supported */
#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
syntax highlighted by Code2HTML, v. 0.9.1