JAIN SIP #7 (Create Invite ตอนที่ 1 )
ในที่สุดก็มา ถึงเรื่องการสร้าง Invite เพื่อจัดตั้ง Connection ไปหาผู้รับ โดยหลักการของ SIP หลังจากที่ได้ Register เรียบร้อยแล้ว ก็มาถึงส่วนของการ Invite มี Flow การทำงานดังนี้
ผู้ส่ง ผู้รับ
Invite + SDP ------->
<--- Proxy Authentication
<--- Trying
<--- Ringing
Invite + SDP + Authen -->
<--- 200 OK + SDP
เริ่มต้นกระบวนการ เราก็มาสร้าง Request และ Invite message โดยเรียก method createInvite() จากนั้นเมื่อได้ request เราก็เอาไปสร้างเป็น transaction (เพราะเป็นแบบ stateful) แล้วก็จัดการส่ง Invite Request นี้ไปหา SIP Server (Asterisk) ได้เลยตามโค๊ดตัวอย่าง
| try { Request request = this.createInvite(""); // Create the client transaction. inviteTid = sipProvider.getNewClientTransaction(request); // send the request out. inviteTid.sendRequest(); System.out.println("INVITE with no Authorization sent:\n" + request); dialog = inviteTid.getDialog(); // Print SIP INVITE message } catch (Exception e) { System.out.println("Creating call CreateInvite()"); System.out.println(e.getMessage()); e.printStackTrace(); } |
เอ.... แล้วเจ้่า createInvite(""); มันหน้าตาเป็นอย่างไรนะ? ตามผมมาดูต่อได้เลย
| public Request createInvite(String callId) throws ParseException, InvalidArgumentException { String fromName = "300"; String fromSipAddress = "147.127.240.92"; String fromDisplayName = "pleX - [300]"; String toSipAddress = "147.127.240.92"; String toUser = "200"; String toDisplayName = "Server - [200]"; // Create ViaHeaders ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); ViaHeader viaHeader = headerFactory.createViaHeader(myAddress, sipProvider.getListeningPoint(transport).getPort(), transport, null); // add via headers viaHeaders.add(viaHeader); // create >From Header SipURI fromAddress = addressFactory.createSipURI(fromName, fromSipAddress); Address fromNameAddress = addressFactory.createAddress(fromAddress); fromNameAddress.setDisplayName(fromDisplayName); FromHeader fromHeader = headerFactory.createFromHeader(fromNameAddress, "12345678"); // create To Header SipURI toAddress = addressFactory.createSipURI(toUser, toSipAddress); Address toNameAddress = addressFactory.createAddress(toAddress); toNameAddress.setDisplayName(toDisplayName); ToHeader toHeader = headerFactory.createToHeader(toNameAddress, null); // create Request URI SipURI requestURI = addressFactory.createSipURI(toUser, sipServer); // Create ContentTypeHeader ContentTypeHeader contentTypeHeader = headerFactory .createContentTypeHeader("application", "sdp"); // Create a new CallId header CallIdHeader callIdHeader; callIdHeader = sipProvider.getNewCallId(); // System.out.println("== calID Header1 = " + callIdHeader.getCallId()); if (callId.trim().length() > 0) callIdHeader.setCallId(callId); myCallId = callId; // save value for check Reinvite or New invite // Create a new Cseq header CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(invco++, Request.INVITE); // Create a new MaxForwardsHeader MaxForwardsHeader maxForwards = headerFactory .createMaxForwardsHeader(70); // Create the request. Request request = messageFactory.createRequest(requestURI, Request.INVITE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards); // Create contact headers String host = myAddress; SipURI contactUrl = addressFactory.createSipURI(fromName, host); contactUrl.setPort(udpListeningPoint.getPort()); // Create the contact name address. SipURI contactURI = addressFactory.createSipURI(fromName, host); contactURI.setPort(sipProvider.getListeningPoint(transport).getPort()); Address contactAddress = addressFactory.createAddress(contactURI); // Add the contact address. contactAddress.setDisplayName(fromName); contactHeader = headerFactory.createContactHeader(contactAddress); request.addHeader(contactHeader); String sdpData = "v=0\r\n" + "o=pleX 4010 341 IN IP4 "+ myAddress +"\r\n" + "s=pleX Test SIP Client\r\n" + "c=IN IP4 "+ myAddress +"\r\n" + "t=0 0 \r\n" + "m=audio " + audioPort + " RTP/AVP 0 4 18\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; byte[] contents = sdpData.getBytes(); request.setContent(contents, contentTypeHeader); Header callInfoHeader = headerFactory.createHeader("Call-Info", "<http://www.antd.nist.gov>"); request.addHeader(callInfoHeader); return request; } |
ดูตัวอย่าง code นี้ เริ่มน่ากลัวแฮะ เพราะเริ่มยาว แต่จริง ๆ แล้วก็ไม่มีอะไรครับ ก็ใช้ Header Factory ต่าง ๆ สร้าง header ขึ้น แล้วก็จับ header ที่สร้างมาทั้งหมดยัดใส่ลงไปใน Request เท่านั้นเอง จุดที่น่าสนใจในฟังก์ชันนี้ มีนิดหน่อยตรงที่ if (callId.trim().length() > 0) ซึ่งเงื่อนไขนี้ จะเป็นจริง เมื่อเราทำ Invite ครั้งที่ 2 (ตาม flow ที่อธิบายข้างบน) โดยเราจะดึง callId ซึ่งเป็น String parameter ของ createInvite() อยู่แล้ว ส่วนการส่ง Invite ครั้งแรกนั้น เราสามารถสร้าง Call Id เพื่อไว้อ้างอิง SIP Session ของเราเองได้เลยครับ
ครับ เพียงเท่านี้ เราก็ส่ง Invite ไปหา อีกผู้รับได้แล้ว แต่กระบวนการขั้นตอนการ Invite ยังไม่จบครับ ติดตามตอนต่อไป ... :-)