53 set(TERMINATE,
'q',
"bye");
59 linked_pointer<segment> sp = segments.begin();
62 shell::debug(2,
"cancelling call %08x:%u", source->sequence, source->cid);
79 invited = ringing = ringbusy = 0;
84 linked_pointer<segment> sp = segments.begin();
90 shell::debug(2,
"joining call %08x:%u with session %08x:%u",
91 source->sequence, source->cid, join->
sequence, join->
cid);
98 forwarding = diverting = NULL;
102 if(s != source && s != target) {
121 shell::debug(4,
"disconnecting call %08x:%u\n", source->sequence, source->cid);
146 reason =
"terminated";
159 linked_pointer<segment> sp = segments.begin();
161 if(!sp->sid.closed) {
162 if(&(sp->sid) == sp->sid.parent->source)
166 sp->sid.closed =
true;
177 if(state != INITIAL && state != FINAL) {
179 set(FINAL,
'q',
"exit");
195 if(state == RINGING) {
206 shell::debug(3,
"sip: sending source reply %d", error);
216 shell::debug(3,
"sip: source reply %d failed", error);
228 String::set(
map->state + 1,
sizeof(
map->state) - 1, text);
233 bool closing =
false;
235 Mutex::protect(
this);
242 if(s == source || s == target) {
259 Mutex::release(
this);
266 assert(thread != NULL);
268 Mutex::protect(
this);
279 set(RINGING,
'r',
"ringin");
291 Mutex::release(
this);
296 assert(thread != NULL);
298 Mutex::protect(
this);
303 Mutex::release(
this);
320 if(!ringing && ringbusy)
321 set(BUSY,
'b',
"busy");
324 set(FAILED,
'*',
"failed");
329 set(FAILED,
'*',
"failed");
334 set(FAILED,
'*',
"failed");
340 Mutex::release(
this);
351 bool holding =
false;
355 assert(thread != NULL);
358 Mutex::protect(
this);
381 Mutex::release(
this);
389 if(state != ANSWERED && state != RINGBACK) {
391 if(state != ANSWERED)
392 set(RINGBACK,
'r',
"ringback");
399 Mutex::release(
this);
403 if(body && body->
body) {
417 set(HOLDING,
'h',
"holding");
419 set(JOINED,
'j',
"joined");
425 Mutex::release(
this);
430 if(body && body->
body)
442 Mutex::release(
this);
444 shell::debug(2,
"reinvite failed for call %08x:%u",
445 source->sequence, source->cid);
457 assert(thread != NULL);
460 Mutex::protect(
this);
461 if(s == source || (target != NULL && target != s)) {
462 Mutex::release(
this);
463 shell::debug(2,
"cannot answer call %08x:%u from specified session",
464 source->sequence, source->cid);
472 set(ANSWERED,
'a',
"answered");
478 ctx = source->context;
488 ctx = target->context;
489 Mutex::release(
this);
494 Mutex::release(
this);
495 shell::debug(2,
"cannot answer non-ringing call %08x:%u",
496 source->sequence, source->cid);
499 Mutex::release(
this);
506 shell::debug(2,
"answer failed for call %08x:%u",
507 source->sequence, source->cid);
508 failed(thread, source);
514 assert(thread != NULL);
520 Mutex::protect(
this);
523 Mutex::release(
this);
534 assert(thread != NULL);
543 Mutex::protect(
this);
544 if(s == source && target) {
546 ctx = target->context;
548 else if(s == target) {
550 ctx = source->context;
558 set(TRANSFER,
'x',
"transfer");
560 Mutex::release(
this);
571 Mutex::release(
this);
579 if(body && body->
body)
587 assert(thread != NULL);
595 Mutex::protect(
this);
597 Mutex::release(
this);
598 shell::debug(2,
"cannot confirm call %08x:%u from session %08x:%u\n",
599 source->sequence, source->cid, s->
sequence, s->
cid);
606 set(JOINED,
'j',
"joined");
612 arm((timeout_t)((expires - now) * 1000l));
618 ctx = target->context;
621 else if(s == target) {
623 ctx = source->context;
627 Mutex::release(
this);
628 shell::debug(2,
"cannot confirm unanswered call %08x:%u",
629 source->sequence, source->cid);
632 Mutex::release(
this);
638 shell::debug(2,
"confirm failed to send for call %08x:%u",
639 source->sequence, source->cid);
645 assert(thread != NULL);
647 Mutex::protect(
this);
651 set(BUSY,
'b',
"busy");
653 Mutex::release(
this);
661 Mutex::release(
this);
667 if(s && s != source) {
683 if(!ringing && ringbusy && invited == 1 && s != source) {
692 ringbusy = invited = 0;
696 Mutex::release(
this);
702 set(BUSY,
'b',
"busy");
709 Mutex::release(
this);
722 if(state == INITIAL) {
723 shell::debug(3,
"sip: sending initial ring %d",
SIP_RINGING);
728 answering -= (unsigned)(now - starting);
731 Mutex::protect(
this);
732 set(TRYING,
't',
"trying");
734 Mutex::release(
this);
740 Mutex::protect(
this);
741 current = timer.get();
746 Mutex::release(
this);
752 linked_pointer<segment> sp;
761 if(answering == 1 && forwarding) {
791 shell::debug(4,
"expiring call %08x:%u\n", source->sequence, source->cid);
810 if(!joined && target)
811 joined = target->sysident;
820 node->
cid = source->cid;
821 node->
duration = (
unsigned long)(ending - starting);
822 String::set(node->
uuid,
sizeof(node->
uuid), source->uuid);
823 String::set(node->
reason,
sizeof(node->
reason), reason);
824 String::set(node->
ident,
sizeof(node->
ident), source->sysident);
825 String::set(node->
dialed,
sizeof(node->
dialed), dialed);
826 String::set(node->
joined,
sizeof(node->
joined), joined);
827 String::set(node->
display,
sizeof(node->
display), source->display);
829 snprintf(node->
network,
sizeof(node->
network),
"%s/%s", source->network, target->network);
831 String::set(node->
network,
sizeof(node->
network), source->network);
Structure for SIP Message (REQUEST and RESPONSE).
static void close(session *s)
static bool forward(stack::call *cr)
#define SIP_CALL_IS_BEING_FORWARDED
void set(state_t state, char id, const char *text)
static cdr * get(void)
Get a free cdr node to fill from the cdr memory pool.
static bool make_answer_response(context_t ctx, tid_t tid, int status, msg_t *msg)
static void destroy(session *s)
static void send_ack_message(context_t ctx, did_t did, msg_t msg=NULL)
int did
unique id for SIP dialogs
unsigned cid
Internal call sequence identifiers.
Structure for holding Body.
char sysident[MAX_IDENT_SIZE]
void failed(thread *thread, session *s)
enum sipwitch::cdr::@0 type
Start or end of call?
time_t starting
Time the call was received.
static bool make_ack_message(context_t ctx, did_t did, msg_t *msg)
void ring(thread *thread, session *s=NULL)
void closingLocked(session *s)
static void send_dialog_message(context_t ctx, did_t did, msg_t msg)
char reason[16]
Reason the call was terminated.
void disconnectLocked(void)
static bool make_dialog_request(context_t ctx, did_t did, const char *method, msg_t *msg)
#define SIP_TEMPORARILY_UNAVAILABLE
static void server_requires(voip::msg_t msg, const char *txt)
enum sipwitch::stack::session::@10 state
timeout_t getTimeout(void)
char joined[MAX_IDENT_SIZE]
Call destination eventually joined to.
void busy(thread *thread, session *s=NULL)
void trying(thread *thread)
void arm(timeout_t timeout)
static timeout_t resetTimeout(void)
osip_message_t * request
request within current transaction
char dialed[MAX_IDENT_SIZE]
Destination requested on our switch.
static void siplog(voip::msg_t msg)
static void attach(msg_t msg, const char *type, const char *body)
static void server_supports(voip::msg_t msg, const char *txt)
void message_reply(thread *thread, session *s)
static void release_call(context_t ctx, call_t cid, did_t did)
static void send_answer_response(context_t ctx, tid_t tid, int status, msg_t msg=NULL)
void bye(thread *thread, session *s)
void confirm(thread *thread, session *s)
char display[MAX_DISPLAY_SIZE]
Display name of calling party.
char ident[MAX_IDENT_SIZE]
Ident of calling parting.
void answer(thread *thread, session *s)
static voip::context_t out_context
void terminateLocked(void)
int status_code
Status Code (SIP answer only)
char * body
buffer containing data
void joinLocked(session *s)
void relay(thread *thread, session *s)
Interface class for call detail records.
int tid
unique id for transactions (to be used for answers)
static void decUse(mapped *rr, stats::stat_t stat)
int osip_message_get_body(const osip_message_t *sip, int pos, osip_body_t **dest)
Get one body header.
osip_message_t * response
last response within current transaction
unsigned long duration
Total duration of the call in seconds.
void reinvite(thread *thread, session *s)
void reply_source(int error)
char uuid[48]
A unique identifier for each and every call.
static void header(msg_t msg, const char *key, const char *value)
char network[MAX_NETWORK_SIZE *2]
Subnet interface the caller appeared on.