package com.rokid.homebase.driver.h3c;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import com.rokid.homebase.driver.h3c.entity.ServerPortEntity;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
public class XinHuaService extends Service {
private static DriverHandler mHandler;
private static final String TAG = "H3C";
public final class DriverHandler extends Handler {
public static final int MSG_UPDATE_PORT = 10;
public static final int MSG_LUNCH_SERVER_WITH_PORT = 20;
private int mCounter;
public DriverHandler(Looper lpr) {
super(lpr);
mCounter = 50;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_PORT: {
fetchServerLunchPort(true);
}
break;
case MSG_LUNCH_SERVER_WITH_PORT: {
ServerPortEntity entity = (ServerPortEntity) msg.obj;
Log.d(TAG, "recv port resp: " + entity.toString());
switch (entity.getResponseStatus().getRequestStatus()) {
case HttpURLConnection.HTTP_OK: {
if (entity.status == 0) {
XinhuaServer.lunch(getApplicationContext(), entity.port);
} else {
Log.e(TAG, "req port status: " + entity.status);
// TODO retry mechanism required ...
mCounter--;
if (mCounter > -1) {
mHandler.sendEmptyMessageDelayed(DriverHandler.MSG_UPDATE_PORT,
100L * (50 - mCounter));
}
}
}
break;
default:
Log.e(TAG, "recv response: " + entity.getResponseStatus().getDescription());
super.handleMessage(msg);
break;
}
}
break;
default:
super.handleMessage(msg);
}
}
}
public static DriverHandler getMyHandler() {
return mHandler;
}
private URL getURL(String host, int port, String methods, HashMap params)
throws MalformedURLException, NullPointerException {
if (port < 1)
throw new MalformedURLException("illegal port value: " + port);
if (host == null || host.length() < 1)
throw new NullPointerException("host is nil ...");
StringBuffer urlStr = new StringBuffer();
urlStr.append(host);
urlStr.append(":");
urlStr.append(port);
urlStr.append(methods);
urlStr.append("?");
Iterator paramsKeys = params.keySet().iterator();
while (paramsKeys.hasNext()) {
String currKey = paramsKeys.next();
urlStr.append(currKey);
urlStr.append("=");
urlStr.append(params.get(currKey));
if (paramsKeys.hasNext())
urlStr.append("&");
}
Log.d(TAG, "fetched url: " + urlStr.toString());
return (new URL(urlStr.toString()));
}
@Override
public void onCreate() {
Log.d(TAG, "----onCreate---XinhuasanService");
if (mHandler == null) {
mHandler = new DriverHandler(Looper.getMainLooper());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: " );
if (mHandler != null) {
mHandler.sendEmptyMessage(DriverHandler.MSG_UPDATE_PORT);
}
return Service.START_STICKY;
}
private void fetchServerLunchPort(boolean relunch) {
// TODO
// chk whether should relunch server or not ...
if (XinhuaServer.isServerAlive()) {
if (!relunch) {
Log.e(TAG, "server is running ...");
return;
} else {
XinhuaServer.terminate();
}
}
Log.d(TAG, "fetch port to re-lunch server...");
Resources res = getApplicationContext().getResources();
final HashMap params = new HashMap();
params.put("vendor", res.getString(com.rokid.homebase.driver.h3c.R.string.vendor));
try {
URL portUrl = getURL(res.getString(com.rokid.homebase.driver.h3c.R.string.sayhello_host),
res.getInteger(com.rokid.homebase.driver.h3c.R.integer.sayhello_port),
res.getString(com.rokid.homebase.driver.h3c.R.string.sayhello_methods),
params);
(new HttpRequestThread(res.getInteger(com.rokid.homebase.driver.h3c.R.integer.sayhello_timeout), portUrl)).start();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "failed to re-lunch server for URL problems...");
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: " + intent.getAction());
return null;
}
}
package com.rokid.homebase.driver.h3c;
import android.os.Message;
import android.util.Log;
import com.rokid.homebase.driver.h3c.entity.ServerPortEntity;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpRequestThread extends Thread {
private URL mURL;
private int mTimeout;
private static final String TAG = "H3C";
public HttpRequestThread(int timeout, URL url) {
mURL = url;
mTimeout = timeout;
}
public void setTimeout(int timeout) {
this.mTimeout = timeout;
}
@Override
public void run() {
Log.d(TAG, "http request thrd run with id: " + Thread.currentThread().getId());
try {
HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
conn.setConnectTimeout(mTimeout);
conn.connect();
int code = conn.getResponseCode();
ServerPortEntity entity;
Log.d(TAG, "-----code:" + code);
switch (code) {
case HttpURLConnection.HTTP_OK: {
entity = new ServerPortEntity(code, handleInput(conn.getInputStream()));
}
break;
default: {
entity = new ServerPortEntity(code, null);
}
break;
}
if (XinHuaService.getMyHandler() != null) {
XinHuaService.DriverHandler hdl = XinHuaService.getMyHandler();
Message msg = hdl.obtainMessage();
msg.what = XinHuaService.DriverHandler.MSG_LUNCH_SERVER_WITH_PORT;
msg.obj = entity;
hdl.sendMessage(msg);
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
private String handleInput(InputStream in) throws java.io.IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(in));
String line;
String content = "";
while ((line = reader.readLine()) != null) {
content += line;
}
return content;
}
}
ServerPortEntity方法:
public ServerPortEntity(int code, String json) {
responseStatus = Status.lookup(code);
if (json == null || json.length() < 1) {
status = -1;
port = -1;
}
else {
try {
JSONObject obj = new JSONObject(json);
Log.d("cccc", "ServerPortEntity: "+ obj.toString());
status = obj.getInt("status");
JSONObject body = obj.getJSONObject("data");
port = body.getInt("port");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
XinhuaServer
package com.rokid.homebase.driver.h3c;
import android.content.Context;
import android.util.Log;
import com.h3c.app.shome.sdk.entity.AirConEntity;
import com.h3c.app.shome.sdk.entity.BindGwListEntity;
import com.h3c.app.shome.sdk.entity.CallResultEntity;
import com.h3c.app.shome.sdk.entity.CentrumLoginEntity;
import com.h3c.app.shome.sdk.entity.CurtainEntity;
import com.h3c.app.shome.sdk.entity.DeviceEntity;
import com.h3c.app.shome.sdk.entity.DeviceListEntity;
import com.h3c.app.shome.sdk.entity.DeviceTypeEnum;
import com.h3c.app.shome.sdk.entity.DimmerEntity;
import com.h3c.app.shome.sdk.entity.ISwitchEntity;
import com.h3c.app.shome.sdk.http.AbsSmartHomeHttp;
import com.h3c.app.shome.sdk.http.RemoteModeHttp;
import com.h3c.app.shome.sdk.service.ISDKCallBack;
import com.h3c.app.shome.sdk.service.RetCodeEnum;
import com.h3c.app.shome.sdk.service.ServiceFactory;
import com.h3c.app.shome.sdk.util.CommonUtils;
import com.rokid.homebase.driver.GwItem;
import com.rokid.homebase.driver.MyApplication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.NanoHTTPD;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.util.ServerRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
* Created by DW on 17/2/8.
*/
public class XinhuaServer extends NanoHTTPD {
private static final String TAG = "H3C";
private static XinhuaServer sServer = null;
private Context mCtx;
private H3CDriver h3cDriver;
public static void lunch(Context ctx, int port) {
if (sServer == null) {
sServer = new XinhuaServer(ctx, port);
}
if (!sServer.isAlive()) {
ServerRunner.executeInstance(sServer);
}
Log.d(TAG, "-----------sServer.isAlive() : " + sServer.isAlive());
}
public XinhuaServer(Context context, int port) {
super(port);
mCtx = context;
h3cDriver = new H3CDriver();
}
public static boolean isServerAlive() {
return (sServer != null && sServer.isAlive());
}
public static void terminate() {
if (sServer != null) {
sServer.stop();
sServer = null;
}
}
//接受网页端的请求返回response给网页端
@Override
public Response serve(IHTTPSession session) {
super.serve(session);
Log.d(TAG, " ----serve---- : " + session.getMethod() + " -----session.getUri():" + session.getUri());
switch (session.getMethod()) {
case POST:
try {
Map headers = session.getHeaders();
try {
Log.d(TAG, "------parseRequest: begin");
//url,请求体
return parseRequest(session.getUri(), session.getRawJSON());
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "------parseRequest: Exception");
return DriverResponse.jsonExceptionResponse();
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "------session.getHeaders();exception");
return null;
}
default:
Log.d(TAG, "------default: ");
return DriverResponse.wrongMethodResponse(
mCtx.getResources().getString(com.rokid.homebase.driver.h3c.R.string.response_exception_method_not_allowed));
}
}
@Override
public void stop() {
super.stop();
}
private Response parseRequest(String uri, String body) throws JSONException {
Log.d(TAG, "-------recv uri: " + uri + " ----in thrd: " + Thread.currentThread().getId() + "-----body:" + body.toString());
JSONObject req = new JSONObject(body);
Map devList = new HashMap();
//command
// /list
// /get
// /execute
if ("/command".equalsIgnoreCase(uri)) {
JSONObject loginExceptionObj = new JSONObject();
Log.d(TAG, "parseRequest: " + loginExceptionObj.toString());
JSONObject authObj = req.getJSONObject("params");
String account = authObj.getString("username");
String psw = authObj.getString("password");
String[] password = psw.split("//");
Log.d(TAG, "parseRequest: psw:" + password[0] + " ,gwpsw:" + password[1]);
if (account != null && !account.equals("") && psw != null && !psw.equals("")) {
h3cDriver.gotoLogin(account, password);
}
Log.d(TAG, "-----isLogin?" + h3cDriver.isUserLogined());
if (!h3cDriver.isUserLogined()) {
loginExceptionObj.put("message", "login failed retry now ...");
return DriverResponse.customizedResponse(1, loginExceptionObj);
}
if (!h3cDriver.isGwInited()) {
loginExceptionObj.put("message", "gw login failed retry now ...");
return DriverResponse.customizedResponse(1, loginExceptionObj);
}
else {
return DriverResponse.okResponse(h3cDriver.obtainJsonLogin());
}
} else if ("/list".equalsIgnoreCase(uri)) {
JSONObject loginExceptionObj = new JSONObject();
Log.d(TAG, "parseRequest: " + loginExceptionObj.toString());
JSONObject authObj = req.getJSONObject("userAuth");
String account = authObj.getString("userId");
String psw = authObj.getString("userToken");
// String[] password = psw.split("//");
Log.d(TAG, "parseRequest: psw:" + psw);
if (account != null && !account.equals("") && psw != null && !psw.equals("")) {
Log.d(TAG, "-----isLogin?" + h3cDriver.isUserLogined() + "--isGwlogin:" + h3cDriver.isGwInited());
if (h3cDriver.isGwInited()) {
h3cDriver.obtainH3CDevices();
}
if (h3cDriver.getDevList() != null && h3cDriver.getDevList().size() > 0) {
devList = h3cDriver.getDevList();
}
}
JSONArray jsonList = new JSONArray();
if (devList == null || devList.size() < 1) {
JSONObject expObj = new JSONObject();
expObj.put("message", "no device founded ...");
return DriverResponse.customizedResponse(1, expObj);
} else {
Log.d(TAG, " list size is: " + devList.size());
Iterator itor = devList.keySet().iterator();
while (itor.hasNext()) {
jsonList.put(h3cDriver.getJSONDevices(devList.get(itor.next())));
}
return DriverResponse.okResponse(jsonList);
}
} else if ("/get".equalsIgnoreCase(uri)) {
JSONObject devObj = req.getJSONObject("device");
if (h3cDriver.getDevList() != null && h3cDriver.getDevList().size() > 0) {
devList = h3cDriver.getDevList();
}
if (devList == null) {
h3cDriver.obtainH3CDevices();
return DriverResponse.customizedResponse(2, null);
} else {
H3CDevice device = devList.get(devObj.getString("deviceId"));
if (device == null)
return DriverResponse.customizedResponse(2, null);
else
return DriverResponse.okResponse(h3cDriver.getJSONDevice(device));
}
} else if ("/execute".equalsIgnoreCase(uri)) {
JSONObject devObj = req.getJSONObject("device");
Map h3cDevList = new HashMap();
JSONObject controlResultObj = null;
if (h3cDriver.getDevList() != null && h3cDriver.getDevList().size() > 0) {
devList = h3cDriver.getDevList();
h3cDevList = h3cDriver.getH3cDevList();
}
if (devList == null) {
h3cDriver.obtainH3CDevices();
return DriverResponse.customizedResponse(2, null);
} else {
final JSONObject requestActions = req.getJSONObject("action");
H3CDevice device = devList.get(devObj.getString("deviceId"));
final DeviceEntity h3cDev = h3cDevList.get(devObj.getString("deviceId"));
for (H3CDeviceActions h3cAction : device.getActions()) {
// Log.d(TAG, "parseRequest: "+h3cAction.getActionName()+" action:"+requestActions.getString(h3cAction.getActionName()));
if (requestActions.has(h3cAction.getActionName())) {
if (requestActions.getString(h3cAction.getActionName()) != null) {
Log.d(TAG, "parseRequest action is :" + requestActions.getString(h3cAction.getActionName()));
controlResultObj = h3cDriver.controlH3CDevice(h3cAction.getActionName(),
requestActions.getString(h3cAction.getActionName()), h3cDev, device);
}
}
}
}
if (controlResultObj != null) {
return DriverResponse.okResponse(controlResultObj);
}
return DriverResponse.customizedResponse(2, null);
} else {
JSONObject respObj = new JSONObject();
respObj.put("message", "no such command ...");
return DriverResponse.okResponse(respObj);
}
}
}
DriverResponse
package com.rokid.homebase.driver.h3c;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;
public class DriverResponse {
private static final String TAG="H3C";
private static final String JSON_MIME_TYPE = "application/json";
private static final Status RESP_STATUS_OK = Status.lookup(200);
private static final Status RESP_STATUS_BAD_METHOD = Status.lookup(405);
private static final Status RESP_STATUS_NOT_ACCEPTABLE = Status.lookup(406);
private static final int DRIVER_RESP_OKAY = 0;
private static String genException(int code, String desc) {
try {
JSONObject obj = new JSONObject();
obj.put("status", code);
obj.put("message", desc);
Log.d(TAG,"------thread:"+Thread.currentThread().getId()+"-------Response:"+obj.toString());
return obj.toString();
}
catch (JSONException e) {
return null;
}
}
public static Response wrongMethodResponse(String customizedDesc) {
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_BAD_METHOD,
DriverResponse.JSON_MIME_TYPE,
genException(DriverResponse.RESP_STATUS_BAD_METHOD.getRequestStatus(),
customizedDesc));
}
public static Response jsonExceptionResponse() {
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_NOT_ACCEPTABLE,
DriverResponse.JSON_MIME_TYPE,
genException(2, "json parsing exception"));
}
public static Response customizedResponse(int code, JSONObject obj) {
JSONObject resp = new JSONObject();
try {
resp.put("status", code);
if (obj == null)
resp.put("data", "null");
else
resp.put("data", obj);
}
catch (Exception e) {
e.printStackTrace();
}
//Log.d(TAG,"-------------Response:"+obj.toString());
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_OK, DriverResponse.JSON_MIME_TYPE, resp.toString());
}
public static Response okResponse(JSONObject json) {
JSONObject obj = new JSONObject();
try {
obj.put("status", DRIVER_RESP_OKAY);
obj.put("data", json);
}
catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG,"------thread:"+Thread.currentThread().getId()+"-------Response:"+obj.toString());
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_OK,
DriverResponse.JSON_MIME_TYPE,
obj.toString());
}
public static final Response okResponse(JSONArray array) {
JSONObject obj = new JSONObject();
try {
obj.put("status", DRIVER_RESP_OKAY);
obj.put("data", array);
}
catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG,"------thread:"+Thread.currentThread().getId()+"-------Response:"+obj.toString());
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_OK,
DriverResponse.JSON_MIME_TYPE,
obj.toString());
}
public static Response wrongContentTypeResponse() {
return Response.newFixedLengthResponse(
DriverResponse.RESP_STATUS_NOT_ACCEPTABLE,
DriverResponse.JSON_MIME_TYPE,
genException(DriverResponse.RESP_STATUS_NOT_ACCEPTABLE.getRequestStatus(),
null));
}
}