Exemple #1
0
// Call callbacks
void Endpoint::on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallStateParam prm;
    prm.e.fromPj(*e);
    
    call->processStateChange(prm);
    /* If the state is DISCONNECTED, call may have already been deleted
     * by the application in the callback, so do not access it anymore here.
     */
}
Exemple #2
0
void Endpoint::on_stream_destroyed(pjsua_call_id call_id,
                                   pjmedia_stream *strm,
                                   unsigned stream_idx)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnStreamDestroyedParam prm;
    prm.stream = strm;
    prm.streamIdx = stream_idx;
    
    call->onStreamDestroyed(prm);
}
Exemple #3
0
static void mainProg1() throw(Error)
{
    Endpoint ep;

    // Create library
    ep.libCreate();

    // Init library
    EpConfig ep_cfg;
    ep_cfg.logConfig.level = 4;
    ep.libInit( ep_cfg );

    // Transport
    TransportConfig tcfg;
    tcfg.port = 5060;
    ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);

    // Start library
    ep.libStart();
    std::cout << "*** PJSUA2 STARTED ***" << std::endl;

    // Add account
    AccountConfig acc_cfg;
    acc_cfg.idUri = "sip:[email protected]";
    acc_cfg.regConfig.registrarUri = "sip:pjsip.org";
    acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*",
                                                        "test1", 0, "test1") );
    std::auto_ptr<MyAccount> acc(new MyAccount);
    acc->create(acc_cfg);
    
    pj_thread_sleep(2000);
    
    // Make outgoing call
    Call *call = new MyCall(*acc);
    acc->calls.push_back(call);
    CallOpParam prm(true);
    prm.opt.audioCount = 1;
    prm.opt.videoCount = 0;
    call->makeCall("sip:[email protected]", prm);
    
    // Hangup all calls
    pj_thread_sleep(8000);
    ep.hangupAllCalls();
    pj_thread_sleep(4000);
    
    // Destroy library
    std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl;
}
Exemple #4
0
void
BluetoothHfpManager::SendCLCC(Call& aCall, int aIndex)
{
  NS_ENSURE_TRUE_VOID(aCall.mState !=
                        nsITelephonyService::CALL_STATE_DISCONNECTED);
  NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);

  BluetoothHandsfreeCallState callState =
    ConvertToBluetoothHandsfreeCallState(aCall.mState);

  if (mPhoneType == PhoneType::CDMA && aIndex == 1 && aCall.IsActive()) {
    callState = (mCdmaSecondCall.IsActive()) ? HFP_CALL_STATE_HELD :
                                               HFP_CALL_STATE_ACTIVE;
  }

  if (callState == HFP_CALL_STATE_INCOMING &&
      FindFirstCall(nsITelephonyService::CALL_STATE_CONNECTED)) {
    callState = HFP_CALL_STATE_WAITING;
  }

  sBluetoothHfpInterface->ClccResponse(
    aIndex, aCall.mDirection, callState, HFP_CALL_MODE_VOICE,
    HFP_CALL_MPTY_TYPE_SINGLE, aCall.mNumber,
    aCall.mType, mDeviceAddress, new ClccResponseResultHandler());
}
Exemple #5
0
void Endpoint::on_call_tsx_state(pjsua_call_id call_id,
                                 pjsip_transaction *tsx,
                                 pjsip_event *e)
{
    PJ_UNUSED_ARG(tsx);

    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallTsxStateParam prm;
    prm.e.fromPj(*e);
    
    call->onCallTsxState(prm);
}
// This test verifies if the role is invalid in scheduler's framework message,
// the event is error on the stream in response to a Subscribe call request.
TEST_P(SchedulerHttpApiTest, RejectFrameworkWithInvalidRole)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  Call call;
  call.set_type(Call::SUBSCRIBE);

  Call::Subscribe* subscribe = call.mutable_subscribe();
  v1::FrameworkInfo framework = v1::DEFAULT_FRAMEWORK_INFO;
  // Set invalid role.
  framework.set_role("/test/test1");
  subscribe->mutable_framework_info()->CopyFrom(framework);

  // Retrieve the parameter passed as content type to this test.
  const string contentType = GetParam();

  process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL);
  headers["Accept"] = contentType;

  Future<Response> response = process::http::streaming::post(
      master.get()->pid,
      "api/v1/scheduler",
      headers,
      serialize(call, contentType),
      contentType);

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
  AWAIT_EXPECT_RESPONSE_HEADER_EQ("chunked", "Transfer-Encoding", response);
  ASSERT_EQ(Response::PIPE, response.get().type);

  Option<Pipe::Reader> reader = response.get().reader;
  ASSERT_SOME(reader);

  auto deserializer = lambda::bind(
      &SchedulerHttpApiTest::deserialize, this, contentType, lambda::_1);

  Reader<Event> responseDecoder(Decoder<Event>(deserializer), reader.get());

  Future<Result<Event>> event = responseDecoder.read();
  AWAIT_READY(event);
  ASSERT_SOME(event.get());

  // Check event type is error.
  ASSERT_EQ(Event::ERROR, event.get().get().type());
}
Exemple #7
0
//==========================================================================================================
// If call-id exists, return the call that it is mapped to.
// If not create a new call object. Its direction will be the direction of its first message.
//==========================================================================================================
Call* ScriptReader::CallsMap::get_call(SipMessage* msg)
{
    string call_id = msg->get_call_id();
    Call* call;

    if(calls_map.count(call_id) != 0)
    {
        call = calls_map[call_id];
        call->update(msg);
        return call;
    }
    else
    {
        calls_map[call_id] = new Call(++last_call_num, msg);
        return calls_map[call_id];
    }
}
Exemple #8
0
void Call::xferReplaces(const Call& dest_call,
                  const CallOpParam &prm) throw(Error)
{
    call_param param(prm.txOption);
    
    PJSUA2_CHECK_EXPR(pjsua_call_xfer_replaces(id, dest_call.getId(),
                                               prm.options, param.p_msg_data) );
}
Exemple #9
0
void SIPEngine::onAnswer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp)
{
    Call *pCall = (Call*)is->getAppDialogSet().get();

    const char* peerIP = sdp.session().origin().getAddress().c_str();
    unsigned int peerPort = sdp.session().media().front().port();

    LOG("Outgoing call was answered. SDP: "<<peerIP<<":"<<peerPort);

    Dumais::Sound::RTPSession *rtpSession = pCall->getRTPSession();
    rtpSession->setPeerAddress(peerIP, peerPort);
    rtpSession->start();

    pCall->mCallState = Answered;
    mpObserver->onAnswer(pCall);

}
  string serialize(const Call& call, const string& contentType)
  {
    if (contentType == APPLICATION_PROTOBUF) {
      return call.SerializeAsString();
    }

    return stringify(JSON::protobuf(call));
  }
    void resourceOffers(const vector<Offer>& offers)
    {
        foreach (const Offer& offer, offers) {
            cout << "Received offer " << offer.id() << " with " << offer.resources()
                 << endl;

            static const Resources TASK_RESOURCES = Resources::parse(
                    "cpus:" + stringify(CPUS_PER_TASK) +
                    ";mem:" + stringify(MEM_PER_TASK)).get();

            Resources remaining = offer.resources();

            // Launch tasks.
            vector<TaskInfo> tasks;
            while (tasksLaunched < totalTasks &&
                    TASK_RESOURCES <= remaining.flatten()) {
                int taskId = tasksLaunched++;

                cout << "Launching task " << taskId << " using offer "
                     << offer.id() << endl;

                TaskInfo task;
                task.set_name("Task " + lexical_cast<string>(taskId));
                task.mutable_task_id()->set_value(
                    lexical_cast<string>(taskId));
                task.mutable_slave_id()->MergeFrom(offer.slave_id());
                task.mutable_executor()->MergeFrom(executor);

                Option<Resources> resources =
                    remaining.find(TASK_RESOURCES, framework.role());

                CHECK_SOME(resources);
                task.mutable_resources()->MergeFrom(resources.get());
                remaining -= resources.get();

                tasks.push_back(task);
            }

            Call call;
            call.mutable_framework_info()->CopyFrom(framework);
            call.set_type(Call::LAUNCH);

            Call::Launch* launch = call.mutable_launch();
            foreach (const TaskInfo& taskInfo, tasks) {
                launch->add_task_infos()->CopyFrom(taskInfo);
            }
Exemple #12
0
  void killTask(const TaskID& taskId, const AgentID& agentId)
  {
    cout << "Asked to kill task '" << taskId
         << "' on agent '" << agentId << "'" << endl;

    Call call;
    call.set_type(Call::KILL);

    CHECK(frameworkInfo.has_id());
    call.mutable_framework_id()->CopyFrom(frameworkInfo.id());

    Call::Kill* kill = call.mutable_kill();
    kill->mutable_task_id()->CopyFrom(taskId);
    kill->mutable_agent_id()->CopyFrom(agentId);

    mesos->send(call);
  }
Exemple #13
0
	Call::Call(const Call& src) :
	    DocumentObject(src.getDocument(),"",0),
	    _callType(src._callType), _destinationEntry(src._destinationEntry), 
	    _callMean(src._callMean), _histogram(src._histogram),
	    _hasResultVarianceWaitingTime(false),
	    _resultWaitingTime(0.0), _resultWaitingTimeVariance(0.0),
	    _resultVarianceWaitingTime(0.0), _resultVarianceWaitingTimeVariance(0.0),
	    _resultDropProbability(0.0), _resultDropProbabilityVariance(0.0)
	{
	}
Exemple #14
0
// must be locked
vector<Call> CallManager::getClientList(unsigned int translator)
{
	vector<Call> calllist;
	for (int i=0; i<calls.size(); i++) {
		Call *call = calls[i];
		PhoneCall *pcall = dynamic_cast<PhoneCall *>(call);
		if (pcall) {
			if (pcall->getTranslator() != translator)
				continue;

			pcall->lock();
			Call callc = *pcall;
			pcall->unlock();
			callc.reset_lock();
			calllist.push_back(callc);
		}
	}
	return calllist;
}
static gboolean
dtmf_pressed(RingMainWindow *win,
              GdkEventKey *event,
              G_GNUC_UNUSED gpointer user_data)
{
    g_return_val_if_fail(event->type == GDK_KEY_PRESS, GDK_EVENT_PROPAGATE);

    /* we want to react to digit key presses, as long as a GtkEntry is not the
     * input focus
     */
    GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(win));
    if (GTK_IS_ENTRY(focus))
        return GDK_EVENT_PROPAGATE;

    /* make sure that a call is selected*/
    QItemSelectionModel *selection = CallModel::instance().selectionModel();
    QModelIndex idx = selection->currentIndex();
    if (!idx.isValid())
        return GDK_EVENT_PROPAGATE;

    /* make sure that the selected call is in progress */
    Call *call = CallModel::instance().getCall(idx);
    Call::LifeCycleState state = call->lifeCycleState();
    if (state != Call::LifeCycleState::PROGRESS)
        return GDK_EVENT_PROPAGATE;

    /* filter out cretain MOD masked key presses so that, for example, 'Ctrl+c'
     * does not result in a 'c' being played.
     * we filter Ctrl, Alt, and SUPER/HYPER/META keys */
    if ( event->state
        & ( GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK ))
        return GDK_EVENT_PROPAGATE;

    /* pass the character that was entered to be played by the daemon;
     * the daemon will filter out invalid DTMF characters */
    guint32 unicode_val = gdk_keyval_to_unicode(event->keyval);
    QString val = QString::fromUcs4(&unicode_val, 1);
    call->playDTMF(val);
    g_debug("attemptingto play DTMF tone during ongoing call: %s", val.toUtf8().constData());

    /* always propogate the key, so we don't steal accelerators/shortcuts */
    return GDK_EVENT_PROPAGATE;
}
// This test sends a unsupported Accept media type for the Accept
// header. The response should be NotAcceptable in this case.
TEST_P(ExecutorHttpApiTest, NotAcceptable)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  Future<Nothing> __recover = FUTURE_DISPATCH(_, &Slave::__recover);

  Try<PID<Slave>> slave = StartSlave();
  ASSERT_SOME(slave);

  AWAIT_READY(__recover);

  // Wait for recovery to be complete.
  Clock::pause();
  Clock::settle();

  // Retrieve the parameter passed as content type to this test.
  const ContentType contentType = GetParam();

  process::http::Headers headers;
  headers["Accept"] = "foo";

  // Only subscribe needs to 'Accept' JSON or protobuf.
  Call call;
  call.mutable_framework_id()->set_value("dummy_framework_id");
  call.mutable_executor_id()->set_value("dummy_executor_id");

  call.set_type(Call::SUBSCRIBE);

  call.mutable_subscribe();

  Future<Response> response = process::http::streaming::post(
      slave.get(),
      "api/v1/executor",
      headers,
      serialize(contentType, call),
      stringify(contentType));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(NotAcceptable().status, response);

  Shutdown();
}
Exemple #17
0
void Endpoint::on_call_transfer_request2(pjsua_call_id call_id,
                                         const pj_str_t *dst,
                                         pjsip_status_code *code,
                                         pjsua_call_setting *opt)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallTransferRequestParam prm;
    prm.dstUri = pj2Str(*dst);
    prm.statusCode = *code;
    prm.opt.fromPj(*opt);
    
    call->onCallTransferRequest(prm);
    
    *code = prm.statusCode;
    *opt = prm.opt.toPj();
}
Exemple #18
0
  void doReliableRegistration()
  {
    if (state == SUBSCRIBED || state == DISCONNECTED) {
      return;
    }

    Call call;
    call.set_type(Call::SUBSCRIBE);

    if (frameworkInfo.has_id()) {
      call.mutable_framework_id()->CopyFrom(frameworkInfo.id());
    }

    Call::Subscribe* subscribe = call.mutable_subscribe();
    subscribe->mutable_framework_info()->CopyFrom(frameworkInfo);

    mesos->send(call);

    process::delay(Seconds(1), self(), &Self::doReliableRegistration);
  }
