Fachhochschule Köln University of Applied Sciences Cologne 07 Fakultät für Informations-, Medien- und Elektrotechnik Studiengang Elektrotechnik/NT Institut für Nachrichtentechnik Labor für Datennetze Diplomarbeit Thema: Entwicklung und Untersuchung eines Java basierten VoIP Clients für mobile Endgeräte Student : Bernd Müller Referent : Prof. Dr.-Ing. Andreas Grebe Fachhochschule Köln Korreferent : Dr.-Ing. Christoph Bach Ericsson GmbH Abgabedatum : 13. August 2007 II Hiermit versichere ich, dass ich die Diplomarbeit selbständig angefertigt und keine anderen als die angegebenen und bei Zitaten kenntlich gemachten Quellen und Hilfsmittel benutzt habe. Bernd Müller INHALTSVERZEICHNIS III Inhaltsverzeichnis Abbildungsverzeichnis Tabellenverzeichnis Einleitung 1 Grundlagen VoIP V VII 1 2 1.1 Funktionsprinzip........................................................................................... 2 1.2 Verbindungsaufbau...................................................................................... 3 1.3 QoS / Sprachqualität................................................................................... 3 1.4 Codecs....................................................................................................... 5 2 Protokolle 7 2.1 SIP (Session Initiation Protocol)...................................................................... 7 2.1.1 Komponenten.................................................................................... 8 2.1.2 SIP-Nachrichten.................................................................................. 9 2.1.3 SIP-Verbindungsaufbau..................................................................... 13 2.2 SDP (Session Description Protocol)............................................................... 15 2.3 RTP (Real-Time Transport Protocol).............................................................. 16 2.4 RTP-Proxy.................................................................................................. 18 2.5 RTCP (Real Time Control Protocol)............................................................... 18 3 Der MjSIP-Stack 19 3.1 MjServer.................................................................................................... 20 3.2 MjUA........................................................................................................ 21 3.3 MjSIPME................................................................................................... 23 3.4 Konfiguration............................................................................................. 24 4 Java Sound 30 4.1 Aufnahme / Wiedergabe ............................................................................ 33 INHALTSVERZEICHNIS IV 4.2 Alternative zu Java Sound........................................................................... 36 5 Mobile Endgeräte 37 5.1 Sony Ericsson P990i................................................................................... 37 5.1.1 Java Plattform (J2ME)........................................................................ 38 5.1.2 Installation....................................................................................... 41 5.1.3 Implementierung auf der CDC Plattform............................................. 43 5.1.4 Implementierung auf der CLDC Plattform............................................ 46 5.1.5 Fazit................................................................................................ 49 5.2 Nokia 770................................................................................................ 50 5.2.1 Java Plattform.................................................................................. 51 5.2.2 Blackdown JRE................................................................................. 53 5.2.3 JaLiMo............................................................................................ 54 5.2.4 Implementierung............................................................................... 56 5.2.5 Fazit................................................................................................ 59 5.3 HP iPAQ hx4700....................................................................................... 60 5.3.1 Mysaifu JVM..................................................................................... 61 6 Design und Implementierung 64 6.1 JQoS........................................................................................................ 64 6.2 Test und Implementierung........................................................................... 70 6.3 Performance.............................................................................................. 73 7 Fazit und Ausblick 74 Abkürzungsverzeichnis 76 Quellenverzeichnis 78 Anhang A 81 Technische Daten der mobilen Endgeräte.......................................................... 81 Screenshots.................................................................................................... 84 Quellcode...................................................................................................... 86 ABBILDUNGSVERZEICHNIS V Abbildungsverzeichnis Abbildung 1.1: VoIP Funktionsprinzip...................................................................... 2 Abbildung 1.2: ToS-Feld (Quelle:[tospic])................................................................ 4 Abbildung 2.1: Einordnung der Protokolle im OSI-Modell......................................... 7 Abbildung 2.2: Verbindungsaufbau mit Proxy-Server................................................. 8 Abbildung 2.3: Beispiel INVITE-Request................................................................. 11 Abbildung 2.4: Beispiel einer SIP-Response............................................................ 13 Abbildung 2.5: einfacher Verbindungsaufbau......................................................... 13 Abbildung 2.6: Verbindungsaufbau über SIP-Server................................................ 14 Abbildung 2.7: Beispiel eines SDP-Pakets.............................................................. 15 Abbildung 2.8: RTP-Header.................................................................................. 17 Abbildung 2.9: Beispiel eines RTP-Pakets............................................................... 18 Abbildung 2.10: RTP-Proxy................................................................................... 18 Abbildung 3.1: MjSIP Verzeichnisstruktur................................................................ 20 Abbildung 3.2: MjSIP GraphicalUA....................................................................... 21 Abbildung 3.3: Beispiel Java DataLines................................................................. 27 Abbildung 3.4: SDP (Media Attribut "rtpmap:0 GSM/8000“)................................... 28 Abbildung 3.5: RTP-Paket (PCMU- statt GSM-Payload)........................................... 28 Abbildung 4.1: Line Interface Hierarchie................................................................ 30 Abbildung 4.2: Darstellung der Interfaces.............................................................. 31 Abbildung 5.1: Sony Ericsson P990i...................................................................... 37 Abbildung 5.2: Java 2 Plattformen (Quelle: [dsj2me])............................................. 38 Abbildung 5.3: J2ME Klassenbibliotheken.............................................................. 39 Abbildung 5.4: P990i CLDC Aufbau..................................................................... 40 Abbildung 5.5: P990i CDC Aufbau....................................................................... 41 Abbildung 5.6: Netbeans CDC GUI Designer (Quelle: [netb])................................. 42 Abbildung 5.7: API Vergleich von J2SE1.4.2 / FP1.1 / PBP1.1 / PP1.1..................... 43 Abbildung 5.8: Sony Ericsson CDC API Vergleich (Quelle: [dgcdc]).......................... 44 Abbildung 5.9: MjSIPME CLDC Plattform............................................................... 46 Abbildung 5.10: MjSIPME SIP-Nachricht................................................................ 47 ABBILDUNGSVERZEICHNIS VI Abbildung 5.11: Nokia 770................................................................................. 50 Abbildung 5.12: JaLiMo Java Gnome GUI (Quelle: [jalimo])................................... 55 Abbildung 5.13: HP iPAQ hx4700........................................................................ 60 Abbildung 5.14: Mysaifu Auswahl Dialog.............................................................. 61 Abbildung 5.15: AWT Demo................................................................................ 63 Abbildung 5.16: Image Viewer............................................................................. 63 Abbildung 6.1: Eclipse IDE................................................................................... 64 Abbildung 6.2: MjSIP Instanzen............................................................................ 65 TABELLENVERZEICHNIS VII Tabellenverzeichnis Tabelle 1: VoIP-Codecs (Quelle: [rtppar])................................................................ 6 Tabelle 2: SIP Status-Codes (Quelle: [sippar])........................................................ 11 Tabelle 3: SIP-Header.......................................................................................... 12 Tabelle 4: SDP-Parameter.................................................................................... 15 Tabelle 5: Java Support für Pocket PC (Quelle: [jsoppc])......................................... 52 Tabelle 6: Sony Ericsson P990i technische Daten.................................................... 81 Tabelle 7: Nokia 770 technische Daten................................................................. 82 Tabelle 8: HP iPAQ hx4700 technische Daten....................................................... 83 EINLEITUNG 1 Einleitung Entwickler von mobilen Endgeräten statten die Geräte inzwischen mit einer Technik, vergleichbar mit herkömmlichen Desktop PCs, aus. Diese Geräte besitzen inzwischen nicht nur Übertragungsstandards wie Infrarot, sondern auch Bluetooth und WLAN (Wireless LAN). Heutzutage wird fast jeder Internetanschluss mit einem WLAN-Router betrieben. Diese Funkverbindung können auch mobile Endgeräte für den Internetzugang nutzen. Da die Preise für Telefongespräche über die Mobilfunknetze immer noch recht teurer sind, bietet es sich an mit mobilen Endgeräten (z.B. Handys u. Pocket PCs) kostengünstig, untereinander auch kostenlos (durch gleichen Provider), VoIP (Voice over IP)Gespräche zu führen. Dazu stehen heute zahlreiche Zugangspunkte in Cafés, Hotels, Flughäfen, Bahnhöfen etc. zur Verfügung. Da es eine sehr große Anzahl von Geräten auf dem Markt gibt, die zum größten Teil auf unterschiedlichen Plattformen basieren, wird eine plattformunabhängigen VoIPImplementierung benötigt, um diese Applikation auf verschieden Endgeräten nutzen zu können. Im Rahmen dieser Diplomarbeit soll versucht werden eine plattformunabhängige VoIPApplikation basierend auf Java zu implementieren, da mobile Endgeräte meistens eine JVM (Java Virtual Machine) mitbringen. Für die Diplomarbeit wurden drei unterschiedliche Geräte für die Implementierung ausgewählt: – Sony Ericsson P990i (Smartphone) – Nokia 770 (Internet Tablet) – HP iPAQ hx4700 (Pocket PC) Die Implementierung des VoIP-Clients basiert auf dem in Java geschriebenen MjSIPStack. Auf nicht genutzte Funktionen der hier verwendeten Protokolle wird nicht eingegangen und Grundkenntnisse im Bereich Datennetze, VoIP, Java Sound und JavaProgrammierung werden vorausgesetzt. Einleitung © 2007, Bernd Müller 1 GRUNDLAGEN VOIP 2 1 Grundlagen VoIP In diesem Kapitel sollen die wichtigsten Grundlagen über VoIP vermittelt werden, die für die Entwicklung des Clients ausschlaggebend sind. Es soll helfen ein grundlegendes Verständnis zu erlangen und als Basis für die nachfolgenden Kapitel dienen. Unter VoIP versteht man das Telefonieren über Computernetzwerke auf Basis von IP (Internet Protokoll). Hierbei wird die Sprache in Echtzeit und Steuerinformationen für den Verbindungsauf- und abbau über das IP-Netzwerk übertragen. 1.1 Funktionsprinzip Wie auch bei der herkömmlichen Telefonie wird die Sprache mit einem Mikrofon aufgezeichnet, dann aber mit einem Analog/Digital-Wandler in ein digitales Format umgewandelt und mit Hilfe von bestimmten Codecs in ein entsprechendes Audio-Binärformat kodiert. Nach der Kodierung wird der kontinuierliche Datenstrom in kleine Pakete unterteilt (Paketierung) und über IP versendet. Im Unterschied zum klassischen Telefongespräch werden hier aber keine Leitungen geschaltet. Jedes einzelne Paket wird dann als IP-Paket im Netzwerk über ein nicht festgelegten Weg (s. Abbildung 1.1) über verschiedene Router zum Ziel übertragen. Beim Gesprächspartner werden die ankommenden Daten erstmal in einem Puffer zwischengespeichert. Die digitalen Daten durchlaufen dann einen Digital/AnalogWandler, der mit dem gleichen Codec die Daten wieder in analoge Sprache umwandelt, die dann schließlich von einem Lautsprecher wiedergegeben wird. Abbildung 1.1: VoIP Funktionsprinzip 1.1 Funktionsprinzip © 2007, Bernd Müller 1 GRUNDLAGEN VOIP 3 1.2 Verbindungsaufbau Die Verbindung wird über ein von der Sprache getrenntes Protokoll aufgebaut. Dafür werden hauptsächlich das SIP1- und H.3232-Protokoll eingesetzt. Damit eine Verbindung zu einem Gesprächspartner aufgebaut werden kann, muss dessen IP-Adresse in Zusammenhang mit der Portnummer bekannt sein. Da aber die IP-Adressen oftmals dynamisch durch DHCP-Server vergeben werden, ist es nicht ohne weiteres möglich zu wissen unter welcher IP-Adresse und Portnummer der Gesprächspartner zu erreichen ist. Aus diesem Grund hat die IETF das SIP-Protokoll entwickelt. SIP-Teilnehmer können sich zeitlich befristet bei einem SIP-Server (Registrar-Server) anmelden. Hierdurch können andere SIP-Teilnehmer bei dem SIP-Server die IP-Adresse des gewünschten Gesprächspartners erfragen. Um eine Verbindung in herkömmliche Telefonnetze aufzubauen, werden so genannte Gateways3 benötigt. Diese Gateways leiten bidirektional Anfragen aus dem IP-Netz in ein anderes Telefonnetz. 1.3 QoS / Sprachqualität Die Sprachqualität lässt sich heute (Stand 2007) durchaus mit der Telefonie über herkömmliche Telefonnetze vergleichen und Voice over IP ist auch mittlerweile aus den Kinderschuhen heraus gewachsen. Entscheidend für die Qualität sind aufgrund der paketorientierten Übertragung, die Bandbreite, Latenz(Ende-zu-Ende Verzögerung), Jitter(Schwankung der Verzögerung) und die Paketverlustrate. VoIP in einem internen Netz z.B. eines Unternehmens kann heute als sehr gut bewertet werden. Über eine private DSL-Leitung hingegen werden eine Menge an Daten vermittelt. Verursacht durch Downloads, Aufrufe von Webseiten, E-Mails und gleichzeitige VoIP-Gespräche können Datenpakete verloren gehen oder nicht rechtzeitig zugestellt werden. Die Ursache hierfür ist die geringe Bandbreite im Upstream. Dazu kommt, dass die Übertragung über das Internet von langen Laufwegen gekennzeichnet ist. Die 1 Session Initiation Protocol ist ein Netzwerkprotokoll zum Aufbau einer Kommunikationsverbindung 2 H.323 ist ein Protokoll für audio-visuelle Kommunikation in paketorientierten Netzen 3 Vermittlungsrechner für Kommunikation von Netzwerken, die auf unterschiedlichen Protokollen basieren 1.3 QoS / Sprachqualität © 2007, Bernd Müller 1 GRUNDLAGEN VOIP 4 Zeitdifferenz zwischen dem Senden und Empfangen liegt im Bereich von 90 bis 250 ms. Für VoIP muss die Laufzeit so gering wie möglich gehalten werden und sollte für eine ausreichend gute Sprachqualität 150 ms nicht überschreiten. Eine Lösung hierfür wäre eine ausreichende Bandbreite für den Upload und eine Priorisierung der VoIP-Daten, damit diese von Netzwerkgeräten bevorzugt behandelt werden. Das heute verwendete IPv4 Protokoll bietet zwar die Priorisierung (z.B. mit DiffServ4, hier wird das schon vorhandene ToS5-Feld (s. Abbildung 1.2) im IPv4-Header gesetzt), jedoch wird sie in der Regel von den Routern im Internet nicht beachtet. Sorgfältig geplante und konfigurierte private IP-Netze können eine gute Quality of Service gewährleisten und dadurch auch bei hohem Datenaufkommen die VoIPTelefonie ermöglichen. Aktueller Stand im Internet ist jedoch der Best-Effort-Transport, das heißt die Gleichbehandlung aller Pakete. Die heutige VoIP-Telefonie-Qualität ist den Übertragungskapazitäten der aktuellen Netze zu verdanken. Abbildung 1.2: ToS-Feld (Quelle:[tospic]) Vom Nachfolgeprotokoll IPv6 erwartet man die flächendeckende Bereitstellung von Quality of Service. IPv6 bringt durch Flow Labels und Traffic Classes zwar Effizienzsteigerungen, das Grundproblem Quality of Service ist jedoch auch damit nicht endgültig gelöst. Ob diese Markierungen (Priorität, DSCP) in den Netzen dann berücksichtigt werden oder nicht, ist letztendlich eine finanzielle Frage. 4 Differentiated Services ist ein QoS Verfahren zu Priorisierung von IP-Paketen 5 Type of Service ist ein Feld im IP-Header zur Priorisierung der Pakete 1.3 QoS / Sprachqualität © 2007, Bernd Müller 1 GRUNDLAGEN VOIP 5 Die Zukunft wird zeigen, ob die Internet-Provider für mehr Geld auch qualitativ höherwertige IP-Ströme bereitstellen werden. 1.4 Codecs Ein Codec(engl. coder u. decoder) ist ein Verfahren, mit dem Daten digital kodiert und dekodiert werden. Dabei wird zwischen Audio-und Videocodecs unterschieden. Nach dem Kodiervorgang der Sprache in einen digitalen Bitstrom wird je nach Codec noch eine unterschiedlich starke Komprimierung der digitalen Daten durchgeführt. Die meisten Codecs benutzen dabei ein Verfahren, bei dem die für den Menschen nicht hörbare Informationen weggelassen werden. Dadurch wird die Datenmenge verkleinert und die für die Übertragung benötigte Bandbreite verringert. Werden allerdings die Daten zu stark komprimiert, d.h. zu viele Informationen weggelassen, so leidet auch die Sprachqualität. Manche Codecs sind speziell dafür ausgelegt, um jeden Preis eine niedrige Bandbreite zu erreichen, andere dagegen verbessern die seit Jahrzehnten gewohnte schlechte Telefonqualität sogar auf CD-Qualität. Je nach Codec variiert also die erforderliche Bandbreite und Sprachqualität. Es gibt eine große Anzahl unterschiedlicher Audiocodecs, die bei verschiedenen Telefonnetzen zum Einsatz kommen. Die beste Sprachqualität liefert das bei ISDN genutzte Sprachkodierungsverfahren PCM6 (Pulse Code Modulation), das in der ITU-T Empfehlung G.7117 standardisiert wurde. Dieses Transformationsverfahren nutzt das µ-law- und A-law-Verfahren. Aufgrund seiner Eigenschaft werden die Daten unkomprimiert übertragen, wodurch eine hohe Bandbreite (z.B. Einsatz in einem Firmennetzwerk) vorausgesetzt wird. Für niedrigere Bandbreiten (z.B. VoIP an Hot Spots) stehen verschiedene Codecs zur Verfügung, die letztendlich je nach Komprimierung unterschiedlich gute Qualität liefern. Im Mobilfunk kommt europaweit der GSM8-Standard zum Einsatz. 6 Pulse Code Modulation ist ein von der ITU-T standardisiertes Digitalisierungsverfahren zur Umwandlung analoger Tonsignale in digitale Daten 7 G.711 ist eine Empfehlung der ITU-T für Audiokompression 8 Global System for Mobile Communications ist ein Standard für Mobilfunknetze 1.4 Codecs © 2007, Bernd Müller 1 GRUNDLAGEN VOIP 6 Für die Sprachübertragung bei GSM wurden im Laufe der Jahre mehrere Codecs standardisiert. Die nachfolgende Tabelle stellt eine Übersicht der gängigsten AudioCodecs für den Einsatz von VoIP dar. Die RTP-Parameter werden in den RTP-Paketen mitgeführt und geben dem Empfänger an, welcher Codec genutzt wird. Dadurch kann der Empfänger mit dem gleichen Codec die Sprachdaten wieder decodieren. Die Sprachqualität wird nach persönlichem Empfinden üblicherweise als MOS9-Wert auf einer Skala von eins (mangelhaft) bis fünf (sehr gut) angegeben. Ein MOS-Wert kleiner als 4,0 ist vergleichbar mit einer Sprachqualität im Mobilfunk. Im Festnetz wird mit ISDN wird ein MOS-Wert von 4,0 – 4,5 erreicht. Codec Übertragungsrate MOS-Wert RTP-Parameter G.711u 64 kbit/s 4,4 0 G.711a 64 kbit/s 4,4 8 G.721 32 kbit/s 4,2 2 G.722 64 kbit/s 4,4 9 G.723 6,3 kbit/s 3,5 - 4,0 4 G.726 16 / 24 / 32 kbit/s 4,2 dynamisch (96 - 127) G.728 16 kbit/s 4,2 15 G.729 8 kbit/s 4,0 18 GSM 06.10 13 kbit/s 3,8 3 Speex 2 - 44 kbit/s 4,0 dynamisch (96 - 127) iLBC 13,3 kbit/s 3,8 dynamisch (96 - 127) Tabelle 1: VoIP-Codecs (Quelle: [rtppar]) Die RTP-Parameter 96 – 127 werden dynamisch während der Laufzeit individuell einem Codec zugewiesen. Dazu dient die sogenannte “RTP MAP“, die mit dem “Media Attribute (a)“ übergeben wird. Ein Beispiel hierfür wäre: “Media Attribute (a): rtpmap:97 iLBC/8000“. 9 Mean Opinion Score ist eine Bewertungsskala für die Qualität von Bild- und Sprachübertragungen 1.4 Codecs © 2007, Bernd Müller 2 PROTOKOLLE 7 2 Protokolle In diesem Kapitel wird auf die wichtigsten Protokolle eingegangen, die bei VoIP eingesetzt werden. Eine Übersicht über die Einordnung der Protokolle in den Schichten des OSI1-Modells zeigt die folgende Abbildung: Abbildung 2.1: Einordnung der Protokolle im OSI-Modell 2.1 SIP (Session Initiation Protocol) Das Session Initiation Protocol (RFC2 3261) ist ein Signalisierungsprotokoll für die Multimediakommunikation zwischen zwei oder mehreren Teilnehmern. SIP ermöglicht den Auf- und Abbau, sowie die Veränderung von Verbindungen. Für ein VoIP-Gespräch werden aber noch zusätzliche Protokolle benötigt. Um die Codecs und Transportprotokolle auszuhandeln, wird das Session Description Protocol (SDP) eingesetzt. Die eigentlichen Sprachdaten müssen dann über andere Protokolle übertragen werden. Dafür wird das Real-Time Transport Protocol (RTP) genutzt. SIP setzt auf UDP und TCP auf, wobei die Verwendung von UDP empfohlen wird. Es wurde von der IETF entwickelt und orientiert sich an der Architektur gängiger InternetAnwendungen. Dabei wurde von Beginn an auf leichte Implementierbarkeit, Erweiterbarkeit, Skalierbarkeit und Flexibilität geachtet. Beliebige Sessions zwischen 1 Open Systems Interconnection Reference Model beschreibt die Datenübertragung für die Kommunikation informationsverarbeitender Systeme 2 Requests for Comments bezeichnet eine Reihe von technischen und organisatorischen Dokumenten zum Internet 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 8 mehreren Teilnehmern können durch SIP verwaltet werden. Dabei kann es auch z.B. für Multimedia- und Computerspielsessions eingesetzt werden. Das SIP-Protokoll ist sehr an das HTTP-Protokoll angelehnt, da es eine ähnliche Header-Struktur verwendet und ebenfalls ein textbasiertes Protokoll ist. Die Adressierung findet dann in einem E-Mail ähnlichen Format statt, der so genannten SIP-URI3 (oder auch SIP-URL4) z.B. “sip:[email protected]“. 2.1.1 Komponenten • User Agent (UA Ein User Agent (UA) ist ein SIP-fähiges Endgerät (IP-Telefon oder Softphone auf einem PC, PDA etc.). Dabei wird meist noch eine Aufteilung in User Agent Client (UAC) und User Agent Server (UAS) vorgenommen. – der UAC initiiert die Session – der UAS nimmt Anfragen des UAC entgegen und beantwortet diese Bei einer Ende-zu-Ende Kommunikation zweier Geräte ist eine eindeutige Zuordnung nicht möglich, da jedes Gerät als UAC und UAS fungiert. • Proxy Server Ein Proxy-Server bearbeitet SIP-Nachrichten, indem er das Routing der Nachrichten übernimmt und an den Zielrechner weiterleitet (s. Abbildung 2.2). Für den Kommunikationspartner ist der Proxy-Server ein UAC. Er ist ausschließlich für den Aufbau und Abbruch einer Verbindung zuständig. Ist einmal eine Session aufgebaut, erfolgt die weitere Kommunikation (Übertragung der Sprachdaten) direkt zwischen den beiden Teilnehmern. Abbildung 2.2: Verbindungsaufbau mit Proxy-Server 3 Uniform Resource Identifier ist ein Identifikator zur Bezeichnung von Ressourcen im Internet 4 Uniform Ressource Locator ist eine Untergruppe der URI und identifiziert eine Ressource und den Ort 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 9 • Registrar Server Damit ein Proxy-Server weiß, wo der betreffende Teilnehmer zu finden ist, muss sich sein UA an einem Registrar-Server anmelden. Dieser speichert dann die Informationen (IP-Adresse, Port usw.) zur Identität des Teilnehmers in einer Datenbank. Üblicherweise ist diese Funktionalität im Redirect-Server integriert. • Redirect Server Aufgabe dieses Servers ist es, bei eingehenden Anfragen den gewünschten Empfänger in der Datenbank zu ermitteln. Die gefundenen Informationen werden dann dem anfragenden Teilnehmer mit einer entsprechenden Nachricht zurückgesandt. • Location Server Der Location-Server ist die Datenbank mit den Kontaktinformationen der User, damit diese zurückverfolgt werden können. Der Location-Server bekommt die Daten vom Registrar-Server und liefert diese Informationen an den Proxy- und Redirect-Server. Üblicherweise werden Registrar-, Redirect- und Location-Server zusammengefasst und als SIP-Server implementiert. Dadurch wird eigentlich nur noch zwischen SIP-Proxy und SIP-Server unterschieden. 2.1.2 SIP-Nachrichten Beim Session Initiation Protocol gibt es zwei Arten von Nachrichten: Requests (Anfragen) und Responses (Antworten auf Anfragen). Der Nachrichtentyp einer SIP-Nachricht wird in der ersten Zeile angegeben, gefolgt vom Message Header und Message Body (s. nachfolgendes Beispiel). Requests initiieren eine Verbindung oder übertragen Anforderungen zum Kommunikationspartner. In Responses wird der Empfang eines Requests bestätigt und der Status-Code der Bearbeitung übermittelt. 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 10 Nach RFC 3261 gibt es sechs grundlegende Request-Methoden: • INVITE — initiiert eine Verbindung • ACK — bestätigt den Austausch von SIP-Nachrichten • BYE — beendet die aktuelle Verbindung • CANCEL — wird von Servern oder Proxies zum Signalisieren eines Abbruchs verwendet • REGISTER — SIP-Teilnehmer meldet sich am SIP-Server an/ab, Authentifizierung nach ”Digest Authentication“-Verfahren • OPTIONS — wird benutzt, um Informationen über die Endsysteme abzufragen Es gibt inzwischen noch weitere Request-Methoden, die aber hier nicht weiter relevant sind. Bei Response-Nachrichten unterscheidet man zwischen sechs Status-CodeGrundtypen von 1xx bis 6xx. Die Status-Codes im SIP-Protokoll werden von der IANA5 verwaltet. Die folgende Tabelle zeigt eine Übersicht der wichtigsten Status-Codes, die das Ergebnis einer INVITE-Request angeben: Code 1xx Bedeutung Erläuterung Provisional Request erhalten und in Bearbeitung 100 Trying Versuch anzurufen 180 Ringing es klingelt beim Gesprächspartner 2xx Successful 200 OK 202 Accepted 3xx Redirection Request erfolgreich empfangen alles in Ordnung Verbindung akzeptiert weitere Aktionen sind notwendig 5 Internet Assigned Numbers Authority ist eine Organisation, die die Vergabe von IP-Adressen, Domains und IP-Protokollnummern regelt 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 4xx 11 Request Failure Client Fehler 400 Bad Request SIP-Request fehlerhaft 401 Unauthorized Autorisierung fehlerhaft 403 Forbidden 407 nicht gestattet Proxy Authentication Required Proxy benötigt Autorisierung 5xx Server Failure Server Fehler 6xx Global Failure Request wird nicht akzeptiert 603 Declined Gesprächspartner hat Anruf abgelehnt Tabelle 2: SIP Status-Codes (Quelle: [sippar]) Weitere Informationen werden über das Session Description Protocol übertragen, das in eine SIP-Nachricht eingebettet wird. SDP dient dazu, die zwischen den Teilnehmern verwendeten Codecs, Transportprotokolle etc. auszuhandeln. Frame 8 (594 bytes on wire, 594 bytes captured) Ethernet II, Src: IntelCor_22:b1:32 (00:15:00:22:b1:32), Dst: Avm_76:67:c2 (00:04:0e:76:67:c2) Internet Protocol, Src: 192.168.178.102 (192.168.178.102), Dst: 217.10.79.9 (217.10.79.9) User Datagram Protocol, Src Port: 5060 (5060), Dst Port: 5060 (5060) Session Initiation Protocol Request-Line: INVITE sip:[email protected] SIP/2.0 Method: INVITE [Resent Packet: False] Message Header Via: SIP/2.0/UDP 192.168.178.102:5060;rport;branch=z9hG4bK60846 Max-Forwards: 70 To: <sip:[email protected]> From: <sip:[email protected]>;tag=z9hG4bK66687806 Call-ID: [email protected] CSeq: 1 INVITE Contact: <sip:[email protected] Expires: 3600 User-Agent: mjsip stack 1.6 Content-Length: 159 Content-Type: application/sdp Message body Session Description Protocol Session Description Protocol Version (v): 0 Owner/Creator, Session Id (o): <sip:[email protected]> 0 0 IN IP4 192.168.178.102 Session Name (s): Session SIP/SDP Connection Information (c): IN IP4 192.168.178.102 Time Description, active time (t): 0 0 Media Description, name and address (m): audio 21000 RTP/AVP 0 Media Attribute (a): rtpmap:0 PCMU/8000 Abbildung 2.3: Beispiel INVITE-Request SIP-Nachrichten bestehen aus einem Message Header und Body. Es gibt vier verschiedene Message Header die folgende Informationen enthalten (s. RFC 2543): 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 12 • General Headers Informationen über Absender – und Empfänger • Entity Header Informationen über Typ und Länge der SIP-Nachricht • Response Header Informationen vom Server • Request Header weitere Informationen vom Client INVITE sip:[email protected] SIP/2.0 Methode, Zieladresse, SIP-Version Via: SIP/2.0/UDP192.168.178.102:5060; SIP-Version, Transportprotokoll und rport;branch=z9hG4bK60846 Routinginformationen Max-Forwards: 70 Anzahl der Proxy- oder Gateway-Weiterleitungen To: <sip:[email protected]> Empfänger From: <sip:[email protected]>; Sender Call-ID: [email protected] alle Elemente einer Session haben die gleiche eindeutige ID und können somit eindeutig der Session zugeordnet werden CSeq: 1 INVITE Request-Methode und Sequenznummer innerhalb einer Session mit derselben Call-ID Contact: <sip:[email protected] URL des Senders / Initiators Expires: 3600 Gültigkeit der Nachricht in Sekunden User-Agent: mjsip stack 1.6 Informationen über UA einer SIP-Nachricht Content-Length: 159 Größe Message Body in Bytes Content-Type: application/sdp Protokoll Message Body Tabelle 3: SIP-Header Nicht jede SIP-Nachricht enthält einen Message Body. Bei einer BYE-Nachricht wird der Message Body nicht benötigt. Für eine ACK-, INVITE- oder OPTIONS-Nachricht ist der Message Body die Sessionbeschreibung (SDP). Auf diese Request wird die nachfolgende Response zurückgesendet, die annähernd die gleichen Parameter enthält. Hier ist eine Authentifizierung beim SIP-Proxy notwendig, was durch den Status-Code 407 angegeben wird. 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 13 Frame 9 (475 bytes on wire, 475 bytes captured) Ethernet II, Src: Avm_76:67:c2 (00:04:0e:76:67:c2), Dst: IntelCor_22:b1:32 (00:15:00:22:b1:32) Internet Protocol, Src: 217.10.79.9 (217.10.79.9), Dst: 192.168.178.102 (192.168.178.102) User Datagram Protocol, Src Port: 5060 (5060), Dst Port: 5060 (5060) Session Initiation Protocol Status-Line: SIP/2.0 407 Proxy Authentication Required Status-Code: 407 [Resent Packet: False] Message Header Via: SIP/2.0/UDP 192.168.178.102:5060;rport=61580;branch=z9hG4bK60846;received=80.xxx.xxx.238 To: <sip:[email protected]>;tag=b11cb9bb270104b49a99a995b8c68544.f9bc From: <sip:[email protected]>;tag=z9hG4bK66687806 Call-ID: [email protected] CSeq: 1 INVITE Proxy-Authenticate: Digest realm="sipgate.de", nonce="467bab0d1e9e82d9818aaf600d35ade1a1118fcf" Content-Length: 0 Abbildung 2.4: Beispiel einer SIP-Response 2.1.3 SIP-Verbindungsaufbau Einfacher Verbindungsaufbau Eine Kommunikation zwischen zwei Teilnehmern ist bei Kenntnis der Kontaktdaten auch ohne den Verbindungsaufbau über einen SIP-Server (s. Abbildung 2.5) möglich. Durch das Senden einer INVITE-Request wird die Verbindung initiiert. Durch RINGING wird der Empfang des Requests und mit OK das Abheben bestätigt. Darauf sendet der Initiator als Bestätigung noch ein ACK. Der Verbindungsabbruch wird von einem der beiden Teilnehmer mit einem BYE eingeleitet und von der Gegenseite durch ein OK bestätigt. Abbildung 2.5: einfacher Verbindungsaufbau 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 14 Verbindungsaufbau über einen SIP-Server Der Verbindungsaufbau über einen SIP-Server (s. Abbildung 2.6) ist der typische Aufbau einer Kommunikation. Durch das Registrieren beim SIP-Server kennt dieser die Kontaktdaten der beiden Teilnehmer. Dadurch kann er die Anfragen an die zuständigen Empfänger weiterleiten. Nach erfolgreichem Kommunikationsaufbau werden die Sprachdaten über RTP direkt zwischen den Teilnehmern übertragen. Abbildung 2.6: Verbindungsaufbau über SIP-Server Es gibt noch weitere Möglichkeiten eine Kommunikation zwischen zwei Teilnehmern aufzubauen. Wird ein SIP-Proxy genutzt, so stellt er den Kommunikationspartner der Teilnehmer dar. Sind die Teilnehmer nicht beim gleichen SIP-Server registriert, werden 2.1 SIP (Session Initiation Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 15 die Verbindungsanfragen von einen SIP-Server zu dem mit dem zweiten registrierten Teilnehmer weitergeleitet. Dieser SIP-Server leitet dann alle Nachrichten an den Empfänger weiter. 2.2 SDP (Session Description Protocol) Das Session Description Protocol (RFC 4566) ist kein eigenständiges Protokoll, sondern baut auf SIP oder RTP auf und stellt somit eine sinnvolle Erweiterung dieser Protokolle dar. Es dient der Aushandlung von Codecs, Transportprotokollen etc., indem es eine Beschreibung der Multimedia-Session bereitstellt. Dafür werden folgende im SDP definierten Parameter gesetzt: Parameter Name Beschreibung v version Protokoll Version o owner Informationen über Session und Benutzer s session Name der Session i* session information zusätzliche Informationen über die Session c* connection information Verbindungsinformationen t time Zeit der aktiven Session m media Medienname, IP-Adresse und Port a* attribute Session Attribut Tabelle 4: SDP-Parameter Alle mit (*)-gekennzeichneten Parameter sind optional. Weitere verfügbare SDPParameter sind hier nicht aufgeführt und auch nicht relevant. Ein Auszug aus der vorherigen INVITE-Request-Nachricht soll dies veranschaulichen: Session Description Protocol Session Description Protocol Version (v): 0 Owner/Creator, Session Id (o): <sip:[email protected]> 0 0 IN IP4 192.168.178.102 Session Name (s): Session SIP/SDP Connection Information (c): IN IP4 192.168.178.102 Time Description, active time (t): 0 0 Media Description, name and address (m): audio 21000 RTP/AVP 0 Media Attribute (a): rtpmap:0 PCMU/8000 Abbildung 2.7: Beispiel eines SDP-Pakets 2.2 SDP (Session Description Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 16 Die hier verwendete SDP-Protokollversion ist 0. Mit dem o-Parameter wird der Absender [email protected], Session ID 0, Session Version 0, Network Type IN (Internet), Address Type IP4 (IP Vers. 4) sowie die Adresse des Initiators 192.168.178.102 angegeben. Der Name Session SIP/SDP wird durch den s-Parameter angegeben. Die Zeit (Start- und Endzeit) der aktiven Session wird durch den t-Parameter gekennzeichnet. In diesem Fall bedeutet 0 0, dass die Session sofort nach dem Verbindungsaufbau beginnt und zu jedem beliebigen Zeitpunkt beendet werden kann. Mit dem m-Parameter wird der Medientype audio, Port 21000 und die Medienkodierung angegeben, d.h. alle möglichen Medienformate, hier aber nur PCMU (RTP/AVP 0) (s. Tabelle: VoIP-Codecs (RTP-Parameter)). Der a-Parameter wird genutzt, um das Medienattribute anzugeben. In diesem Fall kann das Endgerät RTP-Daten nach PCMU (PCM µ-Law) mit einer Abtastrate von 8000 Samples pro Sekunde codieren und decodieren. 2.3 RTP (Real-Time Transport Protocol) Das Real-Time Transport Protocol wird eingesetzt, um einen kontinuierlichen Multimedia-Strom wie Audio und Video zu übertragen. RTP paketiert die MultimediaDaten und versendet diese Pakete über UDP. Es beinhaltet wichtige Mechanismen wie Sequenznummern, Zeit- und Synchronisierungsmarkierungen, um die Echtzeitdaten zu versenden. Somit können beim Empfänger ankommende Pakete in der richtigen Reihenfolge zusammengesetzt und Paketverluste feststellt werden. Eine Möglichkeit dies zu verhindern bietet RTP jedoch nicht, was auch nicht möglich wäre, da als Transport UDP eingesetzt wird. Durch die Paketierung und Wiedergabemechanismen kann versucht werden, die Paketverluste zu kompensieren. Die Verwendung von TCP wäre für Multimedia-Ströme nicht sinnvoll, da aufgrund vom Retransmission-Mechanismus bei TCP (erneutes Senden verlorengegangener Pakete) zu spät kommende Pakete nicht wiedergegeben werden können. Dies würde bei einer Kommunikation eher zu Verwirrungen führen und daher müssten diese Pakete sowieso verworfen werden. Die nachfolgende Abbildung zeigt den typischen Aufbau eines RTP-Pakets (Header). 2.3 RTP (Real-Time Transport Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 17 Abbildung 2.8: RTP-Header • V– RTP-Version (2 Bit) • P– Padding (1 Bit), falls gesetzt, enthält das Paket zusätzliche Füll-Bytes am Ende des Pakets, die kein Payload sind. Das letzte Byte gibt die Anzahl der Füll-Bytes an • X– Extension (1 Bit), falls gesetzt, ist eine Header Extension vorhanden • CC – CSRC Count (4 Bit), gibt die Anzahl der im CSRC-Feld vorhandenen Identifier an • M – Marker (1 Bit), reserviert für bestimmte Anwendung • PT – Payload Type (7 Bit), gibt das Format (Kodierung) des Payloads an • Sequence Number (16 Bit), jedes Paket erhält eine eindeutige Sequenznummer, die für jedes weitere Paket erhöht wird. Damit kann der Empfänger die Reihenfolge und fehlende Pakete erkennen • Timestamp (32 Bit), dient zur Synchronisierung, da unterschiedliche Laufzeiten (Jitter) entstehen • SSRC (32 Bit), identifiziert eindeutig den Medienstrom • CSRC (0 – 16 Byte)(optional), wird verwendet, falls die Daten nicht von dem Originalsystem stammen, sondern durch ein Zwischensystem verändert wurden 2.3 RTP (Real-Time Transport Protocol) © 2007, Bernd Müller 2 PROTOKOLLE 18 Frame 17 (214 bytes on wire, 214 bytes captured) Ethernet II, Src: IntelCor_22:b1:32 (00:15:00:22:b1:32), Dst: Avm_76:67:c2 (00:04:0e:76:67:c2) Internet Protocol, Src: 192.168.178.102 (192.168.178.102), Dst: 217.10.68.72 (217.10.68.72) User Datagram Protocol, Src Port: 21000 (21000), Dst Port: 45106 (45106) Real-Time Transport Protocol [Stream setup by SDP (frame 13)] [Setup frame: 13] [Setup Method: SDP] 10.. .... = Version: RFC 1889 Version (2) ..0. .... = Padding: False ...0 .... = Extension: False .... 0000 = Contributing source identifiers count: 0 0... .... = Marker: False Payload type: ITU-T G.711 PCMU (0) Sequence number: 2 Timestamp: 40 Synchronization Source identifier: 1126849400 Payload: 7A797A7A7A797B7C7B7C7A7C7D7B7C7B7C7B7D7C7E7E7EFF... Abbildung 2.9: Beispiel eines RTP-Pakets 2.4 RTP-Proxy Der RTP-Datenaustausch bei VoIP geschieht in der Regel zwischen den Teilnehmern der Session. Wird ein RTP-Proxy eingesetzt, so laufen alle RTP-Daten über diesen Proxy. Er übernimmt die ankommenden Pakete des Senders, verpackt sie mit einen neuen Header und sendet diese dann an den Empfänger weiter. Dadurch ist der RTP-Proxy der direkte Kommunikationspartner der SIP-Teilnehmer. Abbildung 2.10: RTP-Proxy 2.5 RTCP (Real Time Control Protocol) Das Real Time Control Protocol ist ein Steuerprotokoll und wird im Zusammenhang mit RTP genutzt. Es dient der Aushandlung und Einhaltung der Dienstgüte (QoS), indem zwischen Sender und Empfänger Steuernachrichten ausgetauscht werden. Weiter wird auf RTCP nicht eingegangen, da es für diese Diplomarbeit nicht relevant ist. 2.5 RTCP (Real Time Control Protocol) © 2007, Bernd Müller 3 DER MJSIP-STACK 19 3 Der MjSIP-Stack Für die Implementierung eines VoIP-Clients in Java wird ein SIP-Stack benötigt, der in Java entwickelt wurde und somit plattformunabhängig eingesetzt werden kann. MjSIP ist ein leistungsfähiger, in Java programmierter SIP-Stack zur Entwicklung SIPbasierter Applikationen. Die komplette SIP-Architektur, wie in RFC 3261 definiert, wird von MjSIP implementiert und ist absolut konform mit dem SIP-Standard. In dem MjSIP-Package, erhältlich unter [mjsip], sind sofort nutzbare Implementierungen einiger SIP-Systeme (UACs und SIP-Server) enthalten. Diese können nach durchgeführter Konfiguration als UAC oder UAS auf Java-fähigen Plattformen (ab J2SE1 1.3.1) eingesetzt werden. MjSIP Vers. 1.6 soll laut Angaben des Herstellers auf J2SE und J2ME2/CDC3 (aktuell J2ME/CDC/PersonalProfile1.0) Plattformen implementiert werden können. Die SIP-Systeme werden als jar4-Dateien bereitgestellt. Zusätzlich ist eine Portierung für J2ME (MjSIP2ME) Plattformen erhältlich und soll unter J2ME/CLDC51.1/MIDP2.0 lauffähig sein. Der Stack beinhaltet zusätzlich alle APIs, Klassen und Methoden, um eigene SIP-Applikationen zu entwickeln. MjSIP unterliegt der GNU General Public License (GPL6) , d.h. der Quellcode ist frei verfügbar und darf modifiziert werden. MjSIP wurde an der Universität von Parma / Italien von Luca Veltri entwickelt und dort zu Forschungszwecken eingesetzt. Der MjSIP-Stack ist in verschiedene Bereiche unterteilt. Jeder Bereich besteht aus einer eigenen Klasse, in der die verschieden Aufgaben umgesetzt werden. Beispielsweise ist die Klasse org.zoolu.sip.provider.SipStack für die Initialisierung und Instantiierung des MjSIP Stacks zuständig. 1 2 3 4 Java Platform Standard Edition gilt ab Version 1.2 als J2SE (vorher Java SE) Java 2 Micro Edition ist eine Umsetzung der J2SE für “embedded systems“ Connected Device Configuration ist eine Konfiguration der J2ME-Laufzeitumgebung JAR (Java Archive) ist eine ZIP-Datei, die zusätzlich Metadaten enthält. JARs werden zur Verteilung von Java-Programmen und Libraries eingesetzt 5 Connected Limited Device Configuration ist die kleinstmögliche Konfiguration einer J2MELaufzeitumgebung 6 Die GPL ist eine von der Free Software Foundation herausgegebene Lizenz für die Lizenzierung freier Software, http://www.gnu.org/copyleft/gpl.html 3 Der MjSIP-Stack © 2007, Bernd Müller 3 DER MJSIP-STACK 20 Es gibt zwei Hauptverzeichnisse local und org. Im local-Verzeichnis befinden sich alle wichtigen Klassen für den UA, die z.B. für das Handling der Multimediadaten zuständig sind (Capturing, Playback, RTP-Transport etc.). Das org-Verzeichnis beinhaltet alle Klassen zum Aufbau einer Verbindung, d.h. IP-, UDP/TCP-, SIP- und SDP-Nachrichten . __________________________________Audio Handling(Capturing, Playback) ____________________________________________RTP-Streams, Paketierung ____________________________________________________Server Instanzen _______________________________________________________UA Instanzen _______________________________________________Netzwerk-Nachrichten ___________________________________________________SDP-Nachrichten ____________________________________________________SIP-Nachrichten ______________________________zusätzliche Klassen(Verschlüsselung, Logs) Abbildung 3.1: MjSIP Verzeichnisstruktur 3.1 MjServer MjServer ist ein auf dem MjSIP Stack basierender SIP-Server, der als Registrar-, Redirectund Proxy-Server eingesetzt werden kann. Zusätzlich kann er als Stateless- oder StatefulProxy konfiguriert werden. Stateless-Proxies leiten Anfragen einfach weiter, wodurch sie schneller als Stateful-Proxies arbeiten. Stateful Proxies hingegen erzeugen für jede Anfrage einen Zustand (state) und behalten diesen, bis die Transaktion beendet ist. Dadurch können sie weitergehende Dienste anbieten. Die Konfiguration des Servers geschieht über eine Textdatei, die beim Starten des Servers eingelesen wird. Auf den MjServer wird hier nicht weiter eingegangen, da dieser nicht genutzt wird. 3.1 MjServer © 2007, Bernd Müller 3 DER MJSIP-STACK 21 3.2 MjUA MjUA ist eine einfache Implementierung eines UAC, basierend auf dem MjSIP-Stack. Der UAC steht in zwei verschiedenen Versionen zur Verfügung: • GraphicalUA (wird über java.awt und javax.swing Komponenten dargestellt ) Abbildung 3.2: MjSIP GraphicalUA • CommandLineUA (wird über die Kommandozeile angesteuert) Gestartet wird der UAC über die Kommandozeile. Durch den Aufruf von java und der entsprechenden Klasse können noch zusätzliche Parameter sowie die zu nutzenden Libraries angegeben werden. Die zusätzlichen Parameter werden angegeben, falls keine Konfigurationsdatei genutzt wird. Der GraphicalUA kann durch folgenden Befehl gestartet werden: java -classpath sip.jar;ua.jar local.ua.GraphicalUA -f config.cfg Der Parameter classpath gibt die zu nutzenden Libraries an. sip.jar und ua.jar sind die MjSIP-Libraries, die alle notwendigen Klassen und Methoden zur SIP- Kommunikation enthalten. local.ua.GraphicalUA verweist auf den Pfad der zu startenden GraphicalUA-Klasse. Der f-Parameter spezifiziert die Konfigurationsdatei, die den UAC bzw. UAS konfiguriert. Weitere Parameter können direkt beim Aufruf des UA angegeben werden: -t <secs> Zeit, nach der das Gespräch beendet wird (bei 0 wird das Gespräch manuell beendet) -g <time> registriert die SIP-URL beim Registrar-Server, die Zeitangabe gibt die Dauer der Registrierung an -u 3.2 MjUA meldet die SIP-URL beim Registrar-Server ab © 2007, Bernd Müller 3 DER MJSIP-STACK 22 -z meldet alle SIP-URLs ab -c ruft Teilnehmer an -y <secs> automatische Antwortzeit -i <secs> re-invite nach angegebener Zeit -r <url> Umleitung des Anrufs zur URL -q <url><secs> umleiten des Anrufs zur URL nach angegebener Zeit -a Audio-Support (Sprachübertragung) -v Video-Support -m <port> Media Port -p <port> SIP Port -o nutzt angegebenen Proxy <addr>[:<port>] --via-addr über bestimmte IP-Adresse (falls mehrere Netzwerkkarten) --keep-alive Abstand der keep-alive-Pakete in <ms> --from-url Address-of-Record (AOR7) --contact-url Kontakt URL --username Benutzername --realm Domain des Benutzers --passwd Passwort --recv-only keine Sprachdaten werden gesendet --send-only Sprachdaten werden nicht wiedergegeben --send-tone Testton (100 Hz) wird generiert und gesendet --send-file Audiodatei wird gesendet und beim Empfänger abgespielt --recv-file Sprachdaten werden in einer Datei gespeichert --debug-level Logbuch wird erstellt --log-path Pfad für Log-Dateien Neben der Signalisierung über SIP wird der Datenaustausch von Audio und Video unterstützt. 7 Address-of-Record enthält Informationen über die Erreichbarkeit der SIP-Benutzer (IP, Port, Ort) 3.2 MjUA © 2007, Bernd Müller 3 DER MJSIP-STACK 23 Die Audiounterstützung kann durch drei unterschiedliche Implementierungen realisiert werden: – standard Java – JMF8 (Java Media Framework) – externe Audioapplikation z.B. RAT9(Robust Audio Toolkit) Die Videounterstützung wird realisiert durch: – JMF – VIC10 (Video Conferencing Tool) Der MjUA unterstützt die Weiterleitung eines Anrufs, call transfer und redirection. Es können Sessions sowohl von UAC-to-UAC sowie über Proxy-Server aufgebaut werden. Für die Anmeldung an einem SIP-Server wird die “Digest Authentication“ eingesetzt. Digest-Authentication ist ein Authentifizierungsverfahren bei SIP (basierend auf der HTTP Digest Authentication RFC 2617, RFC 3310), das zur Verschlüsselung des Passwortes den MD5-Algorithmus nutzt. Ein “only signalling“-Mode wird vom MjUA auch unterstützt und kann für Testzwecke verwendet werden. Hierbei wird keine RTPVerbindung aufgebaut und somit keine Sprachdaten übertragen. Zusätzlich können Multimedia-Daten aus Dateien gesendet oder Sprachdaten in Dateien geschrieben werden. Weitere unterstützte Funktionalität lassen sich aus der Konfigurationsdatei entnehmen. 3.3 MjSIPME MjSIPME ist eine textbasierte SIP-Kommunikation, d.h. es werden keine Audio/VideoDaten übertragen. Die Kommunikation wird lediglich per Text, ähnlich eines ChatProgramms, durchgeführt (s. Abbildung 5.9). 8 Java Media Framework ist eine Java-Library zum Handling von Audio- und Videosignalen 9 Robust Audio Toolkit ist ein Konferenzsystem für Audiokommunikation 10 Video Conferencing Tool ist ein Konferenzsystem für Videokommunikation 3.3 MjSIPME © 2007, Bernd Müller 3 DER MJSIP-STACK 24 3.4 Konfiguration Die Konfiguration der MjSIP-Systeme wird standardmäßig durch eine Textdatei durchgeführt. Beim Starten des UA wird die konfigurierte Datei angegeben, die dann von der Methode parseLine() in der jeweilig zuständigen Klasse eingelesen wird. Jede zu konfigurierende Klasse (SipStack, SipProvider, UserAgentProfile etc.) besitzt diese Methode. Alle dazugehörigen Parameter werden ausgelesen und den Variablen der Klasse übergeben. Die Konfigurationsdatei enthält sechs Abschnitte, die für bestimmte Konfigurationen vorgesehen sind. Eine Basiskonfiguration ist bereits enthalten und muss nur in bestimmten Abschnitten angepasst werden. Die wichtigsten hier genutzten Abschnitte und Einstellungen sind: • SIP-Stack Konfiguration In diesem Abschnitt wird normalerweise keine Änderung der Konfiguration durchgeführt, da dies Standard-SIP-Einstellungen sind. Die wichtigsten Einstellungen sind nachfolgend dargestellt, wurden aber nicht geändert: default_port: 5060 (SIP standard Port) default_transport_protocols: udp, tcp (unterstützte Transport-Protokolle) default_nmax_connections: 32 (max. gleichzeitige Transportverb.) use_rport: yes (rport11-Tag wird im Via-Header-Feld in Requests eingefügt) max_forwards: 70 (max. Anzahl an durchlaufen Proxies) default_expires: 3600 (Gültigkeit der Nachricht in Sekunden) ua_info: <mjsip rel.> (UA Info im Message Header einer Request-Nachricht) • SIP-Provider Konfiguration Folgende Parameter können angepasst werden, um die Einstellungen der SIPTransport-Schicht zu konfigurieren: 11 Mit dem rport-Tag wird signalisiert, dass die Response an eine bestimmte IP-Adresse und Port geschickt werden soll 3.4 Konfiguration © 2007, Bernd Müller 3 DER MJSIP-STACK host_addr: 25 AUTO-CONFIGURATION (Via address/name, IP-Adresse, die genutzt werden soll) host_ifaddr: ALL-INTERFACES (Netzwerk-Interface-Adresse für SIPNachrichten) host_port: 5060 (lokaler SIP-Port) transport_protocols: udp (genutztes Transport-Protokoll) outbound_proxy12: NONE (wird nicht genutzt) • UA Konfiguration Dieser Abschnitt enthält alle Parameter für die Konfiguration des UA, dem so genannten UserAgentProfile. Es können Einstellungen für den SIP-Server (Benutzername, Passwort, realm) vorgenommen, Kontakte, Codecs, Audio- und Video-Support angegeben und das Verhalten des UA eingestellt werden. Die wichtigsten Einstellungen sind nachfolgend dargestellt: from_url: sip:[email protected] (AOR zum Anmelden beim SIPServer) contact_url: sip:[email protected]:5060 (Kontakt URL) username: user (Benutzername) realm: sipgate.de (Domain des Providers) passwd: password (Passwort des Benutzers) contacts_file: contacts.lst (Pfad zu Kontaktdaten-Datei) do_register: yes (am SIP-Server anmelden) do_unregister: yes (Kontaktadresse wird abgemeldet) do_unregister_all: no (alle Kontaktadressen werden abgemeldet) expires: 3600 (Gültigkeit der Nachricht) keepalive_time: 8000 (Abstand der keepalive-Pakete) 12 Ein outbound proxy wird in Verbindung mit einer Firewall/NAT genutzt, um die Signalisierung und den Medientransport über die Firewall/NAT zu leiten 3.4 Konfiguration © 2007, Bernd Müller 3 DER MJSIP-STACK call_to: 26 NONE (Teilnehmer wird beim Start des UA angerufen) accept_time: -1 (autom. Gesprächsannahme) hangup_time: -1 (Anruf-Dauer) redirect_to: NONE (Anruf wird weitergeleitet) audio: yes (Sprachdaten werden übertragen) video: no (Videodaten werden übertragen) recv_only: no (keine Sprachdaten werden gesendet) send_only: no (Sprachdaten werden nicht wiedergegeben) send-file: NONE (Audiodatei wird gesendet und beim Empfänger abgespielt) recv-file: NONE (Sprachdaten werden in einer Datei gespeichert) audio_port: 21000 (Audio Port) audio_avp: 0 (RTP-Parameter für Codec) audio_codec: PCMU (µ-Law Kodierungsverfahren) audio_sample_rate: 8000 (Anzahl Abtastwerte pro Sek.) audio_sample_size: 2 (Größe eines Samples in Byte) audio_frame_size: 160 (Größe eines Frames in Byte) video_port: 21070 (Standard Video Port) use_jmf: no (ob das JMF für Audio/VideoStreaming genutzt wird) use_rat: no (ob RAT für das Senden und Empfangen von Audio genutzt wird) 3.4 Konfiguration © 2007, Bernd Müller 3 DER MJSIP-STACK use_vic: 27 no (ob VIC für das Senden und Empfangen von Video genutzt wird) Für das Capturing und Playback der Sprachdaten werden mit Java so genannte DataLines geöffnet. Beim Capturing (AudioInput) wird eine TargetDataLine geöffnet und beim Playback (AudioOutput) eine SourceDataLine. Wird der recv-only-Mode genutzt, so bewirkt diese Einstellung keine Übertragung von Sprachdaten in beide Richtungen (s. Quelle: [ronly]), obwohl eine SourceDataLine geöffnet wird. Hier scheint ein Fehler in dem SIP-Stack vorhanden zu sein, der aber keine Auswirkung auf die restliche Arbeit hat, da diese Funktion nicht genutzt wird. Der send-only-Mode hingegen funktioniert sehr gut. Hier werden die Sprachdaten in beide Richtungen übertragen (s. Quelle: [sonly]). Die ankommenden Sprachdaten werden jedoch nicht wiedergegeben, da nur eine TargetDataLine geöffnet wird. Folgendes Beispiel, indem der send-only- und recv-only-Mode in der Konfigurationsdatei deaktiviert ist, soll dies verdeutlichen, es werden beide DataLines geöffnet: C:\mjua_1.6>java -classpath C:\Programme\Java\jre1.6.0_01\lib;lib/sip.jar;lib/ua.jar local.ua.GraphicalUA -f config\config.cfg Graphical MJSIP UA 1.0 AudioInput: TargetDataLine: com.sun.media.sound.DirectAudioDevice$DirectTDL@ae000d AudioOutput: SourceDataLine: com.sun.media.sound.DirectAudioDevice$DirectSDL@92e78c UA: REGISTRATION UA: Registration success: 200 OK Abbildung 3.3: Beispiel Java DataLines Bei der Auswahl des Codecs steht nur PCMU zur Verfügung. In der BeispielKonfigurationsdatei des MjSIP-Packages ist zwar beim Parameter audio_codec auch der Wert GSM als Alternative zu PCMU angegeben, jedoch hat dies keine Auswirkung auf die Sprachkodierung. Die Daten werden immer nach dem PCMU-Verfahren kodiert. Die Angabe des GSM-Codecs bewirkt lediglich, dass in dem SDP als Media Attribute “rtpmap:0 GSM/8000“ gesetzt wird. Folgender Teil (SIP-INVITE Message Body (SDPAbschnitt)) aus einem Mitschnitt zeigt dieses Problem (Quelle: [mjgsm]) 3.4 Konfiguration © 2007, Bernd Müller 3 DER MJSIP-STACK 28 Session Description Protocol Session Description Protocol Version (v): 0 Owner/Creator, Session Id (o): "Bernd Mueller" <sip:[email protected]> 0 0 IN IP4 192.168.178.102 Session Name (s): Session SIP/SDP Connection Information (c): IN IP4 192.168.178.102 Time Description, active time (t): 0 0 Media Description, name and address (m): audio 21000 RTP/AVP 0 Media Attribute (a): rtpmap:0 GSM/8000 Abbildung 3.4: SDP (Media Attribut "rtpmap:0 GSM/8000“) Wie aus Tabelle [1] zu entnehmen ist, wird aber mit dem RTP-Parameter “0“ eine PCMU-Kodierung angegeben. Dadurch sind die ankommenden Daten vom Gesprächspartner nach dem PCMU-Verfahren kodiert, obwohl sie aber GSM kodiert erwartet werden. Nachfolgend ist das erste RTP-Paket dargestellt, das als Payload PCMU statt erwartete GSM kodierte Sprachdaten enthält: Real-Time Transport Protocol [Stream setup by SDP (frame 14)] 10.. .... = Version: RFC 1889 Version (2) ..0. .... = Padding: False ...0 .... = Extension: False .... 0000 = Contributing source identifiers count: 0 0... .... = Marker: False Payload type: ITU-T G.711 PCMU (0) Sequence number: 0 Timestamp: 0 Synchronization Source identifier: 2288579477 Payload: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF... Abbildung 3.5: RTP-Paket (PCMU- statt GSM-Payload) Beim Zusammensetzten der SDP-Nachricht wird standardmäßig immer der RTPParameter für PCMU gesetzt. Dies liegt daran, dass in der Klasse UserAgentProfile ein Parameter “(int)audio_avp“ Einfluss bei der Zusammensetzung der SDP-Nachricht hat. Dieser Parameter “audio_avp=0“ ist vom Typ Integer und kann somit nur einen RTP-Parameter, in diesem Fall für die PCMU-Kodierung, aufnehmen. Durch die Medienbeschreibung RTP/AVP werden mehrere, d.h. alle unterstützten Codecs zur Aushandlung angegeben. Hierbei ist es nur die PCMU-Kodierung die durch die “0“ gesetzt wird. Hinzu kommt, dass im MjSIP-Stack nur die G.711-Klasse zur Kodierung 3.4 Konfiguration © 2007, Bernd Müller 3 DER MJSIP-STACK 29 der Sprachdaten zur Verfügung steht. Diese Klasse enthält Methoden zur µ-Law, A-Law und linear PCM-Kodierung. Sollen die Sprachdaten mit anderen Codecs kodiert werden, müssen die entsprechenden Java-Klassen als sogenannte Plug-Ins eingebunden werden, damit auf diese zugegriffen werden kann. Frei verfügbare in Codecs sind z.B.: • JSpeex13 ist eine frei erhältliche Java-Portierung des Speex-Sprachcodecs • GSM06.1014 Codec ist ein Plug-In aus der Tritonus-Implementierung (plattformunabhängige Implementierung der Java Sound API) Weitere MjSIP-Konfigurationsmöglichkeiten über die Konfigurationsdatei bestehen für Logs, SIP-Server und Session Border Controller (SBC), auf die hier nicht eingegangen wird. 13 [jspeex] 14 [triton] 3.4 Konfiguration © 2007, Bernd Müller 4 JAVA SOUND 30 4 Java Sound Die Java Sound API ist eine Audioerweiterung für die Java Plattform, die in den javax.sound.* Packages definiert ist. Sie bietet ein low-level Framework, d.h. relativ nahen Hardwarezugriff für Audiooperationen wie Playback, Capturing und Mixing an. Java Sound ist ab der Java Plattform v1.3.1 ein fester Bestandteil der J2SE. Die Java Sound API besteht aus folgenden Packages: • javax.sound.sampled ist für die Aufnahme, Abspielen sowie das Bearbeiten und den Transport der Audiodaten zuständig • javax.sound.sampled.spi die so genannten SPIs (Service Provider Interfaces) dienen der Erweiterung (z.B. der Unterstützung von mp3) und sind für die Audiokonvertierung sowie für das Lesen und Schreiben von Audiodaten zuständig • javax.sound.midi für MIDI-Daten • javax.sound.midi.spi Schnittstellen für Anbieter von neuen MIDI-Diensten Hier wird nur das javax.sound.midi-Package javax.sound.sampled-Package erläutert, auf das wird nicht weiter eingegangen. Line Port Mixer SourceDataLine DataLine TargetDataLine Clip Abbildung 4.1: Line Interface Hierarchie 4 Java Sound © 2007, Bernd Müller 4 JAVA SOUND 31 Das Line-Interface ist ein Objekt, das die Audiozufuhr in und aus einem System darstellt. Als Line-Objekte werden üblicherweise die Interfaces Port, TargetDataLine, SourceDataLine und Clip bezeichnet (d.h. Ein- und Ausgänge der Mixer). Ports sind die Anschlüsse für die Ein- und Ausgabe von Audiogeräten. Typische Beispiele für Ports sind Mikrofon, Lautsprecher, Line-In und Line-Out. Ein Mixer ist ein Gerät mit einer oder mehreren Lines (mehrere Eingänge, aber nur einen Ausgang). Er übernimmt die gleiche Aufgabe wie ein Hardware-Mischpult und kann mehrere Streams zusammenführen. Eine DataLine beschreibt eine Datenstrom und bietet Methoden zur Behandlung der Mediendaten an. Die Aufnahme und das Abspielen von Audiodaten ist nur über ihre Subinterfaces möglich. Die SourceDataLine- und Clip-Instanzen ermöglichen das Abspielen, die TagetDataLine-Instanzen die Aufnahme von Port Input MIXER Anschluss SourceDataLine TargetDataLine Anwendung Line Clip Output MIXER Port Anschluss Line Lautsprecher Mikrofon Audiodaten (s. Abbildung 4.2). Abbildung 4.2: Darstellung der Interfaces • SourceDataLine – ist der Eingang für den Ausgabe-Mixer, d.h. enthält die Daten für die Wiedergabe – für kontinuierliche Datenströme ausgelegt – bietet Methoden an, um Daten Stück für Stück in den Buffer zu schreiben und nachzufragen, wie viele Daten noch geschrieben werden können. Sind Daten in den Buffer geladen, werden diese abgespielt und der Buffer mit den nachfolgenden Daten wieder gefüllt. • TartgetDataLine – ist der Ausgang des Eingabe-Mixers, d.h. enthält die Aufnahmedaten 4 Java Sound © 2007, Bernd Müller 4 JAVA SOUND 32 – bietet Methoden an, um Daten aus dem Buffer zu lesen und nachzufragen, wie viele Daten noch vorhanden sind • Clip – lädt die Daten im Voraus komplett in den Speicher. Dadurch können sie sofort abgespielt werden – ist das Gegenstück zur SourceDataLine, die für Streaming ausgelegt ist – Bei Clip ist die Größe bekannt, somit ist jede beliebige Position für das Abspielen wählbar. Die wichtigsten Klassen der Java Sound API sind: • AudioSystem – diese Klasse ist der Einstiegspunkt in die Audio-Systemressourcen – erlaubt den Zugriff auf Systemressourcen – bietet Methoden zum Umwandeln verschiedener Audioformate – bietet Methoden zur Umwandlung von Audiodateien in Audio-Streams – erzeugt Line-Objekte • AudioFormat spezifiziert ein bestimmtes Audio-Format mit folgenden Informationen – Kodierung (PCM [signed / unsigned], µ-Law, A-Law) – Abtastrate (sample rate [samples/s]) – Auflösung (sample size in bits [bits/sample]) – Anzahl d. Kanäle (Mono / Stereo [1 / 2]) – Paketgröße (frame size [bytes]) – Paketrate (frame rate [frames/s] – Byte Reihenfolge1 (little-endian / big-endian) 1 little-endian und big-endian geben die Reihenfolge der Bytes innerhalb eines Samples an. Bei littleendian wird das LSB (Least Significant Byte) an erster Stelle gespeichert, bei big-endian das MSB (Most Significant Byte) 4 Java Sound © 2007, Bernd Müller 4 JAVA SOUND 33 • AudioInputStream – enthält Audio-Samples und Format-Informationen des Streams • DataLine.Info – ist ein Informationsobjekt und wird benötigt für die Erstellung eines Line-Objektes – identifiziert Line-Objekte 4.1 Aufnahme / Wiedergabe Folgendes Beispiel TargetDataLine demonstriert die Nutzung einer SourceDataLine und zum Wiedergeben und Aufnehmen der Sprache. Die Daten werden unkomprimiert im PCM-Format aufgenommen, in einen Buffer geschrieben, danach ausgelesen und wiedergegeben. import javax.sound.sampled.*; public class Stream_Aufnahme { public static void main(String[] args) throws Exception { // AudioFormat für Stream erzeugen AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000F, 8, 1, 1, 8000F, false); final int seconds = 10; System.out.println("Aufnahme fuer " + seconds + " Sekunden ..."); byte[] wavedata = record(format, seconds); System.out.println("Fertig"); System.out.println("Wiedergabe ..."); play(format, wavedata); System.out.println("Fertig"); System.exit(0); } // Aufnahme-Methode static byte[] record(AudioFormat format, int seconds) throws LineUnavailableException { // DataLine.Info-Objekt erstellen DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // TargetDataLine anfordern TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info); int sampleRate = (int) format.getSampleRate(); int channels = format.getChannels(); int sampleSizeInBits = format.getSampleSizeInBits(); final int bytesPerSec = (int)(sampleRate * channels * sampleSizeInBits / 8); // Buffer erstellen für Daten des angegebenen Formats byte[] buff = new byte[bytesPerSec * seconds]; // Line öffnen, starten line.open(format); line.start(); // Daten aus dem TargetDataLine-Input-Buffer lesen line.read(buff, 0, buff.length); // warten bis Buffer leer ist 4.1 Aufnahme / Wiedergabe © 2007, Bernd Müller 4 JAVA SOUND 34 line.drain(); line.close(); return buff; } // Wiedergabe-Methode static void play(AudioFormat format, byte[] wavedata) throws LineUnavailableException { // DataLine.Info-Objekt erstellen DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); // SourceDataLine anfordern SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); // Line öffnen, starten line.open(format); line.start(); // Daten aus der line werden in den Mixer geschrieben, somit wiedergegeben line.write(wavedata, 0, wavedata.length); // warten bis Buffer leer ist line.drain(); line.close(); } } Zunächst wird ein AudioFormat für den Streams festlegt. Dann wird dieses Format und die Dauer der Aufnahme der DataLine.Info-Objekt TargetDataLine) record-Methode übergeben. Jetzt muss ein erzeugt werden, das Informationen über eine Line (hier mit dem entsprechenden AudioFormat enthält. Dieses info-Objekt wird nun genutzt, um mit den entsprechenden Spezifikationen eine Instanz der TargetDataLine zu erzeugen. Dieser Aufruf muss in einen try-Block eingebunden werden, da möglicherweise die entsprechende line nicht erzeugt werden kann. Ohne den try-Block lässt sich dieser Code nicht kompilieren. Nach der Erstellung eines temporären Buffers, der die Daten im angegebenen Format aufnehmen kann, wird die line geöffnet. Mit der read-Methode werden die Daten aus dem Input-Buffer der TargetDataLine in den Buffer gelesen. Der buff-Parameter ist das Byte-Array (Buffer) das die Daten erhält, der Parameter 0 (Offset) gibt die Startposition in Bytes an, was bedeutet, dass von Anfang an gelesen werden soll. Der letzte Parameter kennzeichnet die Anzahl der gelesenen Bytes. Bevor die line geschlossen werden kann, wird durch die drain-Methode gewartet, bis alle Daten aus dem Buffer gelesen wurden. Danach wird diese Methode verlassen und die play-Methode aufgerufen, in der die gleiche Abfolge wie in der record-Methode stattfindet, jetzt nur für die SourceDataLine. Mit der write-Methode werden die Daten in den wavedata-Buffer und damit auf die SourceDataLine geschrieben und somit abgespielt. Durch die drain-Methode wird 4.1 Aufnahme / Wiedergabe © 2007, Bernd Müller 4 JAVA SOUND 35 dann wieder gewartet, bis alle im Buffer der SourceDataLine befindlichen Daten abgespielt wurden. Die line muss unbedingt geschlossen werden, da die Ressource sonst nach Beendigung der Anwendung bis zum Neustart des Systems reserviert bleibt. Bei diesem Codebeispiel werden die Sprachdaten unkomprimiert aufgenommen und nach dem PCM-Verfahren kodiert. Um Sprachdaten in ein anderes Format umzuwandeln, bietet die Klasse AudioSystem entsprechende Methoden an, falls auf den benötigten FormatConversionProvider2 (SPI) zugegriffen werden kann. Mit der Methode isConversionSupported(targetFormat, sourceFormat) kann ermittelt werden, ob die gewünschte Konvertierung von dem einen in das andere Format unterstützt wird. Dies ist die typische Vorgehensweise in Java, wenn Sprachdaten in einem anderen Format benötigt werden. Die SPIs sind Java Sound Plug-Ins und werden genutzt, um Java Sound um Dateiformate, Komprimierungsverfahren und Audio-Hardware zu erweitern. Für das javax.sound.sampled-Package gibt es vier Arten von Providern: • AudioFileReader (Lesen von Audiodateien) • AudioFileWriter (Schreiben von Audiodateien) • FormatConversionProvider (Formatumwandlungen zwischen unterschiedlichen Audioformaten) • MixerProvider (stellt versch. Mixer zur Verfügung, bietet Zugriff auf Audio-Hardware) Um diese Plug-Ins für Java Sound verfügbar zu machen, müssen sie sich in einer jarDatei befinden. Innerhalb dieses Archivs werden im Verzeichnis META-INF/Services die implementierten Plug-Ins angegeben. Für jede abstrakte Klasse muss eine Datei mit dem vollständigen Namen dieser Klasse als Dateinamen in diesem Verzeichnis hinterlegt werden (z.B. javax.sound.sampled.spi.FormatConversionProvider). Innerhalb dieser Datei werden dann die vollständigen Klassennamen aller SPIs, die in der jar-Datei enthaltenen sind, untereinander aufgelistet: 2 FormatConversionProvider ist ein Service Provider Interface (SPI) und bietet Umwandlungsmethoden für unterschiedliche Formate an 4.1 Aufnahme / Wiedergabe © 2007, Bernd Müller 4 JAVA SOUND 36 # Providers for FormatConversion com.sun.media.sound.UlawCodec com.sun.media.sound.AlawCodec com.sun.media.sound.PCMtoPCMCodec Die jar-Datei muss dann in den Classpath eingebunden werden, indem der Pfad zur jarDatei angegeben oder sie in der IDE dem Projekt hinzufügt wird. 4.2 Alternative zu Java Sound Neben der Java Sound Implementierung von SUN Microsystems gibt es Tritonus, eine freie Java Sound Implementierung, die ursprünglich für die Linux Plattform entwickelt wurde. Tritonus basiert auf der GNU LGPL3 und ist eine sehr gute Alternative zur Java Sound Implementierung von SUN. 3 GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html 4.2 Alternative zu Java Sound © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 37 5 Mobile Endgeräte 5.1 Sony Ericsson P990i Das Sony Ericsson P990i ist ein Smartphone, d.h. ein Gerät mit PDA- und Telefonfunktion. Es ist im 4.Quartal 2006 auf dem deutschen Markt erschienen. Als Betriebssystem setzt Sony Ericsson auf Symbian v9.1 mit der inzwischen eigenen Oberfläche UIQ13. Für die Kommunikation ist das P990i mit WLAN (802.11b2 Standard), Bluetooth, USB, Infrarot ausgestattet und Tri-band (GSM900, GSM1800, GSM1900) sowie UMTS (W-CDMA3) fähig. Bedient wird das Gerät über eine der beiden Tastaturen (Nummern- oder QWERTZ-Tastatur) oder das 240x320 Pixel große QVGA Touchscreen. Auf dem Gerät kommt ein 208 MHz ARM-Prozessor zum Einsatz. 80MB interner Speicher steht zur Verfügung und kann über einen Memory Stick auf bis zu 8GB erweitert werden. Für das Capturing unterstützt das P990i die Sprachcodecs HR (Half Rate), FR (Full Rate), EFR (Enhanced Full Rate) und AMR4 (Adaptive Multi Rate). Beim Audio-Streaming können alle gängigen Audioformate (AAC, AMR-NB, AU, MIDI, MP3, WAV, Real Audio etc.) wiedergegeben werden. Auf diese Kodierungsverfahren kann nicht mit Java, sondern nur über die Programmiersprache C++ zugegriffen werden. Java-fähig ist das P990i natürlich auch. Es bietet keine vollständig kompatible J2SE-Runtime, aber eine J2ME CDC und CLDC Umgebung. Abbildung 5.1: Sony Ericsson P990i 1 User Interface Quartz ist eine grafische Oberfläche speziell für die Bedienung über Touchscreens mit Symbian OS 2 802.11b ist ein Standard für WLAN-Kommunikation mit einem Datentransfer bis zu 11 MBit/s 3 Wideband Code Devision Multiple Access ist ein Codemultiplexverfahren das Daten gleichzeitig auf einem gemeinsamen Frequenzband übertragt. 4 Adaptive Multi Rate ist ein Sprachcodec für den Einsatz bei GSM-Telefonen mit variablen Datenraten 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 38 5.1.1 Java Plattform (J2ME) Java ist in unterschiedliche Plattformen unterteilt, die für unterschiedliche Zielgeräte vorgesehen sind. Folgende J2xE -Plattformen sind verfügbar: • J2SE Java 2 Standard Edition (Standard Version mit grafischen Erweiterungen) • J2EE Java 2 Enterprise Edition (für serverseitige Anwendungen) • J2ME Java 2 Micro Edition (für mobile Endgeräte, embedded devices) Abbildung 5.2: Java 2 Plattformen (Quelle: [dsj2me]) J2ME ist der Java Standard für kleine bzw. mobile Geräte, der in zwei Untergruppen (d.h. Konfigurationen und Profile) unterteilt wurde. Je nach Speicher- und Hardwareunterstützung werden mobilen Endgeräten die unterschiedlichen Konfigurationen zugeteilt. Die Konfiguration (CDC oder CLDC) besteht dabei aus einer Java Virtual Machine und Bibliotheken. Die Profile definieren die APIs für die jeweilige Konfiguration. Leistungsfähigere mobile Geräte besitzen typischerweise eine CDC-, leistungs-schwächere eine CLDC-Konfiguration. Der Umfang der CDC-Bibliotheken ist 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 39 fast gleich der J2SE (s. Abbildung 5.3), es wurden lediglich einige Klassen auf die Umgebung mit weniger Speicher optimiert, sowie einige wenige Bibliotheken weggelassen. Die Konfigurationen können aber auch um zusätzliche Funktionen erweitert werden. CDC-Programme werden durch eine CVM (Customer Virtual Machine ist eine angepasste Version der JVM) interpretiert. CLDC-Geräte besitzen noch weniger Speicher und haben dadurch einen noch kleineren Funktionsumfang der J2SE. Speziell auf Handys ausgerichtet, kommt das MIDP (Mobile Information Device Profile) zum Einsatz, das speziell auf die Bedürfnisse des jeweiligen Geräts zugeschnitten ist. CLDC und MIDP verwenden die von SUN entwickelte KVM5 (Kilobyte Virtual Machine). Applikationen auf Grundlage von MIDP werden Midlets genannt. Das MIDP ist auf minimalste Hardwareanforderungen ausgerichtet. Klassen ausserhalb der J2SE J2SE CDC CLDC Abbildung 5.3: J2ME Klassenbibliotheken Vergleich der J2ME Konfigurationen: CDC CLDC • Speicheranforderungen: 2-16 MB • Speicheranforderungen: 128KB-512KB (min. 512KB ROM, 256KB RAM) • bietet eine komplette Implementierung der standard JVM (min. 128 KB ROM für KVM und CLDCLibraries, min. 32KB Java Runtime und Objekte) 5 Kilobyte Virtual Machine ist die JVM für kleine Endgeräte, die speziell für den Umgang mit eingeschränkten Ressourcen entwickelt wurde 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE • große Bandbreite für Netzwerkverbindungen 40 • geringe Bandbreite für Netzwerkverbindungen • verschieden Verbindungstypen • drahtlose Verbindung möglich • für 32 Bit Prozessoren • Verbindungsgeschwindigkeit nur bis 9600 bps • 16 oder 32 Bit Prozessor • für Geräte mit geringem Stromverbrauch Auf dem P990i ist die Nutzung von Java-Programmen möglich, da eine J2ME Umgebung für CDC 1.0 und CLDC 1.1 von Sony Ericsson implementiert wurde. Folgende Auflistung zeigt die unterstützten APIs der CDC- und CLDC-Umgebung: CLDC 1.1 JARs unterstützen: CLDC Applikation • JTWI 1.0 (JSR6-185) Nokia UI API 1.1 consisting of CLDC 1.1 HI (JSR-139) Mobile 3D Graphics • MIDP 2.0 (JSR-118) Mobile Media API • WMA 1.1 (JSR-120) Wireless Messaging API 2.0 Bluetooth • PDA PIM and File Access (JSR-75) PDA PIM and File Access • Web Service (JSR-172) • Mobile Media API (JSR-135) • Mobile 3D Graphics (JSR-184) • Nokia UI API 1.1 CLDC • Wireless Messaging API 2.0 (JSR-205) Profile • Bluetooth™ wireless technology (JSR-82) JTWI 1.1 WMA 1.1 MIDP 2.0 CLDC 1.1 Bibliotheken KVM Betriebssystem (Symbian v9.1) Abbildung 5.4: P990i CLDC Aufbau 6 Java Specification Request beschreibt die mögliche Weiterentwicklung einer Java-Spezifikation. Mit diesem Verfahren werden neue Java-Standards definiert. 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 41 CDC 1.0 JARs unterstützen: CDC Applikation • Foundation profile 1.0 (JSR-46) constrained environments – No UI support • Personal profile 1.0 (JSR-62) Profile – Designed for low-footprint , resource Personal Profile 1.0 Foundation Profile 1.0 CDC – Java Standard Edition 1.3 derived APIs PDA File Access CDC 1.0 Bibliotheken CVM Betriebssystem (Symbian v9.1) – Foundation Profile + Personal Abbildung 5.5: P990i CDC Aufbau Basis Profile – Full AWT, support for all the AWT components from JDK7 1.1.8 – Support for the applet application programming model • PDA File Access (JSR-75) (Quellen: [wpR6A], [dgcdc]) 5.1.2 Installation Für die Entwicklung eines VoIP-Clients in Java für das P990i wird eine Entwicklungsumgebung mit CDC/CLDC-Unterstützung benötigt. Die von SUN entwickelte IDE (Integrated Development Environment) Netbeans 5.5 wurde für die Programmiersprache Java entwickelt, es werden aber auch andere Sprachen wie C, C++ unterstützt. Für Netbeans gibt es sogenannte Plug-Ins und Packs, wodurch die IDE um zusätzliche Funktionen erweitert werden kann. Die J2ME-Entwicklung in der Netbeans-Umgebung wird durch das sogenannte “Mobility Pack“ ermöglicht, welches in zwei Versionen erhältlich ist, das “Netbeans Mobility Pack for CDC“ und das “Netbeans Mobility Pack for CLDC“. Durch die Mobility Packs ist es schnell und einfach möglich grafische Anwendungen zu entwickeln, da viele visuelle Werkzeuge zur Verfügung stehen. Zusätzlich werden die Programme nach dem Kompilieren durch vorhandene Funktionen in jar-Dateien gepackt ohne vorher durch Kommandozeilenaufrufe erstellt werden zu müssen. 7 JDK ist das Software Development Kit (SDK) von Sun Microsystems und wird als Java Development Kit angegeben 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 42 Andere wichtige Schritte, die zur Erstellung eines Programms notwendig sind, werden mit Hilfe eines Assistenten sehr erleichtert. Die folgende Abbildung zeigt die einfache Nutzung der IDE: Abbildung 5.6: Netbeans CDC GUI Designer (Quelle: [netb]) Für die Installation der IDE werden folgende Komponenten benötigt: • eine Java Plattform (aktuell J2SE v1.6) • UIQ3 SDK8 enthält auch einen P990i-Emulutor • Netbeans 5.5 • Netbeans Mobility Pack for CDC • Netbeans Mobility Pack for CLDC • Sony Ericsson CDC Platform 1 Extension Package for P990i übernimmt spezifische Einstellungen der IDE sowie für den Emulator 8 Software Development Kit besteht aus Programmen und Dokumenten zu einer Software. Soll Entwicklern den Einstieg in die Softwareentwicklung erleichtern 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 43 5.1.3 Implementierung auf der CDC Plattform Auf den Aufbau des JQoS-Projekts und des MjSIP-Stacks sowie die Funktionen und die Nutzung der einzelnen Klassen (auch des javax.sound-Packages), wird in diesem Kapitel nicht eingegangen (s. hierzu Kapitel 4.3). Die Java Virtual Machine der Connected Device Configuration (Customer Virtual Machine) bietet denselben Funktionsumfang wie die standard JVM. Es gibt jedoch noch zusätzliche Implementierung in der J2SE, die in der CDC-Plattform nicht enthalten sind (s. Abbildung 5.7) und die von der CVM nicht unterstützt werden. Dazu gehören z.B. die javax-Packages (javax.swing und javax.sound), die für die Implementierung des MjSIP-Stacks notwendig sind. Das javax.sound-Package wird für die Aufnahme und Wiedergabe der Sprache, das javax.swing-Package für die grafische Oberfläche benötigt. Abbildung 5.7: API Vergleich von J2SE1.4.2 / FP1.1 / PBP1.1 / PP1.1 (Quelle: [wpcdc]) 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 44 Der MjSIP-Stack nutzt das javax.sound-Package, welches durch die Java CDC Implementierung im P990i nicht unterstützt wird (s. Abbildung 5.8). Abbildung 5.8: Sony Ericsson CDC API Vergleich (Quelle: [dgcdc]) Nach dem Erstellen einer CDC-Applikation wird der MjSIP-Stack in das JQoS-Projekt eingebunden und Instanzen der benötigten Klassen werden erstellt. Der Error-Output sowie der Standard-Output werden vom P990i-Emulator nicht in einer Konsole, sondern in Textdateien ausgegeben. Beim Starten der Applikation im P990i-Emulator wird folgende Exception ausgelöst: java.lang.NoClassDefFoundError: javax.sound.sampled.AudioInputStream at java.lang.J9VMInternals.verifyImpl(Native Method) at java.lang.J9VMInternals.verify(Unknown Source) at java.lang.J9VMInternals.initialize(Unknown Source) at JQoS.UserAgent.launchMediaApplication(Unknown Source) at JQoS.UserAgent.onCallAccepted(Unknown Source) at JQoS.Call.onDlgInviteSuccessResponse(Unknown Source) at JQoS.InviteDialog.onTransSuccessResponse(Unknown Source) at JQoS.ExtendedInviteDialog.onTransSuccessResponse(Unknown Source) at JQoS.InviteTransactionClient.onReceivedMessage(Unknown Source) at JQoS.SipProvider.processReceivedMessage(Unknown Source) at JQoS.SipProvider.onReceivedMessage(Unknown Source) at JQoS.UdpTransport.onReceivedPacket(Unknown Source) at JQoS.UdpProvider.run(Unknown Source) Die “NoClassDefFoundError“-Exception wird ausgelöst, wenn eine Klassendefinition nicht gefunden werden kann, die aber während der Laufzeit benötigt wird. Hier ist eindeutig zu sehen, dass die entsprechende javax.sound-Implementierung nicht 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 45 vorhanden ist. Das javax.sound-Package ist einzeln unter [java] erhältlich und kann normalerweise in ein Projekt als zusätzliche Bibliothek eingebunden werden. Diese Bibliothek wird als jar-Datei angeboten und in der IDE dem JQoS-Projekt hinzugefügt. Durch den Aufruf der Applikation wird jetzt eine andere Exception ausgelöst, da die CVM die zusätzlichen Sound-Bibliotheken nicht nutzen kann: ERROR: AudioLine not supported by this System. java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED, 8000.0 Hz, 16 bit, mono, little-endian, audio data, and buffers of 40960 to 40960 bytes is supported. at javax.sound.sampled.AudioSystem.getLine(Unknown Source) at JQoS.AudioInput.initAudioLine(Unknown Source) at JQoS.AudioInput.init(Unknown Source) at JQoS.AudioInput.<init>(Unknown Source) at JQoS.JAudioLauncher.<init>(Unknown Source) at JQoS.UserAgent.launchMediaApplication(Unknown Source) at JQoS.UserAgent.onCallAccepted(Unknown Source) at JQoS.Call.onDlgInviteSuccessResponse(Unknown Source) at JQoS.InviteDialog.onTransSuccessResponse(Unknown Source) at JQoS.ExtendedInviteDialog.onTransSuccessResponse(Unknown Source) at JQoS.InviteTransactionClient.onReceivedMessage(Unknown Source) at JQoS.SipProvider.processReceivedMessage(Unknown Source) at JQoS.SipProvider.onReceivedMessage(Unknown Source) at JQoS.UdpTransport.onReceivedPacket(Unknown Source) at JQoS.UdpProvider.run(Unknown Source) Die “IllegalArgumentException“ wird ausgelöst, wenn ein ungültiger Parameterwert einer Methode übergeben wird. In diesem Fall kann keine TargetDataLine mit den angegeben Parametern erstellt werden. Die CVM muss bei der Implementierung an die Geräte angepasst und für alle zu nutzenden Bibliotheken konfiguriert werden. Dadurch dass der MjSIP-Stack auf einer J2SE-Plattform basiert, werden auch nur bestimmte Formate für die Aufnahme der Sprache unterstützt. Nach der Aufnahme müssen diese Daten in ein entsprechendes Format umgewandelt werden. Diese Umwandlung wird mit Hilfe der in dem javax.sound.sampled.spi-Package vorhanden FormatConversionProvider mit bestimmten Kodierungsverfahren durchgeführt. Die Umwandlungsmethode in z.B. das µ-Law-Format setzt bestimmte Formate für die Aufnahme voraus. Mit diesem Format wird vorher die TargetDataLine erstellt. Für Testzwecke wurde im CDC-Projekt in der Konfiguration des MjSIP-Stacks der Parameter “userProfile.audio=false“ gesetzt um, die SIP-Signalisierung zu testen. Dadurch 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 46 dass keine javax.sound-Klassen aufgerufen werden, wird auch keine Exception im Emulator ausgelöst, die SIP-Signalisierung funktionierte somit problemlos. Beim Starten der Anwendung auf dem P990i treten aber schwerwiegende Fehler (KERN-EXEC, ESock_client usw.) auf und das Endgerät führt einen Neustart durch. Mit Audiounterstützung konnte die Anwendung auf dem P990i auch nicht getestet werden. Das Starten der Applikation führte immer zu einem Absturz und Neustart des Endgerätes. Da auf dem P990i die Aufnahme in keinem Format möglich war, wurde die Entwicklung für das Sony Ericsson P990i auf der Java CDC-Plattform eingestellt. 5.1.4 Implementierung auf der CLDC Plattform MjSIPME ist eine Portierung des MjUA auf die Java CLDC Plattform. MjSIPME ist eine textbasierte SIP-Kommunikation ohne Sprachdaten. Die Kommunikation wird nur per Text durchgeführt (s. Abbilung 5.9). Abbildung 5.9: MjSIPME CLDC Plattform 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 47 Hierzu wurde ein CLDC-Projekt mit der Netbeans IDE und dem Mobility Pack for CLDC erstellt und die portierten MjSIPME-Klassen eingebunden. Die Applikation wurde als jarDatei erstellt und zum Testen auf dem Emulator und dem P990i ausgeführt. Beim J2ME CLDC Emulator kann zusätzlich ein Network-Monitor gestartet werden, der den Netzwerkverkehr mitschneidet. Der Aufbau der SIP-Messages ist gleich der für die J2SE, jedoch wird im Message-Body der SIP-Nachricht nur Text übertragen. Frame 1 (443 bytes on wire, 443 bytes captured) Ethernet II, Src: SonyEric_b7:53:7f (00:12:ee:b7:53:7f), Dst: IntelCor_22:b1:32 (00:15:00:22:b1:32) Internet Protocol, Src: 192.168.178.99 (192.168.178.99), Dst: 192.168.178.102 (192.168.178.102) User Datagram Protocol, Src Port: 5080 (5080), Dst Port: 5070 (5070) Session Initiation Protocol Request-Line: MESSAGE sip:[email protected]:5070 SIP/2.0 Message Header Via: SIP/2.0/UDP 192.168.178.99:5080;rport;branch=z9hG4bK62177 Max-Forwards: 70 To: <sip:[email protected]:5070> From: <sip:[email protected]:5080>;tag=z9hG4bK25927574 Call-ID: [email protected] CSeq: 1 MESSAGE Expires: 3600 User-Agent: mjsip stack 1.6 Content-Type: application/text Content-Length: 23 Message body Test-message from P990i Abbildung 5.10: MjSIPME SIP-Nachricht Dadurch dass keine Sprachkommunikation mit der MjSIPME-Version möglich ist, soll im Rahmen dieser Diplomarbeit versucht werden, die Sprachdaten mit der MMAPI (Mobile Media API (JSR 135)) aufzunehmen, d.h. Playback und Capturing. Um diese Funktionen nutzen zu können, wurde vorab ein kleines Midlet für Testzwecke erstellt. Hiermit soll die Aufnahme der Sprachdaten getestet werden. Der Test wird auf dem Endgerät durchgeführt. Bei der Ausführung des Midlets auf dem P990i tritt ein schwerwiegender Fehler auf: Error javax.microedition.media.MediaException: Unsupported or unknown io protocol capture Aus Kapitel 5.1.1 (Abbildung 5.4) ist zu entnehmen, dass die Unterstützung der MMAPI laut [wpR6A] vorhanden ist. Ein Eintrag vom Sony Ericsson Developer Support im Sony 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 48 Ericsson Developer Forum [nsupp] gibt an, dass momentan (Feb. 2007) nur Audio- und Video-Playback, aber kein Capturing unterstützt wird. Aufgrund dieser Information wird mit einem kleinen Testtool MIDP System Properties v1.2, erhältlich unter [midpsp], die tatsächliche Unterstützung der MMAPI getestet. Dieses Tool fragt mit der Methode System.getProperty() die Systemeigenschaften des Endgerätes ab. Das Tool liefert folgende interessante Ergebnisse: • CLDC & MIDP microedition.profiles: MIDP-1.0 MIDP-2.0 microedition.configuration: CLDC-1.1 microedition.platform: SonyEricssonP990i/R4B03 microedition.encoding: ISO-8859-1 microedition.commports: COM0,IR0 microedition.jtwi.version: 1.0 • Optional Packages microedition.media.version: 1.1 microedition.pim.version: 1.0 microedition.sip.version: null microedition.chapi.version: null microedition.io.file.FileConnection.version: 1.0 • MMAPI supports.mixing: false supports.audio.capture: false supports.video.capture: false supports.recording: false (ob die Aufnahme unterstützt wird) audio.encodings: null (unterst. Formate z.B. encoding=audio/wav) video.encodings: null video.snapshot.encodings: null streamable.contents: null 5.1 Sony Ericsson P990i (ob Audio-Capturing unterstützt wird) © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 49 Die Angabe der nicht unterstützten Aufnahme der MMAPI (s. Ergebnis MIDP System Properties v1.2) wurde durch die Entwickler des Sony Ericsson Developer Forums, [sedw] entgegen der Angabe im White Paper [wpR6A], bestätigt. Zitat: “For JME applications audio and video recording is not supported by the P990, M600 or W950 phones. Currently only audio and video playback is supported using JSR-135“ (Quelle: [sedse]) 5.1.5 Fazit Das Sony Ericsson P990i ist ein Smartphone, das sich bei seiner Auslieferung auf dem Markt als absoluter Konkurrent gegenüber den anderen Smartphones durchgesetzt hat. Es bietet sehr viele Funktionen für Business- und Multimedia-Nutzer. Durch sein großes Touchscreen und die neue UIQ3 Benutzeroberfläche lässt es sich gut bedienen. Mit seinem WLAN-Modul ist eine Internetanbindung möglich. Spiele und andere JavaApplikation sind durch die implementierte CVM ausführbar, jedoch nur mit eingeschränkten Möglichkeiten. Im Rahmen dieser Diplomarbeit sollte versucht werden, einen VoIP-Client zu implementieren. Nach aktuellem Stand (März 2007) der Java Implementierung auf der Sony Ericsson P990i Plattform mit der CDC 1.0 als auch der CLDC 1.1 ist es nicht möglich, einen lauffähigen VoIP-Client in Java zu implementieren, d.h. auch mit der Übertragung von Sprachdaten. Die SIP-Signalisierung funktioniert problemlos, die Audioübertragung hingegen kann nicht realisiert werden. Trotz Angabe der Unterstützung der MMAPI im Sony Ericsson P990i White Paper [wpR6A] wurden die wichtigen Funktionalitäten nicht implementiert und können dadurch auch nicht genutzt werden. 5.1 Sony Ericsson P990i © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 50 5.2 Nokia 770 Das Nokia 770 ist ein Internet Tablet ohne GSM/GPRS/UMTS Unterstützung, d.h. es besitzt keine Telefonfunktion. Den Kern des Nokias bildet ein 220 MHz ARM-Prozessor, der mit 64MB Arbeitsspeicher auskommen muss. Die Internetanbindung ist durch das vorhandene WLAN-Modul (802.11b/g) oder über ein kompatibles Mobiltelefon möglich. Zusätzlich bietet es noch die Verbindungsmöglichkeiten über Bluetooth und USB. Durch sein hochauflösendes Display mit 800x480 Pixeln ist es ein elegantes und kompaktes Tablet, das für komfortables Surfen im Internet optimiert wurde. Es ist sehr gut für die Kommunikation über das Internet geeignet, da es alle gängigen Protokolle für z.B. E-Mail, Instant Messaging und VoIP unterstützt. Außerdem bietet das Nokia 770 die Möglichkeit Internetradio zu hören, Video- und Musikclips zu genießen oder aktuelle Nachrichten über den integrierten Newsreader abzurufen. Auf dem Nokia 770 kommt ein embedded Linux Betriebssystem (Internet Tablet OS Edition 2006) zum Einsatz, das eine Eigenentwicklung von Nokia ist und auf der bekannten “Debian“ Linux Distribution basiert. Mit seinem 128 MB internen Flash Speicher und bis 1GB extern erweiterbarem SD-Karten Speicher ist das Nokia 770 eine gute Basis für multimediale Dienste. Durch den Einsatz eines Linux Betriebssystems gibt es für das Nokia 770 eine Menge freier Software, die von anderen Entwicklern zur Verfügung gestellt wird. Eine komplette Entwicklungsumgebung für eigene Applikationen wird von Nokia auf maemo.org zur Verfügung gestellt. Maemo ist eine komplette Entwicklungsplattform für das Nokia 770 und andere konforme Handhelds und ist eine Alternative zu Symbian OS, Palm OS und Windows CE. Abbildung 5.11: Nokia 770 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 51 5.2.1 Java Plattform Das Nokia 770 bringt aktuell (April 2007) keine offizielle J2ME oder J2SE Implementierung mit. Es gibt jedoch einige Open Source JVMs, die für die Nokia 770 Plattform (d.h. ARM-Prozessor Architektur) portiert wurden. Diese JVMs basieren auf der GNU Classpath (ist eine nach der GNU GPL erhältliche Java API), die mittlerweile fast alle Klassen der Sun Java API implementiert hat. Dadurch dass MjSIP auf der J2SE basiert, muss eine JVM genutzt werden, die mit der J2SE JVM kompatibel ist. Folgende Übersicht zeigt die erhältlichen JVMs: • Blackdown J2RE (ARM Port) ist eine JVM, die speziell für Linux Systeme entwickelt und angepasst wurde, da von Sun keine JVM zur Verfügung stand. Als Libraries werden die Sun Klassenbibliotheken eingesetzt. • JamVM ist eine ziemlich langsamer Java Interpreter (JVM), die auf die Maemo Plattform portiert wurde. Diese JVM nutzt als Klassenbibliotheken die GNU Classpath und ist kompatibel mit den J2SE Spezifikationen. Der Quellcode kann mit dem Java Compiler Jikes von IBM kompiliert werden. • CacaoVM ist eine JVM, die für unterschiedliche Plattformen erhältlich ist und basiert auch auf der GNU Classpath als Klassenbibliotheken und ist somit auch kompatibel mit der J2SE. Tabelle 5 zeigt einen Vergleich der verfügbaren JVMs mit unterschiedlichen Implementierungen für unterschiedliche Plattformen. 5.2 Nokia 770 © 2007, Bernd Müller 5.2 Nokia 770 CE.net, PocketPC/2002 Personal Java schnell Betriebssystem JVM Kompatibilität Geschwindigkeit langsamer Start, angemessene Ausführung Java 2 (1.3.1) Familiar Linux Blackdown J2RE (ARM port) PocketPC/ARM, Palm, HPC Contact NSIcom unterstützte Hardware Kosten kostenlos iPAQ H36xx (or better) zusätzl. unterstützte SWING COMM, All available under Linux Pakete CORBA, SQL, JSSE NSIcom CrEme 3.2.2 Name & Version $49.95 from Handango Dell Axim X5 - schnell Personal Java WinCE 2.11, PocketPC, Linux Esemertec Jeode Kaffe (AWT, J2SE) - Kaffe Familiar Linux Kaffe - langsam Personal Java WinCE 2.11, PocketPC Hewlett Packard ChaiVM kostenlos kostenlos kostenlos PocketPC/ARM, Sharp Zaurus, PocketPC/AR PocketPC/ARM Palm, HPC, Linux, Win32 M Waba, ActiveSync mittel - schnell Java 1.1, Java 1.2 Personal Java, Linux, PocketPC/2002, Windows, Palm, HPC Pro Ewe VM 5 MOBILE ENDGERÄTE 52 Tabelle 5: Java Support für Pocket PC (Quelle: [jsoppc]) © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 53 Trotz dieses relativ großen Angebots an unterschiedlichen JVMs für das Linux Betriebssystem kommen diese JVMs nicht in Frage. Grund dafür ist der stark eingeschränkte Java-Standard, welcher für die embedded Linux Plattform angebotenen wird. Tabelle 5 kann entnommen werden, dass die JVMs, die für embedded Linux angeboten werden, lediglich mit der Java v1.1 bzw. v1.2 oder der Personal Java kompatibel sind, mit Ausnahme der Blackdown JRE, auf die im nachfolgenden Kapitel eingegangen wird. 5.2.2 Blackdown JRE Auf [bldport] ist eine Übersicht der Blackdown JRE Portierungen und der kompatiblen JDK Versionen. Hieraus ist zu entnehmen, dass nur eine JDK 1.1.8 kompatible Version für ARM-Prozessoren erhältlich ist. Da in der JDK 1.1.8 Version noch keine Java Sound Implementierung enthalten ist, kann diese JVM nicht genutzt werden. Unter [ftp://ftp.informatik.hu-berlin.de/pub/Java/Linux/JDK-1.3.1/arm/rc1] ist jedoch eine Blackdown JRE v1.3.1 erhältlich, bei der durch die Verzeichnisstruktur des ftpServers zu erkennen ist, dass diese Version auch für ARM-Architekturen kompiliert wurde. In diesem Verzeichnis ist ein Archiv mit zusätzlichen Paketen für iPAQ-Produkte vorhanden. Anscheinend ist diese Blackdown Version nicht für die embedded Linux Plattform des Nokias abgestimmt, da alles auf eine Familar Linux Distribution der iPAQProdukte hinweist. Die Installation dieser Version ist nicht einfach durchzuführen, da einige Abhängigkeiten von Bibliotheken nicht stimmen. Mit dem Befehl uname -m kann die Hardware des Endgerätes festgestellt werden. Blackdown setzt eine amrv4l-Hardware voraus und uname -m liefert armv5tel. Somit mussten Softlinks auf die bestimmten Verzeichnisse mit den Laufzeitbibliotheken gesetzt werden, die vorher nicht vorhanden waren [oesf]: ln -s /home/root/usr/local/j2re1.3.1/bin/armv4l /home/root/usr/local/j2re1.3.1/bin/armv5tel ln -s /home/root/usr/local/j2re1.3.1/lib/armv4l /home/root/usr/local/j2re1.3.1/lib/armv5tel 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 54 Beim Aufruf von java erscheint immer die Fehlermeldung: libjava.so not found, obwohl diese Bibliothek vorhanden ist. Beim Ausführen des java-Befehls wird diese Script-Datei (JAVA_HOME/bin/.java_wrapper) gestartet, die folgende Befehle enthält: case "`uname -m`" in i[3-7]86 | ia32 | ia64) proc=i386 ;; sparc*) proc=sparc ;; armv5tel) proc=armv4l ;; *) proc="`uname -m`" ;; esac # ----- zusätzlich eingefügte Option ----- In dem case-Block musste zusätzlich die Option für armv5tel gesetzt werden, da uname -m dies zurück liefert. Dadurch wird die proc-Variable auf armv4l gesetzt, damit die entsprechenden Libraries genutzt werden können. Zusätzlichen wurde der Pfad zu allen vorhanden Libraries in die Umgebungsvariablen geschrieben, doch ohne Erfolg. Die Blackdown JRE 1.3.1 ist für die ARM Linux Architektur ausgelegt, scheint aber auf dem Nokia 770 nicht so einfach implementiert werden zu können, da mobile Endgeräte, die auf embedded Linux basieren, unterschiedliche Hardware enthalten, auf die die JVMs angepasst werden müssen. Trotz mehrerer Kontakt-Versuche zu den Entwicklern der Blackdown JRE und langer Suche in Internet-Foren, konnte dieses Problem nicht gelöst werden. Somit ist die Implementierung der vorliegenden Blackdown JRE auf dem Nokia 770 nicht möglich und wird eingestellt. 5.2.3 JaLiMo JaLiMo ist ein Projekt mit dem Ziel einen kompatiblen Java Stack für mobile LinuxGeräte zu erhalten. JaLiMo basiert auf der GNU Classpath als Klassenbibliotheken und nutzt als Java Interpreter die JamVM oder CacaoVM. Der Einsatz der CacaoVM wird von JaLiMo empfohlen, da diese JVM den Bytecode 2-3 mal schneller interpretiert als die JamVM. Die Startup-Zeit der CacaoVM beträgt ca. 3 Sekunden und ist somit auf den ersten Blick langsamer als die JamVM. Dies bezieht sich aber nur auf den Startup. 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 55 Abbildung 5.12: JaLiMo Java Gnome GUI (Quelle: [jalimo]) Um eine JVM auf dem Nokia 770 installieren zu können, werden root-Rechte benötigt, die man üblicherweise nicht hat. Um root-Rechte zu erlangen, wird ein SSH-Server benötigt, über den auf das Gerät mit root-Rechten zugegriffen werden kann. Dabei gelangt man in den so genannten Research & Development Mode (R&D). Die meisten Programme und Tools für diese Plattform sind unter [maemo] erhältlich. Mit dem Nokia 770 kann die Software einfach installiert werden, indem auf der Webseite die entsprechenden Pakete angeklickt werden. Die Installation der hier benötigten Pakete wird dann automatisch durchgeführt. Zunächst wird aber eine Konsole (Xterm) installiert. Zusätzlich wird noch ein SSH-Server (Dropbear) benötigt. Jetzt wird eine SSHVerbindung von einem Host über WLAN zu dem Nokia 770 aufgebaut. ssh [email protected] Als Passwort ist rootme einzugeben. Ab jetzt besitzt man root-Rechte auf dem Endgerät. Nach dem Verlassen des R&D Modes mit exit kann man durch folgendes Kommando erneut root-Rechte bekommen: sudo gainroot Nach dem Erlangen von root-Rechten kann jetzt eine JVM installiert werden. Bei Linux ist dies nicht immer einfach möglich, da die Installation oft über KommandozeilenAufrufe geschehen muss. Dazu wird die in der /etc/source.lst die Quelle der Pakete 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 56 angegeben, so dass diese dann mit dem Befehl apt-get install xxx.deb installiert werden können. Alternativ können für die Maemo-Plattform die Internetseiten mit den Quellen aufgerufen und durch anklicken der Pakete direkt installiert werden. 5.2.4 Implementierung CacaoVm, JamVM und die GNU Classpath sind als deb-Pakete unter [jalimo] erhältlich und können ohne weitere Probleme direkt über den Browser auf der Webseite installiert werden. Durch die Bereitstellung der deb-Pakete ist keine weitere Konfiguration notwendig. Nach der Installation wurde eine kleines HelloWorld Programm zum Testen der JVMs ausgeführt. Die Performance ist nicht wirklich gut und anders als erwartet. Bei der JamVM dauert die Ausgabe ca. 1-2 Sekunden und bei der CacaoVM ca. 3-4 Sekunden. Bevor die Implementierung des MjSIP-Stacks vorgenommen wird, soll die Aufnahme und das Umwandeln der Sprachdaten erstmal mit kleinen Testprogrammen vorab getestet werden. Für die Umwandlung zwischen verschiedenen Standard-Formaten der Java Sound API wurden folgende AudioFormate definiert und mit der Methode AudioSystem.isConversionSupported() getestet: AudioFormat outformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000F, 16, 1, 2, 8000F, false); AudioFormat i1 = new AudioFormat(AudioFormat.Encoding.ULAW, 1, 8000F, false); AudioFormat i2 = new AudioFormat(AudioFormat.Encoding.ULAW, 2, 8000F, false); AudioFormat i3 = new AudioFormat(AudioFormat.Encoding.ULAW, 1, 1, 8000F, false); AudioFormat i4 = new AudioFormat(AudioFormat.Encoding.ULAW, 1, 2, 8000F, false); 8000F, 8, 1, 8000F, 8, 1, 8000F, 16, 8000F, 16, Die Ausführung auf dem Nokia 770 lieferte folgendes Ergebnis: Nokia770-49:/media/mmc1/jar_files# cacao i1 -> outformat: false outformat -> i1: false i2 -> outformat: false outformat -> i2: false i3 -> outformat: false outformat -> i3: false i4 -> outformat: false outformat -> i4: false Nokia770-49:/media/mmc1/jar_files# -jar conversionSupported.jar Bei der Ausführung auf einem PC mit der Sun J2SE v1.6.0 liefert der gleiche Quellcode folgende Ausgabe: 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE i1 -> outformat: outformat -> i1: i2 -> outformat: outformat -> i2: i3 -> outformat: outformat -> i3: i4 -> outformat: outformat -> i4: 57 true true true false true false true false Dabei ist das outformat das Standard-Format zum Aufnehmen und Abspielen der Sprachdaten im MjSIP-Stack. Die Sprachdaten werden dann in das Format i1 kodiert und verschickt. Ohne die Umwandlung von PCM<-> µ-Law (ULAW) kann die Implementierung des MjSIP-Stacks nicht durchgeführt werden, da die Gegenstelle die Sprachdaten µ-Law (oder auch A-Law) kodiert erwartet. Mit einem weiteren Programm soll die Aufnahme getestet werden. Zunächst wird wieder ein AudioFormat definiert: AudioFormat informat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000F, 8, 1, 1, 8000F, false); Danach muss ein Data.Line-Objekt erzeugt werden, mit Informationen für die Line: DataLine.Info info = new DataLine.Info(TargetDataLine.class, informat); Diese Objekt wird dann genutzt, um eine TargetDataLine anzufordern, die Daten in dem informat aufnehmen kann: TargetDataLine line = (TargetDataLine)AudioSystem.getLine(info); Hierbei wird jetzt wieder eine Exception ausgelöst, während die line mit Hilfe des infoObjekts angefordert wird: Nokia770-49:/media/mmc1/jar_files# cacao -jar Testaufnahme.jar Conversion supported: IN -> OUT: false IN_AudioFormat: pcm_signed 8000.0 Hz 8 bits 1 channels OUT_AudioFormat: ulaw 8000.0 Hz 8 bits 1 channels Start recording 5 seconds... Recording-Format: pcm_signed 8000.0 Hz 8 bits 1 channels Exception in thread "main" javax.sound.sampled.LineUnavailableException: no Clip available at javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:392) at bernd.TestSoundAPI.SoundTest.record(SoundTest.java:47) at bernd.TestSoundAPI.SoundTest.main(SoundTest.java:33) Nokia770-49:/media/mmc1/jar_files# Die Entwickler von JaLiMo antworteten mit folgender Aussage auf das Auftreten dieser Exception: 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 58 Zitat: “...Classpath liefert ein 'no Clip available' zurück, wenn kein MixerProvider für die javax.sound API vorhanden ist. javax.sound ist nur eine Art leere Hülle, für die eine Implementierung mitgeliefert werden muss...“ (Quelle: [jasce]) Bei einem weiteren Testprogramm, sollen die Sprachdaten im PCM-Format kodiert und in eine Datei geschrieben werden. Bei der Ausführung dieses Programms treten auf dem Nokia 770 nicht nachvollziehbare Fehler auf: Nokia770-49:/media/mmc1/jar_files# cacao -jar captureDatei.jar cacao: emit.c:253: emit_store: Assertion `(((dst->vv.regoff) & 0xffff0000) >> 16) != 16' failed. Aborted Nokia770-49:/media/mmc1/jar_files# Als letzter Test soll der MjSIP-Stack mit minimalsten Anforderungen innerhalb des JQoSProjekts implementiert werden. Es werden nur die wichtigsten Klassen instantiiert und die Audio-Unterstützung wurde deaktiviert, d.h. es werden keine Formatumwandlungen durchgeführt und keine DataLines angefordert, die eventuell nicht unterstützt werden. Beim Ausführen trat jedoch wieder ein unerwarteter Fehler auf: Nokia770-49:/media/mmc1/jar_files# cacao -jar CmdLineUA_no_audio.jar Exception in thread "main" java.util.zip.ZipException: Not a valid zip file at java.util.zip.ZipFile.checkZipFile(ZipFile.java:209) at java.util.zip.ZipFile.<init>(ZipFile.java:139) at java.util.jar.JarFile.<init>(JarFile.java:199) at java.util.jar.JarFile.<init>(JarFile.java:181) Nokia770-49:/media/mmc1/jar_files# In der Java API ist für diese Exception folgende Erklärung zu finden: Die ZipException tritt nur auf dem Nokia 770 auf. Das gleiche Programm läuft auf einem PC mit J2SE Plattform ohne Fehler ab. Die Klassenbibliotheken der GNU Classpath sind auf dem Nokia 770 in folgendem Archiv enthalten: \classpath\share\classpath\glibj.zip Im Verzeichnis META-INF\services der glibj.zip ist keine Datei mit Informationen über vorhandene FormatConversionProvider vorhanden. Damit bietet die JVM auch keine Umwandlung zwischen den Audioformaten an. 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 59 Die JVMs für mobile Endgeräte scheinen immer noch nicht richtig ausgereift zu sein. Die wichtigsten Klassen sind portiert und funktionieren auch, werden aber bestimmte Klassenbibliotheken, wie die javax.sound-Packages benötigt, so stoßen die JVMs an ihre Grenzen. Die Entwickler von JaLiMo haben ihre Prioritäten auf die Implementierung anderer Bibliotheken und Funktionen gesetzt, so dass in naher Zukunft keine funktionierende Implementierung der Java Sound API innerhalb des JaLiMo Projekts zu erwarten ist. Aus diesem Grund wird die Entwicklung des VoIP-Clients in Java auf diesem Gerät auch eingestellt. Ohne eine absolut kompatible JVM für ARM-Prozessoren, die den gleichen Funktionsumfang einer JVM der J2SE besitzt, ist die Implementierung eines VoIP-Clients (in Java) auf dem Nokia 770 momentan (Mai 2007) nicht möglich. 5.2.5 Fazit Bei dem Nokia 770 handelt es sich um ein tolles Gerät, das viele Funktionen bietet aber auch einige Schwächen zeigt. Als Internet Tablet ist es gut geeignet, stößt jedoch auf Grund seines geringen Arbeitsspeichers ab und zu auch an seine Grenzen, gerade wenn mehrere Anwendungen gleichzeitig geöffnet werden. Durch das Linux Betriebssystem und seine offene Struktur erlaubt das Nokia 770 Anwendungen, die mit anderen PDAs schwer oder gar nicht möglich sind (z.B. die Konsole). Schade ist nur die fehlende Implementierung einer JVM, da heute sehr viel im Internet auf Java basiert. Die erhältlichen JVMs kommen alle aus dem Open Source Bereich und werden ständig verbessert. Bis heute (Mai 2007) gibt es keine JVM für das Nokia 770, die den Bytecode für MSIP vernünftig interpretieren kann. Die eingebundenen Klassenbibliotheken (GNU Classpath) sind in den meisten Klassen inzwischen absolut kompatibel, aber die JVMs greifen noch nicht auf alle Bibliotheken zu. Die Entwickler erweitern ständig ihre JVMs, um Funktionen, die noch nicht unterstützt wurden, beispielsweise den javax.swing-Support. Dabei ist die Unterstützung des javax.soundPackages für diese Diplomarbeit viel wichtiger als die swing-Unterstützung, hat aber bei den Entwickler eine niedrigere Priorität. Hinzu kommt, dass bei den JVMs oft Funktionen für die Ansteuerung des X-Servers noch nicht implementiert wurden. Aus all diesen Gründen wird die Entwicklung auf dem Nokia 770 eingestellt. 5.2 Nokia 770 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 60 5.3 HP iPAQ hx4700 Der hx4700 von HP ist ein PDA der iPAQ Serie und für Business-Anwender ausgelegt. Als Betriebssystem kommt von Microsoft Windows Mobile 2003 Second Edition zum Einsatz. Den Kern bildet ein 624 MHz Xscale-Prozessor, der mit 128MB ROM und 64MB RAM viel Platz für Programme und Daten bietet. Die Internetanbindung ist durch das vorhandene WLAN-Modul (802.11b) möglich. Zusätzlich bietet er noch die Verbindungsmöglichkeiten über Bluetooth, Infrarot und USB. Mit seinem 640x480 Pixel großem VGA-Display bietet er eine gute Möglichkeit, die mitgelieferten Anwendungen zu nutzen. Bei Bedarf lässt sich die Ansicht auch in das Querformat umstellen. Die Bedienung ist kinderleicht und wird durch das Touchscreen durchgeführt. Als erster PDA bietet der hx4700 ein kleines Touchpad, das zum Scrollen, Navigieren oder gar zum Bewegen des Mauszeigers genutzt werden kann. Außer den Standardanwendungen Pocket Outlook, Word, Excel und Internet Explorer liefert HP eine ganze Reihe eigener Utilities (z.B. Backup, Image Zone und Task Switcher). Die Wireless-Verbindungen mit dem hx4700 funktionieren hervorragend. Das Gerät verbindet sich sehr schnell mit einem Access-Point. Da dieses Endgerät keine Telefonfunktion besitzt, soll nun die WLAN-Verbindung genutzt werden, um VoIP-Gespräche führen zu können. So ist der hx4700 nun das dritte Endgerät, auf dem die Implementierung eines VoIP-Clients in Java auf Basis des MjSIP-Stacks durchgeführt werden soll. Da der HP iPAQ hx4700 keine Java Plattform implementiert, muss eine JVM für das WM 2003 SE Betriebssystem gefunden werden, die absolut kompatibel mit der J2SE ist. Abbildung 5.13: HP iPAQ hx4700 5.3 HP iPAQ hx4700 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 61 5.3.1 Mysaifu JVM Mysaifu ist die einzige frei erhältliche Java Virtual Machine für Windows Mobile Betriebssysteme. Das Ziel des Projekts ist die Entwicklung einer JVM die auf der J2SE basiert. Mysaifu wird unter der GPLv2 (GNU Public License Version 2) zur Verfügung gestellt. Aktuell (Juni 2007) steht die JVM in der Version 0.3.3 zur Verfügung und kann auf folgenden Plattformen installiert werden: • Windows Mobile 5.0 (Windows Mobile 2005) • Windows Mobile 2003 Second Edition • Windows Mobile 2003 Mysaifu nutzt als Klassenbibliotheken die GNU Classpath v0.92. Seit der JVM v0.2.2 wird das javax.sound.sampled-Package implementiert, damit ist die Aufnahme und das Abspielen von Sprachdaten möglich. Alle notwendigen Windows CE Klassen und Bibliotheken wurden eingebunden. Die Standard-Klassen der GNU Classpath sind fast gleich der J2SE. Damit können J2SE basierte Applikationen entwickelt werden. Die Installation der Mysaifu JVM findet, wie unter den Pocket PC Betriebssystemen üblich, durch sogenannte cab-Dateien statt. Durch den Aufruf dieser Datei wird eine Installationsroutine gestartet und die JVM installiert. Die JVM besitzt eine grafische Oberfläche und wird nicht, wie von anderen Desktop-Systemen bekannt, über eine Konsole bedient. Nach dem Starten von Mysaifu erscheint ein Input-Dialog. Hier wird eine class-Datei oder jar-Datei angegeben (s. Abbildung 5.14), die ausgeführt werden soll. Abbildung 5.14: Mysaifu Auswahl Dialog 5.3 HP iPAQ hx4700 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE Unter Options können 62 diverse Einstellungen vorgenommen werden, die in unterschiedliche Kategorien unterteilt sind und auf dem entsprechenden Tab ausgewählt werden. Nachfolgend sind die wichtigsten Einstellungen erläutert: • Command line arguments bestimmte Argumente für die Applikation • CLASSPATH Ort der class-Dateien für die Ausführung • Current directory das aktuelle Verzeichnis • Max heap size maximale Größe des Heaps (Der Heap ist ein Speicherbereich der JVM und wird genutzt, um Java Objekte und Klassen während der Laufzeit zu speichern) • Console logfile gibt den Namen der Log-Datei an • Bootclasspath Angabe der Laufzeitbibliotheken • Enable assertions9 Assertions einschalten • Verbose:gc GC10-Log auf Konsole ausgeben 9 geben einen auftretenden Error (nicht Exception) in Java an, wenn eine Bedingung nicht erfüllt ist 5.3 HP iPAQ hx4700 © 2007, Bernd Müller 5 MOBILE ENDGERÄTE 63 • Hide VM window Fenster der JVM nicht anzeigen Nach der Angabe einer class- oder jar-Datei, kann die entsprechende Anwendung ausgeführt werden. Die Ausgabe von System.out und System.err sowie das Einlesen von System.in geschieht über die Konsole. Beim Ausführen eines Java Programms können Parameter als sogenannte “command line options“ angegeben werden. Eine Übersicht der Parameter befindet sich auf [mysf]. Dadurch dass die Mysaifu JVM kompatibel zur J2SE ist, können auch grafische Anwendungen erstellt werden. Dazu können die java.awt- und javax.swing-Packages genutzt werden. Die folgenden Abbildungen zeigen zwei Beispielprogramme, die unter [mysf] erhältlich sind, im direkten Vergleich zur Ausführung unter der Windows XP Plattform. Abbildung 5.15: AWT Demo Abbildung 5.16: Image Viewer 10 Garbage Collector ist in Java für das Speichermanagement zuständig. Werden Objekte zur Laufzeit nicht mehr benötigt, so werden diese vom GC automatisch aus dem Speicher entfernt. 5.3 HP iPAQ hx4700 © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 64 6 Design und Implementierung Der HP iPAQ hx4700 bietet von den drei Endgeräten die beste und schnellste Hardware. Außerdem ist durch die Mysaifu JVM die beste Kompatibilität zur J2SE gegeben. Aufgrund dieser viel versprechenden Basis soll nun die VoIP Implementierung durchgeführt werden. 6.1 JQoS Der Name JQoS ist im Rahmen dieser Diplomarbeit entstanden und soll als Synonym für den VoIP-Client auf Basis des MjSIP-Stacks dienen. Für die Entwicklung von JQoS wurde die Eclipse IDE ausgewählt. Sie ist die bekannteste IDE für Java und ist frei erhältlich. Mit Eclipse können Anwendungen für unterschiedliche Plattformen erstellt werden. Eclipse wird auch durch sogenannte Plug-Ins erweitert. Die Programmierung der grafischen Oberfläche wurde mit dem Visual Editor unter Eclipse durchgeführt. Abbildung 6.1: Eclipse IDE 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 65 Für die Entwicklung von JQoS muss erstmal verstanden werden, wie MjSIP aufgebaut ist und welche Klassen benutzt und instantiiert werden müssen. In diesem Kapitel wird aber nur auf die wichtigsten Klassen eingegangen. Die Zusammensetzung der Nachrichten und Pakete, sowie der restliche Ablauf im MjSIP-Stack, wird nicht erläutert. Die folgende Abbildung zeigt die wichtigsten Klassen des MjSIP-Stacks, die für die Entwicklung von JQoS ausschlaggebend sind: new JQoS() new UserAgent() UserAgent JQoS new UserAgentProfile() new RegisterAgent() UserAgentProfile new SipProvider() RegisterAgent SipProvider new JAudioLauncher() JAudioLauncher new AudioInput() AudioInput new AudioOutput() AudioOuput new AudioInputStream() new AudioOutputStream() Abbildung 6.2: MjSIP Instanzen Der Einstiegspunkt der Java-Anwendung ist die Methode main(). Hier wird eine neue Instanz der JQoS-Klasse gebildet. Innerhalb dieser Klasse ist der ganze Ablauf der Anwendung enthalten. Nach der Variablendeklaration und dem Erstellen der grafischen Elemente muss der Client zunächst an einem SIP-Server registriert werden. Über den Button jBtn_register wird zunächst die Methode SipStack.init() aufgerufen, die den SipStack initialisiert (standard Port, Protokolle etc. werden gesetzt). Danach wird eine Instanz des UserAgentProfiles gebildet. Das UserAgentProfile enthält alle Angaben über den Benutzer, die Art der Registrierung, Audio- und Videounterstützung. Alle Angaben auf der grafischen Oberfläche werden eingelesen und in die Variablen des UserAgentProfiles geschrieben. 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 66 // new UserAgentProfile UserAgentProfile user_profile = new UserAgentProfile(null); // UA configuration if (jTxtField_Username.getText() != "") user_profile.username = jTxtField_Username.getText(); if (jPasswordField.getText() != "") user_profile.passwd = jPasswordField.getText(); if (jTxtField_Realm.getText() != "") user_profile.realm = jTxtField_Realm.getText(); if (jCheckBox_do_register.isSelected()) user_profile.do_register = true; if (jCheckBox_do_unregister.isSelected()) user_profile.do_unregister = true; if (jCheckBox_do_unregister_all.isSelected()) user_profile.do_unregister_all = true; if (Long.parseLong(jTxtField_keepalive_time.getText().trim()) >= 0) user_profile.keepalive_time = Long.parseLong(jTxtField_keepalive_time.getText().trim()); if (jCheckBox_audio_support.isSelected()) user_profile.audio = true; if (jCheckBox_receive_only.isSelected()) user_profile.recv_only = true; if (jCheckBox_send_only.isSelected()) user_profile.send_only = true; user_profile.from_url = ("<sip:").concat(jTxtField_Username.getText()).concat("@") .concat(jTxtField_Realm.getText()).concat(">"); //Audio-Codec user_profile.audio_codec = "PCMU"; //Codec RTP-Parameter user_profile.audio_avp = 0; Danach wird eine Instanz der Klasse SipProvider erstellt, die für den Transport der SIPNachrichten zuständig ist. // new SipProvider SipProvider sip_provider = new SipProvider(SipProvider.AUTO_CONFIGURATION, port); Mit dem Aufruf der apply()-Methode werden die Klassen UserAgent und RegisterAgent instantiiert, UserAgentProfile indem den Konstruktoren dieser Klassen das und der SipProvider übergeben werden. /** new UserAgent & RegisterAgent */ public void apply(SipProvider sip_provider, UserAgentProfile user_profile) { this.user_profile = user_profile; ua = new UserAgent(sip_provider, user_profile,this); ua.listen(); ra = new RegisterAgent(sip_provider, user_profile.from_url, user_profile.contact_url, user_profile.username, user_profile.realm, user_profile.passwd, this); run(); } Der UserAgent ist der zentrale Punkt (so genannter Prototyp) dieser Anwendung. Innerhalb dieser Klasse sind alle wichtigen Methoden definiert. Hier werden alle Einstellungen durchgeführt und andere Klassen aufgerufen, die für den Aufbau der SIP- 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 67 Kommunikation notwendig sind. Der RegisterAgent enthält Methoden, um den Benutzer einmal oder periodisch bei dem SIP-Server zu registrieren oder abzumelden. Die vorgenommenen Einstellungen im UserAgentProfile werden mit der run()Methode überprüft um dann die entsprechenden Methoden aufzurufen. Wird eine Registrierung verlangt, so wird die loopRegister()-Methode zum periodischen Registrieren am SIP-Server ausgeführt: /** Periodically registers the contact address with the registrar server. * @param expire_time expiration time in seconds * @param renew_time renew time in seconds * @param keepalive_time keep-alive packet rate (inter-arrival time) in milliseconds */ public void loopRegister(int expire_time, int renew_time, long keepalive_time) { if (ra.isRegistering()) ra.halt(); ra.loopRegister(expire_time,renew_time,keepalive_time); } Wird der Client erfolgreich am Server registriert, so wird der Status-Code “200 OK“ zurückgegeben. Tritt ein Fehler oder Timeout auf, wird der entsprechende Status-Code ausgegeben. Wenn der Client beim SIP-Server abgemeldet werden soll, so wird die unregister()-Methode ausgeführt und der Status-Code ausgegeben. /** Unregister with the registrar server */ public void unregister() { if (ra.isRegistering()) ra.halt(); ra.unregister(); } Für Testzwecke gibt es einen “only signalling mode“, der durch setzen der Variable audio=false im UserAgentProfile aktiviert wird. Hierbei werden keine DataLines (TargetDataLine und SourceDataLine) angefordert. Es wird lediglich eine SIPSignalisierung durchgeführt und keine Sprachdaten übertragen. Ist JQoS einmal an an SIP-Server registriert, so befindet sich die Anwendung im Zustand “idle“. Im UserAgent sind vier Zustände definiert, die je nach eintretender Aktion gesetzt werden: • UA_IDLE (wartet auf Aktion) • UA_INCOMING_CALL (eingehender Anruf) • UA_OUTGOING_CALL (ausgehender Anruf) • UA_ONCALL (Gespräch wird geführt) 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 68 Zum Tätigen eines Anrufs wird die SIP-URI des Gesprächspartners eingegeben. Durch Drücken des jBtn_Call-Buttons wird erstmal überprüft, ob der UserAgent im Zustand “idle“ ist. // make a call if (ua.statusIs(UserAgent.UA_IDLE)) { // if SIP URL is empty if(jTextArea_Call_to.getText().equalsIgnoreCase(zero)) jTextArea_SIP_Messages.setText("Enter valid SIP URL"); String SIP_URL = (String)jTextArea_Call_to.getText(); System.out.println("CALLING " + jTextArea_Call_to.getText()); if (SIP_URL != null && SIP_URL.length()>0) { ua.hangup(); ua.call(SIP_URL); jTextArea_SIP_Messages.append("\nCALLING " + SIP_URL); } } // accept a call else if (ua.statusIs(UserAgent.UA_INCOMING_CALL)) { ua.accept(); jTextArea_SIP_Messages.append("\nON CALL"); } Befindet sich der ua.call(SIP_URL) UserAgent in diesem Zustand, so wird die Methode aufgerufen und die Verbindung hergestellt. Geht ein Anruf ein, wird wieder der Zustand überprüft und die ua.accept()-Methode aufgerufen. Nach dem Annehmen oder Einleiten eines Anrufs werden die benötigten Methoden aufgerufen und die Verbindung hergestellt. Ist die Verbindung zwischen den Teilnehmern hergestellt, so wird in der Klasse UserAgent die Methode lauchMediaApplication() aufgerufen, die eine neue Instanz der Klasse JaudioLauncher erstellt. Diese Klasse ist für die Aufnahme und das Abspielen der Sprachdaten zuständig und basiert auf dem javax.soundPackage. In dem Konstruktor der Klasse wird zunächst ein neues AudioFormat für die Transportdaten definiert. Danach wird die Klasse AudioInput instantiiert und dieses AudioFormat /** int /** int (Format der Sprachdaten beim Transport) dieser Klasse übergeben. Sample rate [bytes] */ sample_rate=8000; Sample size [bytes] */ sample_size=1; AudioFormat.Encoding codec=AudioFormat.Encoding.ULAW; boolean big_endian=false; // AUDIO INPUT from MIC (ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame) AudioFormat format = new AudioFormat(codec, sample_rate, 8*sample_size,1, sample_size, sample_rate, big_endian); audio_input=new AudioInput(format); 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 69 In dieser Klasse AudioInput wird das Aufnahmeformat definiert und damit ein DataLine.Info-Objekt erstellt, das Informationen über dieses Aufnahmeformat (PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes/frame) enthält. Danach wird eine TargetDataLine mit diesem Objekt erstellt und geöffnet. // capturing format AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, fFrameRate, 16, 1, 2, fFrameRate, false); // DataLine.Info object DataLine.Info lineInfo = new DataLine.Info(TargetDataLine.class, format, INTERNAL_BUFFER_SIZE); if (!AudioSystem.isLineSupported(lineInfo)) { System.err.println("ERROR: AudioLine not supported by this System."); } try { // create line target_line = (TargetDataLine)AudioSystem.getLine(lineInfo); if (DEBUG) println("TargetDataLine: "+target_line); // open line target_line.open(format,INTERNAL_BUFFER_SIZE); } catch (LineUnavailableException e) { System.err.println("ERROR: LineUnavailableException at AudioSender()"); e.printStackTrace(); } Mit dem folgenden Aufruf wird ein AudioInputStream-Objekt erstellt, das die Daten aus der angegebenen TargetDataLine liest: audio_input_stream = new AudioInputStream(target_line); Danach müssen diese Daten in das zuvor übergebene Format (ULAW 8000.0 Hz, 8 bit, mono, AudioSystem 1 bytes/frame) umgewandelt werden. Dafür bietet die Klasse eine Umwandlungsmethode an. // convert the audio stream to the selected format // ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame audio_input_stream = AudioSystem.getAudioInputStream(format,audio_input_stream); Der audio_input_stream im PCM-Format wird jetzt in das ULAW-Format mit Hilfe eines FormatConversionProviders umgewandelt. Danach können die Daten mit Hilfe weiterer Methoden und Klassen verpackt und über RTP versendet werden. Das Empfangen und Abspielen der eingehenden Sprachdaten geschieht analog. Hierbei kommen die Daten im ULAW-Format an und müssen vor dem Abspielen in das PCMFormat umgewandelt werden. Der einzige Unterschied besteht in der Umwandlung der 6.1 JQoS © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 70 Sprachdaten von ULAW nach PCM. Im javax.sound-Package ist kein äquivalenter AudioOutputStream im MjSIP-Stack zu dem bestehenden AudioInputStream vorhanden. Hier wird die implementierte AudioOutputStream-Klasse verwendet, um die Sprachdaten zu behandeln und abzuspielen. 6.2 Test und Implementierung Der VoIP-Client “JQoS“ wird nun als jar-Datei aus der IDE exportiert. Beim Ausführen auf dem Pocket PC wird die grafische Oberfläche angezeigt. Die Registrierung beim SIP-Server wird ohne Probleme durchgeführt und liefert den Status-Code “200 OK“ zurück. Zum Testen wird erstmals der “only signalling mode“ ausgeführt. Die SIPSignalisierung funktioniert und die Verbindung zwischen den Teilnehmern wird aufgebaut. Jetzt soll der Client mit Audiounterstützung getestet werden. Dazu wird vom Pocket PC aus ein Teilnehmer angerufen. Nach dem Abheben der Gegenstelle werden weder auf dem Pocket PC noch auf der Gegenstelle Sprachdaten ausgegeben. Der Grund dafür ist eine Exception, die auf dem Pocket PC ausgelöst wird und folgende Fehlermeldungen enthält: starting JQoS VoIP Client ... Capturing Format: pcm_signed 8000.0 Hz 16 bits 1 channels little endian AudioInput: TargetDataLine: gnu.javax.sound.sampled.wce.WCETargetDataLine@4c028f8c Output Format: pcm_signed 8000.0 Hz 16 bits 1 channels little endian AudioOutput: SourceDataLine: gnu.javax.sound.sampled.wce.WCESourceDataLine@4c09f1cc UA: REGISTRATION UA: 200 OK CALLING [email protected]:5080 UA: RINGING UA: ACCEPTED/CALL java.lang.IllegalArgumentException: format not supported for stream at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:240) at JQoS.AudioInput.init(AudioInput.java:111) at JQoS.AudioInput.<init>(AudioInput.java:91) at JQoS.JAudioLauncher.<init>(JAudioLauncher.java:145) at JQoS.UserAgent.launchMediaApplication(UserAgent.java:394) at JQoS.UserAgent.onCallAccepted(UserAgent.java:514) at JQoS.Call.onDlgInviteSuccessResponse(Call.java:224) at JQoS.InviteDialog.onTransSuccessResponse(InviteDialog.java:606) at JQoS.ExtendedInviteDialog.onTransSuccessResponse(ExtendedInviteDialog.java:254) at JQoS.InviteTransactionClient.onReceivedMessage(InviteTransactionClient.java:107) at JQoS.SipProvider.processReceivedMessage(SipProvider.java:903) at JQoS.SipProvider.onReceivedMessage(SipProvider.java:1009) at JQoS.UdpTransport.onReceivedPacket(UdpTransport.java:92) at JQoS.UdpProvider.run(UdpProvider.java:151) at java.lang.VMThread.run(VMThread.java:120) AudioLauncher: starting java audio.. 6.2 Test und Implementierung © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 71 UA: CLOSE AudioLauncher: halting java audio.. JVM exit. Das Abspielen und die Aufnahme der Sprachdaten wird im PCM-Format auf dem Pocket PC unterstützt. Der aufgenommene Stream muss dann in das ULAW-Format umgewandelt werden. Beim Abspielen kommen die Daten im ULAW-Format an und müssen vor der Ausgabe im Lautsprecher in das PCM-Format umgewandelt werden. Diese Umwandlungen werden nicht unterstützt. Im Quelltext der Klasse AudioInput wird folgende Formatumwandlung durchgeführt. audio_input_stream = AudioSystem.getAudioInputStream(format,audio_input_stream); Hier soll der AudioInputStream (d.h. die Aufnahme vom Mikrofon), der im PCMFormat kodiert ist, in das ULAW-Format umgewandelt werden, da die Gegenstelle die Sprachdaten ULAW kodiert erwartet. Diese Konvertierung kann nicht durchgeführt werden, da die Mysaifu JVM keine FormatConversionProvider implementiert. Auch das Überprüfen der Umwandlung zwischen den beiden Formaten mit der in Kapitel 4.1 vorgestellten Methode des AudioSystems lieferte den Rückgabewert “false“. System.out.println(AudioSystem.isConversionSupported(targetFormat, sourceFormat)); Die Mysaifu JVM greift auf Bibliotheken zurück, die im folgenden Verzeichnis auf dem Pocket PC installiert wurden: \Mysaifu JVM\jre\lib\ Die Klassenbibliotheken der GNU Classpath sind im Archiv rt.jar enthalten. In diesem Archiv fehlt das Verzeichnis META-INF\services. Hier müssten Dateien vorhanden sein, wie z.B. javax.sound.sampled.spi.FormatConversionProvider, die den Ort der SPIs angeben (z.B. com.sun.media.sound.UlawCodec). Weitere Bibliotheken sind im resource.jar Archiv enthalten. Hier existiert das Verzeichnis META-INF\services und enthält Dateien mit Angaben über SPIs. Es ist aber keine FormatConversionProvider-Datei vorhanden, die den Ort der Konvertierungsklassen angibt. Unter [mysf] ist angegeben, dass zur Zeit als AudioFormat nur linear-PCM (8/16 Bit) unterstützt wird. 6.2 Test und Implementierung © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 72 Zitat: “Now javax.sound.sampled supported. You can play and record sounds. Read and write sound file also. Currently, supported sound format is linear-PCM (8bit/16bit).“ (Quelle: [mysf]) Durch diese Angabe wird deutlich warum die Mysaifu JVM noch keine SPIs für die Audiokonvertierung implementiert hat. Dieses Problem wurde versucht durch Einbinden der freien Java Sound Implementierung “Tritonus“ zu lösen. Jedoch brachte dieser Versuch auch keinen Erfolg, da die JVM auf die SPIs von Tritonus nicht zugreift. Ein Test mit Tritonus für verschiedene Umwandlungen z.B. PCM<->GSM06.10 funktioniert auf dem PC, löst auf dem HP iPAQ hx4700 jedoch folgende Exception aus: java.lang.IllegalArgumentException: conversion not supported at org.tritonus.sampled.convert.gsm.GSMFormatConversionProvider.getAudioInputStream(GSMFormat ConversionProvider.java:151) at JQoS.AudioInput.init(AudioInput.java:120) at JQoS.AudioInput.<init>(AudioInput.java:97) at JQoS.JAudioLauncher.<init>(JAudioLauncher.java:156) at JQoS.UserAgent.launchMediaApplication(UserAgent.java:367) at JQoS.UserAgent.onCallAccepted(UserAgent.java:488) at JQoS.Call.onDlgInviteSuccessResponse(Call.java:224) at JQoS.InviteDialog.onTransSuccessResponse(InviteDialog.java:606) at JQoS.ExtendedInviteDialog.onTransSuccessResponse(ExtendedInviteDialog.java:254) at JQoS.TransactionClient.onReceivedMessage(TransactionClient.java:80) at JQoS.SipProvider.processReceivedMessage(SipProvider.java:903) at JQoS.SipProvider.onReceivedMessage(SipProvider.java:1010) at JQoS.UdpTransport.onReceivedPacket(UdpTransport.java:92) at JQoS.UdpProvider.run(UdpProvider.java) at java.lang.VMThread.run(VMThread.java:120) Nach Angabe der Entwickler von Tritonus müssen diese Pakete nur dem Classpath hinzugefügt werden. Während der Laufzeit werden diese von Java automatisch eingebunden und können über das AudioSystem genutzt werden. Trotz dieser Angaben greift die Mysaifu JVM nicht auf die Tritonus-Pakete zu. Danach wurde zum Testen der Klassenbibliotheken der Mysaifu JVM das rt.jar Archiv (Klassenbibliotheken) in das JQoS-Projekt eingebunden. Dazu wurde das rt.jar Archiv vom Pocket PC kopiert und in der IDE dem Projekt zur Verfügung gestellt. Die Klassenbibliotheken des SUN JDK 1.6 wurden aus dem Projekt entfernt und waren 6.2 Test und Implementierung © 2007, Bernd Müller 6 DESIGN UND IMPLEMENTIERUNG 73 somit nicht nutzbar. Bei der Ausführung mit den Mysaifu Klassenbibliotheken tritt kein Fehler auf dem PC auf und JQoS läuft stabil wie mit den SUN Klassenbibliotheken. Dadurch dass JQoS auf einem PC mit diesen Klassenbibliotheken läuft, wird ersichtlich, dass die Mysaifu JVM die Klassen die enthalten sind, nicht nutzt. Hier wird dringend eine Anpassung oder Erweiterung der Mysaifu JVM benötigt. Werden diese Unterstützungen implementiert, so ist die Ausführung von JQoS ohne jegliche Anpassung oder Konfiguration auf dem mobilen Endgerät sofort möglich. 6.3 Performance Der HP iPAQ hx4700 ist mit Abstand das leistungsfähigste Gerät der drei Endgeräte. Trotz seines verhältnismäßig schnellen Intel XScale Prozessors ist die Ausführung von Java Programmen auf solchen Endgräten nur bedingt möglich. Je umfangreicher die Programme werden, desto langsamer wird das Gerät, da die JVM auch einiges an Prozessorleistung und Speicher benötigt. Eine Implementierung einer Software, die in einer Programmiersprache wie C/C++ geschrieben wird, ist hier wesentlich sinnvoller, da der Code nicht noch durch eine virtuelle Maschine interpretiert werden muss und somit wesentlich schneller ausgeführt werden kann. Der Startup von JQoS dauert schon mehrere Sekunden. Dabei werden beim Start nur grafische Komponenten initialisiert. Durch die grafischen Komponenten in JQoS wird das System zusätzlich stark ausgebremst. Je nach Button kann eine Reaktion auf das Betätigen dieses Buttons mehrere Sekunden dauern. Damit ist die Empfehlung von Java-Anwendungen bei leistungsschwächeren Geräten nicht sehr sinnvoll. Nur der Einsatz von kleinerer Java-Software in Verbindung mit einer JVM ist auf dem Pocket PC empfehlenswert. 6.3 Performance © 2007, Bernd Müller 7 FAZIT UND AUSBLICK 74 7 Fazit und Ausblick Diese Diplomarbeit wurde in Kooperation mit der Ericsson GmbH durchgeführt. Die Implementierung des VoIP-Clients war ursprünglich nur auf dem Sony Ericsson P990i geplant. Aufgrund der aufgetretenen Probleme wurden jedoch zwei weitere Geräte für die Implementierung ausgewählt. Das Ziel dieser Diplomarbeit war die Entwicklung und Untersuchung eines Java basierten VoIP-Clients für mobile Endgeräte. Dazu wurde JQoS im Rahmen dieser Diplomarbeit entwickelt, um die Nutzung eines VoIP-Clients in Java auf diesen mobilen Endgeräten zu demonstrieren. Dabei traten große Probleme mit der Kompatibilität der JVMs zur J2SE auf. Es musste eine JVM gefunden werden, die absolut konform mit der J2SE ist. Dadurch dass solch eine JVM weder auf diesen mobilen Endgeräten implementiert wurde noch frei erhältlich war, konnte die Realisierung dieses VoIPClients basierend auf dem MjSIP-Stack nicht durchgeführt werden. Das Ziel dieser Diplomarbeit war die Implementierung eines Java basierten VoIP-Clients und nicht die Implementierung von JVMs auf mobilen Endgeräten. Das hier immer wieder aufgetretene Problem war die Unterstützung der wichtigen Klassen für das Capturing und die Umwandlung von Sprachdaten in das gewünschte Audioformat (hier µ-Law). Ohne diese Unterstützungen ist es im Rahmen dieser Diplomarbeit nicht möglich, eine funktionierende Implementierung, d.h. auch mit Übertragung der Sprachdaten, auf einem der hier genutzten mobilen Endgeräte zu realisieren. Bei der Entwicklung von Java-Programmen wird keine Rücksicht auf die Kompatibilität der JVM des jeweiligen Zielsystems genommen. Wenn Java-Programme entwickelt werden, wird in der Spezifikation einzig und allein die Unterstützung einer J2SE Umgebung angegeben. Ist diese Umgebung nicht oder nur zum Teil gegeben, so muss von Seiten der Entwickler der JVMs die nötige Kompatibilität geschaffen werden. Dadurch das SUN im Frühjahr 2007 bekannt gegeben hat, den Java-Quellcode zu veröffentlichen, kann man eventuell in der nächsten Zeit eine vollständig kompatible JVM für leistungsfähige, mobile Endgeräte erwarten. 7 Fazit und Ausblick © 2007, Bernd Müller 7 FAZIT UND AUSBLICK 75 Auf einer Windows XP sowie Linux Plattform, die als Java-Unterstützung die J2SE ab v1.3.1 implementiert, läuft der JQoS VoIP-Client sehr schnell und stabil. Einzig und allein eine J2SE Basis ist für die JQoS Ausführung notwendig. Zur Zeit ist die Entwicklung einer absolut kompatiblen JVM für verschiedene mobile Endgeräte dringend notwendig. Das Internet entwickelt sich immer mehr zu einer multimedialen Plattform. Es werden immer mehr Dienste für Multimedia-Applikationen bereitgestellt, die durch die Implementierung einer JVM plattformunabhängig angeboten werden könnten. Aufgrund dieser großen Probleme mit den JVMs, die während dieser Diplomarbeit auftraten, wäre die Entwicklung und Implementierung einer solchen JVM für mobile Endgeräte, ein weiteres Thema für eine zukünftige Diplomarbeit. 7 Fazit und Ausblick © 2007, Bernd Müller ABKÜRZUNGSVERZEICHNIS 76 Abkürzungsverzeichnis Die wichtigsten hier verwendeten Abkürzungen: CDC Connected Device Configuration JSR 36 CLDC Connected Limited Device Configuration JSR 30 DHCP Dynamic Host Configuration Protocol RFC 2131 DiffServ Differentiated Services RFC 2474, RFC 2475 DSCP Differentiated Services Code Point RFC 2474 DSL Digital Subscriber Line GPL General Public License GPRS General Packet Radio Service GSM Global System for Mobile Communications HTTP Hypertext Transfer Protocol IANA Internet Assigned Numbers Authority IETF Internet Engineering Task Force iLBC internet Low Bitrate Codec IP Internet Protocol IDE Integrated Development Environment ISDN Integrated Services Digital Network ITU-T International Telecommunication Union J2ME Java 2 Micro Edition J2SE Java 2 Standard Edition JSR Java Specification Request JMF Java Media Framework KVM Kilobyte Virtual Machine LAN Local Area Network MD5 Message Digest Algorithm 5 RFC 1321 MIDP Mobile Information Device Profile JSR 37, JSR 118 MMAPI Mobile Media API JSR 135 MOS Mean Opinion Score NAT Network Address Translation OSI Open Systems Interconnection RFC 1945, RFC 2616 RFC 791 RFC 3022, RFC 2663 © 2007, Bernd Müller ABKÜRZUNGSVERZEICHNIS 77 PCM Pulse Code Modulation PDA Personal Digital Assistant QoS Quality of Service RAT Robust Audio Toolkit RFC Requests for Comments RTCP Real Time Control Protocol RFC 3551 RTP Real-Time Transport Protocol RFC 3550 SDP Session Description Protocol RFC 4566 SIP Session Initiation Protocol RFC 3261 TCP Transmission Control Protocol RFC 793 ToS Type of Service RFC 1349 UAC User Agent Client UAS User Agent Server UDP User Datagram Protocol UIQ User Interface Quartz UMTS Universal Mobile Telecommunications System URI Uniform Resource Identifier RFC 3986 URL Uniform Ressource Locator RFC 1738, RFC 3986 USB Universal Serial Bus VIC Video Conferencing Tool VoIP Voice over IP WLAN Wireless LAN SDK Software Development Kit RFC 768 © 2007, Bernd Müller QUELLENVERZEICHNIS 78 Quellenverzeichnis [tospic]: QoS/ToS (IP Layer-3 Priorisierung) http://de.wikipedia.org/wiki/Bild:Voip_tos.jpg [rtppar]: RTP Payload types http://www.iana.org/assignments/rtp-parameters [sippar]: SIP Parameter http://www.iana.org/assignments/sip-parameters [mjsip]: MjSIP http://mjsip.org/ [ronly]: Captured packets (receive only mode) file://recv-only-Mode.pcap [sonly]: Captured packets (send only mode) file//send-only-Mode.pcap [mjgsm]: Captured packets (MjSIP mit GSM-Codec) file://MjSIP(rtmap_0_GSM_8000 - RTP_payload_PCMU_8000).pcap [jspeex]: JSpeex (Java Portierung des Speex SPrachcodecs) http://jspeex.sourceforge.net [triton]: Tritonus: Plattformunabhängige Implementierung der Java Sound API http://www.tritonus.org/ [dsj2me]: Java 2 Micro Edition Datasheet http://www.sun.com/software [wpR6A]: Sony Ericsson P990i White Paper (R6A) file://Sony Ericsson P990i White Paper (R6A).pdf [dgcdc]: Sony Ericsson Developers Guidelines J2ME CDC file://SE Developers Guidelines - Java ME CDC.pdf [netb]: Netbeans IDE und Mobility Packs http://www.netbeans.org [wpcdc]: Java Platform Micro Edition CDC White Paper (June 2005) http://java.sun.com/javame © 2007, Bernd Müller QUELLENVERZEICHNIS [java]: 79 Sun Microsystems Java 2 Platform http://java.sun.com [nsupp]: Sony Ericsson Developer Support (audio/video capture not supported) http://developer.sonyericsson.com/thread.jspa?threadID=31960& tstart=90 [midpsp]: Forum Nokia (MIDP System Properties v1.2) http://www.forum.nokia.com/info/sw.nokia.com/id/37086440-dcce4fb4-aa3e-8d8c16d62b33/MIDP_System_Properties_v1_2_en.zip.html [sedse]: Sony Ericsson Developer Support (E-Mail) file://Sony Ericsson Developer Support.htm [jsoppc]: Java Support on Pocket PC http://www.comp.lancs.ac.uk/~fittond/ppcjava.html [bldport]: Übersicht der Blackdown Portierungen http://gd.tuwien.ac.at:8090/java-linux/ports.html [oesf]: Open Embedded Software Foundation http://www.oesf.org/forums [jalimo]: Java Linux Mobile Project http://www.jalimo.org [maemo]: Maemo Open Source Development http://maemo.org [jasce]: JaLiMo Sound Caturing Problem (E-Mail) file://JaLiMo Sound Caturing.txt [mysf]: Mysaifu Java Virtual Machine http://www2s.biglobe.ne.jp/~dat/java/project/jvm/index_en.html [triapi]: Tritonus API http://tritonus.sourceforge.net/apidoc http://sourceforge.net/projects/tritonus [jspg] Java Sound API Programmer's Guide http://java.sun.com/j2se/1.5.0/docs/guide/sound/programmer_guide [jsrc]: Java Sound Resources http://www.jsresources.org © 2007, Bernd Müller QUELLENVERZEICHNIS [jsgs] 80 Java Sound, Getting Started by Richard G. Baldwin http://www.developer.com/java/other/article.php/1572251 [wiki]: Wiki http://de.wikipedia.org [voipw]: VoIP Wiki http://www.voip-info.org/wiki [voipgr]: VoIP Grundlagen (Autoren: Mathias Hein/Michael Reisner) http://www.voipango.de [ietf]: IETF Dokumente http://tools.ietf.org/html [sedw]: Sony Ericsson Developer World http://developer.sonyericsson.com [jcp]: Java Community Process http://jcp.org [n770ds]: Nokia 770 Datenblatt http://europe.nokia.com/A4145105 [uiq]: UIQ Developer Community http://developer.uiq.com [jamvm]: JamVM Java Virtual Machine http://jamvm.sourceforge.net [bdown]: Blackdown Java Platform 2 for Linux http://www.blackdown.org [cacvm]: CacaoVM Java Virtual Machine for Linux http://www.cacaojvm.org Ansgar Gerlicher: Symbian OS - Eine Einführung in die Anwendungsentwicklung, dpunkt.verlag, 2004 ISBN 3-89864-285-2 Martin de Jode: Programming Java 2 Micro Edition on Symbian OS, John Wiley & Sons Ltd, 2004 ISBN 0-470-09223-8 © 2007, Bernd Müller ANHANG A 81 Anhang A Technische Daten der mobilen Endgeräte Sony Ericsson P990i Plattform Symbian v9.1 / UIQ3 CPU 208 Mhz AMR Display 240x320 Pixel QVGA mit 262.144 Farben Speicher 64MB RAM, 128MB Flash Memory, extern bis 8GB Bedienung Nummer- und QWERTZ-Tastatur, Touchscreen Kartensteckplätze Memory Stick Pro Duo Konnektivität Infrarot, Bluetooth, USB 2.0, WLAN Mikrofon / Lautsprecher Ja / Ja Java CDC 1.0, CLDC 1.1 Messaging SMS, EMS, MMS, E-Mail Browser Opera v8 Media Audio: AU, iMelody, AAC, AMR, MP3, RMF, DLS, M4A, Real Audio, MIDI, WAV, XMF Video: MP4, 3GP, Real Video Laufzeit Standby 340 Std., Gesprächszeit 9 Std. Dimensionen 114x57x25 mm (HxBxT) Gewicht 155 g Extras UMTS, Kamera, RDS Radio, Videotelefonie, u.v.m. Tabelle 6: Sony Ericsson P990i technische Daten © 2007, Bernd Müller ANHANG A 82 Nokia 770 Plattform Linux embedded (Internet Tablet OS 2006 Edition) CPU 220 Mhz ARM-Prozessor Display 800x480 Pixel mit 65.536 Farben Speicher 64MB RAM, 128MB Flash Memory, extern bis 1GB Bedienung Touchscreen Kartensteckplätze SD-Card Konnektivität Bluetooth, USB, WLAN Mikrofon / Lautsprecher Ja / Ja Java MIDP 2.0 Messaging E-Mail Browser Opera v8 Media Audio: AAC, AMR, MP2, MP3, RA (Real Audio), WAV, WMA Video: 3GP, AVI, H.263, MPEG-1, MPEG-4, RV (Real Video) Laufzeit 3 Std., Standby 168 Std. Dimensionen 79x141x19 mm (HxBxT) Gewicht 230 g Extras Internet-Radio, PDF-Viewer, Kalender, u.v.m. Tabelle 7: Nokia 770 technische Daten © 2007, Bernd Müller ANHANG A 83 HP iPAQ hx4700 Plattform Microsoft Windows Mobile 2003 Second Edition CPU 624 Mhz Intel XScale PXA270 Prozessor Display 480x640 Pixel mit 65.536 Farben Speicher 64MB RAM, 128MB ROM, extern bis 1GB Bedienung Touchscreen Kartensteckplätze SD-Card, Compaq Flash Konnektivität Infrarot, Bluetooth, USB 1.1, WLAN Mikrofon / Lautsprecher Ja / Ja Java - Messaging E-Mail Browser Internet Explorer Media unterstützt alle gängigen Audio- und Videoformate (Windows Media Player 9 Series) Laufzeit k.A. Dimensionen 129x77x15 mm Gewicht 187 g Extras Kalender, Kontakte, ActiveSync, VPN-Client, u.v.m. Tabelle 8: HP iPAQ hx4700 technische Daten © 2007, Bernd Müller ANHANG A 84 Screenshots JQoS starting Main View About View Call View © 2007, Bernd Müller ANHANG A Configuration View (registering) 85 Configuration View (registration failed) Configuration View (unregistering) Call View (after registration) © 2007, Bernd Müller ANHANG A 86 Quellcode JQoS.java (die wichtigesten Methodenaufrufe) /***** MAIN *****/ public static void main(String[] args) { System.out.println("starting JQoS VoIP Client ..."); JQoS frame = new JQoS(); frame.setVisible(true); } /***** This method initializes jTabbedPane *****/ private JTabbedPane getJTabbedPane() { if (jTabbedPane == null) { jTabbedPane = new JTabbedPane(); jTabbedPane.setTabPlacement(JTabbedPane.TOP); jTabbedPane.setPreferredSize(new Dimension(480, 533)); jTabbedPane.setMaximumSize(new Dimension(480, 533)); jTabbedPane.setBackground(Color.lightGray); jTabbedPane.setMinimumSize(new Dimension(480, 533)); jTabbedPane.setAutoscrolls(false); jTabbedPane.setLocation(new Point(0, 10)); jTabbedPane.setSize(new Dimension(480, 533)); jTabbedPane.addTab("Main",null, getJPanel_Main(), null); jTabbedPane.addTab("Call", null, getJPanel_Call(), null); jTabbedPane.addTab("Configuration", null, getJPanel_Configuration(), null); jTabbedPane.addTab("Contacts", null, getJPanel_Contacts(), null); } return jTabbedPane; } /***** This method initializes jBtn_Call_1 *****/ private JButton getJBtn_Call_1() { if (jBtn_Call_1 == null) { jBtn_Call_1 = new JButton(); jBtn_Call_1.setBounds(new Rectangle(15, 255, 61, 46)); jBtn_Call_1.setFont(new Font("Dialog", Font.BOLD, 12)); jBtn_Call_1.setBorder(BorderFactory.createEtchedBorder (EtchedBorder.RAISED)); jBtn_Call_1.setText("1"); jBtn_Call_1.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent e) { jTextArea_Call_to.append("1"); } }); } return jBtn_Call_1; } ... © 2007, Bernd Müller ANHANG A 87 /***** jBtn_register pressed *****/ SipStack.init(null); SipStack.ua_info = "JQoS v0.10 based on MjSIP v1.6"; // new UserAgentProfile UserAgentProfile user_profile = new UserAgentProfile(null); // UA configuration if (jTxtField_Username.getText() != "") user_profile.username = jTxtField_Username.getText(); if (jPasswordField.getText() != "") user_profile.passwd = jPasswordField.getText(); if (jTxtField_Realm.getText() != "") user_profile.realm = jTxtField_Realm.getText(); if (jCheckBox_do_register.isSelected()) user_profile.do_register = true; if (jCheckBox_do_unregister.isSelected()) user_profile.do_unregister = true; if (jCheckBox_do_unregister_all.isSelected()) user_profile.do_unregister_all = true; if (Long.parseLong(jTxtField_keepalive_time.getText().trim()) >= 0) user_profile.keepalive_time = Long.parseLong(jTxtField_keepalive_time.getText().trim()); if (jCheckBox_audio_support.isSelected()) user_profile.audio = true; if (jCheckBox_receive_only.isSelected()) user_profile.recv_only = true; if (jCheckBox_send_only.isSelected()) user_profile.send_only = true; user_profile.from_url = ("<sip:").concat(jTxtField_Username.getText()).concat("@"). concat(jTxtField_Realm.getText()).concat(">"); user_profile.contacts_file = "contacts.lst"; //Audio-Codec String in SDP user_profile.audio_codec = "PCMU"; //Codec RTP-Parameter user_profile.audio_avp = 0; int port; if(Integer.parseInt(jTxtField_Port.getText().trim()) >= 0) port = Integer.parseInt(jTxtField_Port.getText().trim()); else port = SipStack.default_port; //new SipProvider SipProvider sip_provider = new SipProvider(SipProvider.AUTO_CONFIGURATION, port); jBtn_register.setEnabled(false); if(!jBtn_register.isEnabled()) jBtn_register.setToolTipText("restart JQoS to register again"); apply(sip_provider, user_profile); /***** new UserAgent & RegisterAgent *****/ public void apply(SipProvider sip_provider, UserAgentProfile user_profile) { this.user_profile = user_profile; ua = new UserAgent(sip_provider, user_profile,this); ua.listen(); ra = new RegisterAgent(sip_provider, user_profile.from_url, user_profile.contact_url, user_profile.username, user_profile.realm, user_profile.passwd, this); run(); } © 2007, Bernd Müller ANHANG A 88 /***** Starts the UA *****/ void run() { // set the re-invite if (user_profile.re_invite_time > 0) { ua.reInvite(user_profile.contact_url, user_profile.re_invite_time); } // set the transfer (REFER) if (user_profile.transfer_to != null && user_profile.transfer_time > 0) { ua.callTransfer(user_profile.transfer_to, user_profile.transfer_time); } // only signaling if (!user_profile.audio && !user_profile.video) { ua.printLog("ONLY SIGNALING, NO MEDIA"); jTextArea_SIP_Messages.append("\nONLY SIGNALING, NO MEDIA"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); } // unregisters ALL contact URLs if (user_profile.do_unregister_all) { ua.printLog("UNREGISTER ALL contact URLs"); jTextArea_SIP_Messages.append("\nUNREGISTER ALL contact URLs"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); unregisterall(); } // unregisters the contact URL if (user_profile.do_unregister) { ua.printLog("UNREGISTER the contact URL"); jTextArea_SIP_Messages.append("\nUNREGISTER the contact URL"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); unregister(); } // registers the contact URL with the registrar server if (user_profile.do_register) { ua.printLog("REGISTRATION"); jTextArea_SIP_Messages.append("\nREGISTRATION"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); loopRegister(user_profile.expires, user_profile.expires/2, user_profile.keepalive_time); } // make a call with the remote URL if (user_profile.call_to!=null) { ua.printLog("UAC: CALLING " + user_profile.call_to); ua.call(user_profile.call_to); } } /***** Register with the registrar server *****/ public void register(int expire_time) { if (ra.isRegistering()) ra.halt(); ra.register(expire_time); } © 2007, Bernd Müller ANHANG A 89 /***** Periodically registers the contact address with the registrar server *****/ public void loopRegister(int expire_time, int renew_time, long keepalive_time) { if (ra.isRegistering()) ra.halt(); ra.loopRegister(expire_time,renew_time,keepalive_time); } /***** Unregister with the registrar server *****/ public void unregister() { if (ra.isRegistering()) ra.halt(); ra.unregister(); } /***** Unregister all contacts with the registrar server *****/ public void unregisterall() { if (ra.isRegistering()) ra.halt(); ra.unregisterall(); } /***** When a new call is incoming *****/ public void onUaCallIncoming(UserAgent ua, NameAddress callee, NameAddress caller) { if (ua.user_profile.redirect_to!=null) // redirect the call { jTextArea_SIP_Messages.append("\nCALL redirected to " + ua.user_profile.redirect_to); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); ua.redirect(ua.user_profile.redirect_to); } else if (ua.user_profile.accept_time>=0) // automatically accept the call { jTextArea_SIP_Messages.append("\nON CALL"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); jTextArea_Call_to.setText(caller.toString()); //ua.accept(); ua.automaticAccept(ua.user_profile.accept_time); } else { this.setAlwaysOnTop(true); // set application on top jTabbedPane.setSelectedComponent(jPanel_Call); // select CALL_tap when call is incomming Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nINCOMING CALL: " + caller.toString()); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); this.setAlwaysOnTop(false); // disable application on top } } © 2007, Bernd Müller ANHANG A 90 /***** When an ougoing call is remotly ringing *****/ public void onUaCallRinging(UserAgent ua) { jTextArea_SIP_Messages.append("\nRINGING"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); } /***** When an ougoing call has been accepted *****/ public void onUaCallAccepted(UserAgent ua) { Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nON CALL"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); } /***** When an incoming call has been cancelled *****/ public void onUaCallCancelled(UserAgent ua) { Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nCANCELLED"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); ua.listen(); } /***** When a call has been trasferred *****/ public void onUaCallTrasferred(UserAgent ua) { Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nTRASFERRED"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); ua.listen(); } /***** When an ougoing call has been refused or timeout *****/ public void onUaCallFailed(UserAgent ua) { Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nFAILED"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); ua.listen(); } /***** When a call has been locally or remotely closed *****/ public void onUaCallClosed(UserAgent ua) { Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nBYE"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); ua.listen(); } /***** When a UA has been successfully (un)registered *****/ public void onUaRegistrationSuccess(RegisterAgent ra, NameAddress target, NameAddress contact, String result) { ua.printLog("Registration success: " + result, LogLevel.HIGH); ua.printLog(result, LogLevel.HIGH); is_registered = result; jTextArea_SIP_Messages.append(": " + result); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); this.setTitle(user_profile.from_url); is_registered(); } © 2007, Bernd Müller ANHANG A 91 /***** When a UA failed on (un)registering *****/ public void onUaRegistrationFailure(RegisterAgent ra, NameAddress target, NameAddress contact, String result) { ua.printLog("Registration failure: " + result, LogLevel.HIGH); is_registered = result; jTextArea_SIP_Messages.append("\nRegistration failure: " + result); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); this.setTitle(user_profile.contact_url); is_registered(); } /***** jBtn_Call pressed *****/ try { // make a call if (ua.statusIs(UserAgent.UA_IDLE)) { // if SIP URL is empty if(jTextArea_Call_to.getText().equalsIgnoreCase(zero)) jTextArea_SIP_Messages.setText("Enter valid SIP URL"); String SIP_URL = (String)jTextArea_Call_to.getText(); System.out.println("CALLING " + jTextArea_Call_to.getText()); if (SIP_URL != null && SIP_URL.length()>0) { ua.hangup(); ua.call(SIP_URL); jTextArea_SIP_Messages.append("\nCALLING " + SIP_URL); } } // accept a call else if (ua.statusIs(UserAgent.UA_INCOMING_CALL)) { ua.accept(); jTextArea_SIP_Messages.append("\nON CALL"); } } catch (NullPointerException npe) { jTextArea_Call_to.setText("please register first on configuration tab"); } /**** jBtn_Hangup pressed *****/ try { if (!ua.statusIs(UserAgent.UA_IDLE)) { ua.hangup(); ua.listen(); Toolkit.getDefaultToolkit().beep(); jTextArea_SIP_Messages.append("\nHANGUP"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText(). length()); } } catch (NullPointerException npe) { } © 2007, Bernd Müller ANHANG A 92 /**** jBtn_unregister pressed *****/ try { ua.printLog("UNREGISTER the contact URL"); jTextArea_SIP_Messages.append("\nUNREGISTER the contact URL"); jTextArea_SIP_Messages.setCaretPosition(jTextArea_SIP_Messages.getText().length()); jLbl_is_registering.setText("UNREGISTER"); jLbl_Status_Code.setBackground(new Color(238,238,238)); jLbl_Status_Code.setText("waiting..."); jBtn_unregister.setEnabled(false); if(!jBtn_unregister.isEnabled()) jBtn_unregister.setToolTipText("restart JQoS to register again"); unregister(); } catch (NullPointerException npe) { jLbl_restart_to_register_again.setText("Please register first!"); } © 2007, Bernd Müller