it-swarm-id.com

Bagaimana Anda mengatur ulang perangkat USB dari baris perintah?

Apakah mungkin untuk mereset koneksi perangkat USB, tanpa secara fisik memutus/menghubungkan dari PC?

Secara khusus, perangkat saya adalah kamera digital. Saya menggunakan gphoto2, tetapi akhir-akhir ini saya mendapatkan "kesalahan baca perangkat", jadi saya ingin mencoba melakukan pengaturan ulang perangkat lunak dari koneksi tersebut.

Dari apa yang saya tahu, tidak ada modul kernel yang dimuat untuk kamera. Satu-satunya yang terlihat terkait adalah usbhid.

156
cmcginty

Simpan yang berikut ini sebagai usbreset.c

/* usbreset -- send a USB port reset to a USB device */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/usbdevice_fs.h>


int main(int argc, char **argv)
{
    const char *filename;
    int fd;
    int rc;

    if (argc != 2) {
        fprintf(stderr, "Usage: usbreset device-filename\n");
        return 1;
    }
    filename = argv[1];

    fd = open(filename, O_WRONLY);
    if (fd < 0) {
        perror("Error opening output file");
        return 1;
    }

    printf("Resetting USB device %s\n", filename);
    rc = ioctl(fd, USBDEVFS_RESET, 0);
    if (rc < 0) {
        perror("Error in ioctl");
        return 1;
    }
    printf("Reset successful\n");

    close(fd);
    return 0;
}

Jalankan perintah berikut di terminal:

  1. Kompilasi program:

    $ cc usbreset.c -o usbreset
    
  2. Dapatkan Bus dan ID Perangkat dari perangkat USB yang ingin Anda atur ulang:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Jadikan program terkompilasi kami dapat dijalankan:

    $ chmod +x usbreset
    
  4. Jalankan program dengan hak istimewa Sudo; buat penggantian yang diperlukan untuk id <Bus> dan <Device> seperti yang ditemukan dengan menjalankan perintah lsusb:

    $ Sudo ./usbreset /dev/bus/usb/002/003  
    

Sumber program di atas: http://marc.info/?l=linux-usb&m=121459435621262&w=2

112
Li Lo

Saya belum menemukan diri saya dalam keadaan spesifik Anda sebelumnya, jadi saya tidak yakin apakah itu akan cukup, tetapi cara paling sederhana yang saya temukan untuk menyetel ulang perangkat USB adalah perintah ini: (Tidak perlu aplikasi eksternal)

Sudo sh -c "echo 0 > /sys/bus/usb/devices/1-4.6/authorized"
Sudo sh -c "echo 1 > /sys/bus/usb/devices/1-4.6/authorized"

Itulah yang sebenarnya saya gunakan untuk mengatur ulang Kinect saya karena libfreenect tampaknya tidak memiliki API untuk membuatnya kembali tidur. Itu ada di kotak Gentoo saya, tetapi kernel seharusnya cukup baru untuk menggunakan struktur path yang sama untuk sysfs.

Jelas Anda bukan 1-4.6 tetapi Anda dapat menarik jalur perangkat itu dari log kernel Anda (dmesg) atau Anda dapat menggunakan sesuatu seperti lsusb untuk mendapatkan vendor dan ID produk dan kemudian menggunakan perintah cepat seperti ini untuk membuat daftar bagaimana jalur berhubungan ke pasangan vendor/ID produk yang berbeda:

for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done
55
ssokolow

Ini akan mengatur ulang semua port USB1/2/3 yang terpasang [1]:

for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
  [ -e "$i" ] || continue
  echo "${i##*/}" > "${i%/*}/unbind"
  echo "${i##*/}" > "${i%/*}/bind"
done

Saya percaya ini akan menyelesaikan masalah Anda. Jika Anda tidak ingin mengatur ulang semua titik akhir USB, Anda dapat menggunakan ID perangkat yang sesuai dari /sys/bus/pci/drivers/ehci_hcd