Exemple #19
0
void Endpoint::on_stream_created(pjsua_call_id call_id,
                                 pjmedia_stream *strm,
                                 unsigned stream_idx,
                                 pjmedia_port **p_port)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnStreamCreatedParam prm;
    prm.stream = strm;
    prm.streamIdx = stream_idx;
    prm.pPort = (void *)*p_port;
    
    call->onStreamCreated(prm);
    
    if (prm.pPort != (void *)*p_port)
        *p_port = (pjmedia_port *)prm.pPort;
}
void map_ids(const Call& o){
	Container::map_id_to_number()[o.getId()] = Container::get_id_counter();
	if(o.type == "fsm"){
		bool isResolved = o.lib->contains_fsm(o.text);
		if(isResolved) o.lib->map_ids_fsm(o.text, o.id);
	}
	if(o.type == "bt"){
		bool isResolved = o.lib->contains_tree(o.text);
		if(isResolved) o.lib->map_ids_tree(o.text, o.id);
	}
}
Exemple #21
0
void SIPEngine::onProvisional(resip::ClientInviteSessionHandle cis, const resip::SipMessage& msg)
{
    Call *call = (Call*)cis->getAppDialogSet().get();

    switch (msg.header(h_StatusLine).statusCode())
    {
    case 100:
        break;
    case 180:
        {
            if (call->mCallState==Initial)
            {
                LOG("Call is ringing");
                call->mCallState = Ringing;            
                AppDialogSetRONACommand cmd(call->getHandle());
                mDum->getSipStack().post(cmd,mRONATimeout,mDum);
            }
        }   
        break;
    }
}
  void update(const TaskInfo& task, const TaskState& state)
  {
    UUID uuid = UUID::random();

    TaskStatus status;
    status.mutable_task_id()->CopyFrom(task.task_id());
    status.mutable_executor_id()->CopyFrom(executorId);
    status.set_state(state);
    status.set_source(TaskStatus::SOURCE_EXECUTOR);
    status.set_timestamp(process::Clock::now().secs());
    status.set_uuid(uuid.toBytes());

    Call call;
    call.mutable_framework_id()->CopyFrom(frameworkId);
    call.mutable_executor_id()->CopyFrom(executorId);

    call.set_type(Call::UPDATE);

    call.mutable_update()->mutable_status()->CopyFrom(status);

    // Capture the status update.
    updates[uuid] = call.update();

    mesos->send(call);
  }
