ARM platform QT detection USB flash drive plugging (3)-egg pain Recv () Blocking

Source: Internet
Author: User

Because we finally need to implement this function on tiny210, and finally chose hotplug.

Bytes.

#ifndef HOSTPLUG_H#define HOSTPLUG_H#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/un.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <linux/types.h>#include <linux/netlink.h>#include <errno.h>#include <fcntl.h>static int init_hotplug_sock(void){    struct sockaddr_nl snl;    const int buffersize = 16 * 1024 * 1024;    int retval;    memset(&snl, 0x00, sizeof(struct sockaddr_nl));    snl.nl_family = AF_NETLINK;    snl.nl_pid = getpid();    snl.nl_groups = 1;    int hotplug_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);    if(hotplug_sock == -1)    {        printf("Error getting socket;%s\n", strerror(errno));        return -1;    }    /*set receive buffersize*/    setsockopt(hotplug_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize)); int flags=fcntl(hotplug_sock, F_GETFL,0); fcntl(hotplug_sock, F_SETFL, flags | O_NONBLOCK);    retval = bind(hotplug_sock, (struct sockaddr*)&snl, sizeof(struct sockaddr_nl) );    if(retval < 0)    {        printf("bind failed: %s", strerror(errno));        close(hotplug_sock);        hotplug_sock = -1;        return -1;    }    return hotplug_sock;}#endif // HOSTPLUG_H

Then add a timer with a timer time of 500 ms, that is, scanning every MS, as shown below:

void Widget::timerEvent(QTimerEvent *event){    static int n = 0;    char buf[1024] = {0};   //UEVENT_BUFFER_SIZE*2    if(event->timerId() == timer.timerId())    {        recv(hotplug_sock, &buf, sizeof(buf), 0); //use a timer to query socket from core -netlink        QString result = buf;         rectFlag = result;        qDebug()<<result;        if(result.contains("add"))        {            n++;            if (n>10)                n = 10;            ui->progressBar->setValue(n);        }        else if(result.contains("remove"))        {            n--;            if(n<0)                n = 0;            ui->progressBar->setValue(n);        }    }    else        QWidget::timerEvent(event);}

Note that the most important thing here is

recv(hotplug_sock, &buf, sizeof(buf), 0);

This function saves received messages to the Buf. However, the default hotplug_sock is blocked, that is, when the Recv is executed, the program will stop here until the new kernel message is received again, and the program will continue to run. To this end, the program must be modified. One idea is to open a thread and run the Recv. It doesn't matter if you stop it. The other idea is to change the sock to non-blocking. For details about the changes, see. red lines in the H file!

Int flags = fcntl (hotplug_sock, f_getfl, 0 );
Fcntl (hotplug_sock, f_setfl, flags | o_nonblock );

When the kernel has no message, the Buf after Recv () is empty. After cross-compilation, the program runs well in tiny210!


Previous:


Unfortunately, the industry is not doing this well. to scan a USB flash drive, a timer should be enabled to scan it, therefore, you can determine whether the USB flash disk is inserted by checking whether/proc/SCSI/USB-storage exists. I have considered whether the mount point/udisk exists after the USB flash drive is inserted. However, when the user is in the/udisk directory, the USB flash disk is suddenly unplugged. /Udisk will exist, and the result of LS is an error. In this case, the USB flash drive directory is unmounted and Linux cannot be unmounted. When the USB flash drive is properly inserted, there will be three files in the USB-storage folder. When the unmount fails, there will be two files. When the unmount is successful, the USB-storage folder disappears. Use the test file in the image/udisk to determine whether/udisk is available. If it is unavailable, the system will prompt you:

bool Widget::checkSaveFile(){    QString fileName = "/proc/scsi/usb-storage/a.txt";    QFile file(fileName);    if(!file.open(QFile::WriteOnly|QFile::Text))        return false;    else    {   file.close();        file.remove();        return true;    }}

The slot function for querying the U disk status:

Void Widget: on_querybutton_clicked () {qdir Dir ("/proc/SCSI/USB-storage"); // If the mount point is detected on the board, change it: qdir Dir ("/udisk") checks the mount point qmessagebox box; qstring mess; box. setwindowtitle (TC-> tounicode ("U disk status"); qdebug () <"dir. count () = "<dir. count (); If (rectflag. contains ("add") mess = tc-> tounicode ("being recognized, please wait -----"); else if (rectflag. contains ("Remove") mess = tc-> tounicode ("deleting your USB flash drive -------"); else if (dir. exists ()){ If (dir. Count ()> 2) {// If (checksavefile () mess = tc-> tounicode ("the USB flash disk is connected! "); // Else // mess = tc-> tounicode (" your USB flash drive has been inserted, but the mount point is faulty and cannot be used normally! We recommend that you unplug the USB flash drive and restart it! ");} Else if (dir. count () = 2) {qdir dirmount ("/udisk"); If (dirmount. exists () {int FD = system ("umount/udisk"); qdebug () <"FD =" <FD ;} else mess = tc-> tounicode ("/udisk no exist! "); // If (checksavefile () // mess = tc-> tounicode (" You have not inserted a USB flash disk. However, the mount point can be written without affecting the usage. Insert a USB flash drive if necessary! "); // This situation is logically impossible. // Else // mess = tc-> tounicode ("You have not inserted a USB flash drive. However, there is a problem with the current mount point. We recommend that you re-insert the USB flash disk after restarting! ");} Else mess = tc-> tounicode (" the USB flash drive is faulty. Please restart and insert the USB flash drive! ");} Else mess = tc-> tounicode (" the USB flash drive is not connected! "); // Process-> Start (" ls/mnt \ n "); // qstring test = qstring: Number (A, 10 ); // qstring test = process-> readallstandardoutput (); // UI-> gettextedit-> insertplaintext (test + "\ n "); UI-> gettextedit-> insertplaintext (mess + "\ n"); autoscroll ();
}

In this way, the USB flash drive can be detected normally. If you want to add a progress bar, add it. If this parameter is not added, the system can detect the vulnerability.

The problem is that the test file is written to/udisk to check whether/udisk is available, but sometimes the user will write the USB flash disk for protection. I tried all the methods and used open, opendir, access, stat, and so on to check whether the/udisk attribute is different from the normal state in case of exceptions. I finally did not find it. You also use ls/udisk>/a.txt to intercept ls content. However, when/udisk encounters an exception, the error is reported by the Board, not by ls. Ls: The result is blank.

In fact, it is better to prevent this mistaken USB flash drive. After my research, I found that when ls has a/udisk fatal error, you only need to execute/umount/udisk, manually unmount the folder, and plug in the USB flash disk again. To this end, we can see that in my above program, when we check dir. Count = 2, we will check whether/udisk exists. If yes, we will unmount/udisk.

This is basically a perfect solution to the problem. In the US, when an exception occurs, if the board program is running all the time, unplugging the USB flash disk and then plugging it in. If the Board restarts at this time, insert the USB flash drive to the Board again before the Board restarts. At this time, because our application is not running, we have not executed umount/udisk, at this time, the program cannot detect it.

To avoid this problem, you should use the method of writing data to the USB flash disk to determine the situation, or if you can scan the information queried by hostplug to know the registration of USB, this idea should also be OK. A small USB flash disk detection has finally come to an end, implementing a QT detection USB disk for both x86 and arm platforms! ---------------- Yanzi1225627

Here is a source code resource written by a foreigner. It uses qtcpsocket to listen to Netlink messages. The code written by foreigners is different. For details, refer:

Http://download.csdn.net/detail/yanzi1225627/4514740

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.