/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cnam.nsy208.sudoku.bluetooth;
import cnam.nsy208.sudoku.main.Sudoku;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
/**
*
* @author Martial
*/
public class SudokuClient extends Thread implements BtInterface {
private BtClient _client ;
private Sudoku _controler ;
private char[] _gridChar ;
private String _name ;
private int _number ;
private StreamConnectionNotifier _notifierServ ;
private StreamConnection _connServ ;
private LocalDevice _localDeviceServ ;
private OutputStream _outputServ ;
private InputStream _inputServ = null;
private boolean _isInitServ ;
private boolean _stopServ ;
private UUID _client_UUID ;
private String _serverUrl ;
/**
* Inialise les variables
* @param c : controlleur
* @param name : nom du client
*/
public SudokuClient( Sudoku c , String name ) {
_controler = c ;
_name = name ;
_number = 0 ;
_client = new BtClient( Sudoku.RFCOMM_UUID , this ) ;
_isInitServ = false;
}
/**
* Affecte l'uid au client
* @param uid : uid
*/
public void setUUID( int uid ) {
_client_UUID = new UUID( uid ) ;
_serverUrl = "btspp://localhost:" + _client_UUID + ";name=SudokuClient;authorize=true";
}
/**
* Fonction d'initialisation des client Bt
*/
public void init() {
String msg ;
String id = "A" ;
String data ;
try {
_client.open() ;
// 1 - INSCRIPTION
System.out.println( "1 - INSCRIPTION" );
sendLogin() ;
// 2 - Reception nom de joueur
System.out.println( "2 - Reception nom de joueur" );
msg = _client.readData() ;
id = getId( msg ) ;
data = getData( msg ) ;
if( id.compareTo( "A" ) != 0 ) {
if( id.compareTo( "J" ) == 0 ) {
while( data.substring( 0 , 1).compareTo( "0" ) == 0 ) {
data = data.substring( 1 , data.length() ) ;
}
_number = Integer.parseInt( data ) ;
setUUID( _number ) ;
_controler.setTextSudokuView( "Joueur" + data , "Attente de la grille!" ) ;
}
// 3 - Demande de la grille
System.out.println( "3 - Demande de la grille" );
askGrid() ;
// 4 - Reception de la grille
System.out.println( "4 - Reception de la grille" );
msg = _client.readData();
id = getId( msg ) ;
data = getData( msg ) ;
if( id.compareTo( "G" ) == 0 ) {
_gridChar = data.toCharArray();
_controler.setTextSudokuView( "Joueur" , "Attente du top départ!" ) ;
}
} else {
_controler.setTextSudokuView( "Joueur" , "Inscription refusée!" ) ;
}
_client.close();
} catch (Exception ex) {
System.out.println(ex);
}
if( id.compareTo( "A" ) != 0 ) {
// Démarrage du serveur
start() ;
}
}
/**
* Retourne l'Identifiant de trame
* @param msg : Message à identifier
* @return Identifiant
*/
public String getId( String msg ) {
return msg.substring( 0 , 1 );
}
/**
* Retourne les données utiles du message
* @param msg : message à parser
* @return Données utilies
*/
public String getData( String msg ) {
String data ;
if( msg.length() > 1 ) {
data = new String( msg.substring( 1 , msg.length() ) ) ;
} else {
data = new String( "");
}
return data ;
}
/**
* Envoi d'un message de demande d'inscription au serveur
*/
private void sendLogin() {
String msg = new String( "I" + _name ) ;
_client.writeData( msg );
}
/**
* Envoi d'un message de demande de grille au serveur
*/
private void askGrid() {
String msg = new String( "D" ) ;
_client.writeData( msg );
}
/**
* Envoi d'un message de solution trouvée au serveur
* @param score : score du joueur
*/
public void sendNotifEndGame( int score ) {
String msg;
String strNumber ;
if(_client.getActive() != 0){
strNumber = new String( Integer.toString( _number ) );
while( strNumber.length() < 3 ) {
strNumber = "0" + strNumber ;
}
_client.open() ;
msg = new String("R" + strNumber + score );
_client.writeData( msg ) ;
_client.setActive(0);
_client.close() ;
}
}
/**
* Arrete le serveur
*/
public void stopServer() {
_stopServ = true ;
}
/**
* Démarre le serveur client
*/
public void run() {
String msg ;
String id ;
String data ;
_stopServ = false ;
if (!_isInitServ) {
// Initialization is done in the thread to avoid dead lock 'isInit' ensures it is done once only
try {
_connServ = null;
_localDeviceServ = LocalDevice.getLocalDevice();
_localDeviceServ.setDiscoverable(DiscoveryAgent.GIAC);
_notifierServ = (StreamConnectionNotifier) Connector.open( _serverUrl );
} catch (BluetoothStateException e) {
System.err.println("BluetoothStateException: " + e.getMessage());
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
}
_isInitServ = true;
System.out.println("Starting Echo Server");
}
try {
System.out.println("\n\nServer Running...");
while( !_stopServ ) {
// Pauses thread until Transmission occurs
_connServ = _notifierServ.acceptAndOpen();
_outputServ = _connServ.openOutputStream();
_inputServ = _connServ.openInputStream();
// Read Data Transmission
msg = readDataServ() ;
System.out.println("Received Message from Client: " + msg );
id = getId( msg ) ;
data = getData( msg ) ;
System.out.println( "id : " + id + " data : " + data ) ;
// Attente du top départ
if( id.compareTo( "T" ) == 0 ) {
_controler.setNbPlayers( Integer.parseInt( data ) );
_controler.setTextSudokuView( "Joueur" , "Top départ" ) ;
_controler.setSudokuViewIsReady( true ) ;
// Affectation de la grille
_controler.setGrid( _gridChar ) ;
//Départ du timer
_controler.setStartAcardeTime(System.currentTimeMillis());
}
if( id.compareTo( "F" ) == 0 ) {
_controler.setTypeGameMode(Sudoku.MODE_FIN);
_controler.setTextSudokuView( "Joueur" , "Fin de partie" );
_controler.setSudokuViewIsReady(false) ;
msg = readDataServ() ;
id = getId( msg ) ;
data = getData( msg ) ;
if( id.compareTo( "S" ) == 0 ) {
Thread.sleep(2000);
_controler.displayRankingSudokuView(data);
}
this._stopServ = true;
}
_outputServ.close();
_inputServ.close();
}
} catch (Exception ex) {
System.err.println("Bluetooth Server Running Error: " + ex);
}
}
/**
* Lit des données sur la connexion BT serveur
* @return Les données lues
*/
public String readDataServ() {
byte[] data = null;
try {
// Probably want to throw an exception if length is not greater then 0
int length = _inputServ.read();
data = new byte[length];
length = 0;
// Assemble data
while (length != data.length) {
int ch = _inputServ.read(data, length, data.length - length);
if (ch == -1) {
throw new IOException("Can't read data");
}
length += ch;
}
} catch (IOException e) {
System.err.println(e);
}
return new String(data);
}
/**
* Ecrit des données sur la connexion BT serveur
* @param msg : Données à écrire
*/
public void writeDataServ( String msg ) {
try {
_outputServ.write(msg.length()); // length is 1 byte
_outputServ.write(msg.getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
}
}