static void
search_entry_placecall(G_GNUC_UNUSED GtkWidget *entry, gpointer win)
{
    RingMainWindowPrivate *priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(win));

    const gchar *number_entered = gtk_entry_get_text(GTK_ENTRY(priv->search_entry));

    if (number_entered && strlen(number_entered) > 0) {
        /* detect Ring hash */
        gboolean is_ring_hash = FALSE;
        if (strlen(number_entered) == 40) {
            is_ring_hash = TRUE;
            /* must be 40 chars long and alphanumeric */
            for (int i = 0; i < 40 && is_ring_hash; ++i) {
                if (!g_ascii_isalnum(number_entered[i]))
                    is_ring_hash = FALSE;
            }
        }

        QString number = QString{number_entered};

        if (is_ring_hash)
            number = "ring:" + number;

        g_debug("dialing to number: %s", number.toUtf8().constData());

        Call *call = priv->q_completion_model->call();
        call->setDialNumber(number);
        call->performAction(Call::Action::ACCEPT);

        /* make this the currently selected call */
        QModelIndex idx = CallModel::instance().getIndex(call);
        CallModel::instance().selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);

        /* move focus away from entry so that DTMF tones can be entered via the keyboard */
        gtk_widget_child_focus(GTK_WIDGET(win), GTK_DIR_TAB_FORWARD);
        /* clear the entry */
        gtk_entry_set_text(GTK_ENTRY(priv->search_entry), "");
    }
}
// This test sets an unsupported media type as Content-Type. This
// should result in a 415 (UnsupportedMediaType) response.
TEST_P(ExecutorHttpApiTest, UnsupportedContentMediaType)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  Future<Nothing> __recover = FUTURE_DISPATCH(_, &Slave::__recover);

  Try<PID<Slave>> slave = StartSlave();
  ASSERT_SOME(slave);

  AWAIT_READY(__recover);

  // Wait for recovery to be complete.
  Clock::pause();
  Clock::settle();

  ContentType contentType = GetParam();
  process::http::Headers headers;
  headers["Accept"] = stringify(contentType);

  Call call;
  call.mutable_framework_id()->set_value("dummy_framework_id");
  call.mutable_executor_id()->set_value("dummy_executor_id");
  call.set_type(Call::SUBSCRIBE);

  call.mutable_subscribe();

  const string unknownMediaType = "application/unknown-media-type";

  Future<Response> response = process::http::post(
      slave.get(),
      "api/v1/executor",
      headers,
      serialize(contentType, call),
      unknownMediaType);

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(UnsupportedMediaType().status, response);

  Shutdown();
}
Exemple #25
0
//----------------------------------------------------------------------
void SipPhone::incomingCallCb(pjsua_acc_id acc_id, pjsua_call_id call_id,
                              pjsip_rx_data *rdata)
{
    pjsua_call_info ci;

    PJ_UNUSED_ARG(acc_id);
    PJ_UNUSED_ARG(rdata);

    pjsua_call_get_info(call_id, &ci);

    if (pjsua_call_get_count() <= 1)
        Sound::getInstance().startRing();

    Call *call = new Call(self_, Call::TYPE_INCOMING);
    call->setCallId(call_id);
    call->setUrl(ci.remote_contact.ptr);
    call->setName(ci.remote_info.ptr);
    LogInfo info(LogInfo::STATUS_MESSAGE, "pjsip", 0, "Incoming Call");
    self_->signalLogData(info);

    self_->signalIncomingCall(call);
}
Exemple #26
0
void Endpoint::on_pager_status2( pjsua_call_id call_id,
				 const pj_str_t *to,
				 const pj_str_t *body,
				 void *user_data,
				 pjsip_status_code status,
				 const pj_str_t *reason,
				 pjsip_tx_data *tdata,
				 pjsip_rx_data *rdata,
				 pjsua_acc_id acc_id)
{
    PJ_UNUSED_ARG(tdata);

    OnInstantMessageStatusParam prm;
    prm.userData	= user_data;
    prm.toUri		= pj2Str(*to);
    prm.msgBody		= pj2Str(*body);
    prm.code		= status;
    prm.reason		= pj2Str(*reason);
    if (rdata)
	prm.rdata.fromPj(*rdata);

    if (call_id != PJSUA_INVALID_ID) {
	Call *call = lookupCall(call_id, "on_pager_status2()");
	if (!call) {
	    /* Ignored */
	    return;
	}

	call->onInstantMessageStatus(prm);
    } else {
	Account *acc = lookupAcc(acc_id, "on_pager_status2()");
	if (!acc) {
	    /* Ignored */
	    return;
	}

	acc->onInstantMessageStatus(prm);
    }
}
// This test sends a Call from an unknown FrameworkID. The call
// should return a BadRequest.
TEST_P(ExecutorHttpApiTest, MessageFromUnknownFramework)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  Future<Nothing> __recover = FUTURE_DISPATCH(_, &Slave::__recover);

  Try<PID<Slave>> slave = StartSlave();
  ASSERT_SOME(slave);

  AWAIT_READY(__recover);

  // Wait for recovery to be complete.
  Clock::pause();
  Clock::settle();

  ContentType contentType = GetParam();
  process::http::Headers headers;
  headers["Accept"] = stringify(contentType);

  Call call;
  call.mutable_framework_id()->set_value("dummy_framework_id");
  call.mutable_executor_id()->set_value("dummy_executor_id");
  call.set_type(Call::MESSAGE);

  call.mutable_message()->set_data("hello world");

  Future<Response> response = process::http::post(
      slave.get(),
      "api/v1/executor",
      headers,
      serialize(contentType, call),
      stringify(contentType));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);

  Shutdown();
}
Exemple #28
0
    int f(ptime time, int dt) {
        NF *f = new NF;
        f->set_dt(dt);
        f->set_allocated_current_time(ptime_to_DataTime(time));
        assert(f->IsInitialized());

        Call c;
        c.set_type(Call::N_F);
        c.set_allocated_n_f(f);
        assert(c.IsInitialized());

        std::string buf = c.SerializeAsString();
        zmq::message_t req((void*) buf.data(), buf.length(), 0);

        socket.send(req);
        zmq::message_t resp;
        socket.recv(&resp);

        Response r;
        r.ParseFromArray(resp.data(), resp.size());
        assert(r.type() == Call::N_F);
        return r.n_f();
    }
