예제 #1
0
파일: controlapi.go 프로젝트: houcy/push
func controlDevice(w rest.ResponseWriter, r *rest.Request) {
	type ControlParam struct {
		Token   string `json:"token"`
		Service string `json:"service"`
		Cmd     string `json:"cmd"`
	}

	devId := r.PathParam("devid")
	body := r.Env["body"]
	if body == nil {
		rest.Error(w, "Empty body", http.StatusBadRequest)
		return
	}
	b := body.([]byte)
	param := ControlParam{}
	if err := json.Unmarshal(b, &param); err != nil {
		log.Warnf("Error decode body: %s", err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if !checkAuthz(param.Token, devId) {
		log.Warnf("Auth failed. token: %s, device_id: %s", param.Token, devId)
		rest.Error(w, "Authorization failed", http.StatusForbidden)
		return
	}

	stats.Cmd(param.Service)
	resp := cloud.ApiResponse{}
	result, err := rpcClient.Control(devId, param.Service, param.Cmd)
	if err != nil {
		if _, ok := err.(*mq.NoDeviceError); ok {
			stats.CmdOffline(param.Service)
			rest.NotFound(w, r)
			return
		} else if _, ok := err.(*mq.TimeoutError); ok {
			stats.CmdTimeout(param.Service)
			resp.ErrNo = cloud.ERR_CMD_TIMEOUT
			resp.ErrMsg = fmt.Sprintf("recv response timeout [%s]", devId)
		} else if _, ok := err.(*mq.InvalidServiceError); ok {
			stats.CmdInvalidService(param.Service)
			resp.ErrNo = cloud.ERR_CMD_INVALID_SERVICE
			resp.ErrMsg = fmt.Sprintf("Device [%s] has no service [%s]", devId, param.Service)
		} else if _, ok := err.(*mq.SdkError); ok {
			stats.CmdOtherError(param.Service)
			resp.ErrNo = cloud.ERR_CMD_SDK_ERROR
			resp.ErrMsg = fmt.Sprintf("Error when calling service [%s] on [%s]", param.Service, devId)
		} else {
			stats.CmdOtherError(param.Service)
			resp.ErrNo = cloud.ERR_CMD_OTHER
			resp.ErrMsg = err.Error()
		}
	} else {
		stats.CmdSuccess(param.Service)
		resp.ErrNo = cloud.ERR_NOERROR
		resp.Data = result
	}

	w.WriteJson(resp)
}
예제 #2
0
파일: controlapi.go 프로젝트: houcy/push
func postRouterCommand(w rest.ResponseWriter, r *rest.Request) {
	log.Debugf("Request from RemoterAddr: %s", r.RemoteAddr)

	resp := CommandResponse{}
	resp.Status = STATUS_OK

	uid := r.FormValue("uid")
	if uid == "" {
		resp.Status = STATUS_INVALID_PARAM
		resp.Error = "missing 'uid'"
		w.WriteJson(resp)
		return
	}

	rid := r.FormValue("rid")
	if rid == "" {
		resp.Status = STATUS_INVALID_PARAM
		resp.Error = "missing 'rid'"
		w.WriteJson(resp)
		return
	}

	if !checkAuthzUid(uid, rid) {
		log.Warnf("auth failed. uid: %s, rid: %s", uid, rid)
		resp.Status = STATUS_OTHER_ERR
		resp.Error = "authorization failed"
		w.WriteJson(resp)
		return
	}

	if r.Body == nil {
		resp.Status = STATUS_INVALID_PARAM
		resp.Error = "missing POST data"
		w.WriteJson(resp)
		return
	}

	body, err := ioutil.ReadAll(r.Body)
	r.Body.Close()
	if err != nil {
		resp.Status = STATUS_INVALID_PARAM
		resp.Error = "invalid POST body"
		w.WriteJson(resp)
		return
	}

	var cmd string
	var serviceName string

	if len(rid) == len("c80e774a1e78") {
		// To old agent
		serviceName = "gibbon_agent"
		type CommandRequest struct {
			//Uid string `json:"uid"`
			Cmd string `json:"cmd"`
		}
		cmdRequest := CommandRequest{
			//Uid: uid,
			Cmd: string(body),
		}
		bCmd, _ := json.Marshal(cmdRequest)
		cmd = string(bCmd)
	} else {
		// To new android service
		serviceName = "com.letv.letvroutersettingservice"
		type RouterCommand struct {
			Forward string `json:"forward"`
		}
		var rc RouterCommand
		if err := json.Unmarshal([]byte(body), &rc); err != nil {
			resp.Status = -2000
			resp.Error = "Request body is not JSON"
			w.WriteJson(resp)
			return
		}
		cmd = rc.Forward
		if cmd == "" {
			resp.Status = -2001
			resp.Error = "'forward' is empty"
			w.WriteJson(resp)
			return
		}
	}

	stats.Cmd(serviceName)
	result, err := rpcClient.Control(rid, serviceName, cmd)
	if err != nil {
		if _, ok := err.(*mq.NoDeviceError); ok {
			stats.CmdOffline(serviceName)
			resp.Status = STATUS_ROUTER_OFFLINE
			resp.Error = fmt.Sprintf("device (%s) offline", rid)
		} else if _, ok := err.(*mq.TimeoutError); ok {
			stats.CmdTimeout(serviceName)
			resp.Status = STATUS_OTHER_ERR
			resp.Error = fmt.Sprintf("recv response timeout [%s]", rid)
		} else if _, ok := err.(*mq.InvalidServiceError); ok {
			stats.CmdInvalidService(serviceName)
			resp.Status = STATUS_OTHER_ERR
			resp.Error = fmt.Sprintf("Device [%s] has no service [%s]", rid, serviceName)
		} else {
			stats.CmdOtherError(serviceName)
			resp.Status = STATUS_OTHER_ERR
			resp.Error = err.Error()
		}
		w.WriteJson(resp)
		return
	} else {
		stats.CmdSuccess(serviceName)
		if len(rid) == len("c80e774a1e78") {
			// reply from gibbon agent
			w.(http.ResponseWriter).Write([]byte(result))
		} else {
			// reply from android service
			type RouterCommandReply struct {
				Status int    `json:"status"`
				Descr  string `json:"descr"`
				Result string `json:"result"`
			}
			var reply RouterCommandReply
			reply.Status = 0
			reply.Descr = "OK"
			reply.Result = result
			w.WriteJson(reply)
		}
	}
}