| |
"A Reality for Java Embedded Computing"
Vol. 6, Issue 10, p. 94
Listing 1: jtalkSessionClient.java
public interface jtalkSessionClient
{
/**
* This method is called by the session to deliver a status
message
* to the client.
*/
public void jtalkSessionStatus(String s);
/**
* This method is called by the session to get a character
typed
* by the local user of the session; each such character is
* transmitted by the session to the remote user of the ses
sion.
*/
public int jtalkSessionITyped();
/**
* This method is called by the session to inform the client
of a
* character typed by the remote user of the session.
*/
public void jtalkSessionHeTyped(int b);
/**
* This method is called by the session when it is about to
shut
* down.
*/
public void jtalkSessionEnding();
}
Listing 2: jtalk.java
public class jtalk
extends Frame
implements ActionListener,
KeyListener,
WindowListener,
jtalkSessionClient
Listing 3: jtalkSessionException.java
public class jtalkSessionException
extends RuntimeException
{
/**
* Construct a jtalk session exception without a detail mes
sage.
*/
public jtalkSessionException() {
super();
}
/**
* Construct a jtalk session exception with a detail message.
*/
public jtalkSessionException(String s) {
super(s);
}
}
Listing 4: jtalkSession.java
try {
myInetAddr = java.net.InetAddress.getLocalHost();
if (args[arg].equals("-host")) {
myInetAddr = java.net.InetAddress.getByName(args[arg + 1]);
arg += 2;
nargs -= 2;
}
myHostName = myInetAddr.getHostName();
}
catch (Throwable t) {
t.printStackTrace();
throw new jtalkSessionException("can't determine local host name");
}
client.jtalkSessionStatus("talk@" + myHostName + " starting.");
Listing 5: In the process context
1. <announce invitation to callee's talkd daemon>
2. <leave actual invitation on local talkd daemon>
3. <use setjmp() to establish this as a jump-to point>
4. <set SIGALRM timer for 30 seconds>
5. <call accept() to accept an incoming connection>
6. <cancel SIGALRM timer>
Code snippet from invite.c:
void
invite_remote()
{
...
setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
message("Waiting for your party to respond");
signal(SIGALRM, re_invite);
(void) setjmp(invitebuf);
while ((new_sockt = accept(sockt, 0, 0)) < 0) {
if (errno == EINTR)
continue;
p_error("Unable to connect with your party");
}
In the SIGALRM handler context:
1. <announce the invitation again>
2. <leave the invitation again>
3. <use longjmp to jump to the point 3 in the process context>
Code snippet from invite.c:
void
re_invite(signo)
int signo;
{
message("Ringing your party again");
waddch(my_win.x_win, '\n');
if (current_line < my_win.x_nlines - 1)
current_line++;
/* force a re-announce */
msg.id_num = htonl(remote_id + 1);
announce_invite();
longjmp(invitebuf, 1);
}
Listing 6: jatlkSession.java
void issueInvitation()
{
...
for (;;) {
if (current_idnum >= 0) {
client.jtalkSessionStatus(RINGING);
current_idnum++;
}
client.jtalkSessionStatus(ANNOUNCING);
msg.setMessage((byte) talkdMessage.ANNOUNCE,
current_idnum,
myUserName,
hisUserName,
hisTerminal,
server,
control,
myInetAddr);
controlTransaction(hisInetAddr);
remote_idnum = rs.getIdNum();
if (rs.getAnswer() != talkdResponse.SUCCESS) {
throw new jtalkSessionException("invitation rejected: " +
rs.decodeAnswer());
}
client.jtalkSessionStatus(INVITING);
msg.setMessage((byte) talkdMessage.LEAVE_INVITE,
current_idnum,
myUserName,
hisUserName,
hisTerminal,
server,
control,
myInetAddr);
controlTransaction(myInetAddr);
local_idnum = rs.getIdNum();
client.jtalkSessionStatus(WAITING2);
try {
data = server.accept();
data.setSoTimeout(1 * 1000);
dataInput = data.getInputStream();
dataOutput = data.getOutputStream();
}
catch (InterruptedIOException x) {
current_idnum = remote_idnum;
continue;
}
catch (Throwable t) {
t.printStackTrace();
new jtalkSessionException("can't get connection");
}
finally {
msg.setMessage((byte) talkdMessage.DELETE,
local_idnum,
myUserName,
hisUserName,
hisTerminal,
null,
control,
myInetAddr);
controlTransaction(myInetAddr);
msg.setMessage((byte) talkdMessage.DELETE,
remote_idnum,
myUserName,
hisUserName,
hisTerminal,
null,
control,
myInetAddr);
controlTransaction(hisInetAddr);
}
break;
}
}
|
|