Beispiel #1
0
void ReconnectRouterOp::onConnectProfileFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("connectProfile self aborted!"));
        return;
    }

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("connectProfile op aborted!"));
        return notifyFinished(AbortedError);
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("connectWlanProfile %1 result: %1").arg(m_wifiName).arg(result));
    if (result == WlanProfileNotFound )
    {
        LOG_DEBUG(QString::fromUtf8("recreate profile?"));
        notifyFinished(WlanProfileNotFound);
    }
    if (result != NoError)
    {
        return retry();
    }

    discoverRouter();
}
Beispiel #2
0
void CheckInternetOp::onConnectHostFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("connectHost self aborted!"));
        return;
    }

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("connectHost op aborted!"));
        return notifyFinished(AbortedError);
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("connectHost result: %1").arg(result));
    if (result != NoError)
    {
        return retry();
    }

    notifyFinished(NoError);
}
Beispiel #3
0
void MasterDiscoverRouterSoapOp::onOpFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("MasterDiscoverRouterSoapOp::onOpFinished() aborted"));
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("MasterDiscoverRouterSoapOp::onOpFinished() %1").arg(result));

    if (result != NoError)
    {
        if (m_retryCount < m_maxRetryCount)
        {
            LOG_DEBUG(QString::fromUtf8("MasterDiscoverRouterSoapOp Failed, but will retry later"));
            ++m_retryCount;
            m_timer1.setSingleShot(true);
            m_timer1.setInterval(m_retryDelay);
            connect(&m_timer1, SIGNAL(timeout()), SLOT(onRetryTimeout()));
            m_timer1.start();
            return;
        }
        LOG_DEBUG(QString::fromUtf8("MasterDiscoverRouterSoapOp Failed, no more retry chance!"));
        return notifyFinished(UnknownError);
    }

    copyValues(op);
    notifyFinished(NoError);
}
Beispiel #4
0
void ChangeRouterWanSettingsOp::onSoapFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    notifyFinished(NoError);
}
Beispiel #5
0
void CheckRouterSoapOp::onGetInfo3Finished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo3Finished() aborted"));
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo3Finished() %1").arg(result));

    if (result != NoError)
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = op->value("responseCode").toInt(&ok);
    if (!ok || responseCode != 0)
    {
        LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo3Finished() response error: %1 %2").arg(responseCode).arg(ok));
        return notifyFinished(result);
    }

    m_values.unite(qvariant_cast<QVariantMap>(op->value("response")));
    setValues(m_values);
    notifyFinished(result);
}
Beispiel #6
0
void ChangeRouterPasswordOp::onCreateProfileFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("createWlanProfile result: %1").arg(result));
    if (result == WlanRadioOffError || result == WlanServiceDownError || result == WlanNoDeviceError)
    {
        return notifyFinished(NoError);
    }

    if (result != AsyncOp::NoError)
    {
        return notifyFinished(result);
    }

    m_op = m_bean->reconnectRouter(3000, 10, m_infoResp.value(QLatin1String("NewWLANMACAddress")).toString(), m_infoResp.value(QLatin1String("NewSSID")).toString(), true);
    connect(m_op, SIGNAL(finished()), SLOT(onReconnectFinished()));
}
Beispiel #7
0
void ReconnectRouterOp::onDiscoverRouterFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("discoverRouter self aborted!"));
        return;
    }

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("discoverRouter op aborted!"));
        return notifyFinished(AbortedError);
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("discoverRouterSoap result: %1").arg(result));
    if (result != NoError)
    {
        return retry();
    }

    int matchIndex = op->value("matchIndex").toInt();
    LOG_DEBUG(QString::fromUtf8("matchIndex %1").arg(matchIndex));
    if (matchIndex < 0)
    {
        return retry();
    }

    copyValues(op);
    notifyFinished(NoError);
}
Beispiel #8
0
	void finishCall (int64_t call) {
		AsyncOp * op;
		op = getReadyAsyncOp (call);
		if (op) {
			assert (op->type() == 1 || op->type() == 2);
			if (op->type() == 1) { Op1 * op1 = (Op1*) op; op1->cb (op->id(), NoError); }
			if (op->type() == 2) { Op2 * op2 = (Op2*) op; op2->cb (op->id(), NoError, 0x12345678); }
		}
		delete op;
	}
