Could be anything, but most likely you aren't receiving those in Kam because the PBX sends them somewhere else, check where the PBX sends those, check the Contact URI, that's the address where ACKs will be sent out.

The SBC for Teams article suggests a double header record_route_preset() for transport conversion, not sure why your config is different.

Also, at the very least, the config seems to invoke record_route[_preset]() twice per INVITE, it shouldn't be like that. 

Good luck.

On Sun, Jul 19, 2020 at 3:55 AM Daniel van der Tang <tangd122@gmail.com> wrote:
Hello,

I'm setting up a Kamailio MSFT Teams SBC that is connected to our SIP trunk provider. This server is directly connected to the Internet and not behind a NAT routing. 

It is successfully processing invites from both sides (MSFT Teams and SIP trunk). Unfortunately the ACKs and CANCEL messages are not relaying to Teams. In the sipdump i can't find these messages. 

Does anyone see what I am doing wrong? Below you can find my config

#!KAMAILIO

####### Defined Values #########

#!define MULTIDOMAIN 0

# - flags
#   FLT_ - per transaction (message) flags
# FLB_ - per branch flags
#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3
#!define FLT_NATS 5

#!define FLB_NATB 6
#!define FLB_NATSIPPING 7

#!define FROM_TEAMS 11
#!define FROM_PBX 12

######## Define Modules ###########
#!define WITH_RTPENGINE
#!define WITH_TLS
#!define WITH_SIPDUMP
#!define WITH_DISPATCH

####### Global Parameters #########

### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR
debug=2
log_stderror=no

memdbg=5
memlog=5

log_facility=LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "

/* number of SIP routing processes */
children=2

/* uncomment the next line to disable TCP (default on) */
# disable_tcp=yes

alias=SBC_FQDN

/* listen addresses */
listen=udp:PUBLIC_IP:5060 advertise SBC_FQDN:5060
#!ifdef WITH_TLS
listen=tls:PUBLIC_IP:5061 advertise SBC_FQDN:5061
#!endif

server_header= "Server: ABC SBC"
user_agent_header= "User-Agent: ABC SBC"


###### TLS Enable ######
#!ifdef WITH_TLS
enable_tls=yes
#tcp_connect_timeout=1000

tcp_accept_no_cl=yes
tcp_async = yes
tcp_connection_lifetime=600

/* upper limit for TLS connections */
tls_max_connections=2048
#!endif


####### Custom Parameters #########

/* These parameters can be modified runtime via RPC interface
 * - see the documentation of 'cfg_rpc' module.
 *
 * Format: group.id = value 'desc' description
 * Access: $sel(cfg_get.group.id) or @cfg_get.group.id */

####### Modules Section ########

/* set paths to location of modules */
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "acc.so"
loadmodule "counters.so"

#!ifdef WITH_RTPENGINE
loadmodule "rtpengine.so"
#!endif

#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif

#!ifdef WITH_SIPDUMP
loadmodule "sipdump.so"
#!endif

#!ifdef WITH_DISPATCH
loadmodule "dispatcher.so"
#!endif

# ----------------- setting module-specific parameters ---------------

#!ifdef WITH_RTPENGINE
# ----- rtpengine params -----+
modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:12222")
#!endif

#!ifdef WITH_TLS
# ----- tls params -----+
modparam("tls", "xavp_cfg", "tls")
modparam("tls", "config", "/etc/kamailio/tls.cfg")
modparam("tls", "connection_timeout", 10)
modparam("tls", "ssl_release_buffers", 1)
modparam("tls", "send_close_notify", 1)
modparam("tls", "session_cache", 0)

#!endif

#!ifdef WITH_SIPDUMP
modparam("sipdump", "enable", 1)
#!endif

#!ifdef WITH_DISPATCH
#---------- dispatch
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_ping_interval", 300)
#!endif


# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
/* set the path to RPC fifo control file */
# modparam("jsonrpcs", "fifo_name", "/run/kamailio/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
# modparam("jsonrpcs", "dgram_socket", "/run/kamailio/kamailio_rpc.sock")

# ----- ctl params -----
/* set the path to RPC unix socket control file */
# modparam("ctl", "binrpc", "unix:/run/kamailio/kamailio_ctl")

# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)

# ----- rr params -----
# set next param to 1 to add value to ;lr param (helps with some UAs)
modparam("rr", "enable_full_lr", 0)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)

# ----- acc params -----
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 0)
/* by default ww do not adjust the direct of the sequential requests.
 * if you enable this parameter, be sure the enable "append_fromtag"
 * in "rr" module */
