Bluez板载驱动移植全过程

如何实现任意平台BlueZ5驱动移植

一,编译依赖库与必要应用

1,准备编译工作之前,需要了解什么是buildroot,跨平台的库与文件都通过buildroot来实现。

About Buildroot:Buildroot is a tool that simplifies and automates the process of building a complete Linux system for an embedded system, using cross-compilation.

In order to achieve this, Buildroot is able to generate a cross-compilation toolchain, a root filesystem, a Linux kernel image and a bootloader for your target. Buildroot can be used for any combination of these options, independently (you can for example use an existing cross-compilation toolchain, and build only your root filesystem with Buildroot).

Buildroot is useful mainly for people working with embedded systems. Embedded systems often use processors that are not the regular x86 processors everyone is used to having in his PC. They can be PowerPC processors, MIPS processors, ARM processors, etc.

Buildroot supports numerous processors and their variants; it also comes with default configurations for several boards available off-the-shelf. Besides this, a number of third-party projects are based on, or develop their BSP 1 or SDK 2 on top of Buildroot.

Buildroot信息:https://buildroot.org/

Linux下获取链接:

gitclonehttps://git.buildroot.net/buildroot  gitclonegit://git.buildroot.net/buildroot

2,设定对应交叉工具链的Buildroot配置信息(如下以Mstar平台为例)

2.1 配置Target Options

| |                                    Target Architecture (ARM (little endian))  --->                                                  | |  | |                                    Target Binary Format (ELF)  --->                                                                  | |  | |                                    Target Architecture Variant (cortex-A7)  --->                                                    | |  | |                                    Target ABI (EABIhf)  --->                                                                        | |  | |                                    Floating point strategy (VFPv2)  --->                                                            | |  | |                                    ARM instruction set (ARM)  --->

注意选择对应平台的信息!!!

2.2 配置Toolchain(这一步很关键,如果错了会直接影响编译)

+--------------------------------------------------------------- Toolchain ----------------------------------------------------------------+  |  Arrow keys navigate the menu.  <Enter> selects submenus ---> (or empty submenus ----).  Highlighted letters are hotkeys.  Pressing <Y>  | 

  |  selects a feature, while <N> excludes a feature.  Press <Esc><Esc> to exit, <?> for Help, </> for Search.  Legend: [*] feature is      | 

  |  selected  [ ] feature is excluded                                                                                                      | 

  |                                                                                                                                          | 

  | +--------------------------------------------------------------------------------------------------------------------------------------+ | 

  | |                                    Toolchain type (External toolchain)  --->                                                        | | 

  | |                                    *** Toolchain External Options ***                                                                | | 

  | |                                    Toolchain (Custom toolchain)  --->                                                                | | 

  | |                                    Toolchain origin (Pre-installed toolchain)  --->                                                  | | 

  | |                                (/opt/arm-buildroot-linux-uclibcgnueabihf-4.9.4/usr) Toolchain path                                  | | 

  | |                                (arm-buildroot-linux-uclibcgnueabihf) Toolchain prefix                                                | | 

  | |                                    External toolchain gcc version (4.9.x)  --->                                                      | | 

  | |                                    External toolchain kernel headers series (3.18.x)  --->                                          | | 

  | |                                    External toolchain C library (uClibc/uClibc-ng)  --->                                            | | 

  | |                                [*] Toolchain has WCHAR support?                                                                      | | 

  | |                                [ ] Toolchain has locale support?                                                                    | | 

  | |                                [*] Toolchain has threads support?                                                                    | | 

  | |                                [*]  Toolchain has threads debugging support?                                                        | | 

  | |                                [*]  Toolchain has NPTL threads support?                                                            | | 

  | |                                [*] Toolchain has SSP support?                                                                        | | 

  | |                                [*]  Toolchain has SSP strong support?                                                              | | 

  | |                                [ ] Toolchain has RPC support?                                                                        | | 

  | |                                [*] Toolchain has C++ support?                                                                        | | 

  | |                                [ ] Toolchain has D support?                                                                          | | 

  | |                                [ ] Toolchain has Fortran support?                                                                    | | 

  | |                                [ ] Toolchain has OpenMP support?                                                                    | | 

  | |                                [ ] Copy gdb server to the Target                                                                    | | 

  | |                                    *** Host GDB Options ***                                                                          | | 

  | |                                [*] Build cross gdb for the host                                                                      | | 

  | |                                [ ]  TUI support                                                                                    | | 

  | |                                [ ]  Python support                                                                                  | | 

  | |                                [ ]  Simulator support                                               

  | |                                      GDB debugger Version (gdb 8.2.x)  --->                                                          | | 

  | |                                    *** Toolchain Generic Options ***                                                                | | 

  | |                                ()  Extra toolchain libraries to be copied to target                                                  | | 

  | |                                [*] Enable MMU support                                                                                | | 

  | |                                ()  Target Optimizations                                                                              | | 

  | |                                ()  Target linker options                                                                            | | 

  | |                                [ ] Register toolchain within Eclipse Buildroot plug-in                                              | |                               

  |+--------------------------------↓(+)--------------------------------------------------------------------------------------------------+| 

  +------------------------------------------------------------------------------------------------------------------------------------------+ 

  |                                        <Select>    < Exit >    < Help >    < Save >    < Load >                                        | 

  +------------------------------------------------------------------------------------------------------------------------------------------+