Beispiel #9
0
void ChangeRouterWifiPasswordOp::onSetWLANFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("onSetWLANFinished %1").arg(result));
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    if (m_configFinish)
    {
        m_op = m_bean->m_soapCore->invoke(QLatin1String("DeviceConfig"), QLatin1String("ConfigurationFinished"), QLatin1String("NewStatus"), QLatin1String("ChangesApplied"));
        connect(m_op, SIGNAL(finished()), SLOT(onCommitFinished()));

        connect(&m_timer1, SIGNAL(timeout()), SLOT(onTimeout1()));
        m_timer1.setSingleShot(true);
        m_timer1.start(8000);
    }
    else
    {
        notifyFinished(NoError);
    }
}
Beispiel #10
0
void ChangeRouterWifiPasswordOp::onCommitFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    LOG_DEBUG(QString::fromUtf8("onCommitFinished %1").arg(op->result()));

    notifyFinished(NoError);
}
Beispiel #11
0
void ChangeRouterPasswordOp::onGetKeysFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    QVariant varResponse = op->value("response");
    if (!varResponse.isValid())
    {
        return notifyFinished(UnknownError);
    }

    QVariantMap resp = qvariant_cast<QVariantMap>(varResponse);
    m_currentWifiKey = resp.value(QLatin1String("NewWPAPassphrase")).toString();

    m_bean->m_soapCore->setWrappedMode(false);
    m_op = m_bean->m_soapCore->invoke(QLatin1String("LANConfigSecurity"), QLatin1String("GetInfo"));
    connect(m_op, SIGNAL(finished()), SLOT(onGetLanInfoFinished()));
}
Beispiel #12
0
void DiscoverRouterSoapOp::onSoapFinished()
{
    if (!m_mac.isNull())
    {
        AsyncOp *op = qobject_cast<AsyncOp*>(sender());
        if (op)
        {
            int index = -1;
            for (int i = 0; i < m_opList.count(); i++)
            {
                if (m_opList.at(i) == op)
                {
                    index = i;
                    break;
                }
            }
            if (index >= 0)
            {
                QString mac = op->values().value(QLatin1String("newwlanmacaddress")).toString().toUpper();
                if (mac.compare(m_mac, Qt::CaseInsensitive) == 0)
                {
                    LOG_DEBUG(QString::fromUtf8("DiscoverRouterSoapOp fast path for %1 %2").arg(mac).arg(m_ls.at(index)));
                    for (int i = 0; i < m_opList.count(); i++)
                    {
                        AsyncOp *op = m_opList.at(i);
                        disconnect(op, SIGNAL(finished()), this, SLOT(onSoapFinished()));
                        op->abort();
                    }
                    QVariantMap varMap = op->values();
                    varMap.insert(QLatin1String("soapHostName"), m_ls.at(index));
                    QVariantList fullList;
                    fullList.push_back(varMap);
                    setValue("fullList", fullList);
                    setValue("matchIndex", 0);
                    return notifyFinished(NoError);
                }
            }
        }
    }

    if (m_count++ == m_opList.count())
    {
        process();
    }
}
Beispiel #13
0
void ChangeRouterPasswordOp::onConfigOutFinished()
{
    m_timer1.stop();

    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        return;
    }

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

//	if (responseCode != 0) {
//		return notifyFinished(UnknownError);
//	}