Catatan: [1]: driver kernel *hci_hcd biasanya mengontrol port USB. ohci_hcd dan uhci_hcd untuk port USB1.1, ehci_hcd untuk port USB2 dan xhci_hcd untuk port USB3. (lihat https://en.wikipedia.org/wiki/Host_controller_interface_ (USB, _Firewire) )

46
Tamás Tapsonyi

Saya perlu mengotomatiskan ini dalam skrip python, jadi saya mengadaptasi jawaban LiLo yang sangat membantu sebagai berikut:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
import fcntl
driver = sys.argv[-1]
print "resetting driver:", driver
USBDEVFS_RESET= 21780

try:
    lsusb_out = Popen("lsusb | grep -i %s"%driver, Shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().split()
    bus = lsusb_out[1]
    device = lsusb_out[3][:-1]
    f = open("/dev/bus/usb/%s/%s"%(bus, device), 'w', os.O_WRONLY)
    fcntl.ioctl(f, USBDEVFS_RESET, 0)
except Exception, msg:
    print "failed to reset device:", msg

Dalam kasus saya itu adalah driver cp210x (yang dapat saya katakan dari lsmod | grep usbserial), sehingga Anda dapat menyimpan cuplikan di atas sebagai reset_usb.py dan kemudian melakukan ini:

Sudo python reset_usb.py cp210x

Ini mungkin juga berguna jika Anda belum memiliki setup c compiler di sistem Anda, tetapi Anda memiliki python.

9
Peter

Saya telah membuat skrip Python yang menyederhanakan seluruh proses berdasarkan jawaban di sini.

Simpan skrip di bawah ini sebagai reset_usb.py atau klon repo ini .

Pemakaian:

python reset_usb.py help  # Show this help
Sudo python reset_usb.py list  # List all USB devices
Sudo python reset_usb.py path /dev/bus/usb/XXX/YYY  # Reset USB device using path /dev/bus/usb/XXX/YYY
Sudo python reset_usb.py search "search terms"  # Search for USB device using the search terms within the search string returned by list and reset matching device
Sudo python reset_usb.py listpci  # List all PCI USB devices
Sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X  # Reset PCI USB device using path /sys/bus/pci/drivers/.../XXXX:XX:XX.X
Sudo python reset_usb.py searchpci "search terms"  # Search for PCI USB device using the search terms within the search string returned by listpci and reset matching device

Naskah:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
import fcntl

instructions = '''
Usage: python reset_usb.py help : Show this help
       Sudo python reset_usb.py list : List all USB devices
       Sudo python reset_usb.py path /dev/bus/usb/XXX/YYY : Reset USB device using path /dev/bus/usb/XXX/YYY
       Sudo python reset_usb.py search "search terms" : Search for USB device using the search terms within the search string returned by list and reset matching device
       Sudo python reset_usb.py listpci : List all PCI USB devices
       Sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X : Reset PCI USB device using path
       Sudo python reset_usb.py searchpci "search terms" : Search for PCI USB device using the search terms within the search string returned by listpci and reset matching device       
       '''


if len(sys.argv) < 2:
    print(instructions)
    sys.exit(0)

option = sys.argv[1].lower()
if 'help' in option:
    print(instructions)
    sys.exit(0)


def create_pci_list():
    pci_usb_list = list()
    try:
        lspci_out = Popen('lspci -Dvmm', Shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().decode('utf-8')
        pci_devices = lspci_out.split('%s%s' % (os.linesep, os.linesep))
        for pci_device in pci_devices:
            device_dict = dict()
            categories = pci_device.split(os.linesep)
            for category in categories:
                key, value = category.split('\t')
                device_dict[key[:-1]] = value.strip()
            if 'USB' not in device_dict['Class']:
                continue
            for root, dirs, files in os.walk('/sys/bus/pci/drivers/'):
                slot = device_dict['Slot']
                if slot in dirs:
                    device_dict['path'] = os.path.join(root, slot)
                    break
            pci_usb_list.append(device_dict)
    except Exception as ex:
        print('Failed to list pci devices! Error: %s' % ex)
        sys.exit(-1)
    return pci_usb_list


def create_usb_list():
    device_list = list()
    try:
        lsusb_out = Popen('lsusb -v', Shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().decode('utf-8')
        usb_devices = lsusb_out.split('%s%s' % (os.linesep, os.linesep))
        for device_categories in usb_devices:
            if not device_categories:
                continue
            categories = device_categories.split(os.linesep)
            device_stuff = categories[0].strip().split()
            bus = device_stuff[1]
            device = device_stuff[3][:-1]
            device_dict = {'bus': bus, 'device': device}
            device_info = ' '.join(device_stuff[6:])
            device_dict['description'] = device_info
            for category in categories:
                if not category:
                    continue
                categoryinfo = category.strip().split()
                if categoryinfo[0] == 'iManufacturer':
                    manufacturer_info = ' '.join(categoryinfo[2:])
                    device_dict['manufacturer'] = manufacturer_info
                if categoryinfo[0] == 'iProduct':
                    device_info = ' '.join(categoryinfo[2:])
                    device_dict['device'] = device_info
            path = '/dev/bus/usb/%s/%s' % (bus, device)
            device_dict['path'] = path

            device_list.append(device_dict)
    except Exception as ex:
        print('Failed to list usb devices! Error: %s' % ex)
        sys.exit(-1)
    return device_list


if 'listpci' in option:
    pci_usb_list = create_pci_list()
    for device in pci_usb_list:
        print('path=%s' % device['path'])
        print('    manufacturer=%s' % device['SVendor'])
        print('    device=%s' % device['SDevice'])
        print('    search string=%s %s' % (device['SVendor'], device['SDevice']))
    sys.exit(0)

if 'list' in option:
    usb_list = create_usb_list()
    for device in usb_list:
        print('path=%s' % device['path'])
        print('    description=%s' % device['description'])
        print('    manufacturer=%s' % device['manufacturer'])
        print('    device=%s' % device['device'])
        print('    search string=%s %s %s' % (device['description'], device['manufacturer'], device['device']))
    sys.exit(0)

if len(sys.argv) < 3:
    print(instructions)
    sys.exit(0)

option2 = sys.argv[2]

print('Resetting device: %s' % option2)


# echo -n "0000:39:00.0" | tee /sys/bus/pci/drivers/xhci_hcd/unbind;echo -n "0000:39:00.0" | tee /sys/bus/pci/drivers/xhci_hcd/bind
def reset_pci_usb_device(dev_path):
    folder, slot = os.path.split(dev_path)
    try:
        fp = open(os.path.join(folder, 'unbind'), 'wt')
        fp.write(slot)
        fp.close()
        fp = open(os.path.join(folder, 'bind'), 'wt')
        fp.write(slot)
        fp.close()
        print('Successfully reset %s' % dev_path)
        sys.exit(0)
    except Exception as ex:
        print('Failed to reset device! Error: %s' % ex)
        sys.exit(-1)


if 'pathpci' in option:
    reset_pci_usb_device(option2)


if 'searchpci' in option:
    pci_usb_list = create_pci_list()
    for device in pci_usb_list:
        text = '%s %s' % (device['SVendor'], device['SDevice'])
        if option2 in text:
            reset_pci_usb_device(device['path'])
    print('Failed to find device!')
    sys.exit(-1)


def reset_usb_device(dev_path):
    USBDEVFS_RESET = 21780
    try:
        f = open(dev_path, 'w', os.O_WRONLY)
        fcntl.ioctl(f, USBDEVFS_RESET, 0)
        print('Successfully reset %s' % dev_path)
        sys.exit(0)
    except Exception as ex:
        print('Failed to reset device! Error: %s' % ex)
        sys.exit(-1)


if 'path' in option:
    reset_usb_device(option2)


if 'search' in option:
    usb_list = create_usb_list()
    for device in usb_list:
        text = '%s %s %s' % (device['description'], device['manufacturer'], device['device'])
        if option2 in text:
            reset_usb_device(device['path'])
    print('Failed to find device!')
    sys.exit(-1)
4
mcarans

Saya menggunakan semacam palu godam dengan memuat ulang modul. Ini skrip usb_reset.sh saya:

#!/bin/bash

# USB drivers
rmmod xhci_pci
rmmod ehci_pci

# uncomment if you have firewire
#rmmod ohci_pci

modprobe xhci_pci
modprobe ehci_pci

# uncomment if you have firewire
#modprobe ohci_pci

Dan ini adalah file layanan systemd saya /usr/lib/systemd/system/usbreset.service yang menjalankan usb_reset.sh setelah manajer permainan saya mulai:

[Unit]
Description=usbreset Service
After=gdm.service
Wants=gdm.service

[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh

Karena kasus khusus dari pertanyaan adalah masalah komunikasi gphoto2 dengan kamera pada USB, ada opsi di gphoto2 untuk mengatur ulang koneksi USB-nya:

gphoto2 --reset

Mungkin opsi ini tidak ada pada 2010 ketika pertanyaan diajukan.

4
mviereck

Saya membuat skrip python yang akan mereset perangkat USB tertentu berdasarkan nomor perangkat. Anda dapat mengetahui nomor perangkat dari perintah lsusb.

sebagai contoh:

$ lsusb

Bus 002 Device 004: ID 046d:c312 Logitech, Inc. DeLuxe 250 Keyboard

Dalam string ini 004 adalah nomor perangkat

import os
import argparse
import subprocess

path='/sys/bus/usb/devices/'

def runbash(cmd):
    p = subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE)
    out = p.stdout.read().strip()
    return out

def reset_device(dev_num):
    sub_dirs = []
    for root, dirs, files in os.walk(path):
            for name in dirs:
                    sub_dirs.append(os.path.join(root, name))

    dev_found = 0
    for sub_dir in sub_dirs:
            if True == os.path.isfile(sub_dir+'/devnum'):
                    fd = open(sub_dir+'/devnum','r')
                    line = fd.readline()
                    if int(dev_num) == int(line):
                            print ('Your device is at: '+sub_dir)
                            dev_found = 1
                            break

                    fd.close()

    if dev_found == 1:
            reset_file = sub_dir+'/authorized'
            runbash('echo 0 > '+reset_file) 
            runbash('echo 1 > '+reset_file) 
            print ('Device reset successful')

    else:
            print ("No such device")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--devnum', dest='devnum')
    args = parser.parse_args()

    if args.devnum is None:
            print('Usage:usb_reset.py -d <device_number> \nThe device    number can be obtained from lsusb command result')
            return

    reset_device(args.devnum)

if __name__=='__main__':
    main()
3
Raghu

Cara tercepat untuk mengatur ulang adalah mengatur ulang pengontrol USB itu sendiri. Melakukan hal itu akan memaksa udev untuk membatalkan registrasi perangkat saat terputus, dan pendaftaran kembali setelah Anda mengaktifkannya.

echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind
echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind

Ini harus bekerja untuk sebagian besar lingkungan PC. Namun, jika Anda menggunakan beberapa perangkat keras khusus, Anda cukup mengulanginya melalui nama perangkat. Dengan metode ini Anda tidak perlu mencari tahu nama perangkat dengan lsusb. Anda dapat memasukkan dalam skrip otomatis juga.

3
chandank

Berikut ini skrip yang hanya akan mereset ID produk/vendor yang cocok.

#!/bin/bash

set -euo pipefail
IFS=$'\n\t'

VENDOR="045e"
PRODUCT="0719"

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
2
cmcginty

Terkadang saya ingin melakukan operasi ini pada perangkat tertentu, seperti yang diidentifikasi oleh VID (vendor id) dan PID (id produk). Ini adalah skrip yang saya temukan berguna untuk tujuan ini, yang menggunakan perpustakaan libusb yang bagus.

Lari pertama:

Sudo apt-get install libusb-dev

Kemudian, resetDeviceConnection file c ++ ini harus melakukan tugas ini, mengatur ulang koneksi perangkat seperti yang diidentifikasi oleh vid dan pid.

#include <libusb-1.0/libusb.h>

int resetDeviceConnection(UINT_16 vid, UINT_16 pid){
    /*Open libusb*/
    int resetStatus = 0;
    libusb_context * context;
    libusb_init(&context);

    libusb_device_handle * dev_handle = libusb_open_device_with_vid_pid(context,vid,pid);
    if (dev_handle == NULL){
      printf("usb resetting unsuccessful! No matching device found, or error encountered!\n");
      resetStatus = 1;
    }
    else{
      /*reset the device, if one was found*/
      resetStatus = libusb_reset_device(dev_handle);
    }
    /*exit libusb*/
    libusb_exit(context);
    return resetStatus;
}

(Dicuri dari katalog TIL pribadi saya: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )

1
Marviel

Apakah ada yang memesan palu? Ini disatukan dari berbagai jawaban lain di sini.

#!/bin/bash

# Root required
if (( UID )); then
        exec Sudo "$0" "[email protected]"
fi

cd /sys/bus/pci/drivers

function reinit {(
        local d="$1"
        test -e "$d" || return

        rmmod "$d"

        cd "$d"

        for i in $(ls | grep :); do
                echo "$i" > unbind
        done

        sleep 1

        for i in $(ls | grep :); do
                echo "$i" > bind
        done

        modprobe "$d"

)}

for d in ?hci_???; do
        echo " - $d"
        reinit "$d"
done
1
Mark K Cowan

Coba ini, ini mencabut perangkat lunak (Keluarkan).

Terkadang tidak berfungsi hanya melepaskan ikatan perangkat untuk beberapa perangkat.

Contoh:

Saya ingin menghapus atau mengeluarkan "Genius NetScroll 120" saya.

Maka saya pertama-tama Periksa perangkat usb saya yang terpasang

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 03f0:231d Hewlett-Packard 
Bus 001 Device 004: ID 138a:0007 Validity Sensors, Inc. VFS451 Fingerprint Reader
Bus 001 Device 005: ID 04f2:b163 Chicony Electronics Co., Ltd 
Bus 002 Device 009: ID 0458:003a KYE Systems Corp. (Mouse Systems) NetScroll+ Mini Traveler / Genius NetScroll 120  **<----This my Mouse! XDDD**

Ok, saya menemukan mouse saya, ini memiliki Bus 002, Device 009, idVendor 0458 dan idProduct 003a, jadi ini adalah informasi perangkat referensi tentang mouse.

Ini penting, nomor Bus adalah jalur nama mulai ke perangkat dan saya akan memeriksa Id produk dan Vendor untuk memastikan perangkat yang benar untuk dihapus.

$ ls /sys/bus/usb/drivers/usb/
1-1/    1-1.1/  1-1.3/  1-1.5/  2-1/    2-1.3/  bind    uevent  unbind  usb1/   usb2/

Perhatikan folder-folder, periksa permulaan dengan folder nomor 2, saya akan memeriksa ini karena Bus saya adalah 002, dan satu per satu saya telah memeriksa setiap folder yang berisi idVendor dan idProduct yang benar tentang info mouse saya.

Dalam hal ini, saya akan mengambil info dengan perintah ini:

cat /sys/bus/usb/drivers/usb/2-1.3/idVendor
0458
cat /sys/bus/usb/drivers/usb/2-1.3/idProduct
003a

Oke, path /sys/bus/usb/drivers/usb/2-1.3/ cocok dengan mouse info saya! XDDD.

Sudah waktunya untuk menghapus perangkat!

su -c "echo 1 > /sys/bus/usb/drivers/usb/2-1.3/remove"

Tancapkan kembali perangkat usb dan berfungsi lagi!

0
user242078

saya membuat skrip bash sederhana untuk mengatur ulang perangkat USB tertentu.

#!/bin/bash
#type lsusb to find "vendor" and "product" ID in terminal
set -euo pipefail
IFS=$'\n\t'

#edit the below two lines of vendor and product values using lsusb result
dev=$(lsusb -t | grep usbdevicename | grep 'If 1' | cut -d' ' -f13|cut -d"," -f1)
#VENDOR=05a3
#PRODUCT=9230
VENDOR=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f1)
PRODUCT=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f2)

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
0
Thoht

Jika Anda tahu nama perangkat Anda, skrip python ini akan berfungsi:

#!/usr/bin/python
"""
USB Reset

Call as "usbreset.py <device_file_path>"

With device_file_path like "/dev/bus/usb/bus_number/device_number"
"""
import fcntl, sys, os

USBDEVFS_RESET = ord('U') << (4*2) | 20

def main():
    fd = os.open(sys.argv[1], os.O_WRONLY)
    if fd < 0: sys.exit(1)
    fcntl.ioctl(fd, USBDEVFS_RESET, 0)
    os.close(fd)
    sys.exit(0)
# end main

if __== '__main__':
    main()
0
Clay

Mungkin ini bekerja untuk kamera juga:

Setelah menghidupkan kembali USB 3.0 HDD yang kelaparan di 3.4.42 (kernel.org) Linux di sisi saya. dmesg memberi tahu, bahwa itu adalah pengaturan waktu setelah 360s (maaf, saya tidak dapat menyalin syslog di sini, bukan jaringan yang terhubung) dan drive tergantung sepenuhnya. Proses mengakses perangkat diblokir di kernel, tidak dapat digunakan. NFS hung, ZFS hung, dd hung.

Setelah melakukan ini, semuanya bekerja kembali. dmesg memberi tahu hanya satu baris tentang perangkat USB yang ditemukan.

Saya benar-benar tidak tahu apa yang dilakukan berikut secara detail. Tapi itu berhasil.

Contoh output berikut adalah dari Debian Squeeze dengan kernel 2.6.32-5-686, jadi saya pikir ini berfungsi untuk 2.6 dan di atasnya:

$ ls -al /dev/sdb
brw-rw---T 1 root floppy 8, 16 Jun  3 20:24 /dev/sdb

$ ls -al /sys/dev/block/8:16/device/rescan
--w------- 1 root root 4096 Jun  6 01:46 /sys/dev/block/8:16/device/rescan

$ echo 1 > /sys/dev/block/8:16/device/rescan

Jika ini tidak berhasil, mungkin orang lain dapat mengetahui cara mengirim setel nyata ke perangkat.

0
Tino