00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SIPFSM_H_
00010 #define SIPFSM_H_
00011
00012 #include <qsqldatabase.h>
00013 #include <qregexp.h>
00014 #include <qtimer.h>
00015 #include <qptrlist.h>
00016 #include <qthread.h>
00017 #include <qwidget.h>
00018 #include <qsocketdevice.h>
00019 #include <qdatetime.h>
00020
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 #ifndef WIN32
00024 #include <sys/ioctl.h>
00025 #include <fcntl.h>
00026 #include <linux/videodev.h>
00027 #include <mythtv/mythwidgets.h>
00028 #include <mythtv/dialogbox.h>
00029 #endif
00030
00031 #include "sipstack.h"
00032
00033 #ifndef WIN32
00034 #include "vxml.h"
00035 #endif
00036
00037
00038 class SipEvent : public QCustomEvent
00039 {
00040 public:
00041 enum Type { SipStateChange = (QEvent::User + 400), SipNotification, SipStartMedia, SipStopMedia, SipChangeMedia,
00042 SipAlertUser, SipCeaseAlertUser, SipRingbackTone, SipCeaseRingbackTone };
00043
00044 SipEvent(Type t) : QCustomEvent(t) {}
00045 SipEvent(Type t, QString rIp, int ap, QString ac, int vp, QString vc, int dp, int rap, int rvp, QString vr) : QCustomEvent(t)
00046 {
00047 audPayload=ap; vidPayload=vp; dtmfPayload=dp; remoteAudioPort=rap; remoteVideoPort=rvp;
00048 audCodec=ac; vidCodec=vc; vidResolution=vr;
00049 remoteIp=rIp;
00050 }
00051 SipEvent(Type t, QString cUser, QString cUrl, QString cName, bool cAudio) : QCustomEvent(t)
00052 {
00053 callerUser = cUser; callerName = cName; callerUrl = cUrl; callIsAudioOnly = cAudio;
00054 }
00055 ~SipEvent() {}
00056 int getAudioPayload() { return audPayload; }
00057 int getVideoPayload() { return vidPayload; }
00058 int getDTMFPayload() { return dtmfPayload; }
00059 int getAudioPort() { return remoteAudioPort; }
00060 int getVideoPort() { return remoteVideoPort; }
00061 QString getRemoteIp() { return remoteIp; }
00062 QString getAudioCodec() { return audCodec; }
00063 QString getVideoCodec() { return vidCodec; }
00064 QString getVideoRes() { return vidResolution; }
00065 QString getCallerUser() { return callerUser; }
00066 QString getCallerUrl() { return callerUrl; }
00067 QString getCallerName() { return callerName; }
00068 bool getCallIsAudioOnly() { return callIsAudioOnly; }
00069
00070 private:
00071 int audPayload, vidPayload, dtmfPayload, remoteAudioPort, remoteVideoPort;
00072 QString audCodec, vidCodec, vidResolution, remoteIp;
00073 QString callerUser, callerName, callerUrl;
00074 bool callIsAudioOnly;
00075 };
00076
00077 class SipDebugEvent : public QCustomEvent
00078 {
00079 public:
00080 enum Type { SipDebugEv = (QEvent::User + 430), SipErrorEv, SipTraceRxEv, SipTraceTxEv };
00081
00082 SipDebugEvent(Type t, QString s) : QCustomEvent(t) { text=s;}
00083 ~SipDebugEvent() {}
00084 QString msg() { return text;}
00085
00086 private:
00087 QString text;
00088 };
00089
00090
00091
00092
00093 #define SIP_IDLE 0x1
00094 #define SIP_OCONNECTING1 0x2 // Invite sent, no response yet
00095 #define SIP_OCONNECTING2 0x3 // Invite sent, 1xx response
00096 #define SIP_ICONNECTING 0x4
00097 #define SIP_ICONNECTING_WAITACK 0x5
00098 #define SIP_CONNECTED 0x6
00099 #define SIP_DISCONNECTING 0x7
00100 #define SIP_CONNECTED_VXML 0x8 // This is a false state, only used as indication back to the frontend
00101 #define SIP_CONNECT_MODIFYING1 0x9 // Connected; sent a re-Invite to modify the SDP
00102 #define SIP_CONNECT_MODIFYING2 0xA // Connected; rxed a re-Invite and sent a 200ok, waiting for ACK
00103
00104
00105 #define SIP_REG_DISABLED 0x01 // Proxy registration turned off
00106 #define SIP_REG_TRYING 0x02 // Sent a REGISTER, waiting for an answer
00107 #define SIP_REG_CHALLENGED 0x03 // Initial REGISTER was met with a challenge, sent an authorized REGISTER
00108 #define SIP_REG_FAILED 0x04 // REGISTER failed; will retry after a period of time
00109 #define SIP_REG_REGISTERED 0x05 // Registration successful
00110
00111
00112 #define SIP_SUB_IDLE SIP_IDLE
00113 #define SIP_SUB_SUBSCRIBED 0x10
00114
00115
00116 #define SIP_WATCH_IDLE SIP_IDLE
00117 #define SIP_WATCH_TRYING 0x20
00118 #define SIP_WATCH_ACTIVE 0x21
00119 #define SIP_WATCH_STOPPING 0x22
00120 #define SIP_WATCH_HOLDOFF 0x23
00121
00122
00123 #define SIP_IM_IDLE SIP_IDLE
00124 #define SIP_IM_ACTIVE 0x30
00125
00126
00127
00128 #define SIP_UNKNOWN 0x0
00129 #define SIP_OUTCALL 0x100
00130 #define SIP_INVITE 0x200
00131 #define SIP_INVITESTATUS_2xx 0x300
00132 #define SIP_INVITESTATUS_1xx 0x400
00133 #define SIP_INVITESTATUS_3456xx 0x500
00134 #define SIP_ANSWER 0x600
00135 #define SIP_ACK 0x700
00136 #define SIP_BYE 0x800
00137 #define SIP_HANGUP 0x900
00138 #define SIP_BYESTATUS 0xA00
00139 #define SIP_CANCEL 0xB00
00140 #define SIP_CANCELSTATUS 0xC00
00141 #define SIP_REGISTER 0xD00
00142 #define SIP_RETX 0xE00
00143 #define SIP_REGISTRAR_TEXP 0xF00
00144 #define SIP_REGSTATUS 0x1000
00145 #define SIP_REG_TREGEXP 0x1100
00146 #define SIP_SUBSCRIBE 0x1200
00147 #define SIP_SUBSTATUS 0x1300
00148 #define SIP_NOTIFY 0x1400
00149 #define SIP_NOTSTATUS 0x1500
00150 #define SIP_PRESENCE_CHANGE 0x1600
00151 #define SIP_SUBSCRIBE_EXPIRE 0x1700
00152 #define SIP_WATCH 0x1800
00153 #define SIP_STOPWATCH 0x1900
00154 #define SIP_MESSAGE 0x1A00
00155 #define SIP_MESSAGESTATUS 0x1B00
00156 #define SIP_INFO 0x1C00
00157 #define SIP_INFOSTATUS 0x1D00
00158 #define SIP_IM_TIMEOUT 0x1E00
00159 #define SIP_USER_MESSAGE 0x1F00
00160 #define SIP_KICKWATCH 0x2000
00161 #define SIP_MODIFYSESSION 0x2100
00162 #define SIP_OPTIONS 0x2200
00163
00164 #define SIP_CMD(s) (((s)==SIP_INVITE) || ((s)==SIP_ACK) || ((s)==SIP_BYE) || ((s)==SIP_CANCEL) || ((s)==SIP_REGISTER) || ((s)==SIP_SUBSCRIBE) || ((s)==SIP_NOTIFY) || ((s)==SIP_MESSAGE) || ((s)==SIP_INFO) || ((s)==SIP_OPTIONS))
00165 #define SIP_STATUS(s) (((s)==SIP_INVITESTATUS_2xx) || ((s)==SIP_INVITESTATUS_1xx) || ((s)==SIP_INVITESTATUS_3456xx) || ((s)==SIP_BYTESTATUS) || ((s)==SIP_CANCELSTATUS) || ((s)==SIP_SUBSTATUS) || ((s)==SIP_NOTSTATUS) || ((s)==SIP_MESSAGESTATUS) || ((s)==SIP_INFOSTATUS) )
00166 #define SIP_MSG(s) (SIP_CMD(s) || SIP_STATUS(s))
00167
00168
00169 #define SIP_IDLE_OUTCALL (SIP_IDLE | SIP_OUTCALL)
00170 #define SIP_IDLE_BYE (SIP_IDLE | SIP_BYE)
00171 #define SIP_IDLE_INVITE (SIP_IDLE | SIP_INVITE)
00172 #define SIP_IDLE_INVITESTATUS_1xx (SIP_IDLE | SIP_INVITESTATUS_1xx)
00173 #define SIP_IDLE_INVITESTATUS_2xx (SIP_IDLE | SIP_INVITESTATUS_2xx)
00174 #define SIP_IDLE_INVITESTATUS_3456 (SIP_IDLE | SIP_INVITESTATUS_3456xx)
00175 #define SIP_OCONNECTING1_INVITESTATUS_3456 (SIP_OCONNECTING1 | SIP_INVITESTATUS_3456xx)
00176 #define SIP_OCONNECTING1_INVITESTATUS_2xx (SIP_OCONNECTING1 | SIP_INVITESTATUS_2xx)
00177 #define SIP_OCONNECTING1_INVITESTATUS_1xx (SIP_OCONNECTING1 | SIP_INVITESTATUS_1xx)
00178 #define SIP_OCONNECTING1_RETX (SIP_OCONNECTING1 | SIP_RETX)
00179 #define SIP_OCONNECTING2_INVITESTATUS_3456 (SIP_OCONNECTING2 | SIP_INVITESTATUS_3456xx)
00180 #define SIP_OCONNECTING2_INVITESTATUS_2xx (SIP_OCONNECTING2 | SIP_INVITESTATUS_2xx)
00181 #define SIP_OCONNECTING2_INVITESTATUS_1xx (SIP_OCONNECTING2 | SIP_INVITESTATUS_1xx)
00182 #define SIP_OCONNECTING1_HANGUP (SIP_OCONNECTING1 | SIP_HANGUP)
00183 #define SIP_OCONNECTING2_HANGUP (SIP_OCONNECTING2 | SIP_HANGUP)
00184 #define SIP_OCONNECTING1_INVITE (SIP_OCONNECTING1 | SIP_INVITE)
00185 #define SIP_ICONNECTING_INVITE (SIP_ICONNECTING | SIP_INVITE)
00186 #define SIP_ICONNECTING_ANSWER (SIP_ICONNECTING | SIP_ANSWER)
00187 #define SIP_ICONNECTING_CANCEL (SIP_ICONNECTING | SIP_CANCEL)
00188 #define SIP_ICONNECTING_WAITACK_ACK (SIP_ICONNECTING_WAITACK | SIP_ACK)
00189 #define SIP_ICONNECTING_WAITACK_RETX (SIP_ICONNECTING_WAITACK | SIP_RETX)
00190 #define SIP_ICONNECTING_WAITACK_CANCEL (SIP_ICONNECTING_WAITACK | SIP_CANCEL)
00191 #define SIP_ICONNECTING_WAITACK_HANGUP (SIP_ICONNECTING_WAITACK | SIP_HANGUP)
00192 #define SIP_CONNECTED_ACK (SIP_CONNECTED | SIP_ACK)
00193 #define SIP_CONNECTED_INVITESTATUS_2xx (SIP_CONNECTED | SIP_INVITESTATUS_2xx)
00194 #define SIP_CONNECTED_RETX (SIP_CONNECTED | SIP_RETX)
00195 #define SIP_CONNECTED_BYE (SIP_CONNECTED | SIP_BYE)
00196 #define SIP_CONNECTED_HANGUP (SIP_CONNECTED | SIP_HANGUP)
00197 #define SIP_DISCONNECTING_BYESTATUS (SIP_DISCONNECTING | SIP_BYESTATUS)
00198 #define SIP_DISCONNECTING_ACK (SIP_DISCONNECTING | SIP_ACK)
00199 #define SIP_DISCONNECTING_RETX (SIP_DISCONNECTING | SIP_RETX)
00200 #define SIP_DISCONNECTING_CANCEL (SIP_DISCONNECTING | SIP_CANCEL)
00201 #define SIP_DISCONNECTING_CANCELSTATUS (SIP_DISCONNECTING | SIP_CANCELSTATUS)
00202 #define SIP_DISCONNECTING_BYE (SIP_DISCONNECTING | SIP_BYE)
00203 #define SIP_CONNECTED_MODIFYSESSION (SIP_CONNECTED | SIP_MODIFYSESSION)
00204 #define SIP_CONNECTED_INVITE (SIP_CONNECTED | SIP_INVITE)
00205 #define SIP_CONNMOD1_INVITESTATUS_1xx (SIP_CONNECT_MODIFYING1 | SIP_INVITESTATUS_1xx)
00206 #define SIP_CONNMOD1_INVITESTATUS_2xx (SIP_CONNECT_MODIFYING1 | SIP_INVITESTATUS_2xx)
00207 #define SIP_CONNMOD1_INVITESTATUS_3456 (SIP_CONNECT_MODIFYING1 | SIP_INVITESTATUS_3456xx)
00208 #define SIP_CONNMOD1_RETX (SIP_CONNECT_MODIFYING1 | SIP_RETX)
00209 #define SIP_CONNMOD2_ACK (SIP_CONNECT_MODIFYING2 | SIP_ACK)
00210 #define SIP_CONNMOD2_RETX (SIP_CONNECT_MODIFYING2 | SIP_RETX)
00211
00212
00213 #define SIP_REG_TRYING_STATUS (SIP_REG_TRYING | SIP_REGSTATUS)
00214 #define SIP_REG_CHALL_STATUS (SIP_REG_CHALLENGED| SIP_REGSTATUS)
00215 #define SIP_REG_REGISTERED_TREGEXP (SIP_REG_REGISTERED| SIP_REG_TREGEXP)
00216 #define SIP_REG_TRYING_RETX (SIP_REG_TRYING | SIP_RETX)
00217 #define SIP_REG_CHALL_RETX (SIP_REG_CHALLENGED| SIP_RETX)
00218 #define SIP_REG_FAILED_RETX (SIP_REG_FAILED | SIP_RETX)
00219
00220
00221 #define SIP_SUB_IDLE_SUBSCRIBE (SIP_SUB_IDLE | SIP_SUBSCRIBE)
00222 #define SIP_SUB_SUBS_SUBSCRIBE (SIP_SUB_SUBSCRIBED | SIP_SUBSCRIBE)
00223 #define SIP_SUB_SUBS_SUBSCRIBE_EXPIRE (SIP_SUB_SUBSCRIBED | SIP_SUBSCRIBE_EXPIRE)
00224 #define SIP_SUB_SUBS_RETX (SIP_SUB_SUBSCRIBED | SIP_RETX)
00225 #define SIP_SUB_SUBS_NOTSTATUS (SIP_SUB_SUBSCRIBED | SIP_NOTSTATUS)
00226 #define SIP_SUB_SUBS_PRESENCE_CHANGE (SIP_SUB_SUBSCRIBED | SIP_PRESENCE_CHANGE)
00227
00228
00229 #define SIP_WATCH_IDLE_WATCH (SIP_WATCH_IDLE | SIP_WATCH)
00230 #define SIP_WATCH_TRYING_WATCH (SIP_WATCH_TRYING | SIP_WATCH)
00231 #define SIP_WATCH_ACTIVE_SUBSCRIBE_EXPIRE (SIP_WATCH_ACTIVE | SIP_SUBSCRIBE_EXPIRE)
00232 #define SIP_WATCH_TRYING_RETX (SIP_WATCH_TRYING | SIP_RETX)
00233 #define SIP_WATCH_ACTIVE_RETX (SIP_WATCH_ACTIVE | SIP_RETX)
00234 #define SIP_WATCH_TRYING_SUBSTATUS (SIP_WATCH_TRYING | SIP_SUBSTATUS)
00235 #define SIP_WATCH_ACTIVE_SUBSTATUS (SIP_WATCH_ACTIVE | SIP_SUBSTATUS)
00236 #define SIP_WATCH_ACTIVE_NOTIFY (SIP_WATCH_ACTIVE | SIP_NOTIFY)
00237 #define SIP_WATCH_TRYING_STOPWATCH (SIP_WATCH_TRYING | SIP_STOPWATCH)
00238 #define SIP_WATCH_ACTIVE_STOPWATCH (SIP_WATCH_ACTIVE | SIP_STOPWATCH)
00239 #define SIP_WATCH_STOPPING_RETX (SIP_WATCH_STOPPING | SIP_RETX)
00240 #define SIP_WATCH_STOPPING_SUBSTATUS (SIP_WATCH_STOPPING | SIP_SUBSTATUS)
00241 #define SIP_WATCH_TRYING_SUBSCRIBE (SIP_WATCH_TRYING | SIP_SUBSCRIBE)
00242 #define SIP_WATCH_HOLDOFF_WATCH (SIP_WATCH_HOLDOFF | SIP_WATCH)
00243 #define SIP_WATCH_HOLDOFF_STOPWATCH (SIP_WATCH_HOLDOFF | SIP_STOPWATCH)
00244 #define SIP_WATCH_HOLDOFF_SUBSCRIBE (SIP_WATCH_HOLDOFF | SIP_SUBSCRIBE)
00245 #define SIP_WATCH_HOLDOFF_KICK (SIP_WATCH_HOLDOFF | SIP_KICKWATCH)
00246
00247
00248
00249 #define SIP_OPT_SDP 1
00250 #define SIP_OPT_CONTACT 2
00251 #define SIP_OPT_VIA 4
00252 #define SIP_OPT_ALLOW 8
00253 #define SIP_OPT_EXPIRES 16
00254 #define SIP_OPT_TIMESTAMP 32
00255
00256
00257 #define REG_RETRY_TIMER 3000 // seconds
00258 #define REG_FAIL_RETRY_TIMER 180000 // 3 minutes
00259 #define REG_RETRY_MAXCOUNT 5
00260 #define SIP_POLL_OFFLINE_UA 180000 // 3 minutes - period between polls to see if a logged off user has logged on
00261
00262 #define SIP_POLL_PERIOD 2 // Twice per second
00263
00264
00265
00266 class SipFsm;
00267 class SipTimer;
00268 class SipThread;
00269 class SipRegisteredUA;
00270 class SipRegistrar;
00271 class SipRegistration;
00272 class SipContainer;
00273
00274
00275 extern SipContainer *sipContainer;
00276
00277
00278 struct CodecNeg
00279 {
00280 int Payload;
00281 QString Encoding;
00282 };
00283 #define MAX_AUDIO_CODECS 5 // Make 1 more than max so we can use last place in array as a terminator
00284
00285 class SipContainer
00286 {
00287 public:
00288 SipContainer();
00289 ~SipContainer();
00290 void PlaceNewCall(QString Mode, QString uri, QString name, bool disableNat);
00291 void AnswerRingingCall(QString Mode, bool disableNat);
00292 void HangupCall();
00293 void ModifyCall(QString audCodec, QString vidCodec="UNCHANGED");
00294 void UiOpened(QObject *);
00295 void UiClosed();
00296 void UiWatch(QStrList uriList);
00297 void UiWatch(QString uri);
00298 void UiStopWatchAll();
00299 QString UiSendIMMessage(QString DestUrl, QString CallId, QString Msg);
00300 bool GetNotification(QString &type, QString &url, QString ¶m1, QString ¶m2);
00301 void GetRegistrationStatus(bool &Registered, QString &RegisteredTo, QString &RegisteredAs);
00302 int GetSipState();
00303 void GetIncomingCaller(QString &u, QString &d, QString &l, bool &audOnly);
00304 void GetSipSDPDetails(QString &ip, int &aport, int &audPay, QString &audCodec, int &dtmfPay, int &vport, int &vidPay, QString &vidCodec, QString &vidRes);
00305 void notifyRegistrationStatus(bool reg, QString To, QString As) { regStatus=reg; regTo=To; regAs=As;}
00306 void notifyCallState(int s) { CallState=s;}
00307 void notifySDPDetails(QString ip, int aport, int audPay, QString audCodec, int dtmfPay, int vport, int vidPay, QString vidCodec, QString vidRes)
00308 { remoteIp=ip; remoteAudioPort=aport; audioPayload=audPay; audioCodec=audCodec;
00309 dtmfPayload=dtmfPay; remoteVideoPort=vport; videoPayload=vidPay; videoCodec=vidCodec; videoRes=vidRes; }
00310 void notifyCallerDetails(QString cU, QString cN, QString cUrl, bool inAudOnly)
00311 { callerUser=cU; callerName=cN; callerUrl=cUrl; inAudioOnly=inAudOnly; }
00312 bool killThread() { return killSipThread; }
00313 QString getLocalIpAddress();
00314 QString getNatIpAddress();
00315
00316
00317 private:
00318 SipThread *sipThread;
00319 bool killSipThread;
00320 int CallState;
00321 bool regStatus;
00322 QString regTo;
00323 QString regAs;
00324 QString callerUser, callerName, callerUrl;
00325 bool inAudioOnly;
00326 QString remoteIp;
00327 int remoteAudioPort;
00328 int remoteVideoPort;
00329 int audioPayload;
00330 int dtmfPayload;
00331 int videoPayload;
00332 QString audioCodec;
00333 QString videoCodec;
00334 QString videoRes;
00335 };
00336
00337
00338
00339 class SipThread : public QThread
00340 {
00341 public:
00342 SipThread(SipContainer *c) { sipContainer = c;};
00343 ~SipThread() {};
00344 virtual void run();
00345
00346 private:
00347 void SipThreadWorker();
00348 void CheckUIEvents(SipFsm *sipFsm);
00349 void CheckNetworkEvents(SipFsm *sipFsm);
00350 void CheckRegistrationStatus(SipFsm *sipFsm);
00351 void ChangePrimaryCallState(SipFsm *sipFsm, int NewState);
00352
00353 SipContainer *sipContainer;
00354 bool FrontEndActive;
00355 bool vxmlCallActive;
00356 #ifndef WIN32
00357 vxmlParser *vxml;
00358 rtp *Rtp;
00359 #endif
00360 int CallState;
00361 QString callerUser, callerName, callerUrl;
00362 bool inAudioOnly;
00363 QString remoteIp;
00364 int remoteAudioPort;
00365 int remoteVideoPort;
00366 int audioPayload;
00367 int dtmfPayload;
00368 int videoPayload;
00369 QString audioCodec;
00370 QString videoCodec;
00371 QString videoRes;
00372 int rnaTimer;
00373 };
00374
00375
00376
00377
00378 class SipFsmBase
00379 {
00380 public:
00381 SipFsmBase(SipFsm *p);
00382 virtual ~SipFsmBase();
00383 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0) { (void)Event; (void)sipMsg; (void)Value; return 0; }
00384 virtual QString type() { return "BASE"; }
00385 virtual SipUrl *getUrl() { return remoteUrl; }
00386 virtual int getCallRef() { return -1; }
00387 QString callId() { return CallId.string(); }
00388
00389 protected:
00390 void BuildSendStatus(int Code, QString Method, int statusCseq, int Option=0, int statusExpires=-1, QString sdp="");
00391 void ParseSipMsg(int Event, SipMsg *sipMsg);
00392 bool Retransmit(bool force);
00393 void DebugFsm(int event, int old_state, int new_state);
00394 QString EventtoString(int Event);
00395 QString StatetoString(int S);
00396
00397 QString retx;
00398 QString retxIp;
00399 int retxPort;
00400 int t1;
00401 bool sentAuthenticated;
00402 SipFsm *parent;
00403
00404 SipCallId CallId;
00405 QString viaIp;
00406 int viaPort;
00407 int rxedTimestamp;
00408 QString myTag;
00409 QString remoteTag;
00410 QString remoteEpid;
00411 QString rxedTo;
00412 QString rxedFrom;
00413 QString RecRoute;
00414 QString Via;
00415 SipUrl *remoteUrl;
00416 SipUrl *toUrl;
00417 SipUrl *contactUrl;
00418 SipUrl *recRouteUrl;
00419 SipUrl *MyUrl;
00420 SipUrl *MyContactUrl;
00421
00422 };
00423
00424
00425 class SipRegistration : public SipFsmBase
00426 {
00427 public:
00428 SipRegistration(SipFsm *par, QString localIp, int localPort, QString Username, QString Password, QString ProxyName, int ProxyPort);
00429 ~SipRegistration();
00430 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00431 virtual QString type() { return "REGISTRATION"; };
00432 bool isRegistered() { return (State == SIP_REG_REGISTERED); }
00433 QString registeredTo() { return ProxyUrl->getHost(); }
00434 QString registeredAs() { return MyContactUrl->getUser(); }
00435 int registeredPort() { return ProxyUrl->getPort(); }
00436 QString registeredPasswd() { return MyPassword; }
00437
00438 private:
00439 void SendRegister(SipMsg *authMsg=0);
00440
00441 int State;
00442 int Expires;
00443 QString sipLocalIp;
00444 int sipLocalPort;
00445 int regRetryCount;
00446
00447 SipUrl *ProxyUrl;
00448 QString MyPassword;
00449 int cseq;
00450 };
00451
00452
00453 class SipCall : public SipFsmBase
00454 {
00455 public:
00456 SipCall(QString localIp, QString natIp, int localPort, int n, SipFsm *par);
00457 ~SipCall();
00458 int getState() { return State; };
00459 void setVideoPayload(int p) { videoPayload = p; };
00460 void setVideoResolution(QString v) { txVideoResolution = v; };
00461 void setAllowVideo(bool a) { allowVideo = a; };
00462 void setDisableNat(bool n) { disableNat = n; };
00463 void to(QString uri, QString DispName) { DestinationUri = uri; DisplayName = DispName; };
00464 void dialViaProxy(SipRegistration *s) { viaRegProxy = s; };
00465 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00466 virtual QString type() { return "CALL"; };
00467 virtual int getCallRef() { return callRef; };
00468 void GetIncomingCaller(QString &u, QString &d, QString &l, bool &aud)
00469 { u = CallersUserid; d = CallersDisplayName; l = CallerUrl; aud = (videoPayload == -1); }
00470 void GetSdpDetails(QString &ip, int &aport, int &audPay, QString &audCodec, int &dtmfPay, int &vport, int &vidPay, QString &vidCodec, QString &vidRes)
00471 { ip=remoteIp; aport=remoteAudioPort; vport=remoteVideoPort; audPay = CodecList[audioPayloadIdx].Payload;
00472 audCodec = CodecList[audioPayloadIdx].Encoding; dtmfPay = dtmfPayload; vidPay = videoPayload;
00473 vidCodec = (vidPay == 34 ? "H263" : ""); vidRes = rxVideoResolution; }
00474 bool ModifyCodecs(QString audioCodec, QString videoCodec);
00475
00476 private:
00477 int State;
00478 int callRef;
00479
00480 void initialise();
00481 bool UseNat();
00482 void ForwardMessage(SipMsg *msg);
00483 void BuildSendInvite(SipMsg *authMsg);
00484 void BuildSendReInvite(SipMsg *authMsg);
00485 void BuildSendAck();
00486 void BuildSendBye(SipMsg *authMsg);
00487 void BuildSendCancel(SipMsg *authMsg);
00488 void AlertUser(SipMsg *rxMsg);
00489 void GetSDPInfo(SipMsg *sipMsg);
00490 void addSdpToInvite(SipMsg& msg, bool advertiseVideo, int audioCodec=-1);
00491 QString BuildSdpResponse();
00492
00493 QString DestinationUri;
00494 QString DisplayName;
00495 CodecNeg CodecList[MAX_AUDIO_CODECS];
00496 QString txVideoResolution;
00497 QString rxVideoResolution;
00498
00499 int cseq;
00500 SipRegistration *viaRegProxy;
00501
00502
00503 QString CallersUserid;
00504 QString CallersDisplayName;
00505 QString CallerUrl;
00506 QString remoteIp;
00507 int remoteAudioPort;
00508 int remoteVideoPort;
00509 int audioPayloadIdx;
00510 int videoPayload;
00511 int dtmfPayload;
00512 bool allowVideo;
00513 bool disableNat;
00514 int ModifyAudioCodec;
00515
00516 QString myDisplayName;
00517 QString sipLocalIP;
00518 QString sipNatIP;
00519 int sipLocalPort;
00520 QString sipUsername;
00521
00522 int sipRtpPacketisation;
00523 int sipAudioRtpPort;
00524 int sipVideoRtpPort;
00525 };
00526
00527
00528 class SipSubscriber : public SipFsmBase
00529 {
00530 public:
00531 SipSubscriber(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString status);
00532 ~SipSubscriber();
00533 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00534 virtual QString type() { return "SUBSCRIBER"; };
00535 virtual SipUrl *getUrl() { return watcherUrl; }
00536
00537 private:
00538 void SendNotify(SipMsg *authMsg);
00539
00540 QString sipLocalIp;
00541 int sipLocalPort;
00542 SipRegistration *regProxy;
00543 QString myStatus;
00544
00545 int State;
00546 SipUrl *watcherUrl;
00547 int expires;
00548 int cseq;
00549 };
00550
00551
00552 class SipWatcher : public SipFsmBase
00553 {
00554 public:
00555 SipWatcher(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString destUrl);
00556 ~SipWatcher();
00557 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00558 virtual QString type() { return "WATCHER"; };
00559 virtual SipUrl *getUrl() { return watchedUrl; }
00560
00561 private:
00562 void SendSubscribe(SipMsg *authMsg);
00563
00564 QString sipLocalIp;
00565 int sipLocalPort;
00566 SipRegistration *regProxy;
00567 SipUrl *watchedUrl;
00568 QString watchedUrlString;
00569 int State;
00570 int expires;
00571 int cseq;
00572 };
00573
00574
00575 class SipIM : public SipFsmBase
00576 {
00577 public:
00578 SipIM(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString destUrl="", QString callIdStr="");
00579 ~SipIM();
00580 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00581 virtual QString type() { return "IM"; };
00582
00583 private:
00584 void SendMessage(SipMsg *authMsg, QString Text);
00585
00586 QString msgToSend;
00587 QString sipLocalIp;
00588 int sipLocalPort;
00589 SipUrl *imUrl;
00590 SipRegistration *regProxy;
00591 int State;
00592 int rxCseq;
00593 int txCseq;
00594 };
00595
00596
00597 class SipOptions : public SipFsmBase
00598 {
00599 public:
00600 SipOptions(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString callIdStr="");
00601 ~SipOptions();
00602 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00603 virtual QString type() { return "Options"; };
00604
00605 private:
00606 QString sipLocalIp;
00607 int sipLocalPort;
00608 SipRegistration *regProxy;
00609 int rxCseq;
00610 int txCseq;
00611 };
00612
00613
00614 class SipFsm : public QWidget
00615 {
00616
00617 Q_OBJECT
00618
00619 public:
00620
00621 SipFsm(QWidget *parent = 0, const char * = 0);
00622 ~SipFsm(void);
00623 bool SocketOpenedOk() { return sipSocket != 0 ? true : false; }
00624 static void Debug(SipDebugEvent::Type t, QString dbg);
00625 void NewCall(bool audioOnly, QString uri, QString DispName, QString videoMode, bool DisableNat);
00626 void HangUp(void);
00627 void Answer(bool audioOnly, QString videoMode, bool DisableNat);
00628 void ModifyCall(QString audioCodec, QString videoCodec);
00629 void StatusChanged(char *newStatus);
00630 void DestroyFsm(SipFsmBase *Fsm);
00631 void CheckRxEvent();
00632 SipCall *MatchCall(int cr);
00633 SipFsmBase *MatchCallId(SipCallId *CallId);
00634 SipCall *CreateCallFsm();
00635 SipSubscriber *CreateSubscriberFsm();
00636 SipWatcher *CreateWatcherFsm(QString Url);
00637 SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
00638 SipOptions *CreateOptionsFsm(QString Url="", QString callIdStr="");
00639 void StopWatchers();
00640 void KickWatcher(SipUrl *Url);
00641 void SendIM(QString destUrl, QString CallId, QString imMsg);
00642 int numCalls();
00643 int getPrimaryCall() { return primaryCall; };
00644 int getPrimaryCallState();
00645 QString OpenSocket(int Port);
00646 void CloseSocket();
00647 void Transmit(QString Msg, QString destIP, int destPort);
00648 bool Receive(SipMsg &sipMsg);
00649 void SetNotification(QString type, QString url, QString param1, QString param2);
00650 SipTimer *Timer() { return timerList; };
00651 void HandleTimerExpiries();
00652 SipRegistrar *getRegistrar() { return sipRegistrar; }
00653 bool isRegistered() { return (sipRegistration != 0 && sipRegistration->isRegistered()); }
00654 QString registeredTo() { if (sipRegistration) return sipRegistration->registeredTo(); else return ""; }
00655 QString registeredAs() { if (sipRegistration) return sipRegistration->registeredAs(); else return ""; }
00656
00657
00658
00659
00660 private:
00661 int MsgToEvent(SipMsg *sipMsg);
00662 QString DetermineNatAddress();
00663
00664 int localPort;
00665 QPtrList<SipFsmBase> FsmList;
00666 QSocketDevice *sipSocket;
00667 int callCount;
00668 int primaryCall;
00669 int lastStatus;
00670 SipTimer *timerList;
00671 SipRegistrar *sipRegistrar;
00672 SipRegistration *sipRegistration;
00673 QString PresenceStatus;
00674 };
00675
00676 class SipRegisteredUA
00677 {
00678 public:
00679 SipRegisteredUA(SipUrl *Url, QString cIp, int cPort);
00680 ~SipRegisteredUA();
00681 QString getContactIp() { return contactIp; }
00682 int getContactPort() { return contactPort; }
00683 bool matches(SipUrl *u);
00684
00685 private:
00686 SipUrl *userUrl;
00687 QString contactIp;
00688 int contactPort;
00689 };
00690
00691 class SipRegistrar : public SipFsmBase
00692 {
00693 public:
00694 SipRegistrar(SipFsm *par, QString domain, QString localIp, int localPort);
00695 ~SipRegistrar();
00696 virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
00697 virtual QString type() { return "REGISTRAR"; };
00698 bool getRegisteredContact(SipUrl *remoteUrl);
00699
00700 private:
00701 void SendResponse(int Code, SipMsg *sipMsg, QString rIp, int rPort);
00702 void add(SipUrl *Url, QString hostIp, int Port, int Expires);
00703 void remove(SipUrl *Url);
00704 SipRegisteredUA *find(SipUrl *Url);
00705
00706 QPtrList<SipRegisteredUA> RegisteredList;
00707 QString sipLocalIp;
00708 int sipLocalPort;
00709 QString regDomain;
00710
00711 };
00712
00713
00714 class SipNotify
00715 {
00716 public:
00717 SipNotify();
00718 ~SipNotify();
00719 void Display(QString name, QString number);
00720
00721 private:
00722 QSocketDevice *notifySocket;
00723 };
00724
00725
00726
00727 class aSipTimer
00728 {
00729 public:
00730 aSipTimer(SipFsmBase *I, QDateTime exp, int ev, void *v=0) { Instance = I; Expires = exp; Event = ev; Value = v;};
00731 ~aSipTimer() {};
00732 bool match(SipFsmBase *I, int ev, void *v=0) { return ((Instance == I) && ((Event == ev) || (ev == -1)) && ((Value == v) || (v == 0))); };
00733 SipFsmBase *getInstance() { return Instance; };
00734 int getEvent() { return Event; };
00735 void *getValue() { return Value; };
00736 QDateTime getExpire() { return Expires; };
00737 bool Expired() { return (QDateTime::currentDateTime() > Expires); };
00738 private:
00739 SipFsmBase *Instance;
00740 QDateTime Expires;
00741 int Event;
00742 void *Value;
00743 };
00744
00745 class SipTimer : public QPtrList<aSipTimer>
00746 {
00747 public:
00748 SipTimer();
00749 ~SipTimer();
00750 void Start(SipFsmBase *Instance, int ms, int expireEvent, void *Value=0);
00751 void Stop(SipFsmBase *Instance, int expireEvent, void *Value=0);
00752 int msLeft(SipFsmBase *Instance, int expireEvent, void *Value=0);
00753 virtual int compareItems(QPtrCollection::Item s1, QPtrCollection::Item s2);
00754 void StopAll(SipFsmBase *Instance);
00755 SipFsmBase *Expired(int *Event, void **Value);
00756
00757 private:
00758 };
00759
00760
00761
00762
00763 #endif