cswamp api

一、协议规范

1.1 请求

  • 当请求中没有二进制数据时。
    json格式数据
  • 当请求中含有二进制数据时。
    4+json格式数据+二进制数据+20字节的二进制数据SHA1
  • 每个请求中都有version、nonce字段
    字段类型 
    versionstringapp正使用的Rose版本。示例:1.0.9-20210516。server内部有一个能支持的最低Rose版本。一旦app的Rose版本低于那个版本,应答返回-2(app版本太低,server不支持)。如果version不是x.x.x-xxxxxxxx(x全是数字)格式, 报ParamError。
    nonceint一个整型随机数。server的应答也须有这同名、同值字段。以便app通过它们判断这是一对请求、应答

1.2 应答

字段类型 
codeint成功、失败时都必须包含。值0表示成功,负数表示失败。不能出现正数。
msgstring成功、失败时都必须包含。用英文描述的处理结果。
nonceint成功、失败时都必须包含。值等于client请求中的nonce(一个整型随机数)。
resultsobject在成功时必须包含,失败时则禁止出现。服务端中的被调用方法决定了该成员的值。

失败示例

{"code":-7,"msg":"password error", "nonce": 13778}

1.3 code值

enumcode 
Success0成功
ParamError-1参数(字段)值错误
ClientVersionTooLow-2app版本太低,server不支持
InvalidDeiveSession-5http sessionid错误
UserNotExisted -6用户不存在
PasswordError-7密码错误
SignError-10SHA1签名不匹配
FileNotExisted-11文件不存在
RequestNotSupported-15server不支持该命令
AuthorizationError-16该用户存在,但没有授权访问

如果错误情形不在上面的,可自加一个负数的code值。

二、命令

2.1 下载小程序

  • 请求URL。
    http://ip:port/cswamp/device/getapplet
  • 请求方式。
    POST
  • 不需要已登录

请求

参数必选类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
typeyesstringdistribution/development。distribution:Applet Store中的小程序。development:个人中心/小程序中的小程序,如果Applet Store中已经是最新的,返回错误FileNotExisted(-11)。
bundleidyesstring该小程序绑定的Bundle ID。 示例:aplt.leagor.blesmart

应答

 字节数 
json长度4后面json数据字节数(大端序)
json数据 见底下json数据
二进制数据块rsp的文件长度*.rsp文件
SHA1签名20二进制数据块的SHA1签名

json数据(results)

参数必选类型说明
nameyesstring小程序名称
titleyesstring小程序名称(留它是为和以前版本兼容,过段时间再删)
subtitleyesstring小程序副标题
timeyestimestamp秒。distribution:小程序在商店开售时间。development:小程序上传时间
usernameyesstring小程序开发者
rspfsizeyesint二进制数据中*.rsp字节数
appyesstring该小程序能运行在的app。语义等同findapplet应答中的app字段。

 

2.2 搜索小程序

  • 请求URL。
    http://ip:port/cswamp/device/findapplet
  • 请求方式。
    POST
  • 需要/不需要已登录

只在Applet Store中搜索。

请求

参数必选类型说明

version

yesstring见“1.1 请求”

nonce

yesint见“1.1 请求”

sessionid

nostringlogin时返回的sessionid

app

nostring

值:launcher或kdesktop。1)sessionid不空时,要得该人名下和该app关联的、该人的名下小程序。2)sessionid空时,app可以是空,如果不空,搜索条件上小程序还需能在该app运行,并且client最多只会传一个,即不是launcher就是kdesktop。

maxapplets

noint指示只返回最前面的maxapplets个小程序。maxapplets不在[1, 30]范围时,强制认为30。
bundleidsnostring小程序Bundle ID,多个时用逗号分隔。
namenostring小程序名称。一旦不为空,名称中需含有name字符串。

依sessionid是否为空,分两情况。

  • sessionid不空时,sessionid必须是一个正有效的sessionid,此时app不能为空,忽略maxapplets、bundleids、name。目的是得到该用户名下、该类app的小程序。什么是该用户名下、某类app的小程序,见“2.5 同步小程序列表”。
  • sessionid为空时,此时须检查app、maxapplets、bundleids、name。bundleds、name是两个条件,当中至少有一个不能为空,当两个都不空时,总条件是逻辑与。bundleids不为空时,返回那些小程序。如果此时name也不为空,这些小程序名称都需要含有name字符串。如果app同时不为空,查到的小程序还需要能在这app运行。(旧版本:sessionid为空时,此时须检查maxapplets、bundleids、name,忽略app。bundleds、name是两个条件,当中至少有一个不能为空,当两个都不空时,总条件是逻辑与。bundleids不为空时,返回那些小程序。如果此时name也不为空,这些小程序名称都需要含有name字符串。)

应答(json数据(results))

count:实际搜索到满足条件的小程序数目。

{
  "code": 0,
  "msg": "success",
  "nonce": 13778,
  "results": {
    "count": 34
    "applets": [{
       "bundleid": "aplt.leagor.blesmart",
       "name": "BLE Smart",
       "subtitle": "BLE测试工具",
       "time": 1622509363,
       "username": "兰栖科技",
       "rspfsize": 15949608,
       "version": "1.0.2-20210131"
       ……
     }]
  }
}
参数必选类型说明
bundleidyesstring小程序bundleid
nameyesstring小程序名称
subtitleyesstring小程序副标题
timeyestimestamp秒。distribution:小程序在商店开售时间。
usernameyesstring小程序开发者
rspfsizeyesint该小程序*.rsp的文件字节数
versionyesstring该小程序版本。示例:1.0.9-20210516
roseversionyesstring该小程序基于的Rose版本。示例:1.0.8
appyesstring该小程序能运行在的app,多个时逗号隔开。示例:launcher,kdesktop

 

2.3 上传文件

  • 请求URL
    http://ip:port/cswamp/device/uploadfile
  • 请求方式
    POST
  • 需要登录/不需要已登录

请求

 字节数 
json长度4后面json数据字节数(大端序)
json数据 见底下json数据
二进制数据块json块中size值文件内容
SHA1签名20二进制数据块的SHA1签名

json数据

参数必选类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”。注1。
sessionidoptstring须要登录后才能上传的文件时,必须提供。login时返回的sessionid
fileyesstring文件。注2
offsetyesint此次要传输的开始偏移。注3
sizeyesint此次要上传的字节数
endyesbooltrue:后面已没有文件数据,可关闭。false:后面还会有该文件数据。注4

注1。除公用功能之外,此命令中的nonce还一个作用:传输同一个文件时,会用同一个noce值。如果nonce不同,即使是offset都接上了,那也不能认为是一个文件。

注2。file指示要传什么文件。文件可能是哪平台下哪app的升级包。后面还会有用户地图、定时任务、小程序等。

filesessionid功能说明文件说明
launcher.android不须要android平台launcher升级包 *.rsp。Tag3-L4=2,android apk
kdesktop.android不须要android平台kdesktop升级包*.rsp。Tag3-L4=2,android apk

注3。offset值是0时,先把同名文件清空,打开,写入数据。非0时,要同时满足三个条件才算正确:同名文件需存在、nonce和之前一样、已有长度是offset,一旦有一个不满足,不必等待,返回一个用response_code指示错误的应答。

注4。server一旦处理完一个end=false请求,溢出时间设为30秒,如果30秒后没有收到下一个uploadfile,认为上传此次上传文件失败。

 

应答(results)

参数必选类型说明
    

 

2.4 下载文件

  • 请求URL
    http://ip:port/cswamp/device/downloadfile
  • 请求方式
    POST

请求

参数必选类型说明
versionyesstring见“1.1 请求”
nonce yesint见“1.1 请求”
sessionidoptstring须要登录后才能上传的文件时,必须提供。login时返回的sessionid
fileyesstring文件。见“2.3 上传文件”中的file
offsetyesint此次要传输的开始偏移。
sizeyesint此次要传输的字节数

