Udev webcam rule read, but not respected?

本文探讨了在Linux环境下,两个USB摄像头设备号在启动时可能出现的切换问题,并提供了解决方案。通过创建udev规则,确保每个摄像头都有固定的设备链接,避免了设备号的不确定性。文章详细记录了udev规则的编写过程,包括参数的选择和规则文件的测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ask Question
Asked 7 years, 1 month ago
Active 6 years, 10 months ago
Viewed 6k times
8

I have two usb-webcams on them machine, but at boot they sometimes switch /dev/video number. The solution to this problem seems to be creating a new udev rule. I have added this rule in
/etc/udev/rules.d/jj-video.rules:
Fix webcam 1

KERNEL==“video1”, SUBSYSTEM==“video4linux”, SUBSYSTEMS==“usb”,
ATTRS{idVendor}“1d6b”, ATTRS{idProduct}“0001”, SYMLINK+=“webcam1”

Fix webcam 2

KERNEL==“video2”, SUBSYSTEM==“video4linux”, ATTR{name}“Logitech
QuickCam Pro 3000”, KERNELS
"0000:00:1d.0", SUBSYSTEMS==“pci”,
DRIVERS==“uhci_hcd”, ATTRS{vendor}“0x8086”,
ATTRS##{device}
“0x2658”, SYMLINK+=“webcam2”

but the webcam symlinks are not created. I have tried many different combinations in this file. The present ones are just my latest attempts.

I found the parameters in:

jjk@eee-old:~$ udevadm info -a -p $(udevadm info -q path -p
/class/video4linux/video1)

Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.

looking at device
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/video4linux/video1’:
KERNEL==“video1”
SUBSYSTEM==“video4linux”
DRIVER==""
ATTR{name}“Logitech QuickCam Pro 3000”
ATTR{index}
“0”
ATTR{button}==“0”

looking at parent device
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0’:
KERNELS==“2-2:1.0”
SUBSYSTEMS==“usb”
DRIVERS==“Philips webcam”
ATTRS{bInterfaceNumber}“00”
ATTRS{bAlternateSetting}
" 9"
ATTRS{bNumEndpoints}“02”
ATTRS{bInterfaceClass}
“0a”
ATTRS{bInterfaceSubClass}“ff”
ATTRS{bInterfaceProtocol}
“00”
ATTRS{supports_autosuspend}==“0”

looking at parent device
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2’:
KERNELS==“2-2”
SUBSYSTEMS==“usb”
DRIVERS==“usb”
ATTRS{configuration}""
ATTRS{bNumInterfaces}
" 3"
ATTRS{bConfigurationValue}“1”
ATTRS{bmAttributes}
“a0”
ATTRS{bMaxPower}“500mA”
ATTRS{urbnum}
“371076”
ATTRS{idVendor}“046d”
ATTRS{idProduct}
“08b0”
ATTRS{bcdDevice}“0002”
ATTRS{bDeviceClass}
“00”
ATTRS{bDeviceSubClass}“00”
ATTRS{bDeviceProtocol}
“00”
ATTRS{bNumConfigurations}“1”
ATTRS{bMaxPacketSize0}
“8”
ATTRS{speed}“12”
ATTRS{busnum}
“2”
ATTRS{devnum}“2”
ATTRS{devpath}
“2”
ATTRS{version}" 1.10"
ATTRS{maxchild}
“0”
ATTRS{quirks}“0x0”
ATTRS{avoid_reset_quirk}
“0”
ATTRS{authorized}“1”
ATTRS{serial}
“01402100A5000000”

looking at parent device ‘/devices/pci0000:00/0000:00:1d.0/usb2’:
KERNELS==“usb2”
SUBSYSTEMS==“usb”
DRIVERS==“usb”
ATTRS{configuration}""
ATTRS{bNumInterfaces}
" 1"
ATTRS{bConfigurationValue}“1”
ATTRS{bmAttributes}
“e0”
ATTRS{bMaxPower}" 0mA"
ATTRS{urbnum}
“34”
ATTRS{idVendor}“1d6b”
ATTRS{idProduct}
“0001”
ATTRS{bcdDevice}“0302”
ATTRS{bDeviceClass}
“09”
ATTRS{bDeviceSubClass}“00”
ATTRS{bDeviceProtocol}
“00”
ATTRS{bNumConfigurations}“1”
ATTRS{bMaxPacketSize0}
“64”
ATTRS{speed}“12”
ATTRS{busnum}
“2”
ATTRS{devnum}“1”
ATTRS{devpath}
“0”
ATTRS{version}" 1.10"
ATTRS{maxchild}
“2”
ATTRS{quirks}“0x0”
ATTRS{avoid_reset_quirk}
“0”
ATTRS{authorized}“1”
ATTRS{manufacturer}
“Linux 3.2.0-29-generic uhci_hcd”
ATTRS{product}“UHCI Host Controller”
ATTRS{serial}
“0000:00:1d.0”
ATTRS{authorized_default}==“1”

looking at parent device ‘/devices/pci0000:00/0000:00:1d.0’:
KERNELS==“0000:00:1d.0”
SUBSYSTEMS==“pci”
DRIVERS==“uhci_hcd”
ATTRS{vendor}“0x8086”
ATTRS{device}
“0x2658”
ATTRS{subsystem_vendor}“0x1043”
ATTRS{subsystem_device}
“0x82d8”
ATTRS{class}“0x0c0300”
ATTRS{irq}
“23”
ATTRS{local_cpus}“ff”
ATTRS{local_cpulist}
“0-7”
ATTRS{dma_mask_bits}“32”
ATTRS{consistent_dma_mask_bits}
“32”
ATTRS{broken_parity_status}“0”
ATTRS{msi_bus}
""

looking at parent device ‘/devices/pci0000:00’:
KERNELS==“pci0000:00”
SUBSYSTEMS==""
DRIVERS==""

jjk@eee-old:~$

And tested the setup:

sudo udevadm --debug test /sys/class/video4linux/video1

main: runtime dir ‘/run/udev’ run_command: calling: test adm_test:
version 175 This program is for debugging only, it does not run any
program, specified by a RUN key. It may show incorrect results,
because some values may be different, or not available at a simulation
run.

