== AsteriskSource/SipModule == * call-limit * static int load_module(void) * ASTOBJ_CONTAINER_INIT * user, peer, registry object list * sched = sched_context_create() * io = io_context_create() * reload_config(sip_reloadreason) * ast_channel_register(&sip_tech) * register * cli, rtp_proto, udptl_prot, application, custom_function, manager * sip_poke_all_peers(); * sip_send_all_registers(); * restart_monitor(); * return AST_MODULE_LOAD_SUCCESS; * static int restart_monitor(void) * monitor_thread == pthread_self() * ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) * return 0; * do_monitor * sipsock_read * handle_request * INVITE, OPTIONS, REFER, BYE, CANCEL * handle_response {{{ * A new INVITE is sent to handle_request_invite(), that will end up * starting a new channel in the PBX, the new channel after that executing * in a separate channel thread. This is an incoming "call". * When the call is answered, either by a bridged channel or the PBX itself * the sip_answer() function is called. }}} == sip_request_call == * static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause) * if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { * *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; * Can't find codec to connect to host * return NULL; * } * if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { * *cause = AST_CAUSE_SWITCH_CONGESTION; * } * if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { * *cause = AST_CAUSE_SWITCH_CONGESTION; * return NULL; * } * if (create_addr(p, host, NULL)) { * *cause = AST_CAUSE_UNREGISTERED; * return NULL; * } * tmpc = sip_new(p, AST_STATE_DOWN, host); * restart_monitor(); * return tmpc; * static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title) * { * tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i); * } * if (!tmp) { * return NULL; * } * if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { * Unable to start PBX on * tmp = NULL; * } * return tmp; * ast_pbx_start * AST_PBX_FAILED: -1 * AST_PBX_CALL_LIMIT: -2 * AST_PBX_SUCCESS: 0 * static int sip_call(struct ast_channel *ast, char *dest, int timeout) * if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { * return -1; * } * res = update_call_counter(p, INC_CALL_RINGING); * if ( res != -1 ) { * if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { * res = -1; * } else { * xmitres = transmit_invite(p, SIP_INVITE, 1, 2); * if (xmitres == XMIT_ERROR) * return -1; * p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); * } * } else { * ast->hangupcause = AST_CAUSE_USER_BUSY; * } * return res; == Sip protocol == * What are the benefits of SIP? * Generally it is used by two end-points to negotiate a "call." * By negotiate I mean * the medium (text, voice, other), * the transport (usually RTP, Real Time Protocol), and * the encoding (codec). * Once the negotiation is successful, * the two end-points use the selected method * for talking to each other - independently of SIP. * Once the "call" is over, * SIP is used to indicate a disconnection. * Therefore, SIP is best used as a signaling mechanism. * SIP and its extensions also provide related functions * such as instant messaging, registration, and presence. * A sip call session between 2 phones is established as follows: * The calling phone sends out an invite * The called phone sends an information response 100 - Trying - back. * When the called phone starts ringing a response 180 - Ringing - is sent back * When the caller picks up the phone, the called phone sends a response 200 - OK * The calling phone responds with ACK - acknowledgement * Now the actual conversation is transmitted as data via RTP * When the person calling hangs up, a BYE request is sent to the calling phone * The calling phone responds with a 200 - OK. * Call-ID * The Call-ID is seen as a unique identifier for a particular call. * It is then used by the originating client to match responses appropriately. * Call-ID acts as a unique identifier to group together a series of messages. * So what does this group means? * A Sip call consists of a series of requests/responses. * Clients (both client and server) need a mechanism to associate(group) such requests/responses. * Components of sip * User Agent Client (UAC) * User Agent Server (UAS) * Proxy server * Redirect server * Registra * Location server * SIP request and reply * start line * request INVITE sip:user@sipserver.com SIP/2.0 * reply SIP/2.0 200 OK * message headers * Via * From * To * Call-id * Cseq * Contact * User-Agent * Content-Type * Content-Length * message body * Request methods * INVITE : Indicates that the user or service is being invited to participate in a session. The body of this message would include a description of the session to which the callee is being invited. * ACK : Confirms that the client has received a final response to an INVITE request, and is only used with INVITE requests. * BYE : Is sent by a User Agent Client to indicate to the server that it wishes to terminate the call. * CANCEL : Is used to cancel a pending request. * OPTIONS : Is used to query a server about its capabilities. * REGISTER : Is used by a client to register an address with a SIP server. * INFO * Response classes * provisional * final == Cseq == * A CSeq header field in a request contains * a single decimal sequence number * and the request method * The CSeq header field serves * to identify and order transactions within a dialog, * to provide a means to uniquely identify transactions, * and to differentiate between new requests and request retransmissions. * Two CSeq header fields are considered equal * if the sequence number and the request method are identical. * Method * The method part of CSeq is case-sensitive and MUST match that of the request. * Sequence number * is chosen by the requesting client * and is unique within a single value of Call-ID. * MUST be expressible as a 32-bit unsigned integer * and MUST be less than 2**31. * For non-REGISTER requests outside of a dialog, * the sequence number value is arbitrary. * Consecutive Requests that differ in method, headers or body, but have the same CallIdHeader * must contain strictly monotonically increasing * and contiguous sequence numbers; * sequence numbers do not wrap around. * Retransmissions of the same Request carry the same sequence number, * but an INVITE Request with a different message body or different headers (a "re-invitation") acquires a new, higher sequence number. * A server must echo the CSeqHeader from the Request in its Response. * If the method value is missing in the received CSeqHeader, * the server fills it in appropriately. * ACK and CANCEL Requests must contain the same CSeqHeader sequence number (but not method) as the INVITE Request they refer to, * while a BYE Request cancelling an invitation must have a higher sequence number. * An user agent server must remember the highest sequence number for any INVITE Request with the same CallIdHeader. * The server must respond to, and then discard, any INVITE Request with a lower sequence number. == sip address == * sip address * A SIP address is a way to be reachable and to reach people. You can compare it to an e-mail address. You can signup for a free account on Ekiga.net. It will give you a unique SIP address that you can give to your friends so that they can contact you. An example of SIP address is sip:dsandras@ekiga.net. * sip * SIP is the Session Initiation Protocol, defined in RFC 3261. It is the most widely used standard for VoIP signalling. It was designed to be a general-purpose way to set up real-time multimedia sessions between groups of participants. SIP is used during and after the call setup. * sip URI * URI Means "Uniform Resource Identifier". A SIP URI is used to identify an entity to be addressed via SIP, just like an email address identifies the email recipient. The general format of a SIP URI is user@domain:port user" identifies the particular user to address. The user can be a phone number, if this is supported by the SIP server. {{{ Your ¡°SIP program¡± registers its online presence with a ¡°SIP Proxy¡±: ¡°Hey, i¡¯m on my home network right now, and I can be reached at this IP address¡±. When you arrive at work, your SIP program will now say ¡°Yoohoo, i¡¯ve moved, i¡¯m now here!¡±. If someone wants to call you, they¡¯ll type your SIP address in their SIP program. The SIP provider will help this person¡¯s SIP software get in touch with your computer¡¯s SIP software, partly thanks to some STUN magic thrown in the middle. A SIP address looks exactly like an e-mail address, and, with some providers such as EarthLink, can very-well be one and the same. In my case, you can send me an e-mail at hollandct@earthlink.net or plug hollandct@earthlink.net ( or sip:hollandct@earthlink.net ) in your SIP program to call me up. If i¡¯m not online or available, you¡¯ll hear my voicemail, which will then be delivered as a .wav attachment to my e-mail address ¡¦ which Mail.app plays inline just fine! You don¡¯t even need a ¡°SIP Provider¡± to do SIP. If you know your party¡¯s IP address or host name, if their SIP software is properly configured, you can plug their IP address into your SIP program to give them a ring. Having a SIP address just gives you a more universal way for people to get in touch with you. }}}