00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <qapplication.h>
00012 #include <qdatetime.h>
00013 #include <qhostaddress.h>
00014 #include <qdom.h>
00015
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <iostream>
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #ifndef WIN32
00022 #include <unistd.h>
00023 #include <sys/ioctl.h>
00024 #include <netdb.h>
00025 #endif
00026
00027 #ifdef WIN32
00028 #include <winsock2.h>
00029 #endif
00030
00031 using namespace std;
00032
00033 #ifndef WIN32
00034 #include "config.h"
00035 #endif
00036 #include "sipstack.h"
00037 #include "md5digest.h"
00038
00040
00042
00043
00044 SipMsg::SipMsg(QString Method)
00045 {
00046 thisMethod = Method;
00047 Msg = "";
00048 statusCode = 0;
00049 statusText = "";
00050 cseqValue = 0;
00051 cseqMethod = "";
00052 Expires = -1;
00053 Timestamp = -1;
00054 msgContainsSDP = false;
00055 msgContainsXPIDF = false;
00056 msgContainsPlainText = false;
00057 PlainTextContent = "";
00058 callId = 0;
00059 sdp = 0;
00060 xpidf = 0;
00061 contactUrl = 0;
00062 recRouteUrl = 0;
00063 fromUrl = 0;
00064 toUrl = 0;
00065 completeVia = "";
00066 completeRR = "";
00067 completeTo = "";
00068 completeFrom = "";
00069 viaIp = "";
00070 viaPort = 0;
00071 }
00072
00073 SipMsg::SipMsg()
00074 {
00075 thisMethod = "";
00076 Msg = "";
00077 statusCode = 0;
00078 statusText = "";
00079 cseqValue = 0;
00080 cseqMethod = "";
00081 Expires = -1;
00082 Timestamp = -1;
00083 msgContainsSDP = false;
00084 msgContainsXPIDF = false;
00085 msgContainsPlainText = false;
00086 PlainTextContent = "";
00087 callId = 0;
00088 sdp = 0;
00089 xpidf = 0;
00090 contactUrl = 0;
00091 recRouteUrl = 0;
00092 fromUrl = 0;
00093 toUrl = 0;
00094 completeVia = "";
00095 completeRR = "";
00096 completeTo = "";
00097 completeFrom = "";
00098 viaIp = "";
00099 viaPort = 0;
00100 }
00101
00102 SipMsg::~SipMsg()
00103 {
00104 if (callId)
00105 delete callId;
00106 if (sdp)
00107 delete sdp;
00108 if (xpidf)
00109 delete xpidf;
00110 if (contactUrl)
00111 delete contactUrl;
00112 if (recRouteUrl)
00113 delete recRouteUrl;
00114 if (fromUrl)
00115 delete fromUrl;
00116 if (toUrl)
00117 delete toUrl;
00118 }
00119
00120 SipMsg &SipMsg::operator= (SipMsg &rhs)
00121 {
00122 if (this == &rhs)
00123 return *this;
00124
00125 Msg = rhs.Msg;
00126 thisMethod = rhs.thisMethod;
00127 statusCode = rhs.statusCode;
00128 statusText = rhs.statusText;
00129 if (callId != 0)
00130 callId = new SipCallId(*rhs.callId);
00131 cseqValue = rhs.cseqValue;
00132 cseqMethod = rhs.cseqMethod;
00133 msgContainsSDP = rhs.msgContainsSDP;
00134 msgContainsXPIDF = rhs.msgContainsXPIDF;
00135 msgContainsPlainText = rhs.msgContainsPlainText;
00136 PlainTextContent = rhs.PlainTextContent;
00137
00138
00139
00140
00141
00142
00143 sdp = 0;
00144 xpidf = 0;
00145
00146 return *this;
00147 }
00148
00149 void SipMsg::addRequestLine(SipUrl &Url)
00150 {
00151 Msg = thisMethod + " " + Url.formatReqLineUrl() + " SIP/2.0\r\n";
00152 }
00153
00154 void SipMsg::addStatusLine(int Code)
00155 {
00156 Msg = "SIP/2.0 " + QString::number(Code) + " " + StatusPhrase(Code) + "\r\n";
00157 }
00158
00159 void SipMsg::addVia(QString Hostname, int Port)
00160 {
00161 Msg += "Via: SIP/2.0/UDP " + Hostname + ":" + QString::number(Port) + "\r\n";
00162 }
00163
00164 void SipMsg::addGenericLine(QString Line)
00165 {
00166 Msg += Line;
00167 }
00168
00169 void SipMsg::addTo(SipUrl &to, QString tag, QString epid)
00170 {
00171 Msg += "To: " + to.string();
00172 if (tag.length() > 0)
00173 Msg += ";tag=" + tag;
00174 if (epid.length() > 0)
00175 Msg += ";epid=" + epid;
00176 Msg += "\r\n";
00177 }
00178
00179 void SipMsg::addToCopy(QString To, QString Tag)
00180 {
00181 if ((Tag.length() != 0) && (To.endsWith("\r\n")))
00182 Msg += To.insert(To.length()-2, QString(";tag="+Tag));
00183 else
00184 Msg += To;
00185 }
00186
00187 void SipMsg::addFrom(SipUrl &from, QString tag, QString epid)
00188 {
00189 Msg += "From: " + from.string();
00190 if (tag.length() > 0)
00191 Msg += ";tag=" + tag;
00192 if (epid.length() > 0)
00193 Msg += ";epid=" + epid;
00194 Msg += "\r\n";
00195 }
00196
00197 void SipMsg::addCallId(SipCallId id)
00198 {
00199 Msg += "Call-ID: " + id.string() + "\r\n";
00200 }
00201
00202 void SipMsg::addCSeq(int c)
00203 {
00204 Msg += QString("CSeq: ") + QString::number(c) + " " + thisMethod + "\r\n";
00205 }
00206
00207 void SipMsg::addContact(SipUrl contact, QString Methods)
00208 {
00209 Msg += "Contact: " + contact.formatContactUrl();
00210 if (Methods.length()>0)
00211 Msg += ";methods=\"" + Methods + "\"";
00212 Msg += "\r\n";
00213 }
00214
00215 void SipMsg::addUserAgent(QString ua)
00216 {
00217 Msg += "User-Agent: " + ua + "\r\n";
00218 }
00219
00220 void SipMsg::addAllow()
00221 {
00222 Msg += "Allow: INVITE, ACK, CANCEL, BYE, INFO, NOTIFY\r\n";
00223 }
00224
00225 void SipMsg::addEvent(QString Event)
00226 {
00227 Msg += "Event: " + Event + "\r\n";
00228 }
00229
00230 void SipMsg::addSubState(QString State, int Expires)
00231 {
00232 Msg += "Subscription-State: " + State;
00233 if (Expires != -1)
00234 Msg += ";expires=" + QString::number(Expires);
00235 Msg += "\r\n";
00236 }
00237
00238 void SipMsg::addAuthorization(QString authMethod, QString Username, QString Password, QString Realm, QString Nonce, QString Uri, bool Proxy)
00239 {
00240
00241 HASHHEX HA1;
00242 HASHHEX HA2 = "";
00243 HASHHEX Response;
00244 DigestCalcHA1("md5", Username, Realm, Password, Nonce, "", HA1);
00245 DigestCalcResponse(HA1, Nonce, "", "", "", thisMethod, Uri, "", HA2, Response);
00246
00247 if (Proxy)
00248 Msg += "Proxy-Authorization: " + authMethod;
00249 else
00250 Msg += "Authorization: " + authMethod;
00251 Msg += " username=\"" + Username + "\"";
00252 Msg += ", realm=\"" + Realm + "\"";
00253 Msg += ", uri=\"" + Uri + "\"";
00254 Msg += ", nonce=\"" + Nonce + "\"";
00255 Msg += QString(", response=\"") + Response + "\"";
00256 Msg += ", algorithm=md5\r\n";
00257 }
00258
00259 void SipMsg::addProxyAuthorization(QString authMethod, QString Username, QString Password, QString Realm, QString Nonce, QString Uri)
00260 {
00261 addAuthorization(authMethod, Username, Password, Realm, Nonce, Uri, true);
00262 }
00263
00264 void SipMsg::addExpires(int e)
00265 {
00266 Msg += "Expires: " + QString::number(e) + "\r\n";
00267 }
00268
00269 void SipMsg::addTimestamp(int t)
00270 {
00271 if (t >= 0)
00272 Msg += "Timestamp: " + QString::number(t) + "\r\n";
00273 }
00274
00275 void SipMsg::addNullContent()
00276 {
00277 Msg += "Content-Length: 0\r\n\r\n";
00278 }
00279
00280 void SipMsg::addContent(QString contentType, QString contentData)
00281 {
00282 Msg += QString("Content-Type: ") + contentType + "\r\n"
00283 "Content-Length: " + QString::number(contentData.length()) + "\r\n"
00284 "\r\n"
00285 + contentData;
00286 }
00287
00288 void SipMsg::insertVia(QString Hostname, int Port)
00289 {
00290
00291 QStringList::Iterator it;
00292 for (it=attList.begin(); (it != attList.end()) && (*it != ""); it++)
00293 {
00294 if ((*it).find("Via:", 0, false) == 0)
00295 break;
00296 }
00297
00298
00299 QString Via = "Via: SIP/2.0/UDP " + Hostname + ":" + QString::number(Port);
00300 if ((*it).find("Via:", 0, false) == 0)
00301 attList.insert(it, Via);
00302 else
00303 attList.insert(attList.at(1), Via);
00304
00305
00306 Msg = attList.join("\r\n");
00307 }
00308
00309 void SipMsg::removeVia()
00310 {
00311
00312 QStringList::Iterator it;
00313 for (it=attList.begin(); (it != attList.end()) && (*it != ""); it++)
00314 {
00315 if ((*it).find("Via:", 0, false) == 0)
00316 break;
00317 }
00318
00319
00320 if ((*it).find("Via:", 0, false) == 0)
00321 {
00322 int commaPosn;
00323 if ((commaPosn = (*it).find(',')) != -1)
00324 (*it).remove(5, commaPosn-4);
00325 else
00326 attList.remove(it);
00327 }
00328
00329
00330 Msg = attList.join("\r\n");
00331
00332
00333 viaIp = "";
00334 viaPort = 0;
00335 for (it=attList.begin(); (it != attList.end()) && (*it != ""); it++)
00336 {
00337 if ((*it).find("Via:", 0, false) == 0)
00338 {
00339 decodeVia(*it);
00340 break;
00341 }
00342 }
00343 }
00344
00345 QString SipMsg::StatusPhrase(int Code)
00346 {
00347 switch (Code)
00348 {
00349 case 100: return "Trying";
00350 case 180: return "Ringing";
00351 case 200: return "OK";
00352 case 400: return "Bad Request";
00353 case 404: return "Not Found";
00354 case 406: return "Not Acceptable";
00355 case 481: return "Call Leg/Transaction Does Not Exist";
00356 case 486: return "Busy Here";
00357 case 488: return "Not Acceptable Here";
00358 }
00359 return "Dont know";
00360 }
00361
00362
00363 void SipMsg::decode(QString sipString)
00364 {
00365 Msg = sipString;
00366
00367
00368 attList = QStringList::split("\r\n", sipString, true);
00369
00370
00371 decodeRequestLine(attList[0]);
00372 QStringList::Iterator it = attList.begin();
00373 if (it != attList.end())
00374 it++;
00375 for (; (it != attList.end()) && (*it != ""); it++)
00376 decodeLine(*it);
00377
00378
00379 if (msgContainsSDP)
00380 decodeSdp(sipString.section("\r\n\r\n", 1, 1));
00381 if (msgContainsXPIDF)
00382 decodeXpidf(sipString.section("\r\n\r\n", 1, 1));
00383 if (msgContainsPlainText)
00384 decodePlainText(sipString.section("\r\n\r\n", 1, 1));
00385 }
00386
00387 void SipMsg::decodeLine(QString line)
00388 {
00389 if (line.find("Via:", 0, false) == 0)
00390 decodeVia(line);
00391 else if (line.find("To:", 0, false) == 0)
00392 decodeTo(line);
00393 else if (line.find("From:", 0, false) == 0)
00394 decodeFrom(line);
00395 else if (line.find("Contact:", 0, false) == 0)
00396 decodeContact(line);
00397 else if (line.find("Record-Route:", 0, false) == 0)
00398 decodeRecordRoute(line);
00399 else if (line.find("Call-ID:", 0, false) == 0)
00400 decodeCallid(line);
00401 else if (line.find("CSeq:", 0, false) == 0)
00402 decodeCseq(line);
00403 else if (line.find("Expires:", 0, false) == 0)
00404 decodeExpires(line);
00405 else if (line.find("Timestamp:", 0, false) == 0)
00406 decodeTimestamp(line);
00407 else if (line.find("Content-Type:", 0, false) == 0)
00408 decodeContentType(line);
00409 else if (line.find("WWW-Authenticate:", 0, false) == 0)
00410 decodeAuthenticate(line);
00411 else if (line.find("Proxy-Authenticate:", 0, false) == 0)
00412 decodeAuthenticate(line);
00413 }
00414
00415 void SipMsg::decodeRequestLine(QString line)
00416 {
00417 QString Token = line.section(' ', 0, 0);
00418 if ((Token == "INVITE") || (Token == "ACK") || (Token == "BYE") || (Token == "CANCEL") || (Token == "REGISTER") || (Token == "SUBSCRIBE") || (Token == "NOTIFY") || (Token == "MESSAGE") || (Token == "INFO") || (Token == "OPTIONS"))
00419 thisMethod = Token;
00420 else if (Token == "SIP/2.0")
00421 {
00422 thisMethod = "STATUS";
00423 statusCode = (line.section(' ', 1, 1)).toInt();
00424 statusText = line.section(' ', 2, -1);
00425 }
00426 else
00427 thisMethod = "UNKNOWN-" + Token;
00428 }
00429
00430 void SipMsg::decodeVia(QString via)
00431 {
00432 if ((via.find("Via: SIP/2.0/UDP", 0, false) == 0) && (viaIp.length() == 0))
00433 {
00434 QString str1 = via.mid(17);
00435 QString str2 = str1.section(';', 0, 0);
00436 QString str3 = str2.section(',', 0, 0);
00437 viaIp = str3.section(':', 0, 0);
00438 QString viaPortStr = str3.section(':', 1, 1);
00439 viaPort = (viaPortStr.length() != 0) ? viaPortStr.toInt() : 5060;
00440 }
00441 completeVia += via + "\r\n";
00442 }
00443
00444 void SipMsg::decodeAuthenticate(QString auth)
00445 {
00446 authMethod = auth.section(' ', 1, 1);
00447 QString Params = auth.section(' ', 2);
00448 while (Params.length() > 0)
00449 {
00450 QString thisParam = Params.section(',', 0, 0);
00451 Params.remove(0, thisParam.length()+1);
00452 QString temp = Params.stripWhiteSpace();
00453 Params = temp;
00454
00455 QString thisParamNoWs = thisParam.stripWhiteSpace();
00456 QString ParamName = thisParamNoWs.section('=', 0, 0);
00457 QString ParamValue = thisParamNoWs.section('=', 1);
00458 QString ParamValueNoQuotes = (ParamValue.startsWith("\"")) ? ParamValue.section('\"', 1, 1) : ParamValue;
00459
00460 if (ParamName == "realm")
00461 authRealm = ParamValueNoQuotes;
00462 else if (ParamName == "nonce")
00463 authNonce = ParamValueNoQuotes;
00464 else if (ParamName == "qop")
00465 {
00466 if (ParamValueNoQuotes != "auth")
00467 cout << "SIP: QOP value not set to AUTH in Challenge\n";
00468 }
00469 else
00470 cout << "SIP: Unknown parameter in -Authenticate; " << ParamName << endl;
00471 }
00472 }
00473
00474 void SipMsg::decodeFrom(QString from)
00475 {
00476 if (fromUrl != 0)
00477 delete fromUrl;
00478 fromUrl = decodeUrl(from.mid(6));
00479 QString temp1 = from.section(";tag=", 1, 1);
00480 QString temp2 = from.section(";epid=", 1, 1);
00481 fromTag = temp1.section(";", 0, 0);
00482 fromEpid = temp2.section(";", 0, 0);
00483 completeFrom = from + "\r\n";
00484 }
00485
00486 void SipMsg::decodeTo(QString to)
00487 {
00488 if (toUrl != 0)
00489 delete toUrl;
00490 toUrl = decodeUrl(to.mid(4));
00491 QString temp = to.section(";tag=", 1, 1);
00492 toTag = temp.section(";", 0, 0);
00493 completeTo = to + "\r\n";
00494 }
00495
00496 void SipMsg::decodeContact(QString contact)
00497 {
00498 if (contactUrl != 0)
00499 delete contactUrl;
00500 contactUrl = decodeUrl(contact.mid(9));
00501 QString temp = contact.section(";expires=", 1, 1);
00502 QString expiresStr = temp.section(";", 0, 0);
00503 if (expiresStr.length() > 0)
00504 Expires = expiresStr.toInt();
00505 }
00506
00507 void SipMsg::decodeRecordRoute(QString rr)
00508 {
00509 if (recRouteUrl != 0)
00510 delete recRouteUrl;
00511 recRouteUrl = decodeUrl(rr.mid(14));
00512 completeRR += rr + "\r\n";
00513 }
00514
00515 SipUrl *SipMsg::decodeUrl(QString source)
00516 {
00517 QString str1, str2, str3, str4, str5, str6, str7, str8, str9, str10;
00518 int Port = 0;
00519
00520
00521
00522
00523
00524
00525
00526
00527 str3 = str7 = str9 = "";
00528 str1 = source.section(';', 0, 0);
00529 if (str1.contains('<'))
00530 {
00531 str2 = str1.section('<', 0, 0);
00532 str3 = (str2.startsWith("\"")) ? str2.section('\"', 1, 1) : str2.stripWhiteSpace();
00533 str4 = str1.section('<', 1, 1);
00534 str5 = str4.section('>', 0, 0);
00535 }
00536 else
00537 str5 = str1;
00538
00539 if (str5.startsWith("sip:"))
00540 {
00541 str6 = str5.mid(4);
00542 if (str6.contains('@'))
00543 {
00544 str7 = str6.section('@', 0, 0);
00545 str8 = str6.section('@', 1, 1);
00546 }
00547 else
00548 {
00549 str7 = "";
00550 str8 = str6;
00551 }
00552 str9 = str8.section(':', 0, 0);
00553 str10 = str8.section(':', 1, 1);
00554 Port = (str10.length() > 0) ? str10.toInt() : 5060;
00555 }
00556
00557 return new SipUrl(str3, str7, str9, Port);
00558 }
00559
00560 void SipMsg::decodeCseq(QString cseq)
00561 {
00562 cseqValue = (cseq.section(' ', 1, 1)).toInt();
00563 cseqMethod = cseq.section(' ', 2, 2);
00564 }
00565
00566 void SipMsg::decodeExpires(QString Exp)
00567 {
00568 Expires = (Exp.section(' ', 1, 1)).toInt();
00569 }
00570
00571 void SipMsg::decodeTimestamp(QString ts)
00572 {
00573 Timestamp = (ts.section(' ', 1, 1)).toInt();
00574 }
00575
00576 void SipMsg::decodeCallid(QString callid)
00577 {
00578 if (callId == 0)
00579 callId = new SipCallId;
00580 callId->setValue(callid.section(' ', 1, 1));
00581 }
00582
00583 void SipMsg::decodeContentType(QString cType)
00584 {
00585 QString content = cType.section(' ', 1, 1);
00586 if (content.startsWith("application/sdp"))
00587 msgContainsSDP = true;
00588 if (content.startsWith("application/xpidf+xml"))
00589 msgContainsXPIDF = true;
00590 if (content.startsWith("text/plain"))
00591 msgContainsPlainText = true;
00592 }
00593
00594
00595 void SipMsg::decodeSdp(QString content)
00596 {
00597 QStringList sdpList = QStringList::split("\r\n", content, true);
00598 QStringList::Iterator it;
00599 if (sdp != 0)
00600 delete sdp;
00601 sdp = new SipSdp("", 0, 0);
00602 QPtrList<sdpCodec> *codecList = 0;
00603 for (it=sdpList.begin(); (it != sdpList.end()) && (*it != ""); it++)
00604 {
00605 codecList = decodeSDPLine(*it, codecList);
00606 }
00607 }
00608
00609 void SipMsg::decodeXpidf(QString content)
00610 {
00611 if (xpidf != 0)
00612 delete xpidf;
00613 xpidf = new SipXpidf();
00614
00615 QDomDocument xmlContent;
00616 xmlContent.setContent(content);
00617 QDomElement rootElm = xmlContent.documentElement();
00618 QDomNode n = rootElm.firstChild();
00619 while (!n.isNull())
00620 {
00621 QDomElement e = n.toElement();
00622 if (!e.isNull())
00623 {
00624 if (e.tagName() == "address")
00625 {
00626 QString uri1, uri2, uri3;
00627
00628 uri1 = e.attribute("uri");
00629 if (uri1.startsWith("sip:"))
00630 uri2 = uri1.mid(4);
00631 else
00632 uri2 = uri1;
00633 uri3 = uri2.section(';',0,0);
00634
00635 xpidf->setUserHost(uri3.section('@',0,0), uri3.section('@',1,1));
00636 }
00637 else if (e.tagName() == "status")
00638 xpidf->setStatus(e.attribute("status"));
00639 else if (e.tagName() == "msnsubstatus")
00640 xpidf->setSubStatus(e.attribute("substatus"));
00641 }
00642 QDomNode nextNode = n.firstChild();
00643 if (nextNode.isNull())
00644 nextNode = n.nextSibling();
00645 if (nextNode.isNull())
00646 nextNode = n.parentNode().nextSibling();
00647 n = nextNode;
00648 }
00649 }
00650
00651 void SipMsg::decodePlainText(QString content)
00652 {
00653 PlainTextContent = content;
00654 }
00655
00656 QPtrList<sdpCodec> *SipMsg::decodeSDPLine(QString sdpLine, QPtrList<sdpCodec> *codecList)
00657 {
00658 if (sdpLine.startsWith("c="))
00659 decodeSDPConnection(sdpLine);
00660 else if (sdpLine.startsWith("m="))
00661 codecList = decodeSDPMedia(sdpLine);
00662 else if (sdpLine.startsWith("a="))
00663 decodeSDPMediaAttribute(sdpLine, codecList);
00664 return codecList;
00665 }
00666
00667 void SipMsg::decodeSDPConnection(QString c)
00668 {
00669 if (sdp)
00670 {
00671 sdp->setMediaIp(c.section(' ', 2, 2));
00672 }
00673 }
00674
00675 QPtrList<sdpCodec> *SipMsg::decodeSDPMedia(QString m)
00676 {
00677 if (sdp)
00678 {
00679 int c=0;
00680 QString s;
00681 if (m.startsWith("m=audio"))
00682 {
00683 sdp->setAudioPort((m.section(' ', 1, 1)).toInt());
00684 while ((s = m.section(' ', c+3, c+3)) != 0)
00685 {
00686 sdp->addAudioCodec(s.toInt(), "");
00687 c++;
00688 }
00689 return (sdp->getAudioCodecList());
00690 }
00691 else if (m.startsWith("m=video"))
00692 {
00693 sdp->setVideoPort((m.section(' ', 1, 1)).toInt());
00694 while ((s = m.section(' ', c+3, c+3)) != 0)
00695 {
00696 sdp->addVideoCodec(s.toInt(), "", "");
00697 c++;
00698 }
00699 return (sdp->getVideoCodecList());
00700 }
00701 }
00702 return 0;
00703 }
00704
00705 void SipMsg::decodeSDPMediaAttribute(QString a, QPtrList<sdpCodec> *codecList)
00706 {
00707 if ((codecList != 0) && ((a.startsWith("a=rtpmap:")) || (a.startsWith("a=fmtp:"))))
00708 {
00709 QString attrib = a.section(':', 1, 1);
00710 int payload = (attrib.section(' ', 0, 0)).toInt();
00711
00712 sdpCodec *c;
00713 for (c=codecList->first(); c; c=codecList->next())
00714 {
00715 if (c->intValue() == payload)
00716 {
00717 if (a.startsWith("a=rtpmap:"))
00718 c->setName(attrib.section(' ', 1, 1));
00719 else
00720 c->setFormat(attrib.section(' ', 1, 1));
00721 }
00722 }
00723 }
00724 }
00725
00726
00728
00730
00731 SipUrl::SipUrl(QString url, QString DisplayName)
00732 {
00733 thisDisplayName = DisplayName;
00734 QString temp = url;
00735 if (url.startsWith("sip:"))
00736 url = temp.mid(4);
00737 QString PortStr = url.section(':', 1, 1);
00738 thisPort = PortStr.length() > 0 ? PortStr.toInt() : 5060;
00739 QString temp1 = url.section(':', 0, 0);
00740 thisUser = temp1.section('@', 0, 0);
00741 thisHostname = temp1.section('@', 1, 1);
00742 HostnameToIpAddr();
00743 encode();
00744 }
00745
00746 SipUrl::SipUrl(QString dispName, QString User, QString Hostname, int Port)
00747 {
00748 thisDisplayName = dispName;
00749 thisUser = User;
00750 thisHostname = Hostname;
00751 thisPort = Port;
00752
00753 if (Hostname.contains(':'))
00754 {
00755 thisHostname = Hostname.section(':', 0, 0);
00756 thisPort = atoi(Hostname.section(':', 1, 1));
00757 }
00758
00759 HostnameToIpAddr();
00760 encode();
00761 }
00762
00763 SipUrl::SipUrl(SipUrl *orig)
00764 {
00765 thisDisplayName = orig->thisDisplayName;
00766 thisUser = orig->thisUser;
00767 thisHostname = orig->thisHostname;
00768 thisPort = orig->thisPort;
00769 thisUrl = orig->thisUrl;
00770 thisHostIp = orig->thisHostIp;
00771 }
00772
00773 void SipUrl::HostnameToIpAddr()
00774 {
00775 if (thisHostname.length() > 0)
00776 {
00777 QHostAddress ha;
00778 ha.setAddress(thisHostname);
00779 if (ha.toString() != thisHostname)
00780 {
00781
00782 struct hostent *h;
00783 h = gethostbyname((const char *)thisHostname);
00784 if (h != 0)
00785 {
00786 ha.setAddress(ntohl(*(long *)h->h_addr));
00787 thisHostIp = ha.toString();
00788 }
00789 else
00790 thisHostIp = "";
00791 }
00792 else
00793 thisHostIp = thisHostname;
00794 }
00795 else
00796 thisHostIp = "";
00797 }
00798
00799 void SipUrl::encode()
00800 {
00801 QString PortStr = "";
00802 thisUrl = "";
00803 if (thisPort != 5060)
00804 PortStr = QString(":") + QString::number(thisPort);
00805 if (thisDisplayName.length() > 0)
00806 thisUrl = "\"" + thisDisplayName + "\" ";
00807 thisUrl += "<sip:";
00808 if (thisUser.length() > 0)
00809 thisUrl += thisUser + "@";
00810 thisUrl += thisHostname + PortStr + ">";
00811 }
00812
00813 QString SipUrl::formatReqLineUrl()
00814 {
00815 QString s("sip:");
00816 if (thisUser.length() > 0)
00817 s += thisUser + "@";
00818 s += thisHostname;
00819 if (thisPort != 5060)
00820 s += ":" + QString::number(thisPort);
00821 return s;
00822 }
00823
00824 QString SipUrl::formatContactUrl()
00825 {
00826 QString s("<sip:");
00827 s += thisHostIp;
00828 if (thisPort != 5060)
00829 s += ":" + QString::number(thisPort);
00830 s += ">";
00831 return s;
00832 }
00833
00834 SipUrl::~SipUrl()
00835 {
00836 }
00837
00838
00839
00841
00843
00844 int callIdEnumerator = 0x6243;
00845
00846 SipCallId::SipCallId(QString ip)
00847 {
00848 Generate(ip);
00849 }
00850
00851 SipCallId::~SipCallId()
00852 {
00853 }
00854
00855 void SipCallId::Generate(QString ip)
00856 {
00857 QString now = (QDateTime::currentDateTime()).toString("hhmmsszzz-ddMMyyyy");
00858 thisCallid = QString::number(callIdEnumerator++,16) + "-" + now + "@" + ip;
00859 }
00860
00861 bool SipCallId::operator== (SipCallId &rhs)
00862 {
00863 bool match = (thisCallid.compare(rhs.string()) == 0);
00864 return match;
00865 }
00866
00867 SipCallId &SipCallId::operator= (SipCallId &rhs)
00868 {
00869 if (this == &rhs)
00870 return *this;
00871
00872 thisCallid = rhs.thisCallid;
00873
00874 return *this;
00875 }
00876
00877
00878
00879
00881
00883
00884 SipSdp::SipSdp(QString IP, int aPort, int vPort)
00885 {
00886 audioPort = aPort;
00887 videoPort = vPort;
00888 MediaIp = IP;
00889 thisSdp = "";
00890 }
00891
00892 SipSdp::~SipSdp()
00893 {
00894 sdpCodec *c;
00895 while ((c=audioCodec.first()) != 0)
00896 {
00897 audioCodec.remove();
00898 delete c;
00899 }
00900 while ((c=videoCodec.first()) != 0)
00901 {
00902 videoCodec.remove();
00903 delete c;
00904 }
00905 }
00906
00907 void SipSdp::addAudioCodec(int c, QString descr, QString fmt)
00908 {
00909 audioCodec.append(new sdpCodec(c, descr, fmt));
00910 }
00911
00912 void SipSdp::addVideoCodec(int c, QString descr, QString fmt)
00913 {
00914 videoCodec.append(new sdpCodec(c, descr, fmt));
00915 }
00916
00917 void SipSdp::encode()
00918 {
00919 sdpCodec *c;
00920
00921 thisSdp = "v=0\r\n"
00922 "o=Myth-UA 0 0 IN IP4 " + MediaIp + "\r\n"
00923 "s=SIP Call\r\n"
00924 "c=IN IP4 " + MediaIp + "\r\n"
00925 "t=0 0\r\n";
00926
00927 if ((audioPort != 0) && (audioCodec.count()>0))
00928 {
00929 thisSdp += QString("m=audio ") + QString::number(audioPort) + " RTP/AVP";
00930 for (c=audioCodec.first(); c; c=audioCodec.next())
00931 thisSdp += " " + QString::number(c->intValue());
00932 thisSdp += "\r\n";
00933 for (c=audioCodec.first(); c; c=audioCodec.next())
00934 thisSdp += QString("a=rtpmap:") + QString::number(c->intValue()) + " " + c->strValue() + "\r\n";
00935 for (c=audioCodec.first(); c; c=audioCodec.next())
00936 if (c->fmtValue() != "")
00937 thisSdp += "a=fmtp:" + QString::number(c->intValue()) + " " + c->fmtValue() + "\r\n";
00938 thisSdp += "a=ptime:20\r\n";
00939 }
00940
00941 if ((videoPort != 0) && (videoCodec.count()>0))
00942 {
00943 thisSdp += QString("m=video ") + QString::number(videoPort) + " RTP/AVP";
00944 for (c=videoCodec.first(); c; c=videoCodec.next())
00945 thisSdp += " " + QString::number(c->intValue());
00946 thisSdp += "\r\n";
00947 for (c=videoCodec.first(); c; c=videoCodec.next())
00948 thisSdp += QString("a=rtpmap:") + QString::number(c->intValue()) + " " + c->strValue() + "\r\n";
00949 for (c=videoCodec.first(); c; c=videoCodec.next())
00950 if (c->fmtValue() != "")
00951 thisSdp += "a=fmtp:" + QString::number(c->intValue()) + " " + c->fmtValue() + "\r\n";
00952 }
00953
00954 }
00955
00956
00957
00959
00961
00962 SipXpidf::SipXpidf()
00963 {
00964 user = "";
00965 host = "";
00966 sipStatus = "open";
00967 sipSubstatus = "online";
00968 }
00969
00970 SipXpidf::SipXpidf(SipUrl &Url)
00971 {
00972 user = Url.getUser();
00973 host = Url.getHost();
00974 sipStatus = "open";
00975 sipSubstatus = "online";
00976 }
00977
00978 QString SipXpidf::encode()
00979 {
00980 QString xpidf = "<?xml version=\"1.0\"?>\n"
00981 "<!DOCTYPE presence\n"
00982 "PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
00983 "<presence>\n"
00984 "<presentity uri=\"sip:" + user + "@" + host + ";method=SUBSCRIBE\" />\n"
00985 "<atom id=\"1000\">\n"
00986 "<address uri=\"sip:" + user + "@" + host + ";user=ip\" priority=\"0.800000\">\n"
00987 "<status status=\"" + sipStatus + "\" />\n"
00988 "<msnsubstatus substatus=\"" + sipSubstatus + "\" />\n"
00989 "</address>\n"
00990 "</atom>\n"
00991 "</presence>";
00992 return xpidf;
00993 }
00994
00995
00996