parse_file: reading ‘/lib/udev/rules.d/40-crda.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/40-fuse.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/40-gnupg.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/40-hplip.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/40-ia64.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/40-inputattach.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/40-libgphoto2-2.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/40-libsane.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/40-ppc.rules’ as
rules file parse_file: reading
‘/lib/udev/rules.d/40-usb_modeswitch.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/40-xserver-xorg-video-intel.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/42-qemu-usb.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/50-firmware.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/50-udev-default.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/55-dm.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/56-hpmud_support.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/60-cdrom_id.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/60-pcmcia.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/60-persistent-alsa.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/60-persistent-input.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/60-persistent-serial.rules’ as
rules file parse_file: reading
‘/lib/udev/rules.d/60-persistent-storage-dm.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/60-persistent-storage-tape.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/60-persistent-storage.rules’ as
rules file parse_file: reading
‘/lib/udev/rules.d/60-persistent-v4l.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/61-accelerometer.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/64-xorg-xkb.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/66-xorg-synaptics-quirks.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/69-cd-sensors.rules’ as rules
file add_rule: IMPORT found builtin ‘usb_id’, replacing
/lib/udev/rules.d/69-cd-sensors.rules:76 parse_file: reading
‘/lib/udev/rules.d/69-libmtp.rules’ as rules file parse_file: reading
‘/lib/udev/rules.d/69-xorg-vmmouse.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/69-xserver-xorg-input-wacom.rules’ as rules
file parse_file: reading ‘/etc/udev/rules.d/70-persistent-cd.rules’ as
rules file parse_file: reading
‘/etc/udev/rules.d/70-persistent-net.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/70-printers.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/70-udev-acl.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/75-cd-aliases-generator.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/75-net-description.rules’ as
rules file parse_file: reading
‘/lib/udev/rules.d/75-persistent-net-generator.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/75-probe_mtd.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/75-tty-description.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/77-mm-ericsson-mbm.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/77-mm-longcheer-port-types.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/77-mm-nokia-port-types.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/77-mm-pcmcia-device-blacklist.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/77-mm-platform-serial-whitelist.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/77-mm-qdl-device-blacklist.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/77-mm-simtech-port-types.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/77-mm-usb-device-blacklist.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/77-mm-x22x-port-types.rules’ as
rules file parse_file: reading
‘/lib/udev/rules.d/77-mm-zte-port-types.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/77-nm-olpc-mesh.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/78-graphics-card.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/78-sound-card.rules’
as rules file parse_file: reading ‘/lib/udev/rules.d/80-drivers.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/80-mm-candidate.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/80-udisks.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/85-brltty.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/85-hdparm.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/85-hplj10xx.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/85-keyboard-configuration.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/85-regulatory.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/85-usbmuxd.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/90-alsa-restore.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/90-alsa-ucm.rules’
as rules file parse_file: reading ‘/lib/udev/rules.d/90-libgpod.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/90-pulseaudio.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/95-cd-devices.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/95-keyboard-force-release.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/95-keymap.rules’ as rules file
parse_file: reading ‘/lib/udev/rules.d/95-udev-late.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-dell.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-fujitsu.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-gateway.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-ibm.rules’ as rules file
parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-lenovo.rules’ as rules
file parse_file: reading
‘/lib/udev/rules.d/95-upower-battery-recall-toshiba.rules’ as rules
file parse_file: reading ‘/lib/udev/rules.d/95-upower-csr.rules’ as
rules file parse_file: reading ‘/lib/udev/rules.d/95-upower-hid.rules’
as rules file parse_file: reading
‘/lib/udev/rules.d/95-upower-wup.rules’ as rules file parse_file:
reading ‘/lib/udev/rules.d/97-bluetooth-hid2hci.rules’ as rules file
parse_file: reading ‘/etc/udev/rules.d/jj-video.rules’ as rules file
udev_rules_new: rules use 259284 bytes tokens (21607 * 12 bytes),
37913 bytes buffer udev_rules_new: temporary index used 67520 bytes
(3376 * 20 bytes) udev_device_new_from_syspath: device 0x215103e0 has
devpath
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/video4linux/video1’
udev_device_new_from_syspath: device 0x21510758 has devpath
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/video4linux/video1’
udev_device_read_db: device 0x21510758 filled with db file data
udev_device_new_from_syspath: device 0x21510e10 has devpath
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0’
udev_device_new_from_syspath: device 0x21511b10 has devpath
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2’
udev_device_new_from_syspath: device 0x215132f8 has devpath
‘/devices/pci0000:00/0000:00:1d.0/usb2’ udev_device_new_from_syspath:
device 0x21513650 has devpath ‘/devices/pci0000:00/0000:00:1d.0’
udev_device_new_from_syspath: device 0x21513980 has devpath
‘/devices/pci0000:00’ udev_rules_apply_to_event: GROUP 44
/lib/udev/rules.d/50-udev-default.rules:29 udev_rules_apply_to_event:
IMPORT ‘v4l_id /dev/video1’
/lib/udev/rules.d/60-persistent-v4l.rules:7 udev_event_spawn: starting
‘v4l_id /dev/video1’ spawn_read: ‘v4l_id /dev/video1’(out)
‘ID_V4L_VERSION=2’ spawn_read: ‘v4l_id /dev/video1’(out)
‘ID_V4L_PRODUCT=Logitech QuickCam Pro 3000’ spawn_read: ‘v4l_id
/dev/video1’(out) ‘ID_V4L_CAPABILITIES=:capture:’ spawn_wait: ‘v4l_id
/dev/video1’ [2609] exit with return code 0 udev_rules_apply_to_event:
IMPORT builtin ‘usb_id’ /lib/udev/rules.d/60-persistent-v4l.rules:9
builtin_usb_id: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0:
if_class 10 protocol 0 udev_builtin_add_property: ID_VENDOR=046d
udev_builtin_add_property: ID_VENDOR_ENC=046d
udev_builtin_add_property: ID_VENDOR_ID=046d
udev_builtin_add_property: ID_MODEL=08b0 udev_builtin_add_property:
ID_MODEL_ENC=08b0 udev_builtin_add_property: ID_MODEL_ID=08b0
udev_builtin_add_property: ID_REVISION=0002 udev_builtin_add_property:
ID_SERIAL=046d_08b0_01402100A5000000 udev_builtin_add_property:
ID_SERIAL_SHORT=01402100A5000000 udev_builtin_add_property:
ID_TYPE=generic udev_builtin_add_property: ID_BUS=usb
udev_builtin_add_property: ID_USB_INTERFACES=:0aff00:010100:010200:
udev_builtin_add_property: ID_USB_INTERFACE_NUM=00
udev_builtin_add_property: ID_USB_DRIVER=Philips webcam
udev_rules_apply_to_event: LINK
‘v4l/by-id/usb-046d_08b0_01402100A5000000-video-index0’
/lib/udev/rules.d/60-persistent-v4l.rules:10
udev_rules_apply_to_event: IMPORT builtin ‘path_id’
/lib/udev/rules.d/60-persistent-v4l.rules:16
udev_builtin_add_property: ID_PATH=pci-0000:00:1d.0-usb-0:2:1.0
udev_builtin_add_property: ID_PATH_TAG=pci-0000_00_1d_0-usb-0_2_1_0
udev_rules_apply_to_event: LINK
‘v4l/by-path/pci-0000:00:1d.0-usb-0:2:1.0-video-index0’
/lib/udev/rules.d/60-persistent-v4l.rules:17
udev_rules_apply_to_event: RUN ‘udev-acl --action= e n v A C T I O N − − d e v i c e = env{ACTION} --device= envACTIONdevice=env{DEVNAME}’ /lib/udev/rules.d/70-udev-acl.rules:74 udev_rules_apply_to_event: LINK ‘webcam1’
/etc/udev/rules.d/jj-video.rules:2 udev_event_execute_rules: no node
name set, will use kernel supplied name ‘video1’ udev_node_add:
creating device node ‘/dev/video1’, devnum=81:1, mode=0660, uid=0,
gid=44 udev_node_mknod: preserve file ‘/dev/video1’, because it has
correct dev_t udev_node_mknod: preserve permissions /dev/video1,
020660, uid=0, gid=44 node_symlink: preserve already existing symlink
‘/dev/char/81:1’ to ‘…/video1’ link_find_prioritized: found ‘c81:2’
claiming
‘/run/udev/links/v4l\x2fby-id\x2fusb-046d_08b0_01402100A5000000-video-index0’
udev_device_new_from_syspath: device 0x21516748 has devpath
‘/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2:1.0/video4linux/video2’
udev_device_read_db: device 0x21516748 filled with db file data
link_find_prioritized: found ‘c81:1’ claiming
‘/run/udev/links/v4l\x2fby-id\x2fusb-046d_08b0_01402100A5000000-video-index0’
link_update: creating link
‘/dev/v4l/by-id/usb-046d_08b0_01402100A5000000-video-index0’ to
‘/dev/video1’ node_symlink: atomically replace
‘/dev/v4l/by-id/usb-046d_08b0_01402100A5000000-video-index0’
link_find_prioritized: found ‘c81:1’ claiming
‘/run/udev/links/v4l\x2fby-path\x2fpci-0000:00:1d.0-usb-0:2:1.0-video-index0’
link_update: creating link
‘/dev/v4l/by-path/pci-0000:00:1d.0-usb-0:2:1.0-video-index0’ to
‘/dev/video1’ node_symlink: preserve already existing symlink
‘/dev/v4l/by-path/pci-0000:00:1d.0-usb-0:2:1.0-video-index0’ to
‘…/…/video1’ link_find_prioritized: found ‘c81:1’ claiming
‘/run/udev/links/webcam1’ link_update: creating link ‘/dev/webcam1’ to
‘/dev/video1’ node_symlink: preserve already existing symlink
‘/dev/webcam1’ to ‘video1’ udev_device_update_db: created db file
‘/run/udev/data/c81:1’ for
‘/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/video4linux/video1’
ACTION=add COLORD_DEVICE=1 COLORD_KIND=camera
DEVLINKS=/dev/v4l/by-id/usb-046d_08b0_01402100A5000000-video-index0
/dev/v4l/by-path/pci-0000:00:1d.0-usb-0:2:1.0-video-index0
/dev/webcam1 DEVNAME=/dev/video1
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/video4linux/video1
ID_BUS=usb ID_MODEL=08b0 ID_MODEL_ENC=08b0 ID_MODEL_ID=08b0
ID_PATH=pci-0000:00:1d.0-usb-0:2:1.0
ID_PATH_TAG=pci-0000_00_1d_0-usb-0_2_1_0 ID_REVISION=0002
ID_SERIAL=046d_08b0_01402100A5000000 ID_SERIAL_SHORT=01402100A5000000
ID_TYPE=generic ID_USB_DRIVER=Philips webcam
ID_USB_INTERFACES=:0aff00:010100:010200: ID_USB_INTERFACE_NUM=00
ID_V4L_CAPABILITIES=:capture: ID_V4L_PRODUCT=Logitech QuickCam Pro
3000 ID_V4L_VERSION=2 ID_VENDOR=046d ID_VENDOR_ENC=046d
ID_VENDOR_ID=046d MAJOR=81 MINOR=1 SUBSYSTEM=video4linux
TAGS=:udev-acl: UDEV_LOG=6 USEC_INITIALIZED=18213768 run: ‘udev-acl
–action=add --device=/dev/video1’ jjk@eee-old:~$

