@Override public synchronized OtrSession openSession(Send<Bytestring> send) throws InterruptedException, IOException {
  if (send == null)   throw new NullPointerException();
  Chan<Boolean> chan=new BasicChan<>(1);
  OtrSendAlice alice=new OtrSendAlice(send,chan);
  Session<Address,Bytestring> session=peer.openSession(alice);
  if (session == null)   return null;
  final SessionID sessionID=new SessionID("","","");
  OtrPolicy policy=new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ALLOW_V3 | OtrPolicy.ERROR_START_AKE);
  SessionImpl sessionImpl=new SessionImpl(sessionID,new SendOtrEngineHost(policy,session));
  alice.sessionImpl=sessionImpl;
  String query="?OTRv23?";
  session.send(new Bytestring(query.getBytes()));
  Boolean result=chan.receive();
  if (result) {
  }
 else {
    chan.close();
    session.close();
    return null;
  }
  return new OtrSession(session,sessionImpl);
}

@ Override public synchronized OtrSession openSession ( Send < Bytestring > send ) throws InterruptedException , IOException { if ( send == null ) throw new NullPointerException ( ) ; Chan < Boolean > chan = new BasicChan < > ( 1 ) ; OtrSendAlice alice = new OtrSendAlice ( send , chan ) ; Session < Address , Bytestring > session = peer . openSession ( alice ) ; if ( session == null ) return null ; final SessionID sessionID = new SessionID ( "" , "" , "" ) ; OtrPolicy policy = new OtrPolicyImpl ( OtrPolicy . ALLOW_V2 | OtrPolicy . ALLOW_V3 | OtrPolicy . ERROR_START_AKE ) ; SessionImpl sessionImpl = new SessionImpl ( sessionID , new SendOtrEngineHost ( policy , session ) ) ; alice . sessionImpl = sessionImpl ; String query = "?OTRv23?" ; session . send ( new Bytestring ( query . getBytes ( ) ) ) ; Boolean result = chan . receive ( ) ; if ( result ) { } else { chan . close ( ) ; session . close ( ) ; return null ; } return new OtrSession ( session , sessionImpl ) ; }
the opensession ( ) method starts the otr protocol . it creates a basicchan object that is passed into otrsendalice and when the key exchange is complete , this chan " chan " is notified and an otrsession object is returned . we also create a sessionimpl object for handling messages and pass that into both our otrsendalice object and the returned otrsession object . to start the actual protocol , a specific string needs to be crafted . in our implementation , we used " ? otrv23 ? " which means we are initializing otr version 3 , with version 2 as a backup if version 3 is not available . other protocol strings are possible . we then call chan . receive ( ) , and when the key exchange in otrsendalice returns , we check to see if the key exchange was successful or not . if it is , we return a new otrsession object . else , we shut everything down . note : the otrpolicy variable allows otrv2 and otrv3 . this can be changed if the user desires different versions of otr .
