2011-06-27 13:06:26 +00:00
|
|
|
package net.i2p.itoopie.i2pcontrol;
|
|
|
|
|
|
|
|
import java.net.MalformedURLException;
|
|
|
|
import java.net.URL;
|
2011-07-08 09:52:09 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collections;
|
2011-06-27 13:06:26 +00:00
|
|
|
import java.util.HashMap;
|
2011-07-08 09:52:09 +00:00
|
|
|
import java.util.List;
|
2011-06-27 13:06:26 +00:00
|
|
|
import java.util.Map;
|
2011-07-08 09:52:09 +00:00
|
|
|
import java.util.Map.Entry;
|
2011-06-27 13:06:26 +00:00
|
|
|
import java.util.Random;
|
2011-07-08 09:52:09 +00:00
|
|
|
import java.util.Set;
|
2011-06-27 13:06:26 +00:00
|
|
|
|
2011-07-01 08:19:14 +00:00
|
|
|
import net.i2p.itoopie.configuration.ConfigurationManager;
|
2011-06-27 13:06:26 +00:00
|
|
|
|
2011-07-08 09:52:09 +00:00
|
|
|
import org.GNOME.Accessibility.CollectionHelper;
|
2011-06-27 13:06:26 +00:00
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
|
|
|
|
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
|
|
|
|
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
|
|
|
|
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
|
|
|
|
import com.thetransactioncompany.jsonrpc2.client.JSONRPC2Session;
|
|
|
|
import com.thetransactioncompany.jsonrpc2.client.JSONRPC2SessionException;
|
|
|
|
|
2011-07-05 12:32:08 +00:00
|
|
|
public class JSONInterface {
|
2011-06-27 13:06:26 +00:00
|
|
|
private static Log _log;
|
|
|
|
private static ConfigurationManager _conf;
|
2011-07-05 12:32:08 +00:00
|
|
|
private static String DEFAULT_PASSWORD = "itoopie";
|
2011-06-27 13:06:26 +00:00
|
|
|
private static int nonce;
|
2011-07-05 12:32:08 +00:00
|
|
|
private static final int MAX_NBR_RETRIES = 2;
|
2011-06-27 13:06:26 +00:00
|
|
|
private static JSONRPC2Session session;
|
2011-07-05 12:32:08 +00:00
|
|
|
private static String token;
|
2011-07-08 09:52:09 +00:00
|
|
|
/*
|
|
|
|
* i2p.router.net.ntcp.port
|
|
|
|
* i2p.router.net.ntcp.hostname
|
|
|
|
* i2p.router.net.ntcp.autoip // true|always|false //disables autodetect|disabled //disables ntcp
|
|
|
|
* i2p.router.net.ssu.port
|
|
|
|
* i2p.router.net.ssu.hostname
|
|
|
|
* i2p.router.net.ssu.detectedip
|
|
|
|
* i2p.router.net.ssu.autoip //[local,upnp,ssu] any of prev., in order |fixed // fixed = no detection
|
|
|
|
* i2p.router.net.upnp //
|
|
|
|
* i2p.router.net.bw.share
|
|
|
|
* i2p.router.net.bw.in
|
|
|
|
* i2p.router.net.bw.out
|
|
|
|
* i2p.router.net.laptopmode
|
|
|
|
*/
|
|
|
|
public interface RemoteSetable{ public boolean isSetable(); }
|
|
|
|
public static enum NETWORK_INFO implements RemoteSetable{
|
|
|
|
DETECTED_IP { public boolean isSetable(){ return false;} public String toString() { return "i2p.router.net.ssu.detectedip"; }},
|
|
|
|
TCP_PORT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.port"; }},
|
|
|
|
TCP_HOSTNAME { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.hostname"; }},
|
|
|
|
TCP_AUTOIP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ntcp.autoip"; }},
|
|
|
|
UDP_PORT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.port"; }},
|
|
|
|
UDP_HOSTNAME { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.hostname"; }},
|
|
|
|
UDP_AUTO_IP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.ssu.autoip"; }},
|
|
|
|
UPNP { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.upnp"; }},
|
|
|
|
BW_SHARE { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.share"; }},
|
|
|
|
BW_IN { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.in"; }},
|
|
|
|
BW_OUT { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.bw.out"; }},
|
|
|
|
LAPTOP_MODE { public boolean isSetable(){ return true;} public String toString() { return "i2p.router.net.laptopmode"; }}
|
|
|
|
};
|
|
|
|
private final static HashMap<String,NETWORK_INFO> enumMap;
|
|
|
|
|
2011-06-27 13:06:26 +00:00
|
|
|
static {
|
|
|
|
_log = LogFactory.getLog(JSONInterface.class);
|
|
|
|
_conf = ConfigurationManager.getInstance();
|
|
|
|
Random rnd = new Random();
|
|
|
|
nonce = rnd.nextInt();
|
|
|
|
setupSession();
|
2011-07-08 09:52:09 +00:00
|
|
|
enumMap = new HashMap<String,NETWORK_INFO>();
|
|
|
|
for (NETWORK_INFO n : NETWORK_INFO.values()){
|
|
|
|
enumMap.put(n.toString(), n);
|
|
|
|
}
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
private static synchronized int incrNonce() {
|
2011-06-27 13:06:26 +00:00
|
|
|
return ++nonce;
|
|
|
|
}
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
public static void setupSession() {
|
2011-06-27 13:06:26 +00:00
|
|
|
URL srvURL = null;
|
2011-07-05 14:10:19 +00:00
|
|
|
String srvHost = _conf.getConf("server.hostname", "localhost");
|
|
|
|
int srvPort = _conf.getConf("server.port", 7656);
|
|
|
|
String srvTarget = _conf.getConf("server.target", "jsonrpc");
|
2011-06-27 13:06:26 +00:00
|
|
|
try {
|
2011-07-05 12:32:08 +00:00
|
|
|
srvURL = new URL("https://" + srvHost + ":" + srvPort + "/"
|
|
|
|
+ srvTarget);
|
|
|
|
} catch (MalformedURLException e) {
|
|
|
|
_log.error("Bad URL: https://" + srvHost + ":" + srvPort + "/"
|
|
|
|
+ srvTarget, e);
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
|
|
|
session = new JSONRPC2Session(srvURL);
|
2011-07-01 06:34:21 +00:00
|
|
|
session.trustAllCerts(true);
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
private static JSONRPC2Response sendReq(JSONRPC2Request req)
|
2011-07-08 09:52:09 +00:00
|
|
|
throws InvalidPasswordException, UnrecoverableFailedRequestException,
|
|
|
|
InvalidParametersException, JSONRPC2SessionException{
|
2011-07-05 12:32:08 +00:00
|
|
|
return sendReq(req, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static JSONRPC2Response sendReq(JSONRPC2Request req, int tryNbr)
|
2011-07-08 09:52:09 +00:00
|
|
|
throws InvalidPasswordException, UnrecoverableFailedRequestException,
|
|
|
|
InvalidParametersException, JSONRPC2SessionException {
|
|
|
|
if (tryNbr > MAX_NBR_RETRIES){
|
|
|
|
throw new UnrecoverableFailedRequestException(); // Max retries reached. Throw exception.
|
|
|
|
}
|
|
|
|
HashMap outParams = (HashMap) req.getParams();
|
|
|
|
outParams.put("Token", token); // Add authentication token
|
|
|
|
req.setParams(outParams);
|
|
|
|
|
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
|
|
|
resp = session.send(req);
|
|
|
|
JSONRPC2Error err = resp.getError();
|
|
|
|
if (err != null) {
|
|
|
|
switch (err.getCode()) {
|
|
|
|
case -32700:
|
|
|
|
// Parse error
|
|
|
|
_log.error(err.getMessage());
|
|
|
|
break;
|
|
|
|
case -32600:
|
|
|
|
// Invalid request
|
|
|
|
_log.error(err.getMessage());
|
|
|
|
break;
|
|
|
|
case -32601:
|
|
|
|
// Method not found
|
|
|
|
_log.error(err.getMessage());
|
|
|
|
break;
|
|
|
|
case -32602:
|
|
|
|
// Invalid params
|
|
|
|
_log.error(err.getMessage());
|
|
|
|
throw new InvalidParametersException();
|
|
|
|
//break;
|
|
|
|
case -32603:
|
|
|
|
// Internal error
|
|
|
|
_log.error("Remote host: " + err.getMessage());
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Custom errors (as defined by the I2PControl API)
|
|
|
|
case -32001:
|
|
|
|
// Invalid password
|
|
|
|
_log.info("Provided password was rejected by the remote host");
|
|
|
|
throw new InvalidPasswordException();
|
|
|
|
// break;
|
|
|
|
case -32002:
|
|
|
|
// No token
|
|
|
|
token = getNewToken();
|
|
|
|
throw new FailedRequestException();
|
|
|
|
// break;
|
|
|
|
case -32003:
|
|
|
|
// Invalid token
|
|
|
|
token = getNewToken();
|
|
|
|
throw new FailedRequestException();
|
|
|
|
//break;
|
|
|
|
case -32004:
|
|
|
|
// Token expired
|
|
|
|
token = getNewToken();
|
|
|
|
throw new FailedRequestException();
|
|
|
|
// break;
|
2011-07-05 12:32:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return resp;
|
2011-07-08 09:52:09 +00:00
|
|
|
}catch (FailedRequestException e) {
|
|
|
|
return sendReq(req, ++tryNbr);
|
2011-07-05 12:32:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static synchronized String getNewToken()
|
2011-07-08 09:52:09 +00:00
|
|
|
throws InvalidPasswordException, JSONRPC2SessionException {
|
|
|
|
JSONRPC2Request req = new JSONRPC2Request("Authenticate", incrNonce());
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
Map outParams = new HashMap();
|
2011-07-08 09:52:09 +00:00
|
|
|
outParams.put("Password",
|
2011-07-05 12:32:08 +00:00
|
|
|
_conf.getConf("server.password", DEFAULT_PASSWORD));
|
|
|
|
req.setParams(outParams);
|
|
|
|
|
2011-06-27 13:06:26 +00:00
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
2011-07-05 12:32:08 +00:00
|
|
|
resp = sendReq(req);
|
2011-07-08 09:52:09 +00:00
|
|
|
Map inParams = (HashMap) resp.getResult();
|
|
|
|
return (String) inParams.get("Token");
|
2011-07-05 12:32:08 +00:00
|
|
|
}catch (UnrecoverableFailedRequestException e) {
|
2011-07-08 09:52:09 +00:00
|
|
|
return null; // Shouldn't normally happen.
|
|
|
|
} catch (InvalidParametersException e) {
|
|
|
|
_log.error("getNewToken() invalid parameters used");
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
2011-07-08 09:52:09 +00:00
|
|
|
return null;
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
2011-07-05 12:32:08 +00:00
|
|
|
|
2011-06-27 13:06:26 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2011-07-05 12:32:08 +00:00
|
|
|
public static Double getRateStat(String stat, long period)
|
2011-07-08 09:52:09 +00:00
|
|
|
throws InvalidPasswordException, JSONRPC2SessionException, InvalidParametersException {
|
2011-07-05 12:32:08 +00:00
|
|
|
|
2011-07-08 09:52:09 +00:00
|
|
|
JSONRPC2Request req = new JSONRPC2Request("GetRate", incrNonce());
|
2011-06-27 13:06:26 +00:00
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
Map params = new HashMap();
|
2011-07-08 09:52:09 +00:00
|
|
|
params.put("Stat", stat);
|
|
|
|
params.put("Period", period);
|
2011-06-27 13:06:26 +00:00
|
|
|
req.setParams(params);
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
|
|
|
resp = sendReq(req);
|
2011-07-08 09:52:09 +00:00
|
|
|
Map inParams = (HashMap) resp.getResult();
|
|
|
|
return (Double) inParams.get("Result");
|
2011-07-05 12:32:08 +00:00
|
|
|
}catch (UnrecoverableFailedRequestException e) {
|
|
|
|
_log.error("getRateStat failed.", e);
|
|
|
|
}
|
2011-07-08 09:52:09 +00:00
|
|
|
return null;
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|
2011-07-05 12:32:08 +00:00
|
|
|
|
2011-07-01 06:34:21 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2011-07-08 09:52:09 +00:00
|
|
|
public static String getEcho(String str)
|
|
|
|
throws InvalidPasswordException, JSONRPC2SessionException {
|
2011-07-05 12:32:08 +00:00
|
|
|
|
2011-07-08 09:52:09 +00:00
|
|
|
JSONRPC2Request req = new JSONRPC2Request("Echo", incrNonce());
|
2011-07-01 06:34:21 +00:00
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
Map params = new HashMap();
|
2011-07-08 09:52:09 +00:00
|
|
|
params.put("Echo", str);
|
2011-07-01 06:34:21 +00:00
|
|
|
req.setParams(params);
|
2011-07-05 12:32:08 +00:00
|
|
|
|
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
|
|
|
resp = sendReq(req);
|
2011-07-08 09:52:09 +00:00
|
|
|
Map inParams = (HashMap) resp.getResult();
|
|
|
|
return (String) inParams.get("Result");
|
|
|
|
} catch (UnrecoverableFailedRequestException e) {
|
|
|
|
_log.error("GetEcho failed.", e);
|
|
|
|
} catch (InvalidParametersException e) {
|
|
|
|
_log.error("Remote host rejected provided parameters: " + req.toJSON().toJSONString());
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static HashMap getNetworkInfo(NETWORK_INFO ... options)
|
|
|
|
throws InvalidPasswordException, JSONRPC2SessionException{
|
|
|
|
|
|
|
|
JSONRPC2Request req = new JSONRPC2Request("NetworkSetting", incrNonce());
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
Map outParams = new HashMap();
|
|
|
|
List<NETWORK_INFO> list = Arrays.asList(options);
|
|
|
|
|
|
|
|
for (NETWORK_INFO i : list){
|
|
|
|
outParams.put(i.toString(), null);
|
|
|
|
}
|
|
|
|
|
|
|
|
req.setParams(outParams);
|
|
|
|
|
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
|
|
|
resp = sendReq(req);
|
|
|
|
HashMap map = (HashMap) resp.getResult();
|
|
|
|
if (map != null){
|
|
|
|
Set<Entry> set = map.entrySet();
|
|
|
|
HashMap output = new HashMap();
|
|
|
|
for (Entry e: set){
|
|
|
|
output.put(enumMap.get(e.getKey()), e.getValue());
|
|
|
|
}
|
|
|
|
return map;
|
|
|
|
} else {
|
|
|
|
return new HashMap();
|
|
|
|
}
|
|
|
|
} catch (UnrecoverableFailedRequestException e) {
|
|
|
|
_log.error("getNetworkInfo failed.", e);
|
|
|
|
} catch (InvalidParametersException e) {
|
|
|
|
_log.error("Remote host rejected provided parameters: " + req.toJSON().toJSONString());
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static HashMap<NETWORK_INFO, Boolean> setNetworkSetting(Map<NETWORK_INFO,String> settings)
|
|
|
|
throws InvalidPasswordException, JSONRPC2SessionException, InvalidParametersException{
|
|
|
|
|
|
|
|
JSONRPC2Request req = new JSONRPC2Request("NetworkSetting", incrNonce());
|
|
|
|
|
|
|
|
Map outParams = new HashMap();
|
|
|
|
|
|
|
|
Set<Entry<NETWORK_INFO,String>> set = settings.entrySet();
|
|
|
|
for (Entry<NETWORK_INFO,String> e : set){
|
|
|
|
if(e.getKey().isSetable()){
|
|
|
|
outParams.put(e.getKey().toString(), e.getValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
req.setParams(outParams);
|
|
|
|
|
|
|
|
JSONRPC2Response resp = null;
|
|
|
|
try {
|
|
|
|
resp = sendReq(req);
|
|
|
|
HashMap map = (HashMap) resp.getResult();
|
|
|
|
return map;
|
2011-07-05 12:32:08 +00:00
|
|
|
} catch (UnrecoverableFailedRequestException e) {
|
2011-07-08 09:52:09 +00:00
|
|
|
_log.error("setNetworkInfo failed.", e);
|
2011-07-05 12:32:08 +00:00
|
|
|
}
|
2011-07-08 09:52:09 +00:00
|
|
|
return null;
|
2011-07-01 06:34:21 +00:00
|
|
|
}
|
2011-06-27 13:06:26 +00:00
|
|
|
}
|