(and correspondingly for video2)

It looks to me like my rules are read, but not respected. What am I doing wrong?
webcam udev
shareimprove this question
edited Dec 12 '12 at 15:37

1 Answer
active
oldest
votes
10

It looks like you have two problems.

The first is an ordering problem. Reading the kernel.org manpage on udev, it mentions:

All rules files are ... processed in lexical order

Meaning rules are processed in alphabetical order. The first rule that triggers for a device creates the device file. It looks like you’ve named your rule file jj-video.rules. Looking at the output you provided of udevadm --debug test, it shows that this file is parsed LAST of all the rule files on your system.

Try renaming your file 00-jj-video.rules. That should put it first in the udev rule list, and make it trigger before the other rules.

The second issue is with the rules themselves. The rules read that you’re trying to create /dev/webcam2 when the Logitech QuickCam Pro 3000 is plugged in and when the kernel puts it on /dev/video2. From what you said, you don’t want to match on the device name. Another problem is that you aren’t always using hexadecimal notation in your ATTRS.

This rule should work for the Logitech QuickCam Pro 3000, based on the information you provided in the question:

SUBSYSTEM==“video4linux”, ATTRS{idVendor}“0x046d”,
ATTRS{idProduct}
“0x08b0”, SYMLINK+=“webcam2”

The following may work for the other webcam. I can’t be sure, because you didn’t provide full information on it:

SUBSYSTEM==“video4linux”, SUBSYSTEMS==“usb”,
ATTRS{idVendor}“0x1d6b”, ATTRS{idProduct}“0x0001”,
SYMLINK+=“webcam1”

The most useful tutorial I’ve found on writing udev rules is
http://www.reactivated.net/writing_udev_rules.html.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值