PJSIP is definitely what you need. Tell something more about what exactly your problem is.
Example below shows simple application based on PJSUA (high level API of PJSIP).
#include <pjsua-lib/pjsua.h>
#include <iostream>
#define THIS_FILE "sipdtmf.cpp"
using namespace std;
void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) {
PJ_LOG(1, (THIS_FILE, "Incoming call!"));
pjsua_call_answer(call_id, PJSIP_SC_OK, nullptr, nullptr);
}
void on_dtmf_digit(pjsua_call_id call_id, int digit) {
PJ_LOG(1, (THIS_FILE, "Got DTMF %c", char(digit)));
}
void init_pjsua() {
pjsua_config cfg;
pjsua_logging_config log_cfg;
pjsua_transport_config transport_cfg;
pjsua_acc_id acc_id;
pjsua_transport_id transport_id;
pjsua_media_config media_cfg;
pj_status_t status;
status = pj_init();
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "PJ init error", status);
exit(1);
}
status = pjsua_create();
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "PJSUA create error", status);
exit(1);
}
pjsua_config_default(&cfg);
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_dtmf_digit = &on_dtmf_digit;
cfg.user_agent = pj_str("SIPDTMF 1.0");
pjsua_media_config_default(&media_cfg);
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 1;
status = pjsua_init(&cfg, &log_cfg, &media_cfg);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "PJSUA init error", status);
exit(1);
}
pjsua_transport_config_default(&transport_cfg);
transport_cfg.port = 5060;
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &transport_cfg, &transport_id);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Transport error", status);
pjsua_destroy();
exit(1);
}
status = pjsua_start();
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "PJSUA start error", status);
pjsua_destroy();
exit(1);
}
status = pjsua_acc_add_local(transport_id, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Account error", status);
pjsua_destroy();
exit(1);
}
}
int main (int argc, char *argv[]) {
char c;
init_pjsua();
cout << "SIPDTMF ready. Type Q to stop." << endl;
while (cin >> c) {
if (c == 'Q' || c == 'q') {
pjsua_call_hangup_all();
pjsua_destroy();
break;
}
}
return 0;
}
void on_dtmf_digit(...)
is callback where you can do something on incoming DTMF (eg. call some system command).
This example use local account. It's mean any SIP call to device which running above application will be handled.