注意:

a, 其中Tool Path和Tool Prefix填自己的信息,之后会让你重新配置gcc version和kernel version,依葫芦画瓢就可以了。

b,如出现Cannot execute cross-compile,请核对再三Target Option信息。(笔者亲身经历:前期无法执行交叉工具链的,配置信息有误)

2.3 配置BlueZ5,并执行编译。

clone之后,在buildroot目录下,再次执行

makemenuconfig//查找bluez5在哪?Symbol:BR2_PACKAGE_BLUEZ5_UTILS[=y]|    |Type:bool|    |Prompt:bluez-utils5.x|    |Location:                                                                                                                              |    |->Targetpackages|    | (6)->Networkingapplications|    |Definedatpackage/bluez5_utils/Config.in:1|    |Dependson:BR2_USE_WCHAR[=y]&&BR2_TOOLCHAIN_HAS_THREADS[=y]&&BR2_USE_MMU[=y]&&!BR2_STATIC_LIBS[=n]&&BR2_TOOLCHAIN_HEADERS|    |Selects:BR2_PACKAGE_DBUS[=y]&&BR2_PACKAGE_LIBGLIB2[=y]|    |Selectedby[n]:                                                                                                                      |    |-BR2_PACKAGE_BLUEZ_ALSA[=n]&&!BR2_STATIC_LIBS[=n]&&BR2_TOOLCHAIN_HAS_THREADS_NPTL[=y]&&BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_4[= | 

  |  - BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_BLUEZ [=n]&&BR2_PACKAGE_GSTREAMER1[=n]&&BR2_PACKAGE_GST1_PLUGINS_BAD[=n]&&BR2_USE_WCHAR|    |-BR2_PACKAGE_KODI_BLUEZ[=n]&&BR2_PACKAGE_KODI[=n]&&BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_4[=y]&&BR2_TOOLCHAIN_HAS_SYNC_4[=y]|    |-BR2_PACKAGE_CWIID[=n]&&!BR2_STATIC_LIBS[=n]&&BR2_USE_WCHAR[=y]&&BR2_TOOLCHAIN_HAS_THREADS[=y]&&BR2_USE_MMU[=y]&&BR2_T|    |-BR2_PACKAGE_USSP_PUSH[=n]&&!BR2_STATIC_LIBS[=n]&&BR2_USE_WCHAR[=y]&&BR2_TOOLCHAIN_HAS_THREADS[=y]&&BR2_USE_MMU[=y]&&B|    |-BR2_PACKAGE_SCONESERVER_BLUETOOTH[=n]&&BR2_PACKAGE_SCONESERVER[=n]&&BR2_USE_WCHAR[=y]&&BR2_USE_MMU[=y]&&BR2_TOOLCHAIN_HA|    |-BR2_PACKAGE_BLUEZ_UTILS[=n]&&!BR2_SKIP_LEGACY[=n]&&BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_4[=y]&&BR2_TOOLCHAIN_HAS_SYNC_4[=y]|    |                                                                                                                                          |

选择所需配置:

//当你勾选了bluez-utils5之后,所有的依赖库都会被捆绑在一起。//这里我只用bluez5实现ble slave,故没有选取过多设置,可以按需选取| |                                [*] bluez-utils 5.x                                                                                  | | 

  | |                                [ ]  build OBEX support                                                                              | | 

  | |                                [*]  build CLI client                                                                                | | 

  | |                                [*]    install deprecated tool                                                                      | | 

  | |                                [ ]  build experimental obexd plugin                                                                | | 

  | |                                [ ]  build health plugin                                                                            | | 

  | |                                [ ]  build midi profile                                                                              | | 

  | |                                [ ]  build nfc plugin                                                                                | | 

  | |                                [ ]  build sap plugin                                                                                | | 

需要说明的是,buildroot这点做的真的挺傻瓜式操作,一键式捆绑动作。免去了所有麻烦!!!

由于我勾选了rootfs,所以make之后回生成rootfs

>>>  Generating filesystem image rootfs.tar

检查一下Output是否有输出bluez的一系列安装包。

root@ubuntu:/home/cheng/buildroot/buildroot# ls output/build/alsa-lib-1.2.1.2host-attr-2.4.48host-libtool-2.4.6host-pkgconf-1.6.1libffi-3.3skeletonalsa-utils-1.2.1host-autoconf-2.69host-libzlib-1.2.11host-python3-3.8.2libglib2-2.62.4skeleton-init-common**bluez5_utils-5.52**  host-automake-1.15.1host-lz4-1.9.2host-python3-setuptools-41.4.0libiconv-1.15skeleton-init-sysvbluez-alsa-2.1.0host-dbus-1.12.16host-lzo-2.10host-skeleton                  libsndfile-1.0.28toolchainbuildroot-config  host-dbus-glib-0.110host-m4-1.4.18host-squashfs-4.4libzlib-1.2.11toolchain-externalbuildroot-fs      host-expat-2.2.9host-makedevs        host-util-linux-2.35.1ncurses-6.1toolchain-external-custombuild-time.log    host-fakeroot-1.20.2host-meson-0.53.1host-xz-5.2.4packages-file-list-host.txt    zlibbusybox-1.31.1host-gdb-8.2.1host-mkpasswd        host-zlib                      packages-file-list-staging.txtdbus-1.12.16host-gettext                                                host-ncurses-6.1host-zstd-1.4.3packages-file-list.txtdbus-glib-0.110host-gettext-tiny-adaa9c64921e80f2b8dd3610ffb508618b9204f3  host-ninja-1.10.0initscripts                    pcre-8.43expat-2.2.9host-libffi-3.3host-patchelf-0.9libbsd-0.10.0readline-8.0host-acl-2.2.53host-libglib2-2.62.4host-pcre-8.43libedit-20190324-3.1sbc-1.4

确认OK后,就完成了编译工作!

第六点会给出详细地如何替换自己想要的bluez版本的方式!

如需要strip,可以在build option下勾选上,以达到节省空间的要求。

二,移植对应所需配置文件以及依赖库

1,确定板载所需要的配置文件以及库

//对应bin文件:bluetoothd  dbus-daemon  hciconfig//其中bluetoothd  dbus-daemon为bluetooth进程和dbus守护进程,这两部分可以在bluez5_utils-5.52和dbus-1.12.16里面找到。//对应lib:libdbus-1.so.3libexpat.so.1libglib-2.0.so.0libiconv.so.2libintl.so  libncursesw.so.6libpcre.so.1libreadline.so.8//这部分已经做了相应的精简,具体到每一个文件都不可以落下//对应dbus配置文件:etc/: bluetooth.conf  session.conf system.confusr/share: dbus-1glib-2.0这里是渔!!!root@ubuntu:/home/cheng/buildroot/buildroot#  find . -name xxxxx*//所有文件与库也可以在生成的rootfs.tar中找到

注意这些库移植从虚拟机到windows、或者到mnt/share时,需要压缩解压缩,否则会出现符号链接异常等问题。

2,确定编译所需要的依赖库

参照上一点中lib,可对应该文件类的所有库都拷贝到对应工具链。

三,准备蓝牙驱动固件以及KO文件

前述:本次使用的是瑞昱Rtl8723du wifi+ble双模芯片,蓝牙类型:USB

1,固件及配置文件:

rtl8723du_configrtl8723du_fw

2,KO文件:

Makefile  rtk_bt.crtk_bt.hrtk_bt.o.ur-safertk_coex.crtk_coex.hrtk_coex.o.ur-safertk_misc.crtk_misc.h//直接make即可Makefile      Module.symversrtk_bt.hrtk_bt.o.ur-safertk_btusb.mod.crtk_btusb.ortk_coex.hrtk_coex.o.ur-safertk_misc.hmodules.orderrtk_bt.crtk_bt.ortk_btusb.kortk_btusb.mod.ortk_coex.crtk_coex.ortk_misc.crtk_misc.o

对应固件放入lib/firmware 即可。

四,准备脚本文件以及编译根文件系统

1,准备启动脚本文件

#!/bin/sh## debug in sd cardinsmod/mnt/sdcard/bluez_bin/rtk_btusb.ko//加载驱动,自载入firmware到rtl8723du中#export LD_LIBRARY_PATH=/mnt/sdcard/bluez_libcp -rf/mnt/sdcard/bluez_lib/var/lib///由于链接了动态库到/var/lib,所以把库都copy到该位置,编译rootfs可把所有都cp -rf bluez_lib/*/lib/mkdir/var/run/dbus//dbus-daemon启动时会动态生成socket file,所以需要在该目录下创建dbus文件夹/mnt/sdcard/bluez_bin/dbus-daemon--system&//启动dbus-daemonsleep 1/mnt/sdcard/bluez_bin/hciconfighci0 up//启动蓝牙sleep 1/mnt/sdcard/bluez_bin/bluetoothd--compat-n  &//启动bluetoothdsleep 1/mnt/sdcard/bluez_bin/hciconfighci0 noscan//双模芯片,主动关闭piscansleep 1/mnt/sdcard/bluez_bin/hciconfighci0 name 'TY'//设置名字sleep 1/mnt/sdcard/bluez_bin/hciconfighci0 down    sleep 1/mnt/sdcard/bluez_bin/hciconfighci0 up//重启蓝牙sleep 2

2,准备rootfs,并烧录Mstar平台

a:将第二点中对应可执行文件拷贝到bin中

b:将第二点中对应lib拷贝到/lib/中

c:将usr和etc文件拷贝到对应位置。

d:烧录rootfs到对应区域。

//确认分区/mnt/mmcblk0p1# cat /proc/mtd dev:size  erasesize  namemtd0:0005000000010000"boot"mtd1:0022000000010000"rootfs"mtd2:0020000000010000"kernel"mtd3:001e000000010000"nvrservice"mtd4:004a000000010000"system"mtd5:004a000000010000"backup"mtd6:0005000000010000"mtd"mtd7:0002000000010000"factory"//烧录rootfs/mnt/mmcblk0p1# flashcp rootfs.squashfs.img /dev/mtd1 -v

五,实现跨平台Demo,验证与测试

1, 确认设备是否可正常运行

//查看设备加载是否成功/mnt/mmcblk0p1 # lsmodrtk_btusb394500- Live0xbf920000(O)//查看进程是否运行正常mnt/mmcblk0p1 # ps2847dbus0:01/mnt/sdcard/bluez_bin/dbus-daemon --system2924root0:00./bluez_bin/bluetoothd --compat -n

2,验证性测试

/mnt/mmcblk0p1 # ./bluez_ble_slave gatt-service unique name: :1.14adddefault_gatt proxyGetPrimary:TrueGetUUID: 1910Exist Includes: 1910GetPrimary:TrueGetUUID: 1920Exist Includes: 1920Registered service: /tuya_service_common_data /tuya_service_bulk_data然后就是手机APP一顿连接.......

3,输出接口库验证

/mnt/mmcblk0p1# ./tuya_ble_lib_test gatt-serviceuniquename::1.16adddefault_gattproxyGetPrimary:TrueGetUUID:1910ExistIncludes:1910GetPrimary:TrueGetUUID:1920ExistIncludes:1920Registeredservice:/tuya_service_common_data/tuya_service_bulk_datatuya_bluez_hci_control_piscan:ioctlfailederr=-1piscan(0,0)error,ret:-95GetPrimary:TrueGetUUID:1920ExistIncludes:1920GattServicedontinitGattServicedontinitGetPrimary:TrueGetUUID:1910ExistIncludes:1910GattServicedontinitGattServicedontinitRegisterApplication:OKtuya_ble_advertising_update:adv->len=28,count=0.tuya_ble_advertising_update:scan_resp->len=30//该测试用例下可以直接用lightblue连接,同时相互透传,验证上下行。//同时可在wifiscan时,验证ble连通性

六,问题总结与梳理

1, 如何更换BlueZ5版本。

root@ubuntu:/home/cheng/buildroot/buildroot# vi package/bluez5_utils/bluez5_utils.mk//更换版本信息################################################################################## bluez5_utils################################################################################## Keep the version and patchesinsyncwithbluez5_utils-headersBLUEZ5_UTILS_VERSION =5.52//更改此处版本信息BLUEZ5_UTILS_SOURCE = bluez-$(BLUEZ5_UTILS_VERSION).tar.xzBLUEZ5_UTILS_SITE = $(BR2_KERNEL_MIRROR)/linux/bluetoothBLUEZ5_UTILS_INSTALL_STAGING = YESBLUEZ5_UTILS_LICENSE = GPL-2.0+, LGPL-2.1+BLUEZ5_UTILS_LICENSE_FILES = COPYING COPYING.LIB//更新Hash值,该网站下有所有Bluez的版本,切换版本会校验Hash值# From https://www.kernel.org/pub/linux/bluetooth/sha256sums.asc:sha256  f7144ce2039202cfac18ccb52426efea11c98e4f6e1bb8041bcb994b8378560a  bluez-5.52.tar.xz

2,问题梳理与说明

【Issue】:is not allowed to own the service "org.bluez" due to security policies in the configuration file

【Issue】:Failed to start message bus: Could not get UID and GID for username "dbus"

该问题主要是dbus权限问题,以及bluetooth.conf配置信息未加载

权限可添加至/etc/passwd

root@ubuntu:/home/cheng/buildroot/buildroot# cat output/target/etc/passwdroot:x:0:0:root:/root:/bin/shdaemon:x:1:1:daemon:/usr/sbin:/bin/falsedbus:x:1000:1000:DBusmessagebususer:/var/run/dbus:/bin/false

以及,bluetooth.conf

root@ubuntu:/home/cheng/buildroot/buildroot# find . -name bluetooth.conf./output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/etc/dbus-1/system.d/bluetooth.conf./output/build/bluez5_utils-5.52/src/bluetooth.conf./output/target/etc/dbus-1/system.d/bluetooth.conf./output/target/etc/dbus-1/system.d/bluetooth.conf//拷贝对那个/etc下dbus-1到对应rootfs目录下

【Issue】:Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory

该问题是因为执行dbus-daemon时,无法在/var/run下创建dbus/system_bus_socket,故运行Bluetoothd的时候无法连接到该socket file。

解决方式:

可提前在/var/run下mkdir dbus,重新运行dbus-daemon的时候会自动生成该文件,继而可以运行bluetoothd。

【说明】:关于bluetoothd的说明

NAMEbluetoothd - Bluetooth daemonSYNOPSISbluetoothd [--version] | [--help]bluetoothd [--nodetach] [--compat] [--experimental] [--debug=<files>] [--plugin=<plugins>] [--noplugin=<plugins>]DESCRIPTIONThis manual page documents brieflythebluetoothd daemon, which manages alltheBluetooth devices. bluetoothd can also provide anumberofservices viatheD-Bus message bus system.OPTIONS-v,--versionPrint bluetoothdversionandexit.-h,--helpPrint bluetoothd optionsandexit.-n,--nodetachEnable logginginforeground. Directslogoutputtothecontrolling terminalinadditiontosyslog.-f,--configfileSpecifies an explicit configfilepathinstead ofrelyingonthedefault path (/etc/bluetooth/main.conf)fortheconfigfile.-d,--debug=<file1>:<file2>:...Sets how much information bluetoothd sendstothelogdestination (usually syslog's"daemon"facility). Ifthefileoptions are omitted,thendebugging informationfromallthesource files are printed. Iffileoptions are present,thenonly debug printsfromthatsourcefileare printed. The option can be a pattern containing"*"and"?"characters.Example:--debug=src/adapter.c:src/agent.c-p,--plugin=<plugin1>,<plugin2>,..Load these plugins only. The option can be a pattern containing"*"and"?"characters.-P,--noplugin=<plugin1>,<plugin2>,..Never load these plugins. The option can be a pattern containing"*"and"?"characters.-C,--compatProvide deprecated command line interfaces.-E,--experimentalEnable experimental interfaces. Those interfaces arenotguaranteedtobe compatibleorpresentinfuture releases.FILES/etc/bluetooth/main.confLocationoftheglobalconfigurationfile.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容