2011-06-13 17:56:35 +00:00
|
|
|
"
|
2014-02-14 16:23:42 +00:00
|
|
|
(C) 2011-2014 by Holger Hans Peter Freyther
|
2011-06-13 17:56:35 +00:00
|
|
|
All Rights Reserved
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"
|
|
|
|
|
|
|
|
PP.PPCompositeParserTest subclass: SIPParserTest [
|
2013-03-31 15:08:18 +00:00
|
|
|
<category: 'OsmoSIP-Parser-Tests'>
|
2011-06-13 17:56:35 +00:00
|
|
|
<comment: 'I excercise the SIPParser a bit'>
|
|
|
|
|
|
|
|
parserClass [
|
|
|
|
<category: 'accessing'>
|
|
|
|
^ SIPParser
|
|
|
|
]
|
|
|
|
|
2011-06-30 09:41:50 +00:00
|
|
|
testResponseData [
|
|
|
|
^ (WriteStream on: (String new))
|
|
|
|
nextPutAll: 'SIP/2.0 480 Temporarily Unavailable'; cr; nl;
|
2011-07-06 16:47:07 +00:00
|
|
|
nextPutAll: 'Via: SIP/2.0/UDP 172.16.254.34;rport;branch=z9hG4bKMzQ4NTQzNDgxNCwyNDE1Nw__;received=172.16.254.55;ttl=123;bla=foo;maddr=www.moo.de;'; cr; nl;
|
2011-06-30 09:41:50 +00:00
|
|
|
nextPutAll: 'From: <sip:1000@on-waves.com>;tag=MzQ4NTQ0MTg2NzIyNDEwNjkyNjY_'; cr; nl;
|
|
|
|
nextPutAll: 'To: <sip:9198@172.16.1.72>;tag=42eBv22Fj314N;abc=def;kbc;ajk'; cr; nl;
|
|
|
|
nextPutAll: 'Call-ID: MzY3NzE3ODgyNw__@xiaoyu'; cr; nl;
|
|
|
|
nextPutAll: 'CSeq: 1 INVITE'; cr; nl;
|
|
|
|
nextPutAll: 'User-Agent: FreeSWITCH-mod_sofia/1.0.head-git-dff41af 2011-04-20 14-11-24 +0200'; cr; nl;
|
|
|
|
nextPutAll: 'Accept: application/sdp'; cr; nl;
|
|
|
|
nextPutAll: 'Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE'; cr; nl;
|
|
|
|
nextPutAll: 'Supported: timer, precondition, path, replaces'; cr; nl;
|
|
|
|
nextPutAll: 'Allow-Events: talk, hold, presence, dialog, line-seize, call-info, sla, include-session-description, presence.winfo, message-summary, refer'; cr; nl;
|
|
|
|
nextPutAll: 'Reason: Q.850;cause=96;text="MANDATORY_IE_MISSING"'; cr; nl;
|
|
|
|
nextPutAll: 'Content-Length: 0'; cr; nl;
|
|
|
|
nextPutAll: 'Remote-Party-ID: "9198" <sip:9198@172.16.1.72>;party=calling;privacy=off;screen=no'; cr; nl; cr;nl;
|
|
|
|
contents.
|
|
|
|
]
|
|
|
|
|
2011-07-05 15:14:12 +00:00
|
|
|
testByeRequestData [
|
|
|
|
^ (WriteStream on: (String new))
|
|
|
|
nextPutAll: 'BYE sip:osmo_st_sip@213.167.137.242:1187 SIP/2.0'; cr; nl;
|
|
|
|
nextPutAll: 'Via: SIP/2.0/UDP 172.16.1.72:4000;ttl=16;maddr=224.2.0.1;rport;branch=z9hG4bKvt9FDU96c89cQ'; cr;nl;
|
|
|
|
nextPutAll: 'Max-Forwards: 70'; cr; nl;
|
|
|
|
nextPutAll: 'From: <sip:1000@172.16.1.72>;tag=tFFg06FKH425D'; cr; nl;
|
|
|
|
nextPutAll: 'To: <sip:1000@on-waves.com>;tag=MzQ4NzMzMjcxMTUyNDc1OTI2OA__'; cr; nl;
|
|
|
|
nextPutAll: 'Call-ID: MzkwNzQ1NTM2Nw__@xiaoyu'; cr; nl;
|
|
|
|
nextPutAll: 'CSeq: 14600327 BYE'; cr; nl;
|
|
|
|
nextPutAll: 'Contact: <sip:1000@172.16.1.72:5060;transport=udp>'; cr; nl;
|
|
|
|
nextPutAll: 'User-Agent: FreeSWITCH-mod_sofia/1.0.head-git-2e651c8 2011-07-03 22-35-44 -0500'; cr; nl;
|
|
|
|
nextPutAll: 'Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE'; cr; nl;
|
|
|
|
nextPutAll: 'Supported: timer, precondition, path, replaces'; cr; nl;
|
|
|
|
nextPutAll: 'Reason: Q.850;cause=16;text="NORMAL_CLEARING"'; cr; nl;
|
|
|
|
nextPutAll: 'Content-Length: 0'; cr; nl;
|
|
|
|
cr; nl; contents
|
2012-08-05 14:43:34 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
testOPTIONSRequestData [
|
|
|
|
^ (WriteStream on: String new)
|
|
|
|
nextPutAll: 'OPTIONS sip:127.0.0.1:5061 SIP/2.0'; cr; nl;
|
|
|
|
nextPutAll: 'Via: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK1492385841'; cr; nl;
|
|
|
|
nextPutAll: 'Route: "123456" <sip:123456@127.0.0.1>;tag=oxivb'; cr; nl;
|
|
|
|
nextPutAll: 'From: <sip:%60123456@127.0.0.1>;tag=70812965'; cr; nl;
|
|
|
|
nextPutAll: 'To: "123456" <sip:123456@127.0.0.1>;tag=oxivb'; cr; nl;
|
|
|
|
nextPutAll: 'Call-ID: 486321292'; cr; nl;
|
|
|
|
nextPutAll: 'CSeq: 20 OPTIONS'; cr; nl;
|
|
|
|
nextPutAll: 'Accept: application/sdp'; cr; nl;
|
|
|
|
nextPutAll: 'Max-Forwards: 70'; cr; nl;
|
|
|
|
nextPutAll: 'User-Agent: Linphone/3.4.3 (eXosip2/3.6.0)'; cr; nl;
|
|
|
|
nextPutAll: 'Content-Length: 0'; cr; nl;
|
|
|
|
cr; nl; contents
|
|
|
|
]
|
2011-07-05 15:14:12 +00:00
|
|
|
|
2012-08-05 14:43:34 +00:00
|
|
|
testOPTIONSRequest [
|
|
|
|
| res |
|
2011-07-05 15:14:12 +00:00
|
|
|
|
2012-08-05 14:43:34 +00:00
|
|
|
res := self parse: self testOPTIONSRequestData.
|
|
|
|
self assert: res asDatagram = self testOPTIONSRequestData.
|
2011-07-05 15:14:12 +00:00
|
|
|
]
|
|
|
|
|
2011-06-13 17:56:35 +00:00
|
|
|
testResponse [
|
2011-07-05 09:18:45 +00:00
|
|
|
| res |
|
2011-06-30 09:41:50 +00:00
|
|
|
|
|
|
|
res := self parse: self testResponseData.
|
|
|
|
self assert: res asDatagram = self testResponseData.
|
2011-06-13 21:09:02 +00:00
|
|
|
self assert: (res parameter: 'Via') branch = 'z9hG4bKMzQ4NTQzNDgxNCwyNDE1Nw__'.
|
2011-06-14 17:34:54 +00:00
|
|
|
self assert: (res parameter: 'CSeq') number = 1.
|
|
|
|
self assert: (res parameter: 'CSeq') method = 'INVITE'.
|
2011-06-30 09:35:38 +00:00
|
|
|
self assert: (res parameter: 'To') tag = '42eBv22Fj314N'.
|
2011-07-05 09:14:55 +00:00
|
|
|
self assert: (res parameter: 'To') address = 'sip:9198@172.16.1.72'.
|
2011-06-30 09:35:38 +00:00
|
|
|
self assert: ((res parameter: 'To') valueAt: 'abc') = 'def'.
|
|
|
|
self assert: ((res parameter: 'To') valueAt: 'kbc') = nil.
|
|
|
|
self assert: ((res parameter: 'To') valueAt: 'ajk') = nil.
|
|
|
|
self should: [((res parameter: 'To') valueAt: 'foo')] raise: SystemExceptions.NotFound.
|
2011-06-30 10:05:27 +00:00
|
|
|
self assert: (res parameter: 'From') tag = 'MzQ4NTQ0MTg2NzIyNDEwNjkyNjY_'.
|
2011-07-05 09:14:55 +00:00
|
|
|
self assert: (res parameter: 'From') address = 'sip:1000@on-waves.com'.
|
|
|
|
]
|
|
|
|
|
|
|
|
testSIPDialog [
|
2011-07-05 09:18:45 +00:00
|
|
|
| dialog |
|
2011-07-05 09:14:55 +00:00
|
|
|
dialog := SIPDialog fromMessage: (self parse: self testResponseData).
|
|
|
|
self
|
|
|
|
assert: dialog to = 'sip:9198@172.16.1.72';
|
|
|
|
assert: dialog to_tag = '42eBv22Fj314N';
|
|
|
|
assert: dialog from = 'sip:1000@on-waves.com';
|
|
|
|
assert: dialog from_tag = 'MzQ4NTQ0MTg2NzIyNDEwNjkyNjY_';
|
|
|
|
assert: dialog callId = 'MzY3NzE3ODgyNw__@xiaoyu';
|
|
|
|
assert: dialog cseq = 1.
|
2011-06-13 17:56:35 +00:00
|
|
|
]
|
2011-07-05 10:06:36 +00:00
|
|
|
|
|
|
|
testDialogCompatible [
|
|
|
|
| initial_dialog dialog1 dialog2 |
|
|
|
|
initial_dialog := (SIPDialog
|
|
|
|
fromUser: 'sip:1000@on-waves.com' host: '0.0.0.0' port: 5060)
|
|
|
|
fromTag: 'MzQ4NTQ0MTg2NzIyNDEwNjkyNjY_';
|
|
|
|
callId: 'MzY3NzE3ODgyNw__@xiaoyu';
|
|
|
|
yourself.
|
|
|
|
self assert: initial_dialog isUnconfirmed.
|
|
|
|
self deny: initial_dialog isConfirmed.
|
|
|
|
|
|
|
|
dialog1 := initial_dialog newFromRequest: (self parse: self testResponseData).
|
|
|
|
self deny: initial_dialog == dialog1.
|
|
|
|
self assert: dialog1 isConfirmed.
|
|
|
|
|
|
|
|
dialog2 := dialog1 newFromRequest: (self parse: self testResponseData).
|
|
|
|
self assert: dialog1 == dialog2.
|
|
|
|
self assert: dialog2 isConfirmed.
|
|
|
|
]
|
2011-07-05 15:14:12 +00:00
|
|
|
|
|
|
|
testByeRequest [
|
|
|
|
| res |
|
|
|
|
|
|
|
|
res := SIPParser parse: self testByeRequestData.
|
|
|
|
self
|
|
|
|
assert: (res parameter: 'Allow' ifAbsent: []) = 'INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE';
|
|
|
|
assert: (res parameter: 'Via' ifAbsent: []) branch = 'z9hG4bKvt9FDU96c89cQ';
|
|
|
|
assert: (res parameter: 'CSeq' ifAbsent: []) number = 14600327.
|
|
|
|
]
|
2012-08-03 09:02:41 +00:00
|
|
|
|
|
|
|
statusResponseData [
|
|
|
|
^ (WriteStream on: String new)
|
|
|
|
nextPutAll: 'SIP/2.0 416 Unsupported URI Scheme'; cr; nl;
|
|
|
|
nextPutAll: 'Via: SIP/2.0/UDP 192.168.0.101:5061;branch=z9hG4bKMzQ4ODYxODcyOCwyMDg0MA__'; cr; nl;
|
|
|
|
nextPutAll: 'From: <sip:1000@osmocom.org>;tag=MzQ4ODYyNTkyODQxMDY0OTAxMzI_'; cr; nl;
|
|
|
|
nextPutAll: 'To: <1000@192.168.0.106>;tag=5UtDUa1DeFa4S'; cr; nl;
|
|
|
|
nextPutAll: 'Call-ID: MTg3NzU0Mjk2MQ__@xiaoyu'; cr; nl;
|
|
|
|
nextPutAll: 'CSeq: 1 INVITE'; cr; nl;
|
|
|
|
nextPutAll: 'User-Agent: FreeSWITCH-mod_sofia/1.0.head-git-7cb0951 2011-06-24 18-28-56 -0500'; cr; nl;
|
|
|
|
nextPutAll: 'Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE'; cr; nl;
|
|
|
|
nextPutAll: 'Supported: timer, precondition, path, replaces'; cr; nl;
|
|
|
|
nextPutAll: 'Content-Length: 0'; cr; nl;
|
|
|
|
cr; nl;
|
|
|
|
contents
|
|
|
|
]
|
|
|
|
|
|
|
|
testStatusResponse [
|
|
|
|
| res dlg |
|
|
|
|
res := SIPParser parse: self statusResponseData.
|
|
|
|
"dlg := SIPDialog fromMessage: res."
|
|
|
|
]
|
2014-02-11 16:33:16 +00:00
|
|
|
|
|
|
|
resultUnauthorized [
|
|
|
|
^(WriteStream on: String new)
|
|
|
|
nextPutAll: 'SIP/2.0 401 Unauthorized'; cr; nl;
|
|
|
|
nextPutAll: 'Via: SIP/2.0/UDP 172.16.252.198:5060;branch=z9hG4bK6cdba079-8b91-e311-8101-844bf52a8297;rport=5060;received=172.16.252.198'; cr; nl;
|
|
|
|
nextPutAll: 'From: <sip:st@127.0.0.2>;tag=12187969-8b91-e311-8101-844bf52a8297'; cr; nl;
|
|
|
|
nextPutAll: 'To: <sip:st@127.0.0.2>'; cr; nl;
|
|
|
|
nextPutAll: 'Call-ID: fc0f7969-8b91-e311-8101-844bf52a8297@xiaoyu'; cr; nl;
|
|
|
|
nextPutAll: 'CSeq: 7 REGISTER'; cr; nl;
|
|
|
|
nextPutAll: 'WWW-Authenticate: Digest realm="Yate", nonce="373ef30b297545cbce99fad09f1409cb.1392124197", stale=TRUE, algorithm=MD5'; cr; nl;
|
|
|
|
nextPutAll: 'Server: YATE/5.1.0'; cr; nl;
|
|
|
|
nextPutAll: 'Allow: ACK, INVITE, BYE, CANCEL, REGISTER, REFER, OPTIONS, INFO'; cr; nl;
|
|
|
|
nextPutAll: 'Content-Length: 0'; cr; nl;
|
|
|
|
cr; nl;
|
|
|
|
contents
|
|
|
|
]
|
|
|
|
|
|
|
|
testWWWAuthRequired [
|
|
|
|
| res auth|
|
|
|
|
res := self parse: self resultUnauthorized.
|
|
|
|
auth := res parameter: 'WWW-Authenticate'.
|
|
|
|
self assert: (auth at: 'realm') equals: 'Yate'.
|
|
|
|
self assert: (auth at: 'nonce') equals: '373ef30b297545cbce99fad09f1409cb.1392124197'.
|
|
|
|
self assert: (auth at: 'stale').
|
|
|
|
self assert: (auth at: 'algorithm') equals: 'MD5'.
|
2014-03-14 12:45:57 +00:00
|
|
|
self assert: (res parameter: 'cAlL-Id') equals: 'fc0f7969-8b91-e311-8101-844bf52a8297@xiaoyu'.
|
2014-02-11 16:33:16 +00:00
|
|
|
]
|
2014-02-14 16:23:42 +00:00
|
|
|
|
|
|
|
authorizationData [
|
|
|
|
"Shortened because we only care about Authorization"
|
|
|
|
^(WriteStream on: String new)
|
|
|
|
nextPutAll: 'INVITE sip:127.0.0.1 SIP/2.0'; cr; nl;
|
|
|
|
nextPutAll: 'Via: SIP/2.0/MOCK 127.0.0.1:5060;branch=z9hG4bKMz'; cr; nl;
|
|
|
|
nextPutAll: 'Authorization: Digest username="st", realm="Yate", nonce="373ef30b297545cbce99fad09f1409cb.1392124197", uri="sip:127.0.0.1", algorithm=MD5, response="bc8dfaa413e897863dbab4c622e4b9b4"'; cr; nl;
|
|
|
|
cr; nl;
|
|
|
|
contents
|
|
|
|
]
|
|
|
|
|
|
|
|
testAuthorization [
|
|
|
|
| res auth|
|
|
|
|
res := self parse: self authorizationData.
|
|
|
|
auth := res parameter: 'Authorization' ifAbsent: [nil].
|
|
|
|
self deny: auth isNil.
|
|
|
|
|
|
|
|
self assert: auth username equals: 'st'.
|
|
|
|
self assert: auth realm equals: 'Yate'.
|
|
|
|
self assert: auth nonce equals: '373ef30b297545cbce99fad09f1409cb.1392124197'.
|
|
|
|
self assert: auth uri equals: 'sip:127.0.0.1'.
|
|
|
|
self assert: auth response equals: 'bc8dfaa413e897863dbab4c622e4b9b4'.
|
|
|
|
]
|
2011-06-13 17:56:35 +00:00
|
|
|
]
|