应答

 字节数 
json长度4后面json数据字节数(大端序)
json数据 见底下json数据
二进制数据块<=req.size当文件中字节小于请求中的size时,只返回实际剩余字节
SHA1签名20二进制数据块的SHA1签名

json数据(results object)

参数必选类型说明
fsizeyesint此文件长度。不是请求中的size

req.offset == fsize时,不必传“二进制数据块”和SHA1签名,但json数据还是按成功时填充。

如果server没法传输数据,像该文件不存在,参数req.offset超过文件长度等,不必传“二进制数据块”和SHA1签名,json部分指示错误。

 

2.5 登录

  • 请求URL
    http://ip:port/cswamp/device/login
  • 请求方式
    POST
  • 需要/不需要已登录

设备登录。

请求

参数必选类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
typeyesstringpassword/cookie
usernameyesstring用户名
passwordyesstringpassword:密码。cookie:上次login时返回的pwcookie
deviceidyesstring设备唯一标识。值是32个字符的uuid。可以这么认为,只要是同一台设备,这个值总是一样的。
devicenameyesstring登录时设备易记名。示例:iOS(kDesktop)、Android设备。cswamp不解析,原样存储。

登录示例。用户名:test,密码:123456。

  1. [机器人]test在机器人(launcher)手工输入密码的方式登录。发向cswamp的login请求中,deviceid:a11ee49e9fe14e72a295e94d3263af73,devicename:launcher(Android),type:password。
  2. [cswamp]收到这个请求,判断password是否正确。一旦正确,生成两个uuid,一个是sessionid,一个是pwcookie。同时生成一条以a11ee49e9fe14e72a295e94d3263af73(deviceid)为key的登录记录。
  3. [机器人]收到应答,把pwcookie存储在本地配置文件preferences,它将作为后绪cookie方式时的登录密码。
  4. [机器人]发生重启。
  5. [机器人]自动登录。发向cswamp的login请求中,deviceid:a11ee49e9fe14e72a295e94d3263af73,devicename:launcher(Android),type:cookie,password:填preferences文件中的pwcookie,即上次login收到的pwcookie。
  6. [cswamp]收到这个请求,以a11ee49e9fe14e72a295e94d3263af73(deviceid)为key在登录记录表中搜索,发现表中有以收到的pwcookie为key的记录,认为正确,可以登录。并生成两个uuid,一个是sessionid,一是个pwcookie。同时修改这条以a11ee49e9fe14e72a295e94d3263af73(deviceid)为key的登录记录,像pwcookie、最后登录时间。
  7. [iPhone]test在控制端手机(kdesktop)手工输入密码的方式登录。发向cswamp的login请求中,deviceid:3cc51905c1a64d8a89fb981f6ea35d86,devicename:kdesktop(iOS),type:password。
  8. [cswamp]收到这个请求,判断password是否正确,并生成两个uuid,一个是sessionid,一是个pwcookie。同时生成一条以3cc51905c1a64d8a89fb981f6ea35d86(deviceid)为key的登录记录。——至此,test这个用户已有两条登录记录,而且这两条是同时有效,即这两个sessionid要同时有效。

登录这么复杂,主要是两个原因。

  1. 为安全,设备端禁止存储密码到文件。为解决这问题,自动登录改用pwcookie。由于pwcookie和密码没任何关系,即使别人拿到它也猜不出密码。为更安全,每次login后,pwcookie都要变一次。这样pwcookie真泄露了,本人很快能通过login操作让泄露的pwcookie失效。
  2. 同一个用户名会同时在多个设备上正登录着。而且同时登录,会是个普遍现象。

