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