Commit 6a847f33 authored by Gabriel Margiani's avatar Gabriel Margiani

Config und call.

parent 22a4de17
......@@ -22,13 +22,15 @@
#include <pjsua2.hpp>
class p3Account : public pj::Account {
public:
p3Account() {};
~p3Account() {};
namespace p3 {
class account : public pj::Account {
public:
account() {};
~account() {};
virtual void onRegState(OnRegStateParam &prm);
virtual void onIncomingCall(OnIncomingCallParam &iprm);
virtual void onRegState(pj::OnRegStateParam &prm);
virtual void onIncomingCall(pj::OnIncomingCallParam &iprm);
};
}
#endif
/**
* This file is part of 3phone
* Copyright (C) 2015 Gabriel Margiani
*
* 3phone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3phone 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 3phone. If not, see <http://www.gnu.org/licenses/>.
**/
#include "call.h"
p3::call::call(p3::account &acc, int call_id) : Call(acc, call_id) {
}
p3::call::~call() {
}
void p3::call::onCallState(pj::OnCallStateParam& prm) {
}
void p3::call::onCallMediaState(pj::OnCallMediaStateParam& prm) {
}
/**
* This file is part of 3phone
* Copyright (C) 2015 Gabriel Margiani
*
* 3phone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3phone 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 3phone. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef __P3_CALL_H__
#define __P3_CALL_H__
#include <pjsua2.hpp>
#include "account.h"
namespace p3 {
class call : public pj::Call {
public:
call(p3::account& acc, int call_id = PJSUA_INVALID_ID);
~call();
void onCallState(pj::OnCallStateParam &prm);
void onCallMediaState(pj::OnCallMediaStateParam &prm);
};
}
#endif
......@@ -26,11 +26,18 @@
#include "error.h"
std::map<std::string, std::string> p3::client::command_shorthands {
{"c", "call"}
{"c", "call"},
{"q", "quit"},
{"x", "exit"}
};
p3::client::client(int ac, char *av[]) : argv(av, av+ac) {
p3::client::client(int ac, char *av[]) : argv(av, av+ac), interactive(false) {
argv.pop_front();
auto i = std::find(argv.begin(), argv.end(), "-I");
if (i != argv.end()) {
interactive = true;
argv.erase(i);
}
std::random_device rd;
std::default_random_engine e(rd());
......@@ -39,11 +46,12 @@ p3::client::client(int ac, char *av[]) : argv(av, av+ac) {
connection = nullptr;
try {
std::cout << "connecting..." << std::endl;
p3::mQueue ma(p3::mQueue::DefaultId, false);
connection = new mQueue(id, true);
ma.send(p3::protocol::HELLO, id);
p3::mQueueMessage m = ma.receive(30);
p3::mQueueMessage m = connection->receive(30);
if (m.get_command() != p3::protocol::OK) {
throw new p3::perror("client.connection", "cannot connect to server " + m.get_value());
......@@ -66,12 +74,17 @@ std::string p3::client::get_input(std::string q, p3::client::inputType type) {
if (!argv.empty()) {
in = argv.front();
argv.pop_front();
} else if (!interactive && type == COMMAND) {
return "quit"; // We have parsed all arguments...
} else {
do {
std::cout << q << " > " << std::flush;
std::cin >> in;
boost::trim(in);
} while (in == "");
} while (std::cin && in == "");
if (in == "") {
return "quit";
}
}
boost::to_lower(in);
......
......@@ -41,6 +41,8 @@ namespace p3 {
NUMBER
};
bool interactive;
std::string get_input(std::string question, inputType is_command);
public:
......
/**
* This file is part of 3phone
* Copyright (C) 2015 Gabriel Margiani
*
* 3phone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3phone 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 3phone. If not, see <http://www.gnu.org/licenses/>.
**/
#include <fstream>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include "config.h"
p3::config::config(std::string p, std::map<std::string, std::string>& d) : data(d), defaults(d), filename(p) {
load_config();
save_config();
}
p3::config::~config() {
}
void p3::config::load_config() {
std::string l;
std::ifstream f(filename);
while(std::getline(f, l)) {
std::istringstream il(l);
std::string key;
if(std::getline(il, key, '=')) {
std::string value;
if(std::getline(il, value)) {
boost::trim(key);
boost::to_lower(key);
boost::trim(value);
data[key] = value;
}
}
}
}
void p3::config::save_config() {
std::ofstream f(filename, std::ofstream::out | std::ofstream::trunc);
for (auto p : data) {
f << p.first << " = " << p.second << std::endl;
}
f.close();
}
std::string p3::config::get_string(std::string k) {
return data.at(k);
}
int p3::config::get_int(std::string k) {
return std::stoi(data.at(k));
}
bool p3::config::get_bool(std::string k) {
std::string s = data.at(k);
return (s == "true" || s == "True" || s == "1");
}
/**
* This file is part of 3phone
* Copyright (C) 2015 Gabriel Margiani
*
* 3phone is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3phone 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 3phone. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef __P3_CONFIG_H__
#define __P3_CONFIG_H__
#include <string>
#include <map>
namespace p3 {
class config {
std::map<std::string, std::string> data;
std::map<std::string, std::string>& defaults;
std::string filename;
public:
config(std::string filename, std::map<std::string, std::string>& defaults);
~config();
void load_config();
void save_config();
std::string get_string(std::string k);
int get_int(std::string k);
bool get_bool(std::string k);
};
}
#endif
......@@ -26,6 +26,7 @@
void print_usage() {
std::cout << "3phone - p3 usage: " << std::endl
<< "p3 s erve - start the server" << std::endl
<< "p3 quit, stop - terminate server" << std::endl
<< "p3 c all [nr] - call someone" << std::endl
<< "p3 a nswer - answer a currently ringing call" << std::endl
<< "p3 l ist - list current calls" << std::endl
......@@ -33,15 +34,17 @@ void print_usage() {
<< "p3 p ause, hold [id] - pause/hold/reinvite" << std::endl
<< "p3 j oin - conference current calls" << std::endl
<< "p3 f orward [id] [nr] - forward call" << std::endl
<< "p3 r ecord [file] - record" << std::endl;
<< "p3 r ecord [file] - record" << std::endl
<< "-I for an interactive shell" << std::endl;
}
int run_server() {
try {
p3::server srv;
std::cout << "running server" << std::endl;
srv.run();
} catch (p3::mQueueException * e) {
std::cout << "Server Error: " << e->what() << std::endl;
} catch (p3::perror const & e) {
std::cout << "Server Error: " << e.what() << std::endl;
return 1;
}
return 0;
......
......@@ -16,8 +16,10 @@
* along with 3phone. If not, see <http://www.gnu.org/licenses/>.
**/
#include <iostream>
#include <cerrno>
#include <ctime>
#include <string.h>
#include "msgq.h"
......@@ -40,7 +42,7 @@ p3::mQueue::mQueue(std::string id, bool c) {
}
mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 30;
attr.mq_maxmsg = 10;
attr.mq_msgsize = 253;
attr.mq_curmsgs = 0;
......@@ -69,7 +71,7 @@ p3::mQueue::mQueue(std::string id, bool c) {
case ENOMEM:
throw p3::mQueueException(key + ":open", "Memory full");
default:
throw p3::mQueueException(key + ":open", "Open or Creation failed: " + errno);
throw p3::mQueueException(key + ":open", "Open or Creation failed: " + std::string(strerror(err)));
}
}
}
......@@ -108,7 +110,7 @@ void p3::mQueue::send(p3::mQueueMessage & qmsg) {
case ETIMEDOUT:
throw p3::mQueueException(key + ":send", "Queue full, Timeout");
default:
throw p3::mQueueException(key + ":send", "Failed to send Message: " + msg);
throw p3::mQueueException(key + ":send", "Failed to send Message: " + msg + " - " + std::string(strerror(errno)));
}
}
}
......@@ -136,7 +138,7 @@ p3::mQueueMessage p3::mQueue::receive(int timeout) {
case ETIMEDOUT:
throw p3::mQueueException(key + ":recv", "Queue full, Timeout");
default:
throw p3::mQueueException(key + ":recv", "Failed to receive");
throw p3::mQueueException(key + ":recv", "Failed to receive - " + std::string(strerror(errno)));
}
}
}
......
......@@ -20,6 +20,8 @@
#include "phonebook.h"
p3::phonebook::phonebook(p3::config& c) : conf(c) {}
std::string p3::phonebook::parse_number(std::string nr) {
std::cout << "parsing Number " << nr << std::endl;
return nr;
......
......@@ -21,12 +21,18 @@
#include <string>
#include "config.h"
namespace p3 {
class phonebook {
config& conf;
public:
explicit phonebook(config& c);
std::string parse_number(std::string nr);
};
......
......@@ -17,13 +17,31 @@
**/
#include <iostream>
#include <cstdlib>
#include "server.h"
std::atomic_bool p3::server::terminate_threads(false);
p3::server::server() : connection(p3::mQueue::DefaultId, true), phone(), book() {
}
std::map<std::string, std::string> p3::server::default_config {
{"test", "test"},
{"pj:max_calls", "10"},
{"pj:log_level", "5"},
{"account:id_uri", "sip:test@3phone.com"},
{"account:registrar", "sip:3phone.com"},
{"account:sheme", "digest"},
{"account:realm", "*"},
{"account:username", "test"},
{"account:password", "pass"},
};
p3::server::server() :
conf(std::string(std::getenv("HOME")) + "/.3phonerc", p3::server::default_config),
connection(p3::mQueue::DefaultId, true),
phone(conf),
book(conf)
{}
p3::server::~server() {
finish_threads();
......@@ -36,6 +54,7 @@ void p3::server::run() {
p3::mQueueMessage m = connection.receive(-1);
switch (m.get_command()) {
case p3::protocol::HELLO:
std::cout << "Got hello" << std::endl;
dispatch_thread(m.get_value());
break;
case p3::protocol::QUIT:
......@@ -56,8 +75,12 @@ void p3::server::dispatch_thread(std::string id) {
}
void p3::server::server_thread(std::string id) {
p3::clientHandler c(id, phone, book);
c.run();
try {
p3::clientHandler c(id, phone, book);
c.run();
} catch (p3::perror & e) {
std::cout << "Error in client " << id << ": " << e.what() << std::endl;
}
}
void p3::server::finish_threads() {
......@@ -101,6 +124,7 @@ void p3::clientHandler::run() {
break;
default:
std::cout << "Protokol Error, invalid command in " << id << ": " << m.get_value() << std::endl;
connection.send(p3::protocol::ERROR, "PROTOKOLL ERROR, unknown command.");
}
}
} catch (p3::perror & e) {
......@@ -125,7 +149,8 @@ void p3::clientHandler::handle_call() {
std::string nr = book.parse_number(n.get_value());
phone.call(nr);
} catch (p3::perror & e) {
connection.send(p3::protocol::FATAL_ERROR, e.what());
throw;
connection.send(p3::protocol::ERROR, e.what());
return;
}
connection.send(p3::protocol::OK, "Call OK");
}
......@@ -23,14 +23,19 @@
#include <thread>
#include <atomic>
#include <list>
#include <map>
#include "msgq.h"
#include "sipphone.h"
#include "phonebook.h"
#include "config.h"
namespace p3 {
class server {
static std::map<std::string, std::string> default_config;
config conf;
std::list<std::thread *> clients;
mQueue connection;
......
......@@ -18,71 +18,83 @@
#include <iostream>
#include "error.h"
#include "sipphone.h"
//#include "account.h"
//#include "3phone.h"
p3::sipphone::sipphone(p3::config& c) : conf(c) {
// Initiate pj
endpoint = new pj::Endpoint;
//using namespace pj;
try {
endpoint->libCreate();
} catch(pj::Error& error) {
throw p3::perror("sipphone: pjInit: Create error", error.info());
}
//p3Server::p3Server() {
//// Initiate pj
//endpoint = new Endpoint;
//try {
//endpoint->libCreate();
//} catch(Error& error) {
//throw p3Error("p3Server: pjInit: Create error", error.info());
//}
//try {
//EpConfig ep_cfg;
//ep_cfg.logConfig.level = LOGLEVEL;
//ep_cfg.uaConfig.maxCalls = MAX_CALLS;
try {
pj::EpConfig ep_cfg;
ep_cfg.logConfig.level = conf.get_int("pj:log_level");
ep_cfg.uaConfig.maxCalls = conf.get_int("pj:max_calls");
//ep_cfg.mediaConfig.sndClockRate = 16000;
//endpoint->libInit(ep_cfg);
//} catch(Error& error) {
//throw p3Error("p3Server: pjInit: Init error", error.info());
//}
//try {
//TransportConfig tcfg;
//tcfg.port = 5060;
//TransportId tid = endpoint->transportCreate(PJSIP_TRANSPORT_TCP, tcfg);
//} catch(Error& error) {
//throw p3Error("p3Server: pjInit: Transport creation error", error.info());
//}
//try {
//endpoint->libStart();
//} catch(Error& error) {
//throw p3Error("p3Server: pjInit: Start error", error.info());
//}
//AccountConfig acc_cfg;
//acc_cfg.idUri = "sip:test1@pjsip.org";
//acc_cfg.regConfig.registrarUri = "sip:pjsip.org";
//acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*", "test1", 0, "secret1") );
//MyAccount *acc = new MyAccount;
//try {
//acc->create(acc_cfg);
//} catch(Error& error) {
//std::cout << "Account error: " << error.info() << std::endl;
//delete acc;
//return 1;
//}
//}
endpoint->libInit(ep_cfg);
} catch(pj::Error& error) {
throw p3::perror("sipphone: pjInit: Init error", error.info());
}
try {
pj::TransportConfig tcfg;
tcfg.port = 5060;
pj::TransportId tid = endpoint->transportCreate(PJSIP_TRANSPORT_TCP, tcfg);
} catch(pj::Error& error) {
throw p3::perror("sipphone: pjInit: Transport creation error", error.info());
}
try {
endpoint->libStart();
} catch(pj::Error& error) {
throw p3::perror("sipphone: pjInit: Start error", error.info());
}
pj::AccountConfig acc_cfg;
acc_cfg.idUri = conf.get_string("account:id_uri");
acc_cfg.regConfig.registrarUri = conf.get_string("accout:registrar");
acc_cfg.sipConfig.authCreds.push_back(
pj::AuthCredInfo(
conf.get_string("accout:sheme"),
conf.get_string("accout:realm"),
conf.get_string("accout:username"),
0,
conf.get_string("accout:password")
)
);
acc = new p3::account;
try {
acc->create(acc_cfg);
} catch(pj::Error& error) {
delete acc;
throw p3::perror("sipphone: pjInit: Account error", error.info());
}
}
//p3Server::~p3Server() {
//endpoint->libDestroy();
//delete acc;
//delete endpoint;
//}
p3::sipphone::~sipphone() {
endpoint->libDestroy();
delete acc;
delete endpoint;
for (auto c : calls) {
delete c;
}
}
void p3::sipphone::call(std::string& nr) {
std::cout << "calling " << nr << std::endl;
p3::call* c = new p3::call(*acc);
pj::CallOpParam prm(true); // Use default call settings
calls.push_back(c);
try {
c->makeCall(nr, prm);
} catch(pj::Error& err) {
throw p3::perror("sipphone:call", "error calling " + nr + " " + err.info());
}
}
......@@ -20,15 +20,33 @@
#define __P3_SIPPHONE_H__
#include <string>
#include <list>
#include <pjsua2.hpp>
#include "config.h"
#include "account.h"
#include "call.h"
namespace p3 {
class sipphone {
config& conf;
pj::Endpoint* endpoint;
p3::account* acc;
std::list<p3::call *> calls;
public:
explicit sipphone(config& c);
sipphone(const sipphone& c) = delete;
~sipphone();
void call(std::string& nr);
};
};
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment