{"id":1538,"date":"2024-04-18T22:55:49","date_gmt":"2024-04-18T20:55:49","guid":{"rendered":"https:\/\/blog.kolatzek.org\/wblog\/?p=1538"},"modified":"2024-04-19T17:39:21","modified_gmt":"2024-04-19T15:39:21","slug":"drei-rufnummern-drei-trunks-null-zusammenhang","status":"publish","type":"post","link":"https:\/\/blog.kolatzek.org\/wblog\/1538\/drei-rufnummern-drei-trunks-null-zusammenhang","title":{"rendered":"Drei Rufnummern, drei Trunks, null Zusammenhang"},"content":{"rendered":"\n<p>In meinem vorherigen Beitrag ging es um Anrufsignalisierung auf einem Trunk der Telefonanlage, die keine Zielrufnummer mitliefert. Im Beispiel kam ein Sipgate Basic Trunk zu Einsatz. Bei diesem Anbieter gibt es sogar zwei Telefonnummern gratis &#8211; aber nur einen Zugang. Damit ist meine L\u00f6sung obsolet.<\/p>\n\n\n\n<p>Es gibt aber andere Anbieter, die mehrere Nummern gratis anbieten und auch mehrere Zug\u00e4nge erlauben. Zum Beispiel Fonial. Es bietet erstaunlich viele M\u00f6glichkeiten schon auf deren Server. Anrufbeantworter, Spamfilter, einfache Weiterleitungsregelt &#8211; es ist schon einiges und viele werden sicher damit schon gl\u00fccklich. Ich nutze die Nummern mit einer 1:1 Umsetzung auf die Zug\u00e4nge, die ich mir parallel dazu geschaffen habe. Und so sieht es (pseudonymisiert) bei mir aus:<\/p>\n\n\n\n<!--more-->\n\n\n\n<p><em>from-trunk-fonial-A<\/em>, <em>from-trunk-fonial-B<\/em> und <em>from-trunk-fonial-C<\/em> sind die drei Kontexte f\u00fcr die drei Trunks, immer jeweils in &#8222;<em>pjsip settings<\/em>&#8220; hinterlegt. Dann gibt es die drei &#8222;Werkb\u00e4nke&#8220;: <em>ContextFoA<\/em>, <em>ContextFoB<\/em> und <em>ContextFoC<\/em>. Dabei entspricht <strong>A<\/strong> immer der Nummer <strong>0123000003<\/strong> , <strong>B<\/strong> der Nummer <strong>0123000004<\/strong> und C der Nummer <strong>0123000005<\/strong>. Aus dem SIP-Header kann Asterisk die <strong>Extension<\/strong> heraus lesen. Leider ist es nicht die &#8222;Durchwahl&#8220; sondern der Benutzername.  Der Trick besteht also darin, im Dialplan (so nennt man grob den Ablauf in einem Kontext) die Variable EXTEN zu untersuchen und dann zu entscheiden, wohin es gelenkt werden soll. (Es kann mein Versehen sein aber ich habe es mehr als einmal gesehen, dass ein Anruf \u00fcber den falschen Trunk kam und deshalb verlasse ich mich ausschlie\u00dflich auf den Benutzernamen!) Fangen wir an!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;from-trunk-fonial-A]\nexten => _.,1,NoOp(${CONTEXT} -> ${EXTEN})\n same => n,GotoIf($&#91;${EXTEN} = foA]?ContextFoA:ContextFoB)\n same => n(ContextFoA),Goto(ContextFoA,0123000003,1)\n same => n(ContextFoB_ContextFoC),GotoIf($&#91;${EXTEN} = foB]?ContextFoB:ContextFoC)\n same => n(ContextFoB),Goto(ContextFoB,0123000004,1)\n same => n(ContextFoC),Goto(ContextFoC,0123000005,1)<\/code><\/pre>\n\n\n\n<p>Mein erster Trunk loggt als Erstes das Ereignis und das Umfeld. Dann geht es ans Eingemachte: mit einem <strong>GotoIf<\/strong> lasse ich den &#8222;Anruf&#8220; (eigentlich Channel) zu einer weiteren benannten Zeile springen. Deshalb haben die Zeilen nicht nur die fortlaufende Nummer &#8222;<strong>n<\/strong>&#8222;, sondern auch einen <strong>Namen<\/strong>, der in Klammern dahinter steht. Als erste Abfrage wird geschaut: ist die Durchwahl gleich dem Benutzernamen &#8222;<strong>foA<\/strong>&#8222;. Wenn ja (nach dem &#8222;<strong>?<\/strong>&#8222;) springe ich zur Zeile ContextFoA, die den Anruf in den Kontext ContextFoA mit der Nummer 0123000003 als erstem Argument schickt und zwar ab Zeile &#8222;1&#8220;. Ansonsten (nach &#8222;:&#8220;) soll in <strong>ContextFoB_ContextFoC<\/strong> entschieden werden, ob es \u00fcber <strong>ContextFoB<\/strong>-Zeile in den Kontext <strong>ContextFoB<\/strong> oder \u00fcber die Zeile <strong>ContextFoC<\/strong> in den Kontext <strong>ContextFoC<\/strong> geschickt werden soll.<\/p>\n\n\n\n<p>Aber was passiert in dem mysteri\u00f6sen Kontext?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;ContextFoA]\nexten => _.,1,NoOp(${CONTEXT} -> ${EXTEN} )\n same => n,Set(__DID=0123000003)\n same => n,NoOp(${CONTEXT} -> ${EXTEN} -> ${DID} as defined in ContextFoA extensions_custom.conf)\n same => n,Answer()\n same => n(dest-ext),Goto(from-pstn,0123000003,1)<\/code><\/pre>\n\n\n\n<p>Am Anfang kurz zu Protokoll geben, dass was Neues anf\u00e4ngt (die erste Zeile im Dialplan muss als solche erkennbar sein: <strong>Durchwahl,1,Anwendung<\/strong> -> &#8222;<em>exten => _.,1,NoOp&#8230;<\/em>&#8220; und danach kann allem fortlaufend mit &#8222;<strong>same => n,<\/strong>&#8220; als Fortsetzung angegeben werden). Ein &#8222;<strong>_.<\/strong>&#8220; passt dabei auf alles, was eine Rufnummer sein kann.<\/p>\n\n\n\n<p>Die DID wird f\u00fcr m\u00f6gliche sp\u00e4tere Verwendung gespeichert, danach (eigentlich \u00fcberfl\u00fcssig) Log-Eintrag, um zu erkennen wo der Ablauf definiert wurde. Es folgt, wie fr\u00fcher auch, \u00dcbernahme des Anrufs und die Weiterleitung zu &#8222;<strong>from-pstn<\/strong>&#8222;, wo man kein weiteres &#8222;-toheader&#8220; braucht, weil die <strong>EXTEN<\/strong>-Variable schon bef\u00fcllt ist und die<strong> inbound routes<\/strong> erkennen k\u00f6nnen, was zu tun ist.<\/p>\n\n\n\n<p>F\u00fcr die anderen Trunks und Kontexte gilt analog dasselbe und ich bin mir nicht sicher, ob man das nicht noch mehr zusammen fassen k\u00f6nnte oder Duplizierung des Codes verzichten k\u00f6nnte. Ja, man kann sogar <strong>ohne Kontext-Wechsel<\/strong> <strong>direkt<\/strong> zur inbound route der DID springen. Dazu lassen wir die 3 Trunks in den Kontext <strong>from-trunk-fonial<\/strong> (also ohne -A, -B und -C) gehen. Die Zeile ContextFoA, ContextFoB oder ContextFoC stellt direkt zu &#8218;from-pstn&#8216; durch. Bei mir gab es aber Probleme mit Erkennung des Anrufers aus der Kontaktdatenbank (sieht nach einem Fehler von FreePBX Dialplan aus) und weil ich wei\u00df, wohin der Anruf soll, schreibe ich es mir noch k\u00fcrzer und \u00fcberspringe dabei die Konfiguration des Channels:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;from-trunk-fonial]\nexten => _.,1,NoOp(${CONTEXT} -> ${EXTEN})\n same => n,GotoIf($&#91;${EXTEN} = foB]?ContextFoB:ContextFoA_ContextFoC)\n same => n(ContextFoB),Goto(from-pstn,0123000004,1)\n same => n(ContextFoA_ContextFoC),GotoIf($&#91;${EXTEN} = foA]?ContextFoA:ContextFoC)\n same => n(ContextFoA),Goto(from-pstn,0123000003,did-cid-hook)\n same => n(ContextFoC),Goto(from-pstn,0123000005,did-cid-hook)<\/code><\/pre>\n\n\n\n<p>Damit kann man auch mehr als drei Trunks abdecken. Aber will man wirklich so komplizierte GotoIf-Abfragen bauen? Gerne lasse ich mir erkl\u00e4ren, wie man es noch einfacher machen k\u00f6nnte! Kommentare also vollkommen willkommen!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In meinem vorherigen Beitrag ging es um Anrufsignalisierung auf einem Trunk der Telefonanlage, die keine Zielrufnummer mitliefert. Im Beispiel kam ein Sipgate Basic Trunk zu Einsatz. Bei diesem Anbieter gibt es sogar zwei Telefonnummern gratis &#8211; aber nur einen Zugang. Damit ist meine L\u00f6sung obsolet. Es gibt aber andere Anbieter, die mehrere Nummern gratis anbieten [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[8],"tags":[182,183,96,184],"class_list":["post-1538","post","type-post","status-publish","format-standard","hentry","category-software","tag-asterisk","tag-freepbx","tag-server","tag-telefonie","entry"],"_links":{"self":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts\/1538","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/comments?post=1538"}],"version-history":[{"count":5,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts\/1538\/revisions"}],"predecessor-version":[{"id":1544,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts\/1538\/revisions\/1544"}],"wp:attachment":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/media?parent=1538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/categories?post=1538"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/tags?post=1538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}