![]() |
[Studienarbeiten: Kommunikation zwischen PDAs] | ![]() |
Ein Konzept der Kommunikationsverwaltung unter EPOC32 ist das Einsetzen
der RSocket Klasse. Wie in der folgenden Grafik zu sehen ist, wird durch die Socket-API
nur der Zugriff auf LM-IAS, sowie LM-MUX bzw IrTinyTP erlaubt. Ein Zugriff auf IrLAP ist
also nicht vorgesehen. Eine andere Möglichkeit ist der direkte Zugriff auf die serielle
Schnittstelle über die Comms Server API ohne Nutzung irgendwelcher IrDA-Schichten.
Ebenfalls über diese API ist der Zugriff auf IrDA IrCOMM möglich. Die folgende Grafik
veranschaulicht diesen Umstand:
Bei der Anpassung der IrDA-Protokolle an ein Socket-System müssen natürlich
Kompromisse geschlossen werden. Da die Protokolle an das ISO-OSI Modell angelehnt sind,
ist eine vorgesehene request.indication Meldung grundsätzlich nur über Interrupts oder
kompliziertere Programmstrukturen möglich. Wie die meisten anderen Betriebssysteme auch
benutzt der Psion deshalb unter EPOC32 das explizite Warten auf eine Verbindung an
einem besimmten LSAP.
LM-IAS kann über weitere Hilfsklassen genutzt werden, die im Folgenden vorgestellt
werden. In der EPOC32 IrDA API gibt es keine Ableitung für die CSocket Klasse (wie z.B.
eine CIrdaSocket Klasse), dafür wurde jedoch für erweiterte Funktionalität eine
Ableitung der TSockAddr Klasse (die zur Bestimmung einer Adresse dient), die Klasse
TIrdaSockAddr, implementiert.
Um eine Verbindung auf Ebene von IrTinyTP aufnehmen zu können, sind diese speziell für die IrDA-Schichten vorgesehenen Klassen aber nicht notwendig. Ein großer Vorteil dieses Konzepts ist die Möglichkeit einer 'relativen' Programmunabhängigkeit von dem benutzten Protokoll - durch geschicktes Implementieren und ein Verzicht auf bestimmte Vorteile von IrDA (wie LM-IAS) könnte ein Programm sowohl unter IrTinyTP als auch unter TCP/IP funktionieren.
Es folgt nun eine Beschreibung der Klassen, die für die IrDA-Kommunikation verwendet werden, sowie einige kleine Besipiele zu bestimmten Programmaufgaben.
Die wichtigste Klasse für die Kommunikation ist die RSocket Klasse. Über sie
kann eine Verbundung zu einem anderen Gerät aufgebaut werden, sie kann Verbindungen
anderer Geräte annehmen und über sie läuft das Austauschen der Daten. Um überhaupt
eine RSocket Instanz erzeugen zu können, benötigt man unter EPOC32 eine
Verbindung zum Socket Server, als Klasse implementiert als RSocketServ. Über
diesen findet man auch die angebotenen Protokolle.
Zum Entdecken anderer Maschinen, das vor allem bei IrDA eine wichtige Rolle spielt, ist
schließlich die RHostResolver Klasse zuständig.
Für LM-IAS werden in EPOC32 einige Hilfsklassen angeboten: TIASQuery, TIASResponse
und TIASDatabaseEntry. Allgemein ist die Klasse RNetDatabase, die in diesem
Fall ebenso benötigt wird.
Connect() | Verbindet zum Socketserver |
FindProtocol() | Sucht nach einem bestimmten Protokoll und liefert Informationen |
NumProtocols() | liefert die Anzahl an verfügbaren Protokollen |
GetProtocolInfo() | liefert wie FindProtocol() Informationen, jedoch über einen Index. |
Im Fall von IrDA ist der Verlauf also folgender: Über Connect() wird die Verbindung
geöffnet, dann über FindProtocol() nach z.B. 'IrTinyTP' gesucht. Ist dies vorhanden,
kann dann über die erhaltenen Informationen dieses Protokolls ein Open() eines RSocket
durchgeführt werden.
Open() | Ein Socket muß zu Beginn geöffnet werden. Hierzu ist ein Socketserver notwendig |
Bind() | Weist dem Socket eine Adresse zu. Im Falle von IrDA ist der Port der Adresse der LSAP-SEL |
SetLocalPort() | Setzt den lokalen Port. Im Falle von IrDA identisch mit der SLSAP-SEL |
Connect() | Zu einer bekannten Adresse wird hiermit eine Verbindung geöffnet |
Listen() | Ein Socket kann über Listen auf eine Verbindung warten |
Accept() | Wird benötigt, um nach einem Listen die neue Verbindung einem Socket zuzuweisen |
Send() | Mit einem verbundenen Socket Daten senden |
Receive() | Mit einem verbundenen Socket Daten empfangen |
Shutdown() | Eine Verbindung schließen |
Close() | Ein Socket muß nach Beendigung seiner Aufgabe geschlossen werden. |
Ioctl() | Führt je nach Protokoll spezielle Befehle aus |
SetOpt()/GetOpt() | Liest oder setzt Verbindungsoptionen (wie Baudrate etc) |
Diese Klasse zur Speicherung einer Adresse ist wichtig für RSocket::Connect() und RSocket::Bind()
SetPort() | Setzt den Port der Adresse. Im Falle von IrDA den LSAP-SEL |
Diese Klasse ist eine Ableitung der TSockAddr und speziell für die Verwendung der IrDA-Protokolle gedacht. Bei der Erzeugung kann eine TSockAddr angegeben werden, die dann zur Initialisierung benutzt wird.
GetRemoteDevAddr() / SetRemoteDevAddr() | Hiermit erhält man (oder setzt) die Adresse des Zielgerätes (als 4 Byte Wert) |
GetFirstServiceHintByte() / SetFirstServiceHintByte | Hiermit erhält man (oder setzt) das erste Hint Byte |
GetSecondServiceHintByte() / SetSecondServiceHintByte() | Hiermit erhält man (oder setzt) das zweite Hint Byte |
GetIrlapVersion() | Ergibt die IrLap Version |
GetSniffStatus() / SetSniffStatus() | Hiermit erhält man (oder setzt) den Sniff Status |
Mit dieser Klasse können andere Geräte entdeckt werden.
Open() | Öffnet einen RHostResolver. Auch hierzu ist ein Socketserver notwendig |
GetByName() | Hiermit erhält man die Adresse einer bestimmten Maschine in Form einer TSockAddr. Wird keine angegeben, so findet GetByName() alle Geräte (zumindest im Falle von des IrDA-Protokolls) |
Close() | Schließt den RHostResolver. |
RNetDatabase ist die Basisklasse für Abfrage und Eintrag in die Datenbasis.
Open() | Die RNetDatabase muß auch unter Angabe eines Protokolls geöffnet werden. |
Add() | Fügt unter Angabe eines TIASDatabaseEntry einen Eintrag in der Datenbank hinzu |
Query() | Frägt einen Eintrag einer anderen Datenbank ab, benötigt einen TIASQuery und liefert einen TIASResponse |
Close() | Nach Beendigung der Aktionen muß die Verbindung geschlossen werden |
TIASDatabaseEntry wird für Einträge in die Datenbasis bei RNetDatabase:Add() benötigt.
SetClassName() | Setzt den Klassennamen |
SetAttributeName() | Setzt den Attributnamen |
SetToInteger() | Setzt den Typ auf eine Zahl und legt den Wert fest |
SetToCharString() | Setzt den Typ auf einen Text und legt den Wert fest |
SetToOctetSeq() | Setzt den Typ auf einen Bytestrom und legt den Wert fest |
Hiermit wird eine Abfrage für RNetDatabase::Query() vorbereitet
Set() | Hierbei wird unter Angabe von Adresse, Klassenname und Attributname eine Abfrage vorbereitet |
Liefert bei RNetDatabase::Query() ein Ergebnis
Type() | liefert den Typ des Ergebnis |
GetInteger() | liefert einen Intergerwert |
GetOctetSeq() | liefert einen Bytestrom |
GetCharString8() | liefert einen Text |
Anmerkung zu 4 und 5: Dies kann auch über RSocket::SetLocalPort() abgekürzt werden.
Anmerkung zu 6: Der Port, der in diesem Falle den LSAP-SEL spielt, muß einer anderen
Maschine über das IAS bekanntgemacht werden, damit diese den korrekten LSAP-SEL für den
Aufbau zu unserem Server benutzen kann. Natürlich könnte der LSAP-SEL auch einen festen
Wert haben - dies würde aber das gleichzeitige problemlose Ablaufen von zwei
IrDA-Programmen verhindern, falls diese den selben LSAP-SEL nutzen würden.
Anmerkung zu 7: Der lokale Port muß nicht festgesetzt werden. Über einen
Autobind-Mechanismus wird der nächste verfügbare Port automatisch ausgewählt. Somit
darf dieser Punkt entfallen.
Anmerkung zu 3 und 4: Im Falle von IrDA kann eine gefundene TSockAddr in eine
TIrdaSockAddr gewandelt werden, um somit weitere Informationen abzuleiten.
Für einen Datenbankeintrag sind folgende Schritte notwendig:
Für eine Abfrage gilt
Erfreulicherweise scheint EPOC32 einen Großteil der IrDA-Spezifikation korrekt eingehalten zu haben. Einige vorgesehene Möglichkeiten des IrLMP-Protokolls fehlen:
Beim Testen der im Rahmen dieser Studienarbeit geschriebenen Programme gelang kein
Connect-Versuch des Window CE-Geräts an den Psion. Die andere Richtung funktionierte
problemlos. Woran und auf welcher Seite dieser Fehler liegt, konnte mangels weiterer
Geräte nicht festgestellt werden. Das Programm des Psion stürzte bei manchen
Connectversuchen komplett ab, wenn das Zielgerät während des Connects entfernt wurde und
ließ sich nicht mehr beenden. Dieser Fehler trat allerdings nur äußerst selten auf.
![]() |
[Studienarbeiten: Kommunikation zwischen PDAs] | ![]() |