//	notifyFinished(NoError);

    updateProfile();
}
Beispiel #14
0
void ChangeRouterPasswordOp::onWifiConfigFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    if (!m_adminPassword.isNull())
    {
        startAdminConfig();
    }
    else
    {
        startConfigOut();
    }
}
Beispiel #15
0
void ChangeRouterPasswordOp::onReconnectFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("reconnectRouter result: %1").arg(result));

    if (result != NoError)
    {
        notifyFinished(result);
    }

    notifyFinished(NoError);
}
Beispiel #16
0
void ChangeRouterWifiPasswordOp::onConfigStarted()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("onConfigStarted %1").arg(result));
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    m_op = m_bean->m_soapCore->invoke(NS_WLANConfiguration, QLatin1String("GetInfo"));
    connect(m_op, SIGNAL(finished()), SLOT(onGetInfoFinished()));
}
Beispiel #17
0
void RestartRouterOp::onConfigStarted()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("onConfigStarted %1").arg(result));
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    m_op = m_bean->m_soapCore->invoke(QLatin1String("DeviceConfig"), QLatin1String("ConfigurationFinished"), QLatin1String("NewStatus"), QLatin1String("RebootRequired"));
    connect(m_op, SIGNAL(finished()), SLOT(onConfigFinished()));
}
Beispiel #18
0
void EnsureSoapOp::onSoapFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    int result = op->result();
    if (result != NoError)
    {
        if (++m_currentCount <= m_retryCount)
        {
            LOG_DEBUG(QString::fromUtf8("EnsureSoap: failed, retry %1").arg(m_currentCount));
            m_timer1.start(m_delay);
            return;
        }
        LOG_DEBUG(QString::fromUtf8("EnsureSoap: no more chance!"));
        return notifyFinished(result);
    }

    LOG_DEBUG(QString::fromUtf8("EnsureSoap: OK!"));
    notifyFinished(NoError);
}
Beispiel #19
0
void RestartRouterOp::onConfigFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("onConfigFinished %1").arg(result));
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    notifyFinished(NoError);
}
Beispiel #20
0
void CheckRouterSoapOp::onGetInfo2Finished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (op->isAborted())
    {
        LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo2Finished() aborted"));
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo2Finished() %1").arg(result));

    if (result != NoError)
    {
        return notifyFinished(result);
    }

    bool ok;
    int responseCode = op->value("responseCode").toInt(&ok);
    if (!ok || responseCode != 0)
    {
        LOG_DEBUG(QString::fromUtf8("CheckRouterSoapOp::onGetInfo2Finished() response error: %1 %2").arg(responseCode).arg(ok));
        return notifyFinished(UnknownError);
    }

    m_values.unite(qvariant_cast<QVariantMap>(op->value("response")));

    SoapCore *soapCore = m_bean->m_soapCore;
    QString host = soapCore->host();
    soapCore->setHost(m_host);
    m_op = soapCore->invoke(QLatin1String("DeviceInfo"), QLatin1String("GetSysUpTime"));
    soapCore->setHost(host);
    connect(m_op, SIGNAL(finished()), SLOT(onGetInfo3Finished()));
}
Status NetworkInterfaceASIO::startCommand(const TaskExecutor::CallbackHandle& cbHandle,
                                          RemoteCommandRequest& request,
                                          const RemoteCommandCompletionFn& onFinish) {
    MONGO_ASIO_INVARIANT(onFinish, "Invalid completion function");
    {
        stdx::lock_guard<stdx::mutex> lk(_inProgressMutex);
        const auto insertResult = _inGetConnection.emplace(cbHandle);
        // We should never see the same CallbackHandle added twice
        MONGO_ASIO_INVARIANT_INLOCK(insertResult.second, "Same CallbackHandle added twice");
    }

    if (inShutdown()) {
        return {ErrorCodes::ShutdownInProgress, "NetworkInterfaceASIO shutdown in progress"};
    }

    LOG(2) << "startCommand: " << redact(request.toString());

    auto getConnectionStartTime = now();

    auto statusMetadata = attachMetadataIfNeeded(request, _metadataHook.get());
    if (!statusMetadata.isOK()) {
        return statusMetadata;
    }

    auto nextStep = [this, getConnectionStartTime, cbHandle, request, onFinish](
        StatusWith<ConnectionPool::ConnectionHandle> swConn) {

        if (!swConn.isOK()) {
            LOG(2) << "Failed to get connection from pool for request " << request.id << ": "
                   << swConn.getStatus();

            bool wasPreviouslyCanceled = false;
            {
                stdx::lock_guard<stdx::mutex> lk(_inProgressMutex);
                wasPreviouslyCanceled = _inGetConnection.erase(cbHandle) == 0;
            }

            Status status = wasPreviouslyCanceled
                ? Status(ErrorCodes::CallbackCanceled, "Callback canceled")
                : swConn.getStatus();
            if (status.code() == ErrorCodes::NetworkInterfaceExceededTimeLimit) {
                status = Status(ErrorCodes::ExceededTimeLimit, status.reason());
            }
            if (status.code() == ErrorCodes::ExceededTimeLimit) {
                _numTimedOutOps.fetchAndAdd(1);
            }
            if (status.code() != ErrorCodes::CallbackCanceled) {
                _numFailedOps.fetchAndAdd(1);
            }

            onFinish({status, now() - getConnectionStartTime});
            signalWorkAvailable();
            return;
        }

        auto conn = static_cast<connection_pool_asio::ASIOConnection*>(swConn.getValue().get());

        AsyncOp* op = nullptr;

        stdx::unique_lock<stdx::mutex> lk(_inProgressMutex);

        const auto eraseCount = _inGetConnection.erase(cbHandle);

        // If we didn't find the request, we've been canceled
        if (eraseCount == 0) {
            lk.unlock();

            onFinish({ErrorCodes::CallbackCanceled,
                      "Callback canceled",
                      now() - getConnectionStartTime});

            // Though we were canceled, we know that the stream is fine, so indicate success.
            conn->indicateSuccess();

            signalWorkAvailable();

            return;
        }

        // We can't release the AsyncOp until we know we were not canceled.
        auto ownedOp = conn->releaseAsyncOp();
        op = ownedOp.get();

        // This AsyncOp may be recycled. We expect timeout and canceled to be clean.
        // If this op was most recently used to connect, its state transitions won't have been
        // reset, so we do that here.
        MONGO_ASIO_INVARIANT_INLOCK(!op->canceled(), "AsyncOp has dirty canceled flag", op);
        MONGO_ASIO_INVARIANT_INLOCK(!op->timedOut(), "AsyncOp has dirty timeout flag", op);
        op->clearStateTransitions();

        // Now that we're inProgress, an external cancel can touch our op, but
        // not until we release the inProgressMutex.
        _inProgress.emplace(op, std::move(ownedOp));

        op->_cbHandle = std::move(cbHandle);
        op->_request = std::move(request);
        op->_onFinish = std::move(onFinish);
        op->_connectionPoolHandle = std::move(swConn.getValue());
        op->startProgress(getConnectionStartTime);

        // This ditches the lock and gets us onto the strand (so we're
        // threadsafe)
        op->_strand.post([this, op, getConnectionStartTime] {
            const auto timeout = op->_request.timeout;

            // Set timeout now that we have the correct request object
            if (timeout != RemoteCommandRequest::kNoTimeout) {
                // Subtract the time it took to get the connection from the pool from the request
                // timeout.
                auto getConnectionDuration = now() - getConnectionStartTime;
                if (getConnectionDuration >= timeout) {
                    // We only assume that the request timer is guaranteed to fire *after* the
                    // timeout duration - but make no stronger assumption. It is thus possible that
                    // we have already exceeded the timeout. In this case we timeout the operation
                    // manually.
                    std::stringstream msg;
                    msg << "Remote command timed out while waiting to get a connection from the "
                        << "pool, took " << getConnectionDuration << ", timeout was set to "
                        << timeout;
                    auto rs = ResponseStatus(ErrorCodes::NetworkInterfaceExceededTimeLimit,
                                             msg.str(),
                                             getConnectionDuration);
                    return _completeOperation(op, rs);
                }

                // The above conditional guarantees that the adjusted timeout will never underflow.
                MONGO_ASIO_INVARIANT(timeout > getConnectionDuration, "timeout underflowed", op);
                const auto adjustedTimeout = timeout - getConnectionDuration;
                const auto requestId = op->_request.id;

                try {
                    op->_timeoutAlarm =
                        op->_owner->_timerFactory->make(&op->_strand, adjustedTimeout);
                } catch (std::system_error& e) {
                    severe() << "Failed to construct timer for AsyncOp: " << e.what();
                    fassertFailed(40334);
                }

                std::shared_ptr<AsyncOp::AccessControl> access;
                std::size_t generation;
                {
                    stdx::lock_guard<stdx::mutex> lk(op->_access->mutex);
                    access = op->_access;
                    generation = access->id;
                }

                op->_timeoutAlarm->asyncWait(
                    [this, op, access, generation, requestId, adjustedTimeout](std::error_code ec) {
                        // We must pass a check for safe access before using op inside the
                        // callback or we may attempt access on an invalid pointer.
                        stdx::lock_guard<stdx::mutex> lk(access->mutex);
                        if (generation != access->id) {
                            // The operation has been cleaned up, do not access.
                            return;
                        }

                        if (!ec) {
                            LOG(2) << "Request " << requestId << " timed out"
                                   << ", adjusted timeout after getting connection from pool was "
                                   << adjustedTimeout << ", op was " << redact(op->toString());

                            op->timeOut_inlock();
                        } else {
                            LOG(2) << "Failed to time request " << requestId
                                   << "out: " << ec.message() << ", op was "
                                   << redact(op->toString());
                        }
                    });
            }

            _beginCommunication(op);
        });
    };

    _connectionPool.get(request.target, request.timeout, nextStep);
    return Status::OK();
}
void NetworkInterfaceASIO::startCommand(const TaskExecutor::CallbackHandle& cbHandle,
                                        const RemoteCommandRequest& request,
                                        const RemoteCommandCompletionFn& onFinish) {
    invariant(onFinish);
    {
        stdx::lock_guard<stdx::mutex> lk(_inProgressMutex);
        const auto insertResult = _inGetConnection.emplace(cbHandle);
        // We should never see the same CallbackHandle added twice
        invariant(insertResult.second);
    }

    LOG(2) << "startCommand: " << request.toString();

    auto startTime = now();

    auto nextStep = [this, startTime, cbHandle, request, onFinish](
        StatusWith<ConnectionPool::ConnectionHandle> swConn) {

        if (!swConn.isOK()) {
            LOG(2) << "Failed to get connection from pool: " << swConn.getStatus();

            bool wasPreviouslyCanceled = false;
            {
                stdx::lock_guard<stdx::mutex> lk(_inProgressMutex);
                wasPreviouslyCanceled = _inGetConnection.erase(cbHandle) == 0;
            }

            onFinish(wasPreviouslyCanceled
                         ? Status(ErrorCodes::CallbackCanceled, "Callback canceled")
                         : swConn.getStatus());
            signalWorkAvailable();
            return;
        }

        auto conn = static_cast<connection_pool_asio::ASIOConnection*>(swConn.getValue().get());

        AsyncOp* op = nullptr;

        stdx::unique_lock<stdx::mutex> lk(_inProgressMutex);

        const auto eraseCount = _inGetConnection.erase(cbHandle);

        // If we didn't find the request, we've been canceled
        if (eraseCount == 0) {
            lk.unlock();

            onFinish({ErrorCodes::CallbackCanceled, "Callback canceled"});

            // Though we were canceled, we know that the stream is fine, so indicate success.
            conn->indicateSuccess();

            signalWorkAvailable();

            return;
        }

        // We can't release the AsyncOp until we know we were not canceled.
        auto ownedOp = conn->releaseAsyncOp();
        op = ownedOp.get();

        // Sanity check that we are getting a clean AsyncOp.
        invariant(!op->canceled());
        invariant(!op->timedOut());

        // Now that we're inProgress, an external cancel can touch our op, but
        // not until we release the inProgressMutex.
        _inProgress.emplace(op, std::move(ownedOp));

        op->_cbHandle = std::move(cbHandle);
        op->_request = std::move(request);
        op->_onFinish = std::move(onFinish);
        op->_connectionPoolHandle = std::move(swConn.getValue());
        op->_start = startTime;

        // This ditches the lock and gets us onto the strand (so we're
        // threadsafe)
        op->_strand.post([this, op] {
            // Set timeout now that we have the correct request object
            if (op->_request.timeout != RemoteCommandRequest::kNoTimeout) {
                op->_timeoutAlarm =
                    op->_owner->_timerFactory->make(&op->_strand, op->_request.timeout);

                std::shared_ptr<AsyncOp::AccessControl> access;
                std::size_t generation;
                {
                    stdx::lock_guard<stdx::mutex> lk(op->_access->mutex);
                    access = op->_access;
                    generation = access->id;
                }

                op->_timeoutAlarm->asyncWait([this, op, access, generation](std::error_code ec) {
                    if (!ec) {
                        // We must pass a check for safe access before using op inside the
                        // callback or we may attempt access on an invalid pointer.
                        stdx::lock_guard<stdx::mutex> lk(access->mutex);
                        if (generation != access->id) {
                            // The operation has been cleaned up, do not access.
                            return;
                        }

                        LOG(2) << "Operation timed out: " << op->request().toString();

                        // An operation may be in mid-flight when it times out, so we
                        // cancel any in-progress async calls but do not complete the operation now.
                        op->_timedOut = 1;
                        if (op->_connection) {
                            op->_connection->cancel();
                        }
                    } else {
                        LOG(4) << "failed to time operation out: " << ec.message();
                    }
                });
            }

            _beginCommunication(op);
        });
    };

    // TODO: thread some higher level timeout through, rather than 5 minutes,
    // once we make timeouts pervasive in this api.
    _connectionPool.get(request.target, Minutes(5), nextStep);
}
	void openBrowseDialogCore(FileDialogType type, const Path& defaultPath, const String& filterList,
		Vector<Path>& paths, AsyncOp& returnValue)
	{
		// Init COM library.
		CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

		IFileDialog* fileDialog = nullptr;

		UINT32 dialogType = ((UINT32)type & (UINT32)FileDialogType::TypeMask);
		bool isOpenDialog = dialogType == (UINT32)FileDialogType::OpenFile || dialogType == (UINT32)FileDialogType::OpenFolder;

		// Create dialog
		IID classId = isOpenDialog ? CLSID_FileOpenDialog : CLSID_FileSaveDialog;
		CoCreateInstance(classId, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&fileDialog));

		addFiltersToDialog(fileDialog, filterList);
		setDefaultPath(fileDialog, defaultPath);

		// Apply multiselect flags
		bool isMultiselect = false;
		if (isOpenDialog)
		{
			if (dialogType == (UINT32)FileDialogType::OpenFile)
			{
				if (((UINT32)type & (UINT32)FileDialogType::Multiselect) != 0)
				{
					DWORD dwFlags;
					fileDialog->GetOptions(&dwFlags);
					fileDialog->SetOptions(dwFlags | FOS_ALLOWMULTISELECT);

					isMultiselect = true;
				}
			}
			else
			{
				DWORD dwFlags;
				fileDialog->GetOptions(&dwFlags);
				fileDialog->SetOptions(dwFlags | FOS_PICKFOLDERS);
			}
		}

		// Show the dialog
		bool finalResult = false;

		// Need to enable all windows, otherwise when the browse dialog closes the active window will become some 
		// background window
		Win32Window::_enableAllWindows();

		if (SUCCEEDED(fileDialog->Show(nullptr)))
		{
			if (isMultiselect)
			{
				// Get file names
				IFileOpenDialog* fileOpenDialog;
				fileDialog->QueryInterface(IID_IFileOpenDialog, (void**)&fileOpenDialog);
				
				IShellItemArray* shellItems = nullptr;
				fileOpenDialog->GetResults(&shellItems);

				getPaths(shellItems, paths);
				shellItems->Release();
				fileOpenDialog->Release();
			}
			else
			{
				// Get the file name
				IShellItem* shellItem = nullptr;
				fileDialog->GetResult(&shellItem);

				LPWSTR filePath = nullptr;
				shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath);

				paths.push_back((Path)UTF8::fromWide(WString(filePath)));
				CoTaskMemFree(filePath);

				shellItem->Release();
			}

			finalResult = true;
		}

		// Restore modal window state (before we enabled all windows)
		Win32Window::_restoreModalWindows();

		CoUninitialize();

		returnValue._completeOperation(finalResult);
	}
