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

#ifndef _TIMEKEEPER_H
#define _TIMEKEEPER_H

#include <list>
#include "id_object.h"
#include "protocol.h"
#include "transaction.h"
#include "threads/mutex.h"
#include "threads/sema.h"

using namespace std;

// Forward declarations
class t_phone;
class t_line;
class t_subscription;

/** Timer type */
enum t_timer_type {
    TMR_TRANSACTION,    /**< Transaction timer */
    TMR_PHONE,        /**< Timer associated with the phone */
    TMR_LINE,        /**< Timer associated with a line */
    TMR_SUBSCRIBE,        /**< Subscription timer */
    TMR_PUBLISH,        /**< Publication timer */
    TMR_STUN_TRANSACTION    /**< STUN timer */
};
////////////////////////////////////////////////////////////////
// General timer.
////////////////////////////////////////////////////////////////
// Instances should be created from subclasses.
class t_timer : public t_id_object {
private:
    long            duration; // milliseconds
    long            relative_duration; // milliseconds

public:
    t_timer(long dur);
    virtual ~t_timer() {}

    // This method is invoked on expiry
    // Subclasses should implent the action to be taken.
    virtual void expired(void) = 0;

    long get_duration(void) const;
    long get_relative_duration(void) const;
    void set_relative_duration(long d);
    virtual t_timer *copy(void) const = 0;
    virtual t_timer_type get_type(void) const = 0;

    // Get the name of the timer (for debugging purposes)
    virtual string get_name(void) const = 0;
};

////////////////////////////////////////////////////////////////
// Transaction timer
////////////////////////////////////////////////////////////////
class t_tmr_transaction : public t_timer {
private:
    unsigned short    transaction_id;
    t_sip_timer    sip_timer;

public:
    t_tmr_transaction(long dur, t_sip_timer tmr, unsigned short tid);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    unsigned short get_tid(void) const;
    t_sip_timer get_sip_timer(void) const;
    string get_name(void) const;
};

////////////////////////////////////////////////////////////////
// Phone timer
////////////////////////////////////////////////////////////////
class t_tmr_phone : public t_timer {
private:
    t_phone        *the_phone;
    t_phone_timer    phone_timer;

public:
    t_tmr_phone(long dur, t_phone_timer ptmr, t_phone *p);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    t_phone_timer get_phone_timer(void) const;
    t_phone *get_phone(void) const;
    string get_name(void) const;
};

////////////////////////////////////////////////////////////////
// Line timer
////////////////////////////////////////////////////////////////
class t_tmr_line : public t_timer {
private:
    t_object_id    line_id;
    t_line_timer    line_timer;
    t_object_id    dialog_id;

public:
    t_tmr_line(long dur, t_line_timer ltmr, t_object_id lid,
            t_object_id d);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    t_line_timer get_line_timer(void) const;
    t_object_id get_line_id(void) const;
    t_object_id get_dialog_id(void) const;
    string get_name(void) const;
};

////////////////////////////////////////////////////////////////
// Subscribe timer
////////////////////////////////////////////////////////////////
class t_tmr_subscribe : public t_timer {
private:
    t_subscribe_timer    subscribe_timer;
    t_object_id        line_id;
    t_object_id        dialog_id;
    string            sub_event_type;
    string            sub_event_id;


public:
    t_tmr_subscribe(long dur, t_subscribe_timer stmr, t_object_id lid, t_object_id d,
        const string &event_type, const string &event_id);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    t_subscribe_timer get_subscribe_timer(void) const;
    t_object_id get_line_id(void) const;
    t_object_id get_dialog_id(void) const;
    string get_sub_event_type(void) const;
    string get_sub_event_id(void) const;
    string get_name(void) const;
};

/** Publication timer */
class t_tmr_publish : public t_timer {
private:
    t_publish_timer        publish_timer;    /**< Type of timer */
    string            event_type;    /**< Event type of publication */


public:
    t_tmr_publish(long dur, t_publish_timer ptmr, const string &_event_type);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    t_publish_timer get_publish_timer(void) const;
    string get_name(void) const;
};

////////////////////////////////////////////////////////////////
// STUN transaction timer
////////////////////////////////////////////////////////////////
class t_tmr_stun_trans : public t_timer {
private:
    unsigned short    transaction_id;
    t_stun_timer    stun_timer;

public:
    t_tmr_stun_trans(long dur, t_stun_timer tmr, unsigned short tid);

    void expired(void);
    t_timer *copy(void) const;
    t_timer_type get_type(void) const;
    unsigned short get_tid(void) const;
    t_stun_timer get_stun_timer(void) const;
    string get_name(void) const;
};


////////////////////////////////////////////////////////////////
// Timekeeper
////////////////////////////////////////////////////////////////
// A timekeeper keeps track of multiple timers per thread.
// Only one single thread should call the methods of a single
// timekeeper. Multiple threads using the same timekeeper will
// cause havoc.

class t_timekeeper {
private:
    // List of running timers in order of timeout. As there
    // is only 1 real timer running on the OS. Each timer gets
    // a duration relative to its predecessor in the list.
    list<t_timer *>        timer_list;

    // Mutex to synchronize timekeeper actions.
    t_mutex            mutex;

    // Indicate if current timer was stopped, but not removed
    // to prevent race conditions. Expiry of a stopped timer
    // will not trigger any actions.
    bool            stopped;

    // Indicate if the current timer expired while the
    // mutex was locked.
    bool            timer_expired;

    // Every method should start with locking the timekeeper
    // and end with unlocking. The unlocking method will check
    // if a timer expired during the locked state. If so, then
    // the expiry will be processed.
    void lock(void);
    void unlock(void);

    // Start the timekeeper from the thread that will handle
    // the SIGALRM signal. Start must be called before the
    // timekeeper can be used.
    void start(void (*timeout_handler)(int));

    // Start a timer. The timer id is returned. This id is
    // needed to stop a timer. Pointer t should not be used
    // or deleted after starting. When the timer expires or
    // is stopped it will be deleted.
    void start_timer(t_timer *t);

    void stop_timer(t_object_id id);

public:
    // The timeout_handler must be a signal handler for SIGALRM
    t_timekeeper();
    ~t_timekeeper();

    // Report that the current timer has expired.
    void report_expiry(void);

    // Get remaining time of a running timer.
    // Returns 0 if the timer is not running anymore.
    unsigned long get_remaining_time(t_object_id timer_id);

    // Main loop to be run in a separate thread
    void run(void);
};

// Entry function for timekeeper thread
void *timekeeper_main(void *arg);

// Entry function of the thread waiting for SIGALRM
// A dedicated thread is started to catch the SIGALRM signal and take
// the appropriate action. All threads must block the SIGALRM signal.
void *timekeeper_sigwait(void *arg);

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