// This test does not set any Accept header for the subscribe call.
// The default response media type should be "application/json" in
// this case.
TEST_P(ExecutorHttpApiTest, NoAcceptHeader)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  Try<PID<Slave>> slave = StartSlave();
  ASSERT_SOME(slave);

  Future<Nothing> __recover = FUTURE_DISPATCH(_, &Slave::__recover);
  AWAIT_READY(__recover);

  // Retrieve the parameter passed as content type to this test.
  const ContentType contentType = GetParam();

  // No 'Accept' header leads to all media types considered
  // acceptable. JSON will be chosen by default.
  hashmap<string, string> headers;

  // Only subscribe needs to 'Accept' JSON or protobuf.
  Call call;
  call.set_type(Call::SUBSCRIBE);

  call.mutable_framework_id()->set_value("dummy_framework_id");
  call.mutable_executor_id()->set_value("dummy_executor_id");

  Future<Response> response = process::http::streaming::post(
      slave.get(),
      "api/v1/executor",
      headers,
      serialize(contentType, call),
      stringify(contentType));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
  EXPECT_SOME_EQ(APPLICATION_JSON, response.get().headers.get("Content-Type"));

  Shutdown();
}
void CallHandler::callCmd(const QStringList &args) {
	CallID id = args.at(0).toInt();

	if (ignore.contains(id))
		return;

	bool newCall = false;

	Call *call;

	if (calls.contains(id)) {
		call = calls[id];
	} else {
		call = new Call(this, skype, id);
		calls[id] = call;
		newCall = true;

		connect(call, SIGNAL(startedCall(int, const QString &)), this, SIGNAL(startedCall(int, const QString &)));
		connect(call, SIGNAL(stoppedCall(int)),                  this, SIGNAL(stoppedCall(int)));
		connect(call, SIGNAL(startedRecording(int)),             this, SIGNAL(startedRecording(int)));
		connect(call, SIGNAL(stoppedRecording(int)),             this, SIGNAL(stoppedRecording(int)));
		connect(call, SIGNAL(showLegalInformation()),            this, SLOT(showLegalInformation()));
	}

	QString subCmd = args.at(1);

	if (subCmd == "STATUS")
		call->setStatus(args.at(2));
	else if (newCall && subCmd == "DURATION")
		// this is where we start recording calls that are already
		// running, for example if the user starts this program after
		// the call has been placed
		call->setStatus("INPROGRESS");

	prune();
}