Beispiel #24
0
void DiscoverRouterSoapOp::process()
{
    QStringList ls1;
    QList<QVariantMap> ls2;
    for (int i = 0; i < m_opList.count(); i++)
    {
        AsyncOp *op = m_opList.at(i);
        if (op->isFinished() && op->result() == NoError)
        {
            ls1.append(m_ls.at(i));
            ls2.append(op->values());
        }
    }

    if (ls1.isEmpty())
    {
        LOG_DEBUG(QString::fromUtf8("No router found!"));
        notifyFinished(UnknownError);
        return;
    }

    QSet<QString> set1;
    int count = ls1.count();
    int i = 0;
    while (i < count)
    {
        const QVariantMap& varMap = ls2.at(i);
        QString mac = varMap.value(QLatin1String("newwlanmacaddress")).toString().toUpper();
        if (set1.find(mac) == set1.end())
        {
            set1.insert(mac);
            i++;
        }
        else
        {
            ls1.removeAt(i);
            ls2.removeAt(i);
            count--;
        }
    }

    int matchIndex = -1;
    QVariantList fullList;
    LOG_DEBUG(QString::fromUtf8("found %1 router(s)").arg(ls1.count()));
    for (int i = 0; i < ls1.count(); i++)
    {
        QString hostName = ls1.at(i);
        QVariantMap varMap = ls2.at(i);
        varMap.insert(QLatin1String("soapHostName"), hostName);
        QString mac = varMap.value(QLatin1String("newwlanmacaddress")).toString().toUpper();
        fullList.push_back(varMap);
        m_mac = mac;
        //if (!m_mac.isNull() && mac.compare(m_mac, Qt::CaseInsensitive) == 0) {
        matchIndex = i;
        //}
        LOG_DEBUG(QString::fromUtf8("%1 [%2]").arg(hostName).arg(mac));
    }

    setValue("fullList", fullList);
    setValue("matchIndex", matchIndex);
    notifyFinished(NoError);
}
Beispiel #25
0
void ChangeRouterWifiPasswordOp::onGetInfoFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    LOG_DEBUG(QString::fromUtf8("onGetInfoFinished %1").arg(result));
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    QVariant varResponse = op->value("response");
    if (!varResponse.isValid())
    {
        return notifyFinished(UnknownError);
    }

    QVariantMap response = qvariant_cast<QVariantMap>(varResponse);

    QString ssid = m_ssid.isNull() ? response.value(QLatin1String("NewSSID")).toString() : m_ssid;

    QStringList paramNames;
    QStringList paramValues;

    paramNames << QLatin1String("NewSSID") << QLatin1String("NewRegion") << QLatin1String("NewChannel") << QLatin1String("NewWirelessMode");
    paramValues << ssid << response.value(QLatin1String("NewRegion")).toString() << response.value(QLatin1String("NewChannel")).toString() << response.value(QLatin1String("NewWirelessMode")).toString();

    QString actionName;
    if (m_password.isNull())
    {
        actionName = QLatin1String("SetWLANNoSecurity");
    }
    else
    {
        actionName = QLatin1String("SetWLANWPAPSKByPassphrase");
        paramNames << QLatin1String("NewWPAEncryptionModes") << QLatin1String("NewWPAPassphrase");
        paramValues << QLatin1String("WPA2-PSK") << m_password;
    }
    m_bean->m_soapCore->setWrappedMode(false);
    m_op = m_bean->m_soapCore->invoke(NS_WLANConfiguration, actionName, paramNames, paramValues);
    connect(m_op, SIGNAL(finished()), SLOT(onSetWLANFinished()));
}
Beispiel #26
0
void ChangeRouterPasswordOp::onGetLanInfoFinished()
{
    AsyncOp *op = m_op;
    m_op->deleteLater();
    m_op = NULL;

    if (isAborted())
    {
        return;
    }

    int result = op->result();
    if (result != NoError)
    {
        return notifyFinished(result);
    }

    QVariant varResponseCode = op->value("responseCode");
    if (!varResponseCode.isValid())
    {
        return notifyFinished(UnknownError);
    }

    bool ok;
    int responseCode = varResponseCode.toInt(&ok);
    if (!ok)
    {
        return notifyFinished(UnknownError);
    }

    if (responseCode != 0)
    {
        return notifyFinished(UnknownError);
    }

    QVariant varResponse = op->value("response");
    if (!varResponse.isValid())
    {
        return notifyFinished(UnknownError);
    }

    QVariantMap resp = qvariant_cast<QVariantMap>(varResponse);

    /*	if (!m_wifiPassword.isNull()) {
    		if (m_currentWifiKey != m_oldWifiPassword) {
    			return notifyFinished(InvalidWifiPasswordError);
    		}
    	}
    */
    if (!m_adminPassword.isNull())
    {
        QString oldAdminPassword = resp.value(QLatin1String("NewPassword")).toString();
        if (oldAdminPassword != m_oldAdminPassword)
        {
            return notifyFinished(InvalidAdminPasswordError);
        }
    }

    m_bean->m_soapCore->setWrappedMode(false);
    m_op = m_bean->m_soapCore->invoke(QLatin1String("DeviceConfig"), QLatin1String("ConfigurationStarted"), QStringList(QLatin1String("NewSessionID")), QStringList(m_bean->m_soapCore->sessionId()));
    LOG_DEBUG(QString::fromUtf8("ConfigurationStarted ssid: %1").arg(m_bean->m_soapCore->sessionId()));
    connect(m_op, SIGNAL(finished()), SLOT(onConfigInFinished()));
}