Package eu.pursuit.vopsi

Source Code of eu.pursuit.vopsi.Node$SenderThread

/*-
* Copyright (C) 2011  Mobile Multimedia Laboratory, AUEB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of the
* BSD license.
*
* See LICENSE and COPYING for more details.
*/


package eu.pursuit.vopsi;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import eu.pursuit.vopsi.PPChannelReceiver;
import eu.pursuit.vopsi.PPChannelSender;

import eu.pursuit.client.BlackAdderClient;
import eu.pursuit.client.BlackadderWrapper;
import eu.pursuit.core.ByteIdentifier;
import eu.pursuit.core.Event;
import eu.pursuit.core.Event.EventType;
import eu.pursuit.core.ItemName;
import eu.pursuit.core.ScopeID;
import eu.pursuit.core.Strategy;
import eu.pursuit.vopsi.gui.Logger;

public class Node {

  private byte msg[] = new byte[8];
  private byte sendMsg[] = null;
  private int msgSeqNum = 0;
  private BlockingQueue<VoicePacket> recQueue;
  private BlockingQueue<VoicePacket> dataQueue;
  PPChannelReceiver channelRecv;
  PPChannelSender channelSend;
  private BlackAdderClient client;
  private Event event;
  private ScopeID sId;
  private ByteIdentifier myRid, otherEndId;
  private Vector<ByteIdentifier> participants;

  Strategy strategy = Strategy.DOMAIN_LOCAL;

  String sharedObjPath = null;
  public JavaSoundRecorder recorder;
  public SenderThread senderThread;
  public JavaSoundPlayer player;
  public ReceiverThread receiverThread;

  private enum MsgType {
    DATA, NEWPART, BYE
  }

  public Node() {
    sharedObjPath = Configuration.getInstance().getJniPath();
    BlackadderWrapper.configureObjectFile(sharedObjPath);
    client = BlackAdderClient.getInstance();
    participants = new Vector<ByteIdentifier>();
  }

  public void receiveCall(String callee) throws NoSuchAlgorithmException,
      UnsupportedEncodingException {

    myRid = new ByteIdentifier(Utility.sha1(callee));
    sId = new ScopeID();
    ByteIdentifier b = new ByteIdentifier(Utility.sha1(myRid.getId()));
    sId.addSegment(b);
    ItemName receiveData = new ItemName(sId, myRid);

    Logger.log("waiting for call...");

    client.subscribeItem(receiveData, strategy, null);
    event = client.getNextEvent();

    Logger.log("incoming call...");

    if (event.getType() == EventType.PUBLISHED_DATA) {
      msg = event.getDataCopy();
    }

    otherEndId = new ByteIdentifier(msg);

    msgSeqNum++;

    client.publishRootScope(b, strategy, null);

    ItemName sendData = new ItemName(sId, otherEndId);

    Logger.log("Sending response to caller...");
    client.publishItem(sendData, strategy, null);
    event = client.getNextEvent();

    if (event.getType() == EventType.START_PUBLISH) {

      client.publishData(event.getId(), msg, strategy, null);
      Logger.log("Conversation started...");
    }
    /*
     * The callee responses to the invitation message verifying the pRId
     * derived from the other's party name.
     */

    msgSeqNum++;

    participants.add(otherEndId);

    this.channelSend = new PPChannelSender(sId, otherEndId, client);

    this.channelRecv = new PPChannelReceiver(sId, myRid, client);

    startVoice();
  }

  /*
   * The caller sends the callee an invitation message that contains his RId
   * derived from his name.
   */
  public void makeCall(String caller, String callee)
      throws NoSuchAlgorithmException, UnsupportedEncodingException {

    myRid = new ByteIdentifier(Utility.sha1(caller));
    otherEndId = new ByteIdentifier(Utility.sha1(callee));
    sId = new ScopeID();
    ByteIdentifier b = new ByteIdentifier(Utility.sha1(otherEndId.getId()));
    sId.addSegment(b);
    ItemName sendData = new ItemName(sId, otherEndId);

    client.publishRootScope(b, strategy, null);
    Logger.log("Calling " + callee);

    client.publishItem(sendData, strategy, null);
    event = client.getNextEvent();

    System.arraycopy(myRid.getId(), 0, msg, 0, myRid.length());

    if (event.getType() == EventType.START_PUBLISH) {

      client.publishData(event.getId(), msg, strategy, null);
    }

    msgSeqNum++;

    ItemName receiveData = new ItemName(sId, myRid);

    client.subscribeItem(receiveData, strategy, null);
    event = client.getNextEvent();

    if (event.getType() == EventType.PUBLISHED_DATA) {
      msg = event.getDataCopy();
      System.out.println("Type :" + event.getType());
    }

    if (Arrays.equals(msg, myRid.getId())) {

      participants.add(otherEndId);
      Logger.log("Answer received...");
      Logger.log("Session established...");

    } else {
      Logger.log("Mismatched RId received as response...");
      Logger.log("Program will exit now.");
      System.exit(0);
    }

    this.channelSend = new PPChannelSender(sId, otherEndId, client);

    this.channelRecv = new PPChannelReceiver(sId, myRid, client);

    startVoice();
  }

  public void addParticipant(String participantName)
      throws NoSuchAlgorithmException, UnsupportedEncodingException {

    ByteIdentifier participantId = new ByteIdentifier(
        Utility.sha1(participantName));
    participants.add(participantId);

    client.publishRootScope(sId.get(0), strategy, null);

    ItemName updateData;

    for (int i = 0; i < participants.size(); i++) {

      updateData = new ItemName(sId, participants.get(i));

      System.out.println("Sending new participant to all...");
      Logger.log("Adding " + participantName + " to the conversation...");
      client.publishItem(updateData, strategy, null);
      event = client.getNextEvent();
      System.out.println("got a notification");

      prepareHeader(MsgType.NEWPART);

      System.arraycopy(participantId, 0, sendMsg, 1,
          participantId.length());

      if (event.getType() == EventType.START_PUBLISH) {

        client.publishData(event.getId(), sendMsg, strategy, null);
        System.out.println("New participant sent...");
      }
    }
  }

  public void leaveConversation() {

    client.publishRootScope(sId.get(0), strategy, null);

    ItemName leaveData;

    for (int i = 0; i < participants.size(); i++) {

      leaveData = new ItemName(sId, participants.get(i));

      System.out.println("Sending bye msg to all...");
      Logger.log("Sending Bye message to all...");
      client.publishItem(leaveData, strategy, null);
      event = client.getNextEvent();
      System.out.println("got a notification");

      prepareHeader(MsgType.BYE);

      System.arraycopy(myRid, 0, sendMsg, 5, myRid.length());

      if (event.getType() == EventType.START_PUBLISH) {

        client.publishData(event.getId(), sendMsg, strategy, null);
        System.out.println("New participant sent...");
      }
    }
  }

  public void startVoice() {
    this.dataQueue = new LinkedBlockingQueue<VoicePacket>();
    this.recQueue = new LinkedBlockingQueue<VoicePacket>();

    recorder = new JavaSoundRecorder(recQueue);
    Thread recorderThread = new Thread(recorder, "recorder");

    senderThread = new SenderThread(this.channelSend, this.recQueue);
    senderThread.start();
    recorderThread.start();

    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    player = new JavaSoundPlayer(this.dataQueue);
    Thread playerThread = new Thread(player, "player");

    receiverThread = new ReceiverThread(this.channelRecv, this.dataQueue);
    receiverThread.start();
    playerThread.start();

  }

  public class SenderThread extends Thread {

    private BlockingQueue<VoicePacket> queue;
    private PPChannelSender channel;
    final VoicePacket STOP = new VoicePacket(null);

    public SenderThread(PPChannelSender channelSend,
        BlockingQueue<VoicePacket> recQueue) {
      this.channel = channelSend;
      this.queue = recQueue;
    }

    @Override
    public void run() {

      while (true) {

        try {
          VoicePacket p = this.queue.take();
         
          if(p == STOP){
            break;
          }
         
          this.channel.send(p.getBuffer());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    public void finish() {
      this.queue.clear();
      this.queue.add(STOP);
    }

  }

  public class ReceiverThread extends Thread {

    private PPChannelReceiver channel;
    private BlockingQueue<VoicePacket> queue;
    private boolean finished = false;

    public ReceiverThread(PPChannelReceiver channelRecv,
        BlockingQueue<VoicePacket> dataQueue) {
      this.queue = dataQueue;
      this.channel = channelRecv;
    }

    @Override
    public void run() {

      while (!finished) {

        try {
          byte[] msg = channel.receive();
          if (msg.length > 0) {
            this.queue.put(new VoicePacket(msg));
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
   
    public void finish() {

      finished = true;
    }

  }

  public void prepareHeader(MsgType type) {

    /*
     * First bit: Stream or document (1 for stream) Sec bit: Cacheable or
     * not (0 for no) Third and fourth bit for three types of messages
     * during conversation
     */

    if (type.equals(MsgType.DATA)) {

      sendMsg[0] = 1;
      sendMsg[1] = 0;
      sendMsg[2] = 0;
    }

    else if (type.equals(MsgType.NEWPART)) {

      sendMsg[0] = 1;
      sendMsg[1] = 0;
      sendMsg[2] = 1;
      sendMsg[3] = 0;
    }

    // Bye msg
    else {
      sendMsg[0] = 1;
      sendMsg[1] = 0;
      sendMsg[2] = 1;
      sendMsg[3] = 1;
    }
  }
}
TOP

Related Classes of eu.pursuit.vopsi.Node$SenderThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.