Source

haXeTGConnector / thinkgear / JSONConnector.hx

Full commit
package thinkgear;

#if neko
	import neko.net.Socket;
	import neko.net.Host;
	import neko.Sys;
	import neko.Lib;
	import neko.Utf8;
#elseif cpp
	import cpp.net.Socket;
	import cpp.net.Host;
	import cpp.Sys;
	import cpp.Lib;
	import cpp.Utf8;
#end

import hxjson2.JSON;

typedef ESenses = {
	attention : Int,
	meditation : Int,
}

typedef EEGPowers = {
	delta : Int,
	theta : Int,
	lowAlpha : Int,
	highAlpha : Int,
	lowBeta : Int,
	highBeta : Int,
	lowGamma : Int,
	highGamma : Int,
}

typedef EEGData = {
	poorSignalLevel : Int,
	eSense : ESenses,
	eegPower : EEGPowers,
}

class JSONConnector {

	public static var HOST : String = "localhost";		// Thinkgear Connector default Host
	public static var PORT : Int = 13854;				// Thinkgear Connector default Port
	public static var ENABLE_RAW_INPUT : Bool = false;	// Enable this if you want to get RAW DATA as well

	static var credentials = {};
	static var configuration = {};
	
	public static var eeg : EEGData;
	public static var rawEeg : Int;
	public static var blinkStrength : Int;
	public static var socket_error : Dynamic;
	public static var connected : Bool;

	static var sock : Socket;

	// Prior to JSONConnector.open(), 
	// change the documented values above if you need to ( HOST, PORT, ENABLE_RAW_INPUT ).
	public static function open( appName : String) {

		blinkStrength = 0;
		rawEeg = 0;
		eeg = null;

		sock = new Socket();

		configuration = { enableRawOutput : ENABLE_RAW_INPUT, format : "Json" };
		credentials = { appName: appName, appKey: haxe.SHA1.encode( appName ) };
		return connect();
	}

	public static function connect() {
		try {
//			sock.setBlocking( false );
			sock.connect( new Host( HOST ), PORT );
			sock.write( JSON.encode(configuration) );
			sock.write( JSON.encode(credentials) );
		}catch( e : Dynamic ) {
			sock.close();
			socket_error = e;
			Lib.println(socket_error );
			return false;
		}		

		connected = true;
		return true;
	}

	public static function getData() : Dynamic {
		var d : String = null;
		var bufsize= 8192;
		var bytes = haxe.io.Bytes.alloc( bufsize );

		while( true ) {
			
			var l : Int = 0;
			try {
				l = sock.input.readBytes( bytes, 0, bufsize );
			} catch( e : Dynamic ) {
				return null;
			}

			// ignore first 4 bytes packets
			if( l <= 42 ) continue;

			// There should be a better crossplatform test to 
			// see if bs is a valid string
			// if you have any idea, contact me.
			var bs : String = "";
			try { 
				bs = Utf8.decode( bytes.toString() );
			} catch( e : Dynamic ) {
				bs = null;
			}
			if( bs == null ) continue;

			d = bytes.toString();
			break;
		}

		var packets : Array<String> = d.split("\r");
		var data : Dynamic = null;
		try {
			data = JSON.parse( packets[0] ); // ignore \r delimiter which ends every message
		} catch( e : Dynamic ) {
			data = null;
		}

		if( Reflect.hasField(data, "eegPower") ) {
			eeg = cast data;
		} else if( Reflect.hasField(data, "rawEeg") ) {
			rawEeg = data.rawEeg;
		} else if( Reflect.hasField(data, "blinkStrength") ) {
			blinkStrength = data.blinkStrength;
		}

		return data;
	}

	// Don't forget to call JSONConnector.close() 
	// to close the socket before you exit your app.
	public static function close() {
		sock.close();
	}
}