JAIN SIP #9 (Create Invite ตอนที่ 3)

JAIN SIP #9 (Create Invite ตอนที่ 3)

หลัง ๆ  ผมอธิบายไม่ค่อยละเอียด เนื่องจากเริ่มขี้เกียจ + ง่วงนอน ยังไงก็ลองพยายามไล่ code เอาดูด้วยนะครับ มาต่อกันเลยดีกว่า หลังจากที่ส่ง Invite Request ไป ได้รับ Proxy Authen, Trying, Ringing เราก็ส่ง Invite + Authentication แนบไปอีกรอบ คราวนี้ เราควรจะได้ต้องได้รับ 200 OK ตอบกลับมา ไม่งั้น แสดงว่า ต้องมีอะไรผิดพลาดกับ Invite message ที่เราได้ส่งไป

เมื่อผู้รับตอบ 200 OK กลับมา มันก็จะไปเรียกฟังก์ชัน processResponse (เหมือนกับตอนที่ตอบ Proxy Authentication) ซึ่งมีการทำงานดังนี้

    public void processResponse(ResponseEvent responseReceivedEvent) {
        System.out.println("Got a response");
        Response response = (Response) responseReceivedEvent.getResponse();
        ClientTransaction tid = responseReceivedEvent.getClientTransaction();
        CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

        System.out.println("Response received : Status Code = "
                + response.getStatusCode() + " [" +response.getReasonPhrase() + "] "+ cseq);
        if (tid == null) {
            System.out.println("Stray response -- dropping ");
            return;
        }

        try {
            if (response.getStatusCode() == Response.OK) {
               
                if (cseq.getMethod().equals(Request.INVITE)) {
                    Dialog dialog = inviteTid.getDialog();
                    Request ackRequest = dialog.createAck( ((CSeqHeader) response
                            .getHeader(CSeqHeader.NAME)).getSeqNumber() );
                    System.out.println("Sending ACK from Invite");
                    dialog.sendAck(ackRequest);

                    //---------- Start SDP Split ---------------------
                    //------ I don't know how to get SDP data, ---
                    //    then I split it by from response object
                    String respString = (String) response.toString();
                    String addrRecv = "";
                    String portRecv = "";

                    StringTokenizer Tok = new StringTokenizer(respString);
                    while (Tok.hasMoreElements()) {
                       String tmp = Tok.nextElement().toString();
                       if ( tmp.equals("IP4") )
                            addrRecv = Tok.nextElement().toString();
                       else if (  tmp.equals("m=audio") )
                            portRecv  = Tok.nextElement().toString();
                    }
                    //System.out.println("IP  = " + addrRecv + " \nport  = " + portRecv);
                    //---------- End SDP Split ---------------------


                    // ----------- Start Receiver -----------------
                    recRTP = new Receive(audioPort);    

                    // ----------- Start Receiver -----------------
                    transRTP = new Transmit(addrRecv, Integer.parseInt(portRecv) );
                   
                }

            System.out.println("Finish response process");
         } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("From process Response");
            System.exit(0);
        }

    }

ก็คล้าย ๆ ของเิดิมครับ เราก็ตรวจสอบ Response ว่าเป็น OK และ Request ว่าเป็น Invite หรือไม่ ซึ่งมันก็จะตรงกับกรณีนี้ครับ เราก็ส่ง ACK กลับไปบอกให้ผู้รับได้รู้ว่า ได้รับ 200 OK แล้วนะ จากนั้นก็สามารถจัดตั้งการสื่อสารได้ โดยผมใช้วิธีหาข้อมูลของผู้รับ จาก SDP (Session Description Protocol) ที่แนบมากับ 200 OK เื่พื่อที่จะทราบว่าจะต้องส่งข้อมูลไปที่เครื่อง IP ใด และ port ใด (ใช้ StringTokenizer ในการตัด String)

เมื่อได้ข้อมูลจาก SDP เรียบร้อย ก็จัดการเปิด port รอรับข้อมูล และ ส่งข้อมูลไปหาผู้รับเลย  ตรงนี้ ใช้ความรู้ในเรื่อง JMF และ RTP ครับ ถ้าใครไม่เข้าใจ ลองไปดูบทความเรื่อง JMF Transmit กับ JMF Receive ดูนะครับ

ถ้าลองพิจารณาจาก code จะเห็นได้ว่า SIP นั้นไม่ได้มีส่วนเีกี่ยวกับการส่ง stream RTP เลย ตรงนี้อยู่ที่ JMF ล้วน ๆ SIP ทำหน้าที่เพียงแค่จัดตั้ง session และ ตกลงรายละเอียดเกี่ยวกับการใช้ media ผ่าน SDP เท่านั้นเอง

ตรงนี้มีจุดที่น่าสนใจตรงที่ SDP ที่มันตอบกลับมานั้น ในส่วนของ Connection และ Owner นั้นปรากฎว่าเป็น IP ของ SIP Server แทนที่จะเป็น IP ของผู้รับ นั่นก็คือ ผู้รับส่ง ข้อมูล หาผู้ส่ง โดยตรง แต่ผู้ส่ง ส่งข้อมูลหาผู้รับผ่านทาง SIP Server

เอ... แบบนี้ ถ้าผู้รับอยู่ไกลกับ SIP Server ก็แย่สิ? ... ติดตามตอนต่อไปครับ