SMS related additions
This commit is contained in:
		
							
								
								
									
										3
									
								
								.env
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								.env
									
									
									
									
									
								
							| @@ -104,3 +104,6 @@ OSMOMSC_IP=172.22.0.31 | ||||
|  | ||||
| # OSMOHLR | ||||
| OSMOHLR_IP=172.22.0.32 | ||||
|  | ||||
| # SMSC | ||||
| SMSC_IP=172.22.0.33 | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
| cp /mnt/dns/epc_zone /etc/bind | ||||
| cp /mnt/dns/ims_zone /etc/bind | ||||
| cp /mnt/dns/pub_3gpp_zone /etc/bind | ||||
| cp /mnt/dns/e164.arpa /etc/bind | ||||
| cp /mnt/dns/named.conf /etc/bind | ||||
|  | ||||
| [ ${#MNC} == 3 ] && EPC_DOMAIN="epc.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || EPC_DOMAIN="epc.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" | ||||
| @@ -45,11 +46,15 @@ sed -i 's|PCSCF_IP|'$PCSCF_IP'|g' /etc/bind/ims_zone | ||||
| sed -i 's|ICSCF_IP|'$ICSCF_IP'|g' /etc/bind/ims_zone | ||||
| sed -i 's|SCSCF_IP|'$SCSCF_IP'|g' /etc/bind/ims_zone | ||||
| sed -i 's|FHOSS_IP|'$FHOSS_IP'|g' /etc/bind/ims_zone | ||||
| sed -i 's|SMSC_IP|'$SMSC_IP'|g' /etc/bind/ims_zone | ||||
|  | ||||
| sed -i 's|PUB_3GPP_DOMAIN|'$PUB_3GPP_DOMAIN'|g' /etc/bind/pub_3gpp_zone | ||||
| sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/pub_3gpp_zone | ||||
| sed -i 's|ENTITLEMENT_SERVER_IP|'$ENTITLEMENT_SERVER_IP'|g' /etc/bind/pub_3gpp_zone | ||||
|  | ||||
| sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/bind/e164.arpa | ||||
| sed -i 's|DNS_IP|'$DNS_IP'|g' /etc/bind/e164.arpa | ||||
|  | ||||
| sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/bind/named.conf | ||||
| sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/bind/named.conf | ||||
| sed -i 's|PUB_3GPP_DOMAIN|'$PUB_3GPP_DOMAIN'|g' /etc/bind/named.conf | ||||
|   | ||||
							
								
								
									
										14
									
								
								dns/e164.arpa
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								dns/e164.arpa
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| $TTL 1h | ||||
| @ IN SOA ns.e164.arpa. root.e164.arpa. ( | ||||
|                                                         2009010918 ;serial | ||||
|                                                         3600 ;refresh | ||||
|                                                         3600 ;retry | ||||
|                                                         3600 ;expire | ||||
|                                                         3600 ;minimum TTL | ||||
| ) | ||||
| @ IN NS e164.arpa. | ||||
| @ IN A DNS_IP | ||||
|  | ||||
| ; Wildcard to match any tel:+xxxx and change to sip:xxxx@IMS_DOMAIN | ||||
| * IN NAPTR 10 100 "u" "E2U+sip" "!(^.*$)!sip:\\1@IMS_DOMAIN!" . | ||||
| * IN NAPTR 20 100 "u" "E2U+sip" "!(^.*$)!sip:+\\1@IMS_DOMAIN!" . | ||||
| @@ -23,3 +23,7 @@ _sip._udp.scscf         1D SRV 0 0 6060 scscf | ||||
| _sip._tcp.scscf         1D SRV 0 0 6060 scscf | ||||
|  | ||||
| hss                     1D IN A         FHOSS_IP | ||||
|  | ||||
| smsc                    1D IN A         SMSC_IP | ||||
| _sip._udp.smsc          1D SRV 0 0 7060 smsc | ||||
| _sip._tcp.smsc          1D SRV 0 0 7060 smsc | ||||
|   | ||||
| @@ -46,3 +46,8 @@ zone "PUB_3GPP_DOMAIN" { | ||||
|         type master; | ||||
|         file "/etc/bind/pub_3gpp_zone"; | ||||
| }; | ||||
|  | ||||
| zone "e164.arpa" { | ||||
|         type master; | ||||
|         file "/etc/bind/e164.arpa"; | ||||
| }; | ||||
|   | ||||
| @@ -554,6 +554,27 @@ services: | ||||
|     networks: | ||||
|       default: | ||||
|         ipv4_address: ${PCSCF_IP} | ||||
|   smsc: | ||||
|     image: docker_kamailio | ||||
|     container_name: smsc | ||||
|     dns: ${DNS_IP} | ||||
|     volumes: | ||||
|       - ./smsc:/mnt/smsc | ||||
|       - /etc/timezone:/etc/timezone:ro | ||||
|       - /etc/localtime:/etc/localtime:ro | ||||
|     env_file: | ||||
|       - .env | ||||
|     environment: | ||||
|       - COMPONENT_NAME=smsc-1 | ||||
|     depends_on: | ||||
|       - dns | ||||
|       - mysql | ||||
|     expose: | ||||
|       - "7060/udp" | ||||
|       - "7060/tcp" | ||||
|     networks: | ||||
|       default: | ||||
|         ipv4_address: ${SMSC_IP} | ||||
|   osmomsc: | ||||
|     build: ./osmomsc | ||||
|     image: docker_osmomsc | ||||
|   | ||||
| @@ -252,6 +252,13 @@ route{ | ||||
| 		route(register); | ||||
| 	} | ||||
|  | ||||
| 	if (is_method("NOTIFY") && search("^(Event|o)([ \t]*):([ \t]*)reg")) { | ||||
| 		if (!t_relay()) { | ||||
| 			sl_reply_error(); | ||||
| 		} | ||||
| 		exit; | ||||
| 	} | ||||
|  | ||||
| 	if (is_method("INVITE|SUBSCRIBE|MESSAGE|INFO|PUBLISH|CANCEL")) { | ||||
| 		route(initial_request); | ||||
| 	} else { | ||||
|   | ||||
| @@ -33,7 +33,7 @@ RUN apt-get update && \ | ||||
| 	apt-get -y install mysql-server tcpdump screen tmux ntp ntpdate git-core dkms \ | ||||
| 					gcc flex bison libmysqlclient-dev make libssl-dev libcurl4-openssl-dev \ | ||||
| 					libxml2-dev libpcre3-dev bash-completion g++ autoconf libmnl-dev \ | ||||
| 					libsctp-dev libradcli-dev libradcli4 iproute2 net-tools \ | ||||
| 					libsctp-dev libradcli-dev libradcli4 libjson-c-dev pkg-config iproute2 net-tools \ | ||||
| 					iputils-ping | ||||
|  | ||||
| # Fetch Kamailio code (branch 5.3) | ||||
|   | ||||
| @@ -43,6 +43,11 @@ elif [[ "$COMPONENT_NAME" =~ ^(pcscf-[[:digit:]]+$) ]]; then | ||||
| 	/mnt/pcscf/pcscf_init.sh && \ | ||||
| 	mkdir -p /var/run/kamailio_pcscf && \ | ||||
| 	kamailio -f /etc/kamailio_pcscf/kamailio_pcscf.cfg -P /kamailio_pcscf.pid -DD -E -e | ||||
| elif [[ "$COMPONENT_NAME" =~ ^(smsc-[[:digit:]]+$) ]]; then | ||||
| 	echo "Deploying component: '$COMPONENT_NAME'" | ||||
| 	/mnt/smsc/smsc_init.sh && \ | ||||
| 	mkdir -p /var/run/kamailio_smsc && \ | ||||
| 	kamailio -f /etc/kamailio_smsc/kamailio_smsc.cfg -P /kamailio_smsc.pid -DD -E -e | ||||
| else | ||||
| 	echo "Error: Invalid component name: '$COMPONENT_NAME'" | ||||
| fi | ||||
| @@ -7,7 +7,7 @@ modules_dirs:=modules | ||||
| cfg_group_include= | ||||
|  | ||||
| # the list of extra modules to compile | ||||
| include_modules= cdp cdp_avp db_mysql dialplan ims_auth ims_charging ims_dialog ims_diameter_server ims_icscf ims_ipsec_pcscf ims_isc ims_ocs ims_qos ims_registrar_pcscf ims_registrar_scscf ims_usrloc_pcscf ims_usrloc_scscf outbound presence presence_conference presence_dialoginfo presence_mwi presence_profile presence_reginfo presence_xml pua pua_bla pua_dialoginfo pua_reginfo pua_rpc pua_usrloc pua_xmpp sctp tls utils xcap_client xcap_server xmlops xmlrpc | ||||
| include_modules= cdp cdp_avp db_mysql dialplan enum json http_client ims_auth ims_charging ims_dialog ims_diameter_server ims_icscf ims_ipsec_pcscf ims_isc ims_ocs ims_qos ims_registrar_pcscf ims_registrar_scscf ims_usrloc_pcscf ims_usrloc_scscf outbound presence presence_conference presence_dialoginfo presence_mwi presence_profile presence_reginfo presence_xml pua pua_bla pua_dialoginfo pua_reginfo pua_rpc pua_usrloc pua_xmpp sctp tls utils xcap_client xcap_server xmlops xmlrpc | ||||
|  | ||||
| # the list of static modules | ||||
| static_modules= | ||||
| @@ -16,7 +16,7 @@ static_modules= | ||||
| skip_modules= | ||||
|  | ||||
| # the list of modules to exclude from compile list | ||||
| exclude_modules= acc_json acc_radius app_java app_lua app_lua_sr app_mono app_perl app_python app_python3 app_ruby auth_ephemeral auth_identity auth_radius cnxcc cplc crypto db2_ldap db_berkeley db_cassandra db_mongodb db_oracle db_perlvdb db_postgres db_redis db_sqlite db_unixodbc dnssec erlang evapi geoip geoip2 gzcompress h350 http_async_client http_client jansson janssonrpcc json jsonrpcc jwt kafka kazoo lcr ldap log_systemd lost lwsc memcached misc_radius ndb_cassandra mqtt ndb_mongodb ndb_redis nsq osp peering phonenum pua_json rabbitmq regex rls rtp_media_server secsipid secsipid_proc snmpstats stirshaken systemdops topos_redis uuid websocket xhttp_pi xmpp $(skip_modules) | ||||
| exclude_modules= acc_json acc_radius app_java app_lua app_lua_sr app_mono app_perl app_python app_python3 app_ruby auth_ephemeral auth_identity auth_radius cnxcc cplc crypto db2_ldap db_berkeley db_cassandra db_mongodb db_oracle db_perlvdb db_postgres db_redis db_sqlite db_unixodbc dnssec erlang evapi geoip geoip2 gzcompress h350 http_async_client jansson janssonrpcc jsonrpcc jwt kafka kazoo lcr ldap log_systemd lost lwsc memcached misc_radius ndb_cassandra mqtt ndb_mongodb ndb_redis nsq osp peering phonenum pua_json rabbitmq regex rls rtp_media_server secsipid secsipid_proc snmpstats stirshaken systemdops topos_redis uuid websocket xhttp_pi xmpp $(skip_modules) | ||||
|  | ||||
| modules_all= $(filter-out modules/CVS,$(wildcard modules/*)) | ||||
| modules_noinc= $(filter-out $(addprefix modules/, $(exclude_modules) $(static_modules)), $(modules_all))  | ||||
|   | ||||
							
								
								
									
										418
									
								
								smsc/kamailio_smsc.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										418
									
								
								smsc/kamailio_smsc.cfg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,418 @@ | ||||
| #!KAMAILIO | ||||
| # | ||||
| # This config file implements the basic P-CSCF functionality | ||||
| #     - web: http://www.kamailio.org | ||||
| #     - git: http://sip-router.org | ||||
| # | ||||
| # Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php | ||||
| # for an explanation of possible statements, functions and parameters. | ||||
| # | ||||
| # Direct your questions about this file to: <sr-users@lists.kamailio.org>. | ||||
| # | ||||
| # For more information about the various parameters, functions and statements | ||||
| # try http://sip-router.org/wiki/ . | ||||
| # | ||||
|  | ||||
| include_file "smsc.cfg" | ||||
|  | ||||
| ####### Global Parameters ######### | ||||
| debug=2 | ||||
| log_stderror=no | ||||
| sip_warning=no | ||||
| children=4 | ||||
|  | ||||
| user_agent_header="User-Agent: Kamailio SMSC" | ||||
| server_header="Server: Kamailio SMSC" | ||||
|  | ||||
| /* comment the next line to enable the auto discovery of local aliases | ||||
|    based on reverse DNS on IPs (default on) */ | ||||
| auto_aliases=no | ||||
|  | ||||
| check_via=no    # (cmd. line: -v) | ||||
| dns=no          # (cmd. line: -r) | ||||
| rev_dns=no      # (cmd. line: -R) | ||||
| tcp_accept_no_cl=yes | ||||
|  | ||||
| #!define SMS_3GPP 1 | ||||
| #!define SMS_TEXT 2 | ||||
|  | ||||
| alias=SMSC_SERVER | ||||
|  | ||||
| # ------------------ module loading ---------------------------------- | ||||
| mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/:/usr/lib/x86_64-linux-gnu/kamailio/modules/:/usr/local/lib64/kamailio/modules" | ||||
| # (we try both the lib64 and the lib directory) | ||||
|  | ||||
| loadmodule "tm" | ||||
| loadmodule "tmx" | ||||
| loadmodule "smsops" | ||||
| loadmodule "xlog" | ||||
| loadmodule "maxfwd" | ||||
| loadmodule "textops" | ||||
| loadmodule "sl" | ||||
| loadmodule "sanity" | ||||
| loadmodule "siputils" | ||||
| loadmodule "pv" | ||||
| loadmodule "uac" | ||||
| loadmodule "http_client" | ||||
| loadmodule "xhttp" | ||||
| loadmodule "utils" | ||||
| loadmodule "json" | ||||
| loadmodule "enum" | ||||
| loadmodule "db_mysql" | ||||
| loadmodule "dialplan" | ||||
| loadmodule "sqlops" | ||||
| loadmodule "htable" | ||||
| loadmodule "rtimer" | ||||
| loadmodule "usrloc" | ||||
| loadmodule "registrar" | ||||
| loadmodule "pua" | ||||
| loadmodule "pua_reginfo" | ||||
|  | ||||
| modparam("sqlops", "sqlcon", SMS_DB_URL) | ||||
| modparam("dialplan|pua", "db_url", DIALPLAN_PUA_DB_URL) | ||||
| modparam("uac", "restore_mode", "none") | ||||
|  | ||||
| modparam("htable", "htable", "publish_sent=>size=8;autoexpire=SUBSCRIBE_EXPIRE") | ||||
|  | ||||
| # time interval set to 3 seconds | ||||
| modparam("rtimer", "timer", "name=sms;interval=3;mode=1;") | ||||
| modparam("rtimer", "exec", "timer=sms;route=SMS_WORKER") | ||||
|  | ||||
| modparam("pua_reginfo", "server_address", "sip:SMSC_SERVER") | ||||
| modparam("pua_reginfo", "publish_reginfo", 0) | ||||
|  | ||||
| ####### Routing Logic ######## | ||||
| # Main SIP request routing logic | ||||
| # - processing of any incoming SIP request starts with this route | ||||
|  | ||||
| route { | ||||
| 	xlog("L_DBG", "$rm ($fu ($si:$sp) to $tu, $ci)\n"); | ||||
|  | ||||
| 	# per request initial checks | ||||
| 	route(REQINIT); | ||||
|  | ||||
| 	if (is_method("NOTIFY")) { | ||||
| 		route(NOTIFY); | ||||
| 		send_reply("202", "Accepted"); | ||||
| 		exit; | ||||
| 	} | ||||
|  | ||||
| 	if (!is_method("MESSAGE")) { | ||||
| 		append_to_reply("Allow: MESSAGE,NOTIFY\r\n"); | ||||
| 		send_reply("405", "Method not allowed"); | ||||
| 		exit; | ||||
| 	} | ||||
|  | ||||
| 	if ($cT == "application/vnd.3gpp.sms") { | ||||
| 		route(SMS_FROM_3GPP); | ||||
| 	} else if ($cT == "text/plain") { | ||||
| 		route(SMS_FROM_SIP); | ||||
| 	} else { | ||||
| 		send_reply("488", "Content-Type not supported"); | ||||
| 		exit; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # Helper routes (Basic-Checks, NAT-Handling/RTP-Control, XML-RPC) | ||||
| ###################################################################### | ||||
| # Per SIP request initial checks | ||||
| route[REQINIT] { | ||||
| 	# Trace this message | ||||
|  | ||||
| 	if (!mf_process_maxfwd_header("10")) { | ||||
| 		sl_send_reply("483","Too Many Hops"); | ||||
| 		exit; | ||||
| 	} | ||||
|  | ||||
| 	if(!sanity_check("1511", "7")) { | ||||
| 		xlog("Malformed SIP message from $si:$sp\n"); | ||||
| 		exit; | ||||
| 	} | ||||
|  | ||||
| 	# Reply to OPTIONS: | ||||
| 	if (is_method("OPTIONS") && (uri==myself)) { | ||||
| 		options_reply(); | ||||
| 		exit; | ||||
| 	}	 | ||||
|  | ||||
| 	# Ignore Re-Transmits: | ||||
| 	if (t_lookup_request()) { | ||||
| 		exit; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS from VoLTE Handsets | ||||
| ###################################################################### | ||||
| route[SMS_FROM_3GPP] { | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("3GPP-SMS: $rm ($fu ($si:$sp) to $tu, $ci)\n"); | ||||
| 	xlog("SMS for $tpdu(destination) \"$tpdu(payload)\" (Valid: $tpdu(validity) )\n"); | ||||
| #!endif | ||||
| 	send_reply("202", "Accepted"); | ||||
|  | ||||
| 	if (isRPDATA()) { | ||||
| 		$uac_req(method) = "MESSAGE"; | ||||
| 		$uac_req(ruri) = $ai; | ||||
| 		$uac_req(furi) = "sip:"+SMSC_SERVER; | ||||
| 		$uac_req(turi) = $ai; | ||||
| 		$uac_req(hdrs) = "Content-Type: application/vnd.3gpp.sms\r\nRequest-Disposition: no-fork\r\nAccept-Contact: *;+g.3gpp.smsip\r\n"; | ||||
| 		$uac_req(body) = $smsack; | ||||
| 		uac_req_send(); | ||||
|  | ||||
|  | ||||
| 		$avp(from) = $(ai{uri.user}); | ||||
| 		$avp(to) = $tpdu(destination); | ||||
| 		# Translate "To": | ||||
| 		dp_translate("1", "$avp(to)/$avp(to)"); | ||||
| 			 | ||||
| 		$avp(text) = $tpdu(payload); | ||||
| #!ifdef WITH_DEBUG | ||||
| 		xlog("SMS from 3GPP/VoLTE\n"); | ||||
| 		xlog("-------------------------------------\n"); | ||||
| 		xlog("FROM $avp(from)\n"); | ||||
| 		xlog("TO   $avp(to)\n"); | ||||
| 		xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
| 		route(SMS); | ||||
| 	} | ||||
|  | ||||
| 	exit; | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS from OTT Handsets | ||||
| ###################################################################### | ||||
| route[SMS_FROM_SIP] { | ||||
| 	send_reply("200", "OK"); | ||||
|  | ||||
| 	$avp(from) = $(ai{uri.user}); | ||||
| 	# Translate "To": | ||||
| 	$avp(to) = $tU; | ||||
| 	dp_translate("1", "$avp(to)/$avp(to)"); | ||||
| 	$avp(text) = $rb; | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("SMS from SIP/OTT\n"); | ||||
| 	xlog("-------------------------------------\n"); | ||||
| 	xlog("FROM $avp(from)\n"); | ||||
| 	xlog("TO   $avp(to)\n"); | ||||
| 	xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
| 	route(SMS); | ||||
|  | ||||
| 	exit; | ||||
| } | ||||
|  | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS from other networks | ||||
| ###################################################################### | ||||
| event_route[xhttp:request] { | ||||
| 	if ($(hu{url.querystring}{s.len}) > 0) { | ||||
| 		$avp(from) = $(hu{url.querystring}{param.value,msisdn,&}); | ||||
| 		$avp(to) = $(hu{url.querystring}{param.value,to,&}); | ||||
| 		$avp(text) = $(hu{url.querystring}{param.value,text,&}{s.replace,+,%20}{s.unescape.user}); | ||||
| 		$avp(from_outbound) = 1; | ||||
| #!ifdef WITH_DEBUG | ||||
| 		xlog("SMS from Outbound ($hu)\n"); | ||||
| 		xlog("-------------------------------------\n"); | ||||
| 		xlog("FROM $avp(from)\n"); | ||||
| 		xlog("TO   $avp(to)\n"); | ||||
| 		xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
| 	if ($avp(to) == "491771782261") | ||||
| 		$avp(to) = "494046895124";  | ||||
| 	if ($avp(to) == "491771782319")  | ||||
| 		$avp(to) = "494034927220"; | ||||
|  | ||||
| 		route(SMS); | ||||
| 	} | ||||
|  | ||||
| 	xhttp_reply("200", "OK", "text/html", "<html><body>OK - [$si:$sp]</body></html>"); | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS to VoLTE Handsets | ||||
| ###################################################################### | ||||
| route[SMS_TO_3GPP] { | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("SMS to 3GPP/VoLTE\n"); | ||||
| 	xlog("-------------------------------------\n"); | ||||
| 	xlog("FROM $avp(from)\n"); | ||||
| 	xlog("TO   $avp(to)\n"); | ||||
| 	xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
|  | ||||
| 	// Construct a new SMS-Body: | ||||
| 	$rpdata(all) = $null; | ||||
| 	$rpdata(type) = 1; // RP-DATA: Network to UE | ||||
| 	$rpdata(reference) = $avp(id); | ||||
| 	$rpdata(originator) = $avp(from); | ||||
| 	$tpdu(type) = 4; // SMS-Deliver | ||||
| 	$tpdu(origen) = $avp(from); // The Destination becomes the originator of the SMS | ||||
| 	$tpdu(payload) = $avp(text); | ||||
|  | ||||
| 	$uac_req(method) = "MESSAGE"; | ||||
| 	$uac_req(ruri) = "sip:"+$avp(to)+"@"+DOMAIN; | ||||
| 	$uac_req(furi) = "sip:"+SMSC_SERVER; | ||||
| 	$uac_req(turi) = "sip:"+$avp(to)+"@"+DOMAIN; | ||||
| 	$uac_req(hdrs) = "Content-Type: application/vnd.3gpp.sms\r\nRequest-Disposition: no-fork\r\nAccept-Contact: *;+g.3gpp.smsip\r\nX-MSG-ID: "+$avp(id)+"\r\n"; | ||||
| 	$uac_req(body) = $smsbody; | ||||
| 	$uac_req(evroute)=1; | ||||
| 	uac_req_send(); | ||||
| 	# sql_query("sms", "delete from messages where id=$avp(id);"); | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS to OTT-Handsets | ||||
| ###################################################################### | ||||
| route[SMS_TO_SIP] { | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("SMS to SIP/OTT\n"); | ||||
| 	xlog("-------------------------------------\n"); | ||||
| 	xlog("FROM $avp(from)\n"); | ||||
| 	xlog("TO   $avp(to)\n"); | ||||
| 	xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
|  | ||||
| 	$uac_req(method) = "MESSAGE"; | ||||
| 	$uac_req(ruri) = "sip:"+$avp(to)+"@"+DOMAIN; | ||||
| 	$uac_req(furi) = "sip:+"+$avp(from)+"@"+DOMAIN; | ||||
| 	$uac_req(turi) = "sip:"+$avp(to)+"@"+DOMAIN; | ||||
| 	$uac_req(hdrs) = "Content-Type: text/plain\r\nX-MSG-ID: "+$avp(id)+"\r\n"; | ||||
| 	$uac_req(evroute)=1; | ||||
| 	$uac_req(body) = $avp(text); | ||||
|  | ||||
| 	uac_req_send(); | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS to Outbound | ||||
| ###################################################################### | ||||
| route[SMS_TO_OUTBOUND] { | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("SMS to Outbound\n"); | ||||
| 	xlog("-------------------------------------\n"); | ||||
| 	xlog("FROM $avp(from)\n"); | ||||
| 	xlog("TO   $avp(to)\n"); | ||||
| 	xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
| 	if ($avp(from_outbound) == 1) { | ||||
| 		xlog("Not sending: FROM and TO Outbound!\n"); | ||||
| 		return 1; | ||||
| 		exit; | ||||
| 	} | ||||
| 	if ($avp(from) == "494046895124") | ||||
| 		$avp(from) = "491771782261"; | ||||
| 	if ($avp(from) == "494034927220") | ||||
| 		$avp(from) = "491771782319"; | ||||
|  | ||||
| 	http_client_query("https://rest.nexmo.com/sms/json?api_key=NEXMO_APIKEY&api_secret=NEXMO_APISECRET&from=$avp(from)&to=$avp(to)&text=$(avp(text){s.escape.user})", "$var(result)"); | ||||
| 	if ($retcode != 200) return -1; | ||||
| 	json_get_field("$var(result)", "messages", "$var(messages)"); | ||||
| 	json_get_field("$var(messages)", "status", "$var(status)"); | ||||
| 	if ($var(status) != 0) return -1;	 | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS Handling | ||||
| ###################################################################### | ||||
| route[SMS] { | ||||
| #!ifdef WITH_DEBUG | ||||
| 	xlog("SMS-Task\n"); | ||||
| 	xlog("-------------------------------------\n"); | ||||
| 	xlog("FROM $avp(from)\n"); | ||||
| 	xlog("TO   $avp(to)\n"); | ||||
| 	xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
|  | ||||
| 	# Query ENUM: Local number? | ||||
| 	$var(enum) = "+"+$avp(to); | ||||
| 	if (!enum_pv_query("$var(enum)")) { | ||||
| 		route(SMS_TO_OUTBOUND); | ||||
| 		return $retcode; | ||||
| 	} | ||||
| 	if (sql_query("sms", "insert into messages (caller, callee, text, valid) values ('$(avp(from){s.escape.common})', '$(avp(to){s.escape.common})', '$(avp(text){s.escape.common})', now());")) | ||||
| 		return 1; | ||||
| 	else | ||||
| 		return -1; | ||||
| } | ||||
|  | ||||
| ###################################################################### | ||||
| # SMS Handling | ||||
| ###################################################################### | ||||
| route[SMS_WORKER] { | ||||
| 	sql_query("sms", "select id, caller, callee, text from messages;", "q"); | ||||
| 	if ($dbr(q=>rows) > 0) { | ||||
| 		$var(i) = 0; | ||||
| 		while ($var(i) < $dbr(q=>rows)) { | ||||
| 			$avp(id) = $dbr(q=>[$var(i),0]); | ||||
| 			$avp(from) = $dbr(q=>[$var(i),1]); | ||||
| 			$avp(to) = $dbr(q=>[$var(i),2]); | ||||
| 			$avp(text) = $dbr(q=>[$var(i),3]); | ||||
|  | ||||
| 			route(SEND_SMS); | ||||
| #!ifdef WITH_DEBUG | ||||
| 			xlog("ID   $avp(id)\n"); | ||||
| 			xlog("FROM $avp(from)\n"); | ||||
| 			xlog("TO   $avp(to)\n"); | ||||
| 			xlog("TEXT $avp(text)\n"); | ||||
| #!endif | ||||
| 			$var(i) = $var(i) + 1; | ||||
| 		} | ||||
| 	} | ||||
| 	sql_result_free("q"); | ||||
| } | ||||
|  | ||||
| route[NOTIFY] { | ||||
| 	if (has_body("application/reginfo+xml")) { | ||||
| 		if (reginfo_handle_notify("location")) | ||||
| 			send_reply("202", "Accepted"); | ||||
| 	} else { | ||||
| 		send_reply("503", "Invalid Content-Type"); | ||||
| 	} | ||||
| 	exit; | ||||
| } | ||||
|  | ||||
| route[SEND_SMS] { | ||||
| 	$var(uri) = "sip:"+$avp(to)+"@"+DOMAIN; | ||||
| 	 | ||||
| 	if (reg_fetch_contacts("location", "$var(uri)", "caller")) { | ||||
| 		$var(j) = 0; | ||||
| 		$var(is3gpp) = 0; | ||||
| 		while($var(j) < $(ulc(caller=>count))) { | ||||
| 			$var(k) = 0; | ||||
| 			while($var(k) < $(ulc(caller=>addr)[$var(j)]{param.count})) { | ||||
| 				if ($(ulc(caller=>addr)[$var(j)]{param.name,$var(k)}) == "+g.3gpp.smsip") | ||||
| 					$var(is3gpp) = 1; | ||||
| 				$var(k) = $var(k) + 1; | ||||
| 			} | ||||
| 			if ($var(is3gpp) == 1) | ||||
| 				route(SMS_TO_3GPP); | ||||
| 			else | ||||
| 				route(SMS_TO_SIP);		 | ||||
| 			$var(j) = $var(j) + 1; | ||||
| 		} | ||||
| 	} else { | ||||
| 		if ($sht(publish_sent=>$var(uri)) == $null) { | ||||
| 			reginfo_subscribe("$var(uri)", "SUBSCRIBE_EXPIRE"); | ||||
| 			$sht(publish_sent=>$var(uri)) = 1; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| event_route [tm:local-request] { | ||||
| 	if (is_method("SUBSCRIBE")) { | ||||
| 		append_hf("P-Asserted-Identity: $ru\r\n"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| event_route[uac:reply] { | ||||
| 	if (($uac_req(evtype) == 1) && ($uac_req(evcode) == 200)) { | ||||
| 		$var(msgid) = $(uac_req(hdrs){line.sw,X-MSG-ID:}{s.substr,10,0}{s.int}); | ||||
| 		sql_query("sms", "delete from messages where id=$var(msgid);"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										9
									
								
								smsc/smsc-create.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								smsc/smsc-create.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| CREATE TABLE `messages` ( | ||||
|     `id` INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, | ||||
|     `caller` VARCHAR(255) NOT NULL, | ||||
|     `callee` VARCHAR(255) NOT NULL, | ||||
|     `text` VARCHAR(512), | ||||
|     `valid` datetime NOT NULL | ||||
| ); | ||||
|  | ||||
| INSERT INTO version (table_name, table_version) values ('messages','1'); | ||||
							
								
								
									
										17
									
								
								smsc/smsc.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								smsc/smsc.cfg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| listen=udp:SMSC_IP:7060 | ||||
| listen=tcp:SMSC_IP:7060 | ||||
|  | ||||
| #!define DOMAIN "IMS_DOMAIN" | ||||
| #!subst "/DOMAIN/IMS_DOMAIN/" | ||||
| #!define SMSC_SERVER "smsc.IMS_DOMAIN" | ||||
| #!subst "/SMSC_SERVER/smsc.IMS_DOMAIN/" | ||||
|  | ||||
| # Connection URL for the database: | ||||
| #!define SMS_DB_URL "sms=>mysql://smsc:heslo@MYSQL_IP/smsc" | ||||
| #!define DIALPLAN_PUA_DB_URL "mysql://smsc:heslo@MYSQL_IP/smsc" | ||||
|  | ||||
| #!subst "/NEXMO_APIKEY/abcdef/" | ||||
| #!subst "/NEXMO_APISECRET/xyz/" | ||||
| #!subst "/SUBSCRIBE_EXPIRE/7200/" | ||||
|  | ||||
| #!define WITH_DEBUG | ||||
							
								
								
									
										67
									
								
								smsc/smsc_init.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								smsc/smsc_init.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # BSD 2-Clause License | ||||
|  | ||||
| # Copyright (c) 2020, Supreeth Herle | ||||
| # All rights reserved. | ||||
|  | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are met: | ||||
|  | ||||
| # 1. Redistributions of source code must retain the above copyright notice, this | ||||
| #    list of conditions and the following disclaimer. | ||||
|  | ||||
| # 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
| #    this list of conditions and the following disclaimer in the documentation | ||||
| #    and/or other materials provided with the distribution. | ||||
|  | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
| # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| [ ${#MNC} == 3 ] && IMS_DOMAIN="ims.mnc${MNC}.mcc${MCC}.3gppnetwork.org" || IMS_DOMAIN="ims.mnc0${MNC}.mcc${MCC}.3gppnetwork.org" | ||||
|  | ||||
| mkdir -p /etc/kamailio_smsc | ||||
| cp /mnt/smsc/smsc.cfg /etc/kamailio_smsc | ||||
| cp /mnt/smsc/kamailio_smsc.cfg /etc/kamailio_smsc | ||||
|  | ||||
| while ! mysqladmin ping -h ${MYSQL_IP} --silent; do | ||||
| 	sleep 5; | ||||
| done | ||||
|  | ||||
| # Sleep until permissions are set | ||||
| sleep 10; | ||||
|  | ||||
| # Create SMSC database, populate tables and grant privileges | ||||
| if [[ -z "`mysql -u root -h ${MYSQL_IP} -qfsBe "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='smsc'" 2>&1`" ]]; | ||||
| then | ||||
| 	mysql -u root -h ${MYSQL_IP} -e "create database smsc;" | ||||
| 	mysql -u root -h ${MYSQL_IP} smsc < /usr/local/src/kamailio/utils/kamctl/mysql/standard-create.sql | ||||
| 	mysql -u root -h ${MYSQL_IP} smsc < /mnt/smsc/smsc-create.sql | ||||
| 	mysql -u root -h ${MYSQL_IP} smsc < /usr/local/src/kamailio/utils/kamctl/mysql/dialplan-create.sql | ||||
| 	mysql -u root -h ${MYSQL_IP} smsc < /usr/local/src/kamailio/utils/kamctl/mysql/presence-create.sql | ||||
|  | ||||
| 	SMSC_USER_EXISTS=`mysql -u root -h ${MYSQL_IP} -s -N -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE User = 'smsc' AND Host = '%')"` | ||||
| 	if [[ "$SMSC_USER_EXISTS" == 0 ]] | ||||
| 	then | ||||
| 		mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'smsc'@'%' IDENTIFIED WITH mysql_native_password BY 'heslo'"; | ||||
| 		mysql -u root -h ${MYSQL_IP} -e "CREATE USER 'smsc'@'$SMSC_IP' IDENTIFIED WITH mysql_native_password BY 'heslo'"; | ||||
| 		mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON smsc.* TO 'smsc'@'%'"; | ||||
| 		mysql -u root -h ${MYSQL_IP} -e "GRANT ALL ON smsc.* TO 'smsc'@'$SMSC_IP'"; | ||||
| 		mysql -u root -h ${MYSQL_IP} -e "FLUSH PRIVILEGES;" | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| sed -i 's|SMSC_IP|'$SMSC_IP'|g' /etc/kamailio_smsc/smsc.cfg | ||||
| sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_smsc/smsc.cfg | ||||
| sed -i 's|MYSQL_IP|'$MYSQL_IP'|g' /etc/kamailio_smsc/smsc.cfg | ||||
|  | ||||
| # Sync docker time | ||||
| #ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone | ||||
		Reference in New Issue
	
	Block a user