Linux(Ubuntu)下QT检测U盘插入状态与实时热插拔检测

一、检测U盘是否插入

该方法适用于U盘已经插入的状态下,进行U盘插入检测。

bool uDiskSetting::isUDiskExist()
{
    piTerminal.start("sh",QStringList()<<"-c"<<"lsblk | grep media");//其中grep是得到包含media的部分
    piTerminal.waitForFinished();
    QString ret=piTerminal.readAllStandardOutput();
    if(ret  == "")
    {
        return false;
    }
    ret.remove(QRegExp("\\s+"));

    m_uDiskPath = ret.right(ret.length()-ret.lastIndexOf("m")+1);

    return true;
}

其中:QProcess piTerminal,QString m_uDiskPath;

Ubuntu插入U盘后,一般自动挂载到/media目录下,因此利用lsblk | grep media命令找到相应U盘信息,在利用正则表达式进行输出内容的精简,得到有用的U盘信息,在进行字符串截取,获得U盘的路径m_uDiskPath进行操作。

二、实时热插拔

开启线程,进行实时U盘插拔信息监测,获取到相关操作后将信号传到主线程进行其它操作。

利用NETLINK原理,检测Linux系统U盘插拔时候输出打印信息,截取remove或者add信息,其中带有“/block/sd”字符串的一行就是U盘挂载名称,截取后通过拼接"/media”完成整个U盘的路径获取,将带有U盘插拔状态以及路径信息的信号发送出去,代码如下:

#include "UDiskQThread.h"

#define UEVENT_BUFFER_SIZE 2048

UDiskQThread::UDiskQThread(QObject * parent) :
    QThread(parent)
{
    hotplug_sock = init_hotplug_sock();
}
UDiskQThread::~UDiskQThread()
{
}
int UDiskQThread::init_hotplug_sock(void)
{
    const int buffersize = 1024;
      int ret;
      struct sockaddr_nl snl;
      bzero(&snl, sizeof(struct sockaddr_nl));
      snl.nl_family = AF_NETLINK;
      snl.nl_pid = getpid();
      snl.nl_groups = 1;
      int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
      if (s == -1) {
        //perror("socket");
        return -1;
      }
      setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
      ret = bind(s, (struct sockaddr*)&snl, sizeof(struct sockaddr_nl));
      if (ret < 0) {
        //perror("bind");
        close(s);
        return -1;
      }
      return s;
}
void UDiskQThread::run()
{

    /* Netlink message buffer */
    while (1) {
      char buf[UEVENT_BUFFER_SIZE * 2] = {0};
      if (recv(hotplug_sock, &buf, sizeof(buf), 0)> 0)
      {
          //printf("%s\n",buf);//打印热插拔设备全部信息

          //USB设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码
          if (NULL != strstr(buf, "/block/sd") && NULL != strstr(buf, "remove")) // 拔出时内核会发送消息为:remove@
          {
              emit UDiskStatusChange(1,"");
          }
          if (NULL != strstr(buf, "/block/sd") && NULL != strstr(buf, "add")) // 插入时内核会发送消息为:add@/.../ttyUSBx
          {
              //strrchr()函数:查找一个字符串在另一个字符串中 末次 出现的位置,并返回从字符串中的这个位置起,一直到字符串结束的所有字符;
              //add@/devices/platform/musb-da8xx/musb-hdrc/usb2/2-1/2-1:1.0/host4/target4:0:0/4:0:0:0/block/sda
              char *uDisk_name = strrchr((const char *)buf, '/') + 1;//获取U盘名称

              QString path = "/media/";
                      path += QString (uDisk_name);
              emit UDiskStatusChange(0,path);
          }
      }
    }
}

你可能感兴趣的:(嵌入式QT,linux,ubuntu,qt)