Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
123 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#ifndef __TSIPCLIENT_H__
20
#define __TSIPCLIENT_H__
21
 
22
#include <thread>
23
#include <atomic>
24
 
135 andreas 25
#include <pjsua-lib/pjsua.h>
129 andreas 26
 
27
#ifndef _NOSIP_
135 andreas 28
#define SIP_MAX_LINES       2
124 andreas 29
 
135 andreas 30
#define current_acc         pjsua_acc_get_default()
31
 
32
#define PJSUA_APP_NO_LIMIT_DURATION (int)0x7FFFFFFF
33
// Ringtones                US         UK
34
#define RINGBACK_FREQ1      440     // 400
35
#define RINGBACK_FREQ2      480     // 450
36
#define RINGBACK_ON         2000    // 400
37
#define RINGBACK_OFF        4000    // 200
38
#define RINGBACK_CNT        1       // 2
39
#define RINGBACK_INTERVAL   4000    // 2000
40
 
41
#define RING_FREQ1          800
42
#define RING_FREQ2          640
43
#define RING_ON             200
44
#define RING_OFF            100
45
#define RING_CNT            3
46
#define RING_INTERVAL       3000
47
 
48
typedef unsigned int        uint_t;
49
 
123 andreas 50
class TSIPClient
51
{
52
    public:
124 andreas 53
        typedef enum SIP_STATE_t
54
        {
127 andreas 55
            SIP_NONE,               // Undefined state (only valid on startup before initialisation)
56
            SIP_IDLE,               // Initialized but no event
57
            SIP_CONNECTED,          // Call is in progress
58
            SIP_DISCONNECTED,       // Call has ended
59
            SIP_TRYING,             // Trying to call someone
60
            SIP_RINGING,            // Phone is ringing (incoming call)
61
            SIP_HOLD,               // Active call is paused
62
            SIP_REJECTED,           // Outgoing call was rejected
63
            SIP_ERROR               // An error occured
124 andreas 64
        }SIP_STATE_t;
65
 
127 andreas 66
        TSIPClient();
123 andreas 67
        ~TSIPClient();
68
 
135 andreas 69
        bool init();
70
 
123 andreas 71
        void cleanUp();
124 andreas 72
        int getLineID() { return mLine; }
138 andreas 73
        SIP_STATE_t getSIPState(pjsua_call_id id) { if (id >= 0 && id < PJSUA_MAX_CALLS) return mSIPState[id]; else return SIP_NONE; }
135 andreas 74
        bool isRegistered() { return mRegistered; }
141 andreas 75
        static TSIPClient *getSIPClient() { return mMyself; }
123 andreas 76
 
127 andreas 77
        bool call(const std::string& dest);         //<! Start a phone call
135 andreas 78
        bool pickup(pjsua_call_id call);            //<! Lift up if the phone is ringing
127 andreas 79
        bool terminate(int id);                     //<! Terminate a call
80
        bool hold(int id);                          //<! Pause a call
81
        bool resume(int id);                        //<! Resume a paused call
82
        bool sendDTMF(std::string& dtmf);           //<! Send a DTMF string
128 andreas 83
        bool sendLinestate();                       //<! Queries the state of each of the connections used by the SIP device.
84
        bool sendPrivate(bool state);               //<! Enables or disables the privacy feature on the phone (do not disturb).
85
        bool redial();                              //<! Redial last number
86
        bool transfer(int id, const std::string& num);  //<! transfer the current call
138 andreas 87
        bool setDTMFduration(uint_t ms);            //<! Set the DTMF duration in ms.
88
        bool getPrivate() { return mDoNotDisturb; } //<! Returns the current private mode.
144 andreas 89
        bool sendIM(const std::string& target, const std::string& msg); //<! Send an IM to somebody or to the peer of the current call
90
        size_t getNumberMessages() { return mMessages.size(); }
123 andreas 91
 
92
    protected:
141 andreas 93
        void runRinger();                           //<! Plays a ring tone if a call is coming.
123 andreas 94
 
135 andreas 95
        static void _log_call(int level, const char *data, int len);
96
        static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata);
