summaryrefslogtreecommitdiffstats
path: root/src/phone.h
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2015-04-13 09:21:39 +0200
committerMichal Kubecek <mkubecek@suse.cz>2015-04-13 09:21:39 +0200
commite2bc6f4153813cc570ae814c8ddb74628009b488 (patch)
treea40b171be1d859c2232ccc94f758010f9ae54d3c /src/phone.h
downloadtwinkle-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/phone.h')
-rw-r--r--src/phone.h707
1 files changed, 707 insertions, 0 deletions
diff --git a/src/phone.h b/src/phone.h
new file mode 100644
index 0000000..2a08936
--- /dev/null
+++ b/src/phone.h
@@ -0,0 +1,707 @@
+/*
+ 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 _PHONE_H
+#define _PHONE_H
+
+#include <list>
+#include <string>
+#include <vector>
+#include <sys/time.h>
+#include "auth.h"
+#include "call_history.h"
+#include "dialog.h"
+#include "id_object.h"
+#include "phone_user.h"
+#include "protocol.h"
+#include "service.h"
+#include "transaction_layer.h"
+#include "im/msg_session.h"
+#include "mwi/mwi.h"
+#include "sockets/url.h"
+#include "parser/request.h"
+#include "parser/response.h"
+#include "presence/presence_state.h"
+
+// Number of phone lines
+// One line is used by Twinkle internally to park the call towards a
+// referrer while the refer is in progress.
+// Besides the lines for making calls, ephemeral lines will be created
+// for parking calls that are being released. By parking a releasing
+// call, the line visible to the user is free for making new calls.
+#define NUM_CALL_LINES 3 // Total numbers of phone lines for making calls
+#define NUM_USER_LINES 2 // #lines usable for the user
+
+#define LINENO_REFERRER 2 // Internal lineno for referrer
+
+// Number of seconds to wait till all lines are idle when terminating
+// Twinkle
+#define QUIT_IDLE_WAIT 2
+
+using namespace std;
+using namespace im;
+
+// Forward declarations
+class t_dialog;
+class t_client_request;
+class t_line;
+class t_call_info;
+
+enum t_phone_state {
+ PS_IDLE,
+ PS_BUSY
+};
+
+enum t_line_state {
+ LS_IDLE,
+ LS_BUSY
+};
+
+enum t_line_substate {
+ // Idle sub states
+ LSSUB_IDLE, // line is idle
+ LSSUB_SEIZED, // user has seized the line to call
+
+ // Busy sub states
+ LSSUB_INCOMING_PROGRESS, // incoming call in progress
+ LSSUB_OUTGOING_PROGRESS, // outgoing call in progress
+ LSSUB_ANSWERING, // sent 200 OK, waiting for ACK
+ LSSUB_ESTABLISHED, // call established
+ LSSUB_RELEASING // call is being released (BYE sent)
+};
+
+class t_transfer_data {
+private:
+ // The received REFER request
+ t_request *refer_request;
+
+ // Line number on which REFER was received
+ unsigned short lineno;
+
+ // Indicates if triggered INVITE must be anonymous
+ bool hide_user;
+
+ t_phone_user *phone_user;
+
+public:
+ t_transfer_data(t_request *r, unsigned short _lineno, bool _hide_user,
+ t_phone_user *pu);
+ ~t_transfer_data();
+
+ t_request *get_refer_request(void) const;
+ unsigned short get_lineno(void) const;
+ bool get_hide_user(void) const;
+ t_phone_user *get_phone_user(void) const;
+};
+
+class t_phone : public t_transaction_layer {
+private:
+ // Indicates if the phone is active, accepting calls.
+ bool is_active;
+
+ // Phone users
+ list<t_phone_user *> phone_users;
+
+ // Phone lines
+ // The first NUM_CALL_LINES are for making phone calls.
+ // The tail of the vector is for releasing lines in the background.
+ vector<t_line *> lines;
+
+ // Operations like invite, end_call work on the active line
+ unsigned short active_line;
+
+ // 3-way conference data
+ bool is_3way; // indicates an acitive 3-way
+ t_line *line1_3way; // first line in 3-way conf
+ t_line *line2_3way; // second line in 3-way conf
+
+ // Call transfer data. When a REFER comes in, the user has
+ // to give permission before the triggered INVITE can be sent.
+ // While the user interface presents the question to the user,
+ // the data related to the incoming REFER is stored here.
+ t_transfer_data *incoming_refer_data;
+
+ // Time of startup
+ time_t startup_time;
+
+ // Line release operations
+ // Move a line to the background so it will be released in the
+ // background.
+ void move_line_to_background(unsigned short lineno);
+
+ // Move all call lines that are in releasing state to the
+ // background.
+ void move_releasing_lines_to_background(void);
+
+ // Destroy lines in the background that are idle.
+ void cleanup_dead_lines(void);
+
+ // If a line was part of a 3way, then remove it from the
+ // 3way conference data.
+ void cleanup_3way_state(unsigned short lineno);
+
+ // If one of the lines of a 3way calls has become idle, then
+ // cleanup the 3way conference data.
+ void cleanup_3way(void);
+
+ /** @name Actions */
+ //@{
+ /**
+ * Send an INVITE
+ * @param pu The phone user making this call.
+ * @param to_uri The URI to be used a request-URI and To header URI
+ * @param to_display Display name for To header.
+ * @param subject If not empty, this string will go into the Subject header.
+ * @param no_fork If true, put a no-fork request disposition in the outgoing INVITE
+ * @param anonymous Inidicates if the INVITE should be sent anonymous.
+ */
+ void invite(t_phone_user *pu, const t_url &to_uri, const string &to_display,
+ const string &subject, bool no_fork, bool anonymous);
+
+ void answer(void);
+ void redirect(const list<t_display_url> &destinations, int code, string reason = "");
+ void reject(void);
+ void reject(unsigned short line);
+ void end_call(void);
+ void registration(t_phone_user *pu, t_register_type register_type,
+ unsigned long expires = 0);
+ //@}
+
+ // OPTIONS outside dialog
+ void options(t_phone_user *pu, const t_url &to_uri, const string &to_display = "");
+
+ // OPTIONS inside dialog
+ void options(void);
+
+ bool hold(bool rtponly = false); // returns false is call cannot be put on hold
+ void retrieve(void);
+
+ // Transfer a call (send REFER to far-end)
+ void refer(const t_url &uri, const string &display);
+
+ // Call transfer with consultation (attended)
+ // Transfer the far-end on line lineno_from to the far-end of lineno_to.
+ void refer(unsigned short lineno_from, unsigned short lineno_to);
+ void refer_attended(unsigned short lineno_from, unsigned short lineno_to);
+ void refer_consultation(unsigned short lineno_from, unsigned short lineno_to);
+
+ // Setup a consultation call for transferring the call on the active
+ // line. The active line is put on-hold and the consultation call is
+ // made on an idle line.
+ void setup_consultation_call(const t_url &uri, const string &display);
+
+ // Make line l active. If the current line is busy, then that call
+ // will be put on-hold. If line l has a call on-hold, then that
+ // call will be retrieved.
+ void activate_line(unsigned short l);
+
+ // Send a DTMF digit
+ void send_dtmf(char digit, bool inband, bool info);
+
+ void set_active_line(unsigned short l);
+
+ // Handle responses for out-of-dialog requests
+ void handle_response_out_of_dialog(t_response *r, t_tuid tuid, t_tid tid);
+ void handle_response_out_of_dialog(StunMessage *r, t_tuid tuid);
+
+ // Match an incoming message to a phone user
+ t_phone_user *match_phone_user(t_response *r, t_tuid tuid, bool active_only = false);
+ t_phone_user *match_phone_user(t_request *r, bool active_only = false);
+ t_phone_user *match_phone_user(StunMessage *r, t_tuid tuid, bool active_only = false);
+
+ /**
+ * Hunt for an idle line to hande an incoming call.
+ * @return The number of the line to handle the call (starting at 0).
+ * @return -1 if there is no line to handle the call.
+ */
+ int hunt_line(void);
+
+protected:
+ /**
+ * Find a phone user that can handle an out-of-dialog request.
+ * If there is no phone user that can handle the request, then this
+ * method will send an appropriate failure response on the request.
+ * @param r [in] The request.
+ * @param tid [in] Transaction id of the request transaction.
+ * @return The phone user, if there is a phone user that can handle the request.
+ * @return NULL, otherwise.
+ */
+ t_phone_user *find_phone_user_out_dialog_request(t_request *r, t_tid tid);
+
+ /**
+ * Find a line that can handle an in-dialog request.
+ * If there is no line that can handle the request, then this
+ * method will send an appropriate failure response on the request.
+ * @param r [in] The request.
+ * @param tid [in] Transaction id of the request transaction.
+ * @return The line, if there is a line that can handle the request.
+ * @return NULL, otherwise.
+ */
+ t_line *find_line_in_dialog_request(t_request *r, t_tid tid);
+
+ // Events
+ void recvd_provisional(t_response *r, t_tuid tuid, t_tid tid);
+ void recvd_success(t_response *r, t_tuid tuid, t_tid tid);
+ void recvd_redirect(t_response *r, t_tuid tuid, t_tid tid);
+ void recvd_client_error(t_response *r, t_tuid tuid, t_tid tid);
+ void recvd_server_error(t_response *r, t_tuid tuid, t_tid tid);
+ void recvd_global_error(t_response *r, t_tuid tuid, t_tid tid);
+ void post_process_response(t_response *r, t_tuid tuid, t_tid tid);
+
+ void recvd_invite(t_request *r, t_tid tid);
+ void recvd_initial_invite(t_request *r, t_tid tid);
+ void recvd_re_invite(t_request *r, t_tid tid);
+ void recvd_ack(t_request *r, t_tid tid);
+ void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid);
+ void recvd_bye(t_request *r, t_tid tid);
+ void recvd_options(t_request *r, t_tid tid);
+ void recvd_register(t_request *r, t_tid tid);
+ void recvd_prack(t_request *r, t_tid tid);
+ void recvd_subscribe(t_request *r, t_tid tid);
+ void recvd_notify(t_request *r, t_tid tid);
+ void recvd_refer(t_request *r, t_tid tid);
+ void recvd_info(t_request *r, t_tid tid);
+ void recvd_message(t_request *r, t_tid tid);
+ void post_process_request(t_request *r, t_tid cancel_tid, t_tid target_tid);
+
+ void failure(t_failure failure, t_tid tid);
+
+ void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid);
+
+ void recvd_refer_permission(bool permission);
+
+ /** @name Timeout handlers */
+ //@{
+ virtual void handle_event_timeout(t_event_timeout *e);
+
+ /**
+ * Process expiry of line timer.
+ * @param id [in] Line id of the line associate with the timer.
+ * @param timer [in] Type of line timer.
+ * @param did [in] Dialog id if timer is for a dialog, 0 otherwise.
+ */
+ void line_timeout(t_object_id id, t_line_timer timer, t_object_id did);
+
+ /**
+ * Process expiry of a line subscription timer (REFER subscription).
+ * @param id [in] Line id of the line associate with the timer.
+ * @param timer [in] Type of subcription timer.
+ * @param did [in] Dialog id associated with the timer.
+ * @param event_type [in] Event type of the subscription.
+ * @param event_id [in] Event id of the subscription.
+ */
+ void line_timeout_sub(t_object_id id, t_subscribe_timer timer, t_object_id did,
+ const string &event_type, const string &event_id);
+
+ /**
+ * Process expiry of a subcription timer.
+ * @param timer [in] Type of subcription timer.
+ * @param id_timer [in] Timer id of expired timer.
+ */
+ void subscription_timeout(t_subscribe_timer timer, t_object_id id_timer);
+
+ /**
+ * Process expiry of a publication timer.
+ * @param timer [in] Type of publication timer.
+ * @param id_timer [in] Timer id of expired timer.
+ */
+ void publication_timeout(t_publish_timer timer, t_object_id id_timer);
+
+ /**
+ * Process expiry of phone timer.
+ * @param timer [in] Type of phone timer.
+ * @param id_timer [in] Timer id of expired timer.
+ */
+ void timeout(t_phone_timer timer, unsigned short id_timer);
+ //@}
+
+ virtual void handle_broken_connection(t_event_broken_connection *e);
+
+public:
+ t_phone();
+ virtual ~t_phone();
+
+ // Get line based on object id
+ // Returns NULL if there is no such line.
+ t_line *get_line_by_id(t_object_id id) const;
+
+ // Get line based on line number
+ t_line *get_line(unsigned short lineno) const;
+
+ // Get busy/idle state of the phone
+ // PS_IDLE - at least one line is idle
+ // PS_BUSY - all lines are busy
+ t_phone_state get_state(void) const;
+
+ // Returns true if all lines are in the LSSUB_IDLE state
+ bool all_lines_idle(void) const;
+
+ // Get an idle user line.
+ // If no line is idle, then false is returned.
+ bool get_idle_line(unsigned short &lineno) const;
+
+ // Actions to be called by the user interface.
+ // These methods first lock the phone, then call the corresponding
+ // private method and then unlock the phone.
+ // The private methods should only be called by the phone, line,
+ // and dialog objects to avoid deadlocks.
+ void pub_invite(t_user *user,
+ const t_url &to_uri, const string &to_display,
+ const string &subject, bool anonymous);
+ void pub_answer(void);
+ void pub_reject(void);
+ void pub_reject(unsigned short line);
+ void pub_redirect(const list<t_display_url> &destinations, int code, string reason = "");
+ void pub_end_call(void);
+ void pub_registration(t_user *user, t_register_type register_type,
+ unsigned long expires = 0);
+ void pub_options(t_user *user,
+ const t_url &to_uri, const string &to_display = "");
+ void pub_options(void);
+ bool pub_hold(void);
+ void pub_retrieve(void);
+ void pub_refer(const t_url &uri, const string &display);
+ void pub_refer(unsigned short lineno_from, unsigned short lineno_to);
+ void pub_setup_consultation_call(const t_url &uri, const string &display);
+ void mute(bool enable);
+
+ void pub_activate_line(unsigned short l);
+ void pub_send_dtmf(char digit, bool inband, bool info);
+
+ // ZRTP actions
+ void pub_confirm_zrtp_sas(unsigned short line);
+ void pub_confirm_zrtp_sas(void);
+ void pub_reset_zrtp_sas_confirmation(unsigned short line);
+ void pub_reset_zrtp_sas_confirmation(void);
+ void pub_enable_zrtp(void);
+ void pub_zrtp_request_go_clear(void);
+ void pub_zrtp_go_clear_ok(unsigned short line);
+
+ // Join 2 lines in a 3-way conference. Returns false if 3-way cannot
+ // be setup
+ bool join_3way(unsigned short lineno1, unsigned short lineno2);
+
+ // Seize the line.
+ // Returns false if seizure failed.
+ bool pub_seize(void); // active line
+ bool pub_seize(unsigned short line);
+
+ // Unseize the line
+ void pub_unseize(void); // active line
+ void pub_unseize(unsigned short line);
+
+ /** @name MWI */
+ //@{
+ /**
+ * Subscribe to MWI.
+ * @param user [in] The user profile of the subscribing user.
+ */
+ void pub_subscribe_mwi(t_user *user);
+
+ /**
+ * Unsubscribe to MWI.
+ * @param user [in] The user profile of the unsubscribing user.
+ */
+ void pub_unsubscribe_mwi(t_user *user);
+ //@}
+
+ /** @name Presence */
+ //@{
+ /**
+ * Subscribe to presence of buddies in buddy list.
+ * @param user [in] The user profile of the subscribing user.
+ */
+ void pub_subscribe_presence(t_user *user);
+
+ /**
+ * Unsubscribe to presence of buddies in buddy list.
+ * @param user [in] The user profile of the unsubscribing user.
+ */
+ void pub_unsubscribe_presence(t_user *user);
+
+ /**
+ * Publish presence state.
+ * @param user [in] The user profile of the user publishing.
+ * @param basic_state [in] The basic presence state to publish.
+ */
+ void pub_publish_presence(t_user *user, t_presence_state::t_basic_state basic_state);
+
+ /**
+ * Unpublish presence state.
+ * @param user [in] The user profile of the user unpublishing.
+ */
+ void pub_unpublish_presence(t_user *user);
+ //@}
+
+ /** @name Instant messaging */
+ //@{
+ /**
+ * Send a message.
+ * @param user [in] User profile of user sending the message.
+ * @param to_uri [in] Destination URI of recipient.
+ * @param to_display [in] Display name of recipient.
+ * @param msg [in] Message to send.
+ * @return True if sending succeeded, false otherwise.
+ */
+ bool pub_send_message(t_user *user, const t_url &to_uri, const string &to_display,
+ const t_msg &msg);
+
+ /**
+ * Send a message composing state indication.
+ * @param user [in] User profile of user sending the message.
+ * @param to_uri [in] Destination URI of recipient.
+ * @param to_display [in] Display name of recipient.
+ * @param state [in] Message composing state.
+ * @param refresh [in] The refresh interval in seconds (when state is active).
+ * @return True if sending succeeded, false otherwise.
+ * @note For the idle state, the value of refresh has no meaning.
+ */
+ bool pub_send_im_iscomposing(t_user *user, const t_url &to_uri, const string &to_display,
+ const string &state, time_t refresh);
+ //@}
+
+ unsigned short get_active_line(void) const;
+
+ // Authorize the request based on the challenge in the response
+ // Returns false if authorization fails.
+ bool authorize(t_user *user, t_request *r, t_response *resp);
+
+ // Remove cached credentials for a particular user/realm
+ void remove_cached_credentials(t_user *user, const string &realm);
+
+ bool get_is_registered(t_user *user);
+ bool get_last_reg_failed(t_user *user);
+ t_line_state get_line_state(unsigned short lineno) const;
+ t_line_substate get_line_substate(unsigned short lineno) const;
+ bool is_line_on_hold(unsigned short lineno) const;
+ bool is_line_muted(unsigned short lineno) const;
+ bool is_line_transfer_consult(unsigned short lineno,
+ unsigned short &transfer_from_line) const;
+ bool line_to_be_transferred(unsigned short lineno,
+ unsigned short &transfer_to_line) const;
+ bool is_line_encrypted(unsigned short lineno) const;
+ bool is_line_auto_answered(unsigned short lineno) const;
+ t_refer_state get_line_refer_state(unsigned short lineno) const;
+ t_user *get_line_user(unsigned short lineno);
+ bool has_line_media(unsigned short lineno) const;
+ bool is_mwi_subscribed(t_user *user) const;
+ bool is_mwi_terminated(t_user *user) const;
+ t_mwi get_mwi(t_user *user) const;
+
+ /**
+ * Check if all presence subscriptions for a particular user are terminated.
+ * @param user [in] User profile of the user.
+ * @return True if all presence susbcriptions are terminated, otherwise false.
+ */
+ bool is_presence_terminated(t_user *user) const;
+
+ // Get remote uri/display of the active call on a line.
+ // If there is no call, then an empty uri/display is returned.
+ t_url get_remote_uri(unsigned short lineno) const;
+ string get_remote_display(unsigned short lineno) const;
+
+ // Return if a line is part of a 3-way conference
+ bool part_of_3way(unsigned short lineno);
+
+ // Get the peer line in a 3-way conference
+ t_line *get_3way_peer_line(unsigned short lineno);
+
+ // Notify progress of a reference. r is the response to the INVITE
+ // caused by a REFER. referee_lineno is the line number of the line
+ // that is setting up there reference call.
+ void notify_refer_progress(t_response *r, unsigned short referee_lineno);
+
+ // Get call info record for a line.
+ t_call_info get_call_info(unsigned short lineno) const;
+
+ // Get the call history record for a line
+ t_call_record get_call_hist(unsigned short lineno) const;
+
+ // Get ring tone for a line
+ string get_ringtone(unsigned short lineno) const;
+
+ // Get the startup time of the phone
+ time_t get_startup_time(void) const;
+
+ // Initialize the RTP port values for all lines.
+ void init_rtp_ports(void);
+
+ /**
+ * Add a phone user.
+ * @param user_config [in] User profile of the user to add.
+ * @param dup_user [out] Profile of duplicate user.
+ * @return false, if there is already a phone user with the same name
+ * and domain. In this case dup_user is a pointer to the user config
+ * of that user.
+ * @return true, if the phone user was added succesfully.
+ * @note if there is already a user with exactly the same user config
+ * then true is returned, but the user is not added again. The user
+ * will be activated if it was inactive though.
+ */
+ bool add_phone_user(const t_user &user_config, t_user **dup_user);
+
+ /**
+ * Deactivate the phone user.
+ * @param user_config [in] User profile of the user to deactivate.
+ */
+ void remove_phone_user(const t_user &user_config);
+
+ /**
+ * Get a list of user profiles of all phone users.
+ * @return List of user profiles.
+ */
+ list<t_user *> ref_users(void);
+
+ /**
+ * Get the user profile of a user for which user->get_display_uri() ==
+ * display_uri.
+ * @param display_uri [in] Display URI.
+ * @return User profile.
+ */
+ t_user *ref_user_display_uri(const string &display_uri);
+
+ /**
+ * Get the user profile matching the profile name.
+ * @param profile_name [in] User profile name.
+ * @return User profile.
+ */
+ t_user *ref_user_profile(const string &profile_name);
+
+ /**
+ * Get service information for a phone user.
+ * @param user [in] User profile of the phone user.
+ * @return Service object.
+ */
+ t_service *ref_service(t_user *user);
+
+ /**
+ * Get the buddy list of a phone user.
+ * @param user [in] User profile of the phone user.
+ * @return Buddy list.
+ */
+ t_buddy_list *ref_buddy_list(t_user *user);
+
+ /**
+ * Get the presence event publication agent of a phone user.
+ * @param user [in] User profile of the phone user.
+ * @return The presence EPA.
+ */
+ t_presence_epa *ref_presence_epa(t_user *user);
+
+ /**
+ * Find active phone user
+ * @param profile_name [in] User profile name.
+ * @return The phone user for the user profile, NULL if there is no active phone user.
+ */
+ t_phone_user *find_phone_user(const string &profile_name) const;
+
+ /**
+ * Find active phone user
+ * @param user_uri [in] The user URI (AoR) of the user to find.
+ * @return The phone user for the URI, NULL if there is no active phone user.
+ */
+ t_phone_user *find_phone_user(const t_url &user_uri) const;
+
+ /**
+ * Get local IP address for SIP.
+ * @param user [in] The user profile of the user for whom to get the IP address.
+ * @param auto_ip [in] IP address to use if no IP address has been determined through
+ * some NAT procedure.
+ * @return The IP address.
+ */
+ string get_ip_sip(const t_user *user, const string &auto_ip) const;
+
+ /**
+ * Get local port for SIP.
+ * @param user [in] User profile for user for whom to get the port.
+ * @return SIP port.
+ */
+ unsigned short get_public_port_sip(const t_user *user) const;
+
+ /** Indicates if STUN is used. */
+ bool use_stun(t_user *user);
+
+ // Indicates if a NAT keepalive mechanism is used
+ bool use_nat_keepalive(t_user *user);
+
+ /** Disable STUN for a user. */
+ void disable_stun(t_user *user);
+
+ /** Synchronize sending of NAT keep alives with user configuration settings. */
+ void sync_nat_keepalive(t_user *user);
+
+ // Perform NAT discovery for all users having STUN enabled.
+ // If NAT discovery indicates that STUN cannot be used for 1 or more
+ // users, then false will be returned and msg_list contains a list
+ // of messages to be shown to the user.
+ bool stun_discover_nat(list<string> &msg_list);
+
+ // Perform NAT discovery for a single user.
+ bool stun_discover_nat(t_user *user, string &msg);
+
+ // Create a response to an OPTIONS request
+ // Argument 'in-dialog' indicates if the OPTIONS response is
+ // sent within a dialog.
+ t_response *create_options_response(t_user *user, t_request *r,
+ bool in_dialog = false);
+
+ // Timer operations
+ void start_timer(t_phone_timer timer, t_phone_user *pu);
+ void stop_timer(t_phone_timer timer, t_phone_user *pu);
+
+ // Start a timer with the time set in the time-argument.
+ void start_set_timer(t_phone_timer timer, long time, t_phone_user *pu);
+
+ /**
+ * Initialize the phone functions.
+ * Register all active users with auto register.
+ * Initialize extensions for users without auto register.
+ */
+ void init(void);
+
+ /**
+ * Initialize SIP extensions like MWI and presence.
+ * @param user_config [in] User for which the extensions must be initialized.
+ */
+ void init_extensions(t_user *user_config);
+
+ /**
+ * Set the signal handler to handler for LinuxThreads.
+ * @return True if succesful, false otherwise.
+ */
+ bool set_sighandler(void) const;
+
+ /**
+ * Terminate the phone functions.
+ * Release all calls, don't accept any new calls.
+ * Deregister all active users.
+ */
+ void terminate(void);
+};
+
+// Main function for the UAS part of the phone
+void *phone_uas_main(void *arg);
+
+// Entry function of thread catching signals to terminate
+// the application in a graceful manner if NPLT is used.
+void *phone_sigwait(void *arg);
+
+// Signal handler to process signals if LinuxThreads is used.
+void phone_sighandler(int sig);
+
+#endif