mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
280 lines
7.5 KiB
C++
280 lines
7.5 KiB
C++
/*
|
|
daemon.h
|
|
Copyright (C) 2016 Belledonne Communications, Grenoble, France
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
|
your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this library; if not, write to the Free Software Foundation,
|
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifndef DAEMON_H_
|
|
#define DAEMON_H_
|
|
|
|
#include <linphone/core.h>
|
|
#include <linphone/core_utils.h>
|
|
#include <mediastreamer2/mediastream.h>
|
|
#include <mediastreamer2/mscommon.h>
|
|
#include <bctoolbox/list.h>
|
|
|
|
#include <string>
|
|
#include <list>
|
|
#include <queue>
|
|
#include <map>
|
|
#include <sstream>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#ifdef HAVE_READLINE
|
|
#ifdef HAVE_READLINE_H
|
|
#include <readline.h>
|
|
#else
|
|
#ifdef HAVE_READLINE_READLINE_H
|
|
#include <readline/readline.h>
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifdef HAVE_HISTORY_H
|
|
#include <history.h>
|
|
#else
|
|
#ifdef HAVE_READLINE_HISTORY_H
|
|
#include <readline/history.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
class Daemon;
|
|
|
|
class DaemonCommandExample {
|
|
public:
|
|
DaemonCommandExample(const std::string& command, const std::string& output);
|
|
~DaemonCommandExample() {}
|
|
const std::string &getCommand() const {
|
|
return mCommand;
|
|
}
|
|
const std::string &getOutput() const {
|
|
return mOutput;
|
|
}
|
|
private:
|
|
const std::string mCommand;
|
|
const std::string mOutput;
|
|
};
|
|
|
|
class DaemonCommand {
|
|
public:
|
|
virtual ~DaemonCommand() {}
|
|
virtual void exec(Daemon *app, const std::string& args)=0;
|
|
bool matches(const std::string& name) const;
|
|
const std::string getHelp() const;
|
|
const std::string &getProto() const {
|
|
return mProto;
|
|
}
|
|
const std::string &getDescription() const {
|
|
return mDescription;
|
|
}
|
|
const std::list<const DaemonCommandExample*> &getExamples() const {
|
|
return mExamples;
|
|
}
|
|
void addExample(const DaemonCommandExample *example);
|
|
protected:
|
|
DaemonCommand(const std::string& name, const std::string& proto, const std::string& description);
|
|
const std::string mName;
|
|
const std::string mProto;
|
|
const std::string mDescription;
|
|
std::list<const DaemonCommandExample*> mExamples;
|
|
};
|
|
|
|
class Response {
|
|
public:
|
|
enum Status {
|
|
Ok, Error
|
|
};
|
|
virtual ~Response() {
|
|
}
|
|
Response() :
|
|
mStatus(Ok) {
|
|
}
|
|
Response(const std::string& msg, Status status = Error):
|
|
mStatus(status) {
|
|
if( status == Ok) {
|
|
mBody = msg;
|
|
} else {
|
|
mReason = msg;
|
|
}
|
|
}
|
|
|
|
void setStatus(Status st) {
|
|
mStatus = st;
|
|
}
|
|
void setReason(const std::string& reason) {
|
|
mReason = reason;
|
|
}
|
|
void setBody(const std::string& body) {
|
|
mBody = body;
|
|
}
|
|
const std::string &getBody() const {
|
|
return mBody;
|
|
}
|
|
virtual std::string toBuf() const {
|
|
std::ostringstream buf;
|
|
std::string status = (mStatus == Ok) ? "Ok" : "Error";
|
|
buf << "Status: " << status << "\n";
|
|
if (!mReason.empty()) {
|
|
buf << "Reason: " << mReason << "\n";
|
|
}
|
|
if (!mBody.empty()) {
|
|
buf << "\n" << mBody << "\n";
|
|
}
|
|
return buf.str();
|
|
}
|
|
private:
|
|
Status mStatus;
|
|
std::string mReason;
|
|
std::string mBody;
|
|
};
|
|
|
|
class EventResponse: public Response {
|
|
public:
|
|
EventResponse(Daemon *daemon, LinphoneCall *call, LinphoneCallState state);
|
|
};
|
|
|
|
class CallStatsResponse: public Response {
|
|
public:
|
|
CallStatsResponse(Daemon *daemon, LinphoneCall *call, const LinphoneCallStats *stats, bool unique);
|
|
};
|
|
|
|
class AudioStreamStatsResponse: public Response {
|
|
public:
|
|
AudioStreamStatsResponse(Daemon *daemon, AudioStream *stream,
|
|
const LinphoneCallStats *stats, bool event);
|
|
};
|
|
|
|
class CallPlayingStatsResponse: public Response {
|
|
public:
|
|
CallPlayingStatsResponse(Daemon *daemon, int id);
|
|
};
|
|
|
|
class DtmfResponse: public Response {
|
|
public:
|
|
DtmfResponse(Daemon *daemon, LinphoneCall *call, int dtmf);
|
|
};
|
|
|
|
class PayloadTypeResponse: public Response {
|
|
public:
|
|
PayloadTypeResponse(LinphoneCore *core, const PayloadType *payloadType, int index = -1, const std::string &prefix = std::string(), bool enabled_status = true);
|
|
};
|
|
|
|
class PayloadTypeParser {
|
|
public:
|
|
PayloadTypeParser(LinphoneCore *core, const std::string &mime_type, bool accept_all = false);
|
|
inline bool all() { return mAll; }
|
|
inline bool successful() { return mSuccesful; }
|
|
inline PayloadType * getPayloadType()const{
|
|
return mPayloadType;
|
|
}
|
|
inline int getPosition()const{
|
|
return mPosition;
|
|
}
|
|
private:
|
|
bool mAll;
|
|
bool mSuccesful;
|
|
PayloadType *mPayloadType;
|
|
int mPosition;
|
|
};
|
|
|
|
struct AudioStreamAndOther {
|
|
AudioStream *stream;
|
|
OrtpEvQueue *queue;
|
|
LinphoneCallStats *stats;
|
|
AudioStreamAndOther(AudioStream *as) : stream(as) {
|
|
queue = ortp_ev_queue_new();
|
|
rtp_session_register_event_queue(as->ms.sessions.rtp_session, queue);
|
|
}
|
|
~AudioStreamAndOther() {
|
|
rtp_session_unregister_event_queue(stream->ms.sessions.rtp_session, queue);
|
|
ortp_ev_queue_destroy(queue);
|
|
}
|
|
};
|
|
|
|
class Daemon {
|
|
friend class DaemonCommand;
|
|
public:
|
|
typedef Response::Status Status;
|
|
Daemon(const char *config_path, const char *factory_config_path, const char *log_file, const char *pipe_name, bool display_video, bool capture_video);
|
|
~Daemon();
|
|
int run();
|
|
void quit();
|
|
void sendResponse(const Response &resp);
|
|
LinphoneCore *getCore();
|
|
LinphoneSoundDaemon *getLSD();
|
|
const std::list<DaemonCommand*> &getCommandList() const;
|
|
LinphoneCall *findCall(int id);
|
|
LinphoneProxyConfig *findProxy(int id);
|
|
LinphoneAuthInfo *findAuthInfo(int id);
|
|
AudioStream *findAudioStream(int id);
|
|
AudioStreamAndOther *findAudioStreamAndOther(int id);
|
|
void removeAudioStream(int id);
|
|
bool pullEvent();
|
|
int updateCallId(LinphoneCall *call);
|
|
int updateProxyId(LinphoneProxyConfig *proxy);
|
|
inline int maxProxyId() { return mProxyIds; }
|
|
inline int maxAuthInfoId() { return (int)bctbx_list_size(linphone_core_get_auth_info_list(mLc)); }
|
|
int updateAudioStreamId(AudioStream *audio_stream);
|
|
void dumpCommandsHelp();
|
|
void dumpCommandsHelpHtml();
|
|
void enableStatsEvents(bool enabled);
|
|
void enableLSD(bool enabled);
|
|
void enableAutoAnswer(bool enabled);
|
|
void callPlayingComplete(int id);
|
|
void setAutoVideo( bool enabled ){ mAutoVideo = enabled; }
|
|
inline bool autoVideo(){ return mAutoVideo; }
|
|
|
|
private:
|
|
static void* iterateThread(void *arg);
|
|
static void callStateChanged(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state, const char *msg);
|
|
static void callStatsUpdated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
|
|
static void dtmfReceived(LinphoneCore *lc, LinphoneCall *call, int dtmf);
|
|
void callStateChanged(LinphoneCall *call, LinphoneCallState state, const char *msg);
|
|
void callStatsUpdated(LinphoneCall *call, const LinphoneCallStats *stats);
|
|
void dtmfReceived(LinphoneCall *call, int dtmf);
|
|
void execCommand(const std::string &command);
|
|
std::string readLine(const std::string&, bool*);
|
|
std::string readPipe();
|
|
void iterate();
|
|
void iterateStreamStats();
|
|
void startThread();
|
|
void stopThread();
|
|
void initCommands();
|
|
void uninitCommands();
|
|
LinphoneCore *mLc;
|
|
LinphoneSoundDaemon *mLSD;
|
|
std::list<DaemonCommand*> mCommands;
|
|
std::queue<Response*> mEventQueue;
|
|
ortp_pipe_t mServerFd;
|
|
ortp_pipe_t mChildFd;
|
|
std::string mHistfile;
|
|
bool mRunning;
|
|
bool mUseStatsEvents;
|
|
bool mAutoAnswer;
|
|
FILE *mLogFile;
|
|
bool mAutoVideo;
|
|
int mCallIds;
|
|
int mProxyIds;
|
|
int mAudioStreamIds;
|
|
ms_thread_t mThread;
|
|
ms_mutex_t mMutex;
|
|
std::map<int, AudioStreamAndOther*> mAudioStreams;
|
|
};
|
|
|
|
#endif //DAEMON_H_
|