bool ConnectionManager2::applyConfig(QVariant const & config) { if (config.type() != QVariant::List) return false; QList<Connection *> newConns; struct cleanup { QList<Connection *> & conns; cleanup(QList<Connection *> & conns) : conns(conns) {} ~cleanup() { for (int i = 0; i < conns.size(); ++i) conns[i]->releaseAll(); } } cleanupGuard(newConns); QList<QVariant> const & connConfigs = config.toList(); for (int i = 0; i < connConfigs.size(); ++i) { if (connConfigs[i].type() != QVariant::Hash) return false; QHash<QString, QVariant> const & connConfig = connConfigs[i].toHash(); QVariant typev = connConfig.value("type"); if (typev.type() != QVariant::String) return false; QString const & type = typev.toString(); ConnectionPointer<Connection> conn; if (type == "serial_port") conn.reset(new SerialPort()); else if (type == "tcp_client") conn.reset(new TcpSocket()); else if (type == "udp_socket") conn.reset(new UdpSocket()); #ifdef HAVE_LIBYB else if (type == "usb_yb_acm") conn.reset(new UsbAcmConnection2(m_yb_runner)); #endif if (!conn) return false; QVariant settings = connConfig.value("settings"); if (settings.type() != QVariant::Hash || !conn->applyConfig(settings.toHash())) return false; newConns.push_back(conn.data()); conn.take(); } this->clearUserOwnedConns(); while (!newConns.empty()) { this->addUserOwnedConn(newConns.back()); newConns.pop_back(); } return true; }
void LibybUsbEnumerator::pluginEventReceived() { std::vector<yb::usb_plugin_event> events; m_plugin_channel.receive(events); for (size_t i = 0; i < events.size(); ++i) { yb::usb_plugin_event const & ev = events[i]; if (!ev.dev.empty()) { if (!GenericUsbConnection::isFlipDevice(ev.dev)) continue; usb_device_standby st; st.sn = ev.dev.serial_number(); st.vidpid = ev.dev.vidpid(); switch (ev.action) { case yb::usb_plugin_event::a_add: { ConnectionPointer<GenericUsbConnection> conn = m_standby_usb_devices.extract(st); if (!conn) { conn.reset(new GenericUsbConnection(m_runner, ev.dev)); sConMgr2.addConnection(conn.data()); } conn->setRemovable(false); conn->setDevice(ev.dev); m_usb_devices.insert(std::make_pair(ev.dev, conn)); } break; case yb::usb_plugin_event::a_remove: { std::map<yb::usb_device, ConnectionPointer<GenericUsbConnection> >::iterator it = m_usb_devices.find(ev.dev); it->second->clearDevice(); it->second->setRemovable(true); m_standby_usb_devices.add(st, it->second.data()); m_usb_devices.erase(it); } break; } } else { yb::usb_interface_descriptor const & intf = ev.intf.descriptor().altsettings[0]; usb_interface_standby st; st.dev.sn = ev.intf.device().serial_number(); st.dev.vidpid = ev.intf.device().vidpid(); st.intfname = QString::fromUtf8(ev.intf.name().c_str()); if (st.intfname.isEmpty()) st.intfname = QString("#%1").arg(ev.intf.interface_index()); if (GenericUsbConnection::isShupito23Device(ev.intf.device()) && intf.bInterfaceClass == 0xff && intf.in_descriptor_count() > 0 && intf.out_descriptor_count() == 1) { switch (ev.action) { case yb::usb_plugin_event::a_add: { ConnectionPointer<UsbShupito23Connection> conn = m_standby_shupito23_devices.extract(st); if (!conn) { conn.reset(new UsbShupito23Connection(m_runner)); conn->setName(GenericUsbConnection::formatDeviceName(ev.intf.device()), /*isDefault=*/true); sConMgr2.addConnection(conn.data()); } conn->setup(ev.intf); conn->setRemovable(false); m_shupito23_devices.insert(std::make_pair(ev.intf, conn)); } break; case yb::usb_plugin_event::a_remove: { std::map<yb::usb_device_interface, ConnectionPointer<UsbShupito23Connection> >::iterator it = m_shupito23_devices.find(ev.intf); it->second->clear(); it->second->setRemovable(true); m_standby_shupito23_devices.add(st, it->second.data()); m_shupito23_devices.erase(it); } break; } } else if (intf.bInterfaceClass == 0xa && intf.bInterfaceSubClass == 0 && !intf.endpoints.empty()) { Q_ASSERT(!st.intfname.isEmpty()); switch (ev.action) { case yb::usb_plugin_event::a_add: m_usb_acm_devices_by_info.insert(std::make_pair(st, ev.intf)); for (std::set<UsbAcmConnection2 *>::const_iterator it = m_user_owned_acm_conns.begin(); it != m_user_owned_acm_conns.end(); ++it) (*it)->notifyIntfPlugin(ev.intf); break; case yb::usb_plugin_event::a_remove: m_usb_acm_devices_by_info.erase(st); for (std::set<UsbAcmConnection2 *>::const_iterator it = m_user_owned_acm_conns.begin(); it != m_user_owned_acm_conns.end(); ++it) (*it)->notifyIntfUnplug(ev.intf); break; } if (GenericUsbConnection::isShupito20Device(ev.intf.device())) { switch (ev.action) { case yb::usb_plugin_event::a_add: { ConnectionPointer<UsbShupito22Connection> conn = m_standby_shupito22_devices.extract(st); if (!conn) { conn.reset(new UsbShupito22Connection(m_runner)); conn->setName(GenericUsbConnection::formatDeviceName(ev.intf.device()), /*isDefault=*/true); sConMgr2.addConnection(conn.data()); } conn->setup(ev.intf); conn->setRemovable(false); m_shupito22_devices.insert(std::make_pair(ev.intf, conn)); } break; case yb::usb_plugin_event::a_remove: { std::map<yb::usb_device_interface, ConnectionPointer<UsbShupito22Connection> >::iterator it = m_shupito22_devices.find(ev.intf); it->second->clear(); it->second->setRemovable(true); m_standby_shupito22_devices.add(st, it->second.data()); m_shupito22_devices.erase(it); } break; } } else if (st.intfname[0] != '.' && st.intfname[0] != '#') { switch (ev.action) { case yb::usb_plugin_event::a_add: { ConnectionPointer<UsbAcmConnection2> conn = m_standby_usb_acm_devices.extract(st); if (!conn) { conn.reset(new UsbAcmConnection2(m_runner)); conn->setName(QString("%1 @ %2").arg(st.intfname).arg(GenericUsbConnection::formatDeviceName(ev.intf.device())), /*isDefault=*/true); sConMgr2.addConnection(conn.data()); } conn->setEnumeratedIntf(ev.intf); conn->setRemovable(false); this->applyConfig(conn.data()); m_usb_acm_devices.insert(std::make_pair(ev.intf, conn)); } break; case yb::usb_plugin_event::a_remove: { std::map<yb::usb_device_interface, ConnectionPointer<UsbAcmConnection2> >::iterator it = m_usb_acm_devices.find(ev.intf); this->updateConfig(it->second.data()); it->second->clear(); it->second->setRemovable(true); m_standby_usb_acm_devices.add(st, it->second.data()); m_usb_acm_devices.erase(it); } break; } } } else if(GenericUsbConnection::isSTLink32LDevice(ev.intf.device()) && intf.bInterfaceClass == 0xff && st.intfname == "ST Link") { switch (ev.action) { case yb::usb_plugin_event::a_add: { for (std::set<STM32Connection *>::const_iterator it = m_user_owned_stm32_conns.begin(); it != m_user_owned_stm32_conns.end(); ++it) (*it)->notifyIntfPlugin(ev.intf); ConnectionPointer<STM32Connection> conn = m_standby_stm32_devices.extract(st); if (!conn) { conn.reset(new STM32Connection(m_runner)); sConMgr2.addConnection(conn.data()); } conn->setEnumeratedIntf(ev.intf); conn->setRemovable(false); m_stm32_devices.insert(std::make_pair(ev.intf, conn)); } break; case yb::usb_plugin_event::a_remove: { for (std::set<STM32Connection *>::const_iterator it = m_user_owned_stm32_conns.begin(); it != m_user_owned_stm32_conns.end(); ++it) (*it)->notifyIntfUnplug(ev.intf); std::map<yb::usb_device_interface, ConnectionPointer<STM32Connection> >::iterator it = m_stm32_devices.find(ev.intf); it->second->clear(); it->second->setRemovable(true); m_standby_stm32_devices.add(st, it->second.data()); m_stm32_devices.erase(it); } break; } } } } }