97
        static void on_call_state(pjsua_call_id call_id, pjsip_event *e);
98
        static void on_call_media_state(pjsua_call_id call_id);
99
        static void call_on_dtmf_callback2(pjsua_call_id call_id, const pjsua_dtmf_info *info);
100
        static pjsip_redirect_op call_on_redirected(pjsua_call_id call_id, const pjsip_uri *target, const pjsip_event *e);
101
        static void on_call_transfer_status(pjsua_call_id call_id, int status_code, const pj_str_t *status_text, pj_bool_t final, pj_bool_t *p_cont);
102
        static void on_transport_state(pjsip_transport *tp, pjsip_transport_state state, const pjsip_transport_state_info *info);
103
        static void on_ip_change_progress(pjsua_ip_change_op op, pj_status_t status, const pjsua_ip_change_op_info *info);
104
        static void simple_registrar(pjsip_rx_data *rdata);
105
        static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata);
106
        static void ringback_start(pjsua_call_id call_id);
107
        static void ring_start(pjsua_call_id call_id);
108
        static void ring_stop(pjsua_call_id call_id);
109
        static pj_bool_t find_next_call(void);
110
        static void call_timeout_callback(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry);
111
        static void on_playfile_done(pjmedia_port *port, void *usr_data);
112
        static void hangup_timeout_callback(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry);
144 andreas 113
        static void on_pager2(pjsua_call_id call_id, const pj_str_t *from,
114
                              const pj_str_t *to, const pj_str_t *contact,
115
                              const pj_str_t *mime_type, const pj_str_t *body,
116
                              pjsip_rx_data *rdata, pjsua_acc_id acc_id);
117
        static void on_buddy_state(pjsua_buddy_id buddy_id);
118
        static void on_buddy_evsub_state(pjsua_buddy_id buddy_id, pjsip_evsub *sub, pjsip_event *event);
119
        static void on_mwi_info(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info);
135 andreas 120
 
123 andreas 121
    private:
144 andreas 122
        typedef struct _uri_t
123
        {
124
            std::string name;           //!< The name coming in double quotes (optional)
125
            std::string scheme;         //!< The scheme (e.g. sip)
126
            std::string user;           //!< The user name / telephone number
127
            std::string server;         //!< The IP address or FQDN of the server
128
            int port;                   //!< An optional port number
129
        }_uri_t;
130
 
135 andreas 131
        static pjsip_module mod_default_handler;
132
 
127 andreas 133
        int getNumberCalls();
138 andreas 134
        pjsua_call_id getActiveCall();
135
        void setSIPState(SIP_STATE_t s, pjsua_call_id id) { if (id >= 0 && id < PJSUA_MAX_CALLS) mSIPState[id] = s; }
127 andreas 136
 
135 andreas 137
        static void sendConnectionStatus(SIP_STATE_t state, int id);
141 andreas 138
        static void init_ringtone_player();
139
        static pj_status_t start_ring_tone();
140
        static pj_status_t stop_ring_tone();
144 andreas 141
        static pjsua_buddy_id addBuddy(const std::string& rsipurl);
142
        static _uri_t parseUri(const std::string& uri);
138 andreas 143
 
124 andreas 144
        int mLine{0};
135 andreas 145
        bool mRegistered{false};
138 andreas 146
        SIP_STATE_t mSIPState[PJSUA_MAX_CALLS];
135 andreas 147
        pjsua_acc_id mAccountID{0};
148
        std::string mLastCall;
138 andreas 149
        uint_t mDTMFduration{PJSUA_CALL_SEND_DTMF_DURATION_DEFAULT};
150
        bool mDoNotDisturb{false};
144 andreas 151
        std::vector<std::string>mMessages;      // Holds all received messages
123 andreas 152
 
135 andreas 153
        static TSIPClient *mMyself;
154
        static pjsua_call_id mCurrentCall;
155
        static std::atomic<bool> mRefreshRun;
141 andreas 156
        static bool mPhoneRingInit;
135 andreas 157
        // Here is the configuration for the PJSUA library
158
        typedef struct app_call_data
