module ("xiaoqiang.util.XQNetUtil", package.seeall)

local XQFunction = require("xiaoqiang.common.XQFunction")
local XQConfigs = require("xiaoqiang.common.XQConfigs")

local LuciProtocol = require("luci.http.protocol")
local XQHttpUtil = require("xiaoqiang.util.XQHttpUtil")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")

local DEFAULT_TOKEN = "8007236f-a2d6-4847-ac83-c49395ad6d65"
local V3_TOKEN

function getToken()
    return V3_TOKEN
end

function getMacAddr()
    local XQLanWanUtil = require("xiaoqiang.util.XQLanWanUtil")
    return XQLanWanUtil.getDefaultMacAddress()
end

function getSN()
    local LuciUtil = require("luci.util")
    local sn = LuciUtil.exec(XQConfigs.GET_NVRAM_SN)
    if XQFunction.isStrNil(sn) then
        return nil
    else
        sn = LuciUtil.trim(sn)
    end
    return sn
end

function getUserAgent()
    local sn = getSN() or ""
    return "miwifi-"..sn
end

function cryptUrl(serverUrl, subUrl, params, salt)
    local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
    if serverUrl == nil or params == nil then
        return nil
    end
    local time = XQFunction.getTime()
    table.insert(params,{"time",time})
    table.sort(params, function(a, b) return a[1] < b[1] end)
    local str = ""
    table.foreach(params, function(k, v) str = str..v[1].."="..v[2].."&" end)
    if salt ~= nil and salt ~= "" then
        str = str .. salt
    end
    local md5 = XQCryptoUtil.md5Base64Str(str)
    local token = getToken()
    local isV2 = string.find(serverUrl..subUrl,"/v2/") ~= nil or string.find(serverUrl..subUrl,"/rs/") ~= nil
    if XQFunction.isStrNil(token) or isV2 then
        token = DEFAULT_TOKEN
    end

    local url = ""
    if string.find(serverUrl..subUrl,"?") == nil then
        url = serverUrl..subUrl.."?s="..md5.."&time="..time.."&token="..LuciProtocol.urlencode(token)
    else
        url = serverUrl..subUrl.."&s="..md5.."&time="..time.."&token="..LuciProtocol.urlencode(token)
    end

    return url
end

--
-- HBase
--
local HBASE_LOG_UPLOAD_URL = "https://log.miwifi.com/xiaoqiang_log/"
local HBASE_CONFIG_UPLOAD_URL = "https://log.miwifi.com/xiaoqiang_config/"
local SUB_KEY = "false-row-key"
local CURL_CMD = "curl -k -i -f -X PUT %s%s -H \"Content-Type: application/json\" --data @%s 2>/dev/null"
local CONFIG_KEY = "Qzo="

local LOG_TYPE = {
    ["M"] = "TTo=",
    ["B"] = "Qjo=",
    ["X"] = "WDo=",
    ["Y"] = "WTo=",
    ["Z"] = "Wjo="
}

function generateLogKey()
    local mac = getMacAddr()
    local timestamp = string.format("%012d",os.time())
    return mac.."-"..timestamp
end

--[[
    M:Network detection log
    B:System log
    X:Not use
    Y:Not use
    Z:Not use
]]--
function uploadLogFile(logfile, logtype, logkey)
    local LuciJson = require("json")
    local column = LOG_TYPE[logtype]
    if XQFunction.isStrNil(column) then
        return false
    end
    local Mime = require("mime")
    local key = Mime.b64(logkey) or Mime.b64(generateLogKey())
    local filebase64str = luci.util.exec("/usr/bin/base64 "..logfile)
    local blob = {["column"]=column, ["$"]=string.gsub(filebase64str,"\n","")}
    local cell = {blob}
    local item = {["key"]=key,["Cell"]=cell}
    local data = {["Row"]=item}
    local dataStr = LuciJson.encode(data)
    local logJsonFile = io.open(XQConfigs.XQ_LOG_JSON_FILEPATH,"w")
    if logJsonFile then
        logJsonFile:write(dataStr)
        logJsonFile:close()
    end
    local command = string.format(CURL_CMD,HBASE_LOG_UPLOAD_URL,SUB_KEY,XQConfigs.XQ_LOG_JSON_FILEPATH)
    local result = luci.util.exec(command)
    if result == nil or result == "" then
        return false
    else
        if string.find(result,"OK") ~= nil then
            return true
        else
            return false
        end
    end
end

function uploadConfigFile(configfile)
    local Mime = require("mime")
    local LuciJson = require("json")
    local uuid = getMacAddr()
    if uuid == nil then
        return false
    end
    local filebase64str = luci.util.exec("/usr/bin/base64 "..configfile)
    local key = Mime.b64(uuid)
    local config = {["column"]=CONFIG_KEY, ["$"]=string.gsub(filebase64str,"\n","")}
    local cell = {config}
    local item = {["key"]=key,["Cell"]=cell}
    local data = {["Row"]=item}
    local dataStr = LuciJson.encode(data)
    local configJsonFile = io.open(XQConfigs.XQ_CONFIG_JSON_FILEPATH,"w")
    if configJsonFile then
        configJsonFile:write(dataStr)
        configJsonFile:close()
    end
    local command = string.format(CURL_CMD,HBASE_CONFIG_UPLOAD_URL,SUB_KEY,XQConfigs.XQ_CONFIG_JSON_FILEPATH)
    local result = luci.util.exec(command)
    if result == nil or result == "" then
        return false
    else
        if string.find(result,"OK") ~= nil then
            return true
        else
            return false
        end
    end
end

--[[
@param configfile: save path
unzip: invalid option -- t
]]--
-- function getConfigFile(configfile)
--     local Xml = require("slaxdom")
--     local SSLHttps = require("ssl.https")
--     local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
--     local uuid = getMacAddr()
--     if uuid == nil then
--         return false
--     end
--     local url = HBASE_CONFIG_UPLOAD_URL..uuid
--     local xmlstr = SSLHttps.request(url)
--     if xmlstr == nil or xmlstr == "" then
--         return false
--     end
--     if string.find(xmlstr,"html") ~= nil then
--         return false
--     end
--     local obj = Xml:dom(xmlstr)
--     local arr = obj.root.el[1].el
--     if #arr == 0 then
--         return false
--     end
--     local record = arr[1].kids[1].value
--     local decstr = XQCryptoUtil.binaryBase64Dec(record)
--     fd = io.open(configfile, "w")
--     fd:write(decstr)
--     fd:close()
--     local check = luci.util.exec("unzip -o "..configfile)
--     luci.util.exec("rm -rf /tmp/etc/")
--     if string.find(check,"invalid") ~= nil or string.find(check,"inflate error") ~= nil then
--         return false
--     end
--     return true
-- end

--
-- Upload Log V2
--

local FILE_PATH = XQConfigs.LOG_ZIP_FILEPATH
local FILE_TYPE = "tar.gz"
local LOG_URL = "https://log.miwifi.com/log/lite/common/%s"
local LOG_CMD = "curl -k -i -X POST -F 'id=%s' -F '_n=%s' -F '_t=%s' -F 'extra_data={\"version\":\"%s\", \"sn\":\"%s\", \"suffix\":\""..FILE_TYPE.."\"}' -F 'mode=%s' -F 'key=%s' -F 'payload=@"..FILE_PATH.."' %s"

function generateLogKeyV2()
    local deviceId = getDeviceId() or ""
    local hardware = XQSysUtil.getHardware() or ""
    local timestamp = os.time()
    return "common-"..hardware.."-"..deviceId.."-"..timestamp
end

function uploadLogV2(key)
    local LuciSys = require("luci.sys")
    local id = getDeviceId() or ""
    local _n = LuciSys.uniqueid(10)
    local _t = os.time()
    local version = XQSysUtil.getRomVersion()
    local sn = getSN() or ""
    local hardware = XQSysUtil.getHardware() or ""
    local url = string.format(LOG_URL, hardware)
    local mode = ""
    if key then
        mode = "useRomTime"
        _t = key:match("%-(%d+)$")
    else
        key = ""
    end
    local cmd = string.format(LOG_CMD,
        id, _n, _t, version, sn, mode, key, url
    )
    local result = luci.util.exec(cmd)
    if result == nil or result == "" then
        return false
    else
        if string.find(result,"\"code\":0") ~= nil then
            return true
        else
            return false
        end
    end
end

--
-- Xiaomi V3
--
local ACCOUNT_DOMAIN_ONLINE = "https://account.xiaomi.com/"
local ACCOUNT_DOMAIN_STAGING = "http://account.preview.n.xiaomi.net/"
local PASSPORT_LOGIN_PWD_URL = "pass/serviceLoginAuth"
local PASSPORT_LOGIN_PASSTOKEN_URL = "pass/serviceLogin?sid=xiaoqiang"

function xiaomiLogin(username,password)
    local LuciJson = require("json")
    local XQLog = require("xiaoqiang.XQLog")
    local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
    local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
    local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
    local userId,nonce,passToken,ssecurity,psecurity,location,domain
    --
    -- step1 get passtoken security and nonce /https
    --
    local params = {
        {"user", username},
        {"hash", string.upper(password)},
        {"sid", "xiaoqiang"},
        {"deviceId", getSN() or ""}
    }
    local url
    if XQConfigs.SERVER_CONFIG == 1 then
        url = ACCOUNT_DOMAIN_STAGING..PASSPORT_LOGIN_PWD_URL
    else
        url = ACCOUNT_DOMAIN_ONLINE..PASSPORT_LOGIN_PWD_URL
    end
    local data = ""
    table.foreach(params, function(k, v) data = data..v[1].."="..v[2].."&" end)
    local step1 = XQHttpUtil.httpGetRequest(url,string.sub(data,1,-2))
    if step1.code == 302 then
        local extensionPragma = step1.headers["extension-pragma"]
        local setCookie = step1.headers["set-cookie"]
        local extensionJson = LuciJson.decode(extensionPragma)

        location = step1.headers["location"]
        userId = setCookie:match('userId=(%d+);')
        passToken = setCookie:match('passToken=(%S+);')
        domain = setCookie:match('domain=(%S+);')
        nonce = extensionPragma:match('%S+\"nonce\":(%d+),%S+')
        ssecurity = extensionJson["ssecurity"]
        psecurity = extensionJson["psecurity"]
        XQLog.log(7,"XiaomiLogin Step1 Succeed:",step1)

        --
        --  step2 get xiaoqiang server token
        --
        local tobeSign = "nonce="..nonce.."&"..ssecurity
        local sign = XQCryptoUtil.binaryBase64Enc(XQCryptoUtil.sha1Binary(tobeSign))
        local queryStr = LuciProtocol.xq_urlencode_params({
            ["uuid"] = userId,
            ["clientSign"] = sign
        })
        local step2url = location.."&"..queryStr
        local step2 = XQHttpUtil.httpGetRequest(step2url)
        local stoken
        if step2.code == 200 and type(step2.headers) == "table" then
            local xqcookie = step2.headers["set-cookie"]
            if xqcookie then
                stoken = xqcookie:match('serviceToken=(%S+);')
            end
        elseif step2.code == 401 then
            XQLog.log(3,"XiaomiLogin Step2 401 Failed:", step2url, step2)
            return {code = 2}
        end
        local sid = ssecurity
        if not XQFunction.isStrNil(userId) and
            not XQFunction.isStrNil(passToken) and
            not XQFunction.isStrNil(stoken) and
            not XQFunction.isStrNil(sid) and
            not XQFunction.isStrNil(ssecurity) then
            XQLog.log(7,"XiaomiLogin Step2 succeed:"..userId)
            XQDBUtil.savePassport(userId,passToken,stoken,sid,ssecurity)
            local result = {
                code = 0,
                uuid = userId,
                token = passToken,
                stoken = stoken,
                sid = sid,
                ssecurity = ssecurity
            }
            return result
        else
            XQLog.log(3,"XiaomiLogin Step2 Failed:",{
                step2url = step2url,
                userId = userId or "",
                passToken = passToken or "",
                ssecurity = ssecurity or ""
            })
            return {code = 2}
        end
    elseif step1.code == 200 then
        XQLog.log(3,"XiaomiLogin Step1 Username/Password Error:", params, step1)
        return {code = 1}
    else
        XQLog.log(3,"XiaomiLogin Step1 Service Unreachable:", params, step1)
        return {code = 3}
    end
end

function getPassport(uuid)
    local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
    local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
    if XQFunction.isStrNil(uuid) then
        uuid = XQSysUtil.getBindUUID()
    end
    if XQFunction.isStrNil(uuid) then
        return false
    end
    local passport = XQDBUtil.fetchPassport(uuid)[1]
    if not passport then
        return false
    end
    if XQFunction.isStrNil(passport.token) then
        return false
    end
    V3_TOKEN = passport.token
    return passport
end

function generateOrigIconUrl(iconUrl)
    if XQFunction.isStrNil(iconUrl) then
        return ""
    else
        return string.gsub(iconUrl,".jpg","_150.jpg")
    end
end

local GET_USER_INFO = "http://api.account.xiaomi.com/pass/usersCard?ids="
function getUserInfo(uuid)
    local LuciJson = require("json")
    local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
    if XQFunction.isStrNil(uuid) then
        uuid = XQSysUtil.getBindUUID()
        if XQFunction.isStrNil(uuid) then
            return false
        end
    end
    local result = XQHttpUtil.httpGetRequest(GET_USER_INFO..uuid)
    if result.code ~= 200 then
        return false
    end
    local resultJson = LuciJson.decode(result.res)
    if resultJson then
        if string.upper(resultJson.result) == "OK" then
            local data = resultJson.data.list
            if data[1] then
                local userInfo = {}
                userInfo["aliasNick"] = data[1].aliasNick or ""
                userInfo["miliaoNick"] = data[1].miliaoNick or ""
                userInfo["userId"] = data[1].userId or ""
                userInfo["miliaoIcon"] = data[1].miliaoIcon or ""
                userInfo["miliaoIconOrig"] = generateOrigIconUrl(userInfo.miliaoIcon)
                XQSysUtil.setBindUserInfo(userInfo)
                return userInfo
            end
        end
    end
    return false
end

--
-- XiaoQiang
--
local XIAOQIANG_SERVER = XQConfigs.SERVER_CONFIG_ONLINE_URL
if XQConfigs.SERVER_CONFIG == 1 then
    XIAOQIANG_SERVER = XQConfigs.SERVER_CONFIG_STAGING_URL
elseif XQConfigs.SERVER_CONFIG == 2 then
    XIAOQIANG_SERVER = XQConfigs.SERVER_CONFIG_PREVIEW_URL
end
-- GET
local XIAOQIANG_UPGRADE = "/rs/grayupgrade"
local XIAOQIANG_ECHOS = "/rs/grayupgrade/v2/r01"
local XIAOQIANG_RECOVERY_UPGRADE = "/rs/grayupgrade/recovery"
local XIAOQIANG_DEVICELIST = "/s/admin/deviceList"
local XIAOQIANG_ADMINLIST = "/s/device/adminList"
-- POST
local XIAOQIANG_REGISTER = "/s/register"
local XIAOQIANG_PROMOTE = "/s/admin/promote"
local XIAOQIANG_DISMISS = "/s/admin/dismiss"
local XIAOQIANG_PLUGIN_ENABLE = "/s/plugin/enable"
local XIAOQIANG_PLUGIN_DISABLE = "/s/plugin/disable"
local XIAOQIANG_PLUGIN_LIST = "/s/plugin/list"
local XIAOQIANG_PLUGIN_DETAIL = "/s/plugin/detail"
local XIAOQIANG_UPDATE_DEVICENAME = "/s/device/name"

function getDeviceId()
    local LuciUtil = require("luci.util")
    local deviceId = LuciUtil.exec(XQConfigs.XQ_DEVICE_ID)
    if XQFunction.isStrNil(deviceId) then
        deviceId = ""
    end
    return LuciUtil.trim(deviceId)
end

function checkEcosUpgrade(version, channel, sn, countryCode)
    local LuciJson = require("json")
    local params = {
        {"version", version},
        {"hardware", "r01"},
        {"channel", channel},
        {"filterID", sn},
        {"countryCode", countryCode}
    }
    local query = {}
    table.foreach(params, function(k, v) query[v[1]] = v[2] end)
    local queryString = LuciProtocol.urlencode_params(query)
    local subUrl = XIAOQIANG_ECHOS.."?"..queryString
    local requestUrl = cryptUrl(XIAOQIANG_SERVER, subUrl, params, DEFAULT_TOKEN)
    local response = XQHttpUtil.httpGetRequest(requestUrl)
    if response.code ~= 200 then
        return false
    end
    local resultjson
    local function decode(str)
        resultjson = LuciJson.decode(str)
    end
    if not pcall(decode, response.res) then
        return false
    end
    if not resultjson then
        return false
    end
    if tonumber(resultjson["code"]) == 0 then
        local result = {}
        if resultjson.data and resultjson.data.upgradeInfo and resultjson.data.upgradeInfo.link then
            result["needUpdate"] = 1
            result["downloadUrl"] = resultjson.data.upgradeInfo.link
            result["fullHash"] = resultjson.data.upgradeInfo.hash
            result["fileSize"] = resultjson.data.upgradeInfo.size
            result["version"] = resultjson.data.upgradeInfo.toVersion
            result["description"] = resultjson.data.upgradeInfo.description
        else
            result["needUpdate"] = 0
        end
        return result
    else
        return false
    end
end

function checkUpgrade()
    local LuciJson = require("json")
    local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
    local XQPreference = require("xiaoqiang.XQPreference")
    local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
    local XQCountryCode = require("xiaoqiang.XQCountryCode")
    local misc = XQSysUtil.getMiscHardwareInfo()
    local isrecovery = misc.recovery == 1 and true or false
    local params = {}
    if isrecovery then
        local configs = XQSysUtil.getNvramConfigs()
        params = {
            {"deviceID", ""},
            {"rom", configs.rom_ver},
            {"hardware", XQSysUtil.getHardware()},
            {"cfe", configs.uboot},
            {"linux", configs.linux},
            {"ramfs", configs.ramfs},
            {"sqafs", configs.sqafs},
            {"rootfs", configs.rootfs},
            {"channel", configs.rom_channel},
            {"serialNumber", XQFunction.nvramGet("SN", "")}
        }
    else
        params = {
            {"deviceID", getDeviceId()},
            {"rom", XQSysUtil.getRomVersion()},
            {"hardware", XQSysUtil.getHardware()},
            {"cfe", XQSysUtil.getCFEVersion()},
            {"linux", XQSysUtil.getKernelVersion()},
            {"ramfs", XQSysUtil.getRamFsVersion()},
            {"sqafs", XQSysUtil.getSqaFsVersion()},
            {"rootfs", XQSysUtil.getRootFsVersion()},
            {"channel", XQSysUtil.getChannel()},
            {"countryCode", XQCountryCode.getCurrentCountryCode()},
            {"locale", XQCountryCode.getCurrentJLan()},
            {"serialNumber", getSN() or ""}
        }
    end
    local query = {}
    table.foreach(params, function(k, v) query[v[1]] = v[2] end)
    local queryString = LuciProtocol.urlencode_params(query)
    local subUrl = (isrecovery and XIAOQIANG_RECOVERY_UPGRADE or XIAOQIANG_UPGRADE).."?"..queryString
    local requestUrl = cryptUrl(XIAOQIANG_SERVER, subUrl, params, DEFAULT_TOKEN)
    local response = XQHttpUtil.httpGetRequest(requestUrl)
    if response.code ~= 200 then
        return false
    end
    local resultjson
    local function decode(str)
        resultjson = LuciJson.decode(str)
    end
    if not pcall(decode, response.res) then
        return false
    end
    if not resultjson then
        return false
    end
    if tonumber(resultjson["code"]) == 0 then
        local result = {}
        if resultjson.data and resultjson.data.link then
            local changeLog = XQFunction.parseEnter2br(luci.util.trim(resultjson.data.description))
            local weight = tonumber(resultjson.data.weight)
            result["needUpdate"] = 1
            result["downloadUrl"] = resultjson.data.link
            result["fullHash"] = resultjson.data.hash
            result["fileSize"] = resultjson.data.size
            result["version"] = resultjson.data.toVersion
            result["weight"] = weight or 1
            result["changelogUrl"] = resultjson.data.changelogUrl
            result["changeLog"] = changeLog
        else
            local messageBox = require("xiaoqiang.module.XQMessageBox")
            messageBox.removeMessage(1)
            local changeLog = ""
            if resultjson.data and resultjson.data.description then
                changeLog = XQFunction.parseEnter2br(luci.util.trim(resultjson.data.description))
            end
            result["needUpdate"] = 0
            result["version"] = XQSysUtil.getRomVersion()
            result["changeLog"] = changeLog
        end
        return result
    else
        return false
    end
end

function generateSignature(method,url,params,security)
    local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
    local str = ""
    if params and #params > 0 then
        table.sort(params, function(a, b) return a[1] < b[1] end)
        table.foreach(params, function(k, v) str = str..v[1].."="..v[2].."&" end)
    end
    str = str..security
    if not XQFunction.isStrNil(url) then
        str = url.."&"..str
    end
    if not XQFunction.isStrNil(method) then
        str = string.upper(method).."&"..str
    end
    return XQCryptoUtil.hash4SHA1(str)
end

function doRequest(method,url,param,uuid)
    local LuciJson = require("json")
    local XQCrypto = require("xqcrypto")
    local LuciUtil = require("luci.util")
    local XQLog = require("xiaoqiang.XQLog")
    local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
    local passport = getPassport(uuid)
    method = string.upper(method)
    if not passport then
        XQLog.log(3,"XQRequest: Passport missing "..url)
        return false
    end
    local nonce = XQCrypto.generateNonce()
    local cookies = {}
    local encrypt = {}
    local plain = {}
    local params = {}
    cookies["userId"] = passport.uuid
    cookies["serviceToken"] = passport.stoken
    local sessionSecurity = XQCrypto.generateSessionSecurity(nonce,passport.ssecurity)
    local paramStr = ""
    if param and type(param) == "table" then
        table.sort(param, function(a, b) return a[1] < b[1] end)
        for _,item in ipairs(param) do
            table.insert(plain,item)
        end
    else
        param = {}
    end
    local rc4HashPre = generateSignature(method,url,plain,sessionSecurity)
    table.insert(param,{"rc4_hash__",rc4HashPre})
    table.sort(param, function(a, b) return a[1] < b[1] end)
    for _,item in ipairs(param) do
        paramStr = paramStr..item[2]..";;"
    end
    local paramEncStr = XQCrypto.encryptParams(sessionSecurity,string.sub(paramStr,1,-3))
    local paramsEnc = LuciUtil.split(paramEncStr,";;")
    if paramsEnc and #paramsEnc > 0 then
        for i,item in ipairs(param) do
            table.insert(encrypt,{item[1],paramsEnc[i]})
            table.insert(params,{item[1],paramsEnc[i]})
        end
    end
    local rc4Hash = ""
    local signature = generateSignature(method,url,encrypt,sessionSecurity)
    for _,item in ipairs(encrypt) do
        if item[1] == "rc4_hash__" then
            rc4Hash = item[2]
        end
    end
    table.insert(params,{"signature",signature})
    table.insert(params,{"_nonce",nonce})
    table.insert(params,{"rc4_hash__",rc4Hash})
    local query = {}
    table.foreach(params, function(k, v) query[v[1]] = v[2] end)
    local queryString = LuciProtocol.xq_urlencode_params(query)
    local response
    if method == "GET" then
        response = XQHttpUtil.httpGetRequest(XIAOQIANG_SERVER..url, queryString, cookies)
    elseif method == "POST" then
        response = XQHttpUtil.httpPostRequest(XIAOQIANG_SERVER..url, queryString, cookies)
    end
    if response.code == 200 then
        local jsonResult = XQCrypto.decryptResult(sessionSecurity,response.res)
        if not XQFunction.isStrNil(jsonResult) then
            jsonResult = string.gsub(jsonResult,"u201c","\"")
            jsonResult = string.gsub(jsonResult,"u201d","\"")
            XQLog.log(7,"XQRequest succeed:"..jsonResult)
            return LuciJson.decode(jsonResult)
        end
    elseif response.code == 401 then
        XQLog.log(3,"XQRequest 401:"..XIAOQIANG_SERVER..url,"QueryString:"..queryString,params)
        return {code = 401}
    end
    XQLog.log(3,"XQRequest Failed:"..XIAOQIANG_SERVER..url,"QueryString:"..queryString,params)
    return false
end

-- function routerRegister(uuid)
--     local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
--     local param = {}
--     local d = XQFunction.mattool_identify_device()
--     if XQFunction.isStrNil(d) then
--         return false
--     end
--     local deviceName = XQSysUtil.getRouterName()
--     table.insert(param,{"d",d})
--     table.insert(param,{"deviceName",deviceName})
--     local result = doRequest("POST",XIAOQIANG_REGISTER,param,uuid)
--     return result
-- end

-- function promoteAccount(uuid,account)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(account) then
--         return false
--     end
--     table.insert(param,{"account",account})
--     table.insert(param,{"deviceID",deviceID})
--     local result = doRequest("POST",XIAOQIANG_PROMOTE,param,uuid)
--     return result
-- end

-- function dismissAccount(uuid,account)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(account) then
--         return false
--     end
--     table.insert(param,{"account",account})
--     table.insert(param,{"deviceID",deviceID})
--     local result = doRequest("POST",XIAOQIANG_DISMISS,param,uuid)
--     return result
-- end

-- function getAdminList(uuid)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) then
--         return false
--     end
--     table.insert(param,{"deviceID",deviceID})
--     local result = doRequest("GET",XIAOQIANG_ADMINLIST,param,uuid)
--     return result
-- end

-- function getUserDeviceList(uuid)
--     local result = doRequest("GET",XIAOQIANG_DEVICELIST,nil,uuid)
--     return result
-- end

-- function pluginEnable(uuid,pluginId)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(pluginId) then
--         return false
--     end
--     table.insert(param,{"deviceID",deviceID})
--     table.insert(param,{"pluginID",pluginId})
--     local result = doRequest("POST",XIAOQIANG_PLUGIN_ENABLE,param,uuid)
--     return result
-- end

-- function pluginDisable(uuid,pluginId)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(pluginId) then
--         return false
--     end
--     table.insert(param,{"deviceID",deviceID})
--     table.insert(param,{"pluginID",pluginId})
--     local result = doRequest("POST",XIAOQIANG_PLUGIN_DISABLE,param,uuid)
--     return result
-- end

-- function pluginList(uuid)
--     local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
--     local param = {}
--     local deviceID = getDeviceId()
--     local romVersion = XQSysUtil.getRomVersion()
--     local hardwareNum = XQSysUtil.getHardware()
--     if XQFunction.isStrNil(deviceID) then
--         return false
--     end
--     table.insert(param,{"deviceID",deviceID})
--     table.insert(param,{"rom",romVersion})
--     table.insert(param,{"hardware",hardwareNum})
--     local result = doRequest("GET",XIAOQIANG_PLUGIN_LIST,param,uuid)
--     return result
-- end

-- function pluginDetail(uuid,pluginId)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(pluginId) then
--         return false
--     end
--     table.insert(param,{"pluginID",pluginId})
--     local result = doRequest("GET",XIAOQIANG_PLUGIN_DETAIL,param,uuid)
--     return result
-- end

-- function updateDeviceName(uuid,deviceName)
--     local param = {}
--     local deviceID = getDeviceId()
--     if XQFunction.isStrNil(deviceID) or XQFunction.isStrNil(deviceName) then
--         return false
--     end
--     table.insert(param,{"deviceID",deviceID})
--     table.insert(param,{"deviceName",deviceName})
--     local result = doRequest("POST",XIAOQIANG_UPDATE_DEVICENAME,param,uuid)
--     return result
-- end

