anchor.diff:      
   
   %% @doc This function is called by NkSIP to process a new incoming REGISTER request. 
  -%%
  -%% If it is not defined, but `registrar' option was present in the SipApp's 
  -%% startup config, NkSIP will process the request. 
  -%% It will NOT check if <i>From</i> and <i>To</i> headers contains the same URI,
  -%% or if the registered domain is valid or not. If you need to check this,
  -%% implement this function returning `register' if everything is ok.
  -%% See {@link nksip_registrar} for other possible response codes defined in the SIP 
  -%% standard registration process.
  -%%
  -%% `Meta' will include at least the following parameters: app_id, registrar, req
  -%% Parameter `registrar' will be `true' if this `registrar' is present in
  -%% SipApp's config. Parameter `req' will have the full #sipmsg{} object.
  -%%
  -%% If this function is not defined, and no `registrar' option is found, 
  -%% a 405 <i>Method not allowed</i> would be replied. 
  -%%
  -%% You should define this function in case you are implementing a registrar server 
  -%% and need a specific REGISTER processing 
  -%% (for example to add some headers to the response).
  -%%
   -spec sip_register(Req::nksip:request(), Call::nksip:call()) ->
       {reply, nksip:sipreply()} | noreply.
   
  
positive.code: 
  
  %% @doc This function is called by NkSIP for every new request, to check if it must be 
  %% proxied, processed locally or replied immediately. For convenience, the scheme, user
  %% and domain parts of the <i>Request-Uri</i> are included.
  %%
  %% If we want to <b>act as a proxy</b> and route the request, and we are not responsible 
  %% for `Domain' we must return `proxy' or `{proxy, ruri, ProxyOpts}'. 
  %% We must not return an `UriSet' in this case. 
  %% NkSIP will then make additional checks to the request (like inspecting the 
  %% `Proxy-Require' header) and will route it statefully to the same `Request-URI' 
  %% contained in the request.
  %% 
  %% If we are the resposible proxy for `Domain' we can provide a new list 
  %% of URIs to route the request to. NkSIP will use <b><i>serial</i> and/or 
  %% <i>parallel</i> forking</b> depending on the format of `UriSet'. 
  %% If `UriSet' is a simple Erlang array of binaries representing uris, NkSIP will try 
  %% each one serially. If any of the elements of the arrary is in turn a new array 
  %% of binaries, it will fork them in parallel. 
  %% For example, for  ```[ <<"sip:aaa">>, [<<"sip:bbb">>, <<"sip:ccc">>], <<"sip:ddd">>]'''
  %% NkSIP will first forward the request to `aaa'. If it does not receive a successful 
  %% (2xx) response, it will try `bbb' and `cccc' in parallel. 
  %% If no 2xx is received again, `ddd' will be tried. See {@link nksip_registrar}
  %% to find out how to get the registered contacts for this `Request-Uri'.
  %%
  %% Available options for `ProxyOpts' are:
  %% <ul>
  %%  <li>`stateless': Use it if you want to proxy the request <i>statelessly</i>. 
  %%       Only one URL is allowed in `UriSet' in this case.</li>
  %%  <li>`record_route': NkSIP will insert a <i>Record-Route</i> header before sending 
  %%      the request, so that following request inside the dialog will be routed 
  %%      to this proxy.</li>
  %%  <li>`path': For REGISTER requests, if the request includes "path" as part of
  %%      the supported tokens, it will insert a <i>Path</i> header (see RFC3327).
  %%      If path it is not supported, it will reply a 421 ("Extension Required")
  %%      response</li>
  %%  <li>`follow_redirects': If any 3xx response is received, the received contacts
  %%      will be inserted in the list of uris to try.</li>
  %%  <li><code>{route, {@link nksip:user_uri()}}</code>: 
  %%      NkSIP will insert theses routes as <i>Route</i> headers
  %%      in the request, before any other existing `Route' header.
  %%      The request would then be sent to the first <i>Route</i>.</li>
  %%  <li><code>{headers, [{@link nksip:header()}]}</code>: 
  %%      Inserts these headers before any existing header.</li>
  %%  <li>`remove_routes': Removes any previous <i>Route</i> header in the request.
  %%      A proxy should not usually do this. Use it with care.</li>
  %%  <li>`remove_headers': Remove previous non-vital headers in the request. 
  %%      You can use modify the headers and include them with using `{headers, Headers}'. 
  %%      A proxy should not usually do this. Use it with care.</li>
  %% </ul>
  %% 
  %% You can also add headers to the request if the URI contains a `<<"Route">>' header
  %%
  %% If we want to <b>act as an endpoint or B2BUA</b> and answer to the request 
  %% from this SipApp, we must return `process' or `process'. 
  %% NkSIP will then make additional checks to the request (like inspecting 
  %% `Require' header), start a new transaction and call the function corresponding 
  %% to the method in the request (like `invite/3', `options/3', etc.)
  %%
  %% Available options for `ProcessOpts' are:
  %% <ul>
  %%  <li>`stateless': Use it if you want to process this request <i>statelessly</i>. 
  %%       No transaction will be started.</li>
  %% <li><code>{headers, [{@link nksip:header()}]}</code>: 
  %%     Insert these headers before any existing header, before calling the next 
  %%     callback function.</li>
  %% </ul>
  %%
  %% We can also <b>send a reply immediately</b>, replying `{response, Response}', 
  %% `{response, Response, ResponseOpts}' or simply `Response'. See {@link nksip_reply} 
  %% to find the recognized response values. The typical reason to reply a response here 
  %% is to send <b>redirect</b> or an error like `not_found', `ambiguous', 
  %% `method_not_allowed' or any other. If the form `{response, Response}' or 
  %% `{response, Response, ResponseOpts}' is used the response is sent statefully, 
  %% and a new transaction will be started, unless `stateless' is present in `ResponseOpts'.
  %% If simply `Response' is used no transaction will be started. 
  %% The only recognized option in `ResponseOpts' is `stateless'.
  %%
  %% If route/3 is not defined the default reply would be `process'.
  %%
  -type route_reply() ::
      proxy | {proxy, ruri | nksip:uri_set()} | 
      {proxy, ruri | nksip:uri_set(), nksip_lib:optslist()} | 
      proxy_stateless | {proxy_stateless, ruri | nksip:uri_set()} | 
      {proxy_stateless, ruri | nksip:uri_set(), nksip_lib:optslist()} | 
      process | process_stateless |
      {reply, nksip:sipreply()} | 
      {reply, nksip:sipreply(), nksip_lib:optslist()}.
  
  -spec sip_route(Scheme::nksip:scheme(), User::binary(), Domain::binary(), 
              Req::nksip:request(), Call::nksip:call()) ->
      route_reply().
  
  sip_route(_Scheme, _User, _Domain, _Req, _Call) ->
      process.
  
  
  %% @doc This function is called by NkSIP to process a new INVITE request as an endpoint.
  %%
  %% `Meta' will include at least the following parameters: aor, dialog_id, content_type
  %% and body (see {@link nksip_request} for details). If content-type is 
  %% `application/sdp' the body will be decoded as a {@link nksip_sdp:sdp()} object
  %% you can manage with the functions in {@link nksip_sdp}.
  %%
  %% Before replying a final response, you will usually call 
  %% {@link nksip_request:reply/3} to send a provisional response like 
  %% `ringing' (which would send a 180 <i>Ringing</i> reply) or `ringing_rel' to send
  %% a <i>reliable provisional response</i>.%% 
  %%
  %% If a quick response (like `busy') is not going to be sent immediately 
  %% (which is typical for INVITE requests, as the user would normally need to accept 
  %% the call) you must return `{noreply, NewState}' and spawn a new process, 
  %% calling {@link nksip:reply/2} from the new process, in order to avoid 
  %% blocking the SipApp process.
  %%
  %% You must then answer the request. The possible responses are defined in 
  %% {@link nksip_reply}.
  %% If a successful (2xx) response is sent, you should include a new generated SDP body
  %% in the response. A new dialog will then start. 
  %% The remote party should then send an ACK request immediately.
  %% If none is received, NkSIP will automatically stop the dialog.
  %%
  -spec sip_invite(Req::nksip:request(), Call::nksip:call()) ->
      {reply, nksip:sipreply()} | noreply.
  
  sip_invite(_Req, _Call) ->
      {reply, decline}.
  
  
  %% @doc This function is called when a new in-dialog INVITE request is received.
  %%
  %% The guidelines and `Meta' in {@link sip_invite/4} are still valid, 
  %% but you shouldn't send provisional responses, sending a final response inmediatly.
  %% 
  %% If the dialog's target or the SDP session parameters are updated by the request or
  %% its response, {@link dialog_update/3} and/or {@link session_update/3} would be
  %% called.
  %%
  -spec sip_reinvite(Req::nksip:request(), Call::nksip:call()) ->
      {reply, nksip:sipreply()} | noreply.
  
  sip_reinvite(Req, Call) ->
      AppId = nksip_request:app_id(Req),
      AppId:sip_invite(Req, Call).
  
  
  %% @doc Called when a pending INVITE request is cancelled.
  %%
  %% When a CANCEL request is received by NkSIP, it will check if it belongs to an 
  %% existing INVITE transaction. If not, a 481 <i>Call/Transaction does not exist</i> 
  %% will be automatically replied.
  %%
  %% If it belongs to an existing INVITE transaction, NkSIP replies 200 <i>OK</i> to the
  %% CANCEL request. If the matching INVITE transaction has not yet replied a
  %% final response, NkSIP replies it with a 487 (Request Terminated) and this function
  %% is called. If a final response has already beeing replied, it has no effect.
  %% 
  %% `Meta' will include a parameter `{req_id, InviteId}' showing the request id of the
  %% INVITE being cancelled.
  %%
  -spec sip_cancel(InviteReq::nksip:request(), Req::nksip:request(), Call::nksip:call()) ->
      ok.
  
  sip_cancel(_CancelledReq, _Req, _Call) ->
      ok.
  
  
  %% @doc Called when a valid ACK request is received.
  %%
  %% This function is called by NkSIP when a new valid in-dialog ACK request has to
  %% be processed locally.
  %%
  %% `Meta' will include at least the following parameters: dialog_id, content_type
  %% and body (see {@link nksip_request} for details).
  %%
  %% You don't usually need to implement this callback. One possible reason to do it is 
  %% to receive the SDP body from the other party in case it was not present in the INVITE
  %% (you can also get it from the {@link session_update/3} callback).
  %%
  -spec sip_ack(Req::nksip:request(), Call::nksip:call()) ->
      ok.
  
  sip_ack(_Req, _Call) ->
      ok.
  
  
  %% @doc Called when a valid BYE request is received.
  %%
  %% When a BYE request is received, NkSIP will automatically response 481 
  %% <i>Call/Transaction does not exist</i> if it doesn't belong to a current dialog.
  %% If it does, NkSIP stops the dialog and this callback functions is called.
  %% You won't usually need to implement this function, but in case you do, you
  %% should reply `ok' to send a 200 response back.
  %%
  %% `Meta' will include at least the following parameters: aor, dialog_id
  %% (see {@link nksip_request} for details).
  %%
  -spec sip_bye(Req::nksip:request(), Call::nksip:call()) ->
      {reply, nksip:sipreply()} | noreply.
  
  sip_bye(_Req, _Call) ->
      {reply, ok}.
  
  
  %% @doc Called when a valid INFO request is received.
  %%
  %% When an INFO request is received, NkSIP will automatically response 481
  %% <i>Call/Transaction does not exist</i> if it doesn't belong to a current dialog.
  %% If it does, NkSIP this callback functions is called.
  %% If implementing this function, you should reply `ok' to send a 200 response back.
  %%
  %% `Meta' will include at least the following parameters: aor, content-type, body
  %% (see {@link nksip_request} for details).
  %%
  -spec sip_info(Req::nksip:request(), Call::nksip:call()) ->
      {reply, nksip:sipreply()} | noreply.
  
  sip_info(_Req, _Call) ->
      {reply, ok}.
  
  
  %% @doc Called when a OPTIONS request is received.
  %%
  %% This function is called by NkSIP to process a new incoming OPTIONS request as 
  %% an endpoint. If not defined, NkSIP will reply with a 200 <i>OK</i> response, 
  %% including automatically generated `Allow', `Accept' and `Supported' headers.
  %%
  %% NkSIP will not send any body in its automatic response. This is ok for proxies. 
  %% If you are implementing an endpoint or B2BUA, you should implement this function 
  %% and include in your response a SDP body representing your supported list of codecs, 
  %% and also `Allow', `Accept' and `Supported' headers.
  %%
  %% `Meta' will include at least the following parameters: aor
  %% (see {@link nksip_request} for details).
  %%
  -spec sip_options(Req::nksip:request(), Call::nksip:call()) ->
      {reply, nksip:sipreply()} | noreply.
  
  
negative.code: 
  %% @doc Called when the SipApp process receives an unknown message.
  -spec handle_info(Msg::term(), State::term()) ->
      {noreply, State::term()} |
      {noreply, State::term(), Timeout::timeout()} |
      {stop, Reason::term(), State::term()}.
  
  handle_info(_Msg, State) ->
      {noreply, State}.
  
  
  
  %%%%%%%%%%%%%% Other Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  
  %% @doc Called when the status of an automatic ping configuration changes.
  -spec sip_ping_update(PingId::term(), OK::boolean(), AppId::nksip:app_id()) ->
      ok.
  
  sip_ping_update(_PingId, _OK, _AppId) ->
      ok.
  
  
  %% @doc Called when the status of an automatic registration configuration changes.
  -spec sip_register_update(RegId::term(), OK::boolean(), AppId::nksip:app_id()) ->
      ok.
  
  sip_register_update(_RegId, _OK, _AppId) ->
      ok.
  
  
  
  
  
  
  
  
  
  