Improve help.

- Add examples for each command
 - Add the --dump-commands-help option to output the entire help
This commit is contained in:
Ghislain MARY 2012-10-26 17:18:30 +02:00
parent 6c2f4b9312
commit fec1c8ca74
27 changed files with 407 additions and 12 deletions

View file

@ -52,6 +52,19 @@ AdaptiveBufferCompensationCommand::AdaptiveBufferCompensationCommand() :
"Enable or disable adaptive buffer compensation respectively with the 'enable' and 'disable' parameters for the specified stream, "
"return the status of the use of adaptive buffer compensation without parameter.\n"
"<stream> must be one of these values: audio, video.") {
addExample(new DaemonCommandExample("adaptive-jitter-compensation audio",
"Status: Ok\n\n"
"Audio: enabled"));
addExample(new DaemonCommandExample("adaptive-jitter-compensation video",
"Status: Ok\n\n"
"Video: disabled"));
addExample(new DaemonCommandExample("adaptive-jitter-compensation",
"Status: Ok\n\n"
"Audio: enabled\n"
"Video: disabled"));
addExample(new DaemonCommandExample("adaptive-jitter-compensation video enable",
"Status: Ok\n\n"
"Video: enabled"));
}
void AdaptiveBufferCompensationCommand::exec(Daemon *app, const char *args) {

View file

@ -4,7 +4,21 @@ using namespace std;
AnswerCommand::AnswerCommand() :
DaemonCommand("answer", "answer <call id>", "Answer an incoming call.") {
addExample(new DaemonCommandExample("answer 3",
"Status: Error\n"
"Reason: No call with such id."));
addExample(new DaemonCommandExample("answer 2",
"Status: Error\n"
"Reason: Can't accept this call."));
addExample(new DaemonCommandExample("answer 1",
"Status: Ok"));
addExample(new DaemonCommandExample("answer",
"Status: Ok"));
addExample(new DaemonCommandExample("answer",
"Status: Error\n"
"Reason: No call to accept."));
}
void AnswerCommand::exec(Daemon *app, const char *args) {
LinphoneCore *lc = app->getCore();
int cid;

View file

@ -6,6 +6,31 @@ AudioCodecGetCommand::AudioCodecGetCommand() :
DaemonCommand("audio-codec-get", "audio-codec-get <payload_type_number|mime_type>",
"Get an audio codec if a parameter is given, otherwise return the audio codec list.\n"
"<mime_type> is of the form mime/rate/channels, eg. speex/16000/1") {
addExample(new DaemonCommandExample("audio-codec-get 9",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-get G722/8000/1",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-get 2",
"Status: Error\n"
"Reason: Audio codec not found."));
}
void AudioCodecGetCommand::exec(Daemon *app, const char *args) {

View file

@ -6,6 +6,28 @@ AudioCodecMoveCommand::AudioCodecMoveCommand() :
DaemonCommand("audio-codec-move", "audio-codec-move <payload_type_number|mime_type> <index>",
"Move a codec to the specified index.\n"
"<mime_type> is of the form mime/rate/channels, eg. speex/16000/1") {
addExample(new DaemonCommandExample("audio-codec-move 9 1",
"Status: Ok\n\n"
"Index: 1\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-move G722/8000/1 9",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
}
void AudioCodecMoveCommand::exec(Daemon *app, const char *args) {

View file

@ -10,6 +10,39 @@ AudioCodecSetCommand::AudioCodecSetCommand() :
DaemonCommand("audio-codec-set", "audio-codec-set <payload_type_number|mime_type> <property> <value>",
"Set a property (number, clock_rate, recv_fmtp, send_fmtp) of a codec. Numbering of payload type is automatically performed at startup, any change will be lost after restart.\n"
"<mime_type> is of the form mime/rate/channels, eg. speex/16000/1") {
addExample(new DaemonCommandExample("audio-codec-set 9 number 18",
"Status: Ok\n\n"
"Index: 10\n"
"Payload-type-number: 18\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-set G722/8000/1 number 9",
"Status: Ok\n\n"
"Index: 10\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-set 9 clock_rate 16000",
"Status: Ok\n\n"
"Index: 10\n"
"Payload-type-number: 9\n"
"Clock-rate: 16000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
}
static PayloadType *findPayload(LinphoneCore *lc, int payload_type, int *index){

View file

@ -50,10 +50,54 @@ AudioCodecEnableCommand::AudioCodecEnableCommand() :
AudioCodecToggleCommand("audio-codec-enable", "audio-codec-enable <payload_type_number|mime_type|ALL>",
"Enable an audio codec.\n"
"<mime_type> is of the form mime/rate/channels, eg. speex/16000/1", true) {
addExample(new DaemonCommandExample("audio-codec-enable G722/8000/1",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: true"));
addExample(new DaemonCommandExample("audio-codec-enable 9",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: true"));
}
AudioCodecDisableCommand::AudioCodecDisableCommand() :
AudioCodecToggleCommand("audio-codec-disable", "audio-codec-disable <payload_type_number|mime_type|ALL>",
"Disable an audio codec.\n"
"<mime_type> is of the form mime/rate/channels, eg. speex/16000/1", false) {
addExample(new DaemonCommandExample("audio-codec-disable G722/8000/1",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
addExample(new DaemonCommandExample("audio-codec-disable 9",
"Status: Ok\n\n"
"Index: 9\n"
"Payload-type-number: 9\n"
"Clock-rate: 8000\n"
"Bitrate: 64000\n"
"Mime: G722\n"
"Channels: 1\n"
"Recv-fmtp: \n"
"Send-fmtp: \n"
"Enabled: false"));
}

View file

@ -4,6 +4,9 @@ using namespace std;
AudioStreamStartCommand::AudioStreamStartCommand() :
DaemonCommand("audio-stream-start", "audio-stream-start <remote ip> <remote port> <payload type number>", "Start an audio stream.") {
addExample(new DaemonCommandExample("audio-stream-start 192.168.1.28 7078 9",
"Status: Ok\n\n"
"Id: 1"));
}
void AudioStreamStartCommand::exec(Daemon *app, const char *args) {

View file

@ -4,7 +4,13 @@ using namespace std;
AudioStreamStopCommand::AudioStreamStopCommand() :
DaemonCommand("audio-stream-stop", "audio-stream-stop <audio stream id>", "Stop an audio stream.") {
addExample(new DaemonCommandExample("audio-stream-stop 1",
"Status: Ok"));
addExample(new DaemonCommandExample("audio-stream-stop 2",
"Status: Error\n"
"Reason: No Audio Stream with such id."));
}
void AudioStreamStopCommand::exec(Daemon *app, const char *args) {
int id;
if (sscanf(args, "%d", &id) == 1) {

View file

@ -4,7 +4,35 @@ using namespace std;
CallStatsCommand::CallStatsCommand() :
DaemonCommand("call-stats", "call-stats <call id>", "Return all stats of a call.") {
addExample(new DaemonCommandExample("call-stats 1",
"Status: Ok\n\n"
"Audio-ICE state: Not activated\n"
"Audio-RoundTripDelay: 0.0859833\n"
"Audio-Jitter: 296\n"
"Audio-JitterBufferSizeMs: 47.7778\n"
"Audio-Received-InterarrivalJitter: 154\n"
"Audio-Received-FractionLost: 0\n"
"Audio-Sent-InterarrivalJitter: 296\n"
"Audio-Sent-FractionLost: 0\n"
"Audio-Payload-type-number: 111\n"
"Audio-Clock-rate: 16000\n"
"Audio-Bitrate: 44000\n"
"Audio-Mime: speex\n"
"Audio-Channels: 1\n"
"Audio-Recv-fmtp: vbr=on\n"
"Audio-Send-fmtp: vbr=on\n\n"
"Video-ICE state: Not activated\n"
"Video-RoundTripDelay: 0\n"
"Video-Jitter: 0\n"
"Video-JitterBufferSizeMs: 0State: disabled"));
addExample(new DaemonCommandExample("call-stats 2",
"Status: Error\n"
"Reason: No call with such id."));
addExample(new DaemonCommandExample("call-stats",
"Status: Error\n"
"Reason: No current call available."));
}
void CallStatsCommand::exec(Daemon *app, const char *args) {
LinphoneCore *lc = app->getCore();
int cid;

View file

@ -4,6 +4,18 @@ using namespace std;
CallStatusCommand::CallStatusCommand() :
DaemonCommand("call-status", "call-status <call id>", "Return status of a call.") {
addExample(new DaemonCommandExample("call-status 1",
"Status: Ok\n\n"
"State: LinphoneCallStreamsRunning\n"
"From: <sip:daemon-test@sip.linphone.org>\n"
"Direction: out\n"
"Duration: 6"));
addExample(new DaemonCommandExample("call-status 2",
"Status: Error\n"
"Reason: No call with such id."));
addExample(new DaemonCommandExample("call-status",
"Status: Error\n"
"Reason: No current call available."));
}
void CallStatusCommand::exec(Daemon *app, const char *args) {
LinphoneCore *lc = app->getCore();
@ -27,7 +39,7 @@ void CallStatusCommand::exec(Daemon *app, const char *args) {
call_state = linphone_call_get_state(call);
const LinphoneAddress *remoteAddress = linphone_call_get_remote_address(call);
ostringstream ostr;
ostr << linphone_call_state_to_string(call_state) << "\n";
ostr << "State: " << linphone_call_state_to_string(call_state) << "\n";
switch (call_state) {
case LinphoneCallOutgoingInit:

View file

@ -4,6 +4,12 @@ using namespace std;
CallCommand::CallCommand() :
DaemonCommand("call", "call <sip address>", "Place a call.") {
addExample(new DaemonCommandExample("call daemon-test@sip.linphone.org",
"Status: Ok\n\n"
"Id: 1"));
addExample(new DaemonCommandExample("call daemon-test@sip.linphone.org",
"Status: Error\n"
"Reason: Call creation failed."));
}
void CallCommand::exec(Daemon *app, const char *args) {

View file

@ -4,6 +4,12 @@ using namespace std;
DtmfCommand::DtmfCommand() :
DaemonCommand("dtmf", "dtmf <digit>", "Generate a DTMF (one of: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, *, #.") {
addExample(new DaemonCommandExample("dtmf 4",
"Status: Ok"));
addExample(new DaemonCommandExample("dtmf B",
"Status: Ok"));
addExample(new DaemonCommandExample("dtmf #",
"Status: Ok"));
}
void DtmfCommand::exec(Daemon *app, const char *args) {

View file

@ -37,6 +37,16 @@ FirewallPolicyCommand::FirewallPolicyCommand() :
"<type> must be one of these values: none, nat, stun, ice.\n"
"<address> must be specified for the 'nat' and 'stun' types. "
"It represents the public address of the gateway for the 'nat' type and the STUN server address for the 'stun' and 'ice' types.") {
addExample(new DaemonCommandExample("firewall-policy stun stun.linphone.org",
"Status: Ok\n\n"
"Type: stun\n"
"Address: stun.linphone.org"));
addExample(new DaemonCommandExample("firewall-policy none",
"Status: Ok\n\n"
"Type: none"));
addExample(new DaemonCommandExample("firewall-policy",
"Status: Ok\n\n"
"Type: none"));
}
void FirewallPolicyCommand::exec(Daemon *app, const char *args) {

View file

@ -5,15 +5,15 @@ using namespace std;
HelpCommand::HelpCommand() :
DaemonCommand("help", "help <command>", "Show <command> help notice, if command is unspecified or inexistent show all commands.") {
}
void HelpCommand::exec(Daemon *app, const char *args) {
char str[16384] = { 0 };
int written = 0;
ostringstream ost;
list<DaemonCommand*>::const_iterator it;
const list<DaemonCommand*> &l = app->getCommandList();
if (args){
for (it = l.begin(); it != l.end(); ++it) {
if ((*it)->matches(args)){
written += snprintf(str + written, sizeof(str)-1 - written, "\t%s\n%s\n", (*it)->getProto().c_str(),(*it)->getHelp().c_str());
ost << (*it)->getHelp();
break;
}
}
@ -22,10 +22,10 @@ void HelpCommand::exec(Daemon *app, const char *args) {
if (args==NULL){
for (it = l.begin(); it != l.end(); ++it) {
written += snprintf(str + written, sizeof(str)-1 - written, "\t%s\n", (*it)->getProto().c_str());
ost << (*it)->getHelp() << endl;
}
}
Response resp;
resp.setBody(str);
resp.setBody(ost.str().c_str());
app->sendResponse(resp);
}

View file

@ -22,6 +22,15 @@ IPv6Response::IPv6Response(LinphoneCore *core) : Response() {
IPv6Command::IPv6Command() :
DaemonCommand("ipv6", "ipv6 [enable|disable]",
"Enable or disable IPv6 respectively with the 'enable' and 'disable' parameters, return the status of the use of IPv6 without parameter.") {
addExample(new DaemonCommandExample("ipv6 enable",
"Status: Ok\n\n"
"State: enabled"));
addExample(new DaemonCommandExample("ipv6 disable",
"Status: Ok\n\n"
"State: disabled"));
addExample(new DaemonCommandExample("ipv6",
"Status: Ok\n\n"
"State: disabled"));
}
void IPv6Command::exec(Daemon *app, const char *args) {

View file

@ -28,6 +28,15 @@ MediaEncryptionResponse::MediaEncryptionResponse(LinphoneCore *core) : Response(
MediaEncryptionCommand::MediaEncryptionCommand() :
DaemonCommand("media-encryption", "media-encryption [none|srtp|zrtp]",
"Set the media encryption policy if a parameter is given, otherwise return the media encrytion in use.") {
addExample(new DaemonCommandExample("media-encryption none",
"Status: Ok\n\n"
"Encryption: none"));
addExample(new DaemonCommandExample("media-encryption srtp",
"Status: Ok\n\n"
"Encryption: srtp"));
addExample(new DaemonCommandExample("media-encryption",
"Status: Ok\n\n"
"Encryption: srtp"));
}
void MediaEncryptionCommand::exec(Daemon *app, const char *args) {

View file

@ -6,6 +6,14 @@ using namespace std;
MSFilterAddFmtpCommand::MSFilterAddFmtpCommand() :
DaemonCommand("msfilter-add-fmtp", "msfilter-add-fmtp <call/stream> <id> <fmtp>", "Add fmtp to the encoder of a call or a stream") {
addExample(new DaemonCommandExample("msfilter-add-fmtp call 1 vbr=on",
"Status: Ok"));
addExample(new DaemonCommandExample("msfilter-add-fmtp call 2 vbr=on",
"Status: Error\n"
"Reason: No Call with such id."));
addExample(new DaemonCommandExample("msfilter-add-fmtp stream 7 vbr=on",
"Status: Error\n"
"Reason: No Audio Stream with such id."));
}
void MSFilterAddFmtpCommand::exec(Daemon *app, const char *args) {

View file

@ -4,6 +4,9 @@ using namespace std;
PopEventCommand::PopEventCommand() :
DaemonCommand("pop-event", "pop-event", "Pop an event from event queue and display it.") {
addExample(new DaemonCommandExample("pop-event",
"Status: Ok\n\n"
"Size: 0"));
}
void PopEventCommand::exec(Daemon *app, const char *args) {
app->pullEvent();

View file

@ -72,6 +72,29 @@ PortCommand::PortCommand() :
"Set the port to use for type if port is set, otherwise return the port used for type if specified or all the used ports if no type is specified.\n"
"<type> must be one of these values: sip, audio, video.\n"
"<protocol> should be defined only for sip port and have one of these values: udp, tcp, tls.") {
addExample(new DaemonCommandExample("port sip 5060 tls",
"Status: Ok\n\n"
"SIP: 5060 TLS"));
addExample(new DaemonCommandExample("port sip 5060 udp",
"Status: Ok\n\n"
"SIP: 5060 UDP"));
addExample(new DaemonCommandExample("port audio 7078",
"Status: Ok\n\n"
"Audio RTP: 7078"));
addExample(new DaemonCommandExample("port video 9078",
"Status: Ok\n\n"
"Video RTP: 9078"));
addExample(new DaemonCommandExample("port sip",
"Status: Ok\n\n"
"SIP: 5060 UDP"));
addExample(new DaemonCommandExample("port audio",
"Status: Ok\n\n"
"Audio RTP: 7078"));
addExample(new DaemonCommandExample("port",
"Status: Ok\n\n"
"SIP: 5060 UDP\n"
"Audio RTP: 7078\n"
"Video RTP: 9078"));
}
void PortCommand::exec(Daemon *app, const char *args) {

View file

@ -31,6 +31,19 @@ PtimeResponse::PtimeResponse(LinphoneCore *core, Direction dir) : Response() {
PtimeCommand::PtimeCommand() :
DaemonCommand("ptime", "ptime [up|down] <ms>", "Set the upload or download ptime if ms is defined, otherwise return the current value of the ptime.") {
addExample(new DaemonCommandExample("ptime up 20",
"Status: Ok\n\n"
"Upload: 20"));
addExample(new DaemonCommandExample("ptime down 30",
"Status: Ok\n\n"
"Download: 30"));
addExample(new DaemonCommandExample("ptime up",
"Status: Ok\n\n"
"Upload: 20"));
addExample(new DaemonCommandExample("ptime",
"Status: Ok\n\n"
"Upload: 20\n"
"Download: 30"));
}
void PtimeCommand::exec(Daemon *app, const char *args) {

View file

@ -29,6 +29,19 @@ void RegisterStatusResponse::append(int id, const LinphoneProxyConfig* cfg) {
RegisterStatusCommand::RegisterStatusCommand() :
DaemonCommand("register-status", "register-status <register_id|ALL>", "Return status of a registration or of all registrations.") {
addExample(new DaemonCommandExample("register-status 1",
"Status: Ok\n\n"
"Id: 1\n"
"State: LinphoneRegistrationOk"));
addExample(new DaemonCommandExample("register-status ALL",
"Status: Ok\n\n"
"Id: 1\n"
"State: LinphoneRegistrationOk\n\n"
"Id: 2\n"
"State: LinphoneRegistrationFailed"));
addExample(new DaemonCommandExample("register-status 3",
"Status: Error\n"
"Reason: No register with such id."));
}
void RegisterStatusCommand::exec(Daemon *app, const char *args) {

View file

@ -4,6 +4,9 @@ using namespace std;
RegisterCommand::RegisterCommand() :
DaemonCommand("register", "register <identity> <proxy-address> <password>", "Register the daemon to a SIP proxy.") {
addExample(new DaemonCommandExample("register sip:daemon-test@sip.linphone.org sip.linphone.org password",
"Status: Ok\n\n"
"Id: 1"));
}
void RegisterCommand::exec(Daemon *app, const char *args) {
LinphoneCore *lc = app->getCore();

View file

@ -4,6 +4,16 @@ using namespace std;
TerminateCommand::TerminateCommand() :
DaemonCommand("terminate", "terminate <call id>", "Terminate a call.") {
addExample(new DaemonCommandExample("terminate 2",
"Status: Error\n"
"Reason: No call with such id."));
addExample(new DaemonCommandExample("terminate 1",
"Status: Ok\n"));
addExample(new DaemonCommandExample("terminate",
"Status: Ok\n"));
addExample(new DaemonCommandExample("terminate",
"Status: Error\n"
"Reason: No active call."));
}
void TerminateCommand::exec(Daemon *app, const char *args) {
LinphoneCall *call = NULL;

View file

@ -4,6 +4,13 @@ using namespace std;
UnregisterCommand::UnregisterCommand() :
DaemonCommand("unregister", "unregister <register_id|ALL>", "Unregister the daemon from the specified proxy or from all proxies.") {
addExample(new DaemonCommandExample("unregister 3",
"Status: Error\n"
"Reason: No register with such id."));
addExample(new DaemonCommandExample("unregister 2",
"Status: Ok"));
addExample(new DaemonCommandExample("unregister ALL",
"Status: Ok"));
}
void UnregisterCommand::exec(Daemon *app, const char *args) {

View file

@ -15,6 +15,9 @@ VersionResponse::VersionResponse(LinphoneCore *core) : Response() {
VersionCommand::VersionCommand() :
DaemonCommand("version", "version", "Get the version number.") {
addExample(new DaemonCommandExample("version",
"Status: Ok\n\n"
"Version: 3.5.99.0_6c2f4b9312fd4717b2f8ae0a7d7c97b752768c7c"));
}
void VersionCommand::exec(Daemon *app, const char *args) {

View file

@ -1,4 +1,7 @@
#include <cstdio>
#include <sys/ioctl.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
@ -210,8 +213,30 @@ PayloadTypeParser::PayloadTypeParser(LinphoneCore *core, const string &mime_type
}
}
DaemonCommand::DaemonCommand(const char *name, const char *proto, const char *help) :
mName(name), mProto(proto), mHelp(help) {
DaemonCommandExample::DaemonCommandExample(const char *command, const char *output)
: mCommand(command), mOutput(output) {}
DaemonCommand::DaemonCommand(const char *name, const char *proto, const char *description) :
mName(name), mProto(proto), mDescription(description) {
}
void DaemonCommand::addExample(const DaemonCommandExample *example) {
mExamples.push_back(example);
}
const string DaemonCommand::getHelp() const {
ostringstream ost;
ost << getProto() << endl << endl;
ost << "Description:" << endl << getDescription() << endl << endl;
list<const DaemonCommandExample*> examples = getExamples();
int c = 1;
for (list<const DaemonCommandExample*>::iterator it = examples.begin(); it != examples.end(); ++it, ++c) {
ost << "Example " << c << ":" << endl;
ost << ">" << (*it)->getCommand() << endl;
ost << (*it)->getOutput() << endl;
ost << endl;
}
return ost.str();
}
bool DaemonCommand::matches(const char *name) const {
@ -504,6 +529,26 @@ char *Daemon::readPipe(char *buffer, int buflen) {
return NULL;
}
void Daemon::dumpCommandsHelp() {
int cols = 80;
#ifdef TIOCGSIZE
struct ttysize ts;
ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
cols = ts.ts_cols;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
cols = ts.ws_col;
#endif
cout << endl;
for (list<DaemonCommand*>::iterator it = mCommands.begin(); it != mCommands.end(); ++it) {
cout << setfill('-') << setw(cols) << "-" << endl << endl;
cout << (*it)->getHelp();
}
}
static void printHelp() {
fprintf(stdout, "daemon-linphone [<options>]\n"
#if defined(LICENCE_GPL) || defined(LICENCE_COMMERCIAL)
@ -519,6 +564,7 @@ static void printHelp() {
"where options are :\n"
"\t--help\t\t\tPrint this notice.\n"
"\t--dump-commands-help\tDump the help of every available commands.\n"
"\t--pipe <pipename>\tCreate an unix server socket to receive commands.\n"
"\t--log <path>\t\tSupply a file where the log will be saved\n"
"\t--factory-config <path>\tSupply a readonly linphonerc style config file to start with.\n"
@ -618,6 +664,10 @@ int main(int argc, char *argv[]) {
if (strcmp(argv[i], "--help") == 0) {
printHelp();
return 0;
} else if (strcmp(argv[i], "--dump-commands-help") == 0) {
Daemon app(NULL, NULL, NULL, NULL, false, false);
app.dumpCommandsHelp();
return 0;
} else if (strcmp(argv[i], "--pipe") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "no pipe name specify after --pipe");

View file

@ -35,6 +35,21 @@
class Daemon;
class DaemonCommandExample {
public:
DaemonCommandExample(const char *command, const char *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() {
@ -42,17 +57,23 @@ public:
};
virtual void exec(Daemon *app, const char *args)=0;
bool matches(const char *name) const;
const std::string getHelp() const;
const std::string &getProto() const {
return mProto;
}
const std::string &getHelp() const {
return mHelp;
const std::string &getDescription() const {
return mDescription;
}
const std::list<const DaemonCommandExample*> &getExamples() const {
return mExamples;
}
void addExample(const DaemonCommandExample *example);
protected:
DaemonCommand(const char *name, const char *proto, const char *help);
DaemonCommand(const char *name, const char *proto, const char *description);
const std::string mName;
const std::string mProto;
const std::string mHelp;
const std::string mDescription;
std::list<const DaemonCommandExample*> mExamples;
};
class Response {
@ -158,6 +179,7 @@ public:
int updateProxyId(LinphoneProxyConfig *proxy);
inline int maxProxyId() { return mProxyIds; };
int updateAudioStreamId(AudioStream *audio_stream);
void dumpCommandsHelp();
private:
static void* iterateThread(void *arg);
static void callStateChanged(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state, const char *msg);