diff --git a/daemon/commands/audio-codec-disable.cc b/daemon/commands/audio-codec-disable.cc index 317c4f697..82d365de0 100644 --- a/daemon/commands/audio-codec-disable.cc +++ b/daemon/commands/audio-codec-disable.cc @@ -3,25 +3,38 @@ using namespace std; AudioCodecDisableCommand::AudioCodecDisableCommand() : - DaemonCommand("audio-codec-disable", "audio-codec-disable ", "Disable an audio codec.") { + DaemonCommand("audio-codec-disable", "audio-codec-disable ", + "Disable an audio codec.\n" + " is of the form mime/rate/channels, eg. speex/16000/1") { } void AudioCodecDisableCommand::exec(Daemon *app, const char *args) { - int payload_type; - if (sscanf(args, "%d", &payload_type) == 1) { + istringstream ist(args); + + if (ist.peek() == EOF) { + app->sendResponse(Response("Missing parameter.", Response::Error)); + } else { + string mime_type; + int ptnum; + ist >> mime_type; + PayloadTypeParser parser(app->getCore(), mime_type); + if (!parser.successful()) { + app->sendResponse(Response("Incorrect mime type format.", Response::Error)); + return; + } + ptnum = parser.payloadTypeNumber(); + int index = 0; for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { PayloadType *payload = reinterpret_cast(node->data); - if (payload_type == linphone_core_get_payload_type_number(app->getCore(), payload)) { + if (ptnum == linphone_core_get_payload_type_number(app->getCore(), payload)) { linphone_core_enable_payload_type(app->getCore(), payload, false); app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index)); return; } ++index; } - app->sendResponse(Response("Audio codec not found.")); - } else { - app->sendResponse(Response("Missing/Incorrect parameter(s).")); + app->sendResponse(Response("Audio codec not found.", Response::Error)); } } diff --git a/daemon/commands/audio-codec-enable.cc b/daemon/commands/audio-codec-enable.cc index 3aacf1424..fa6e05819 100644 --- a/daemon/commands/audio-codec-enable.cc +++ b/daemon/commands/audio-codec-enable.cc @@ -3,23 +3,37 @@ using namespace std; AudioCodecEnableCommand::AudioCodecEnableCommand() : - DaemonCommand("audio-codec-enable", "audio-codec-enable ", "Enable an audio codec.") { + DaemonCommand("audio-codec-enable", "audio-codec-enable ", + "Enable an audio codec.\n" + " is of the form mime/rate/channels, eg. speex/16000/1") { } + void AudioCodecEnableCommand::exec(Daemon *app, const char *args) { - int payload_type; - if (sscanf(args, "%d", &payload_type) == 1) { + istringstream ist(args); + + if (ist.peek() == EOF) { + app->sendResponse(Response("Missing parameter.", Response::Error)); + } else { + string mime_type; + int ptnum; + ist >> mime_type; + PayloadTypeParser parser(app->getCore(), mime_type); + if (!parser.successful()) { + app->sendResponse(Response("Incorrect mime type format.", Response::Error)); + return; + } + ptnum = parser.payloadTypeNumber(); + int index = 0; for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { PayloadType *payload = reinterpret_cast(node->data); - if (payload_type == linphone_core_get_payload_type_number(app->getCore(), payload)) { + if (ptnum == linphone_core_get_payload_type_number(app->getCore(), payload)) { linphone_core_enable_payload_type(app->getCore(), payload, true); app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index)); return; } ++index; } - app->sendResponse(Response("Audio codec not found.")); - } else { - app->sendResponse(Response("Missing/Incorrect parameter(s).")); + app->sendResponse(Response("Audio codec not found.", Response::Error)); } } diff --git a/daemon/commands/audio-codec-get.cc b/daemon/commands/audio-codec-get.cc index 283215c43..60d1919d2 100644 --- a/daemon/commands/audio-codec-get.cc +++ b/daemon/commands/audio-codec-get.cc @@ -3,29 +3,47 @@ using namespace std; AudioCodecGetCommand::AudioCodecGetCommand() : - DaemonCommand("audio-codec-get", "audio-codec-get ", "Get an audio codec if codec-mime is defined, otherwise return the audio codec list.") { + DaemonCommand("audio-codec-get", "audio-codec-get ", + "Get an audio codec if a parameter is given, otherwise return the audio codec list.\n" + " is of the form mime/rate/channels, eg. speex/16000/1") { } + void AudioCodecGetCommand::exec(Daemon *app, const char *args) { - int payload_type; - bool list = sscanf(args, "%d", &payload_type) != 1; - bool find = list; + int ptnum; + bool list = false; + bool found = false; + istringstream ist(args); + ostringstream ost; + + if (ist.peek() == EOF) { + found = list = true; + } else { + string mime_type; + ist >> mime_type; + PayloadTypeParser parser(app->getCore(), mime_type); + if (!parser.successful()) { + app->sendResponse(Response("Incorrect mime type format.", Response::Error)); + return; + } + ptnum = parser.payloadTypeNumber(); + } + int index = 0; - ostringstream ostr; for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { PayloadType *payload = reinterpret_cast(node->data); if (list) { - ostr << PayloadTypeResponse(app->getCore(), payload, index).getBody() << "\n"; - } else if (payload_type == linphone_core_get_payload_type_number(app->getCore(), payload)) { - ostr << PayloadTypeResponse(app->getCore(), payload, index).getBody(); - find = true; + ost << PayloadTypeResponse(app->getCore(), payload, index).getBody() << "\n"; + } else if (ptnum == linphone_core_get_payload_type_number(app->getCore(), payload)) { + ost << PayloadTypeResponse(app->getCore(), payload, index).getBody(); + found = true; break; } ++index; } - if (!find) { - app->sendResponse(Response("Audio codec not found.")); + if (!found) { + app->sendResponse(Response("Audio codec not found.", Response::Error)); } else { - app->sendResponse(Response(ostr.str().c_str(), Response::Ok)); + app->sendResponse(Response(ost.str().c_str(), Response::Ok)); } } diff --git a/daemon/commands/audio-codec-move.cc b/daemon/commands/audio-codec-move.cc index 713c2c559..2fc23f821 100644 --- a/daemon/commands/audio-codec-move.cc +++ b/daemon/commands/audio-codec-move.cc @@ -3,45 +3,69 @@ using namespace std; AudioCodecMoveCommand::AudioCodecMoveCommand() : - DaemonCommand("audio-codec-move", "audio-codec-move ", "Move a codec to the an index.") { + DaemonCommand("audio-codec-move", "audio-codec-move ", + "Move a codec to the an index.\n" + " is of the form mime/rate/channels, eg. speex/16000/1") { } -void AudioCodecMoveCommand::exec(Daemon *app, const char *args) { - int payload_type; - int index; - if (sscanf(args, "%d %d", &payload_type, &index) == 2 && index >= 0) { - PayloadType *selected_payload = NULL; - for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { - PayloadType *payload = reinterpret_cast(node->data); - if (payload_type == linphone_core_get_payload_type_number(app->getCore(), payload)) { - selected_payload = payload; - break; - } - } - if (selected_payload == NULL) { - app->sendResponse(Response("Audio codec not found.")); - return; - } - int i = 0; - MSList *mslist = NULL; - for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { - PayloadType *payload = reinterpret_cast(node->data); - if (i == index) { - mslist = ms_list_append(mslist, selected_payload); - ++i; - } - if (selected_payload != payload) { - mslist = ms_list_append(mslist, payload); - ++i; - } - } - if (i <= index) { - index = i; - mslist = ms_list_append(mslist, selected_payload); - } - linphone_core_set_audio_codecs(app->getCore(), mslist); - app->sendResponse(PayloadTypeResponse(app->getCore(), selected_payload, index)); - } else { - app->sendResponse(Response("Missing/Incorrect parameter(s).")); +void AudioCodecMoveCommand::exec(Daemon *app, const char *args) { + istringstream ist(args); + + if (ist.peek() == EOF) { + app->sendResponse(Response("Missing parameters.", Response::Error)); + return; } + + string mime_type; + ist >> mime_type; + if (ist.peek() == EOF) { + app->sendResponse(Response("Missing index parameter.", Response::Error)); + return; + } + PayloadTypeParser parser(app->getCore(), mime_type); + if (!parser.successful()) { + app->sendResponse(Response("Incorrect mime type format.", Response::Error)); + return; + } + int ptnum = parser.payloadTypeNumber(); + int index; + ist >> index; + if (ist.fail() || (index < 0)) { + app->sendResponse(Response("Incorrect index parameter.", Response::Error)); + return; + } + + PayloadType *selected_payload = NULL; + for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { + PayloadType *payload = reinterpret_cast(node->data); + if (ptnum == linphone_core_get_payload_type_number(app->getCore(), payload)) { + selected_payload = payload; + break; + } + } + if (selected_payload == NULL) { + app->sendResponse(Response("Audio codec not found.", Response::Error)); + return; + } + + int i = 0; + MSList *mslist = NULL; + for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) { + PayloadType *payload = reinterpret_cast(node->data); + if (i == index) { + mslist = ms_list_append(mslist, selected_payload); + ++i; + } + if (selected_payload != payload) { + mslist = ms_list_append(mslist, payload); + ++i; + } + } + if (i <= index) { + index = i; + mslist = ms_list_append(mslist, selected_payload); + } + linphone_core_set_audio_codecs(app->getCore(), mslist); + + app->sendResponse(PayloadTypeResponse(app->getCore(), selected_payload, index)); } diff --git a/daemon/commands/audio-codec-set.cc b/daemon/commands/audio-codec-set.cc index c750a3d78..b55bb8e0b 100644 --- a/daemon/commands/audio-codec-set.cc +++ b/daemon/commands/audio-codec-set.cc @@ -6,7 +6,9 @@ using namespace std; AudioCodecSetCommand::AudioCodecSetCommand() : - DaemonCommand("audio-codec-set", "audio-codec-set ", "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.") { + DaemonCommand("audio-codec-set", "audio-codec-set ", + "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" + " is of the form mime/rate/channels, eg. speex/16000/1") { } static PayloadType *findPayload(LinphoneCore *lc, int payload_type, int *index){ @@ -23,41 +25,64 @@ static PayloadType *findPayload(LinphoneCore *lc, int payload_type, int *index){ } void AudioCodecSetCommand::exec(Daemon *app, const char *args) { - int payload_type; - char param[256], value[256]; - if (sscanf(args, "%d %255s %255s", &payload_type, param, value) == 3) { - PayloadType *payload; - int index; - if ((payload=findPayload(app->getCore(),payload_type,&index))!=NULL){ - bool handled = false; - if (strcmp("clock_rate", param) == 0) { - payload->clock_rate = atoi(value); + istringstream ist(args); + + if (ist.peek() == EOF) { + app->sendResponse(Response("Missing parameters.", Response::Error)); + return; + } + + string mime_type; + ist >> mime_type; + PayloadTypeParser parser(app->getCore(), mime_type); + if (!parser.successful()) { + app->sendResponse(Response("Incorrect mime type format.", Response::Error)); + return; + } + int ptnum = parser.payloadTypeNumber(); + string param; + string value; + ist >> param; + if (ist.fail()) { + app->sendResponse(Response("Missing/Incorrect parameter(s).", Response::Error)); + return; + } + ist >> value; + if (value.length() > 255) value.resize(255); + + PayloadType *payload; + int index; + if ((payload = findPayload(app->getCore(), ptnum, &index)) != NULL) { + bool handled = false; + if (param.compare("clock_rate") == 0) { + if (value.length() > 0) { + payload->clock_rate = atoi(value.c_str()); handled = true; - } else if (strcmp("recv_fmtp", param) == 0) { - payload_type_set_recv_fmtp(payload, value); - handled = true; - } else if (strcmp("send_fmtp", param) == 0) { - payload_type_set_send_fmtp(payload, value); - handled = true; - }else if (strcmp("number", param) == 0) { - PayloadType *conflict=findPayload(app->getCore(),atoi(value),NULL); - if (conflict){ - app->sendResponse(Response("New payload type number is already used.")); - }else{ - _payload_type_set_number(payload, atoi(value)); + } + } else if (param.compare("recv_fmtp") == 0) { + payload_type_set_recv_fmtp(payload, value.c_str()); + handled = true; + } else if (param.compare("send_fmtp") == 0) { + payload_type_set_send_fmtp(payload, value.c_str()); + handled = true; + } else if (param.compare("number") == 0) { + if (value.length() > 0) { + PayloadType *conflict = findPayload(app->getCore(), atoi(value.c_str()), NULL); + if (conflict) { + app->sendResponse(Response("New payload type number is already used.", Response::Error)); + } else { + _payload_type_set_number(payload, atoi(value.c_str())); app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index)); } return; } - if (handled) { - app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index)); - } else { - app->sendResponse(Response("Invalid codec parameter")); - } - return; } - app->sendResponse(Response("Audio codec not found.")); - } else { - app->sendResponse(Response("Missing/Incorrect parameter(s).")); + if (handled) { + app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index)); + } else { + app->sendResponse(Response("Invalid codec parameter.", Response::Error)); + } + return; } + app->sendResponse(Response("Audio codec not found.", Response::Error)); } diff --git a/daemon/daemon.cc b/daemon/daemon.cc index 9ef15b2ec..6c7f489c0 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -176,6 +176,25 @@ PayloadTypeResponse::PayloadTypeResponse(LinphoneCore *core, const PayloadType * } } +PayloadTypeParser::PayloadTypeParser(LinphoneCore *core, const string &mime_type) : mSuccesful(true), mPayloadTypeNumber(-1) { + istringstream ist(mime_type); + ist >> mPayloadTypeNumber; + if (ist.fail()) { + char type[12]; + int rate, channels; + if (sscanf(mime_type.c_str(), "%11[^/]/%u/%u", type, &rate, &channels) != 3) { + mSuccesful = false; + return; + } + const PayloadType *pt = linphone_core_find_payload_type(core, type, rate, channels); + if (pt == NULL) { + mPayloadTypeNumber = -1; + } else { + mPayloadTypeNumber = linphone_core_get_payload_type_number(core, pt); + } + } +} + DaemonCommand::DaemonCommand(const char *name, const char *proto, const char *help) : mName(name), mProto(proto), mHelp(help) { } diff --git a/daemon/daemon.h b/daemon/daemon.h index 60eafc9ab..5bf88c3c8 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -126,6 +126,16 @@ public: private: }; +class PayloadTypeParser { +public: + PayloadTypeParser(LinphoneCore *core, const std::string &mime_type); + inline bool successful() { return mSuccesful; }; + inline int payloadTypeNumber() { return mPayloadTypeNumber; }; +private: + bool mSuccesful; + int mPayloadTypeNumber; +}; + class Daemon { friend class DaemonCommand; public: