Hi everyone. We are new to Kamailio and using Kamailio 5.8 with FreeSwitch. We have the issue with the incoming call from our provider. They are dropping after 30 seconds. The client doesn't receive ACK from Kamailio. But FreeSwitch sends ACK to Kamailio. The outbound call is working fine. At the moment flow is our provider -> FreeSwitch -> Kamailio -> our web client.Kemi.py. |
import logging import sys import KSR as KSR import requests # global variables corresponding to defined values (e.g., flags) in kamailio.cfg FLT_ACC=1 FLT_ACCMISSED=2 FLT_ACCFAILED=3 FLT_NATS=5
FLB_NATB=6 FLB_NATSIPPING=7 Max_Expires = 60 API_Key = "API_KEY" api_base = "http://ourbaseurl.com" # Set up logging def setup_logger(): logger = logging.getLogger('KamailioLogger') logger.setLevel(logging.INFO) handler = logging.FileHandler('/tmp/kemi.txt') formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) return logger # Global function to instantiate a kamailio class object # Executed when kamailio app_python module is initialized def mod_init(): logger = setup_logger() logger.info("===== from Python mod init\n") print("===== from Python mod init\n") # Instead of creating /tmp/status.txt, log a message logger.info("Hello World") return kamailio(logger) # SIP request routing # -- equivalent of request_route{} def ksr_request_route(): KSR.info("===== request - from kamailio python script\n") KSR.info("===== method [%s] r-uri [%s]\n" % (KSR.pv.get("$rm"), KSR.pv.get("$ru"))) print("===== request - from kamailio python script\n") print("===== method [%s] r-uri [%s]\n" % (KSR.pv.get("$rm"), KSR.pv.get("$ru"))) # Start defining kamailio class class kamailio: def __init__(self, logger): self.logger = logger self.logger.info('===== kamailio.__init__\n') print('===== kamailio.__init__\n') # Executed when kamailio child processes are initialized def child_init(self, rank): self.logger.info('===== kamailio.child_init(%d)\n' % rank) return 0 # SIP request routing - equivalent of request_route{} def ksr_request_route(self, msg): self.logger.info("===== request - from kamailio python script\n") self.logger.info("===== method [%s] r-uri [%s]\n" % (KSR.pv.get("$rm"), KSR.pv.get("$ru"))) print("===== request - from kamailio python script\n") print("===== method [%s] r-uri [%s]\n" % (KSR.pv.get("$rm"), KSR.pv.get("$ru"))) # NAT detection if self.ksr_route_natdetect(msg)==-255 : return 1 # CANCEL processing if KSR.is_CANCEL() : if KSR.tm.t_check_trans()>0 : self.ksr_route_relay(msg) return 1 # -- only initial requests (no To tag) # handle retransmissions if KSR.tmx.t_precheck_trans()>0 : KSR.tm.t_check_trans() return 1 if KSR.tm.t_check_trans()==0 : return 1 if self.ksr_app_auth(msg) == 1: return 1 # record routing for dialog forming requests (in case they are routed) # - remove preloaded route headers KSR.hdr.remove("Route") if KSR.is_method_in("IS") : KSR.rr.record_route() # handle requests within SIP dialogs if self.ksr_route_withindlg(msg)==-255 : return 1 # account only INVITEs if KSR.pv.get("$rm")=="INVITE" : KSR.setflag(FLT_ACC); # do accounting source_ip = KSR.pv.get("$si") source_port = KSR.pv.get("$sp") destination_ip = KSR.pv.get("$di") destination_port = KSR.pv.get("$dp") KSR.log("info", f"Debugging - Source IP: {source_ip}, Source Port: {source_port}") KSR.log("info", f"Debugging - Destination IP: {destination_ip}, Destination Port: {destination_port}") #Check if request is from dispatcher list if source_ip == "FREESWITCH_IP": KSR.log("info","Match found") # Request is from FreeSWITCH to client, perform a lookup location if not KSR.registrar.lookup("location"): KSR.log("info","No registered user found in the location table") KSR.sl.sl_send_reply(404, "Not Found") exit() elif KSR.pv.get("$du") is None: KSR.err("ALERT: this is broken registration!") KSR.sl.sl_send_reply(404, "Not Found") exit() else: if not KSR.dispatcher.ds_select_dst(1, 2): KSR.sl.sl_send_reply(503, "Service Unavailable") exit() KSR.err("ALERT: Updated request domain $du to " + KSR.pv.get("$du")) KSR.err("ALERT: Updated request domain $ru to " + KSR.pv.get("$ru")) # dispatch requests to foreign domains if self.ksr_route_sipout(msg)==-255 : return 1 if KSR.corex.has_ruri_user() < 0 : # request with no Username in RURI KSR.sl.sl_send_reply(484, "Address Incomplete") return 1 # user location service self.ksr_route_location(msg) return 1 def ksr_xhttp_event(self, evname, something): self.logger.info("===== xhttp module triggered event: " + str(evname) + str(something) + "\n") self.logger.info("L_DBG", "HTTP Request Received\n") KSR.websocket.handle_handshake() self.logger.info("===== made it past handle_handshake() \n") return 1 # wrapper around tm relay function def ksr_route_relay(self, msg): # enable additional event routes for forwarded requests # - serial forking, RTP relaying handling, a.s.o. if KSR.is_method_in("IBSU") : if KSR.tm.t_is_set("branch_route")<0 : KSR.tm.t_on_branch("ksr_branch_manage") if KSR.is_method_in("ISU") : if KSR.tm.t_is_set("onreply_route")<0 : KSR.tm.t_on_reply("ksr_onreply_manage") if KSR.is_INVITE() : if KSR.tm.t_is_set("failure_route")<0 : KSR.tm.t_on_failure("ksr_failure_manage") if KSR.tm.t_relay()<0 : KSR.sl.sl_reply_error() return -255 # Handle requests within SIP dialogs def ksr_route_withindlg(self, msg): if KSR.siputils.has_totag()<0 : return 1 # sequential request within a dialog should # take the path determined by record-routing if KSR.rr.loose_route()>0 : if self.ksr_route_dlguri(msg)==-255 : return -255 if KSR.is_BYE() : # do accounting ... KSR.setflag(FLT_ACC) # ... even if the transaction fails KSR.setflag(FLT_ACCFAILED) elif KSR.is_ACK() : # ACK is forwarded statelessly if self.ksr_route_natmanage(msg)==-255 : return -255 elif KSR.is_NOTIFY() : # Add Record-Route for in-dialog NOTIFY as per RFC 6665. KSR.rr.record_route() self.ksr_route_relay(msg) return -255 if KSR.is_ACK() : if KSR.tm.t_check_trans() >0 : # no loose-route, but stateful ACK # must be an ACK after a 487 # or e.g. 404 from upstream server self.ksr_route_relay(msg) return -255 else: # ACK without matching transaction ... ignore and discard return -255 KSR.sl.sl_send_reply(404, "Not here") return -255 # User location service def ksr_route_location(self, msg): # Commented this part to make the outbound call work #rc = KSR.registrar.lookup("location") #if rc<0 : # KSR.tm.t_newtran() # if rc==-1 or rc==-3 : # KSR.sl.send_reply(404, "Not Found") # return -255 # elif rc==-2 : # KSR.sl.send_reply(405, "Method Not Allowed") # return -255 # when routing via usrloc, log the missed calls also if KSR.is_INVITE() : KSR.setflag(FLT_ACCMISSED) self.ksr_route_relay(msg) return -255 # Caller NAT detection def ksr_route_natdetect(self, msg): KSR.force_rport() if KSR.nathelper.nat_uac_test(19)>0 : if KSR.is_REGISTER() : KSR.nathelper.fix_nated_register() elif KSR.siputils.is_first_hop()>0 : KSR.nathelper.set_contact_alias() KSR.setflag(FLT_NATS) return 1 # RTPProxy control def ksr_route_natmanage(self, msg): if KSR.siputils.is_request()>0 : if KSR.siputils.has_totag()>0 : if KSR.rr.check_route_param("nat=yes")>0 : KSR.setbflag(FLB_NATB) if (not (KSR.isflagset(FLT_NATS) or KSR.isbflagset(FLB_NATB))) : return 1 KSR.rtpproxy.rtpproxy_manage("co") if KSR.siputils.is_request()>0 : if not KSR.siputils.has_totag() : if KSR.tmx.t_is_branch_route()>0 : KSR.rr.add_rr_param(";nat=yes") if KSR.siputils.is_reply()>0 : if KSR.isbflagset(FLB_NATB) : KSR.nathelper.set_contact_alias() return 1 # URI update for dialog requests def ksr_route_dlguri(self, msg): if not KSR.isdsturiset() : KSR.nathelper.handle_ruri_alias() return 1 # Routing to foreign domains def ksr_route_sipout(self, msg): if KSR.is_myself_ruri() : return 1 KSR.hdr.append("P-Hint: outbound\r\n") self.ksr_route_relay(msg) return -255 # Manage outgoing branches # -- equivalent of branch_route[...]{} def ksr_branch_manage(self, msg): self.ksr_route_natmanage(msg) return 1 # Manage incoming replies # -- equivalent of onreply_route[...]{} def ksr_onreply_manage(self, msg): KSR.dbg("incoming reply\n") scode = KSR.pv.get("$rs") if scode>100 and scode<299 : self.ksr_route_natmanage(msg) return 1 # Manage failure routing cases # -- equivalent of failure_route[...]{} def ksr_failure_manage(self, msg): if self.ksr_route_natmanage(msg)==-255 : return 1 if KSR.tm.t_is_canceled()>0 : return 1 return 1 # SIP response handling # -- equivalent of reply_route{} def ksr_reply_route(self, msg): KSR.dbg("response handling - python script\n") if KSR.sanity.sanity_check(17604, 6)<0 : KSR.err("Malformed SIP response from " + KSR.pv.get("$si") + ":" + str(KSR.pv.get("$sp")) +"\n") KSR.set_drop() return -255 return 1 #app Auth Handling def ksr_app_auth(self, msg): # This is our custom python function that authenticates from our api.
__________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to [email protected] Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