modparam("acc", "detect_direction", 0)
/* account triggers (flags) */
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "log_missed_flag", FLT_ACCMISSED)
modparam("acc", "log_extra",
  "src_user=$fU;src_domain=$fd;src_ip=$si;"
  "dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)

####### Routing Logic ########


/* Main SIP request routing logic
 * - processing of any incoming SIP request starts with this route
 * - note: this is the same as route { ... } */
request_route {
  # per request initial checks
  route(REQINIT);

  #check who is the sender
  route(INITCHECK);

  # CANCEL processing
  if (is_method("CANCEL")) {
    if (t_check_trans()) {
      route(RELAY);
    }
    exit;
  }

  # handle retransmissions
  if (!is_method("ACK")) {
    if(t_precheck_trans()) {
      t_check_trans();
      exit;
    }
    t_check_trans();
  }

  # handle requests within SIP dialogs
  route(WITHINDLG);

  ### only initial requests (no To tag)

  # record routing for dialog forming requests (in case they are routed)
  # - remove preloaded route headers
  remove_hf("Route");
  if (is_method("INVITE|SUBSCRIBE")) {
    record_route();
  }

  # account only INVITEs
  if (is_method("INVITE")) {
    setflag(FLT_ACC); # do accounting
  }

  if ($rU==$null) {
    # request with no Username in RURI
    sl_send_reply("484","Address Incomplete");
    exit;
  }

  # update $du to set the destination address for proxying
  #$du = "sip:" + $rd + ":9";
 
  route(RELAY);
  exit;
}

route[INITCHECK] {
  if(from_uri =~ ".*microsoft.com")
  {  
    setflag(FROM_TEAMS);
    $du = "sip:" + "PBX_IP";
    route(HANDLE_RTP_FROM_TEAMS);
  } else if(from_uri =~ ".*" + "PBX_IP")
  {
    setflag(FROM_PBX);
    $du="sip:sip.pstnhub.microsoft.com;transport=tls";
    route(HANDLE_RTP_FROM_PBX);
  } else {
    exit;
  }
}

#Manage RTP & transcoding comming from Teams to PBX
route[HANDLE_RTP_FROM_TEAMS] {
 
  if (has_body("application/sdp"))
  {
    t_on_reply("PBX_REPLY_TO_TEAMS");
    rtpengine_manage("RTP codec-mask=all codec-transcode=PCMA replace-origin replace-session-connection ICE=remove");
    record_route();
    t_relay_to_udp("PBX_IP","5060");
  }
 

}

#Manage RTP & transcoding comming from PBX to Teams
route[HANDLE_RTP_FROM_PBX] {
 
    if (has_body("application/sdp"))
    {
      t_on_reply("TEAMS_REPLY_TO_PBX");
     
      rtpengine_manage("SRTP codec-mask=all ICE=force codec-transcode=PCMA replace-origin replace-session-connection");
      record_route_preset("SBC_FQDN:5061;transport=tls");
      add_rr_param(";r2=on");

      $rd = "sip.pstnhub.microsoft.com";
      $td = "SBC_FQDN";
      $fd = "SBC_FQDN";


      #Set TLS SNI (server name & server id)
      $xavp(tls=>server_name) = "SBC_FQDN";
      $xavp(tls=>server_id) = "SBC_FQDN";

      t_relay();
    }
}


# Wrapper for relaying requests
route[RELAY] {

  # enable additional event routes for forwarded requests
  # - serial forking, RTP relaying handling, a.s.o.
  if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
    if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
  }
  if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
    if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
  }
  if (is_method("INVITE")) {
    if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
  }

  if (!t_relay()) {
    sl_reply_error();
  }
  exit;
}

# Per SIP request initial checks
route[REQINIT] {
  if($ua =~ "friendly-scanner|sipcli|VaxSIPUserAgent") {
    # silent drop for scanners - uncomment next line if want to reply
    # sl_send_reply("200", "OK");
    exit;
  }

  if (!mf_process_maxfwd_header("10")) {
    sl_send_reply("483","Too Many Hops");
    exit;
  }

  if(is_method("OPTIONS")) {
    sl_send_reply("200","Keepalive");
    exit;
  }

  if(!sanity_check("1511", "7")) {
    xlog("Malformed SIP message from $si:$sp\n");
    exit;
  }
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
  if (!has_totag()) return;

  #Teams reINVITEs
  if(isflagset(FROM_TEAMS)) {
    t_relay_to_udp("PBX_IP","5060");
    exit;
  }

  # sequential request withing a dialog should
  # take the path determined by record-routing
  if (loose_route()) {
    if (is_method("BYE")) {
      setflag(FLT_ACC); # do accounting ...
      setflag(FLT_ACCFAILED); # ... even if the transaction fails

      #set coresponding cert on transactions
      if($fd == "SBC_FQDN") {
        $xavp(tls=>server_name) = "SBC_FQDN";
        $xavp(tls=>server_id) = "SBC_FQDN";
      }

    } else if ( is_method("NOTIFY") ) {
      # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
      record_route();
    }

    route(RELAY);
    exit;
  }

  if ( is_method("ACK") ) {
    if ( t_check_trans() ) {
      # no loose-route, but stateful ACK;
      # must be an ACK after a 487
      # or e.g. 404 from upstream server
      route(RELAY);
      exit;
    } else {
      # ACK without matching transaction ... ignore and discard
      exit;
    }
  }
  sl_send_reply("404","Not here");
  exit;
}

# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
  xdbg("new branch [$T_branch_idx] to $ru\n");
}

# Manage incoming replies
onreply_route[MANAGE_REPLY] {
  xdbg("incoming reply\n");
}

#PBX On Reply
onreply_route[PBX_REPLY_TO_TEAMS]
{
    if (has_body("application/sdp"))
  {
        rtpengine_manage("SRTP codec-mask=all codec-transcode=PCMA replace-origin replace-session-connection media-address=PUBLIC_IP");
  }
}


#From Teams On Reply
onreply_route[TEAMS_REPLY_TO_PBX]
{
    if (has_body("application/sdp"))
  {
        rtpengine_manage("RTP codec-mask=all codec-transcode=PCMA replace-origin replace-session-connection media-address=PUBLIC_IP");
  }
}

# Manage failure routing cases
failure_route[MANAGE_FAILURE] {
  if (t_is_canceled()) exit;
}

event_route[tm:local-request] {
        if(is_method("OPTIONS") && $ru =~ "pstnhub.microsoft.com") {
               append_hf("Contact: <sip:SBC_FQDN:5061;transport=tls>\r\n");
        }
        xlog("L_INFO", "Sent out tm request: $mb\n");
}
_______________________________________________
Kamailio (SER) - Users Mailing List
sr-users@lists.kamailio.org
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users