projects / voip-6line-twinkle.git / blob
Build Results
 
Summary

Description: Michael Larabel's 6-line VoIP client implementation of Twinkle (normally supports two). Development sponsored by Global Fone.
Last Change: Thu 12/13/07 20:15

 
Files
plain
/*
    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
*/

/**
 * @file
 * Subscription (RFC 3265)
 */

#ifndef _SUBSCRIPTION_H
#define _SUBSCRIPTION_H

#include <queue>
#include <string>
#include "abstract_dialog.h"

/** Subscription role */
enum t_subscription_role {
    SR_SUBSCRIBER,        /**< Subscriber */
    SR_NOTIFIER        /**< Notifier */
};

/** Subscription state */
enum t_subscription_state {
    SS_NULL,        /**< Initial state */
    SS_ESTABLISHED,        /**< Subscription is in place */
    SS_UNSUBSCRIBING,    /**< A request to unsubscribe has been sent */
    SS_UNSUBSCRIBED,    /**< An outoging unsubscribe was succesful. Waiting for the final NOTIFY. */
    SS_TERMINATED,        /**< Subscription ended */
};

/**
 * Convert a subscription state to string.
 * @param state [in] Subscription state.
 * @return String representation of state.
 */
string t_subscription_state2str(t_subscription_state state);

/**
 * RFC 3265
 * Generic subscription state for subscribers and notifiers
 * For each event type this class should be subclassed.
 */
class t_subscription {
protected:
    t_subscription_role    role;
    t_subscription_state    state;

    /**
     *  When a subscriber subscription is terminated, this reason indicates
     * the reason conveyed in the NOTIFY, if any.
     */
    string            reason_termination;

    /**
     * If the NOTIFY indicated that the subscriber may retry subscription at
     * a later time, then resubscribe_after indicates the number of seconds to wait.
     */
    unsigned long        resubscribe_after;

    /** Indicates if a re-subscribe may be done after a failure. */
    bool            may_resubscribe;

    t_abstract_dialog    *dialog; /**< Dialog owning the subscription */
    string            event_type;
    string            event_id;

    /**
     * User profile of user using the line
     * This is a pointer to the user_config owned by a phone user.
     * So this pointer should never be deleted.
     */
    t_user            *user_config;

    bool            pending; /**< Indicates if not active yet. */

    /** @name Timers */
    //@{
    /**
     * For a subscriber the subscription_timeout timer indicates when
     * the subscription must be refreshed.
     * For a notifier it indicates when the subscription expires.
     */
    unsigned short        id_subscription_timeout;

    /**
     * Indicates if a subscriber automatically refreshes the subscritption
     * when the subscription timer expires. If not, then the subscription
     * terminates at expiry.
     */
    bool            auto_refresh;

    /** Subcription expiry for a SUBSCRIBE request */
    unsigned long        subscription_expiry;

    /** Default duration for a subscription */
    unsigned long        default_duration;
    //@}

    /** Protect constructor from being used */
    t_subscription() {};

    /** Write event type and id to log file */
    void log_event() const;

    /**
     * Remove a pending request. Pass one of the client request pointers.
     * @param cr [in] Client request to remove.
     */
    void remove_client_request(t_client_request **cr);

    /** @name Create requests based on the event type */
    //@{
    /**
     * Create a SUBSCRIBE request.
     * Creating a SUBSCRIBE is for subscription refreshment/unsubscribe.
     * @param expires [in] Expiry time in seconds.
     */
    virtual t_request *create_subscribe(unsigned long expires) const;

    /**
     * Create a NOTIFY request.
     * @param sub_state [in] Subscription state to be put in the Subscription-State header.
     * @param reason [in] The reason parameter of the Subscription-State header.
     */
    virtual t_request *create_notify(const string &sub_state,
        const string &reason = "") const;
    //@}

    /**
     * Send request.
     * @param user_config [in] User profile of user sending the request.
     * @param r [in] Request to send.
     * @param tuid [in] Transaction user id.
     */
    void send_request(t_user *user_config, t_request *r, t_tuid tuid) const;

    /**
     * Send response.
     * @param user_config [in] User profile of user sending the response.
     * @param r [in] Response to send.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     */
    void send_response(t_user *user_config, t_response *r, t_tuid tuid, t_tid tid) const;

    /**
     * Start a subscription timer.
     * @param timer [in] Type of subscription timer.
     * @param duration [in] Duration of timer in ms
     */
    void start_timer(t_subscribe_timer timer, long duration);