159
        {
160
            pj_timer_entry      timer;
161
            pj_bool_t           ringback_on{PJ_FALSE};
162
            pj_bool_t           ring_on{PJ_FALSE};
163
        } app_call_data;
123 andreas 164
 
141 andreas 165
        typedef struct ringtone_port_info_t
166
        {
167
            pj_bool_t ring_on{PJ_FALSE};
168
            int ring_slot{0};
169
            pjmedia_port *ring_port{nullptr};
170
            pj_pool_t *pool{nullptr};
171
        } ringtone_port_info_t;
172
 
135 andreas 173
        typedef struct pjsua_app_config
174
        {
175
            pjsua_config        cfg;
176
            pjsua_logging_config log_cfg;
177
            pjsua_media_config  media_cfg;
178
            pj_bool_t           no_refersub{PJ_FALSE};
179
            pj_bool_t           enable_qos{PJ_FALSE};
180
            pj_bool_t           no_tcp{PJ_TRUE};
181
            pj_bool_t           no_udp{PJ_FALSE};
182
            pj_bool_t           use_tls{PJ_FALSE};
183
            pjsua_transport_config  udp_cfg;
184
            pjsua_transport_config  rtp_cfg;
185
            pjsip_redirect_op   redir_op;
186
            int                 srtp_keying{0};
187
 
188
            uint_t              acc_cnt{0};
189
            pjsua_acc_config    acc_cfg[PJSUA_MAX_ACC];
190
 
191
            uint_t              buddy_cnt{0};
192
            pjsua_buddy_config  buddy_cfg[PJSUA_MAX_BUDDIES];
193
 
194
            app_call_data       call_data[PJSUA_MAX_CALLS];
195
 
196
            pj_pool_t          *pool{nullptr};
197
            /* Compatibility with older pjsua */
198
 
199
            uint_t              codec_cnt{0};
200
            pj_str_t            codec_arg[32];
201
            uint_t              codec_dis_cnt{0};
202
            pj_str_t            codec_dis[32];
203
            pj_bool_t           null_audio{PJ_FALSE};
141 andreas 204
            uint_t              wav_count{0};
135 andreas 205
            pj_str_t            wav_files[32];
206
            uint_t              tone_count{0};
207
            pjmedia_tone_desc   tones[32];
208
            pjsua_conf_port_id  tone_slots[32];
209
            pjsua_player_id     wav_id{0};
210
            pjsua_conf_port_id  wav_port{0};
211
            pj_bool_t           auto_play{PJ_FALSE};
212
            pj_bool_t           auto_play_hangup{PJ_FALSE};
213
            pj_timer_entry      auto_hangup_timer;
214
            pj_bool_t           auto_loop{PJ_FALSE};
215
            pj_bool_t           auto_conf{PJ_FALSE};
216
            pj_str_t            rec_file;
217
            pj_bool_t           auto_rec{PJ_FALSE};
218
            pjsua_recorder_id   rec_id{0};
219
            pjsua_conf_port_id  rec_port{0};
220
            unsigned            auto_answer{0};
141 andreas 221
            unsigned            duration{36000};
222
            float               mic_level{100.0};
223
            float               speaker_level{100.0};
135 andreas 224
 
225
            int                 capture_dev{0};
226
            int                 playback_dev{0};
227
            uint_t              capture_lat{0};
228
            uint_t              playback_lat{0};
229
 
230
            pj_bool_t           no_tones{PJ_FALSE};
231
            int                 ringback_slot{0};
232
            int                 ringback_cnt{0};
233
            pjmedia_port        *ringback_port{nullptr};
234
            int                 ring_slot{0};
235
            int                 ring_cnt{0};
236
            pjmedia_port        *ring_port{nullptr};
237
 
238
            uint_t              aud_cnt{0};
239
        }pjsua_app_config;
240
 
241
        static pjsua_app_config mAppConfig;
141 andreas 242
        static ringtone_port_info_t mRingtonePortInfo;
124 andreas 243
};
129 andreas 244
#endif  // _NOSIP_
245
#endif  // __TSIPCLIENT_H__