void NeoCallProvider::clcc(bool, const QAtResult & result) { QModemCall *ic = incomingCall(); bool icMissing = true; int count = 0; // Find the current state of the call in the AT+CLCC results. QAtResultParser parser(result); while (parser.next("+CLCC:")) { uint id = parser.readNumeric(); parser.readNumeric(); // dir uint state = parser.readNumeric(); uint mode = parser.readNumeric(); parser.readNumeric(); // mpty QString number = QAtUtils::decodeNumber(parser); QString callType = resolveCallMode(mode); //qDebug() << "=============== CLCC id=" << id << ", state =" << state << // ", mode=" << mode << ", number=" << number << "callType=" << callType; if (state == 4) { // incoming if (ic && ic->number() == number) { icMissing = false; // still ringing } else { // new incoming call QModemCallProvider::ringing(number, callType, id); announceCall(); clccTimer.start(CLCC_POLL_INTERVAL); return; } } count++; } // We still have call in incoming state if (ic) { if (icMissing) { qLog(Modem) << "Reporting missed call."; // but it's missing in CLCC list ic->setState(QPhoneCall::Missed); // make the call missed return; } clccTimer.start(CLCC_POLL_INTERVAL); // continue with polling return; } // We still have some connected calls if (count > 0) { clccTimer.start(CLCC_POLL_INTERVAL); // continue with polling return; } qLog(Modem) << "No more calls left"; QList < QPhoneCallImpl * >list = calls(); QList < QPhoneCallImpl * >::ConstIterator it; for (it = list.begin(); it != list.end(); ++it) { (*it)->setState(QPhoneCall::HangupRemote); } }
void NeoCallProvider::cpiNotification( const QString& msg ) { // Call progress notification for the NEO device. // %CPI: <id>,<msgType>,<ibt>,<tch>,<dir>,<mode>,<number>,<ton>,<alpha> // where <id> is the call identifier, and <msgType> is one of: // 0 = SETUP, 1 = DISCONNECT, 2 = ALERT, 3 = PROCEED, // 4 = SYNCHRONIZATION, 5 = PROGRESS, 6 = CONNECTED, // 7 = RELEASE, 8 = REJECT // dir: 0 = mobile originated, 1 = mobile terminated, 2 = network initiaited mobile // originated call, 3 = redialing mobile originated uint posn = 5; uint identifier = QAtUtils::parseNumber( msg, posn ); uint status = QAtUtils::parseNumber( msg, posn ); QAtUtils::skipField( msg, posn ); QAtUtils::skipField( msg, posn ); uint direction = QAtUtils::parseNumber( msg, posn ); QModemCall *call = callForIdentifier( identifier ); if ( status == 6 && call && ( call->state() == QPhoneCall::Dialing || call->state() == QPhoneCall::Alerting ) ) { // This is an indication that a "Dialing" connection // is now in the "Connected" state. call->setConnected(); } else if ( ( status == 1 || status == 7 ) && call && ( call->state() == QPhoneCall::Dialing || call->state() == QPhoneCall::Alerting ) ) { // We never managed to connect. hangupRemote( call ); } else if ( status == 2 && call && call->state() == QPhoneCall::Dialing ) { // Call is moving from Dialing to Alerting. call->setState( QPhoneCall::Alerting ); } else if ( ( status == 1 || status == 7 ) && call && ( call->state() == QPhoneCall::Connected || call->state() == QPhoneCall::Hold ) ) { // This is an indication that the connection has been lost. hangupRemote( call ); } else if ( ( status == 1 || status == 7 ) && call && call->state() == QPhoneCall::Incoming ) { // This is an indication that an incoming call was missed. call->setState( QPhoneCall::Missed ); } else if ( ( status == 2 || status == 4 || status == 0) && !call && direction == 1) { // only for incoming calls // if you make an outgoing call, these states can occur, but // we don't want an aborted outgoing call to be registered as missed // therefore we use the direction parameter // This is a newly waiting call. Treat it the same as "RING". uint mode = QAtUtils::parseNumber( msg, posn ); QString callType; if ( mode == 1 || mode == 6 || mode == 7 ) callType = "Data"; // No tr else if ( mode == 2 || mode == 8 ) callType = "Fax"; // No tr else callType = "Voice"; // No tr QString number = QAtUtils::nextString( msg, posn ); uint type = QAtUtils::parseNumber( msg, posn ); ringing( QAtUtils::decodeNumber( number, type ), callType, identifier ); // We got everything we need, indicate the call to the outside world announceCall(); } }