    /**
     * Stop a subscription timer.
     * @param timer [in] Type of subscription timer.
     */
    void stop_timer(t_subscribe_timer timer);

public:
    /** Pending request */
    t_client_request    *req_out;

    /**
     * Queue of pending outgoing NOTIFY requests. A next NOTIFY
     * will only be sent after the previous NOTIFY has been
     * answered.
     */
    queue<t_request *>    queue_notify;

    /**
     * Constructor
     * @param _dialog [in] Dialog owning this subscription. SUBSCRIBE and NOTIFY
     * requests are sent within this dialog.
     * @param _role [in] Role
     * @param _event_type [in] Event type of the subscription.
     */
    t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role,
            const string &_event_type);

    /**
     * Constructor
     * @param _dialog [in] Dialog owning this subscription. SUBSCRIBE and NOTIFY
     * requests are sent within this dialog.
     * @param _role [in] Role
     * @param _event_type [in] Event type of the subscription.
     * @param _event_id [in] Event id.
     */
    t_subscription(t_abstract_dialog *_dialog, t_subscription_role _role,
            const string &_event_type, const string &_event_id);

    /** Destructor */
    virtual ~t_subscription();

    /** @name Getters */
    //@{
    t_subscription_role get_role(void) const;
    t_subscription_state get_state(void) const;
    string get_reason_termination(void) const;
    unsigned long get_resubscribe_after(void) const;
    bool get_may_resubscribe(void) const;
    string get_event_type(void) const;
    string get_event_id(void) const;
    unsigned long get_expiry(void) const;
    //@}

    /** @name Receive requests */
    //@{
    /**
     * Reveive SUBSCRIBE request
     * @param r [in] Received request.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     * @return The return value indicates if processing is finished.
     * This way a subclass can first call the parent class method.
     * If the parent indicates that process is finished, then the child
     * does not need to further process.
     * Note that recv_subscribe returns false if the SUBSCRIBE is valid. The
     * subscription timer will be started, but no response is sent. The subclass
     * MUST further handle the SUBSCRIBE, i.e. send a response and a NOTIFY.
     */
    virtual bool recv_subscribe(t_request *r, t_tuid tuid, t_tid tid);

    /**
     * Receive NOTIFY request.
     * @param r [in] Received request.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     * @return When the NOTIFY is valid, false is returned. The subclass MUST further
     * handle the NOTIFY, i.e. send a response.
     */
    virtual bool recv_notify(t_request *r, t_tuid tuid, t_tid tid);
    //@}

    /** @name Receive responses */
    //@{
    /**
     * Receive NOTIFY/SUBSCRIBE response.
     * @param r [in] Received response.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     * @return The return value indicates if processing is finished.
     */
    virtual bool recv_response(t_response *r, t_tuid tuid, t_tid tid);

    /**
     * Receive NOTIFY response.
     * @param r [in] Received response.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     * @return The return value indicates if processing is finished.
     */
    virtual bool recv_notify_response(t_response *r, t_tuid tuid, t_tid tid);

    /**
     * Receive SUBSCRIBE response.
     * @param r [in] Received response.
     * @param tuid [in] Transaction user id.
     * @param tid [in] Transaction id.
     * @return The return value indicates if processing is finished.
     */
    virtual bool recv_subscribe_response(t_response *r, t_tuid tuid, t_tid tid);
    //@}

    /**
     * Process timeouts
     * @param timer [in] Type of subscription timer.
     * @return The return value indicates if processing is finished.
     */
    virtual bool timeout(t_subscribe_timer timer);

    /**
     * Match timer id with a running timer.
     * @param timer [in] Type of subscription timer.
     * @return True, if id matches, otherwise false.
     */
    virtual bool match_timer(t_subscribe_timer timer, t_object_id id_timer) const;

    /**
     * Does incoming request match with event type and id?
     * @param r [in] Request to match.
     * @return True if request matches, otherwise false.
     */
    virtual bool match(t_request *r) const;

    /**
     * Check if subscription is pending.
     * @return True if subscription is pending, otherwise false.
     */
    bool is_pending(void) const;

    /**
     * Subscribe to an event.
     * @param expires [in] Expiry in seconds. If expires == 0, then the default duration is used.
     */
    virtual void subscribe(unsigned long expires);

    /** Unsubscribe from an event. */
    virtual void unsubscribe(void);

    /** Refresh subscription. */
    virtual void refresh_subscribe(void);
};

#endif
 
Phoronix.com
Linux Driver Forums
Copyright © 2013 by Phoronix Media