cswamp在“个人中心”——“App”页,提供显示、清除登录记录功能。需要这功能,有三个原因。

  1. 设备和deviceid之间不是真的唯一。deviceid即使和某一硬件绑定,像网卡MAC地址,也会发生维修换了网卡。Rose生成devcieid没关联硬件,是判断配置文件pereferences是否存在。不存在时,用操作系统api生成一个uuid。由于只要不卸载app,pereferences就会一直存在,deviceid也就一直不变了。但是,万一app卸载又重装,这设备就会生成新uuid,针对这设备,cswamp的登录记录表就有了两个deviceid。
  2. deviceid+pwcookie可能泄露。泄露会造成何样影响分两种情况。第一种,原用户test继续用该deviceid。这时test的login操作会自动使泄露的deviceid+pwcookie无效,相对来说恶果要小些。第二种,test不再用该deviceid。这时泄露的deviceid+pwcookie将一直有效。别人就可用它持续获得test私有信息,甚至篡改数据。
  3. 用户一旦发现数据有异常,通过查看登录记录,可判断是否有人入侵过,并自行清除。一旦清除所有登录记录,意味着设备都要进行一次密码登录。

在“App”页,同时可查看本用户名下的launcher、kdesktop类的小程序列表。

应答(json数据(results))

参数必选类型说明
sessionidyesstringcswample生成的、唯一指示此次登录的sessionid
pwcookieyesstringapp后绪以cookie方式登录时,填写的password
    

2.6 退出登录

  • 请求URL
    http://ip:port/cswamp/device/logout
  • 请求方式
    POST
  • 需要已登录

退出登录。cswamp在登录记录表中删除此次deviceid为key的记录。

请求

参数必选类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring 

应答(json数据(results))

参数必选类型说明
    
    

 

2.7 同步小程序列表

  • 请求URL
    http://ip:port/cswamp/device/syncappletlist
  • 请求方式
    POST
  • 需要已登录

向server上的小程序列表添加、删除小程序。对每种app,server需各维护一个列表。目前两种app,字符串标识分别是launcher、kdesktop,应而需维护两个小程序列表。

为什么每种app各需一个?假设aplt.leagor.pan是个机器人底盘驱动小程序,launcher(机器人)会安装,(kdesktop)iphone控制端则不会,安装了也用不了。而这两个设备可能登录的是同一个用户名test。于是test在机器人登录时,那它下的launcher列表将包含aplt.leagor.pan这个小程序;iphone上登录时,下的kdesktop列表则不包含它。

请求

参数必选类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring 
appyesstringlauncher或kdesktop
addnostring要添加的小程序bundleid。是多个时,中间用逗号隔开
removenostring要移除的小程序bundleid。是多个时,中间用逗号隔开

add、remove可能都为空,此时client只是想快速得到该人、该app下小程序的bundleid列表。

应答(json数据(results))

参数必选类型说明
appletyesstring经过此次操作后,该人、该app下、且正存在于商店的小程序bundleid,bundleid之间用逗号隔开。client可能add了错误bundleid、该bundleid可能已下架,要剔除

 

2.8 添加事件

事件是什么?设想下机器人在超市巡检,发现商品摆放异位,为提醒,要把“现场图像加文字描述”发到管理员手机,这里的现场图像+文字描述就是事件。在内容上,事件就是图片加一句文字描述。在一事件,可能有多张图像。

在判断事件是否有效上,机器人名称(devicename)不能超过48字节,文字描述(desc)不能超过512字节,总图像字节数不能超过5M。

在cswamp,事件最多存储两天,即48小时。(第二阶段,在个人中心有个“事件”入口,第一步先可以看到已有事件数)。

  • 请求URL
    http://ip:port/cswamp/device/addevent
  • 请求方式
    POST
  • 需要登录

请求

 字节数 
json长度4后面json数据字节数(大端序)
json数据最多1M字节见底下json数据
二进制数据块 json块中imagesize值图像内容
SHA1签名20/0(图像内容是0字节,即没有二进数据块)二进制数据块的SHA1签名

json数据

字段必填类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring须要登录后才能添加事件。login时返回的sessionid
timeyestimestamp事件发生的时间
devicenameyesstring产生事件的机器人名称。一旦超过48字节,认为此个事件无效,返回错误
descyesstring事件关联的描述性文字。一旦超过512字节,认为此个事件无效,返回错误
imagesizeyesint事件关联图像的总字节数。也是二进制数据块字节数。字节数超过5M,认为此个事件无效,返回错误。
imageformatyesstring图像格式。目前只会两种:png(png格式)、jpeg(jpeg格式)。此事件所有图像会用同一种格式。当imagesize=0时,也会传。
imagesyesarray事件关联图像。当imagesize=0时,也会传,值是空数组,即“[]”。
{
    "version": "1.0.9-20241112",
    "nonce": 32,
    "sessionid": "dc8d64d546d36b8d8413c2cb81552f18"
    "time": 1525827441
    "devicename": "益民超市"
    "desc": "商品摆放异位"
    "imageformat": "jpeg"
    "imagesize": 266708
    "images": [{
         "desc": "A区",
         "offset": 0,
         "size": 110932,
    }
    {
         "desc": "B区",
         "offset": 110923,
         "size": 155785,
    }]
}
字段必填类型说明
descyesstring此个图像相关描述,像发生位置。一旦超过512字节,认为此个事件无效,返回错误
offsetyesint此个图像在二进制数据区块内的偏移
sizeyesint此个图像数据的字节数。

 

应答(json数据(results))

字段必填类型说明

 

2.9 心跳

  • 请求URL
    http://ip:port/cswamp/device/keepalive
  • 请求方式
    POST
  • 需要登录

机器人把事件发向cswamp,那手机如何从cswamp得到事件。如果要做到手机即时获取,要估计要用上稍微复杂方法。前期为可以使用,用上种“心跳+获取事件”。实现逻辑大致是这样的。

  1. (手机)每隔N秒,像10秒,向cswamp发心跳(keepalive)。
  2. (cswamp)收到心跳请求,返回该用户最新那个事件的发生时间,存储在event_time。
  3. (手机)比较收到的event_time,发现本地已收到的最后事件时间比这个小,认为有发生新的事件,于是向cswamp发获取事件(getevent),并把本地最后一个事件时间放在event_time字段。
  4. (cswamp)收到获取事件请求,把大于event_time的事件放到应答,返回给手机。

请求

字段必填类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring须要登录后才能发心跳。login时返回的sessionid

 

应答(json数据(results))

字段必填类型说明
event_timeyestimestamp该用户最新那个事件的发生时间

 

2.10 获取事件

  • 请求URL
    http://ip:port/cswamp/device/getevent
  • 请求方式
    POST
  • 需要登录

cswamp判断下来,可能发现要回传好多事件,这时返回多少事件,要满足两个要求。

  1. 最多返回20条。
  2. 总计图像部分字节数不能超过5M字节。

请求

字段必填类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring须要登录后才能获取事件。login时返回的sessionid
event_timeyestimestamp得到比这个时间大的那些事件。一般是存储本地的最后那个事件的发生时间。

应答

 字节数 
json长度4后面json数据字节数(大端序)
json数据 见底下json数据
二进制数据块json块中imagesize值图像内容
SHA1签名20/0(图像内容是0字节,即没有二进数据块)二进制数据块的SHA1签名

应答(json数据(results))

字段必填类型说明
countyesint实际搜索到满足条件的事件数目
imagesizeyesint所有事件关联图像的总字节数。也是二进制数据块字节数。
eventsyesarray事件数组。注1

注1。返回的事件(events)填写离请求给的时间(event_time)最近的那几条。举个例子,请求中event_time是10:00:00,现在已是20:00:00,中间有100条事件。距离10:00:00,按时间排序依次是10:00:01、10:00:10、10:00:37、10:00:59……。对图像字节数,只要01、10、37这三条就超过5M了,那events只填01、10这两条,同时count置为100。在手机端,收到此次应答后,看到count是100,而events只有两条,那认为至少还有98条未接收。它就会发出下一个getevent,此个请求中的event_time会置为上次收到、最后一条的10:00:10。

{
    "code": 0,
    "msg": "success",
    "nonce": 13778,
    "results": {
        "count": 34
        "imagesize": 366719
        "events": [{
           "time": 1525827441
           "devicename": "益民超市"
           "desc": "商品摆放异位",
           "images": [{
               "desc": "A区",
               "offset": 0,
               "size": 110932,
           }
           {
               "desc": "B区",
               "offset": 110923,
               "size": 155785,
           }]
        }
        {
            ……
        }]
    }
}

events中每个事件字段:time、desc、images,相关说明见“2.8 添加事件”。因为事件关联图像字节数已放在根下的imagesize,单个event的就不须要imagesize了。

 

2.11 问询上菜进度

  • 请求URL
    http://ip:port/cswamp/device/querytablecooking
  • 请求方式
    POST
  • 需要登录
餐厅
  1.     顾客用人工点菜、或小程序点菜,点菜结果送到cswamp服务器。
  2.     烧菜中。工作人员根据进度,在cswamp提供的界面,修改各菜进度。
  3.     在餐厅,顾客按下餐桌铃,或语音,问询指定餐桌的上菜进度。机器人收到这问询后,向cswamp发问询请求,cswmap返回结果。

请求

参数必填类型说明
versionyesstring见“1.1 请求”
nonceyesint见“1.1 请求”
sessionidyesstring须要登录后才能问询上菜进度。login时返回的sessionid
tableyesint餐桌索引。从0开始。

机器人通过“table”字段告知此次要查询的是哪张餐桌。在机器人端,会让用户维护一个餐桌数组。在生成这个数组时,不会给让设置索引号,而是最先出现是0,后面逐个增1。用户命名餐桌时,可能是从1开始,像“1号桌”、“2号桌”,“1号包厢”,“2号包厢”,这里从0开始,是为和C/Java的数组索引从0开始,保持一致。

同时,在服务器端,用户也会有个餐桌数组,这个索引号就作为这个数组索引。或这或那原因,可能出现机器人、服务器对同一索引餐桌,写着不同名情况,这时机器人说餐桌名时以服务器上的为准,所以此命令的应答要有个餐桌名。

{
    "version": "1.0.9-20241112",
    "nonce": 32,
    "sessionid": "dc8d64d546d36b8d8413c2cb81552f18"
    "table": 3
}

上面这请求问询索引3餐桌的上菜进度,即餐桌数组中第4张餐桌。

应答(json数据(results))

参数必填类型说明
table_nameyesstring餐桌名称。如果请求要求的table不存在,填空。
total_amountnodouble总金额。若该餐桌处于空闲状态,置0。若餐桌不存在,不发送
order_timenotimestamp下单时间。若该餐桌处于空闲状态,置0。若餐桌不存在,不发送
cookingnoarray还未上桌的菜。如果没有,可以不发,或发一个空数组
donenoarray已上桌的菜。如果没有,可以不发,或发一个空数组

如果请求的餐桌不存在,像"table"超过了服务器上餐桌数量,应答不要返回是个错误,而只是把table_name置空。

cooking(未上桌菜)

参数必填类型说明
name yesstring菜名
count yesint该菜还没上桌份数
time yesint预计还有多少时间上菜。单位秒。如果有多份,取最快那份的剩余时间

 

done(已上桌菜)

参数必填类型说明
nameyesstring菜名
countyesint该菜已上桌份数
{
    "code": 0,
    "msg": "success",
    "nonce": 32
    "results": {
        "table_name": "4号桌",
        "total_amount": 56.7
        "order_time": 1525827441
        "cooking": [{
            name: "椒盐虾",
            time: 60,
            count: 1,
        }
        {
            name: "干锅花菜",
            time: 240,
            count: 1,
        }]
        "done": [{
            name: "毛豆",
            count: 2,
        }
        {
            name: "麻婆豆腐",
            count: 1,
        }]
    }
}

浮点数用double类型。

全部评论: 0

    写评论: