launcher、kDesktop已在用LIPDP实现查询、修改IP,代码在<freerdp>/channels/leagor/leagor_ble.cpp。它们传输消息用的方式是蓝牙。
Leagor实现的远程桌面都是直连,中间不会有中转服务器,这时会有个问题,若不知道server的ip,此时要怎么办。还有,如果server没有连网,即没有一个有效的IP地址,怎么给它分配个IP?LIPDP就是为解决这问题引入的协议,它用于查询、修改周围server的IP地址。

一、消息、消息码
server和client之间收发消息。消息由两部分组成,一是4字节的header,二是payload。payload是什么内容由header的msg指定,header中的len指出了payload字节数。
enum {msg_queryip_req = 1, msg_updateip_req, msg_connectwifi_req, msg_removewifi_req, msg_wifilist_req, msg_queryip_resp = 50, msg_wifilist_resp, msg_error_resp };
msg称为消息码,目前存在8种。命名上带“req”后缀,表示这种消息总是client发出,带“resp”则表示server发出,它可能是对client某个req给出的即时应答,也可能是根据自个状态向client发出的消息。
二、地址
消息中有两个字段共同表示地址:af和address。
// value same as socket. x:/Program Files (x86)/Windows Kits/10/Include/10.0.18362.0/shared\ws2def.h // AF=address family enum {LEAGOR_BLE_AF_UNSPEC = 0, // unspecified LEAGOR_BLE_AF_INET = 2, // internetwork: UDP, TCP, etc. (bytes: 4+1) LEAGOR_BLE_AF_INET6 = 23, // Internetwork Version 6 (bytes: 16+1) LEAGOR_BLE_AF_MAX = 255, };
af占一个字节,指示address中存储的地址格式,常见的像ipv4(LEAGOR_BLE_AF_INET)、ipv6(LEAGOR_BLE_AF_INET6)。address存储着地址值。af是ipv4时,address只使用[0..3]字节。举个例子,192.168.1.115,把这4个字节用小端序uint32_t表示的话,值是0x7301a8c0。
即使当前没有有效IP,像一个工作在ipv4的wlan,它的af也需要设置为LEAGOR_BLE_AF_INET,address则设为0。
LEAGOR_BLE_AF_UNSPEC表示address是一个未指定格式的地址。它有个特殊用途,版本协商时,如果af值是LEAGOR_BLE_AF_UNSPEC,意味着server不能匹配此个client要求的版本,发生版本不匹配。
三、queryip_req、版本协商
queryip_req必须是client发出第一个消息,通过该消息,client可以得到server的ip地址。同时该req有版本协商功能。
- client把自个支持的版本号放在“ver”,生成queryip_req,发向server。
- server收到queryip_req,提取出当中版本号client-ver。如果自个不支持这版本号,以自个版本号放ver、af置LEAGOR_BLE_AF_UNSPEC,生成queryip_resp,发向client。
- client收到queryip_resp,发现af字段是LEAGOR_BLE_AF_UNSPEC,认为出现了版本不匹配。后绪不应该再向该server发和修改IP有关的req。
四、修改Wifi实现修改IP
让wifi连向不同ap,相应地就能实现分配出一个有效IP。这个流程大概是这样的。
- client向server发updateip_req。
- server收到updateip_req,让自个进入status_updateip状态,并以当前IP、系统状态、wifi列表生成wifilist_resp,发向client。
- 对server。处在status_updateip状态时,一旦wifi列表有更新,便会向client发wifilist_resp。
- 对client。为节省传输数据量,server可能不是一有点改动就发wifilist_resp,但client可通过发wifilist_req,让server立即把最新的当前IP、系统状态、wifi列表生成wifilist_resp,它向client。
- client已经有了server的wifi列表,想连接某个ap了,以ssid、password为参数向server发connectwifi_req。
- server收到connectwifi_req,执行连接该ap,成功的话就会分配到一个IP地址。
- client已有经有了server的wifi列表,想删除某个ap网络,以ssid为参数,向server发removewifi_req。
- server收到removewifi_req,执行删除指定ap网络。
五、蓝牙密码
想象下这种场景,你家中有个机器人,邻居拿着手机用蓝牙扫到这机器人,并把它连到自个wifi。这么一来,机器人物理上虽然放在你家,但已连到邻居的wifi局域网,邻居控制机器人了。为解决这问题,在邻居要用蓝牙修改wifi时,强制要求输入个密码,它就是蓝牙密码。
蓝牙密码是随着updateip_req发送到server。server收到密码后,和存储着的蓝牙密码进行比较,如果匹配,server进入可修改ip状态(status_updateip)。如果不匹配,server依旧停留在查询ip状态(status_queryip)。
如果client提供的密码错了,须反馈给用户,用的是error_resp。error_resp是条专门向client反馈错误的命令,cmd指示是处理哪条命令时出错,此刻是updateip_req,code是错误码,此刻是leagorerr_blepassword(-1)。