Professional Documents
Culture Documents
AsteriskBook NasimTel
AsteriskBook NasimTel
در سال ۱۹۹۹متولد شد( و توانستم یک مشاوره کسب و کار را در این زمینه ،بالﻎ بر
یک دهه ادامه دهم .فوقالعاده است که استریسک چگونه توانسته است همچنان یک
بســتر VoIPمنبع باز قطعﯽ براي ایجاد برنامههاي کاربردي و کســب و کارهاي جدید
بماند .در طول این ســالها ،من همچنان از استریسک استفاده کردهام ،چرا که احساس
نزدیکﯽ خاصﯽ به آن دارم و مشــاهده رشد و تبدیل شدن آن به یک انقالب فناورانه
در اینترنت برایم تاثیرگذار بوده است.
استریســک همچنان یک بســتر قوي براي توسعه VoIPاســت و هنوز هم موضوعﯽ
است که افراد زیادي عالقه دارند درباره آن بنویسند .باعث خوشحالﯽ است که آقاي
اســفندیاري و همکارانشان کتابﯽ در زمینه استریســک با موضوعات و سرفصلهاي
جدید به فارسﯽ نوشــتهاند .امیدوار هستم با رشد اینگونه کتابها به زبانهاي مختلف،
دانشجویان و افراد عالقهمند ،بیشتر با استریسک آشنا شوند و بتوانند ازطریق مقاالت،
نوشتهها و توسعه آن ،رشد فناوري VoIPرا موجب شوند.
Leif Madsen
مرجع آموزش ویپ
باسافتسوئیچاستریسک
مجتبیاسفندیاری
سیدمجتبینجفیمقدم
سرشناسه :اسفندیاری ،مجتبی، ۱۳۶۲-
عنوان و نام پديدآور :مرجع آموزش ویپ با سافت سوئیچ استریسک /مجتبی اسفندیاری ،سیدمجتبی نجفیمقدم.
مشخصات نشر :مشهد :واژگان خرد،.۱۳۹۵
مشخصات ظاهری 576 :ص .
شابک 978-964-8931-95-2:
وضعیت فهرست نویسی :فیپا
یادداشت :کتابنامه.
موضوع :استریسک (فایل کامپیوتر) ،Asterisk (Computer file( ،تلفن اینترنتیInternet telephony ،
شناسه افزوده :نجفی مقدم ،سیدمجتبی، ۱۳۶۴-
شناسه افزوده :انتشارات واژگان خرد
ف/TK۵۱۰۵/۸۸۶۵ رده بندی کنگره :۴ ۱۳۹۵م۵ال
رده بندی دیویی :۰۰۴/۶۹۵۰۷۶
شماره کتابشناسی ملی ۴۵۶۷۰۲۸:
مراکز پخش
تهران -شرکت کاوا ارتباطات هوشمند021- 41879000 ، 021 - 4956 ،
مشهد -شرکت نسیم ارتباطات هزاره سوم051 - 31770000 ،
وبسایت جهت خرید آنالین:
www.voipshop.ir www.shop.voip98.com
5 فهرست
فهرست
پیشگفتار������������������������������������������������������������������������������������������������������������������������������������������������������26
39 ی
سطح شهر
40 ی
سطح بینشهر
40 ل
سطح بینالمل
40 ارتباط ISCهای ایران با کریرهای بین المل
ل
نتیجهگیری���������������������������������������������������������������������������������������������������������������������������������������������������41
51 س
ماژول ریز گزارشات تما
52 ک
ماژول رویدادهای استریس
53 ماژول Channel Driversدر استریس
ک
54 ماژول odec Translator
C
نتیجهگیری���������������������������������������������������������������������������������������������������������������������������������������������������62
197 ک
عبارات منطقی در برنامهنویسی استریس
198 عملگرهای مقایسهای (بزرگتر ،کوچکتر ،مساوی ،نامساوی)
199 عملگرهای ریاضی ( )mathemeticalدر استریس
ک
استفاده از دستورات و توابع در برنامهنویسی استریسک������������������������������������������������������������������������������200
200 ک
استفاده از توابع در استریس
202 استفاده از تابع TIMEOUTدر استریس
ک
203 ک
استفاده از دستورات و توابع شرطی در استریس
204 دستور GotoIf
206 دستور GotoIfTime
بررسی خطاهای منطقی در برنامهنویسی استریسک�������������������������������������������������������������������������������������209
استفاده از ماکروها در استریسک ���������������������������������������������������������������������������������������������������������������211
212 تعریف ماکر و
213 انواع متغیرها در ماکر و
تعریف توابع در استریسک ������������������������������������������������������������������������������������������������������������������������215
216 استفاده از دستور Returnدر تواب ع
217 استفاده از متغیر{ $}GOSUB_RETVAL
کانال محلی در استریسک �������������������������������������������������������������������������������������������������������������������������218
219 ک
بهینهسازی کانالها در استریس
استفاده از 221������������������������������������������������������������������������������������������������������������������������������������� AstDB
221 س
نمایش دادههای ذخیره شده در دیتابی
221 ذخیره کردن دادهی جدید در stDB
A
348 س
ساختن صف در دیتابی
نتیجهگیری������������������������������������������������������������������������������������������������������������������������������������������������352
بررسی تأثیر عوامل مؤثر بر مصرف منابع سیستمهای تلفنی 551���������������������������������������������� IPPBX
551 ی
تاثیرمیزان تماس ورودی بر منابع سیستم تلفن
552 تأثیر مدیا ( )RTPبر منابع سیستم تلفن
ی
بررسی کیفیت سرویس ( )Quality of Serviceدر سیستمهای تلفنی 553�������������������������������������������� IPPBX
553 از بین رفتن بستهه ا
554 تاخی ر
554 تغییرات تأخی ر
555 پارامتر MOSدر شبکههای وی
پ
نتیجهگیری������������������������������������������������������������������������������������������������������������������������������������������������556
نتیجهگیری������������������������������������������������������������������������������������������������������������������������������������������������575
پیشگفتار
امروزه فناوریهای مخابراتی و کامپیوتری بهسرعت در حال تغییر و دگرگونیاند و باعث ایجاد یک تحول
عظیم در جوامع بشری شدهاند .از طرف دیگر تجمیع شبکهها با هم و ایجاد شبکههای نسل جدید باعث شده
رؤیای تبدیل شدن جهان به دهکدهی کوچک جهانی ،بیش از پیش به واقعیت نزدیکتر شود.
ســافت سوئیچ استریسک یکی از محبوبترین سافت ســوئیچهای تلفنی است که بهوسیله آقای مارک
اسپنسر در سال ۱۹۹۹نوشته شده است .درحالحاضر شرکت دیجیوم ،مالکیت این سافت سوئیچ را بر عهده
دارد .این شــرکت برای عالقهمندان این حوزه ،دورههای آموزشــی برگزار میکند و در انتهای هر دوره با
برگــزاری آزمونهای بینالمللی مدارک معتبری به دانشــجویان اعطا میکند .کتاب جامع Asterisk_ The
4th Edition ,Definitive Guideآقــای Leif Madsenیکــی از محبوبترین کتابهای آموزشــی برای
عالقمندان در حوزه ویپ است.
کتابی که در پیش رو دارید اولین کتاب در زمینه ســافت ســوئیچ استریسک به زبان فارسی است .اکثر
منابع آموزشــی در این حوزه به زبان التیناند که به گســتردگی در اینترنت یافت میشــوند .در این کتاب
ســعی شده اســت مطالب با موافقت آقای Leif Madsenو بر اساس ســر فصل کتاب ایشان نگارش شود تا
پیوســتگی مطالب حفظ گردد .البته چون از زمان تألیف و چاپ اولین نســخه کتاب ایشان ،نزدیک به یک
دهه میگذرد ،ما ســعی کردهایم مطالب و مفاهیم جدید حوزه ســافت سوئیچ استریسک را نیز در سرفصل
کتاب قرار دهیم.
انگیزهی اصلی نگارش این کتاب این اســت که عالقمندان به حوزه مخابرات و شبکههای ویپ بتوانند
بهراحتی با مفاهیم آن آشنا شوند و آن را بهصورت کاربردی مطالعه نمایند .لذا عنوان کتاب »مرجع آموزش
ویپ با سافت سوئیچ استریسک« انتخاب شده است .این کتاب در ۲۰فصل نگارش شده است که در ادامه
هدف هر فصل شرح داده شده است.
27 پیشگفتار
در فصلهای نخست کتاب )چهار فصل اول( سعی شده بیشتر راجع به نصب و راهاندازی سافت سوئیچ
استریسک و پیکربندی آن صحبت شود و در هر بخش مفاهیم با جزئیات کامل شرح داده شود.
در فصلهای پنجم و هشــتم کتاب به مباحث برنامهنویســی در استریســک وارد شدهایم و در هر فصل
بخشــی از آن را توضیح میدهیم .عالقمندانی که تمایل دارند با ســاختار برنامهنویسی استریسک آشنا شوند
میتوانند به این فصلها مراجعه نمایند.
در فصل ششــم و هفتم چالشهای ارتباط سافت ســوئیچ استریسک با سایر شبکههای مخابراتی و ویپ
مطرح شــده است .همچنین در این فصل انواع روشهای ارتباطی شبکههای ویپ بهصورت مفصل همراه با
مثالهای متعدد توضیح داده شده است.
در فصل نهم ساختار و معماری طراحی سیستمهای کال سنتر معرفی شده است و با معماری صفها در
استریســک آشــنا میشوید .مفاهیم با شــرح مثالها به گونهای توضیح داده میشوند که خواننده کتاب باید
بتواند بعد از مطالعه این فصل ،یک کال سنتر با قابلیتهای محدود طراحی نماید.
در فصل دهم ادامه مبحث در خصوص وضعیت کاربران در شــبکههای ویپ مطرح میشــود که جزء
موضوعات حســاس و کلیدی اســت .ترکیب این فصل با فصل نهم میتواند منجر به ایجاد برنامهای شود که
بتواند درستی وضعیت اپراتورها در کال سنتر را نشان دهد.
در فصل یازدهم کتاب ســاختار اتصال ســافت سوئیچ استریسک با انواع پایگاههای دادهای بررسی شده
است و با قابلیت مهم در استریسک ) (ARAنیز آشنا خواهید شد.
در فصل دوازدهم کتاب چالشهای استفاده از فکس در شبکههای ویپ را بررسی میکنیم .سپس یک
فکس ســرور در کنار ســافت سوئیچ استریســک راه اندازی میکنیم بطوری که بتوانیم از طریق استریسک
فکس هایی را ارسال و دریافت کنیم.
در فصلهای ســیزدهم و چهاردهم دو ابزار مهم در مدیریت و برنامهنویســی سافت سوئیچ استریسک را
معرفی میکنیم .توســط این دو ابزار برنامه نویسان میتوانند برنامههای خود را با سایر زبانهای برنامهنویسی
توسعه دهند .در این فصل ها سعی شده است تا با ارائه مثالهای متعدد ،مفاهیم را به صورت ساده به خواننده
منتقل کنیم.
در فصل پانزدهم یکی از تکنولوژیهای جدید در ســافت ســوئیچ استریســک را معرفی میکنیم .ابزار
RESTfulاین قابلیت را به برنامه نویســان میدهد تا بتواننــد از طریق تکنیکهای Websocketو RESTبا
استریسک در ارتباط باشند.
در فصل شــانزدهم کتاب در خصوص ماژول pjsipتوضیح داده ایم .این ماژول در نســخههای جدیدتر
استریسک قابل استفاده میباشد .همچنین مزایای استفاده از این ماژول را در این فصل شرح خواهیم داد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 28
در فصل هفدهم در خصوص مانیتور کردن و بررســی الگ فایل ها در ســافت سوئیچ استریسک شرح
خواهیم داد.
در فصل هجدهم مباحث امنیتی در استریسک مطرح میشوند .همچنین استفاده از ارتباطات رمزنگاری
شده TLSو SRTPدر این فصل مطرح میشوند.
یکی از چالشهای مهم در شــبکههای ویپ ،ارزیابی عملکرد ســوئیچهای تلفنی و تجهیزات وابسته به
آن میباشد .شاید این سوال بسیاری از مخاطبان باشد که چگونه یک سافت سوئیچ استریسک را برای تعداد
تماس همزمان تســت و ازریابی کنیم و یا برای یک ســناریو چه منابع ســخت افزاری مورد نیاز میباشد .در
فصــل نوزدهم به صورت مفصل و کامل این موارد را با هم بررســی خواهیم کرد و انواع روشهای تســت
کارایی و تست تطابق را انجام خواهیم داد.
در استریسک دستورات و توابع زیادی وجود دارد که در فصل آخر سعی کرده ایم مهمترین و پرکاربرد
ترین دستورات و توابع را توضیح دهیم.
در ابتــدا از آقــای Leif Madsenکه کتــاب اینجانب را مورد لطف خود قرار دادند صمیمانه تشــکر و
سپاسگزاری می کنم .نگارش مطالب این کتاب بدون همکاری آقایان مهندس مجتبی نجفی مقدم و مهندس
مرتضــی ایروانی میســر نمی گردیــد .از زحمات آقای مهندس حامد رســتگار کــه در ویرایش فنی کتاب
اینجانب را همراهی کردند صمیمانه تشکر می کنم .همچنین از آقایان جلیل یزدانی و علیرضا رستمی که در
ویرایش اولیه کتاب اینجانب را همراهی کردند ،سپاسگزاری می کنم.
از همســر عزیز و مهربانم که در نگارش این کتاب به طور مستمر و خستگی ناپذیر اینجانب را تشویق و
ترغیب نمودند صمیمانه تقدیر و تشکر می نمایم.
این کتاب در طی ۲سال با دقت و حساسیت فراوان نگارش شده است .هدف اصلی کتاب این است که
خواننده با مطالعه و انجام مثال های آن با ســافت ســوئیچ استریسک در سطح مقدماتی و پیشرفته آشنا شود.
امیدوار هســتم کتابی مفید برای عالقمندان در حوزه تکنولوژی ویپ باشــد .به طــور حتم این کتاب خالی
از اشــکال نخواهد بود ،لذا از کلیه اســاتید محترم ،دانشــجویان و همکاران عزیز می خواهم چنانچه انتقاد و
پیشــنهادی نســبت به این کتاب دارند ،حتما به ما اطالع دهند تا بتوانیم در ویرایش های بعدی کتاب آنها را
اعمال نماییم.
مجتبی اسفندیاری
زمستان ۱۳۹۵
فصل اول
صدا چیست؟
صــدا یا صوت نوعی انرژی اســت که از تحرک ذرات ماده بهوجــود میآید؛ به این صورت که یک ذره با
حرکت و برخورد به ذرههای دیگر ،آنها را به حرکت درمیآورد و صدا نشــر پیدا میکند .صدا ارتعاشــی
اســت که بهوسیله حس شــنوایی انسان درک میشــود .ما معموالً صداهایی را که در هوا حرکت میکنند،
میشــنویم .صــدا میتواند در گازها ،مایعات و حتــی جامدات نیز حرکت کند .ســرعت صدا در جامدات
به دلیل تراکم زیاد مولکولها ،بیشــتر از مایعات و در مایعات نیز بیشــتر از گازهاســت .صدا برخالف امواج
دیگــری همچــون نور و گرما ،فقط در محیطی نشــر مییابد که در آن ماده وجود داشــته باشــد .این به این
معنی اســت که اگر بر ســطح کره ماه )که هوایی وجود ندارد( انفجاری روی دهد ،هیچوقت صدای آن را
نمیشــنویم .واحد اندازهگیری صدا دسیبل اســت که با نماد ۱ dBنشان میدهند .محدودهی شنوایی انسان
بین ۲۰هرتز تا ۲۰کیلوهرتز است ولی محدودهی توانایی تولید صدا در انسان ۳۰۰هرتز تا 4کیلوهرتز است.
تلفن چیست؟
تلفن یا دورگو 2از دســتگاههای ارتباط از راه دور اســت که برای انتقال صدا بهکار میرود .نخســتین تلفن
بهوســیله الکســاندر گراهام بل اختراع شد .بعدازظهر روز دوم ژوئن سال ۱۸۷۵میالدی مصادف با ۱۱خرداد
۱۲۵۴شمســی ،الکساندر گراهام بل با همکاری دوســتش واتسن موفق به اختراع تلفن شد و در ژانویه ۱۸۷۶
میالدی دســتگاه تلفن بل بهکار افتاد ۱۰ .مارس ۱۸۷۶میالدی ( ۱۲۵۵شمســی) بل از اتاق خود بهوســیله این
1- decibel
-2برگرفته از واژه فرانسوی ()Téléphone
31 آشنایی با تلفن و شبکه های مخابراتی PSTN
دستگاه به دستیارش در اتاق دیگر گفت« :آقای واتسن بیایید با شما کار دارم».
تلفن ،پس از اختراع کامل بهوسیله بل بهسرعت رشد یافت و سیمهای آن از شهری به شهر دیگر کشیده
شد .چهارده سال بعد از اختراع تلفن یعنی در سال ۱۸۹۰میالدی آلمون براون استروجر سیستم تلفن خودکار
را بنا نهاد .دو قاره اروپا و آمریکا تحت پوشــش شبکهای درآمدند که روزبهروز گسترش مییافت .همچنین
در ســال ۱۸۹۱ارتباط تلفنی بین شــهرهای لیون و تهران برقرار شــد .روزی که گراهام بل درگذشت (سال
،)۱۹۲۲به احترام او ارتباط تلفنی در شبکه وسیعی از هفده میلیون تلفن به مدت یک دقیقه قطع شد.
شکل 1-1
در ابتدا هدف از ایجاد شبکههای ،PSTNبرقراری ارتباط بین دو دستگاه تلفن بوده است .این ارتباط مداری
از ســمت تماسگیرنده شروعشــده و تا مقصد ادامه پیدا میکند .در حقیقت یک زوج ســیم از تلفن مبدأ
مرجع آموزش ویپ با سافتسوئیچ استریسک 32
تا مرکز مخابرات و یک زوج ســیم از تلفن مقصد تا مرکز مخابرات وجود داشــت که توســط یک المپ،
وضعیت گوشــی مشخص میشــد .بهعبارتیدیگر ،همه مشترکین بر روی تابلوی سوئیچ ،PSTNیک المپ
ِ
المپ وضعیت مشترک ،با او وضعیت ۱داشــتند .کارمندان شبکههای مخابراتی ،PSTNپس از روشن شدن
صحبت کرده و مقصد را از وی میپرسیدند .پس از مشخص شدن مقصد ،بهوسیله یک کابل ،ارتباط مورد
نیاز بین دو مشترک برقرار میشد .۲شکل ۲-۱یک تابلوی سوئیچ PSTNرا نشان میدهد.
شکل 2-1
باگذشــت زمان و افزایش مشترکین ،این نوع شــبکهها دیگر پاسخگوی نیازهای مردم نبود .همین امر
باعث ایجاد تغییراتی در سیگنالینگ شبکههای مخابراتی PSTNشد.
با اعمال تغییرات در ســیگنالینگ شــبکههای ،PSTNتلفنها به یک شمارهگیر گردان مجهز شدند .این
شــمارهگیرها بهصورت PULLو با صداهای بیپ مانند ،شــماره مقصد را به شبکه PSTNاعالم میکردند.
ســپس دفتر PSTNبهصورت خودکار ،ارتباط مبدأ را با مقصد درخواســتی برقــرار میکرد .بعدها با توجه
به اینکه شــمارهگیری با این نوع تلفنها زمانبر بود و برای شــمارههایی که تعداد زیادی ۹ ،8و یا صفر در
خود داشــتند ،زمان زیادی صرف میشد ،شــمارهگیر گردان را با یک صفحهکلید عوض کردند تا در زمان
صرفهجویی شــود .ایــن صفحهکلیدها هماکنون روی تلفنهای کنونی دیده میشــوند و صدایی با فرکانس
متفاوت برای هر شماره ایجاد میکنند .فرکانس ایجادشده بهوسیله هر کلید ،استاندارد است و شبکه ،PSTN
با دریافت فرکانسها و آنالیز آنها ،مقصد را مشــخص میکند .حاصلضرب فرکانســی ایجادشده بهوسیله
صفحهکلید را اصطالحاً DTMFمیگویند.
1
DTMF
همانطور که در شــکل ۳-۱مشاهده میشــود ،بهازای هر کلید ،دو فرکانس سطر و ستون ) f۱و (f۲در نظر
گرفته میشود .در این حالت با فشردن هر کلید ،فرکانسهای f۱و f۲در هم ضرب و حاصل آن بهصورت
تقســیم زمانی ارسال میشــود؛ یعنی بهازای ارسال هر شماره ،یک مکث کوتاه درنظر گرفته و دوباره ارسال
انجام میشود .شکل ۳-۱حاصلضرب فرکانسی را در واحد زمان نشان میدهد.
همانطور که در شکل ۳-۱مشاهده میشود هر عدد روی صفحه کلید ،متناظر با دو فرکانس است که با
فشــردن هر کلید ،این اعداد در هم ضرب میشــوند و یک فرکانس جدید را ایجاد مینمایند که واژه Dual
Tone Multi Frequencyاز این روش گرفته شده است.
شکل 3-1
خروجی ضرب شکلِ ،۳-۱شکل 4-۱است که در آن هر فرکانس در یک واحد زمانی ارسال و پس از
یک فاصله زمانی فرکانس بعدی ارسال میشود.
شکل 4-1
شکل 5-1
در این نوع شــبکه ،افزونگی 1دادهها داریم؛ چون هر بسته بطور مستقل مسیریابی میشود ،لذا باید درون
هر بســته آدرس مبدأ و مقصد وجود داشــته باشد .این امر باعث افزایش مصرف منابع در این شبکه میشود.
البته راههایی به منظور کاهش مصرف پهنای باند در این شبکهها وجود دارد که در حوصله این کتاب نیست.
شکل 6-1
خطوط آنالوگ
منظور از خط آنالوگ ،همان خط تلفن معمولی است .این خط بعد از برداشتن گوشی و شنیدن بوق آزاد،4
۶4کیلوبیت پهنای باند را از مرکز مخابراتی رزرو میکند .ازجمله دالیل استفاده از خطوط آنالوگ میتوان
به موارد زیر اشاره کرد:
-۱نبود خطوط دیجیتال در یک منطقه؛
-۲هزینه اندک؛
-۳نگهداری خطوط قبلی.
آنالوگ با سیســتم دیجیتال بودهاســت تا بتواند دادههای دیجیتال )صوت( را بهخوبی پشــتیبانی کند .در این
توپولوژی ،صدا نخســت به دادههای دیجیتال تبدیل میشــود و سپس انتقال مییابد .ازجمله مزایای خطوط
دیجیتال میتوان به موارد زیر اشاره کرد:
(۱بیتأثیربودن افت ولتاژ برای فاصلههای دور؛
(۲کاهش تأثیر نویز؛
(۳توانایی انتقال بیشتر از یک کانال روی بستر ثابت؛
(4سرعت باالی برقراری تماس.
شکل 7-1
37 آشنایی با تلفن و شبکه های مخابراتی PSTN
Local Loop
ارتباط بین تجهیزات مشــتریان ) (Analog Phoneبا مرکزمخابرات ) (COاز طریق این لینک برقرار میشود.
در اینجا منظور همان زوج سیم است که از سوی مخابرات به مشتریان درب منزل تحویل داده میشود.
Trunk
ارتباط بین مراکز مخابرات ) (COازطریق این لینک برقرار میشــود .در این حالت ارتباطات از میان خطوط
E1خواهد بود.
Private Switch
ایــن قابلیت وجــود دارد که ارتباط با برخی از مراکز تجاری و صنعتی از طریق Trunkبرقرار گردد .در این
حالت این نوع ارتباط همانند ارتباط بین مراکز مخابرات ) (COاست.
مرجع آموزش ویپ با سافتسوئیچ استریسک 38
شکل 8-1
در یکی از شلفها قرار داده میشود .این کارتها بهعنوان منبع اولیه ذخیره اطالعاتند که برخی از پیغامهای
اولیه و اخطارها را اعالم میکنند.
-2بخش ســوئیچ ( :)Switchاین بخش مسؤولیت مسیریابی ،مســیردهی (سوئیچینگ) و برقراری ارتباط بین
کانالهای مختلف تلفن را ازطریق مسیرهایی که از بخش Accessبه آن متصل میشود ،امکانپذیر میسازد.
-3بخش کنترلی ( :)Controlاین بخش بهعنوان مرکز اصلی یک ســوییچ تلفنی اســت که همه بخشهای
مرکزی را کنترل و مدیریت میکند.
-4بخــش عملیات و نگهداری :)operation and maintenance) O&Mاین بخش امکان ارتباط اپراتور با
سیســتم سوئیچ را امکانپذیر میکند تا کاربر بتواند با انجام تعاریف نرمافزاری ،وضعیت سوئیچ را بررسی و
اطالعات الزم را استخراج کند.
سطح شهری
شــبکه مخابرات شهری شبکهای است که امکان برقراری ارتباط بین مشترکین یک شهر با یکدیگر را فراهم
میکند .این شبکه شامل تجهیزات زیر است:
مراکز محلی :مراکزی هســتند که از یک طرف به شــبکه PSTNو از طرف دیگر از طریق زوج ســیمها ،به
مشترکین وصل میشوند.
مراکــز ترانزیــت :مراکزی هســتند که فقــط وظیفــه ترانزیت کــردن ترافیــک در مراکز هر ناحیــه را به
ســایر نواحــی برعهــده دارنــد .ایــن مراکــز معمــوالً در شــهرهای پرجمعیــت و پرتراکم که شــبکه ،بار
سنگینی دارد ،مناسب است .هر مرکز ترانزیت معموالً چندین مرکز تلفن اطراف خودش را پوشش میدهد.
مراکز :LTXاین مراکز ترکیبی از دو مرکز قبلاند؛ یعنی عالوه بر انجام ســرویسدهی به مشــترکین ،وظیفه
ترانزیت را هم انجام میدهند.
مرجع آموزش ویپ با سافتسوئیچ استریسک 40
سطح بینشهری
این شــبکه در ســطح دوم ارتباطات مخابراتی قرار دارد و برای ارتباطات بینشهری یا بین استانی تعریفشده
است .در این سطح ،سه نوع مرکز بینشهری داریم :مراکز ، SCمراکز PCو مراکز . TX
مراکز :SCمراکزی هســتند کــه چندین PCو یا بهعبارتدیگر چندین اســتان را تحت پوشــش خود قرار
میدهند .ایران درحالحاضر دارای هشــت منطقه مخابراتی است که در هر منطقه دو مرکز SCوجود دارد؛
پس در سطح کشور ۱۶مرکز SCداریم ،جدول 1-1انواع SCها در سطح کشور را نشان میدهد.
مراکز :PCمراکزی هســتند که LXهای یک شــهر یا اســتان را تحت پوشش قرار میدهند و خود نیز تحت
پوشش مراکز SCاند .درحالحاضر حدودا ً ۸۴مرکز PCدر سطح کشور وجود دارد.
سطح بینالملل
این مراکز هم همانگونه که از نامشان پیداست ،دروازه ارتباطات بینالملل ایران با دنیا هستند .درحالحاضر
دو مرکز ISC1و ISC2در سطح کشور فعالاند و ارائه خدمات میدهند .جدول 2-1کدهای مربوط به ISC
های دنیا را نشان میدهد.
مثال شــرکت مخابرات ایران چون امکان واگذاری تلفن ثابت روی زوج ســیم را دارد ،بهعنوان تنها اپراتور
مخابراتی ایران شــناخته میشود .البته امروزه شرکتهایی هســتند که مجوز واگذاری تلفن ثابت روی بستر
IPرا در اختیار دارند .این شــرکتها امروزه در قالب مجوز FCPفعالیت میکنند که مجوز Originationو
Terminationدارند.
از طرف دیگر شــرکتهایی که با کریرهای خارجی در ارتباطند و امکان ارتباط با خارج از کشــور را
فراهم میآورند ،دارندگان مجوز Origination/ Terminationنامیده میشــوند .این شرکتها از یکسو
با کریرهای مختلف دنیا ارتباط دارند (این نوع ارتباط از لحاظ تجاری Interconnectionنامیده میشــوند)
و از سوی دیگر با ISCها مرتبطند بهطوریکه تماسهای بینالملل از طریق این شرکتها صورت میگیرد.
جدول 2-1
نتیجهگیری
هدف از این فصل ،یک آشــنایی مختصر در مورد شــبکههای مخابراتی PSTNو اجزای تشکیل دهنده آن
اســت .نخست تاریخچه شبکه و بعد اصطالحات عمومی شــبکه مخابراتی معرفی شد و در نهایت به معرفی
اجزای تشکیل دهنده شبکه تلفنی PSTNپرداخته شد .آنچه در این فصل از اهمیت ویژهای برخوردار است،
این اســت که یک آشــنایی مختصر و مفید نسبت به شبکه های مخابراتی الزم اســت تا بتوانیم از آنها برای
ارتباط با شــبکههای مخابراتی نســل جدید استفاده کنیم .مسلما توضیح بیشــتر و عمیقتر راجع به شبکههای
مخابراتی PSTNخارج از حوزه کتاب است؛ لذا در این فصل ،بیشتر مطالب و کلیات عمومی مطرح شدهاند
و مطالعه بیشتر درخصوص این نوع شبکهها به خواننده کتاب واگذار میگردد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 42
فصل دوم
معماریاستریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 44
مقدمه
ازنظر ســاختاری و معماری طراحی ،تفاوت زیادی بین ســوئیچ مخابراتی قدیم با ســوئیچ تلفنی ویپ وجود
دارد .در ســوئیچهای مخابراتی ،فناوریهای مختلفی در هر حوزه ارتباطی وجود دارد که مفاهیم آنها باهم
متفاوت اســت .برای مثال فنــاوری ارتباطی بین مراکز مخابرات 1و مراکز خانگــی 2از نوع خطوط آنالوگ
3
است .همچنین فن ّاوری ارتباط بین مراکز مخابرات با مراکز تجاری و سایر مراکز مخابراتی دیگر کام ً
ال باهم
تفاوت دارند .در فصل 1در قسمت معرفی اجزای شبکههای مخابراتی ،PSTNهر بخش شرح داده شد.
ایــن تفاوت در فن ّاوری ارتباط در شــبکههای مخابراتی ،باعث میشــود تجهیزات ســختافزاری برای
راهانــدازی آنها نیز باهم متفاوت باشــند .برای مثال مــا نمیتوانیم ارتباط بین دو مرکــز مخابراتی را از نوع
خطوط مخابراتی آنالوگ برقرار کنیم ،بلکه این ارتباط لزوما باید از نوع Trunk Linkباشــد .از دیگر ســو،
در شبکههای نسل جدید ویپ ،چنین نگاهی را نسبت به منابع نداریم .استفاده از هر فن ّاوریای در شبکههای
ویپ ،ساختار ماژولی 4دارد و بهصورت یک کانال ارتباطیای 5معرفی میشود که بهوسیله آن میتوانیم یک
ارتباط برقرار کنیم.
1- Central Office Switch
2- Analog Telephone
3- Local Loop
4- Modular
5- Channel Driver
45 معماری استریسک
شکل1-2
برای روشنتر شدن مطلب ،شکل 1-2را در نظر بگیرید .همانطور که در سمت چپ مالحظه میکنید،
هر فن ّاوری در شــبکههای مخابراتی ،مســتقل از ســایر فن ّاوریهاســت .برای مثال در ستون سمت چپ بخش
،Trunksفن ّاوریهای متعددی از قبیل PRI، BRIو ...وجود دارد ،درحالیکه در ستون سمت راست بخش
،Stationsفن ّاوریهای دیگری دیده میشود .همچنین در این بخش شما میتوانید با داشتن یک زوج سیم از
مرکز مخابراتی ،سرویسهای مختلفی دریافت کنید.
در شکل سمت راست ،هسته اولیه یک سافت سوئیچ استریسک دیده میشود .از هر فن ّاوری ارتباطی که
موردنیاز باشد ،میتوان بهصورت کام ً
ال مجزا و ماژوالر استفاده کرد .همانطور که در شکل مالحظه میشود،
هستهی اولیه سافت سوئیچ استریسک ،سبک و بدون هیچ قابلیتی است .تمام قابلیتبهصورت ماژوالر میتواند
به هسته اولیه استریسک 1اضافه شود.
کنتــرل و هدایت همه تماسها را در استریســک به دســت گرفــت .بهطورکلی ســاختار و بدنه اصلی یک
برنامهنویسی بهصورت زیر است:
exten => extension, periority, application
دستورات استریسک جزء ساختار و بدنه اصلی برنامهنویسی هستند .استریسک معموالً دستورات متفاوتی
2
را در بدنه خود دارد که همه آنها بهصورت ماژوالر به هســته اضافه شــده و قابلاســتفادهاند .به عنوان مثال،
برای ایجاد یک تماس جدید از دســتوری به نام Dialاســتفاده میکنیم .این دســتورات با اضافه شدن ماژول
app_dial.soبه هسته استریسک ،تعریف و اضافه میشود.
برای آشنایی با انواع دستورات در استریسک ،دستور زیر را در کامند الین استریسک وارد نمایید:
_CLI> module show like app
در جدول 1-2فهرست انواع ماژولهای دستورات قابل استفاده در استریسک را میتوانید مالحظه کنید.
استفاده شدهapp_ برای مشاهده فهرست دستورات استریسک از پیشوند،همانطور که مالحظه میکنید
اگر قصد. نمایش داده میشوندApplication در این حالت تمام ماژولهای دستهبندیشده در حوزه.اســت
در این. باید اســم ماژول را به طور کامل مشخص کنیم،داشــته باشیم فعال بودن یک ماژول را بررسی کنیم
. مشخص خواهد شد که ماژول فعال است یا نیست،صورت با توجه به نوع خروجی استریسک
. در استریسک فعال است یا نهDial برای مثال فرض کنید قرار اســت بررســی کنیم که آیا ماژول دستور
:برای این منظور دستور زیر را در کامند الین استریسک اجرا میکنیم
CLI> module show like app_dial.so
Module Description Use Count
app_dial.so Dialing Application 0
1 modules loaded
مرجع آموزش ویپ با سافتسوئیچ استریسک 50
همانطور که مالحظه میکنید ،ماژول فوق در استریســک فعال است .اکنون فرض کنید بخواهیم این ماژول
را در استریسک موقتاً غیرفعال کنیم .در این صورت دستور زیر را در کامند الین استریسک اجرا میکنیم:
CLI> module unload app_dial.so
Unloaded app_dial.so
›== Unregistered application ‹Dial
›== Unregistered application ‹RetryDial
با غیرفعال کردن ماژول فوق در استریســک ،دســتور Dialغیرفعال شده و دیگر نمیتوانیم از آن استفاده
کنیم .در صورت استفاده کردن از دستور فوق ،استریسک گزارش زیر را در کامند الین نشان می دهد.
[Jun 30 13:06:20] WARNING[7481][C-00000031]: pbx.c:4878 pbx_extension_helper: No
)application ‹Dial› for extension (agents, op103, 5
ما میتوانیم ماژولهایی را که در استریسک نیاز نداریم ،غیرفعال کنیم .غیرفعال کردن ماژولهای اضافی
در استریســک باعث سبکتر شدن آن میشود و در پی آن کارایی استریسک افزایش پیدا میکند .عالوه بر
این ،امنیت در سیستم استریسک نیز افزایش پیدا میکند.
برای مثال فرض کنید قرار است یک سیستم نظرسنجی با استریسک طراحی کنید .در این صورت ،چون
هدف این است که مشترک با سیستم تماس بگیرد و نظر خود را بهصورت اعداد اعالم کند ،مسلماً در چنین
سیســتمی نیازی به فعال بودن برخی ماژولها نیســت؛ چون اکثر تماسها در این سیســتم به صورت ورودی
1
هستند .بنابراین میتوانیم برای باالبردن امنیت ،ماژولهای بالاستفاده را غیرفعال کنیم.
نکته مهم در غیرفعال کردن ماژولها به روش فوق ،این اســت که اگر استریســک مجددا ً راهاندازی شود،
ماژول دوباره فعال میشود .برای غیرفعال کردن ماژول بهصورت دائم ،باید از فایل module.confاز مسیر زیر
استفاده کنیم و تغییرات الزم را انجام دهیم.
#vim /etc/asterisk/modules.conf
>noload => <module name
بعد از انجام تغییرات در این فایل بهصورت فوق ،ماژول برای همیشه در استریسک غیرفعال خواهد ماند .در
فصلهای بعدی در مورد ماژول Applicationو کاربرد آن در استریسک بیشتر توضیح خواهیم داد.
1- Incoming
51 معماری استریسک
ایجاد یک تماس دوطرفه ،استریســک باید دو کانال ارتباطی جدید ایجاد کند و آن دو را به هم متصل کند،
بهطوریکه دادهها )صدا( از یک کانال به کانال دیگر انتقال یابد .این عمل را Bridgeشدن کانالها میگویند.
شکل 2-2
برای مشاهده این نوع ماژولها ،دستور زیر را در کامند الین استریسک اجرا کنید:
_CLI> module show like bridge
در جدول زیر لیست انواع ماژولهای Bridgeدر استریسک ارائه شده است.
1
ماژول ری ز گزارشات تماس
یکــی از قابلیتهــا و امتیــازات منحصربهفــرد یــک ســوئیچ ،گــزارش دقیــق از جزئیــات تماسهــای
ورودی و خروجــی اســت .در استریســک ،مــاژول CDRایــن قابلیتهــا را فراهــم میکنــد تــا بتوانیــم
گــزارش دقیقــی از کارکــرد سیســتم داشــته باشــیم .همــه گزارشهــای CDRبهصورت پیشفــرض در
مســیر /var/log/asterisk/cdr-csv/Master.csvدر فایــل سیســتم ذخیــره میشــوند .ازآنجاکــه کار
بــا ایــن نــوع گزارشها در فایل سیســتم دشــوار اســت ،ایــن قابلیــت در استریســک وجــود دارد که این
گزارشها در پایگاههای دادهای 2همچون MYSQL,postgresql, MSSQLذخیره شوند.
برای مشاهده این نوع ماژولها ،دستور زیر را در کامند الین استریسک اجرا کنید:
1
ماژول رویدادهای استریسک
هر فعالیتی که. دارای یک ســاختار پیامگرا (رویدادگرا) نیز هست،استریســک در کنار ســاختار ماژوالر خود
var/log/asterisk/cel-/ در مســیرCEL بهصــورت رویدادهایی در گزارشهــای،استریســک انجام میدهد
. ذخیره میشوندcustom/Master.csv
: دستور زیر را در کامندالین استریسک اجرا کنید،برای مشاهده این نوع ماژولها
CLI> module show like cel_
3-2 شکل
ارتباط مستقیمی با نوع کدک استفادهشده، کیفیت سرویس ارائهشــده،با توجه به اینکه در شــبکههای ویپ
، در استریسک. بنابراین استفاده از کدک مناسب در شبکه از اهمیت ویژهای برخوردار است،در شــبکه دارد
نکته مهم این است که. میتوان تبدیل کدک انجام داد،چنانچه دو طرف از کدک یکســانی اســتفاده نکنند
1
را بهCPU افت کارایی سیســتم استریســک و افزایش پردازش،تبدیل کدک در بلندمدت و حجمهای باال
.دنبال خواهد داشت
1- Transcoding
55 معماری استریسک
: دستور زیر را در کامند الین استریسک اجرا کنید،برای مشاهده انواع کدکهای فعال در استریسک
CLI> module show like codec_
برای تبدیل صدا از یک کدک به.همانطور که میدانیم در استریســک از تبدیل کدکها اســتفاده میشود
. مدتزمان برحسب میلیثانیه در نظر گرفته میشود،یک کدک دیگر
:دستور زیر تبدیل کدکها به یکدیگر را برحسب میلیثانیه نشان میدهد
CLI> core show translation
Translation times between formats (in microseconds) for one second of data
Source Format (Rows) Destination Format (Columns)
4-2 شکل
Dialplan Function
از توابع قدرتمندی استفاده میکند که باعث تسریع در برنامهنویسی،Application استریسک در کنار ماژولهای
1
: دستور زیر را در کامندالین استریسک وارد نمایید، برای مشاهده انواع توابع در استریسک. میشودDialplan
CLI> module show like func_
1- Function
57 معماری استریسک
.در فصلهای پنجم و هشتم در مورد برنامهنویسی در استریسک به طور مفصل توضیح خواهیم داد
PBX Config
استریسک از یک، در همین راستا. یک ساختار اولیه برای پیکربندی و راهاندازی دارد،اکثر سوئیچهای تلفنی
ساختار فایل سیستمی برخوردار است که میتواند پیکربندی اولیه و ابتدایی استریسک را تنظیم و مدیریت کند؛
اشاره، که مربوط به برنامهنویســی استextension.conf ازجمله این موارد میتوان به ســاختار پیکربندی فایل
.کرد
،1 که در تولید کال فایلهاpbx-spool و ماژولARA است که درpbx-realtime ماژول،از دیگر این موارد
. هر ماژول به تفصیل در فصلهای یازدهم و سیزدهم توضیح داده میشوند.استفاده میشود
: دستور زیر را در کامندالین استریسک اجرا کنید،برای مشاهده انواع ماژولها
CLI> module show like pbx_
ماژول Resource
در استریســک این قابلیت فراهمشده اســت که بتوانیم با سایر سرویسها ارتباط داشــته باشیم؛ برای مثال به
منظور ذخیره کردن گزارشهای استریسک در پایگاههای دادهای ،از این نوع ماژولها استفاده میکنیم.
برای مشاهده انواع ماژولها ،دستور زیر را در کامندالین استریسک اجرا کنید:
_CLI> module show like res
مشخص کرد که چه ماژولهایی باید فعال شوند .همچنین میتوان ترتیب بارگذاری ماژولها در استریسک را
تعیین نمود.
:queues.conf -مدیریت صفها در این فایل انجام میشود.
:iax.conf -تنظیمــات مربوط به تعریف و شناســایی کاربرها و ارتباطات با پروتــکل IAXدر این فایل انجام
میشود.
:asterisk.conf -در این فایل پیکربندی اولیه هسته استریسک انجام میشود.
ل ماژولها در استریسک
فای
مســیر فایلهای ماژول در استریســک در مســیر /usr/lib/asterisk/modules/اســت .استریســک بهصورت
پیشفــرض همه ماژولهایی که در این مســیر قرار دارند را بارگذاری 1میکند ،مگــر آنکه ماژول موردنظر را
بهصورت دستی در فایل modules.confغیرفعال کنیم .همچنین میتوانیم با حذف ماژول موردنظر از این مسیر،
ماژول را بهصورت دائم غیرفعال کنیم .شاید بهتر باشد برای ماژولهایی که به آنها نیازی نداریم ،آنها را برای
همیشــه از این مسیر حذف کنیم .برای مشاهده انواع ماژولهای استریسک ،دستور زیر را در محیط استریسک
اجرا کنید:
#ls /usr/lib/asterisk/modules
2
برنامهنویسی در استریسک
برنامهنویسی در استریسک ،مرکز اصلی کنترل تماسهای ورودی و خروجی در استریسک است .درواقع هر
تماس جدیدی که وارد سیســتم تلفنی استریسک میشــود به وسیله این فایل مسیریابی میشود و در صورت
مطابقت با رولهای 3تعریفشــده ،دســتورات اجرا میشــوند .در استریسک ،ســه روش برای برنامهنویسی
هســت که در ادامه به آنها خواهیم پرداخت .ازآنجاکه در فصلهای آینده راجع به برنامهنویسی استریسک و
قابلیتهای آن توضیح داده خواهد شد ،در این فصل تنها به معرفی انواع روشهای برنامهنویسی در استریسک
اکتفا میکنیم.
1- Load Modules
1- Dial Plan
2- roles
61 معماری استریسک
استفاده از extensions.conf
یکی از ســادهترین روشهای برنامهنویســی در استریسک استفاده از این فایل است .در زیر مثالی ساده از این
نوع برنامهنویسی ارائه شدهاست:
;extensions.conf
][default
)exten => 100,1,playback(please-hold
)exten => 100,2,dial(IAX2/203,60
)exten => 101,1,dial(SIP/101,60
استفاده از extensions.ael
یکی دیگر از روشهای برنامهنویســی در استریسک ،استفاده از برنامهنویسی بهصورت aelاست .نمونهای از
برنامهنویسی با این روش در زیر ارائه شده است.
;extensions.ael
{ context defualt
{ >= 100
;)Playback(please-hold
;)Dial(IAX2/203,60
}
{ >= 101
;)Dial(SIP/101,60
}
استفاده از extensions.lua
یکی دیگر از روشهای برنامهنویســی در استریســک استفاده از برنامهنویسی بهصورت luaاست .نمونهای از
برنامهنویسی با این روش در زیر ارائه شده است.
;extension.lua
{ = extensions
{= default
)[“100”] = function(function,extension
)”app.playback(“please-hold
)app.dial(“IAX2/203”,60
)[“101”] = function(function,extension
)app.dial(“SIP/101”,60
;end
در استریســک میتوانیم از هر ســه روش برای برنامهنویســی اســتفاده کنیم .آنچه در این کتاب بیشتر توضیح
داده میشــود ،برنامهنویســی با روش اول و استفاده از فایل extension.confاســت .استفاده از سایر روشهای
برنامهنویسی در استریسک به خواننده کتاب واگذار میشود.
مرجع آموزش ویپ با سافتسوئیچ استریسک 62
نتیجهگیری
استریســک از کامپوننتها و ماژولهای مختلفی تشکیلشــده اســت که هرکدام از آنهــا قابلیتهایی را به
استریســک اضافه میکنند .استریســک میتواند از همه این قابلیتها ،در صورت فعال بودن در استریســک
استفاده کند .در فصلهای آینده هر یک از این ماژولها و قابلیتها را به تفصیل شرح خواهیم داد.
فصل سوم
نصب و راه اندازی استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 64
1
بروز رسانی سیستم
در سیســتم عامل لینوکس برای نصب بستههای مورد نیاز ،باید ابتدا آنها را بروزرسانی کنیم تا از آخرین
نسخه ارتقا یافته بستهها ،استفاده کنیم .به همین منظور در اولین گام باید سیستم عامل را آپدیت کنیم .مراحل
زیر را با توجه به توزیع لینوکسی انجام میدهیم.
; RHEL
# yum update –y
;Ubuntu
# apt-get update
بعد از انجام عملیات بروزرســانی ،باید سیســتم را مجددا ً راهاندازی کنید .برای راهاندازی سیستم ،دستور
زیــر را اجرا کنید .برای راه اندازی مجدد سیســتم ،دســتورات متعددی وجود دارد کــه میتوان از هر کدام
استفاده کرد .در زیر مثالهایی از هریک آورده شده است:
; RHEL
# reboot
# shutdown –r now
# init 6
;Ubuntu
# reboot
# shutdown –r now
#init 6
اولین اقدامی که بعد از بروزرسانی سیستم لینوکس انجام میدهیم ،نصب نیازمندیهای استریسک است .برای
اینکه بتوانیم استریسک را با موفقیت نصب کنیم باید ابتدا بستههای مورد نیاز استریسک را نصب کنیم .هدف از
این فصل ،نصب استریسک 3 DAHDI ،و LibPRIاست .در فصلهای بعدی توضیح خواهیمداد که برای فعال
کردن برخی قابلیتهای استریسک باید نیازمندیهای آنها را نیز نصب کنیم .این قابلیتهای استریسک در هر
فصل بهطور مستقل شرح داده خواهندشد.
با توجه به توزیع لینوکس ،برای نصب نیازمندیهای استریسک ،دستورات زیر را در کامندالین لینوکس
اجرا کنید:
; RHEL
# yum install gcc gcc-c++ make wget
subversion libxml2-devel
ncurses-devel openssl-devel
sqlite-devel libuuid-devel
vim-enhanced
;Ubuntu
# apt-get install build-essential subversion
libncurses5-dev libssl-dev
libxml2-dev libsqlite3-dev
uuid-dev vim-nox
از آنجاکه برای نصب استریســک 13باید ماژول jsonاز قبل نصب شــده باشد ،میتوانید بهصورت زیر آن
را دانلود و نصب کنید.
;RHEL
#wget http://www.digip.org/jansson/releases/jansson-2.4.tar.gz
#tar -zxf jansson-2.4.tar.gz
#cd jansson-2.4/
#./configure --prefix=/usr/ && make clean && make && make install
;Ubuntu
#apt-get install libjansson-dev
#wget http://www.digip.org/jansson/releases/jansson-2.4.tar.gz
#tar -zxf jansson-2.4.tar.gz
#cd jansson-2.4/
#./configure --prefix=/usr/ && make clean && make && make install
;Ubuntu
# cd /usr/src/asterisk-source/
# cd contrib/scripts/
# ./install_prereq install
اســتفاده از این روش در این مقطع زمانی توصیه نمیشود و از خواننده کتاب درخواست میگردد که نصب
نیازمندیهای استریسک را در زمان خودش و در فصلهای مرتبط ،مستقال انجام دهد.
67 نصب و راهاندازی استریسک
; RHEL
#yum install git
# mkdir -p /usr/src/asterisk
# cd /usr/src/asterisk
# git clone https://gerrit.asterisk.org/asterisk
; Ubuntu
#apt-get install git
# mkdir -p /usr/src/asterisk
# cd /usr/src/asterisk
# git clone https://gerrit.asterisk.org/asterisk
: دستور زیر نمایش داده خواهد شد،بعد از اجرای موفق اسکریپت فوق
######################################
## install completed successfully
######################################
;Ubuntu
# apt-get install wget
# cd /usr/src/
# wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz
# wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/dahdi-linux-
complete-current.tar.gz
# wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-current.tar.gz
;Ubuntu
# cd /usr/src/
# wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/dahdi-linux-
complete-current.tar.gz
# wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-current.tar.gz
. اکنون باید هر بسته به صورت مجزا نصب شود. دانلود شد،تا اینجا بستههای مورد نیاز برای نصب استریسک
. اولویت نصب بستهها توضیح داده خواهد شد،در بخش بعدی
نصب استریسک
گاهی به این نیاز. تنها نصب استریسک از روی سورس آن کافی است،برای استفاده از سافت سوئیچ استریسک
متصل کنیم و از فناوریهای خطوط آنالوگPSTN داریم که سیســتم تلفنی استریســک را به شبکه مخابراتی
وDAHDI در این حالت باید دو بســته.) اســتفاده کنیمE1/T1 (لینکهایPRI ) وFXO/FXS (لینکهــای
برای این منظور اولویت نصب بستهها را به صورت زیر درنظر. را نیز همزمان با استریسک نصب کنیمLibPRI
:بگیرید
• DAHDI
• LibPRI
• Asterisk
از حالت فشرده خارج و بعد دستورات زیر را اجراtar نخست باید آن را به کمک دستورDAHDIبرای نصب
:کنید
; RHEL
# cd /usr/src/
# tar –zxvf dahdi-linux-complete-current.tar.gz
# cd dahdi-linux-complete2.6.1+2.6.1/
# ./configure
#make all
# make install
# make config
: از دستور زیر استفاده کنید./configure استفاده میکنید باید به جای دستورRHEL 64-bit اگر از
# ./configure --libdir=/usr/lib64
;Ubuntu
# cd /usr/src/
# tar –zxvf dahdi-linux-complete-current.tar.gz
# cd dahdi-linux-complete2.6.1+2.6.1/
# make all
69 نصب و راهاندازی استریسک
# make install
# make config
E1/ (خطوطISDN با نصب این بسته میتوانید از فناوری. را نصب کنیدLibPRI بسته،DAHDI پس از نصب
LibPRI برای نصب. استفاده کنیدPSTN ) در ســافت سوئیچ استریسک برای ارتباط با شــبکهی مخابراتیT1
:دستورات زیر را اجرا نمایید
; RHEL
# cd /usr/src/
# tar –zxvf libpri-current.tar.gz
# cd libpri/
# make
# make install
: از دستور زیر استفاده کنیدmake install استفاده میکنید باید بهجای دستورRHEL 64-bit اگر از
# make install libdir=/usr/lib64
;Ubuntu
# cd /usr/src/
# tar –zxvf libpri-current.tar.gz
# cd libpri/
# make
# make install
برای نصب استریسک دستورات زیر را. نوبت به نصب استریســک میرسد،LibPRI وDAHDI بعد از نصب
:اجرا کنید
; RHEL
# cd /usr/src/
# tar –zxvf asterisk-13-current.tar.gz
# cd asterisk13/
# ./configure
# make
# make install
# make samples
# make config
: از دستور زیر استفاده کنید./configure استفاده میکنید باید به جای دستورRHEL 64-bit اگر از
# ./configure --libdir=/usr/lib64
;Ubuntu
# cd /usr/src/
# tar –zxvf asterisk-13-current.tar.gz
# cd asterisk13/
# ./configure
# make
# make install
# make samples
# make config
مرجع آموزش ویپ با سافتسوئیچ استریسک 70
دســتور : make menuselectیک محیط ویزارد متنی است که برای مشاهده انواع ماژولهای فعال و غیرفعال
در استریسک به کار میرود .در این محیط ویزارد متنی میتوان مشخص کرد که کدام ماژولها در استریسک
فعال و کدام یک غیرفعال اســت .دو محیط ویزاردی برای این دستور وجود دارد :محیط ویزاردی سیاه و سفید
( )Cursesو محیط ویزاردی رنگی ( .)Newtدســتور make menuselectدر حالت پیشفرض از محیط ویزادی
سیاه و سفید (شکل )1-3برای نمایش و مدیریت ماژولها در استریسک استفاده میکند.
اگر مایلید دستور make menuselectاز محیط ویزارد رنگی ) (Newtاستفاده کند ،باید ابتدا کتابخانهی
libnewtدر لینوکس را نصب کنید .برای این منظور با توجه به توزیع لینوکس ،دستور زیر را اجرا نمایید:
; RHEL
#yum install libnewt-devel
;Ubuntu
# apt-get install libnewt-dev
شکل1-3
پس از اجرای دســتور فوق ،با اجرای دســتور ،make menuselectمحیط ویزاردی رنگی ( )Newtنمایش داده
خواهد شد (شکل .)2-3
71 نصب و راهاندازی استریسک
شکل 2-3
همانطور که در شــکل 3-3مشــاهده میکنید ،انواع ماژولها در استریسک نمایش داده میشوند .در فصل
قبل درباره انواع ماژولها و کاربرد آنها توضیح دادیم .به عنوان مثال میتوانیم ماژول app_dialرا برای همیشه
در استریسک غیرفعال کنیم .برای این منظور کافی است از قسمت Applicationsماژول app_dialرا انتخاب و
عالمت [*] را حذف کنیم ،سپس استریسک را مجددا ً نصب کنیم .بعد از نصب استریسک ،ماژول فوق غیرقابل
استفاده میشود .با این روش میتوانیم ماژولهایی را که به آنها نیاز نداریم ،در استریسک غیرفعال کنیم .شکل
3-3نحوه غیرفعالکردن ماژول app_dialرا نشان می دهد.
شکل 3-3
مرجع آموزش ویپ با سافتسوئیچ استریسک 72
دســتور : makeوظیفه کامپایل کردن ســورس کدهای استریســک را برعهده دارد .با اجرای این دستور همه
سورس کدهای استریسک و ماژولهای آن کامپایل و فایلهای اجرایی آنها ( )simple objectایجاد میشود.
دستور : make installبا اجرای این دســتور ،همه فایلهای اجرایی استریسک ( )simple objectبه مکانهای
مورد نظر و از قبل تعیین شــده منتقل میشوند تا بتوانیم استریســک را اجرا کنیم .به عنوان مثال مسیر فایلهای
اجرایی ( )simple objectدر استریسک در مسیر زیر قرار دارد .اجرای این دستور در تمامی توزیعهای لینوکسی
یکسان است.
# ls /usr/lib/asterisk/modules/
با اجرای دســتور فوق همه ماژولهای فعال در استریســک نمایش داده میشوند .در زمان اجرای استریسک،
تمامی ماژولهای موجود در این مســیر در استریســک بارگذاری و فعال میشوند .درصورت لزوم میتوانیم
ماژولهایی را از این مسیر حذف یا اضافه کنیم و سپس استریسک را مجددا ً راهاندازی نماییم .در این صورت
استریسک ،آنها را تشخیص میدهد و تغییرات اعمال میشوند.
دســتور : make configوظیفه این دستور این است که یک فایل اجرایی در مسیر /etc/init.d/asteriskایجاد
کند تا بتوانیم استریسک را بهصورت سرویس مدیریت کنیم .همچنین این امکان وجود دارد که استریسک به
صورت سرویس در backgroundاجرا شود.
}#/etc/init.d/asterisk {start|stop|restart|reload|condrestart|status
دستور : make samplesدر مسیر نمونه ،مثالها و راهنماییهایی از پیکربندی استریسک وجود دارد:
#ls /usr/src/asterisk-13.2.0/configs/samples/
درخروجی دستور فوق ،نمونههایی از پیکربندی در هر بخش از استریسک وجود دارد .با اجرای دستور make
،samplesیک نمونه از کل فایلهای فوق در مسیر /etc/asteriskساخته میشود .در ادامه بحث و در فصلهای
آینده مفصل راجع به هر فایل و پیکربندی آن توضیح خواهیم داد.
نصب استریسک با موفقیت انجام شد .اکنون سرویسها را با یکی از روشهای زیر اجرا میکنیم:
# service dahdi start
# service asterisk start
یا
# /etc/ini t.d/dahdi start
# /etc/init.d/asterisk start
بعد از اجرای استریسک میتوان با دستور زیر وارد محیط کامند الین استریسک شد:
# asterisk -r
Asterisk 13.2.0, Copyright (C) 1999 - 2014, Digium, Inc. and others.
>Created by Mark Spencer <markster@digium.com
Asterisk comes with ABSOLUTELY NO WARRANTY; type ‹core show warranty› for details.
This is free software, with components licensed under the GNU General Public
73 نصب و راهاندازی استریسک
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type ‹core show license› for details.
================================================================
)Connected to Asterisk 13.2.0 currently running on Asterisk (pid = 19801
>Asterisk*CLI
همانطورکه مالحظه میکنید نسخه نصب شده استریسک تحت الیسنس GNUنشان داده شده است .آنچه که
ما تا اینجا در باره آن توضیح دادیم ،نصب استریسک و نیازمندیهای آن بود .همچنین برای ارتباط استریسک
با شــبکههای مخابراتی ،PSTNبســتههای DAHDIو LibPRIرا نیز نصب کردیم .در ادامه بحث به پیکربندی
مقدماتی استریسک و آشنایی با فایلسیستمها در استریسک میپردازیم.
1
پیکربندی اولیه استریسک
برای پیکربندی سیستم تلفنی استریسک ،نخست الزم است با ساختار فایلسیستم در استریسک 2آشنا شوید.
استریسک برای کنترل و پیکربندی بخشهای مختلف خود ،از فایلهای پیکربندی متعددی استفاده میکند که
همه آنها در مسیر /etc/asterisk/و با پسوند confقرار دارند .دستور زیر انواع فایلهای پیکربندی در استریسک
را نشان میدهد.
#ls –lh /etc/asterisk
بخش []directories
استریســک در هنگام نصب ،فایلهای اجرایی ( )Simple Objectرا میسازد و در مسیرهایی ذخیره میکند .در
زیر مسیر پیکربندی فایل سیستم استریسک ،نشان داده شدهاست.
)!( ][directories
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /var/lib/asterisk
astdbdir => /var/lib/asterisk
astkeydir => /var/lib/asterisk
ذکر این نکته مهم است که میتوان همزمان چند نسخه از استریسک را روی یک سیستم نصب کرد .برای این
کار ابتدا مسیرهای پیش فرض قسمت [ ]directoriesرا تغییر دهید و مسیر جدید را مشخص کنید.
بخش []options
هنگام اجرای استریسک میتوان از یک سری آپشنها استفاده کرد که هر کدام یکی از قابلیتهای استریسک
را در زمان اجرا شدن فعال میکند .فهرست برخی از این آپشنها از قرار زیر است:
: asterisk -cدر ایــن حالت استریســک بهصورت foregroundاجرا میشــود؛ یعنی تــا زمانیکه کامند الین
استریسک فعال باشد ،استریسک هم فعال است و در صورت خارج شدن از آن ،استریسک متوقف میشود .در
این حالت استریسک به صورت یک برنامه (نه سرویس) اجرا میشود.
: asterisk -rدر این حالت استریســک در backgroundفعال است و بهصورت سرویس کار میکند .در این
روش به محیط کامند الین استریسک متصل میشویم.
: asterisk -vعالمت vدرجه گزارشدهی ( )verboseدر کامند الین استریســک را مشــخص میکند .هرچه
تعداد بیشتری vبگذاریم ،جزئیات بیشتری در محیط کامند الین استریسک نمایش داده میشود.
: asterisk -xگاهی نیاز داریم بدون وارد شــدن به محیط کامند الین استریسک ،دستوراتی را در استریسک
اجرا کنیم .در این حالت از این فرمان استفاده میکنیم .برای مثال فرض کنید قصد داریم ورژن استریسک را
نشان دهیم .در این صورت دستور زیر را اجرا میکنیم:
'# asterisk -x 'core show version
Asterisk 13.2.0 built by root @ ubuntu on a x86_64 running Linux on 2016-05-08 15:19:40
UTC
:safe_asteriskدر زمان نصب استریســک ،اســکریپتی بهنام safe_asteriskایجاد میشــود .این اســکریپت
دائماً وضعیت استریســک را بررسی میکند .در صورتی که در استریسک خطایی رخ دهد که به از کار افتادن
استریسک منتهی شــود ،بالفاصله استریســک را مجددا ً راهاندازی و اطالعرسانی میکند .همچنین این قابلیت
وجود دارد که عاملی که باعث شده استریسک از کار بیفتد را در مسیر فایل /tmp/ذخیره کند.
آنچه در این قسمت از فایل asterisk.confمهم است ،این است که استریسک میتواند در سطوح مختلفی،
گزارشهایی را در صفحهی کامند الین خودش یا در مسیر فایلهای Logاستریسک تولید و نمایش دهد .برای
75 نصب و راهاندازی استریسک
مثال وقتی استریسک را نصب میکنیم و سپس وارد محیط کامند الین استریسک میشویم ،ممکن است هیچ
logو گزارشی نشان دادهنشود.
گزارشها در استریسک در دو بخش verboseو debugتقسیم میشوند .میتوان با دستورات زیر ،سطح
این دو بخش را تعیین نمود:
# asterisk -r
)Connected to Asterisk 13.2.0 currently running on simulate1 (pid = 1635
simulate1*CLI> core set verbose 3
در این دستور ،سطح گزارشهای مربوط به verboseرا روی 3تنظیم میکنیم.
# asterisk –rvvv
همانطورکه مشاهده میکنید با اضافهکردن هر ، vسطح گزارشها ،یکی باال میرود .در نتیجه گزارشهای
بیشتری در محیط کامندالین استریسک نمایش داده میشود.
اگر در بخش [ ]optionدر فایل ، asterisk.confپارامترهای verboseو debugرا فعال و سپس استریسک
را reloadکنید ،از آن به بعد ،ســطح گزارشهای این دو بخش پیش فرض به levelهایی که تنظیم کردهاید،
تغییر مییابد .برای مثال فرض کنید این پارامترها را به صورت زیر تنظیم کرده باشیم:
#vim /etc/asterisk/asterisk.conf
][options
verbose = 3
debug = 3
از جمله پارمترهای مهم دیگر در این بخش ،پارامتر maxcallو maxfileو maxloadاست .این سه پارامتر در
واقع پارامترهای کنترلی و مدیریت تماسها در استریسکاند.
پرسشی که ممکن است در اینجا به ذهن خطور کند این است که این پارامترها ،چه زمانی ممکن است مورد
استفاده قرار گیرند؟ پاسخ به این سوال مستلزم آن است که خواننده بیشتر با استریسک آشنا باشد و نقاط ضعف
و قوت آن را بخوبی بشناسد .اما اگر بخواهیم به یک پاسخ ساده اکتفا کنیم ،پاسخ این است که اگر استریسک
استرس قرار دهیم تا تمام منابع سختافزاری در دسترسش مصرف شود ،در چنین شرایطیِ را در شــرایط تست
استریســک کنترل خود را در ایجاد و مدیریت تماسها ( sessionها) از دســت میدهد؛ چون منابع کافی برای
مدیریت آنها ندارد .بنابراین برای اینکه از چنین شــرایط بحرانیای در استریسک جلوگیری کنیم ،میتوانیم با
توجه به منابع ســختافزاری و انجام تســتهای استرس ، 1حد نرمال را برای استریسک پیدا و پارامترهای آن را
تنظیم نماییم.
در فصــل نوزدهم (بررســی و ارزیابی عملکرد سیســتمهای تلفنــی IP/PBXو تجهیزات وابســته) با انجام
سناریوهای تست استرس آشنایی بیشتری پیدا خواهید کرد.
برای مشاهده و تخصیص منابع سختافزاری موجود به سرویس استریسک ،از دستور زیر استفاده کنید.
خروجی دستور فوق نشان میدهد که سرویس استریسک تا چه اندازه میتواند از منابع سختافزاری سیستم
اســتفاده کنــد و اینکه آیا محدودیتی در اســتفاده از منابع دارد یــا خیر .برای مثال در خروجی دســتور باال،
استریسک میتواند ماکزیمم تا 1024فایل همزمان را باز کند ولی بیشتر از آن با محدودیت مواجه میشود.
سوالی که ممکن است در اینجا پیش آید این است که منظور از max open filesچیست؟ بگذارید سوال
را به شــکل دیگری مطرح کنیم .ممکن است در شــرایطی ما هیچ محدودیتی در استفاده از منابع سختافزاری
نداشتهباشیم ولی باز هم نتوانیم حداکثر استفاده از منابع سختافزاری را در سرور داشته باشیم .در چنین شرایطی
اگر به logهای استریسک مراجعه کنیم متوجه خطاهایی به شکل زیر میشویم:
[2016-05-08 13:33:03] ERROR [10723] acl.c: Cannot create socket
[2016-05-08 13:33:03] ERROR[10723] rtp.c: Unable to allocate socket: Too many open files
[2016-05-08 13:33:03] ERROR [10723]: create_new_socket: Unable to allocate RTP socket:
Too many open files
10723 [2016-05-08 13:33:03] WARNING[657] chan_sip.c: Unable to create RTP audio and
video session: Too many open file
همانطورکه مالحظه میکنید استریسک نمیتواند فایلهای بیشتری را باز کند .اکنون این سوال پیش میآید
که استریســک در چه مواقعی این فایلها را باز میکند .پاســخ این ســوال روشن اســت .استریسک برای هر
مکالمه صوتی 5فایل (یا پورت) در نظر میگیرد.
)maxfiles=(active calls)*(2+2+1
استریسک در هر مکالمه صوتی 2 ،پورت فعال برای RTPو 2پورت فعال برای کنترل جریان ترافیکی RTCP
و یک پورت اضافی برای overheadدر نظر میگیرد .پس برای مثال اگر بخواهیم روی ســروری 300تماس
77 نصب و راهاندازی استریسک
لذا اگر مقدار پارامتر ( max open files=1024مقدار پیش فرض) باشد ،نمیتوانیم به حداکثر تعداد تماس مورد
نیاز در این شرایط برسیم .ما میتوانیم پارامتر maxcallsرا در بخش [ ]optionsرا بهصورت زیر تغییر دهیم:
;asterisk.conf
][options
maxcalls = 10
یکی دیگر از پارامترهای مهم در بخش [ ،]optionsپارامتر execincludesاســت که میتواند مفید باشــد .برای
مثال فرض کنید بخواهیم تعداد زیادی کاربر در سیستم تلفنی استریسک ایجاد کنیم .در این حالت میتوانیم از
این قابلیت در استریســک بهره ببریم .برای مثال فرض کنید برنامهی 1 bash scriptبه صورت زیر برای تعریف
1000کاربر داشتهباشیم.
#vim create_users.sh
#!/bin/bash
")!(]echo "[user
"echo "deny = 0.0.0.0/0.0.0.0
"echo "permit = 0.0.0.0/0.0.0.0
"echo "qualify = yes
"echo "host = dynamic
"echo "nat = force_rport,comedia
"echo "port = 5060
"echo "type = friend
"echo "context = tci
"echo "disallow = all
"echo "allow = ulaw,alaw
"echo "canreinvite = no
"echo "directmedia = no
}for i in {1000..1010
do
")echo "[$i](user
"echo "secret=123123
done
از متدوال ترین و رایج ترین روشهای برنامه نویسی در لینوکس است. bash script -1
مرجع آموزش ویپ با سافتسوئیچ استریسک 78
اکنون با realodشدن استریسک ،فایل create_users.shاجرا میشود و خروجی آن در انتهای فایل sip.conf
قرار میگیرد .با این روش شما میتوانید بهراحتی تعداد زیادی کاربر در استریسک ایجاد کنید .این روش تنها
برای ایجاد کاربر مفید نیست بلکه میتوانید با استفاده از این روش تمام پیکربندی استریسک را انجام دهید.
در این فایل کلمات کلیدیای وجود دارد که هر کدام معنای خاص خودش را دارد .در ادامه به معرفی این
کلمات کلیدی میپردازیم.
: autoloadهمه ماژولهایی که در مسیر نصب ماژولهای استریسک وجود دارند ( )/var/lib/asterisk/modules
به ترتیب بارگذاری میشوند.
][modules
autoload=yes
: preloadگاهی ممکن اســت بارگذاری برخی ماژولها وابســته به بارگذاری ماژولهای دیگری باشد که نیاز
است این ماژولها را قبال به سیستم معرفی کنیم .با این دستور میتوان این معرفی را انجام داد.
][modules
preload => chan_sip.so
: loadدستور بارگذاری ماژول مربوطه را صادر میکند )autoload=yes( .همین کار را برای همه ماژول ها انجام
میدهد.
][modules
load => chan_sip.so
: noloadاجازه نمیدهد ماژول بارگذاری شود و در صورت بارگذاری ،آن را غیر فعال میکند.
][modules
noload => chan_sip.so
: requireدر چنین شــرایطی اگر ماژولی بنا به دالیلی بارگذاری نشود ،استریسک راهاندازی نخواهد شد .برای
مثال فرض کنید بخواهیم چنانچه ماژول chan_sip.soدر استریســک بارگذاری نشد ،استریسک هم راهاندازی
نشود .در این صورت باید ماژول chan_sip.soرا به صورت زیر فعال کنیم.
][modules
require => chan_sip.so
79 نصب و راهاندازی استریسک
برای هر کدام از این toneها ،میتوان الگویی تعریف کرد و در سیســتم تلفنی استریســک بهکار گرفت .برای
مثال در فایل indications.confالگوهای متفاوتی برای این پارامترها بر اساس کشورهای مختلف تعریف شده
است .با دستور زیر این فایل را باز نمایید:
#vim /etc/asterisk/indications.conf
به صورت پیش فرض در استریســک ،این الگوها بر اســاس کشور USتعریف شــدهاند ولی میتوانید در فایل
indications.confاز قسمت [ ]generalآن را تغییر دهید.
][general
country=us
این تغییر روی کل سیستم اعمال میشود .گاهی الزم میشود سوئیچی طراحی کنید که براساس کالر آی دی،
tonezoneرا عوض کند .در این حالت باید از تابع CHANNELدر برنامهنویسی استریسک استفادهکنید.
Same => n,Set(CHANNEL(tonezone)=[yourcountry]) ; i.e., uk, de, etc.
در فصلهای آینده درباره برنامهنویسی در استریسک به تفصیل توضیح داده میشود.
به عنوان یک نمونه جالب فرض کنید خواسته باشیم از آهنگ خاصی برای ringtoneدر سیستم تلفنی خود
اســتفاده نماییم (در این مثال از آهنگ زیبای “ ”starwarsاســتفاده میکنیم ) .در این صورت نخست باید یک
بخش جدید به نام [ ]starwarsایجاد و سپس آن را بهصورت زیر تعریف کنیم:
[starwars](us) description = Star Wars Theme Song
ring = 262/400,392/500,0/100,349/400,330/400,294/400,524/400,392/500,0/100, 349/400,3
30/400,294/400,524/400,392/500,0/100,349/400,330/400,349/400, 294/500,0/2000
اکنون فرض کنید بخواهیم از این آهنگ در برنامه خود در استریســک اســتفاده کنیم .یک نمونه از این نوع
برنامهنویسی در استریسک میتواند بهصورت زیر باشد:
)(exten => 1234,1,Answer
)same => n,Set(CHANNEL(tonezone)=starwars
)same => n,Dial(SIP/Phone1
حالت برای آنها موزیک خاصی پخش میشــود .در استریســک بهمنظور پیکربندی موزیــک انتظار ،از فایل
musiconhold.confاستفاده میکنیم .برای باز کردن این فایل دستور زیر را اجرا کنید:
#vim /etc/asterisk/musiconhold.conf
با اجرای دستور فوق ،محتویات پیکربندی فایل موزیک انتظار را مشاهده میکنید .میتوان از موزیک انتظارهای
متفاوتی در استریسک استفاده نمود .به عنوان مثال در این فایل یک موزیک انتظار پیش فرض به نام []default
تعریف شدهاست .میتوانید هر نوع موزیک انتظاری با نام دلخواه را در این فایل ایجاد کنید .در مثال زیر یک
موزیک انتظار با نام [ ]myfavoriteایجاد میکنیم.
][myfavorite
mode=files
sort=alpha
announcement=queue-thankyou
directory=/usr/src/myfavorite/
در زمــان تعریف یــک موزیک انتظار ،عالوه بر نام دلخــواه باید پارامترهایی را نیــز مقداردهی کنید .انواع
پارامترهای مورد نظر از قرار زیرند:
: modeبا این پارامتر مشخص میکنیم که موزیک انتظار قرار است از طریق فایل سیستم انتخاب و سپس اجرا
شــود .در این حالت مقدار پارامتر files ،خواهد بود .همچنین میتوان از برنامههای پخش زنده ( )streamدر
موزیک انتظار استفاده نمود؛ مثال برنامههایی که رادیو را بهصورت زنده پخش میکنند .در این حالت باید مقدار
این پارامتر را روی customقرار دهید.
: directoryدر صورتی که پارامتر mode = filesتنظیم کرده باشیم ،باید مسیر فایلهای صوتی که قرار است
پخش شــوند را مشخص کنیم .بهصورت پیش فرض مسیر فایلهای صوتی برای موزیک انتظار به صورت زیر
است:
# ls /var/lib/asterisk/moh/
میتوانید در هر مسیری از فایل سیستم لینوکس ،فایلهای صوتی خود را قرار دهید و آدرس آنها را در این
پارامتر درج کنید .در مثال فوق ما از مسیر دیگری برای پخش فایلهای صوتی استفاده نمودیم.
: announcementمیتوان بین موزیک انتظارها یک اعالن برای مشترک پخش نمود .این اعالن با این پارامتر
مشخص میشود .در مثال فوق بین هر موزیک انتظار ،اعالن « »queue-thankyouپخش میشود.
: sortتوسط این پارامتر موزیک انتظارها به ترتیب حروف الفبا پخش میشوند.
: applicationدرصورتیکه پارامتر mode=customتنظیم شــده باشد ،میتوان نام برنامهی پخش streamرا
در اینجا عنوان نمود .برای مثال فرض کنید برنامهای به نام streamplayerوجود دارد ،تنظیمات بهصورت زیر
81 نصب و راهاندازی استریسک
خواهد بود:
application=/usr/bin/streamplayer 172.16.0.100 888
در این حالت بهجای پخش موزیک از فایل ،برنامه اجرا و جریانهای streamپخش میشوند.
: formatاگر از اســتریمهای آنالین استفاده کنیم ( ،)mode=customباید نوع فرمت استریم دریافتی را برای
استریسک مشخص کنیم.
format=ulaw,alaw
نتیجهگیری
در این فصل نصب استریسک و نیازمندیهای آن توضیح داده شد .همچنین برای ارتباط استریسک با شبکههای
مخابراتی ،PSTNبستههای DAHDIو LibPRIنیز نصب شدند .در ادامه در خصوص پیکربندی اولیه استریسک
و آشــنایی با فایلهای مهم در استریســک صحبت شــد .در فصلهای بعدی روی قابلیتها و انواع ماژولهای
استریسک تمرکز میکنیم و پیرامون برنامهنویسی در استریسک توضیح خواهیم داد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 82
فصل چهارم
مقدمه
در یک شــبکهی ویپ ،تجهیزاتی وجود دارد که هر یک به نحوی باید با سیســتم تلفنی استریسک در تعامل
باشــد و کار کنــد .در این فصل بیشــتر روی نحــوه ارتباط با این نــوع از تجهیزات و ارتباط آنها با سیســتم
تلفنی استریســک تمرکز خواهیم داشــت« .ارتباط» در اینجا به این معنی اســت که چگونــه تجهیزات تلفنی
باید درخواســت خود را برای استریســک ارســال کنند و استریســک چگونه باید آن را پــردازش کند و به
درخواستها پاسخ دهد.
شکل 1-4
)2فرآیند انتقال تماس ازطریق سیستم تلفنی استریسک به تلفن مقصد .شکل 2-4این فرآیند را نشان میدهد.
85 پیکربندی تجهیزات در شبکههای ویپ
شکل 2-4
این فرآیندها به کمک پروتکل ســیگنالینگ 1 SIPمدیریت و کنترل میشــود .پروتکل SIPیک پروتکل در
الیهی کاربردی 2مدل OSIدر شــبکه اســت که فرآیندهای تولید ،3کنترل ،مدیریــت 4و خاتمهی تماسها 5را
بهعهده دارد.
برای مثال شکل 3-4فرایند ایجاد تماس در پروتکل SIPبین دو کالینت ( 6)UAرا نشان میدهد.
شکل 3-4
2
مفاهیم نامگذاری تلفنها در شبکههای ویپ
در مخابرات امروزی ،تلفنها را معموالً با نام شماره آنها 3معرفی میکنیم؛ به این معنی که هر شمارهای که به
یک مشترک اختصاص دارد و به عنوان یک عضو واحد و منحصر به فرد در شبکه مخابراتی معرفی میگردد.
اما در شــبکههای ویپ این مفهوم بســیار فراتر است .برای مثال یک اکستنشن میتواند یک شماره اختصاص
داده شــده به یک مشترک باشــد ،یا میتواند به عنوان بخشی از عملیات محاســباتی برای اجرای یک برنامه
در استریسک باشد .همچنین میتواند بخشی از اجرای یک برنامه کاربردی همچون صندوق صوتی باشد.
برای روشنتر شدن مطلب اجازه دهید با یک مثال ساده ،قواعد نامگذاری را شرح دهیم .همهی ما میدانیم
که Numberingدر شبکههای مخابراتی ،PSTNبه شماره مشتریان مخابرات اطالق میگردد .به عبارت دیگر،
هر شماره 8رقمی که در سیستم مخابراتی تعریف شدهباشد ،متعلق به مشترکی است که ازطریق یک زوج سیم
به شــبکه مخابراتی کشور متصل است .اما در شــبکههای مخابراتی نسل جدید ،این موضوع فراتر از شبکههای
مخابراتی PSTNاست .ممکن است شمارهای را درشبکههای ویپ شمارهگیری نمایید که بواسطه آن یکسری
روال محاســباتی در سیستم اجرا شود و حتی با گرفتن یک شماره ،یک تابع فراخوانی گردد .این شمارهها یا به
عبارت دیگر اکستنشــنها متعلق به هیچ مشترکی در شبکه نیستند ،بلکه با شــمارهگیری آنها (فراخوان آنها)،
فرآیندهای محاســباتی از قبل تعریف شــده ،اجرا میشوند .برای مثال سیســتمهای پرداخت تلفنی ،سیستمهای
نوبتدهی و مانند اینها ،همگی از جمله سرویسهای ارزش افزوده 4در شبکههای ویپ هستند.
1- Real Time Protocol
2- Telephony Naming Concepts
3- Extensions
)4- Value Added Services (VAS
87 پیکربندی تجهیزات در شبکههای ویپ
شکل 4-4
در شــبکههای ویپ این قابلیت وجود دارد که بتوانیم با URLموجودیتهای یکتا و منحصر به فردی ایجاد
کنیم و ســپس ازطریق این موجودیت یکتا تماسهایی برقرار کنیم .این شناســه در شــبکههای نســل ( )IMS
جدید با عنوان IMPI1شــناخته میشود .برای مثال کاربران در شــبکههای نسل جدید میتوانند IMPIهایی
بهصورت زیر داشته باشند.
sip:bob@domain1.com
sip:alice@domain2.com
sip:tom@domain3.com
توضیح بیشتر در خصوص شبکههای مخابراتی IMSاز حوصله کتاب خارج است.
:Hardphonesمنظور همان IPPhoneهایی اســت که بهصورت مستقل و از طریق کابل شبکه به سرور ویپ
متصل میشوند .شکل 5-4برخی از انواع گوشیهای IPPhoneرا نشان میدهد.
شکل 5-4
از جمله مزایای این تجهیزات میتوان بهموارد زیر اشاره کرد:
1- IP Multimedia Private Identity
مرجع آموزش ویپ با سافتسوئیچ استریسک 88
.۱کلیدهای میانبر :کلیدهای میانبر در IP Phoneها ،این امکان را بهوجود میآورند که شماری از وظایفی
کــه باید به کمک چند عدد انجام شــوند را تنها با فشــردن یــک دکمه اجرا نمود .ازجملــه این دکمههای
میانبــر ،میتوان به دکمههای ، Transferکنفرانس ،ولوم صدا Mute ، Hold ،و دکمههای قابل برنامهریزی
) BLF (Busy Lamp Fieldاشاره کرد.
.۲امکان نمایش و ارسال پیامهای متنی.
.۳امکان استفاده از افزایندهها با هدف تعداد BLFبیشتر.
Intercomدربعضی از IP .4امکان اســتفاده از Auto answerبرای کاربردهای خاص ،ازجمله pagingو
phoneها.
.5این تجهیزات وابســتگی به مکان ندارند .کافی اســت داخلی موردنظر را به مکان دیگری ببریم و از همان
داخلی در مکان جدید استفاده نماییم.
IP Phone .۶ها پایداری نسبتا باالیی دارند.
از جمله معایب این تجهیزات ،میتوان به موارد زیر اشاره نمود:
.1این مدل گوشیها نسبت به گوشیهای قدیمیتر ،هزینه باالتری دارند.
.2در این مدل ،امکان تطبیق گوشیهای قدیمی و گوشیهای جدید وجود ندارد.
:Softphonesمنظور از Softphoneنرم افزارهایی هســتند که میتوانید آنها را در سیســتم عاملهای مختلف از
قبیل ویندوز ،اندروید و ...نصب کنید و از طریق آنها به سرور شبکه ویپ متصل شوید .تصویر 6-4چند نمونه
از Softphoneها را نشان میدهد.
شکل 6-4
از جمله مزایای این تجهیزات میتوان به موارد زیر اشاره کرد:
.۱ایــن نرمافزارها معموالً خدمات اولیه را رایــگان ارائه میدهند و برای کارهای عمومی رایگاناند و برای
تمام پلتفرمها نیز موجودند ،اما قابلیتهای خاص آنها مستلزم تأمین هزینه است.
89 پیکربندی تجهیزات در شبکههای ویپ
.۳در برخــی نرمافزارها میتوان میانبرهایی برای شــمارهگیری ســریع تعریف کرد کــه تعداد آنها به نوع
نرمافزار مربوطه بستگی دارد.
.4توانایــی مکالمــه تصویری برای تعدادی از ایــن نرمافزارها به رایگان فراهم اســت و برخی هم در ازای
پرداخت وجه اندکی به این امکان مجهز میشوند.
.۵ارسال و دریافت آسانتر پیامها در این نرمافزارها ،به دلیل برخورداری از صفحهکلید کامپیوتری.
Volumeدر این نرمافزارها. .۶برخورداری از کلیدهای میانبر خاص از جمله Mute ،Hold ،Transferو
.7این نرمافزارها به منظور ارائه خدمات پورتابل ،میتوانند روی موبایل یا لپتاپ نصب شوند.
از جمله معایب این سیستم میتوان به موارد زیر اشاره کرد:
.1سطح اطمینان ناکافی در نرمافزار به دالیلی از جمله وابستگی به سیستم عامل.
.2عدم پشتیبانی از گوشیهای قدیمی با توجه به ساختار آنها.
:Gatewayمبدلهایی هســتند که در ظرفیتهای باال ارائه میشوند؛ مثل . FXO-GW، FXS-GW، E1-GW
چند نمونه Gatewayدر شکل 7-4ارائه شده است.
شکل 7-4
.4در این نوع دستگاهها ،میتوان از کلیدهای ترکیبی برای استفاده از آپشنهای ویپ استفاده نمود ،ازجمله
Transferو. ... ، Wait
.۵این دستگاهها بهدلیل سرویسدهی به حجم باالیی از ارتباطات در یک مکان ،امکان جابجایی ندارند.
:1 ATAمبدلهایی هستند که از طریق آنها ،تلفنهای آنالوگ معمولی به شبکههای ویپ متصل میشوند .چند
نمونه ATAدر شکل 8-4ارائه شده است.
شکل 8-4
ATAها از خانواده گیتویها هســتند که مزایا و معایب آن در بخش مربوط به گیتویها بیان شــد.ازجمله
مزایا و معایب این تجهیزات نسبت به گیتویها ،میتوان به موارد زیر اشاره کرد:
.۱هزینه نسبتاً پایین راهاندازی سیستم.
.۲سازگاری با شبکههای قدیمی و قابلیت جابجایی.
از معایب آنها هم میتوان به کانفیگ جزیرهای اشــاره نمود .برای مثال اگر نیاز به کانفیگ سراسری باشد،
باید دستگاهای مختلفی را تنظیم نمایید ،درحالیکه گیتویها را با یک اینترفیس هم میتوانید تنظیم کنید.
تعریف یک کاربر جدید از نوع SIPشــامل یک فرمت اســتاندارد با پارامترهای مشخص است که در ادامه هر
یک از موارد فوق را شرح خواهیم داد.
1- SIP User
2- SIP Password
3- SIP Server
مرجع آموزش ویپ با سافتسوئیچ استریسک 92
پارامتر : denyبا این پارامتر اجازه دسترسی و رجیستر شدن از طریق IPمشخص شده ،سلب میشود.
پارامتر : permitبا این پارامتر ،اجازه دسترسی و رجیستر شدن از IPمشخص شده ،داده میشود.
پارامتر : contextبا این پارامتر ،کانتکست داخلی تعریف میشود که در فصول بعد توضیح داده میشود.
پارامتر : hostاین گزینه معرف آدرس دسترســی به کاربران و داخلیها اســت کــه در صورت تعریفکردن
بصورت ، dynamicکاربر میتواند از هر آدرسی به سیستم تلفنی استریسک رجیستر شود.
پارامتر : typeبا این پارامتر نوع داخلی مورد نظر مشخص میشود .برای مثال شکل 9-4را ببینید.
شکل 9-4
اگر از کدک فشردهسازی در انتقال جریانهای RTPاستفاده کنید DTMF ،تغییر کرده و قابل تشخیص
نخواهد بود.
:rfc2833 .۲این استاندارد همانند استاندارد inbandاست ولی مستقل از کدکهای تعریف شده برای
جریانهای دادهای RTPاست.
:info .۳در این اســتاندارد DTMF ،بهصورت پیامهای ســیگنالینگ ) (SIP info DTMFو مســتقل از
جریانهای دادهای RTPارسال میشد.
:auto .4استریســک بهصــورت پیشفــرض از اســتاندارد rfc2833اســتفاده میکنــد .اگــر ســمت
دیگر)مخاطب( ،این استاندارد را نپذیرد ،آن را به inbandتغییر میدهد.
همانطور که مالحظه میکنید اکثر پارامترها شــبیه تعریف کاربر از نوع SIPاســت .در ادامه سایر پارامترها را
نیز معرفی خواهیم کرد.
پارامتر :transferاین پارامتر شــبیه پارامترهای canreinviteو ( directmediaفصل هفتم) در تعریف کاربر
از نوع پروتکل SIPاســت .با این پارامتر میتوان مشــخص کرد که جریانهای ترافیکی مدیا مستقیما بین دو
کاربر منتقل میشوند .این پارامتر میتواند مقادیر زیر را داشته باشید:
مرجع آموزش ویپ با سافتسوئیچ استریسک 94
: yes .1در این حالت استریسک تالش میکند که جریان های سیگنالینگ و مدیا بین دو کاربر مستقیما
منتقل شــوند .پرواضح است که اگر بین دو کاربر نیاز به transcodingوجود داشته باشد ،این کار انجام
نخواهد شد.
: no .2در این حالت استریسک جریان های سیگنالیگ و مدیا بین دو کاربر را از خود عبور میدهد.
: mediaonly .3در ایــن حالــت استریســک فقط جریان های ســیگنالینگ را از خــود عبور میدهد و
جریانهای مدیا بین دو کاربر مستقیما منتقل میشوند .در این حالت استریسک میتواند گزارشات CDR
را داشته باشد.
1
قالبها
از آنجاکه فرمت تعریف کاربران در اکثر پارامترها مشــابه اســت ،میتوانیم این پارامترهای مشابه را در یک
قالب تعریف کنیم و ســپس در هنگام تعریف کاربران جدید ،از آنها اســتفاده نماییم .برای تعریف قالب از
عالمت (!) استفاده میکنیم .به عنوان مثال در ساخت داخلی میتوانیم به این شکل عمل کنیم.
;sip.conf
)!(][users
deny=0.0.0.0/0.0.0.0
permit=0.0.0.0/0.0.0.0
context = LocalSets
host=dynamic
type=friend
nat=force_rport,comedia
qualify=yes
dtmfmode=rfc2833
اکنون برای تعریف کردن کاربرهای جدید ،آن را به صورت زیر تعریف میکنیم.
;sip.conf
)[Phone_1](users
>callerid = Phone_1 <1000
secret=123123
)[Phone_2](users
>callerid = Phone_2 <1000
secret=123123
context=myContext
در این روش ،فقط پارامترهایی را مینویسیم که یا میخواهیم مقدار آنها تغییر کند و یا در قالب وجود ندارد.
بــرای مثال در هر دو کاربر پارامتــر secretرا تعریف کردهایم ،چون این پارامتــر در قالب ] [usersتعریف
1- Templates
95 پیکربندی تجهیزات در شبکههای ویپ
نشدهاست .همچنین در هنگام تعریف کاربر ، Phone_2پارامتر contextرا دوباره تعریف کردهایم .در این
حالت این مقدار جدید با مقدار قبلی تعریف شده در قالب جایگزین میشود.
بعد از تعریف داخلی جدید در استریســک ،باید حتما ماژول های مربوطه را reloadکنیم تا استریســک
بتواند داخلیهای جدید را بشناسد .برای این منظور میتوانید از محیط کامند الین استریسک استفاده نمایید.
#asterisk –r
CLI> sip reload
)1زمانی که یک داخلی بخواهد به سیســتم تلفنی استریســک رجیستر شود .در این حالت پیام REGISTERاز
طرف کاربر برای استریسک ارسال میشود و استریسک عملیات اعتبار سنجی را انجام میدهد.
)2زمانی که یک داخلی تمایل به ایجاد یک تماس خروجی داشتهباشد ،در این حالت یک پیام INVITEبرای
2
نتیجهگیری
در این فصل در خصوص معرفی انواع تجهیزات مورد نیاز در شبکههای ویپ توضیح داده شد و هر یک به
اختصار بررســی گردید .همچنین توضیح داده شد که در سیستم تلفنی استریسک چگونه میتوان کاربرهای
جدید تعریف نمود .بعد از تعریف کاربرهای جدید ،باید بتوان از آنها اســتفاده و داخلیها را رجیستر نمود.
به این منظور ابتدا باید تغییرات انجام شده در استریسک ثبت و ماژولهای مربوطه reloadشوند .دست آخر
عملیات اعتبارســنجی در استریســک بررسی شد و توضیح داده شــد که استریسک در چه زمانهایی از آن
استفاده میکند.
فصل پنجم
برنامهنویسی مقدماتی در استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 98
1- dialplan
2- role
99 برنامهنویسی مقدماتی در استریسک
;extensions.ael
{ context defualt
{ >= 100
;)Playback(please-hold
;)Dial(IAX2/203,60
}
{ >= 101
;)Dial(SIP/101,60
}
---------------------------------
;extensions.lua
{ = extensions
{= default
)[“100”] = function(function,extension
)”app.playback(“please-hold
)app.dial(“IAX2/203”,60
)[“101”] = function(function,extension
)app.dial(“SIP/101”,60
;end
در استریسک میتوان از هر سه روش در برنامهنویسی استفاده کرد .آنچه در این کتاب بیشتر به آن میپردازیم،
برنامهنویســی به روش اول و استفاده از فایل extensions.confاست .استفاده از سایر روشهای برنامهنویسی
در استریسک به خواننده کتاب واگذار میشود.
در سیســتم تلفنی استریسک فایل extensions.confبرای تنظیمات و پیکربندی برنامهها و رولها در نظر
گرفتهشده است که در ادامه درباره ساختار و بدنه این فایل توضیحات بیشتری آمده است.
اگر فایل extensions.confرا با یک ویرایشــگر لینوکس مانند vimیا nanoباز کنید ،در نگاه اول متوجه
که ساختار هر خط در این فایل از دو قسمت اصلی تشکیل شده که به صورت زیر است: میشوید
][context
exten => extensions,priority,application
برای مثال شــکل ۱-۵را در نظر بگیرید .در کانتکســت ] [demoتمامی اکستنشنهای تعریف شده ،این
قابلیت را دارند که با هم در ارتباط باشند ،ولی اکستنشن های کانتکست ] [demoنمیتوانند با اکستنشن های
تعریف شده در کانتکست ] [defaultدر ارتباط باشند.
شکل 1-5
ما نمیتوانیم در یک کانتکســت برای یک اکستنشــن ،دو رول تعریف کنیم .برای مثال برنامه زیر را در نظر
بگیرید:
][demo1
)exten => 100,1,Playback(hello-world
)exten => 200,1,Playback(hello-world
)exten => 100,1,Dial(SIP/100
][demo3
)exten => 200,1,Dial(SIP/200
)exten => 300,1,Dial(SIP/300
)exten => 400,1,Dial(SIP/400
)exten => 500,1,Dial(SIP/500
همانطورکــه مالحظــه میکنید هر بخش به صــورت کام ً
ال مســتقل تعریف میگردد و هیــچ ارتباطی بین
101 برنامهنویسی مقدماتی در استریسک
بخشها وجود ندارد .میتوان در بخشهای مختلف در صورت لزوم از اکستنشنهای همنام نیز استفاده کرد.
ال متفاوت در دو کانتکست مستقل همانطورکه در مثال باال دیده میشود ،برای اکستنشن ، 300دو رول کام ً
از هم وجود دارد.
نامگذاری کانتکســتها کامــ ً
ا اختیاری و آزادانهاند ،ولی در تعریف و نامگــذاری آنها باید از قواعد
خاص آنها تبعیت کنیم .لذا موارد زیر باید در تعریف نام کانتکست رعایت شود:
-اسم کانتکست باید بین عالمت [ ] قرار بگیرد.
-اسم کانتکست میتواند ترکیبی از A-Z, a-z, 0-9باشد.
-حداکثر طول نام کانتکست نمیتواند بیش از 80کاراکتر باشد.
-نام کانتکســت های پیشفرض در استریســک [ ]general], [globalsو [ ]defaultاســت؛ ترجیحاً از این اسامی
استفاده نشود.
: Nameنام یا شــماره داخلی اکستنشــن برنامه مورد نظر است که باید در هر کانتکست یکتا و منحصر به فرد
باشد.
: Priorityهر اکستنشن میتواند ترکیبی از برنامههای مختلف باشد و مرحله به مرحله و به ترتیب اجرا شود.
با این پارامتر اولویت اجرایی ترتیب دستورات مشخص میشود.
: Applicationبرنامهای اســت که باید بوسیله سیســتم تلفنی استریسک اجرا شود .استریسک از دستورات و
توابع بسیاری استفاده میکند که هرکدام بوسیله ماژولهایی به استریسک اضافه شدهاند .در ادامهی این فصل
و فصلهای آینده با این دستورات و توابع آشنایی بیشتری پیدا خواهید کرد.
به عنوان یک مثال ساده فرضکنید تصمیم داریم اولین برنامه خود را در استریسک بنویسیم ،به گونهای که
اگر کاربر عدد 123را شمارهگیری کرد ،پیام صوتی Hello-worldبرایش پخش شود .برای این منظور نخست
مرجع آموزش ویپ با سافتسوئیچ استریسک 102
بعد از اضافه کردن موارد فوق ،به محیط استریسک بروید و ماژول chan_sip.soرا مجددا reloadکنید.
CLI> module reload chan_sip.so
در استریسک ایجاد کردیم؛ اکنون با دستور زیر میتوانید از صحت تا اینجا ما یک کاربر به نام 0000FFFF0001
اکنون کافی است بوسیله یک سافتفون رجیستر شویم .برای رجیستر شدن ،اطالعات نام کاربری ،رمز عبور
و آی پی ســرور ،مورد نیاز اســت .بعد از رجیسترشدن ،با اجرای دســتور قبلی ،خروجی به صورت زیر نشان
داده میشود:
CLI> sip show peers
Name/username Host Dyn Forcerport ACL Port Status Description
0000FFFF0001 192.168.1.111 D N )A 5060 OK (107 ms
در مرحله بعد باید برنامه موردنظرمان را در استریســک بنویســیم .ازآنجاکه از فایل extensions.confبرای
103 برنامهنویسی مقدماتی در استریسک
نوشتن برنامهها در استریسک استفاده میکنیم ،باید نخست فایل را باز و دستورات زیر را به انتهای آن اضافه
کنید.
#vim /etc/asterisk/extensions.conf
][LocalSets
)(exten => 123,1,Answer
)exten => 123,2,Playback(hello-world
)(exten => 123,3,Hangup
بعد از اعمال تغییرات فوق ،به محیط کامند الین استریسک رفته و ابتدا دستور زیر را اجرا کنید.
CLI> dialplan reload
اجرای دســتور فوق باعث میشود که تغییرات اعمال شده در فایل extensions.confو سایر فایلهای وابسته
به آن ،بوسیله استریسک ثبت شود .اگر تجربه کار با سیستم تلفنی الستیکس را دارید ،با انجام هر تغییری در
آن ،باید گزینه “ ”apply changesرا در محیط وب کلیک کنید .در واقع با این کار شــما این دســتور را در
استریسک اجرا میکنید.
CLI> core reload
تا اینجا ،هم کاربر جدید ساختیم و هم برنامهای برای آن تعریف نمودیم .سؤالی که ممکن است اینجا پرسیده
شــود این اســت که چه ارتباطی میان ساختن فایل در sip.confو رولهای تعریف شده در فایل extensions.
confوجود دارد؟
اجازه بدهید این سوال را با شکل 2-5توضیح دهیم:
شکل 2-5
همانطورکــه مالحظه میکنید در این شــکل ،کاربری از نــوع sipدر فایل sip.confتعریف شدهاســت و در
تعریف کاربر مقدار Context=localSetsتنظیم شدهاســت .معنای این پارامتر این اســت که حوزه فعالیتها و
مجوز دسترسی برای کاربر 0000FFFF0001در کانتکست [ ]localsetsتعریف شده است .مالحظه میشود که
در کانتکست [ ]localSetsفقط یک رول تعریف شدهاست ،آن هم مربوط به 123است .در این صورت اگر از
طرف این کاربر عدد 123ارسال شود ،فایل صوتی hello-worldاجرا میشود
مرجع آموزش ویپ با سافتسوئیچ استریسک 104
نکته مهم در اینجا نحوه ارتباط و تعریف ســطوح دسترســی و عملکرد کاربران در سیســتم تلفنی است.
میتوانیم این ســطح امنیتی را در هنگام تعریف رولها در کانتکســت مربوطــه در نظر بگیریم .همانطورکه
مالحظه میکنید سطح دسترسی این کاربر محدود به حوزهی کانتکستی است که در زمان تعریف کاربر در
پارامتر contextمشخص شدهاست.
در ادامه مثالهای بیشــتری در زمینه برنامهنویسی استریســک خواهد آمد .برای مثال قطعه کد زیر را در
نظر بگیرید:
)(exten => 124,1,Answer
ما یک اکستنشن به نام 124تعریف کردهایم که اولویت اول آن ،اجرای دستور Answerاست .با اجرای
این برنامه ،استریسک به تماس ورودی 124پاسخ میدهد یا به اصطالح آن را Answerمیکند .همانطورکه
مالحظه میکنید اجرای دستورات با اولویت 1شروع میشود .اگر خواسته باشیم چندین دستور را پشت سر
هم اجرا کنیم ،باید اولویت اجرای دستورات را یک به یک افزایش دهیم .برای مثال فرض کنید اجرای چند
دستور را میخواهیم برنامهنویسی کنیم:
)(exten => 124,1,Answer
exten => 124,2, do something
exten => 124,3, do something else
exten => 124,4, do one last thing
)(exten => 124,5,Hangup
همانطورکه مالحظه میکنید پنج دســتور برای اکستنشن 124تعریف کردهایم که با شمارهگیری ،124این
دستورات به ترتیب اولویت از 1تا 5اجرا میشوند.
دقت شــود که ترتیب و توالی دســتورات بسیار مهم اســت و حتما باید اولویت دستورات ،پشت سرهم
بهصورت «تک واحدی» افزایش یابد.
برای مثال دستورات زیر را در نظر بگیرید:
)exten => 124,1,NoOp(This is my first dialplan in asterisk PBX
)(exten => 124,2,Answer
)exten => 124,3,Wait(5
)exten => 124,4,Playback(demo-congrats
)(exten => 124,5,Hangup
همانطورکه مالحظه میکنید با شــمارهگیری ،124ابتدا دســتور 1 NoOpاجرا میشــود .همان طور که از
اســم آن پیداست این دســتور هیچ کاری انجام نمیدهد بلکه فقط عبارتی که جلوی آن باشد را در خروجی
استریســک در زمان اجرا ،نمایش میدهد .از این دستور و دستور Verboseبرای خطایابی و مشاهده الگها
در محیط کنسول استریسک استفاده میشود .در اولویت بعدی ،تماس بوسیله استریسک پاسخ داده میشود،
1- No Operation
105 برنامهنویسی مقدماتی در استریسک
ســپس تماس جاری به مدت 5ثانیه متوقف میشــود .بعد از 5ثانیه ،فایل صوتی demo-congratsبوســیله
دستور Playbackاجرا میشود .در نهایت تماس توسط دستور hangupدر استریسک قطع میشود.
فرض کنید بخواهیم با کاربر Bobتماس بگیریم .میتوانیم از دستورات زیر در برنامه استفاده کنیم:
)exten => 125,1,Dial(SIP/Bob,45
)exten => 125,2,Playback(sorry
)(exten => 125,3,Hangup
در این صورت اگر شــماره 125را شمارهگیری کنیم ،ابتدا کاربر bobبه مدت 45ثانیه زنگ میخورد .اگر
bobدر این مدت تماس را پاسخ ندهد آنگاه اولویت اجرا به خط بعدی رفته و پیام sorryپخش خواهد شد،
سپس تماس قطع میشود.
همانطورکه پیشتر نیز اشــاره شد ،ترتیب اجرای دستورات بر اســاس اولویت مشخص میشود .فرض
کنید دستورات زیر را داشته باشیم:
)(exten => 124,1,Answer
exten => 124,2, do something
exten => 124,3, do something else
.
.
.
exten => 124,100, do one last thing
اکنون فرض کنید دســتوری را بخواهیم در اولویت 51اضافه کنیم؛ واضح اســت که باید تمامی اولویتها را
تا انتها ،یک واحد افزایش دهیم .مســلماً این کار کمی سخت و طاقتفرسا بهنظر میرسد و چندان خوشایند
نیست .برای جلوگیری از اینگونه موارد از اولویت nدر برنامهنویسی استفاده میکنیم.
)(exten => 124,1,Answer
exten => 124,n, do something
exten => 124,n, do something else
.
.
.
exten => 124,n, do one last thing
همانطورکه مالحظه میکنید به جز دســتور اول ،از اولویت nدر برنامهنویسی استفاده کردیم .در این حالت
چنانچه تغییری در بدنه Dialplanدر هر قســمت (در هر اولویتی) ایجاد شود ،به راحتی میتوان آن را اضافه
یا حذف کرد و نیازی به تغییر اولویتها نیســت .در این صورت همه دســتورات به صورت خط به خط اجرا
میشوند.
همانطورکه در زیر مشاهده میکنید ،دو مثال فوق با هم معادلاند:
)(exten => 555,1,Answer
)exten => 555,2,Playback(demo-thanks
مرجع آموزش ویپ با سافتسوئیچ استریسک 106
همچنین میتوانیم برای جلوگیری از تکرار نام اکستنشن ،برنامه باال را بصورت زیر بنویسیم .در این حالت از
عبارت sameاستفاده میکنیم که نشاندهنده اکستنشن در اولویت قبلی است.
)(exten => 555,1,Answer
)same => n,Playback(demo-thanks
)same => n,Voicemail(555
)(same => n,Hangup
مسئله مهم در این تعریف این است که بین برچسب و اولویت ،عالمت کاما وجود ندارد و اکثرا ً به اشتباه بین
این دو از عالمت « » ,استفاده میکنند که منجر به بروز خطا در سیستم میگردد.
به عنوان مثال برنامه زیر را درنظر بگیرید:
)exten => 206,1,GotoIf($["${CALLERID(num)}" = "303"]?dial1
)same => n,GotoIf($["${CALLERID(num)}" != "304"]?moh:dial2
)same => n(dial1),Dial(${SPHONE1},15,rt
)(same => n,Hangup
)same => n(dial2),Dial(${PHONE2},15,rt
)(same => n,Hangup
)same => n(moh),MusicOnHold(default
در این مثال پس از وارد کردن شــماره ، 206ابتدا شــرط کالرآیدی 2چک میشــود .اگر کالرآیدی شــخص
تماسگیرنده 303 3باشد ،اجرای برنامه به برچسب dial1منتقل میشود و در غیر اینصورت به گام بعدی میرود
و در آنجا اگر کالرآیدی 304باشد به بر چسب dial2و در غیر اینصورت به برچسب mohمنتقل میگردد.
نکته مهم این اســت که بعد از انتقال به برچســب مشخص شده ،دســتورات آن قسمت به ترتیب اولویت
اجرا خواهند شد.
1- Label
2- CallerID
3- Caller
107 برنامهنویسی مقدماتی در استریسک
دستور Answer
وقتی یک تماس جدید در استریسک ایجاد میشود ،وضعیت کانال تا زمانی که به آن تماس پاسخ ندادهایم
در حالت Ringingباقی میماند .اکنون اگر تماس را بوسیله خود استریسک پاسخ دهیم ،تماس در این حالت
Answerشــده و ازحالت Ringingخارج میشــود .با اجرا شدن این دســتور ،تماس ورودی بوسیله سیستم
تلفنی استریســک Answerمیشود که در اصطالح به معنای برداشتن گوشی است .کاربرد اصلی این دستور
در مواقعی اســت که میخواهیم توسط سیســتم تلفنی تعامالتی را انجام دهیم و باید قبل از اجرای تعامالت،
مطمئن باشــیم که تماس برقرار و Answerشده است .بهعنوان مثال برای پخش یک فایل صوتی ،کانال باید
Answerشود تا امکان پخش آن بهوجود آید.
دستور Playback
این دســتور بــه منظور پخش کردن فایــل صوتی ،روی کانال مورد اســتفاده قرار میگیرد.نــام فایل صوتی
به عنوان ورودی باید در این دســتور وارد شــود .مســیر پیشفرض فایلهای صوتی در استریســک var/lib/
/asterisk/sounds/enاســت؛ بهطوریکه اگر مســیر فایل صوتی ذکر نشــود استریسک از مسیر پیشفرض
استفاده میکند تا فایل صوتی را پیدا و اجرا کند .درصورتیکه بخواهیم از مسیر دیگری فایل صوتی را اجرا
کنیم ،باید آدرس کامل مسیر را وارد کنیم.
)(exten => 126,1,Answer
)same => n,Playback(/var/spool/storage/sounds/demo-thanks
)(same => n,Hangup
بهتر است پسوند فایل صوتی را در هنگام نوشتن نام فایل ،ذکر نکنیم؛ در این صورت اگر فایل صوتی مورد
نظر با چندین فرمت متفاوت در مســیر مشخص شده وجود داشته باشــد ،استریسک بهترین فرمت (از لحاظ
کمتریــن پردازش جهت تبدیل به کدک مورد نظر) را انتخاب و پخش مینماید .در این حالت استریســک
بار هزینه CPUکمتری را مصرف میکند (در فصل ســوم ،ســاختار استریســک راجع به ماژول Format-
Interpreterتوضیح داده شدهاست).
در استریســک دستورات دیگری برای پخش فایل صوتی از قبیل دستور Readو دستور BackGround
وجود دارد که بعدا با آنها آشنا میشوید.
اینجا به بررسی یک مثال جالب از کاربرد دستور Answerمیپردازیم.
مرجع آموزش ویپ با سافتسوئیچ استریسک 108
فرض کنید دو کاربر 100و 101وجود داشــته باشــند ،بهطوریکه بتوانند یکدیگر را شمارهگیری کنند.
برنامه آنها به صورت زیر و البته خیلی ساده است:
][LocalSets
)exten => 100,1,Dial(SIP/100
)exten => 200,1,Dial(SIP/200
با دســتور Dialمیتوان یک تماس جدید در استریســک به مقصد مشخص ایجاد نمود (در خصوص دستور
Dialدر همین فصل توضیحات الزم خواهد آمد).
با اجرای این ســناریو ،هرگاه شــماره 100یا 101را بگیریم ،داخلی کاربران زنگ خواهد خورد .اکنون
فرض کنید سناریوی فوق را بهصورت زیر پیادهسازی کنیم.
][LocalSets
)(exten => 100,1,Answer
)same => n,Dial(SIP/100
) (exten => 101,1,Answer
)same => n,Dial(SIP/101
) (exten => 200,1,Answer
)same => n,Playback( hello-world
در این ســناریو استفاده از دســتور Answerقبل از دستور Dialمناسب و کاربردی نخواهد بود .همانطورکه
مالحظه میکنید تماس ازطریق خود استریسک پاسخ داده میشود و سپس داخلی مورد نظر زنگ میخورد.
اکنون ممکن است داخلی مورد نظر در دسترس نباشد ،ولی تماس پاسخ داده شدهاست .لذا توجه داشتهباشید
که پیادهســازی ســناریوها در استریســک به این صورت ،باعث میشــود در گزارشــات جزئیات تماسها
1
مشکالتی بهوجود آید .لذا بهتر است سناریوی فوق را بهصورت زیر بازنویسی کنیم.
][LocalSets
)exten => 100,1,Dial(SIP/100
)exten => 101,1,Dial(SIP/101
) (exten => 200,1,Answer
)same => n,Playback( hello-world
دستور BackGround
فرض کنید از شــما خواســته شده که یک ســناریو برای یک شرکت یا ســازمان طراحی کنید؛ بهطوریکه
هرکس با شمارهی این سازمان تماس بگیرد ،یک پیام خوشآمدگویی برای وی پخش شود تا داخلی مورد
نظر خود را وارد نماید .بخش اول سناریو ،پخش پیام خوشآمدگویی welcomeبه صورت زیر است.
][LocalSets
)(exten => s,1,Answer
)same => n,Playback(welcome
تا اینجا موفق به اجرای بخشی از سناریو شدهایم.سوالی که ممکن است پرسیده شود این است که sچه معنایی
میتواند داشته باشد؟ اجازه بدهید بعدا ً مفص ً
ال راجع به آن شرح دهیم ولی اینجا میتوانید آن را با هر شمارهی
دیگری (جهت تست سناریو) جایگزین کنید (دقت کنید که قب ً
ال از آن شماره استفاده نکرده باشید).
با اجرای ســناریو ،پیام صوتی شــروع به پخش میکند .نکته مهم این اســت که در این نوع از سناریوها
لزومی ندارد که حتماً پیام خوشآمدگویی تا انتها شــنیده شــود؛ بلکه باید این قابلیت وجود داشــته باشد که
ِ
پخش پیام صوتی ،بتوانیم داخلی مورد نظر را شــمارهگیری کنیم .اســتفاده از دستور Playbackدر در حین
یک چنین ســناریوهایی به هیچ وجه مناســب نیســت چون مخاطب مجبور میشــود تا انتهای پیام صوتی را
بشــنود و بعد شــماره داخلی مورد نظر خود را وارد کند؛ بنابراین ،از دستور BackGroundاستفاده میکنیم.
دســتور BackGroundدقیقا مانند دســتور Playbackاســت .اجازه دهید مثال قبل را با اســتفاده از دســتور
BackGroundدوباره بازنویسی کنیم.
][LocalSets
)(exten => s,1,Answer
)same => n,BackGround(welcome
تــا اینجا ما پیام صوتی را برای مخاطب پخش کردهایم .اکنــون اگر مخاطب ،داخلی مورد نظر را وارد کند
چه اتفاقی میافتد؟
اکثر سناریوها در سیستمهای تلفنی ،حالت تعاملی دارند .یعنی در حین اجرای دستورات ،منتظر ورودی
از طرف مخاطباند تا بر اساس ورودی ،مسیر تعیین شده را دنبال نمایند.
در مثال قبل ،همانطورکه مالحظه میکنید ابتدا تماس توســط استریســک Answerمیشود و بعد یک
فایــل صوتی پخش میگردد .در حین اجــرای فایل صوتی ،منتظر یک ورودی از طرف مخاطب نیز میماند.
به محض دریافت ورودی (صرفنظر از اینکه فایل صوتی در حال پخش اســت) ،پخش فایل صوتی متوقف و
ادامه Dialplanاجرا میشود.
اکنون میخواهیم ادامه ســناریو را تکمیل کنیم .این کار بســیار ساده و راحت انجام میشود .به مثال زیر
دقت کنید:
][LocalSets
)(exten => s,1,Answer
)same => n,BackGround(welcome
)same => n,WaitExten(5
معموالً زمانی که از مخاطب خواسته میشود تا داخلی مورد نظر خود را وارد کند ،اندکی به او فرصت داده
میشود .دستور WaitExtenهمین کار را انجام میدهد .در این سناریو عالوه بر مدت زمانی که فایل صوتی
مرجع آموزش ویپ با سافتسوئیچ استریسک 110
در حال پخش اســت 5 ،ثانیه هم به مخاطب فرصت داده میشــود تا داخلی خود را وارد نماید .برای آشنایی
بیشتر با ،WaitExtenدستور زیر را وارد کنید.
CLI> core show application WaitExten
در این مثال بعد از Answerشدن تماس ،فایل صوتی شروع به پخششدن میکند .پس از اتمام فایل صوتی،
به مدت 5ثانیه منتظر میماند تا مخاطب عددی را وارد نماید .با وارد کردن هر عدد ،استریسک بهترین رول
را پیدا و اجرا میکند .برای مثال اگر مخاطب عدد 1را وارد نماید ،استریسک این دستور را اجرا میکند:
)exten => 1,1,Playback(digits/1
بنابراین فایل صوتی digit/1پخش میشود .اگر عدد 2را وارد نمایید ،استریسک این دستور را اجرا میکند:
)exten => 2,1,Playback(digits/2
در این حالت فایل صوتی digit/2اجرا میشــود .نکته مهم اینجاســت که چگونه این ساختارها کنار هم قرار
میگیرند و اجرا میشوند .در ادامه در مورد این موضوع و مثالهای مرتبط با آن صحبت خواهیم کرد.
اگر بخواهیم مخاطب ،داخلی مورد نظر را وارد کند باید برنامه مورد نظر به شکل زیر باشد:
][LocalSets
)(exten => s,1,Answer
)exten => s,n,BackGround(welcome
)exten => 100,1,Dial(SIP/100
)exten => 101,1,Dial(SIP/101
در این پیادهســازی ســاده ،فرض کردیم کــه فقط دو داخلی 100و 101داریــم .در صورتی که داخلیهای
بیشتری داشته باشیم باید آنها را نیز اضافه کنیم.
اگر مخاطب شــمارهای وارد کند که وجود نداشــته باشــد ،تماس قطع میشــود .در مثال قبل اگر کاربر
شــماره 102را وارد کند ،در این صورت تماسش قطع خواهد شــد .همچنین اگر کاربر هیچ عددی را وارد
نکند یا عددی به غیر از 1و 2را وارد کند ،تماس پایان خواهد یافت .بیایید مثالی دیگر را با هم بررسی کنیم:
][TestMenu
)(exten => 1000,1,Answer
)same => n,BackGround(enter-ext-of-person
)same => n,WaitExten(5
)exten => 1,1,Playback(digits/1
)same => n,Goto(TestMenu1,start,1
)exten => 2,1,Playback(digits/2
)same => n,Goto(TestMenu2,start,1
در این مثال کاربرانی که اجازه کار در کانتکســت TestMenuرا دارند با شمارهگیری 1000ابتدا تماس
Answerمیشــود ،بعد فایل صوتی enter-ext-of-personپخش میشــود و سپس 5ثانیه منتظر میماند تا
مخاطب شمارهای را وارد نماید .اگر عدد وارد شده 1باشد فایل digits/1پخش میشود .سپس با دستور Goto
111 برنامهنویسی مقدماتی در استریسک
به جایی دیگر منتقل میشود و اجرای دستورات از آنجا ادامه مییابد .اگر عدد وارد شده 2باشد فایل digits/2
پخش میشود و سپس دستور Gotoاجرا میگردد.
دستور Goto
از دســتور Gotoبرای پرش بین دســتورات استفاده میشــود .گاهی نیاز داریم بر اساس شرایطی دستوراتی
خاص اجرا شوند ،بر این اساس باید بتوانیم بین اجرای دستورات پرش داشتهباشیم.
برای آشنا شدن با دستور Gotoمیتوانید دستور زیر را در کامندالین استریسک اجرا کنید:
CLI> core show application Goto
][Syntax
)Goto([[context,]extensions,]priority
][MyContext2
)(exten => start,1,NoOp
)exten => start ,n,Playback(hello-world
)(exten => start, n,Hangup
با در نظر گرفتن ســناریوی باال ،اگر ما شــماره 100را بگیریم ،در اولین اولویت دســتور Gotoرا داریم؛ لذا
باعث میشــود به خطی که دارای برچســب monkeysاســت ،پرش کنیم .در این نحوه پرش حتماً باید نام
اکستنشن یکسان باشد .دستور فوق معادل دستور زیر است:
)exten => 100,1,Goto(MyContext ,100,monkeys
اینجا چون نام کانتکست و اکستنشن یکسان بود؛ آنها را حذف کردیم.
مرجع آموزش ویپ با سافتسوئیچ استریسک 112
اگر شماره 200را بگیریم ،دستور ( Goto (start,1اجرا میشود .با اجرای این دستور ابتدا به اکستنشن start
رفته و آنجا از دستوری با اولویت ،1اجرای دستورات را شروع میکنیم.
با شمارهگیری عدد 300فقط دستور زیر اجرا میشود:
)exten => start, n(monkeys),Playback(tt-monkeys
با شمارهگیری عدد ،400ابتدا به کانتکست MyContext2رفته ،سپس از اولویت اول اکستنشن startشروع
به اجرای دستورات میکند .شکل 3-5نحوه پرش بین دستورات را در مثال باال نمایش میدهد.
شکل 3-5
بیایید یک مثال دیگر را بررسی کنیم.
][TestMenu
)(exten => 110,1,Answer
)same => n,BackGround(enter-ext-of-person
)same => n,WaitExten(5
)exten => 1,1,Playback(digits/1
)same => n,Goto(TestMenu,110,1
)exten => 2,1,Playback(digits/2
)same => n,Goto(TestMenu,110,1
)exten => i,1,Playback(pbx-invalid
)same => n,Goto(TestMenu,110,1
)exten => t,1,Playback(vm-goodbye
)(same => n,Hangup
در این مثال با شــمارهگیری 110ابتدا تماس Answerمیشــود؛ ســپس فایل صوتی enter-ext-of-person
پخش میشود و 5ثانیه نیز منتظر ورود اطالعات از تلفن میماند.
اگر عدد وارد شده 1باشد فایل digits/1پخش میشود و با دستور Gotoبه کانتکست TestMenuو سپس
اکستنشن 110و اولویت 1میرود.
113 برنامهنویسی مقدماتی در استریسک
اگر عدد وارد شده 2باشد فایل digits/2پخش میشود و با دستور Gotoبه کانتکست TestMenuو سپس
اکستنشن 110و اولویت 1میرود.
اگر کاربر عددی اشــتباه وارد نماید (بجز اعداد 1و ،)2اکستنشــن iاجــرا و فایل pbx-invalidپخش
1
میشود و با دستور Gotoبه کانتکست TestMenuو سپس اکستنشن 110و اولویت 1میرود.
اگر کاربر در مدت زمان تعیین شــده عددی وارد نکند؛ اکتستنشن 2 tاجرا و فایل vm-goodbyeپخش
میشود و با دستور Gotoبه کانتکست TestMenuو سپس اکستنشن 110و اولویت 1میرود.
دستور Dial
یکی از مهمترین ویژگیهای یک سیســتم تلفنی ،توانایی برقراری تماس با سایر کاربران و ایجاد یک ارتباط
اســت .این قابلیت زمانی که سیستم تلفنی استریسک کاربران زیادی داشــته باشد ،کاربردیتر و با اهمیتتر
میشــود .برای مثال فرض کنید دو کاربر در سیستم تلفنی استریســک بخواهند با هم تماس برقرار کنند و یا
کاربری بخواهد با مشــترکی در شــبکههای مخابراتی تلفنی( )PSTNارتباط برقرار کند؛ در این صورت باید
از دســتور Dialاستفاده کند .در این حالت سیستم تلفنی استریســک موظف است کانالهای متعددی ایجاد
و ســپس بین آنها ارتباط برقرار کند .این ارتباط برقرارکردن بین کانالها را در اصطالح Channel Bridge
میگویند.
دســتور Dialدر سیستم تلفنی استریسک ،وظیفه شمارهگیری و ایجاد تماس را بر عهده دارد .برای آشنا
شدن با ساختار این دستور ،در محیط کامند الین استریسک ،این دستور را اجرا کنید:
CLI> core show application Dial
][Syntax
)]]]Dial(Technology/Resource[&Technology2/Resource2[&...]][,timeout[,options[,URL
این دستور از چهار بخش تشکیل شده است که در ادامه به آنها خواهیم پرداخت.
منظور از Technologyهمان ماژولهای Channel Driverاســت که بوسیله آن ،کاربرانی از نوع پروتکلهای
SIP,IAX2,DAHDIاستفاده میشــوند .به بیان دیگر منظور از Technologyنوع تکنولوژی ارتباطی با سیستم
تلفنی اســت .منظور از Resourceهمان شــمارهی مقصدی اســت که میخواهیم با آن تماس برقرار کنیم .به
عنوان مثال فرض کنید بخواهیم با کاربری با شماره 100تماس بگیریم ،در این صورت خواهیم داشت:
][LocalSets }{Technology
همانطورکه مالحظه میکنید چون این داخلی از طریق پروتکل ارتباطی SIPبه ســرور متصل شدهاست ،لذا
در قسمت Technologyدستور Dialاز عبارت SIPاستفاده میکنیم.
اکنون فرض کنید بخواهیم از طریق سیســتم تلفنی استریســک ،با شــبکه مخابراتی PTSNارتباط برقرار
کنیم .در این صورت داریم:
][LocalSets
)}exten => _091X.,1,Dial(DAHDI/g0/${EXTEN
در ایــن حالت ما با مشــترک ،از طریــق پروتکل ارتباطــی DAHDIارتباط برقــرار کردهایم .در خصوص
کانالهای DAHDIدر فصل ششــم (ارتباط استریسک با شــبکه مخابراتی) توضیح بیشتری خواهد آمد .در
دستور باال از الگوهای تطابق 1نیز استفاده کردهایم؛ به این صورت که هر شمارهای که با 091شروع شود ،این
دستور اجرا میگردد .منظور از عبارت{ $}EXTENهمان شمارهای است که ما وارد کردهایم .در فصلهای
آینده درخصوص الگوهای تطابق توضیحات بیشتری خواهد آمد.
بهعنوان یک مثال دیگر اگر خواســته باشــیم با شمارهگیری ،203داخلی 203از نوع پروتکل SIPزنگ
بخورد باید اینگونه عمل کنیم.
)exten => 203,1,Dial(SIP/203
فرض کنید بخواهیم با شمارهگیری ،203داخلی 203از نوع پروتکل IAX2زنگ بخورد .در این صورت باید
به شکل زیر عمل کنیم:
)exten => 203,1,Dial(IAX2/203
اگــر بخواهیم با پروتکل DAHDIکار کنیم ،با روشهای متعددی میتوانیم از این قابلیت اســتفاده کنیم .به
عنوان مثال:
)exten => 300,1,Dial(DAHDI/1
در ایــن حالــت هدف ،برقــراری ارتباط با داخلی تعریف شــده به پورت اول کارت FXSاســتFXS ( .ها
ســختافزارهایی هســتند که با اســتفاده از تکنولوژی DAHDIمیتوانیم روی آنهــا داخلی تعریف کنیم و
تلفنهای آنالوگ را به آنها وصل نماییم) .همچنین میتوانیم از کانالهای DAHDIبا شبکه مخابراتی PSTN
تماس برقرارکنیم.
برای عنوان مثال :
)}exten => _X.,1,Dial(DAHDI/1/${EXTEN
در این مثال هر عددی شــمارهگیری شــود در متغیر{ $}EXTENذخیره و با دســتور Dialاز کانال 1کارت
سختافزاری FXOشمارهگیری میشود .در این حالت برای ما مهم است که خروجی تماس ما از یک پورت
خاص (پورت اول کارت )FXOخارج شود.
ولــی اگر پورت یا شــماره پورت خروجی مهم نباشــد میتوانیم با قــرار دادن چندین پورت درون یک
گروه ،از شماره گروه استفاده کنیم .در این صورت با توجه به نوع سناریو ،پورت خروجی مشخص میشود
و شماره مورد نظر را Dialمیکند.
در فصل ششم (ارتباط استریسک با شبکههای مخابراتی) راجع به این موضوع بیشتر توضیح داده میشود.
در این مثال اگر کاربر (داخلی کانال 1از کارت ) FXSتماس را بعد از مدت 20ثانیه پاســخ ندهد ،کنترل
برنامه به خط بعدی (اولویت بعدی اجرای دستورات) منتقل میشود و فایل صوتی « متاسفانه کاربر مورد نظر
در دسترس نیست» پخش میشود .البته میتوان قابلیتهایی به برنامه اضافه کرد ،بهطوریکه اگر داخلی پاسخ
تماس را نداد تماس به سمت صندوق پستی داخلی هدایت شود.
)(exten => 501,1,NoOp
)same => n,Dial(SIP/501,20
)same => n,VoiceMail(501@default,u
در این مثال اگر کاربر 501تماس خود را طی مدت 20ثانیه پاسخ ندهد ،دستور بعدی (صندوق پستی) اجرا
میشود .در فصل هشتم (برنامهنویسی پیشرفته در استریسک) با قابلیتهای صندوق پستی بیشتر آشنا خواهید
شد.
آرگومان سومOptions :
دستور Dialتعداد زیادی آپشن و قابلیتهای قدرتمند دارد که درصورت نیاز میتوانید از آنها استفاده کنید.
برای آشنایی کامل دستور Dialدر محیط کامند الین استریسک ،دستور زیر را تایپ نمایید.
CLI> core show application Dial
جدول 1-5خالصهای از این آپشنها را معرفی میکند و راهنمای استفاده از آنها را شرح میدهد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 116
Option Note
A(x) Play an announcement (x.gsm) to the called party.
C Reset the CDR (Call Detail Record) for this call. This is like using the NoCDR command
c Sets the channel driver flag that the "call is answered elsewhere" if Dial() cancels the call
D After the called party answers, send digits as a DTMF stream, then connect the call to the
originating channel (you can also use 'w' to produce .5 second pauses).
d This flag trumps the 'H' flag and intercepts any single DTMF tone while waiting for the call
to be answered and jumps to that extension if it exists. This allows you to dial a 1-digit
exit extension while waiting for the call to be answered - see also RetryDial. This uses the
current context unless ${EXITCONTEXT} is defined.
e Execute "h" as the peer when this call ends
F(context^exten^pri) When the caller hangs up, transfer the called party to the specified context and extension
and continue execution.
f forces callerid to be set based on a dialplan "hint" for the current channel. For example,
some PSTNs don't allow callerids from other extensions than the ones that are assigned to
you.
G If the call is answered, transfer both parties to the specified context and extension. The
calling party is transferred to priority x, and the called party to priority x+1. This allows the
dialplan to distinguish between the calling and called legs of the call (new in v1.2). You
cannot use any options that would affect the post-answer state if this option is used.
g When the called party hangs up, continue to execute commands in the current context at the
next priority.
H Allow the caller to hang up by dialing * ( * is defined in features.conf -> featuremap ->
disconnect )
h Allow the callee to hang up by dialing * ( * is defined in features.conf -> featuremap ->
disconnect )
i Asterisk will ignore any forwarding requests it may receive on this dial attempt. (new in 1.4)
Useful if you are ringing a group of people and one person has set their phone to forwarded
direct to voicemail on their cell or something which normally prevents any of the other
phones from ringing.
j Asterisk 1.2 and later (1.6???): Jump to priority n+101 if all of the requested channels were
busy (just like behaviour in Asterisk 1.0.x)
K Allow the calling party to enable parking of the call by sending the DTMF sequence defined
for call parking in features.conf (Asterisk v1.4.x)
k Allow the called party to enable parking of the call by sending the DTMF sequence defined
for call parking in features.conf (Asterisk v1.4.x)
L(x[:y][:z]) Limit the call to 'x' ms, warning when 'y' ms are left, repeated every 'z' ms) Only 'x' is
required, 'y' and 'z' are optional. Numbers must be integers- beware of AGI scripts that may
return long integers in scientific notation (esp PHP 5.2.5&6) The following special variables
are optional for limit calls: (pasted from app_dial.c)
M(x) Executes the macro (x) upon connect of the call (i.e. when the called party answers).
m Provide Music on Hold to the calling party until the called channel answers. This is mutually
exclusive with option 'r', obviously. Use m(class) to specify a class for the music on hold.
N Modifies the privacy manager - turns off call screening if caller ID information is present
117 برنامهنویسی مقدماتی در استریسک
Option Note
n(delete) If delete is 0 or not specified, delete the privacy manager introduction if the caller hangs up
before the call is answered. If set to 1, delete the recording even if the call is answered.
O(mode) If mode is set to 1 or isn't specified, ringback immediately if the originator hangs up. If mode
is set to 2, ring back when the operator flashes the trunk. This is only valid when the caller
and called channels are DAHDI channels. It is intended for calling an operator station.
o Restore the Asterisk v1.0 CallerId behaviour (send the original caller's ID) in Asterisk v1.2
(default: send this extension's number)
P(x) This option enables screening mode. This is basically Privacy mode without memory of how
to handle the caller.
p Indicate ringing to the calling party when the called party indicates ringing, pass no audio
until answered. This is available only if you are using kapejod's Bristuff.
R Generate a ringing tone for the calling party, passing no audio from the called channel(s)
until one answers. Without this option, Asterisk will generate ring tones automatically where
it is appropriate to do so; however, "r" will force Asterisk to generate ring tones, even if it is
not appropriate.
r Hangup the call n seconds AFTER called party picks up.
S(n) Allow the calling user to transfer the call by hitting the blind xfer keys (features.conf). Does
not affect transfers initiated through other methods.
T Allow the called user to transfer the call by hitting the blind xfer keys (features.conf)
t Does not affect transfers initiated through other methods.
U(x) Executes, via gosub, routine x on the called channel. This is similar to M above, but a gosub
rather than a macro.
W Allow the calling user to start recording after pressing *1 or what defined in features.conf
(Asterisk v1.2.x); requires Set(DYNAMIC_FEATURES=automon)
w Allow the called user to start recording after pressing *1 or what defined in features.conf
(Asterisk v1.2.x); requires Set(DYNAMIC_FEATURES=automon)
X Allow the calling user to start recording using automixer after pressing *1 or what defined in
features.conf (Asterisk v1.6)
x Allow the called user to start recording using automixer after pressing *1 or what defined in
features.conf (Asterisk v1.6)
1-5 جدول
از موزیک انتظار در زمان ایجاد تماسRingTone به عنوان مثال فرض کنید بخواهیم به جای استفاده از
: در این صورت خواهیم داشت.جدید استفاده کنیم
exten => 502,1,Dial(DAHDI/1,10,m)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
ما میتوانیم. استفاده میکنیمDial همانطورکه مالحظه میکنید از آپشنها بهعنوان آرگومان سوم در دستور
:برنامه باال را بهصورت زیر نیز اجرا کنیم
exten => 502,1,Dial(DAHDI/1,,m)
same => n,Playback(vm-nobodyavail)
مرجع آموزش ویپ با سافتسوئیچ استریسک 118
همانطورکه مالحظه میکنید چون نیازی نداشتیم از آرگومان Timeoutاستفاده کنیم ،جای آن را در دستور
Dialخالی گذاشــتیم .نکته مهم این است که حتما هنگام استفاده از دستور Dialو آرگومانهای آن ،ترتیب
آرگومانها رعایت شود.
1
بررسی اکستنشنهای خاص در استریسک
در استریســک برخی از اکستنشــنها معانی خاصی دارند .باید دقت داشتهباشیم که در برنامهنویسی از آنها به
جز در موارد مشخص شده استفاده نکنیم .در ادامه برخی از آنها را بررسی میکنیم:
: hاین اکستنشــن در زمان Hangupشــدن اجرا میشــود .به عبارت دیگر زمانی که تماســی قطع میشــود
میتوانیم دستورات مشخصی را در این اکستنشن اجرا کنیم.
: sاین اکستنشــن بیشتر در کنار ماکروها و توابع استفاده میشود .به طور کلی زمانی که بخواهیم یکسری از
دستورات را به صورت تکرار ،صرف نظر از نام اکستنشن اجرا کنیم ،از آن استفاده میکنیم .در برخی موارد
به جای sاز startنیز استفاده میشود .در مثالهای بعدی توضیح بیشتری خواهد آمد.
: 2 tاین اکستنشن به معنای تمام شدن مدت زمان پاسخ دادن است .در صورتی که از دستورات BackGround
و WaitExtenاستفاده کنیم ،باید در یک زمان مشخص ،عددی را وارد کنیم ،در غیر این صورت بعد از پایان
یافتن زما ِن پاسخ؛ کنترل برنامه در اختیار این اکستنشن قرار میگیرد.
: Tاین اکستنشــن به معنای مدت زمان فعال بودن یک تماس (کانال) در سیســتم است؛ به این معنی که وقتی
یک تماس وارد سیســتم میشود (ایجاد میشود) حداکثر طول عمر این تماس چقدر است .برای مثال فرض
کنید هر تماســی در سیستم ایجاد شــود ،حداکثر 5دقیقه میتواند زمان داشتهباشــد .برای اینکار باید از تابع
Timeoutبصورت زیر استفاده کنیم:
][incoming
)(exten => 111,1,NoOp
)exten => 111,n,Set(TIMEOUT(absulote)=300
)exten => 111,n,Dial(SIP/111
همانطورکه مالحظه میکنید نخســت حداکثر طول عمــر یک کانال تماس را روی 300ثانیه تنظیم کردیم.
اگر طول مدت زمان مکالمه بیشتر از 300ثانیه باشد ،اجرای برنامه به اکستنشن Tرفته و دستورات آن را اجرا
میکند.
نکته مهم این اســت که ما اینجا از تابع (و نه دســتور ) TIMEOUTاســتفادهکردیم .در فصلهای آینده
راجع به توابع استریسک توضیح خواهیم داد.
شاید این تصور ایجاد شود که میتوانیم از این روش طول مدت زمان یک مکالمه را محدود کنیم ،ولی
این روش برای محدود کردن مکالمه (بعد از پاســخ دادن )1مناســب نیســت .از این روش عمدتا برای کنترل
طول عمر یک کانال ایجاد شده در استریسک استفاده میشود .برای مثال فرض کنید شرکتی از شما بخواهد
هر مخاطبی که به مجموعه زنگ میزند باید در مدت زمان مشــخصی (مثال 5دقیقه) پاســخ خود را بگیرد و
بعد از آن سیســتم باید مکالمه را بالفاصله قطع کند .بنابراین ما هیچگاه تماسهایی نخواهیم داشــت که بیش
از 5دقیقه در سیســتم به طول بینجامد .در حالت دیگر ،فرض کنید مدت زمان هر مکالمه (بعد از پاسخ دادن
تماس) نباید بیشــتر از 5دقیقه طول بکشــد ،در این حالت باید از دستور Dialو پارامتر Limitبرای انجام این
سناریو استفاده کنیم (جدول .)1-5
برای فهم بهتر تفاوت این دو موضوع اجازه دهید مثالی را شرح دهیم .فرض کنید از شما خواسته میشود
که مدت زمان مکالمه هر اپراتور در یک کالســنتر را به 5دقیقه محدود کنید .این کالســنتر دارای 4لینک
ایــوان ( 120خط مســتقیم ورودی از مخابرات) اســت .در زمانهای پیک ترافیک ،اگــر ما مدت زمان فعال
بودن کانال را روی 5دقیقه تنظیم کنیم ،صرف نظر از اینکه آیا تماس هنوز در صف انتظار برای پاسخ دادن
اولین اپراتور اســت یا در حال صحبت با اپراتور ،بعد از سپری شدن 5دقیقه بالفاصله تماس قطع میشود ،اما
اگر مدت زمان مکالمه را به 5دقیقه محدود کنیم ،در این حالت پس از پاســخ اپراتور ،محاسبه 5دقیقه آغاز
خواهد شــد .تفاوت اجرای هر دو سناریو به صورت زیر اســت .در مثال اول مدت زمان فعال بودن کانال در
نظر گرفته میشود و در مثال دوم اگر تماس پاسخ داده شود ،مدت زمان مکالمه لحاظ میگردد.
][incoming
)(exten => 111,1,NoOp
)exten => 111,n,Set(TIMEOUT(absulote)=300
)exten => 111,n,Dial(SIP/operators
][incoming
)(exten => 111,1,NoOp
))exten => 111,n,Dial(SIP/operators,,L(300000,2400000,2300000
: eمیتوان از این اکستنشن به جای اکستنشنهای t ، Tو iاستفاده کرد .اغلب زمانی که نخواهیم به تفکیک
هر اکستنشــن را در سیســتم تحلیل کنیم ،از این اکستنشــن اســتفاده میکنیم .به عنوان مثال میتوان به جای
اکستنشنهای iو tاز اکستنشن eبه صورت زیر استفاده کرد:
][TestMenu
)(exten => 110,1,Answer
)same => n,BackGround(enter-ext-of-person
)same => n,WaitExten(5
)exten => 1,1,Playback(digits/1
)same => n,Goto(TestMenu,110,1
)exten => 2,1,Playback(digits/2
)same => n,Goto(TestMenu,110,1
)(exten => e,1,NoOp
)same => n,Goto(TestMenu,110,1
البته در فصل نهم (آشنایی با صفها 1در استریسک) روشهای بهتری را بررسی خواهیم کرد و مفاهیم پیاده
سازی کال سنتر را شرح خواهیم داد .تا اینجا شما با یکی از مهمترین دستورات استریسک آشنا شدید .برای
مرور آنچه تا اکنون توضیح داده شد ،بیایید مثالی را با هم بررسی کنیم.
][TestMenu
)(exten => start,1,Answer
)same => n,BackGround(enter-ext-of-person
)same => n,WaitExten(5
)exten => 1,1,Dial(SIP/0000FFFF0001,10
)same => n,Playback(vm-nobodyavail
)(same => n,Hangup
)exten => 2,1,Dial(SIP/0000FFFF0002,20
)same => n,Playback(vm-nobodyavail
)(same => n,Hangup
)exten => i,1,Playback(pbx-invalid
)same => n,Goto(TestMenu,start,1
)exten => t,1,Playback(vm-goodbye
)(same => n,Hangup
همانطورکه پیشتر توضیح دادیم وقتی برنامه با اکستنشن sیا startشروع میشود به این معنی است که این
Dialplanازجایی دیگر فراخوانی میشود .برای مثال فرض کنید این فراخوانی به صورت زیر باشد:
][incoming
شکل 4-5
اکنون کد برنامه خود را بهصورت زیر مینویسیم:
)exten => 300,1,Set(SALE=SIP/300
)}same => n,Dial(${SALE
در ایــن مثــال از دســتور Setبرای تعریف یک متغیر جدید اســتفاده کردیم .اســم متغیــر SALEو مقدار آن
SIP/300اســت .از متغیر SALEهر زمان که الزم باشــد استفاده میکنیم .برای استفاده از محتوای ذخیره شده
در یک متغیر ،عالمت{ $}Variable-Nameرا به کار میگیریم .توجه داشته باشید که متغیرها نسبت به حروف
بزرگ و کوچک حســاساند .در استریســک انواع متفاوتی از متغیرها وجود دارند که در ادامه به آنها خواهیم
پرداخت.
متغیرهای سراسری
پارهای از متغیرها میتوانند در استریســک تعریف شــوند که در کل محیط برنامهنویســی استریسک و همه
کانالهای فعال در استریســک قابل استفاده باشند .از این نوع متغیرها در سایر زبانهای برنامهنویسی هم دیده
میشود؛ بهطوریکه در روند اجرای برنامه ،قابل رؤیت و استفادهاند .این متغیرها در قسمت [ ]globalاز فایل
extensions.confقابل تعریفاند .برای مثال:
][globals
SALE = SIP/300
میتــوان در همه قســمتهای Dialplanدر استریســک از متغیر{ $}SALEاســتفاده کــرد .زمانیکه نیاز داریم
1- Global Variable
2- Channel Variable
3- Enviroment Variable
مرجع آموزش ویپ با سافتسوئیچ استریسک 124
متغیرهای سراسری را در زمان اجرای برنامه ( )Runtimeایجاد کنیم ،از تابع GLOBALبهره میگیریم.
برای آشنا شدن با تابع GLOBALدستور زیر را در کامند الین استریسک اجرا کنید:
CLI> core show function GLOBAL
][Synopsis
Gets or sets the global variable specified.
][Description
>Set or get the value of a global variable specified in <varname
][Syntax
)GLOBAL(varname
برای مثال با گرفتن شماره 400در این برنامه ،متغیر سراسری FOOبا مقدار 456بصورت GLOBALتعریف
میشود .برای استفاده از این متغیر ،آن را بهصورت زیر فراخوان کنید:
)} exten => s,1,NoOp(FOO=${FOO
متغیرهای محلی
ایــن متغیرها بهصورت محلی در کانالهای جاری ایجاد میشــوند و مورد اســتفاده قرار میگیرند .برخالف
متغیرهای سراســری ،این متغیرها فقط در مدت زمانی که کانال فعال است قابل استفادهاند و بعد از قطع شدن
تماس (کانال) این متغیرها از بین میروند.
در استریســک متغیرهای محلی فراوانی وجود دارد و همچنین میتوانند تعریف شوند .بهعنوان مثال یکی
از پرکاربردترین متغیرهای محلی ،متغیر{ $}EXTENاست که اشاره به شماره گرفتهشده دارد .در این کتاب
با انواع متغیرهای محلی آشنا میشوید .برای مثال دستور زیر یک متغیر محلی بنام MESPIOایجاد میکند.
)exten => 401,1,Set(MESPIO=401
)}same => n,SayNumber(${MESPIO
متغیرهای محیطی
گاهی نیاز داریم به متغیرهایی در استریســک دسترســی داشته باشــیم که در لینوکس تعریف شدهاند .در این
صورت از تابع ENVاستفاده میکنیم.
برای آشنا شدن با تابع ،ENVدستور زیر را در کامند الین استریسک اجرا کنید:
CLI> core show function ENV
][Synopsis
Gets or sets the environment variable specified.
][Description
Variables starting with ‹AST_› are reserved to the system and may not be set.
][Syntax
)ENV(varname
125 برنامهنویسی مقدماتی در استریسک
هرچند ممکن اســت از این نوع دســتورات و توابع در استریسک استفاده زیادی نداشته باشید ،در هر صورت
برای آشنایی بیشتر با آنها ،مثال زیر مفید است.
در لینوکس متغیرهایی از پیش تعریف شــده داریم .برای مثال فرض کنید بخواهیم از متغیر HOMEاستفاده
کنیم .اگر دستور زیر را در محیط لینوکس اجرا کنیم ،خروجی زیر را خواهیم داشت:
# echo $HOME
/root
اکنون اگر بخواهیم از این متغیر در استریسک نیز استفاده کنیم ،به صورت زیر عمل میکنیم:
)})exten => _X.,1,NoOp(${ENV(HOME
)(same => n,Hangup
با اجرای دستور فوق در استریسک مقدار متغیر HOMEدر کامند الین استریسک نمایش داده میشود.
-- Executing [incoming:1] NoOp("Console/dsp", "/root") in new stack
-- Executing [incoming:2] Hangup("Console/dsp", "") in new stack
همانطورکــه پیشتــر توضیح داده شــد ،اســتفاده از متغیرهای محلی و سراســری ،بیشــترین کاربرد را در
برنامهنویســی استریســک دارند .در ادامه برای آشــنایی بیشــتر با این نوع متغیرها ،به مثالی جامع و کاربردی
خواهیم پرداخت.
مثال زیر را در نظر بگیرید:
][LocalSets
)exten => 402,1,NoOp(Setting Golobal Variable
)same => n,Set(GLOBAL(VAR1)=value1
)})same => n,NoOp(VAR1=${GLOBAL(VAR1
همانطورکه مالحظه میکنید در مثال فوق دو متغیر از نوع سراســری و محلی تعریف کردهایم .اکنون مقدار
متغیر را چاپ میکنیم .خروجی دستور فوق در زمان اجرا به صورت زیر است:
CLI> console dial 402@LocalSets
-- Executing [402@LocalSets:1] NoOp("Console/dsp", "Setting Golobal Variable") in new stack
-- Executing [402@LocalSets:2] Set("Console/dsp", "GLOBAL(VAR1)=value1") in new stack
== Setting global variable ‹VAR1› to ‹value1›-- Executing [402@LocalSets:3] NoOp("Console/dsp",
"VAR1=value1") in new stack
همانطورکه مالحظه میکنید هر دو مقدار متغیر در خروجی نشــان داده شــدهاند .اکنون فرض کنید در
جای دیگری بخواهیم از این دو متغیر تعریفشده در مثال قبل استفاده کنیم .به این مثال توجه کنید:
][LocalSets-2
)exten => 405,1,NoOp(Read Golobal Variable
)})same => n,NoOp(VAR1=${GLOBAL(VAR1
همانطورکه مالحظه میکنید ،متغیرهای سراسری در هر جایی از برنامه قابل دسترس و استفادهاند ولی متغیرهای
محلی فقط در حوزه محلی خود و تا زمانی که کانال فعال باشد ،اعتبار دارند .اینجا به متغیر محلی VAR2که در
جایی دیگر تعریف شده بود ،دسترسی نداریم و مقدار آن خالی است.
متغیرهای وراثتی تک گانه :در این حالت یک متغیر در برنامه استریسک ایجاد میکنیم ،ولی فقط یک بار در
کل استریسک میتوانیم به آن ارجاع داشتهباشیم و مقدار ذخیره شده در آن را بخوانیم.
متغیر وراثتی چندگانه :در این حالت یک متغیر در برنامه استریســک ایجاد میکنیم ،و هر زمان که بخواهیم
میتوانیم در استریسک به آن ارجاع دهیم و مقدار ذخیره شده در آن را بخوانیم.
این نوع متغیرها همانند متغیرهای سراسریاند .برای مثال در برنامههای زیر سه نوع متغیر داریم .متغیر VAR1
][LocalTest
)}exten => 101,1,NoOp(${VAR1 ;not defined
)}same => n,NoOp(${VAR2 ;VAR2=2
)}same => n,NoOp(${VAR3 ;VAR3=3
)same => n,Dial(LOCAL/102@LocalTest
معموالً داخل الگوهای تطابق از حروف و عالمتهایی اســتفاده میشــود که هر کدام معنای خاصی دارند.
برای مثال:
: Xایــن حــرف به معنای یک رقم بین 0تا 9اســت .به عبارت دیگر اگر در الگــوی تطابق این حرف وجود
داشــت به جای آن میتوان یک رقم بین 0تا 9را جایگرین کرد .برای مثال در برنامهی زیر چنانچه عددی
بین 0تا 9گرفته شود ،دستورات زیر اجرا میگردد.
)(exten => _X,1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
: Zاین حرف به معنای جایگزین کردن یک رقم بین 1تا 9است .برای مثال چنانچه در برنامهی زیر عددی
بین 1تا 9درنظر گرفته شود ،دستورات زیر اجرا میشود.
)(exten => _Z,1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
: Nاین حرف به معنای جایگزینکردن یک رقم بین 2تا 9است .برای مثال در برنامه زیر چنانچه عددی بین
2تا 9درنظر گرفته شود ،دستورات زیر اجرا میگردد.
)(exten => _N,1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
[ : ]a-bیعنی عددی بین aو bاست .برای مثال در برنامهی زیر چنانچه عددی بین 5تا 8درنظر گرفته شود،
دستورات زیر اجرا میگردد.
)(exten => _[5-8],1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
[ : ]abcdیعنی یکی از اعداد ذکر شده داخل براکت a ،یا bیا cیا . dبرای مثال در برنامهی زیر چنانچه یکی
از اعداد 3یا 5یا 6یا 8درنظر گرفته شود ،دستورات زیر اجرا میگردد.
)(exten => _[3568],1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
• : 1نقطه به منزله تکرار حداقل یکی و حداکثر بینهایت رقم و حرف اســت .برای مثال برنامه زیر شامل همه
1- period
129 برنامهنویسی مقدماتی در استریسک
الگوهایی است که حداقل 2رقم باشد و رقم اول آن بین 0تا 9باشد:
)(exten => _X.,1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
در مثال باال دقت کنید الگو باید دســت کم شــامل یک رقم و هر چیز دیگری (حرف یا عدد) باشــد و چون
عالمت « ».به منزله تکرار حداقل یک رقم اســت ،میتواند حداکثر شــامل هر تعداد از ترکیب حرف و عدد
باشد.
! : 1عالمت تعجب به منزله تکرار حداقل صفر و حداکثر بینهایت رقم و حروف است .برای مثال برنامهی زیر
کلیه الگوهایی که حداقل یک رقم داشتهباشند و رقم اول بین 0تا 9باشد را شامل میشود:
)(exten => _X!,1,Answer
same => n,do something
same => n,do something else
same => n,do one last thing
)(same => n,Hangup
دقت داشــته باشــید که الگو باید دست کم یک رقم داشته باشد و میتواند شامل هر تعداد رقم باشد .عالمت
(!) در الگوی تطابق ! _Xبه منزله تکرار حداقل یک رقم است.
مثال )1الگوی تطابق زیر را در نظر بگیرید .این الگوی تطابق چه شمارههایی را شامل میشود؟
exten => _ZXX,1, do something
این الگوی تطابق ،هر شماره 3رقمی بین 100تا 999را شامل میشود (از قبیل 256یا .)459
مثال )2الگوی تطابق زیر را در نظر بگیرید .این الگوی تطابق چه شمارههایی را شامل میشود؟
exten => _9X.,1, do something
ایــن الگــوی تطابق ،هر شــمارهی حداقل 3رقمی که رقم اول آن ،9رقــم دوم آن بین 0تا 9و مابقی آن هر
ترکیبی از حرف و عدد باشد ،را شامل می شود( .از قبیل 911یا 90912یا 90939899یا )90ab7
مثال )3الگوی تطابق زیر را در نظر بگیرید .این الگوی تطابق چه شمارههایی را شامل میشود؟
exten => _ZXXXXXX,1, do something
1- bang
مرجع آموزش ویپ با سافتسوئیچ استریسک 130
این الگوی تطابق ،هر شمارهی 7رقمی را شامل میشود (از قبیل 2228045یا .)4228045
مثال )4الگوی تطابق زیر را در نظر بگیرید .این الگوی تطابق چه شمارههایی را شامل میشود؟
exten => _[2-5]6[02468].,1, do something
ایــن الگــوی تطابق ،هر شــمارهی حداقل 4رقمی که رقم اول آن بین 2یا 3یــا 4یا ،5رقم دوم آن عدد ، 6
رقم سوم آن عدد 0یا 2یا 4یا 6یا 8و مابقی آن هر ترکیبی از حرف و عدد باشد ،را شامل میشود (از قبیل
3685یا 262zیا 5660یا .)566057ab
مثال )5الگوی تطابق زیر را در نظر بگیرید .این الگوی تطابق چه شمارههایی را شامل میشود؟
exten => _[0-9a-zA-Z].,1, do something
ایــن الگــوی تطابق ،هر شــمارهی حداقــل دو رقمی که رقم اول آن بیــن ( 0تا ) 9یا ( aتــا )zیا ( Aتا ) Z
و رقــم دوم آن هــر ترکیبی از قبیل حرف یا عدد باشــد (مثل 0912117یــا 0098912117یا z0912117یا
aZ0912117یا )0Az912117را شامل میشود.
منظور از حداقل رقم این است که باید 2رقم و یا بیشتر از 2رقم (تا بینهایت) داشته باشیم.
مثال )6به عنوان یک مثال کاربردی فرض کنید بخواهیم الگوریتم الگوی تطابق را برای چهار سطح متفاوت
تعریف کنیم:
-1داخلیهای یک سیستم :در این سطح فقط این قابلیت وجود دارد که بتوانیم داخلیهای 3رقمی داخل
مجوعه را شمارهگیری کنیم.
][local
)}exten => _ZXX,1,Dial(SIP/${EXTEN
-2تماسهای درون شهری :در این سطح فقط این قابلیت وجود دارد که بتوانیم شمارههای دورن شهری
(هشت رقمی) را شمارهگیری کنیم.
][provinc
)}exten => _ZXXXXXXX,1,Dial(DAHDI/g0/${EXTEN
-3تماسهای برون شــهری-بین استانی :در این سطح فقط این قابلیت وجود دارد که بتوانیم شمارههای
برونشهری -بین استانی را شمارهگیری کنیم.
][national
)}exten => _0Z.,1,Dial(DAHDI/g0/${EXTEN
-4تماسهای برونکشوری :در این سطح فقط این قابلیت وجود دارد که بتوانیم شمارههای برونکشوری
را شمارهگیری کنیم.
][national
)}exten => _00Z. ,1,Dial(DAHDI/g0/${EXTEN
131 برنامهنویسی مقدماتی در استریسک
پر واضح اســت که هر شــماره ســه رقمی با اعداد بین 0تــا 9را بگیریم با این الگــو مطابقت دارد ،لذا
با اســتفاده از متغیر{ $}EXTENمتوجه میشــویم که چه شــمارهای گرفته شدهاســت .بــرای این منظور از
متغیر{ $}EXTENاستفاده میکنیم که به شماره گرفتهشده ،اشاره دارد.
)}exten => _X.,1,NoOp(${EXTEN
در ایــن حالــت اولین رقم آن (رقم )9از ابتدای شــماره حــذف و بقیه ارقام به عنوان شــماره در نظر گرفته
میشوند.
الگوی استفاده از متغیر{ $}EXTENبه صورت زیر است:
} ${EXTEN : x : y
به عنوان مثال فرض کنید شماره 98169671111را شمارهگیری کردهایم .هرکدام از متغیرهای زیر چه
زیرشمارهای از شماره اصلی را برمیگرداند:
)}exten => _X.,1,NoOp(${EXTEN
لذا اســتفاده از الگوریتم الگوی تطابق باعث میشود که بتوانیم با استفاده از متغیر{ $}EXTENهر ترکیبی از
شماره مورد نظر خود را استخراج و از آن استفاده نماییم.
اکنون کدام یک از الگوهای زیر دارای دامنه کمتری از اعدادند؟ پر واضح اســت که الگوی تطابق اول
دامنــهی کمتری دارد ،پــس در تکنیک MAX Match Patternاین الگو دارای اولویت باالتری اســت .لذا
اگر شــمارهای را بگیریم که در هر دو الگوی تطابق صدق کند ،دســتور اول اجرا میشــود .میتوان در یک
133 برنامهنویسی مقدماتی در استریسک
همانطورکه مالحظه میکنید در این برنامه الگوهای تطابق متفاوتی وجود دارد .اکنون فرض کنید بخواهیم
شماره 6199را شمارهگیری کنیم ،سوال اینجاست که کدام یک از الگوها در نظر گرفته خواهد شد؟
ایــن نکته را در نظر داشتهباشــید کــه اولویت در تعریف الگوهای تطابق ،مــاک انتخاب الگوی تطابق
نیســت .سیستم تلفنی استریسک به صورت خودکار با در نظر گرفتن تکنیک MAX Match Patternالگوی
تطابق مناسب را استفاده میکند.
شــاید ســوالی مطرح شود که استریســک کدامیک را ابتدا انتخاب میکند؟ در پاســخ به این سوال باید
بگوییم که اســتفاده از یک دســتور ســاده در محیط کامند الین استریسک میتواند پاســخ خوبی برای این
پرسش باشد:
در محیط کامند الین استریسک دستور زیر را اجرا کنید:
CLI> dialplan show 6199@example_context
] ›[ Context ‹example_context› created by ‹pbx_config
>= ›‹_6199 1. do something ][pbx_config
‹_6[1-9][1-9][1-9]› => 1. do something ][pbx_config
>= ›‹_6X. 1. do something
همانطورکه مالحظه میکنید دستورات بر اساس اولویت الگوهای تطابق مرتب شدهاند.
بنابرایــن توجه داشتهباشــید که ممکن اســت الگوهــای تطابق که تعریــف میکنید ،با هم همپوشــانی
داشتهباشند .در این حالت از تکنیک فوق برای انتخاب الگوی تطابق استفاده میشود.
مرجع آموزش ویپ با سافتسوئیچ استریسک 134
آنچه تاکنون درباره الگوی تطابق توضیح دادیم ،براســاس شماره گرفته شده ( )DID Numberبود .این
فرآیند الگوی تطابق میتواند برای شمارۀ تماس گیرنده ( )Caller IDنیز اتفاق بیافتد .برای استفاده از الگوی
تطابق برای شماره تماس گیرنده از فرمت زیر استفاده کنیم:
)(exten => extension/_pattern,1, dosomething
بــرای مثال فــرض کنید چنانچه فردی با شــمارهای خاص )مثل موبایل( با شــما تماس بگیــرد ،قصد دارید
پروسهای خاص برای او اجرا کنید:
)exten => _X. / _9891. ,1,Goto(Mobile_context,s,1
در این مثال اگر فردی با شماره موبایل تماس بگیرد ،این تماس با الگوی باال تطابق داشته و تماس به سمت
کانتکست مربوطه هدایت میشود و دستورات آن اجرا میگردد .
البته در شــبکه مخابراتی ایران ،شــمارههای موبایل ممکن اســت به یکی از این روشها برای شما ارسال
شود:
91
9891
009891
00009891
در این حالت باید بتوانید با اســتفاده از تکنیکهایی که قب ً
ال توضیح دادیم ،ارقام اصلی آن را تشخیص دهید
و آنها را استخراج کنید.
شکل 5-5
برای مثال شــکل 5-5را در نظر بگیرید .در این شــکل سه کانتکســت متفاوت تعریف شدهاست .کانتکست
ســیاه میتواند به کل کانتکستهای خاکستری و سفید دسترســی داشتهباشد .کانتکست خاکستری میتواند
135 برنامهنویسی مقدماتی در استریسک
به کانتکســت سفید دسترســی داشتهباشــد .ولی عکس این موضوع صادق نخواهدبود .اگر بخواهیم با زبان
ریاضی این موضوع را بیان کنیم ،بهصورت زیر خواهد بود :مجموعه سفید ،زیرمجموعه خاکستری و هر دو
زیرمجموعه سیاه خواهند بود.
white ⊆ grey
white,grey ⊆ black
برنامهی مربوط به عبارت فوق بهصورت زیر است:
][white
)(exten => 301,1,NoOp
][grey
)(exten => 201,1,NoOp
include => white
][black
)(exten => 101,1,NoOp
include => grey
برای روشنتر شدن موضوع ،به یک مثال کاربردی از استفاده و کاربرد includeاکتفا میکنیم.
فرض کنید کاربرهایی با نام Phone1و Phone2در سیستم تعریف شدهباشند:
;sip.conf
][phone1
context=white
][phone2
context=black
کاربر phone۱سعی میکند شماره ۲۰۱را شمارهگیری نماید .چون در این کانتکست ] [whiteبرای شماره
۲۰۱هیچ رولی در نظر گرفته نشده است ،لذا خطایی مبنی بر اینکه چنین رولی در کانتکست ] [whiteوجود
ندارد در محیط کامند الین استریسک مشاهده خواهیدکرد.
حال فرض کنید کاربر Phone2شماره 201را شمارهگیری نماید ،در این کانتکست [ ]blackهم برای شماره
201هیچ رولی تعریف نشده است ،ولی چون کانتکست [ ]grayبه این کانتکست [ ]blackاضافه شدهاست ،1لذا
استریسک در آن کانتکست هم به دنبال رول مورد نظر (شماره )201میگردد .در صورتی که آن را پیدا کند،
اجرا میکند.
بنابراین میتوان با استفاده از includeکردن رولها و قوانین در یک کانتکس دیگر ،از آنها نیز استفاده
1- include
مرجع آموزش ویپ با سافتسوئیچ استریسک 136
نمود .البته استفاده از includeملزم به رعایت قوانین مربوط به آن است که باعث میشود در ایجاد و اجرای
برنامههای بزرگتر ،با خطاهای منطقی روبرو نشویم .در ادامه به بررسی آنها خواهیم پرداخت.
][context_b
)exten => 333,1,Playback(letters/b
][context_c
)exten => 333,1,Playback(letters/c
فرض کنید کاربر Phone1شماره 333را شمارهگیری نماید به نظر شما خروجی دستور چه چیزی خواهد بود؟
البته از خواننده کتاب درخواست میکنیم قبل از اینکه پاسخ سوال را در ادامه مطالعه کند ،اندکی راجع به این
موضوع تأمل نماید.
بعد از شــمارهگیری 333توسط کاربر ،Phone1کنترل برنامه به ســمت [ ]context_aمیآید و چون هیچ
رولی برای شــماره 333در این کانتکست وجود ندارد ،کنترل برنامه به سمت کانتکست [ ]context-bمیرود.
در کانتکست [ ]context_bبرای اکستنشن 333یک تعریف وجود دارد ،بنابراین دستور (Playback (letters/b
1- troubleshooting
137 برنامهنویسی مقدماتی در استریسک
اجرا میشود.
اکنون فرض کنید برنامه را به شکل زیر تغییر دهیم.
][context_a
include => context_c
include => context_b
][context_b
)exten => 333,1,Playback(letters/b
][context_c
)exten => 333,1,Playback(letters/c
با اجرای مجدد سناریوی قبل و شمارهگیری عدد ،۳۳۳خروجی دستور ) Playback (letters/cخواهد بود.
برای فهم بهتر مطلب ،مثال زیر را به دقت بررسی کنید .فرض کنید برنامهی زیر را داشته باشیم:
][context_1
)exten => 1,1,Playback(letters/a
)exten => 1,n,Goto(1
include => context_2
][context_2
)exten => 1,1,Playback(letters/b
)exten => 1,n,Goto(1
خروجــی دســتور زیر چه خواهــد بود؟ به عبارتی دیگر اگــر کاربر عدد ۱را بگیرید ،چه دســتوراتی اجرا
میشوند؟
CLI> console dial 1@context_1
در این مثال دســتور ) Playback (letters/aاجرا و در ادامه دســتور ( Goto(1اجرا میشــود .این دستور
کنترل برنامه را به اولویت اول همان کانتکســت و اکستنشــن منتقل میکند .پس برنامه در داخل یک loop
قرار میگیرد و هر دفعه دستور ) Playback (letters/aاجرا میشود.
به عنوان مثالی دیگر ،این برنامه را در نظر بگیرید:
][context_1
)exten => 1,1,Playback(letters/a
)exten => 1,n,Goto(1
include => context_2
مرجع آموزش ویپ با سافتسوئیچ استریسک 138
][context_2
)exten => 1,1,Playback(letters/b
)exten => 1,n,Goto(1
خروجی دستور زیر چیست؟ به عبارت دیگر اگر کاربر عدد ۲را شمارهگیری کند ،خروجی دستور چه
خواهدبود و چه برنامهای اجرا میشود؟
CLI> console dial 2@context_1
از آنجاکــه اکستنشــن 2در داخــل [ ]context_1وجــود نــدارد ،اجــرای دســتور در [ ]context_2ادامه
مییابــد .در داخــل ایــن کانتکســت برای اکستنشــن 2یــک رول تعریف شدهاســت ،لذا برنامــهی مربوط
بــه آن اجــرا میشــود .به ایــن ترتیــب کــه ابتــدا دســتور ( playback (letters/cاجرا میشــود؛ بــا اجرای
دســتور ( Goto(1,1برنامــه بــه اولویــت اول اکستنشــن 1در کانتکســت [ ]context_1میرود و دســتور
( playback (letters/aاجــرا میشــود؛ ســپس برنامــه وارد یــک loopمیشــود کــه در آن فقط دســتور
( playback (letters/aاجرا میشود.
][context_1
)exten => 1,1,Playback(letters/a
)exten => 1,n,Goto(1
include => context_2
][context_2
)exten => 1,1,Playback(letters/b
)exten => 1,n,Goto(1
همانطورکه مالحظه میکنید تفاوت زیادی بین کانتکستها و دستورات وجود دارد ،بهطوریکه ممکن است
خطاهایی منطقی در سیســتم ایجاد کند .در مثال فوق دقت داشته باشید که دستور ( Goto(1,1مشخص شده به
[ ]context_1اتصال داده میشود.
139 برنامهنویسی مقدماتی در استریسک
][context_2
)exten => 1,1,Playback(letters/b
)exten => 1,n,Goto(1
در این حالت ابتدا دستور ) Playback (letters/dاجرا میشود؛ سپس توسط دستور ) Goto(context_2,2,1به
کانتکست ] [context_2انتقال داده و دستور ) Playback (letters/cپخش میشود .دستور ) Goto(1,1در این
حالت به سمت کانتکست ] [۱_contextنخواهد رفت بلکه در همان کانتکست ] [context_2میماند و دستور
) Playback (letters/bاجرا میشود.
فایلهای تو در تو در فایل سیســتم استریسک استفاده کرد .اســتفاده از includeدر فایل سیستم استریسک
باعث کوچکتر شــدن فایلها در استریسک شده و بررسی و خطایابی را در استریسک آسانتر میکند .به
عنوان مثال به جای آنکه تمام برنامهها را در استریســک در فایل extensions.confبنویسیم ،بهتر است یک
فایل دیگر را به شــکل ضمیه این فایل تعریف کنیم و از آن به عنوان فایل پیوســتی استفادهکنیم و برنامههای
خود را درون آن بنویسیم.
برای مثال فرض کنید بخواهیم برنامههای خود را در فایل دیگری بنویسیم .یک فایل جدید با نام دلخواه
در مسیر دلخواه به صورت زیر بسازید.
#vim /etc/asterisk/routes_extensions.conf
ســپس برنامههــا را داخل آن اضافه میکنیم .دقت داشــته باشــید قوانین نوشــتن برنامه دقیقــاً همانند فایل
extensions.confاست.
][new_context
)exten => 111,1,NoOp(This is new file that included to estension.conf
)same => n,NoOp(This syntax is the same as extensions.conf files
)(same => n,Habgup
اکنون برای آنکه این فایل جدید بوســیله استریسک قابل شناساییباشد ،باید آن را به صورت زیر در انتهای
فایل extensions.confاضافه کنیم:
#include routes-extensions.conf
در ایــن حالــت میتوانیم در فایلهای جدیــد ،همانند فایــل extensions.confبرنامههــای خود را درج و
اجرا کنیم .در فصول بعد موارد پیشــرفتهتری از برنامهنویســی در استریســک خواهد آمد و بررسی عمیقتر
برنامهنویسی در استریسک پیگرفته خواهد شد.
نتیجه گیری
همانطورکه پیشتر نیز بیان شد ،ازآنجاکه این فصل یکی از فصلهای اولیه و مهم در برنامهنویسی استریسک
اســت ،اگر ابهامی در این فصل وجود داشته باشد ،در ســایر فصلها این ابهامات تشدید خواهد شد .بنابراین
الزم است کلیه مطالب این فصل بهصورت دقیق و با جزئیات بررسی و مطالعه شوند و همه مثالهای آن دست
کم یک بار بهصورت عملی تست و اجرا شوند.
فصل ششم
در فصل پنجم در خصوص برنامهنویســی در استریســک توضیح دادیم .در این فصل و فصل بعد در مورد
ارتباط دادن سیســتم تلفنی استریسک با سایر شبکههای ارتباطی )شــبکههای مخابراتی PSTNو شبکههای
مبتنی بر (VoIPمطالبی ارائه خواهیم نمود.
ازآنجاکه تکنولوژی برقراری ارتباط در این دو بستر مخابراتی با یکدیگر متفاوت است ،توضیحات مقدماتی
در این خصوص ضروری است .برای مثال وقتی بخواهیم یک سیستم تلفنی استریسک را به شبکههای مخابراتی
PSTNیــا یک شــبکه ویپ دیگر ( )VoIP Providerمتصل کنیم ،روشهــای متفاوتی وجود دارد .با اینکه
تکنولوژی ارتباطی در هر دو روش کام ً
ال با هم متفاوت اســت ،استریســک هر دو روش ارتباطی را بهصورت
یکسان درنظر میگیرد.
در این فصل ابتدا در خصوص شــبکههای مخابراتی PSTNو انواع تکنولوژیهای آن صحبت میشود
و ســپس درباره ماژول DAHDIو پیکر بندی آن توضیحاتی ارائه خواهد شد ،بهنحویکه خواننده به دالیل
اســتفاده از ماژول DAHDIواقف شــود .پس از آن انواع شیوههای ارتباطی بررسی میشوند .در فصل بعد
به ارتباط سیستم تلفنی استریسک با سایر شبکههای VoIPمیپردازیم و انواع ارتباطات را بررسی و مقایسه
میکنیم.
در فصــل اول در خصوص شــبکههای مخابراتی PSTNمطالبی مقدماتی عنوان شــد .در این فصل در
مورد انواع خطوط ارتباطی در شبکههای PSTNو نحوه ارتباط آنها در سیستم تلفنی استریسک توضیحات
بیشتری خواهد آمد.
ازآنجاکه در شــبکههای مخابراتی PSTNدو نوع خطوط مخابراتی داریم ،بررســی روشهای ارتباط با
143 ارتباط استریسک با شبکههای مخابراتی
خطوط آنالوگ
منظور از این خطوط ،همان خطوط تلفنی معمولی است .این خط پس از برداشتن گوشی و شنیدن بوق آزاد،3
64کیلوبیت پهنای باند را از مرکز مخابراتی رزرو میکند .ازجمله دالیل استفاده از خطوط آنالوگ میتوان
به موارد زیر اشاره کرد:
-1نبود خطوط دیجیتال در یک منطقه؛
-2هزینه اندک؛
-3نگهداری خطوط قبلی.
-سیگنالینگ FXS :5 FXSدرگاهی است که برق (یا سیگنال بوق) را تولید میکند .از این درگاه برای اتصال
گوشیهای معمولی به سیستم استفاده میشود.
شکل 1-6
شــکل 1-6نحوه انتقال صوت در خطوط دیجیتال را نشــان میدهد .ازجمله مزایای خطوط دیجیتال میتوان
به موارد زیر اشاره کرد:
)1بیتأثیر بودن افت ولتاژ برای فاصلههای دور؛
)2کاهش تأثیر نویز؛
)3توانایی انتقال بیش از یک کانال در بستر ثابت؛
)4سرعت باالی برقراری تماس.
2
N-ISDN
فناوری N-ISDNبهدلیل ســرعت نهچندان باال ،در انتقــال دادهها و صدا برای کاربردهای خانگی و تجاری
اســتفاده میشود .برای مثال اکثر خطوط PRIخانگی از نوع N-ISDNاند که بهصورت لینکهای E1/T1/
J1ارائه میشوند .این فناوری بهنام Normal-ISDNنیز نامگذاری شدهاست.
3
ISDN-PRI
ISDN-PRIیکی از استانداردهای خطوط دیجیتال است که دارای استانداردهای اروپایی ) ، (E1آمریکایی
) (T1و ژاپنی ) (J1اســت .در خطوط تلفنی معمولی )آنالوگ( صرفاً یک کانال برای ارتباط داریم ولی در
این خطوط تعداد کانالها بیش از یک است .مث ً
ال در استاندارد آمریکایی ) ۲4 (T1کانال ارتباطی داریم که
۲۳کانال برای انتقال دادههای دیجیتالی ) (D-Channelsو یک کانال برای دادههای کنترلی و ســیگنالینگ
) (B-Channelاستفاده میشود .تعداد کانالها در استاندارد اروپایی ) (E1به اینگونهاست که ۳۰کانال برای
انتقال دادههای دیجیتالی ) (D-Channelsو یک کانال برای دادههای کنترلی و ســیگنالینگ )(B-Channel
اختصاص داده میشود.
درصورتیکه فاصله مرکز مخابرات با مشترک بیش از ۱۵۰متر باشد ،برای استفاده از لینکهای E1/T1
باید از دو دستگاه مودم 1 HDSLبا دو سر ارتباط استفاده کرد .معموالً یک دستگاه در مخابرات منطقه و
دستگاه دیگر در مرکز مشترک نصب میشود.
ISDN-BRI
ISDN-BRIیکی از اســتانداردهای خطوط دیجیتال اســت که از دو کانال برای انتقال دادههای دیجیتالی و
استفاده میکند. یک کانال برای دادههای کنترلی و سیگنالینگ
این نوع ســیگنالینگ جهت ارتبــاط مراکز موجود با یکدیگر اســتفاده میگردد و همواره ســیگنالها روی
کانالهایی که ترافیک تلفنی را حمل مینمایند ،بین مراکز رد و بدل میشود.
در ایــن تکنولوژی به ازای هر 30کانــال ترافیک تلفنی صدا ،یک کانال ســیگنالینگ داریم و همزمان
با ارســال ســیگنالینگ برای برقراری ارتباط ،کانالهای ارتباطی به منظور حمل ترافیک صدا نیز باید برقرار
گردد .اینیکی از معایب بزرگ این نوع سیگنالینگهاســت .عالوه بر این به دلیل انعطافپذیری بســیارکم
سرویسدهی (با توجه به افزایش روزافزون سرویسها) ،این سرویس عم ً
ال کارایی الزم را ندارد.
3
سیگنالینگ کانال مشترک
از این نوع ســیگنالینگ همانند ســیگنالینگ ) (CASبه منظور برقراری ارتباط میان مراکز موجود اســتفاده
میشود .به دلیل افزایش سرعت ارسال سیگنالها ،یک کانال سیگنالینگ قادر به حمل حدود 8۰۰تا ۱۰۰۰
کانال ترافیک تلفنی صدا و اجرای مدیریت شــبکه است .در این نوع سیگنالینگ ،کانال سیگنالینگ مستقل
از کانال دیتاست؛ بنابراین مسیر سیگنالینگ و مسیر دیتا میتوانند از یکدیگر بطور کامل جدا باشند.
یکی دیگر از مزایای بسیار مهم این نوع سیگنالینگ ،تشخیص و بررسی وضعیت مشترک ،پیش از اشغال
کانال برای انتقال دیتاست .یعنی ابتدا وضعیت مشترک بررسی میشود و در صورت آزاد بودن آن و آمادگی
تماس ،فرمان ایجاد کانال دیتا از مشترک Aبه مشترک Bصادر میگردد .این امر باعث میشود بار ترافیکی
1- High-Bit-Rate Digital Subscribe Line
)2- Channel associated signaling (CAS
)3- Common Channel Signaling (CCS
مرجع آموزش ویپ با سافتسوئیچ استریسک 146
اضافی برای تماسهای ناموفق بهدلیل مشــغول بودن یا عدم امکان دسترســی به مشترک انتهایی روی مراکز
تحمیل نشود و درنتیجه از کاهش معیار مخابراتی ASRجلوگیری گردد.
تئوری نایکوئیست-شانن
تئوری نمونهبرداری نایکوئیســت ثابت میکند که اگر قصد نمونهبرداری از یک ســیگنال را داشــته باشیم،
بایــد دو برابر پهنای بانــد موجود ،نمونهبرداری کنیم تا طیف فرکانســی آنها باهم تداخل نکنند .براســاس
تئوری نمونهبرداری نایکوئیست ،از صدا نمونهبرداری میشود ،سپس کوانتایز شده و بهصورت باینری ارسال
میشود.
مطابق تئوری نایکوئیست در تلفنهای معمولی ،صدا را از فیلتر فرکانسی 4کیلوهرتز عبور میدهیم .همچنین
بهمنظور بازســازی سیگنال نمونهبرداری شده در مقصد باید نمونهبرداری را با 8کیلوهرتز انجام دهیم .از طرف
دیگر چون ما 8ســطح کوانتایز در شــبکه مخابراتی PSTNداریم ،حاصلضرب آنهــا عدد 64کیلوهرتز را
میدهد که معرف پهنای باند مصرفی در شبکههای مخابراتی PSTNاست.
پهنای باند در شبکههای مخابراتی PSTNبهصورت تضمینشده است و در یک ارتباط تلفنی ساده ،پهنای
باند رزرو شده از شبکه مخابراتی 64×2 ، PSTNکیلوهرتز است.
8khzنرخ نمونه برداری × 8سطح کوانتایز= ) ۶4khzپهنای باند مصرفی برای یک تلفن شهری(
شکل 2-6
شکل 3-6
برای ارســال صدا بهصورت دیجیتال ،ابتدا صدای اولیه باید از فیلتر 4کیلو هرتز که در شــکل ۳-۶با نام
low-pass filterمشــخص شــده اســت ،بگذرد تا فرکانسهای اضافی و غیرقابل انتقال حذف شوند .سپس
بــهازای هر ثانیه 8۰۰۰ ،بار از صدای اصلی نمونه برداری میشــود )تئوری نایکویســت( که به آن sampler
میگویند .در گام بعدی بهازای هر سطح دامنه صدا ،یک معادل قرار میدهند و سطح صدا را تا نزدیکترین
ســطوح آن گــرد میکنند که بــه آن quantizerمیگویند )خروجی هر دو عملیات در شــکل ۳-۶نشــان
برنولی بیان میکنند که این عملیات بهوسیله encoder دادهشــده اســت( .در انتها هر ســطح را با یک مقدار
انجام میشود.
DAHDIچیست؟
نــام قدیمیتــر ایــن محصول Zaptelبود ،ولــی به این دلیل که یک شــرکت با همین نام تجــاری در زمینه
مرجع آموزش ویپ با سافتسوئیچ استریسک 148
کارتهای تلفنی وجود داشــت ،شــرکت دیجیوم ناچار به تغییر دادن نام این محصول تجاری شد و آن را به
DAHDIتغییر داد.
DAHDIیک تکنولوژی متن باز برای کنترل کارتهای تلفنی دیجیوم و سایر برندهاست .این سرویس
دارای درایورهایی اســت که قادر اســت ســختافزارهای کارتهای تلفنی را به استریسک و سیستم عامل
لینوکس بشناساند و آنها را کنترل و مانیتور کند.
برخی فرآیندها در استریســک نیــاز به همزمانی دارند .برای مثال برنامه کنفرانس تلفنی در استریســک
نیازمنــد همزمانــی بین همه کانالهاســت .در این حالت نیاز بــه ماژولی داریم که ایــن همزمانی را بهوجود
آورد .بــرای اســتفاده از همزمانی هنگام ایجاد یک کنفرانس در استریســک ،باید لزومــا از ماژولی که این
همزمانــی بین کانالها را ایجاد کند ،اســتفاده گردد .این ماژول همزمانی ،ازســوی استریســک و همچنین
ازسوی ماژول DAHDIفراهم میشود .برخی از برنامهها در استریسک )از قبیل دستور ( MeetMeاز ماژول
res_timing_dahdi.soبرای همزمانی بین کانالها اســتفاده میکنند .بنابراین ،وابستگی به ماژول DAHDI
در برخی از برنامههای استریســک وجود دارد .اگر چه برنامههای مشــابهی مثل ConfBridgeوجود دارند
که جایگزین مناســبی برای برنامه MeetMeهســتند و از ماژولهای خود استریسک برای همزمانی استفاده
میکنند ،بهتر اســت همیشه ماژول DAHDIرا در کنار استریســک نصب داشته باشیم؛ حتی زمانی که هیچ
ارتباطی با شبکههای مخابراتی PSTNنداشته باشیم .زمانی که از Gatewayها برای اتصال خطوط شهری به
سیســتم تلفنی استریسک اســتفاده میکنیم ،به ماژول DAHDIنیاز نداریم ،ولی بهتر است این ماژول را هم
هنگام نصب استریســک نصب کنیم .شــکل 4-۶نحوه ارتباط ماژول DAHDIبا استریسک و سیستم عامل
لینوکس را نشان می دهد.
شکل 4-6
149 ارتباط استریسک با شبکههای مخابراتی
:DAHDI-tools -۱در این کامپوننت ابزارها و دســتوراتی برای مدیریت ارتباط سیســتم تلفنی استریسک با
شــبکههای مخابراتی PSTNفراهم شدهاســت .از جمله این دستورات میتوان به dahdi_cfg, dahdi-scan,
dahdi-hardwareو ...اشــاره کرد .هر کدام از دستورات فوق کاربرد مشخصی دارند .در ادامه توضیحات
بیشتری درباره آنها خواهد آمد.
:DAHDI-linux -۲این کامپوننت فراهم کننده کرنل درایورهای ســختافزاری برای کارتهای DAHDI
است .به عبارت دیگر درایور سختافزاری برای کارت بهوسیله این کامپوننت فراهم میشود.
در اکثر نسخههای DAHDIکه دانلود میکنید ،هر دو کامپوننت در قالب نام dahdi-linux-complete-
currentقرار دارند .برای مثال دستورات زیر را در نظر بگیرید.
# tar –zxvf dahdi-linux-complete-current.tar.gz
# cd dahdi-linux-complete2.6.1+2.6.1/
همانطورکه مالحظه میکنید ،بعد از اینکه بسته ماژول DAHDIرا از حالت فشرده خارج کردیم ،نام آن به
همراه اعدادی مانند ) (2.6.1+2.6.1ذخیره شــد .نکته مهم در اینجا این است که این اعداد ،ورژن کامپوننت
را مشخص میکنند .عدد اول )سمت چپ عالمت ( +ورژن کامپوننت DAHDI-linuxو عدد دوم )سمت
راست عالمت ( +ورژن کامپوننت DAHDI-toolsرا مشخص میکنند .نحوه نصب این بسته در فصل سوم
کام ً
ال شرح داده شد.
بعد از نصب ماژول ، DAHDIمســیر فایلهای پیکربندی در /etc/dahdi/قرار میگیرد .دو فایل مهم به نام
modulesو system.confدر این شــاخه وجود دارند .هر کدام از این فایلها قســمتی از پیکربندی ماژول
DAHDIرا انجام میدهند.
فایل modules
ازآنجاکه کارتهای ســختافزاری متنوعی وجود دارد و هر کدام ســاختار منحصر بــه فرد خود را دارند،
ازطریق این فایل میتوان مشــخص کرد که ماژول ،DAHDIکدامیک از این نوع کارتها را باید پشتیبانی
کند یا اینکه کدامها باید غیرفعال شــوند .با غیرفعال کردن یک ماژول خاص DAHDI ،قادر به شناســایی
آن کارت سختافزاری نخواهد بود .برای مثال فرض کنید بخواهیم فایل modulesرا باز کنیم .دستور زیر
مرجع آموزش ویپ با سافتسوئیچ استریسک 150
این اطالعات را مشاهده، بعد از باز شدن فایل.البته میتوانید این فایل را با هر ویرایشگر دیگری نیز باز نمایید
:میکنید
#
# NOTE: Please add/edit /etc/modprobe.d/dahdi or /etc/modprobe.conf if you
# would like to add any module parameters.
#
# Format of this file: list of modules, each in its own line.
# Anything after a ‹#› is ignore, likewise trailing and leading
# whitespaces and empty lines.
همانطورکه مالحظه میکنید در این فایل ابتدا نوع کارتهای ســختافزاری مشخص شدهاند که بهصورت
توضیحات)با عالمت (#آورده شده است و بعد از آن نام ماژول موردنظر بصورت Boldمشخص شدهاست.
ما میتوانیم ماژولهایی را که نیاز نداریم با گذاشتن عالمت » « #غیرفعال کنیم.
بعد از راهاندازی مجدد ســرویس dahdiمشــاهده خواهید کرد که همه ماژولهای موجود در این فایل
مجددا ً راهاندازی شدهاند.
#/etc/init.d/dahdi restart
Unloading DAHDI hardware modules: done
Loading DAHDI hardware modules:
wct4xxp: done wcte43x: done wcte12xp: done wcte13xp: done wct1xxp: done
wcte11xp: done wctdm24xxp: done wcaxx: done wcfxo: done wctdm: done wcb4xxp:
done wctc4xxp: done xpp_usb: done
Running dahdi_cfg: done.
در نظر داشــته باشــید که ما گاهی از برندهای خاصی در تجهیزات ســختافزاری برای ارتباط با شبکههای
PSTNاســتفاده میکنیم .در این حالت ماژول سختافزاری آن تجهیزات لزوما باید بهصورت دستی به این
فایل اضافه شود .در راهنمای نصب تجهیزات مورد نظر ،نام ماژول آورده شده است و لزومی ندارد نسبت به
این موارد نگران باشید .همچنین میتوانید با استفاده از دستور زیر ماژول مورد نیاز برای کارتها را مشاهده
نمایید.
#dahdi-hardware
همانطورکه مالحظه میکنید نام ماژول مورد نیاز برای فعال شــدن این کارت ســختافزاری مشخص شده
است.
فایل system.conf
ایــن فایل مهمترین فایل در بخش پیکربندی تجهیزات کارتهای ســختافزاری اســت .بهوســیله این فایل
تعریف دقیقی از نوع کارت ســختافزاری و کاربرد آن خواهیم داشت .ازآنجاکه پیکربندی این فایل کمی
پیچیده و دشوار بهنظر میرسد ،ابزاری به نام dahdi-genconfدر کامپوننت DAHDI-toolsوجود دارد که
با اجرا کردن آن ،پیکربندی این فایل بهصورت خودکار صورت میگیرد.
#dahdi_genconf
مرجع آموزش ویپ با سافتسوئیچ استریسک 152
چنانچــه پس از اجرای این دســتور ،فایــل system.confرا بــاز کنیم ،متوجه خواهیم شــد که تنظیمات و
پیکربندی تجهیزات در این فایل انجام شدهاســت .ازآنجاکه پیکربنــدی تجهیزات FXO/FXSبا تجهیزات
کارتهــای PRIمتفاوتند ،درخصوص پیکربندی این فایل بهصورت دســتی و معرفی بخشهای آن بیشــتر
صحبــت خواهیم کــرد؛ ولی قبل از آن برخی از دســتورات مهم در کامپوننت DAHDI-toolsرا بررســی
میکنیم.
دستورات مهم
• :lspciیک دســتور لینوکســی است که لیستی از تجهیزات متصل شــده از طریق اسالید PCIو PCI-Eرا
نشان میدهد .این دستور از کتابخانهی libpciاستفاده میکند.
• :lsdahdiاین دستور لیستی از تمامی کانالهای dahdiبه همراه نوع آنها و شماره spanرا نشان میدهد.
• :dahdi_cfgاین دستور فایل system.confرا خوانده و گزارشات پیکربندی را نشان میدهد.
• :dahdi_genconfاین دســتور فایل system.confرا ســاخته و آن را بر اســاس تجهیزات ســختافزاری
موجود پیکربندی میکند .چنانچه بهصورت دســتی تغییراتی در فایل ایجاد کردهباشیم ،با اجرای این دستور
کلیه تغییرات از بین خواهدرفت.
• :dahdi_hardwareاین دســتور نمایشــی از همه تجهیزات سختافزاری شناخته شده بهوسیله DAHDIبه
همراه ماژولهای مورد نیاز را نشان میدهد.
• :dahdi_monitorبا این دستور میتوانید صدای تولید شده در کانال را ضبط کنید.
• :dahdi_scanاین دستور لیستی از تنظیمات کانالهای DAHDIرا با برخی از مشخصهها نشان میدهد.
• :dahdi_testاز این دستور برای بررسی دقت DSPروی کارتهای FXO/FXSاستفاده میشود.
• :dahdi_toolاین دســتور یک محیط گرافیکی اســت برای اینکه مشخص کند چه تجهیزاتی روی سیستم
وجود دارند و چه کاری انجام میدهند.
در ادامه به بررسی مثالهایی از دستورات باال میپردازیم و خروجیهای آنها را با هم مقایسه میکنیم.
برای مثال دستور زیر را اجرا کنید:
#lspci | grep Digium
05:04.0 Communication controller: Digium, Inc. Wildcard TE405P/TE407P quad-span T1/E1/
)J1 card 5.0V (rev 02
البته خروجیهای بیشتری هنگام اجرای دستور داریم ولی با فیلتر کردن عبارت Digiumاین خروجی مرتبط
کارت 4پورت PRIبرند دیجیوم است .همچنین خروجی دستور میتواند بهصورت زیر باشد: با
#lspci | grep Sangoma
05:04.0 Network controller: Sangoma Technologies Corp. A104d QUAD T1/E1 AFT card
خروجی زیر نشان داده، را اجرا کنیمlsdahdi دستور، استPRI چنانچه روی سروری که دارای لینک
:خواهد شد
#lsdahdi
### Span 1: TE4/0/1 "T4XXP (PCI) Card 0 Span 1" (MASTER) CCS/HDB3/CRC4 ClockSource
1 PRI Clear (In use) (EC: MG2 - INACTIVE)
2 PRI Clear (In use) (EC: MG2 - INACTIVE)
3 PRI Clear (In use) (EC: MG2 - INACTIVE)
4 PRI Clear (In use) (EC: MG2 - INACTIVE)
5 PRI Clear (In use) (EC: MG2 - INACTIVE)
6 PRI Clear (In use) (EC: MG2 - INACTIVE)
7 PRI Clear (In use) (EC: MG2 - INACTIVE)
8 PRI Clear (In use) (EC: MG2 - INACTIVE)
9 PRI Clear (In use) (EC: MG2 - INACTIVE)
10 PRI Clear (In use) (EC: MG2 - INACTIVE)
11 PRI Clear (In use) (EC: MG2 - INACTIVE)
12 PRI Clear (In use) (EC: MG2 - INACTIVE)
13 PRI Clear (In use) (EC: MG2 - INACTIVE)
14 PRI Clear (In use) (EC: MG2 - INACTIVE)
15 PRI Clear (In use) (EC: MG2 - INACTIVE)
16 PRI HDLCFCS (In use)
17 PRI Clear (In use) (EC: MG2 - INACTIVE)
18 PRI Clear (In use) (EC: MG2 - INACTIVE)
19 PRI Clear (In use) (EC: MG2 - INACTIVE)
20 PRI Clear (In use) (EC: MG2 - INACTIVE)
21 PRI Clear (In use) (EC: MG2 - INACTIVE)
22 PRI Clear (In use) (EC: MG2 - INACTIVE)
23 PRI Clear (In use) (EC: MG2 - INACTIVE)
24 PRI Clear (In use) (EC: MG2 - INACTIVE)
25 PRI Clear (In use) (EC: MG2 - INACTIVE)
26 PRI Clear (In use) (EC: MG2 - INACTIVE)
27 PRI Clear (In use) (EC: MG2 - INACTIVE)
28 PRI Clear (In use) (EC: MG2 - INACTIVE)
29 PRI Clear (In use) (EC: MG2 - INACTIVE)
30 PRI Clear (In use) (EC: MG2 - INACTIVE)
31 PRI Clear (In use) (EC: MG2 - INACTIVE)
به همــراه هر کانال نوع. همه کانالها را نشــان میدهد،همانطورکــه مالحظــه میکنید خروجی دســتور
کانال، E1 نکته مهم این است که در لینکهای. و شماره کانال را نیز مشاهده میکنید۱الگوریتم حذف اکو
برای همین است که نوع پیکربندی آن با سایر کانالها. استفاده خواهد شد۲ برای سیگنالینگ و همزمانی۱۶
. برای سیگنالینگ و همزمانی استفاده میشود۲4 کانال،T1 در لینکهای.متفاوت است
1- Echo Cancellation
2- B channel
مرجع آموزش ویپ با سافتسوئیچ استریسک 154
system. این اطالعات از طریق فایل. هم پیکربندی کانالها را به ما نشــان میدهدdahdi_cfg دســتور
. بهدست میآیدconf
#dahdi_cfg –vvv
DAHDI Tools Version - 2.10.0.1
DAHDI Version: 2.10.0.1
Echo Canceller(s): MG2
Configuration
======================
SPAN 1: CCS/HDB3 Build-out: 0 db (CSU)/0-133 feet (DSX-1)
Channel map:
Channel 01: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 01)
Channel 02: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 02)
Channel 03: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 03)
Channel 04: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 04)
Channel 05: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 05)
Channel 06: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 06)
Channel 07: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 07)
Channel 08: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 08)
Channel 09: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 09)
Channel 10: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 10)
Channel 11: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 11)
Channel 12: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 12)
Channel 13: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 13)
Channel 14: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 14)
Channel 15: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 15)
Channel 16: D-channel (Default) (Echo Canceler: none) (Slaves: 16)
Channel 17: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 17)
Channel 18: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 18)
Channel 19: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 19)
Channel 20: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 20)
Channel 21: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 21)
Channel 22: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 22)
Channel 23: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 23)
Channel 24: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 24)
Channel 25: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 25)
Channel 26: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 26)
Channel 27: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 27)
Channel 28: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 28)
Channel 29: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 29)
Channel 30: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 30)
Channel 31: Clear channel (Default) (Echo Canceler: mg2) (Slaves: 31)
: شناخته شدهاند را مشاهده کنیمDAHDI همچنین میتوانیم با دستور زیر سختافزارهایی که بهوسیله
#dahdi_hardware
155 ارتباط استریسک با شبکههای مخابراتی
4پورت PRIبهوسیله درایور سختافزاری wct4xxp+ در خروجی اول همانطورکه مالحظه میکنید کارت
و در خروجی نوع دوم هم یک کارت 4پورت PRIبا درایور ســختافزاری wanpipe-شناسایی شدهاست
)به همین دلیل است که در خصوص کارتهای سختافزاری سنگوما باید لزوما درایور wanpipeرا نصب
کنیم ،چون این کارتها فقط با این درایور بهوسیله DAHDIشناخته میشوند(.
نکته مهم این اســت که کارتهای ســختافزاری با درایورهای متفاوتی شناخته میشوند .به همین دلیل
اگر این درایور بهصورت پیشفرض هنگام نصب DAHDIپشتیبانی شود ،کارت سختافزاری بدون درنگ
پس از نصب برنامه شناخته میشود ،درغیراینصورت بستههای مورد نیاز برای نصب درایور ،باید روی سرور
نصب شــوند .معموالً اغلب شرکتهای تولید کننده این نوع سختافزارها ،یک راهنمای نصب برای نصب
درایورهای مورد نیاز ارائه میکنند که پیش از نصب نرمافزار ،بهتر است مطالعه شوند.
ازآنجاکه اســتفاده از این دســتورات در بدو امر ممکن است کمی ســخت و ابهامبرانگیز باشد ،پیشنهاد
میشــود پیش از مطالعهی مباحث بعدی ،مروری بر دســتورات و خروجیهای آنها داشــته باشید .در ادامه
پیکربندی تجهیزات سختافزاری در فایل system.confبهصورت دستی بررسی میشود.
همانطورکه پیشتر آمد ،برای تنظیمات و پیکربندی ماژول DAHDIو کارتهای ســختافزاری ،از فایل
system.confاستفاده میکنیم .این فایل هنگام نصب DAHDIدر مسیر زیر تشکیل میشود.
#vim /etc/dahdi/system.conf
ازآنجاکه تنظیمات و پیکربندی کارتهای FXO/FXSبا کارتهای PRIمتفاوت اســت ،پس از باز کردن
فایل ،محتویات آن ممکن است شبیه آنچه در زیر مشاهده میکنید باشد )در صورتی که از هر دو کارتهای
FXO/FXSو PRIهم زمان استفاده کنید ،محتویات این فایل ،ترکیبی از هر دو پیکربندی را خواهد داشت(.
این قابلیت وجود دارد که تنظیمات برای کارتهای FXOبرای تک تک پورتها بهصورت جداگانه انجام
شود .مثال تنظمیات میتواند بهصورت زیر باشد:
fxsks = 1
echocanceller=mg2,1
fxsks = 2
echocanceller=mg2,2
fxsks = 3
echocanceller=mg2,3
fxsks = 4
echocanceller=mg2,4
همچنیــن این قابلیــت وجود دارد که تنظیمات بــرای کارتهای FXSبرای تک تــک پورتها بهصورت
جداگانه انجام شده باشد .این تنظمیات میتواند بهصورت زیر باشد:
fxoks = 1
echocanceller=mg2,1
fxoks = 2
echocanceller=mg2,2
fxoks = 3
echocanceller=mg2,3
fxoks = 4
echocanceller=mg2,4
همانطورکــه مالحظه میکنید ایــن تنظیمات بهصورت خودکار در زمانی که دســتور dahdi_genconfرا
157 ارتباط استریسک با شبکههای مخابراتی
اجرا کنیم ،ایجاد میشوند .پیشنهاد میشود تا حدامکان از تغییرات دستی در این فایل اجتناب شود ،ولی در
شــرایطی ممکن اســت نیاز داشته باشــیم تغییراتی در این فایل بدهیم .در ادامه مروری بر بخشهای مختلف
این فایل خواهیم داشت.
:SPAN NUMشــماره پورتها یا ترتیب کارتهایی که بهوسیله لینوکس شناخته شدهاند ،به طوری که از
یک شروع شده و به تعداد پورتها ،یکی یکی افزایش مییابد.
:TIMING SOURCEدر تکنولوژی PRIاز یک زمان برای همزمانی ارســال و دریافت دادهها اســتفاده
میشود .اکنون باید مشخص کنیم که این سیگنال همزمانی با چه ترتیبی باید انجام شود .ازآنجاکه تجیهزات
مشــتریان از دیدگاه مخابراتی در حالت slaveقرار دارند ،در چنین شــرایطی هیچگاه تولیدکننده ســیگنال
ایجاد همزمانی نخواهیم بود .در چنین شــرایطی برای ترتیب همزمانی با ســیگنال مرجع )مخابرات( باید از
عدد ۱شــروع کنیم و بهازای هر پورت ،آن را یک واحد افزایش دهیم .هنگام اســتفاده از لینکهای PRI
مخابراتی ،هیچگاه نمیتوانیم تولیدکننده ســیگنال همزمانی باشیم ،به همین دلیل این پارامتر نمیتواند صفر
باشد.
اگر خواســته باشــیم از طریق کارت PRIیک سیستم تلفنی استریسک را به یک سیستم دیگر )به غیر از
لینک مخابراتی( متصل کنیم ،بسته به اینکه کدام طرف ،تولیدکننده سیگنال همزمانی خواهد بود ،باید آن را
صفر در نظر بگیریم .برای مثال ما میتوانیم دو ســرور استریســک را از طریق لینک PRIبه هم متصل کنیم؛
در این حالت باید یکی از آنها تولید کننده سیگنال همزمانی باشد ،پس پارامتر را در آن صفر میکنیم.
انتخاب نامناسب و اشتباه همزمانی سیگنالینگ ،منجر به ایجاد نویز در صدا ،قطعی تماس ،خطا در ارسال
و دریافت فکس و کیفیت پایین صدا میشود.
:LBOفاصله بین کارت PRIو منبع تولید ســیگنال اســت که معموالً صفر در نظر گرفته میشود .از لحاظ
تکنیکی وجود فاصله بین کارت و منبع تولید سیگنال ،محدودیت ایجاد میکند .در زیر فاصله و عدد متناظر
با آن آمده است.
)0: 0 dB (CSU) / 0 - 133 feet (DSX-1
)1: 133 - 266 feet (DSX-1
)2: 266 - 399 feet (DSX-1
)3: 399 - 533 feet (DSX-1
مرجع آموزش ویپ با سافتسوئیچ استریسک 158
:FRAMINGنوع اتصال فیزیکی را مشخص میکند که برای تکنولوژی E1و T1متفاوت است.
• : E1از casیا ccsاستفاده میکنیم.
• :T1از d4یا esfاستفاده میکنیم.
• :BRIاز casیا ccsاستفاده میکنیم.
:CODINGنوع کدینگ روی خط را مشخص میکند.
• :E1از amiیا hdb3استفاده میکنیم.
• :T1از amiیا b8zsاستفاده میکنیم.
• :BRIاز amiیا hdb3استفاده میکنیم.
در خصوص تکنولوژی E1در صورت لزوم میتوان از CRC4نیز استفاده کرد.
پارامتر :bchanدر این پارامتر کانالهایی را مشخص میکنیم که برای انتقال داده (صوت) استفاده میشوند.
پارامتر :dchanدر این پارامتر کانالهایی را مشخص میکنیم که برای سیگنالینگ استفاده میشوند.
پارامتر :echocancelerنوع اکوکنسلر نرمافزاری را برای کانال مشخص میکند .انواع زیادی از الگوریتمهای
اکوکنسلر نرمافزاری وجود دارد که میتوان از آنها استفاده نمود .از مهمترین الگوریتمهای نرم افزاری اکوکنسلر
میتوان به mg2و oslecاشاره کرد .برخی دیگر از انواع اکوکنسلرها ذیال ارائه شدهاند:
)Asterisk mark echo canceller (mec
)Asterisk mark2 echo canceller (mec2
)Asterisk mark3 echo canceller (mec3
)Asterisk steve echo canceller (sec
)Asterisk steve2 echo canceller (sec2
)Asterisk kb1 echo canceller (kb1ec
)Asterisk mg2 echo canceller (mg2ec
پارامتــر loadzoneو :defaultzoneاز این تنظیمات برای مشــخص کردن نوع toneایجاد شــده بهوســیله
کارتهای DAHDIاستفاده میشود .اینجا منظور از ، toneصدای تولید شده برای انواع ringها از قبیل dial،
busy، waitcallو غیره است.
بــرای پیکربندی تنظیمات toneدر استریســک ،از دو فایل متفاوت بهــره میبریم .برای تنظیمات tone
در کارتهای DAHDIاز فایل system.confو برای تنظیمات toneدر سیســتم داخلی استریسک از فایل
indications.confاســتفاده میکنیم .در فصل سوم در خصوص فایل indications.confتوضیحات بیشتری
آمده است.
159 ارتباط استریسک با شبکههای مخابراتی
ت کارتهای FXO/FXS
تنظیما
تنظیمــات مربوط به این نوع کارتها بســیار ســادهتر از تنظیمات مربوط به کارتهای PRIاســت .در این
کارتها باید فقط دو پارامتر را مقداردهی کنیم.
پارامتر مربوط به نوع سیگنالینگ کانال :در این پارامتر نوع سیگنالینگ کانال را مشخص میکنیم .در شبکههای
مخابراتی PSTNروشهای گوناگونی برای تولید ســیگنالینگ وجود دارد .شکل 5-6این حالتها را نمایش
میدهد.
شکل 5-6
برای مثال فرض کنید کانال اول )پورت اول( کارت از نوع FXOباشد؛ تنظیمات مربوط به این پورت
بهصورت زیر خواهد بود .اینجا از Kewl Startاستفاده میشود.
fxsks = 1
echocanceller=mg2,1
ازآنجاکه کارتهای FXOباید دارای سیگنالینگ FXSباشند ،نوع سیگنالینگ را FXSتعیین میکنیم.
اکنــون فرض کنید اگر کانال دوم )پورت دوم( کارت از نوع FXSباشــد ،تنظیمــات مربوط به این پورت
بهصورت زیر است:
fxoks = 1
echocanceller=mg2,1
همانطورکه مالحظه میکنید برای کارتهای FXSباید نوع سیگنالینگ را FXOدر نظر بگیریم.
پارامتر :echocancelerنوع اکوکنسلر نرمافزاری را برای کانال مشخص میکند .این پارامتر شبیه پارامتر معادل
مرجع آموزش ویپ با سافتسوئیچ استریسک 160
در تنظیمات کارتهای PRIاســت .میتوان از انواع اکوکنســلرهای نرمافزاری که پیشتر توضیح داده شــد،
استفاده نمود.
آنچه تاکنون شرح داده شــد ،پیکربندی تنظیمات مربوط به کارتهای DAHDIدر فایلهای system.
confو modulesبود .ســؤالی که ممکن اســت مطرح شــود این اســت که بعد از پیکربندی این فایلها و
کارتهای ،DAHDIسیستم تلفنی استریسک چگونه با آنها ارتباط برقرار کرده و از آنها استفاده میکند؟.
نکته مهمی که باید دقت داشــته باشــیم این اســت که فایل system.confبــرای پیکربندی کارتهای
DAHDIدرنظر گرفته شده است ،در حالی که فایل chan_dahdi.confبرای شناسایی کارتهای DAHDI
بهوســیله استریسک است .به عبارت دیگر برای استفاده از کارتهای DAHDIدر استریسک باید ۲مرحله
را انجام دهیم:
مرحله اول شناســایی کارتها بهوســیله ماژول DAHDIو مرحله دوم ارتباط کارتهای شــناخته شده
بهوسیله DAHDIبا استریسک است .در مرحله اول از ابزارهایی نظیر DAHDI-toolsبرای مدیریت کارتها
نیز میتوانیم استفاده کنیم؛ اما برای شناسایی این کارتها بهوسیله استریسک باید از فایل chan_dahdi.conf
اســتفاده کنیم .آنچه در تعریف و شناسایی کارتها ازطریق استریسک مهم است این است که وقتی تماسی
از طریق یک کانال وارد سیستم تلفنی استریسک میشود ،چگونه باید آن را کنترل و مدیریت کنیم.
وقتی فایل chan_dahdi.confرا باز میکنید ،ممکن اســت با یک فایل طوالنی مواجه شــویم که بیشتر
نحوهی پیکربندی را توضیح میدهد .برای آشــنایی با پارامترهای موجود در این فایل ،از این راهنما استفاده
کنید.
هنــگام نصب و شناســایی برخی کارتها ،تنظیمات مربوط به این فایــل هم بهصورت خودکار صورت
میگیرد؛ اما چنانچه این تنظیمات صورت نگرفت ،باید بهصورت دســتی و به شــکل زیر تنظیمات را انجام
دهیم:
ابتــدا فایــل chan_dahdi.confرا باز کنید و در انتهای آن ،بهصورت زیر یــک فایل دیگر را include
کنید.
#include dahdi_channels.conf
161 ارتباط استریسک با شبکههای مخابراتی
با این کار یک فایل جدید به فایل تنظیمات و پیکربندی اضافه میشود .اکنون تنظیمات مورد نیاز برای
کارتهای FXO/FXSیا PRIرا به این فایل اضافه کنید.
پارامتر context
همانطورکه مالحظه میکنید ،در این تنظیمات کانتکســت را مشــخص کردیم؛ یعنی هر گونه تماسی که از
این طریق ایجاد و به سیســتم تلفنی استریسک وارد شود ،وارد کانتکست ] [from-pstnمیشود .میتوانید از
هر اسمی برای نام کانتکست استفاده کنید.
پارامتر channel
اینجا همهی کانالهای DAHDIمشــخص شــدهاند .به عبارت دیگر مشخص کردهایم که چه کانالهایی در
کارت DAHDIوجود دارند .همانطورکه قب ً
ال اشــاره کردیم در تکنولوژی ،E۱کانالهای ۱-۱۵و ۱7-۳۱
برای انتقال دیتا )صوت( مشــخص شدهاند ،بنابراین در قســمت channelنام کانالها را نیز به همین صورت
مشخص میکنیم )کانال ۱۶جهت سیگنالینگ و همزمانی استفاده میشود(.
پارامتر signaling
یک پارامتر مهم که باید به آن دقت کنید این اســت که تولید کننده ســیگنال همزمانی در کانالهای E۱در
سمت مقابل )مخابرات( انجام خواهد شد .قب ً
ال توضیح داده شد که باید تنظیماتی در فایل system.confدر
قســمت > ،<TIMING SOURCEانجام شــود ،در این فایل هم باید پارامتر signalingرا تنظیم کنید .این
پارامتر میتواند مقادیر زیر را داشته باشد:
• :pri_cpeمنظــور از cpeتجهیزات مشــتریان اســت .زمانی که لینــک کارت E1به مخابرات متصل
1
• :pri_netمنظور از netیعنی لینک کارت E1خود تولید کننده سیگنال همزمانی است .بیشتر در زمانی
مورد استفاده قرار میگیرد که با یک دستگاه دیگر ،ارتباطی از طریق PRIبرقرار کنیم.
پارامتر switchtype
این پارامتر فقط در کارتهای PRIبرای معرفی کردن نوع ســیگنالینگ و بیشــتر برای هماهنگی تنظیمات
بین ســوئیچ مخابراتی و استریسک استفاده میشــود .در کارتهای PRIمیتوان سیگنالینگهای زیر را بین
تجهیزات pri_netو pri_cpeداشت:
• national
• dms100
• 4ess
• 5ess
• euroisdn
• ni1
• qsig
میتوان از هر ســیگنالینگ دلخواه بین دو لینک PRIاســتفاده نمود .در شــبکههای مخابراتی کشور غالبا از
euroisdnاستفاده میشود.
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 2
=callerid
=group
context=default
signalling=fxs_ks
163 ارتباط استریسک با شبکههای مخابراتی
callerid=asreceived
group=0
context=from-pstn
channel => 3
=callerid
=group
context=default
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 4
=callerid
=group
context=default
همانطورکه مالحظه میکنید ،سیگنالینگ در تمام کانالها بهصورت fxs_ksتعریف شدهاست .در صورتی
که پورتها از نوع fxsباشند ،سیگنالینگ بهصورت fxo_ksتعریف میگردد .پارامتر callerid=asreceived
نیز تعریف شده است ،به معنی این که در شروع تماس ،کالرآی دی ارسال میشود .پارامتر کانتکست همانند
قبل روی ] [from-pstnتنظیم شده است تا تماسهای ورودی را کنترل و مدیریت کند.
بعد از اینکه این تنظیمات در فایل chan_dahdi.confانجام شد ،باید وارد محیط کامند الین استریسک
شوید و دستورات زیر را اجرا نمایید.
CLI> core reload
CLI> dahdi show status
ازطریق دســتور فوق میتوانید وضعیت کارتهای DAHDIشناخته شده بهوسیله استریسک را مشاهده
کنید .خروجی آن میتواند بهصورت زیر باشد:
)T2XXP (PCI) Card 0 Span 1 OK 0 0 8 CCS HDB3 CRC4 0 db (CSU)/0-133 feet (DSX-1
)T2XXP (PCI) Card 0 Span 2 RED 0 0 0 CCS HDB3 CRC4 0 db (CSU)/0-133 feet (DSX-1
)Wildcard TDM400P REV E/F Board 5 OK 0 0 0 CAS Unk 0 db (CSU)/0-133 feet (DSX-1
همانطورکــه مالحظه میکنید ،یکــی از کارتها در وضعیت REDقرار دارد .وضعیت REDحالتی را
نشان میدهد که لینک فیزیکی کارت برقرار نشده باشد.
در خصوص کارتهای E1ممکن اســت وضعیت کارت ،نرمال )در حالت (OKباشد ولی هیچ یک از
کانالها فعال نباشند .برای مشخص شدن این وضعیت ،دستور زیر را اجرا کنید.
CLI> pri show spans
پس از آنکه همه کانالها بهوســیله استریسک شناختهشــد ،باید بتوان بهوسیله آنها ،تماس ورودی و تماس
خروجی داشــته باشــیم .در ادامه به بررســی دقیق تماسهــای ورودی و خروجــی در کارتهای DAHDI
)شبکههای مخابراتی (PSTNمیپردازیم.
در این تنظیمات ،تماس ورودی از روی کانال ۱وارد کانتکســت ] [from-pstnمیشــود و دســتورات الزم
اجرا میگردد .ازآنجاکه پارامتر callerid=asreceivedتنظیم شــده اســت ،کالرآی دی میتواند هر چیزی
165 ارتباط استریسک با شبکههای مخابراتی
)هرشمارهای( باشد.
اکثرا ً در تماسهای ورودی از الگوی تطابق یا اکستنشن sاستفاده می کنیم.
][from-pstn
)(exten => _X.,1,Answer
)same => n,BackGround(welcome
)same => n,WaitExten(5
نکته مهم در خصوص تماسهای ورودی از طریق کانالهای آنالوگ این اســت که تماسهای ورودی
اکثرا بهصورت اکستنشن sایجاد و وارد کانتکست میشوند.
نکتــه مهم دیگر این اســت که ما میتوانیم هر کانال را مســتقال مدیریت کنیم .بــرای مثال فرض کنید یک
کارت FXOدوپورت داشــته باشــیم .هر پورت را میتوان بطور مســتقل با کانتکستهای متفاوتی تنظیم و
مدیریت نمود .برای مثال تنظیمات زیر را در نظر بگیرید:
; dahdi-channels.conf
signalling=fxs_ks
callerid=asreceived
group=0
context=incoming1
channel => 1
=callerid
=group
context=default
signalling=fxs_ks
callerid=asreceived
group=1
context= incoming2
channel => 2
=callerid
=group
context=default
مرجع آموزش ویپ با سافتسوئیچ استریسک 166
همانطورکه مالحظه میکنید اگر تماســی از طریق کانال ۱ایجاد شود ،به کانتکست ] [incoming1و اگر
از طریق کانال ۲ایجاد شود ،به کانتکست ] [incoming2وارد میشود.
ممکن اســت این ســوال مطرح شــود که چرا عالوه بر پارامتر ، channelپارامتر groupهم تغییر کرده
است؟ در بخش بعدی به کنترل تماسهاس خروجی از کارتهای DAHDIمیپردازیم.
به این نکتهی مهم توجه شود که فقط پارامترهایی برای یک کانال مشخص شده درنظر گرفته میشوند
که قبل از پارامتر channelتعریف شده باشند .کلیه این تنظیمات برای کارتهای PRIمشابه است.
اکنون برای ایجاد تماس در این کانال ،مراحل زیر را انجام دهید.
;extensions_custom.conf
)exten => _X.,1,NoOp(outgoing call to PSTN network
)}same => n,Dial(DAHDI/1/${EXTEN
در این مثال ،تماس از کانال یک کارت FXOخارج میشود .چنانچه دو نفر همزمان بخواهند یک تماس با
بیرون برقرار کنند ،برای نفر دوم ،کانال یک مشغول خواهد بود و امکان ایجاد تماس برای او میسر نمیشود؛
چون اعالم کردهایم که میخواهیم تماس از طریق کانال یک برقرار شــود .چنانچه برنامه باال بهصورت زیر
تغییر کند:
;extensions_custom.conf
)exten => _X.,1,NoOp(outgoing call to PSTN network
)}same => n,Dial(DAHDI/1/${EXTEN
)}same => n,Dial(DAHDI/2/${EXTEN
)}same => n,Dial(DAHDI/3/${EXTEN
)}same => n,Dial(DAHDI/4/${EXTEN
167 ارتباط استریسک با شبکههای مخابراتی
در این صورت ،نفر اول از اولین کانال استفاده میکند و تماس او برقرار میشود و نفرات بعدی از کانالهای
بعدی استفاده میکنند .این روش برنامهنویسی برای کانالهای DAHDIبه دالیل زیر کاربردی نیست:
1 .1چنانچه تعداد کانالها افزایشیابد ،باید برنامه باال را برای تک تک کانالها بنویسید.
2 .2هنگامیکه ترافیک تماسهای خروجی زیادند ،بهازای هر تماس باید همه کانالهای اولیه بررسیشــوند
تا به اولین کانال آزاد مورد نظر برسیم.
3 .3همیشه صورت حساب هزینه ی کانالهای اولیه بیشتر است.
چنانچه تعداد کانالها افزایش یابد ،مدیریت آنها نیز دشوارترمیشــود ،بنابراین برای سهولت بیشتر بهتر
اســت کانالها را گروهبندی کنید .به این ترتیب که بهجای شــماره کانال ،شــماره گروه را بیاورید .در این
صورت هنگام ایجاد تماس جدید ،از کانالهای آزاد طبق الگوریتم مورد نظر اســتفاده کنید تا تماس برقرار
شود .بر این اساس برنامه باال بهصورت زیر تغییر میکند:
;extensions_custom.conf
)exten => _X.,1,NoOp(outgoing call to PSTN network
)}same => n,Dial(DAHDI/g0/${EXTEN
همانطورکه مالحظه میکنید ،هم کد ســادهتری ایجاد کردیم و هم میتوانیم بدون مشــکل از همه کانالها
اســتفاده کنیم .پارامتــر groupدر تنظیمات فایل dahdi_channels.confبــرای گروهبندی کانالها و ایجاد
تماس خروجی استفاده میشود.
هنگام گروهبندی کانالها ،میتوان براســاس الگوریتمهایی مشــخص کرد که از چه کانالهایی استفاده
شود تا توزیع تماسها بین کانالها یکسان بماند .برای این منظور حالتهای زیر را درنظر بگیرید:
: gترتیب انتخاب پورتها از کمترین به بیشترین ) (۱،۲،۳،4،۵است .برای مثال در اولین شماره ،اولین پورت
استفاده میشود .اگر اولین پورت مشغول باشد ،دومین پورت انتخاب میشود .این نکته مهم است که انتخاب
پورت دوم به اشــغال بودن پورت اول بســتگی دارد )در این حالت billingبرای شــماره پورتهای پایینتر
بیشتر خواهد شد(.
)}exten => _X.,1,Dial(DAHDI/g0/${EXTEN
: Gاین ترتیب دقیقاً مثل gاســت اما انتخاب پورت از بیشترین به کمترین ) (۵،4،۳،۲،۱است )در این حالت
billingبرای شماره پورتهای باالتر بیشتر خواهد شد(.
)}exten => _X.,1,Dial(DAHDI/G0/${EXTEN
: rدر این حالت ترتیب انتخاب از کمترین به بیشــترین و بهصورت چرخشــی ) (Round-robinاست .یعنی
تماس جدید با پورت جدید ایجاد میشود )در این حالت billingبرای پورتها با هم برابر است(.
)}exten => _X.,1,Dial(DAHDI/r0/${EXTEN
: Rدر این حالت ترتیب انتخاب از بیشــترین به کمترین و بهصورت چرخشــی ) (Round-robinاست .یعنی
مرجع آموزش ویپ با سافتسوئیچ استریسک 168
تماس جدید با پورت جدید ایجاد میشود )در این حالت billingبرای پورتها با هم برابر است(.
)}exten => _X.,1,Dial(DAHDI/R0/${EXTEN
بــا ایــن قوانین میتوان بهترین الگو را انتخاب و از آن اســتفاده نمود .این قوانین بــرای کارتهای PRIنیز
برقرار است.
شکل 6-6
شکل 7-6
169 ارتباط استریسک با شبکههای مخابراتی
پارامتر calleridمیتواند هر گونه داخلی مورد نظر شــما باشــد .همانطورکه در تعریف هر داخلی ،باید
شــمارهای به آن تخصیص داده شود ،میتوانید شــماره مورد نظر خود را به آن اختصاص دهید .برای ایجاد
تماس با این داخلی بهصورت زیر برنامه خود را بنویسید:
][LocalSet
)exten => 555,1,NoOp(calling fxs extension
)same => n,Dial(DAHDI/5
مرجع آموزش ویپ با سافتسوئیچ استریسک 170
همه تماسهایی که ازطریق این داخلی ایجاد میشــوند ،با ســایر داخلیهای سیســتم تلفنی استریســک
تفاوتی ندارند؛ لذا با توجه به شماره گرفته شده ،به کانتکست تعیینشده ] [LocalSetمیرود و از آنجا برنامه
مورد نظر اجرا میگردد.
نتیجهگیری
امروزه رشــد شبکههای مخابراتی نسل جدید قابلمالحظه اســت ولی نمیتوان انتظار داشت که این فناوری
بهســرعت با شبکههای مخابراتی PSTNجایگزین شود .به عبارت دیگر گذر از شبکههای مخابراتی PSTN
به شــبکههای نســل جدید یک فرایند تدریجی اســت .ارتباط بین این دو شبکه در این فصل بررسی شد .در
فصل بعدی ،انواع روشهای اتصال شبکههای ویپ را بررسی میکنیم.
فصل هفتم
شکل 1-7
همانطورکه در شــکل ۱-7مالحظه میکنید ،هنگام شــروع یک تماس ،کاربر Bobیک درخواست جدید
برای ایجاد تماس به کاربر Tomارسال میکند ،سپس گوشی Tomزنگ میخورد؛ در این زمان پیام زنگ
خوردن به کاربر Bobارســال میشــود .کاربر Bobمتوجه میشود که گوشی Tomدر حال زنگ خوردن
اســت .پس از اینکه کاربر Tomتماس را پاســخ داد ،پیام تأیید ارســال میشود .در پاسخ به این پیام ،کاربر
Bobپیام تأیید مبنی بر شــروع زمان مکالمه را ارسال میکند .به این ترتیب مراحل پروتکل سیگنالیک SIP
برای ایجاد نشست جدید به پایان میرسد و دو کاربر میتوانند از طریق پروتکل RTPبا هم مکالمه نمایند.
پس از اتمام مکالمه ،دوباره پیام قطع مکالمه بوسیله پروتکل SIPو به واسطه یکی از کاربرها )در اینجا کاربر
را ارسال میکند و تماس قطع میشود و به200 OK پیام، با تأیید آنBob کاربر.( ارســال میشــودTom
.این ترتیب نشست میان این دو کاربر در سرور به پایان میرسد
را میتوانINVITE محتویات پیــام.اکنــون میتوان محتویات پیامهای این نشســت را بررســی کــرد
:مشاهده نمود بهصورت زیر
INVITE sip:Tom@192.168.154.128;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 192.168.154.1:5060;branch=z9hG4bK-d8754z-ca97d503b93222cf-1---
d8754z-
Max-Forwards: 70
Contact: <sip:Bob@192.168.154.1:5060;transport=UDP>
To: <sip:Tom@192.168.154.128;transport=UDP>
From: <sip:Bob@192.168.154.128;transport=UDP>;tag=a5575819
Call-ID: YWMzYjY0YzVhMzgzZDY1ZTlmMDFiYjQ2MDE2NjcxNjU.
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE
Content-Type: application/sdp
Supported: replaces, norefersub, extended-refer, X-cisco-serviceuri
User-Agent: Zoiper rev.11137
Allow-Events: presence, kpml
Content-Length: 329
v=0
o=Zoiper_user 0 0 IN IP4 192.168.154.1
s=Zoiper_session
c=IN IP4 192.168.154.1
t=0 0
m=audio 8000 RTP/AVP 3 0 8 110 98 101
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 speex/8000
a=rtpmap:98 iLBC/8000
a=fmtp:98 mode=30
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
پیام، صادر میشودINVITE پیامی که معموالً )در صورت آمادگی برای پاســخ از ســمت مقابل( در پاسخ
، در پاســخ به این پیام.( اســت و اعالم میکند که طرف مقابل در حال زنگ خوردن اســت۱8۰ Ringing)
. میخوردRinging گوشی ما هم بوق
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 192.168.154.128:5060;branch=z9hG4bK69e0e7c1;rport=5060
Contact: <sip:Bob@192.168.154.1:5060;rinstance=fc85cf7452e43e92;transport=UDP>
175 ارتباط استریسک با سایر شبکههای ویپ
To: <sip:Bob@192.168.154.1:5060;rinstance=fc85cf7452e43e92;transport=UDP>;tag=
9e369779
From: "device"<sip:Tom@192.168.154.128>;tag=as64e26f7e
Call-ID: 17cde2fa7c2ac31d72125de822787ecd@192.168.154.128:5060
CSeq: 102 INVITE
User-Agent: Zoiper rev.11137
Content-Length: 0
v=0
o=Zoiper_user 0 2 IN IP4 192.168.154.1
s=Zoiper_session
c=IN IP4 192.168.154.1
t=0 0
m=audio 8002 RTP/AVP 0 3 8 110 98 101
a=rtpmap:0 PCMU/8000
a=rtpmap:3 GSM/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 speex/8000
a=rtpmap:98 iLBC/8000
a=fmtp:98 mode=30
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
.( در تأیید پاسخ تماس ارسال میشود و دو کاربر میتوانند مکالمه خود را آغاز کنندACK) پیام
ACK sip:Bob@192.168.154.1:5060;rinstance=fc85cf7452e43e92;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 192.168.154.128:5060;branch=z9hG4bK4d0c8070;rport
Max-Forwards: 70
From: "device" <sip:Tom@192.168.154.128>;tag=as64e26f7e
مرجع آموزش ویپ با سافتسوئیچ استریسک 176
To: <sip:Bob@192.168.154.1:5060;rinstance=fc85cf7452e43e92;transport=UDP>;tag=
9e369779
Contact: <sip:Tom@192.168.154.128:5060>
Call-ID: 17cde2fa7c2ac31d72125de822787ecd@192.168.154.128:5060
CSeq: 102 ACK
User-Agent: FPBX-2.8.1(1.8.7.0)
Content-Length: 0
پیشتر هم. همه پیامهای ارســال شــده به صورت متنی و قابل خواندنند،همانطورکه مالحظه میشــود
بــرای درک بهتر این. در برقراری ارتباط اســتفاده میکنیمRTP وSIP اشــاره شــد که ما از دو پروتــکل
. فرض کنید یک ارتباط تلفنی در شبکه ویپ به صورت شکل زیر باشد،موضوع
2-7 شکل
177 ارتباط استریسک با سایر شبکههای ویپ
در ایــن شــکل ما باید از هر دو پروتکل برای ایجاد یک تماس اســتفاده کنیــم .از پروتکل SIPبرای ایجاد
تمــاس ،کنترل و مدیریــت تماس و خاتمه دادن به تماس ،و از پروتکل RTPبــرای انتقال صوت و مدیا در
شبکههای ویپ استفاده میشود.
توجه داشــته باشــید که ما از دو نوع پروتکل مختلف در یک ارتباط تلفنی اســتفاده میکنیم و این خود
مشکالت NAT Traversalمیشود ،چون اکثر کاربران در اینترنت ،با NATکار میکنند. باعث بروز
شکل 3-7
بحث NATدر شبکههای کامپیوتری خارج از چارچوب کتاب است ،ولی ازآنجاکه در شبکههای ویپ،
مشکالت ناشی از NATبسیار شایع است ،مختصری راجع به آن توضیح خواهیم داد.
چنانچه تجهیزاتی که در ارتباط با NATهســتند درخواستهای خود را به شبکهی اینترنت ارسال کنند،
پاســخ آنها را دریافت میکنند .بر همین اساس غالبا بهوسیله ،NATاستفاده از اینترنت راحت است .اکنون
یک پرســش مهم این اســت که آیا این احتمال وجود دارد درخواستی از بیرون وارد شود ولی نتوانیم آن را
به آدرس خاصی نگاشــت دهیم؟ پاســخ مثبت است .بیشتر درخواســتها از داخل شبکه به خارج از آناند،
بنابراین مودم میتواند آنها را بدون مشکل نگاشت کند و هر زمان که پاسخ آنها را دریافت کند ،به آدرس
کالینت مورد نظر ارســال کند .چنانچه درخواســتی در یک پورت جدید به مودم داده شــود و مودم نتواند
آدرسش را نگاشت و کالینت مورد نظر را پیدا کند )که این پاسخ در برابر کدام درخواست رسیده است(،
آن را نخواهد پذیرفت .شکل 4-7این فرآیند را در شبکههای ویپ با پروتکل RTPنمایش میدهد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 178
شکل 4-7
همانطورکه مالحظه میشــود ،کالینت ابتدا درخواســت برقراری تماس را از طریق پروتکل SIPبه ســرور
ارســال و ســرور هم پاســخ آن تماس را قبول میکند .پس از برقراری تماس ،جریانهای ترافیکی از طریق
پروتکل RTPمنتقل میشوند .کالینت از طریق این پروتکل ،دادههای صوتی را برای سرور ارسال میکند و
سرور هم در پاسخ ،دادههای صوتی را روی پورت دیگری برای کالینت ارسال میکند .مودم NATجلوی
دریافت این دادهها را میگیرد و دادهها از بین میروند .در چنین شــرایطی معضل یک طرفهبودن صدا پدید
میآید .برای واضحتر شدن موضوع ،سه سناریوی متفاوت بررسی میشوند:
(۱زمانی که کالینتها با NATکار کنند؛
(۲زمانی که سرور استریسک متصل به NATباشد؛
) double_ NAT (۳زمانی که هر دو به NATمتصل باشند(.
مسلماً در هر یک از شرایط باال ،چالشهایی وجود دارد که باید به دقت مورد بحث قرار گیرد.
شکل 5-7
شکل 6-7
در شــکل ،۶-7یک کامپیوتر ،یک دســتگاه روتر برای اتصال به اینترنت و یک سرور استریسک دیده
میشــود .همانطورکه مالحظه میکنید سرور استریســک دارای آدرس Publicاست .کامپیوتر )که دارای
نرم افزار کالینتی SIPاست( درخواست خود را به صورت شکل 7-7به سمت سرور ارسال کند.
شکل 7-7
مرجع آموزش ویپ با سافتسوئیچ استریسک 180
تا پیش از رســیدن به روتر )قبل از NATشدن( ،آدرس شبکهای با آدرس ذخیره شدن در بدنه پروتکل
SIPبرابر اســت .هنگامیکه در خواســت از روتر عبور میکند ،آدرس شــبکهای آن نیز تغییر میکند و بعد
از مســیریابی به سرور استریسک میرسد .آدرسی که استریســک برای ارتباط با کالینت مورد نظر استفاده
میکند ،به صورت زیر است:
phone-1 | registered@192.168.1.20
اکنون فرض کنید استریســک تماسی را به ســمت کالینت phone-1ارسال کند .ازآنجاکه این کالینت در
یک آدرس نامعتبر از نظر ســرور ذخیره شــده است ،ســرور نمیتواند آدرس فوق را پیدا کند؛ لذا کالینت
phone-1از نظر سرور قابل دسترس نیست .شکل 8-7این موضوع را نمایش میدهد.
شکل 8-7
در یک چنین شــرایطی وقتــی کالینتها با NATکار میکننــد ،باید پارامتر زیــر را در هنگام تعریف
کاربران به این صورت تعریف کنیم:
;sip.conf
][phone-1
nat=yes
حال اگر پیامی از طرف یک کالینت به ســرور استریســک برســد ،استریســک با درنظرگرفتن پارامتر
nat=yesبرای کالینت ،از آدرس آیپی درون بدنه پیام SIPصرفنظر میکند و در عوض آدرس آیپی
شبکهای پیام دریافتی را درنظر میگیرد )شکل .( ۹-7
مطابق شــکل ،۹-7در یک چنین حالتی ) ،(nat=yesآدرس آیپی روتر درنظرگرفته میشــود .در این
حالت استریســک میتواند این آدرس آیپی را مســیریابی و در صورت لزوم ،تماس را به ســمت کالینت
ارسال کند .چنانچه تماس به سمت روتر ارسال شود ،روتر آن را به سمت کالینت مورد نظر فوروارد میکند.
181 ارتباط استریسک با سایر شبکههای ویپ
شکل 9-7
مشــکل NATتنها در خصوص پروتکل ســیگنالینگ SIPاتفاق نمیافتد ،بلکه در خصوص انتقال صدا
) (RTPنیز صادق اســت و منجر به یکطرفهشــدن صدا یا جلوگیری از انتقال آن میشــود؛ بنابراین ،هنگام
فعالکردن پارامتر natدر استریسک ،۱۳باید این مقادیر را تعریف کنیم:
nat = force_report,comedia
اصطــالح comediaمخفف connection oriented mediaاســت .یعنی برای ارســال یک پیام ، RTP
استریســک باید به IPو PORTآدرس شــبکهای که پیام از آنجا ارسال شدهاست ،دسترسی داشتهباشد و به
آدرس ذخیره شده درون بدنه پروتکل SIPکاری نداشته باشد.
ازآنجاکه هر لحظه ممکن اســت ارتباط بین کالینتها و ســرور استریســک قطع شود ،استریسک باید
نســبت به حفظ این ارتباط با کالینتها حســاس باشــد و وضعیت آنها را دائماً بررسی کند .این قابلیت در
استریسک هنگام تعریف داخلی ،ازطریق پارامتر qualifyفعال میشود.
;sip.conf
][phone-1
qualify=yes
درصورتیکه این پارامتر را برای کاربری تعریف نکردهباشــید ،بهصورت پیشفرض استریسک ارتباط
بین کالینت و خودش را چک نمیکند و به صورت unmonitoredباقی میماند .در استریســک با دســتور
زیر میتوانید از وضعیت همه کاربران مطلع شوید.
CLI> sip show peers
اکنون چنانچه ارتباط بین استریسک و کالینت قطع شود چه وقایعی ممکن است رخ دهد؟ پاسخ به این
سوال را به صورت زیر بیان میکنیم:
مرجع آموزش ویپ با سافتسوئیچ استریسک 182
زمانی که برای اولین بار یک کالینت در خواست رجیستر شدن خود را به سرور ارسال میکند ،درواقع
آدرس فیزیکی خود را به استریسک معرفی کرده است .از این پس استریسک چنانچه بخواهد تماسی برای
آن داخلی )کالینت( ارسال کند ،از آدرس ذخیره شده استفاده میکند.
استریســک بایــد دربازههای زمانی متفــاوت ،وضعیت همــه کالینتهای خود را بررســی کند که آیا
قابلدسترســیاند یا نه .اگر وضعیت کالینتی ،غیر قابل دســترس باشــد ،یعنی استریسک نمیتواند تماسی را
به ســمت کالینت مورد نظر ارســال کند ،اما این کالینت میتواند درخواست خود را برای سرور استریسک
ارسال کند ،چون در تنظیمات کالینت ،آدرس استریسک صریحاً معرفی شدهاست.
در این حالت این قابلیت وجود دارد که بهجای آدرس آیپی ،از نام hostبرای معرفی آدرس استفاده کنیم
که در اینصورت آدرس مربوطه باید resolvedشود:
;sip.conf
][general
>externhost = < Domain Name > : < port
externrefresh: 300
در برخی سناریوها ممکن است استریسک پشت NATباشد و کاربرانی هم باشند که با آدرس آیپی داخلی
بخواهند به استریســک متصل شوند )رجیستر شوند( .در یک چنین شرایطی باید پارامتر localnetرا در فایل
sip.confدر سرویس استریسک فعال کنیم تا کاربران داخلی شبکه بتوانند به استریسک متصل شوند.
این تنظیمات میتوانند بصورت زیر باشند:
;sip.conf
][general
externip = 98.139.183.24
localnet = 172.16.0.0/24
localnet = 192.168.100.0/255.255.255.0
183 ارتباط استریسک با سایر شبکههای ویپ
در این شــرایط ،کاربران میتوانند از طریق شــبکه اینترنت به ســرور استریسک متصل شوند و کاربران
داخلی هم با داشتن localnetمیتوانند به سرور استریسک متصل شوند.
شکل 10-7
مرجع آموزش ویپ با سافتسوئیچ استریسک 184
همانطــور که مالحظه میکنید عالوه بر جریانهای ســیگنالینگی از طریق ســرور بین دو کاربر منتقل
میشود ،جریانهای ترافیکی مدیا ) (RTPهم از طریق سرور میانی بین دو کاربر انتقال مییابد.
پر واضح است که در چنین شرایطی چون ترافیک مدیا از سرور عبور میکند ،میتوان همه مکالمات را
ضبط کرد و حتی جریانهای ترافیکی DTMFرا نیز تشــخیص داد .اما باید درنظر داشــت که عبور این نوع
ترافیکها از سرور ،منابع زیادی مصرف میکند.
چنانچه دو کاربر از کدکهای مختلفی در ســمت خود اســتفاده کنند ،هنگامی که داده به سرور برسد،
عملیات تبدیل کدک بوسیله سرور میانی صورت میگیرد و سپس به کاربر مقابل ارسال میگردد .عملیات
تبدیل کدک در سرور نیز منابع زیادی از CPUرا مصرف میکند.
در استریســک برای تنظیم کاربران به منظور استفاده از حالت ، B۲BUAباید تنظیمات زیر را برای هر
کاربر اعمال کنید:
;sip.conf
][phone-1
canreinvite = no
directmedia = no
][phone-2
canreinvite =no
directmedia = no
شکل 11-7
185 ارتباط استریسک با سایر شبکههای ویپ
در این حالت چون جریانهای ترافیکی مدیا از مســیر دیگری )به جز ســرور( عبور میکنند ،سرور منابع
بیشــتری در اختیــار دارد و میتوانــد تماسهای همزمان بیشــتری را کنترل کند.عالوه بــر این ،مکالمات و
DTMFرا نیز نمیتوان ضبط کرد و چون مدیا به صورت مســتقیم میان هر دو کاربر توزیع میشــود ،اگر از
کدکهای یکسانی استفاده نکنید با مشکالتی مواجه خواهیدشد.
در استریسک برای تنظیم کاربران به منظور استفاده از حالت ، P2Pباید تنظیمات زیر را برای هر کاربر
اعمال کنید:
;sip.conf
][phone-1
canreinvite =yes
directmedia = yes
][phone-2
canreinvite =yes
directmedia = yes
سوالی که اینجا مطرح میشود این است که کدامیک از حالت ها برای سرور استریسک بهتر و مناسبتر
است؟
در پاســخ چنانچه ســرور استریســک و همه کاربران ،داخل یک شبکه محلی باشــند ،میتوان از P2P
استفاده نمود ،ولی اگر برخی از کاربران به NATمتصل باشند ،بهتر است از حالت B2BUAاستفاده شود تا
با مشکالت Nat-Traversalدر شبکههای ویپ درگیر نشویم.
در شــرایطی که برخی کاربران به NATمتصلند و برخی دیگر به شبکه محلی ،این قابلیت در استریسک
وجــود دارد که تنها برای کاربران شــبکه محلــی ،جریانهای ترافیکی مدیا به صورت P2Pباشــند .در این
صورت تنظیماتی در سرور استریسک در sip.confباید انجام دهید:
;sip.conf
][general
directmediadeny = 0.0.0.0/0
directmediapermits = 192.168.101.0/24
directmediapermits = 192.168.1.0/24
شــبکههای ویپ میتوانند با توپولوژیهای مختلفی با سایر شبکههای مخابراتی ،در ارتباط باشند که در
ادامه فصل ،به چگونگی این ارتباطات میپردازیم.
PSTN Termination
در شــبکههای ویپ این امکان وجود دارد که تماسهای ایجاد شــده از داخل شــبکه را به شبکه مخابراتی
PSTNمنتقــل کنیم .به عملیات ایجاد تماس از طریق شــبکههای VoIPو انتقال آن به شــبکههای ، PSTN
Terminationگویند. عملیات
مرجع آموزش ویپ با سافتسوئیچ استریسک 186
معمــوالً ارتباط بین شــبکههای VoIPبا شــبکههای مخابراتی PSTNازطریــق PSTN-GWها صورت
میگیرد .این تجهیزات معموالً ازطریق لینکهای پرظرفیت PRIبه شــبکههای مخابراتی متصل میشــوند و
میتوانند بهصورت کارتهای سخت افزاری DAHDIبا استریسک در ارتباط باشند و یا از طریق گیتوی
با سرور استریسک ارتباط برقرار کنند.
PSTN ORGINATION
در شــبکههای ویپ این امکان وجود دارد که تماسهایی از ســمت شــبکه مخابراتی PSTNبه شبکه VoIP
داشــته باشــیم .عملیات ایجاد تماس از طرف شبکه مخابراتی PSTNبه شبکه VoIPرا عملیات Orgination
گویند.
برای ایجاد یک تماس ، Orginationباید یک شــماره معتبــر DID_Numberازطرف مرکز مخابراتی
داشــته باشیم .این شــماره بهصورت صریح در شــبکه مخابراتی PSTNتعریف میشود و در اختیار مشتری
قرار میگیرد.
توپولوژی ذوزنقهای
در این شبکهها ،تماس بین دو کاربر که هر یک از domainمتفاوتی هستند ،ایجاد میشود .در شکل ۱۲-7
کاربر agentAاز ) domainAســرور استریســک (۱یک تماس با agentBاز ) domainBسرور استریسک
(۲برقرار میکند .در این مدل از شبکهها باید بین سرورها یک ارتباط وجود داشته باشد .این ارتباط از نوع
SIP-Trunkتعریف شده است.
شکل 12-7
187 ارتباط استریسک با سایر شبکههای ویپ
توپولوژی مثلثی
در این توپولوژی هر دو کاربر در یک ) Domainســرور استریســک( قرار دارند و تماس میان آنها برقرار
میگردد.
شکل13-7
تا اینجاتوپولوژی مثلثی در مثالها بیشتر توضیح داده شده است .برای ایجاد ارتباط میان سایر شبکههای
ویپ )توپولوژیهای ذوزنقهای( ،باید میان ســرورهای VoIPارتباط برقرار کنید .میان دو ســرور استریسک
میتوان به چند روش مختلف ارتباط برقرار کرد:
• SIP_Trunk
• IAX2_Trunk
• PRI_Link
• H323_Trunk
• TDMOE
در اینجا انواع روش های ارتباطی از طریق SIP_Trunkو IAX2_Trunkرا شرح می دهیم.
SIP_Trunk
ایجاد SIP_Trunkبین دو سرور استریسک ،دو روش وجود دارد: برای
: Registration (۱در این حالت ،ارتباط SIP_Trunkبا عملیات Registrationایجاد میشود .سپس هر دو
ســرور از همین طریق ارتباط خواهند داشت و میتوانند تماسهایی را به سوی یکدیگر انتقال دهند )معموالً
این نوع از ترانک بیشتر توسط VoIP_Providerها انجام میشود(.
: Trust_IP (۲در این ارتباط ،دو ســرور استریســک نســبت به IPیکدیگر قابل اعتمادند و اگر تماسی از
مرجع آموزش ویپ با سافتسوئیچ استریسک 188
طرف این IPها ارســال شــود ،آن را میپذیرنــد .در این روش هیچ گونه عملیــات Registrationصورت
نمیگیرد.
برای مثال اگر بین دو سرور Aو Bیک ارتباط از نوع Trust_IPایجاد کنید ،در طرف Server Aباید
sip.confقرار دهید: تنظیمات زیر را در
شکل 14-7
;sip.conf
][server B
type = peer
host = 192.168.1.102
defaultuser = server A
secret = apples
context = incoming
disallow = all
allow = ulaw
qualify = yes
پس از انجام تغییرات در هر دو ســرور ،وارد محیط کامندالین استریســک شوید و ماژول chan_sip.soرا
reloadنمایید:
CLI> sip reload
برای مشاهده وضعیت ارتباط SIP_Trunkدر هر سرور ،دستور زیر را اجرا کنید:
CLI> sip show peers
پس از اینکه ترانک بین دو سرور برقرار شد ،باید بتوانید بین دو سرور تماس برقرار کنید .در این حالت
فرض کنید در سرور Aبخواهیم شمارهای را که با prefix =6آغاز میشود ،به سوی سرور Bارسال کنیم.
در این صورت باید برنامه زیر را بنویسید:
;ServerA
;extensions.conf
][LocalSets
)exten => _6XXX.,1,Dial(SIP/${EXTEN}@serverB
SIP_Providers
همانطورکه در قبال شــرح داده شــد ،اســتفاده از Registrationعمدتــا ازطریــق VoIP-Providerها که
ســرویسهای ویپ را بهصورت اینترنتی ارائه میدهند ،صورت میگیرد .در یک چنین روشی از Trust_IP
اســتفاده نمیشــود .برای مثال فرض کنید بخواهیم از یک Providerبرای ارسال تماس به سوی آن استفاده
قرار میدهند: کنیم .اکثر Providerها اطالعات زیر را در اختیار کاربران خود
• نام دامین domain IP -
• نام کاربری Username -
• کلمه عبور Password -
اگر بخواهیم از سمت یک Providerفقط تماس ورودی دریافت کنیم ،باید عبارت زیر را در قسمت
] [generalفایل sip.confاضافه کنیم :
;sip.conf
][general
register => username:password@domain
با استفاده از دستور زیر میتوان اطالع پیدا کرد که آیا عملیات رجیستر شدن با موفقیت انجام شده است یا نه:
CLI> sip show registery
اگر بخواهید تماس را به ســوی یک Providerارســال کنید ،باید عبارت زیــر را در فایل sip.confاضافه
نمایید:
;sip.conf
][myprovider
type = peer
>host = <HOST-IP
>defaultuser = <USERNAME
>secret = <SECRET
insecure = invite,port ;very
مرجع آموزش ویپ با سافتسوئیچ استریسک 190
dtmfmode = rfc2833
disallow = all
allow = ulaw,alaw
پس از انجام تغییرات در فایل ،sip.confباید وارد محیط کامندالین استریســک شوید و ماژول chan_sip.
soرا reloadکنید:
CLI> sip reload
برای مشاهده وضعیت ارتباط SIP_Trunkدر هر سرور ،دستور زیر را اجرا کنید:
CLI> sip show peers
IAX2_TRUNK
پروتــکل ) IAX2 (Inter-Asterisk eXchangeیکی دیگر از پروتکلهای شــبکههای VoIPاســت .این
پروتکل بیشــتر بهعنوان پروتکل ارتباطی میان سرورهای استریسک شناخته میشود ،ولی در سطح محبوبیت
پایینتری نسبت به پروتکل SIPقرار دارد.
مهمترین مزیتی که پروتکل IAX2نسبت به پروتکل SIPدارد این است که در این پروتکل ،جریانهای
ترافیکی ســیگنالینگ و مدیا از یک پورت مشــترک )پورت (4۵۶۹ارســال میشــوند ،که این به نوبه خود
مشکل NATدر پروتکل SIPرا برطرف میکند.
فرض کنید طبق شکل ۱۵-7یک ارتباط بین دو سرور Aو Bایجاد کرده باشیم .تنظیمات مربوط به این
نوع ترانک در فایل iax2.confدر دو سرور به صورت زیر است:
شکل 15-7
[serverB]
type = peer
host = 192.168.1.37
trunk =yes
username = serverA
secret = apples
context = incoming
disallow = all
allow = ulaw,alaw
qualify = yes
شروع شده است را به سوی سرور7 بخواهیم شمارههایی که با پیش شمارهA حال فرض کنید در سرور
: مربوطه اضافه کنیدcontext درextensions.conf در این صورت برنامه زیر را در فایل، ارسال کنیمB
;serverA
;extensions.conf
[LocalSets]
exten => _7XXX,1,Dial(IAX2/${EXTEN}@serverB)
نتیجهگیری
در این فصل تالش بر این بود که با مفاهیم شــبکههای ارتباطی ویپ و مشــکالت آنها آشنایی بیشتری پیدا
کنیــم و اینکــه چگونــه بتوانیم آنها را به شــبکههای IPمتصل کنیم .در فصلهای بعــدی مباحث مرتبط با
شبکههای ویپ را ادامه خواهیم داد.
فصل هشتم
اگر بخواهیم دو عدد ۲و ۳را با هم جمع کنیم ،در این حالت باید عبارت محاســباتی ۲+۳را بهصورت زیر
در برنامه خود بنویسیم:
;extensions.conf
][logic
)(exten => 320,1,NoOp
)(same => n,Answer
)]same => n,NoOp(SUM=$[2+3
)(same => n,Hangup
همانطورکه مالحظه میکنید ما از عبارت ] $[۲+۳در برنامه استفاده کردیم .خروجی برنامه فوق در محیط
کامندالین استریسک بهصورت زیر است.
Executing [320@logic:1] NoOp("Console/dsp", "") in new stack
Executing [320@logic:2] Answer("Console/dsp", "") in new stack
Executing [320@logic:3] NoOp("Console/dsp", "SUM=5") in new stack
Executing [320@logic:4] Hangup("Console/dsp", "") in new stack
توجه داشــته باشید که برای آزمون برنامههای این فصل ،داشتن یک کاربر تعریفشده در استریسک الزامی
اســت و باید در کانتکســت مشــخصی برنامه را بنویســید .پس از آن هر بار با شــمارهگیری آن اکستنشن،
میتوانید برنامه را تست کنید .این روش اندکی دشوار مشکل است ولی یک روش سادهتر که در این فصل
از آن زیاد استفاده خواهیم کرد ،استفاده از دستور زیر در محیط کامند الین استریسک است.
CLI> console dial 320@logic
-- Executing [320@logic:1] NoOp("Console/dsp", "") in new stack
-- Executing [320@logic:2] Answer("Console/dsp", "") in new stack
>> << Console call has been answered
-- Executing [320@logic:3] NoOp("Console/dsp", "SUM=5") in new stack
-- Executing [320@logic:4] Hangup("Console/dsp", "") in new stack
›== Spawn extension (logic, 320, 4) exited non-zero on ‹Console/dsp
>> << Hangup on console
>CLI
با اســتفاده از این دستور ،اکستنشــن ۳۲۰در کانتکست ] [logicشمارهگیری و دستوراتش اجرا میشود .این
روش یک ابزار ســاده و راحت برای تســت برنامهها و سناریوهای استریسک است .البته در نظر داشته باشید
که تمامی سناریوها را نمیتوان در این روش تست کرد.
در استریســک میتوان از متغیرها در عبارات محاســباتی و منطقی اســتفاده نمود .برای مثال فرض کنید
متغیری بهنام COUNTداریم که بهصورت زیر تعریف شده است:
;extensions.conf
][logic
)(exten => 321,1,NoOp
)(same => n,Answer
)same => n,Set(COUNT=3
)]same => n,Set(NEWCOUNT=$[${COUNT} + 1
مرجع آموزش ویپ با سافتسوئیچ استریسک 196
همانطورکه مالحظه میکنید ،در اولویت ســوم مقدار عددی ۳با دستور Setدر متغیر COUNTذخیره شد
متغیر NEWCOUNTذخیره نمودیم. و در اولویــت بعدی مقدار COUNTیک واحد افزایــش یافت ،در
در انتها با اجرای دستور ،SayNumberمقدار عددی ذخیره شده در متغیر NEWCOUNTپخش میشود.
البته با استفاده از گزارشهای ایجاد شده در کامند الین استریسک میتوانید صحت برنامه را بررسی کنید.
قبل از ادامه بحث اجازه بدهید مثال قبل را کمی با دقت بررســی کنیم .همانطورکه مالحظه میکنید در
مثال قبل ما بخشهای متفاوتی داریم که عبارت اند از:
(۱ابتدا با دستور Setمتغیر COUNTرا ایجاد میکنیم و مقدار اولیه میدهیم.
(۲مقدار ذخیره شده در متغیر بهصورت} ${COUNTقابل بازیابی است.
(۳به کمک عبارت محاســباتی ] $[${COUNT}+۱مقدار متغیر ارزیابی میشــود؛ لذا عبارت محاســباتی
بهصورت زیر مرحله به مرحله انجام میشود:
)]same => n,Set(NEWCOUNT =$[${ COUNT }+1
) ]same => n,Set(NEWCOUNT =$[3+1
)same => n,Set(NEWCOUNT =4
دســتور SayNumberعدد داده شــده را پخش میکند .برای آشــنایی بیشتر با این دســتور ،در کامند الین
استریسک دستور زیر را وارد کنید:
CLI> core show application SayNumber
عملگر منطقی « : »ORاین عملگر به منزله « »orیا « »pipeدر نظر گرفته میشــود .چنانچه هریک از عبارتها
« »Trueباشــد ،نتیجه کلی عبــارت « »Trueدر نظر گرفته میشــود ،درغیراینصورت نتیجــه عبارت منطقی
« »Falseخواهد بود .در ریاضیات ،این عملگر ترکیب فصلی نامیده میشود.
exper1 | exper2
1- Mathametical
2- Regular Expression
مرجع آموزش ویپ با سافتسوئیچ استریسک 198
.« در نظر گرفته میشودTrue» همانطورکه مالحظه میکنید نتیجه عبارت منطقی
،» باشندTrue« اگر هر دو عبارت.» در نظر گرفته میشودand« این عملیات به منزله: »AND« عملیات منطقی
این عملگر ترکیب عطفی، در ریاضیــات.» اســتFalse« درغیراینصورت نتیجه،» خواهد بودTrue« نتیجــه
.نامیده میشود
exper1 & exper2
.« خواهد بودFalse» « یاTrue» نتیجه عملگرهای مقایسهای بهصورت،همانطورکه مالحظه میکنید
همانطورکه مالحظه میکنید ،در هر قسمت مقدار عبارت محاسباتی ارزیابی و نتیجه در خروجی نشان داده
میشود.
• فراخوانــی یک تابع برای مقداردهی به یــک پارامتر :گاهی نیــاز داریم یک پارامتــر را درون یک تابع
مقداردهی کنیم .در این صورت بهشکل زیر آن را مقداردهی میکنیم .نام پارامتر بهصورت آرگومان ورودی
به تابع داده میشود.
)>exten => n,Set(function_name(argument)=<VALUE
• فراخوانی یک تابع برای خواندن مقدار یک پارامتر :اگر بخواهیم به پارامتر یک تابع دسترســی داشتهباشیم
و مقدار آن را بخوانیم ،باید تابع را بهصورت زیر فراخوانی کنیم.
)})exten => n,NoOp(VALUE=${function_name(argument
همانطورکه مالحظه میکنید استفاده از توابع در برنامهنویسی استریسک بسیار ساده و شبیه استفاده از متغیرها
1- Application
2- Function
201 برنامهنویسی پیشرفته در استریسک
در استریسک است .در استریسک توابع زیادی وجود دارند که همگی بهصورت ماژول به استریسک اضافه
شــدهاند .در فصل دوم )معماری استریســک( توضیح دادیم که این نوع ماژولها در استریســک بهصورت
> func_<function_nameتعریف شــدهاند .برای مشــاهده انواع توابع در استریســک ،دســتور زیر را در
کامندالین استریسک اجرا کنید.
CLI> core show functions
در خروجی دســتور باال ،فهرســت همه توابع در استریســک نشان داده میشــود .عالوه بر این با دستور زیر
میتوانید همه ماژولهایی که مربوط به توابع در استریسک هستند را مشاهده کنید.
_CLI> module show like func
در این دســتور همه ماژولهای مربوط به توابع در استریسک را مشاهده میکنید .میتوانید هر ماژولی را که
نیاز ندارید ،به سادگی غیرفعال کنید .در فصل دوم )معماری استریسک( درباره نحوه غیرفعالکردن ماژولها
توضیحات الزم آمده است.
بهتر است با چند مثال کاربردی ،استفاده از توابع و دستورات در استریسک را شرح دهیم.
برای نمونه برنامه زیر را در نظر بگیرید.
;extensions.conf
][LocalSets
)(exten => 123,1,NoOp
)same => n,Set(TEST=MESPIO
)same => n,Playback(demo-congrats
)})}same => n,NoOp(LET=${LEN(${TEST
)})}same => n,SayNumber(${LEN(${TEST
در این برنامه ،ترکیبی از دستورات و توابع در کنار هم استفاده شدهاند .نکته مهم تفاوت در چگونگی استفاده
اســت .در این مثال دســتورات NoOp, Set,Playback, SayNumberهمگی از نوع Application از آنها
هســتند و تابع LENاز نوع Functionاســت .در این مثال ،این تابع طول رشــتهای متغیر} ${TESTرا که ۶
است ،برمیگرداند و سپس آن را پخش میکند .خروجی برنامه باال بهصورت زیر است.
• : digitsبــا ایــن پارامتر ،حداکثر زمان مورد نیاز برای وارد کردن DTMFبین اعداد را مشــخص میکنیم.
برای مثال در برنامه زیر ،زمان وارد کردن اعداد 5ثانیه تنظیم شدهاست.
;extensions.conf
][LocalSets
)(exten => s,1,NoOp
)same => n,Set(TIMEOUT(digits)=5
• : responseزمانی که دستورات یک برنامه به ترتیب اجرا میشوند و به آخرین دستور میرسند ،بالفاصله
بعد از اجرا شــدن آخرین دستور ،تماس قطع میشود .با این پارامتر میتوان زمان بین اجرای آخرین دستور
1
و قطع شدن تماس را کنترل نمود .برای مثال در برنامه زیر ،این زمان روی حداکثر 3ثانیه تنظیم میشود.
;extensions.conf
][LocalSets
)(exten => s,1,NoOp
)same => n,Set(TIMEOUT(response)=3
;extensions.conf
[LocalSets]
exten => s,1,Answer()
same => n,Set(TIMEOUT(response)=20)
same => n,BackGround(welcome)
same => n,WaitExten()
exten => 1,1,Saynumber(digits/1)
exten => 2,1,Saynumber(digits/2)
exten => 3,1,Saynumber(digits/3)
exten => t,1,NoOp(time out occure after 20 sec)
مدت زمان مجاز برای واردTIMEOUT(response) با تابع،همانطورکه مالحظه میکنید در ابتدای برنامه
کنترل برنامه به اکستنشــن، ثانیه عددی وارد نشــود۲۰ ثانیه تنظیم کردهایم و چنانچه بعد از۲۰ کردن عدد را
. خروجی برنامه باال بهصورت زیر است. انتقال مییابدt
CLI> console dial s@LocalSets
-- Executing [s@LocalSets:1] Answer("Console/dsp", "") in new stack
-- Executing [s@LocalSets:2] Set("Console/dsp", "TIMEOUT(response)=20") in new stack
-- Response timeout set to 20.000
-- Executing [s@LocalSets:3] BackGround("Console/dsp", "welcome") in new stack
-- Executing [s@LocalSets:4] WaitExten("Console/dsp", "") in new stack
-- Timeout on Console/dsp, going to ‹t›
-- Executing [t@LocalSets:1] NoOp("Console/dsp", "time out occure after 20 sec") in new
stack
-- Auto fallthrough, channel ‹Console/dsp› status is ‹UNKNOWN›
<< Hangup on console >>
CLI>
نکته مهم در این.در استریسک این قابلیت وجود دارد که بتوانیم توابع را بهصورت تو در تو فراخوانی کنیم
در فصل، ازآنجاکه تعداد توابع در استریسک زیاد است. رعایت تعداد پرانتزها و براکتها اســت،شــرایط
بیستم )آشنایی با دستورات و توابع مهم و پرکاربرد استریسک( با مهمترین دستورات و توابع استریسک آشنا
.خواهید شد
دستور GotoIf
با این دستور میتوان پس از بررسی شرطهایی ،کنترل اجرای برنامه را به قسمتهای دیگری از برنامه انتقال
داد .نتیجه بررسی شرطها بهصورت منطقی » «Trueیا » «Falseدر نظر گرفته میشود.
فرمت استفاده از دستور GotoIfبهصورت زیر است :
)GotoIf(expression?destination1:destination2
در این صورت اگر مقدار عبارت ) (experssionداخل دســتور «True» ،محاسبه شود ،کنترل برنامه به des-
tination1منتقل میشــود و اگر مقدار عبارت «False» ،محاسبه شود ،کنترل برنامه به destination۲منتقل
میگردد.
نکته مهم در ارزیابی expressionاین اســت که اگر »رشــته خالی« یا » «۰باشد ،به منزله » «Falseدر
نظر گرفته میشود .برای مثال برنامه زیر را در نظر بگیرید.
;extensions.conf
][LocalSets
)(exten => 124,1,NoOp
)same => n,Set(TEST=1
)same => n,GotoIf($[${TEST} = 1]?weasels:iguanas
)same => n(weasels),Playback(announce-one
)(same => n,Hangup
)same => n(iguanas),Playback(announce-two
)(same => n,Hangup
در این مثال ،ابتدا متغیر TESTرا تعریف میکنیم .سپس در خط بعدی ،مقدار متغیر TESTرا با مقدار عددی
۱مقایســه میکنیم .در این حالت چون مقدار متغیر TESTبرابر با ۱اســت ،مقدار عبارت درســت محاسبه
میشود و کنترل برنامه به weaselsمنتقل میشود و دستورات آنجا اجرا میگردد.
خروجی برنامه باال بهصورت زیر است:
CLI> console dial 124@LocalSets
-- Executing [124@LocalSets:1] NoOp("Console/dsp", "") in new stack
-- Executing [124@LocalSets:2] Set("Console/dsp", "TEST=1") in new stack
-- Executing [124@LocalSets:3] GotoIf("Console/dsp", "1?weasels:iguanas") in new stack
)-- Goto (LocalSets,124,4
-- Executing [124@LocalSets:4] Playback("Console/dsp", "announce-one") in new stack
-- Executing [124@LocalSets:5] Hangup("Console/dsp", "") in new stack
›== Spawn extension (LocalSets, 124, 5) exited non-zero on ‹Console/dsp
>CLI
اینجا از برچسب » «weaseleبرای انتقال کنترل اجرای برنامه به محلی دیگر استفاده کردیم .دستور فوق
205 برنامهنویسی پیشرفته در استریسک
در استریسک میتوان کنترل اجرای برنامهها را به صورت های زیر انتقال داد:
)1پرش به اجرای یک اولویت خاص از طریق برچسب اولویت :کنترل اجرای برنامه به برچسب اولویت مورد
نظر از کانتکست و اکستنشن جاری انتقال مییابد و دستورات اجرا میشوند.
)2پرش به یک اکستنشــن خاص با اولویت مشــخص :کنترل برنامه به یک اکستنشن دیگر انتقال مییابد و از
اولویت مشخصشده ،اجرای دستورات را آغاز میکند.
)3پرش به یک کانتکست ،اکستنشــن خاص با اولویت مشخص :دراین حالت میتوان حتی کنترل برنامه را به
یک کانتکست دیگر با اکستنشن و اولویت خاص ،منتقل و دستورات آنجا را اجرا کنیم.
سؤال( چرا در مثال باال دو بار از دستور Hangupاستفاده شدهاست؟ پاسخ :چون دستورات بهصورت پشت
ســر هم اجرا میشوند ،بعد از انتقال اجرای برنامه به برچسب weaslesو اجرای دستورات آن قسمت ،نباید
دســتورات قســمت دوم شرط اجرا شوند .لذا بعد از اتمام دستورات مشــخص شده ،باید از دستور Hangup
استفاده کنیم.
بیایید فرض کنیم دســتور Hangupرا از برنامه حذف کردهایم .بر این اســاس خروجی برنامه بهصورت
زیر خواهد بود.
CLI> console dial 124@LocalSets
-- Executing [124@LocalSets:1] NoOp("Console/dsp", "") in new stack
-- Executing [124@LocalSets:2] Set("Console/dsp", "TEST=1") in new stack
-- Executing [124@LocalSets:3] GotoIf("Console/dsp", "1?weasels:iguanas") in new stack
)-- Goto (LocalSets,124,4
-- Executing [124@LocalSets:4] Playback("Console/dsp", "announce-one") in new stack
-- Executing [124@LocalSets:5] Playback("Console/dsp", "announce-two") in new stack
›-- Auto fallthrough, channel ‹Console/dsp› status is ‹UNKNOWN
>CLI
همانطورکه مالحظه میکنید با حذف دســتور Hangupاز برنامه ،هر دو دســتور Playbackاجرا میشوند.
ایــن امر در برنامههــا موجب بهوجود آمدن خطاهای منطقی میشــود؛ بنابراین ،به ایــن نکات در خصوص
استفاده از توابع شرطی دقت داشته باشید.
روش برنامهنویســی با سبک مثال قبلی ،در استریسک زیاد مرسوم نیست ،چون ممکن است بهدلیل عدم
اســتفاده صحیح از دســتور ،Hangupمشکالتی در برنامه به وجود آید؛ به همین دلیل مثال باال را به شیوه ای
صحیح دوباره مینویسیم .این روش برنامهنویسی از نظر نوع نگارشی ،بهتر و راحتتر است.
;extensions.conf
][LocalSets
مرجع آموزش ویپ با سافتسوئیچ استریسک 206
همانطورکه مالحظه میکنید به جای پرش روی برچســبها و اولویتها ،پرش به یک اکستنشــن دیگر با
اولویت مشخص صورت میگیرد.
بهتر اســت از بحث توابع شــرطی دور نشــویم و به یک مثال جالب دیگر بپردازیم .برنامه زیر را در نظر
بگیرید.
;extensions.conf
][LocalSets
)(exten => 126,1,NoOp
)(same => n,Answer
)same => n,Set(COUNT=10
)same => n(start),GotoIf($[${COUNT} > 0]?:goodbye
)}same => n,SayNumber(${COUNT
)]same => n,Set(COUNT=$[${COUNT} - 1
)same => n,Goto(start
)(same => n(goodbye),Hangup
دستور GotoIfTime
گاهی نیاز داریم براساس زمان سیستم ،دستورات متفاوتی را اجرا کنیم .برای مثال شرکتی را در نظر بگیرید
که میخواهد درساعات اداری ،پیام IVRخود را اجرا کند و در ساعتهای غیر اداری ،پیام دیگری را پخش
کند .در این شرایط دستور GotoIftimeمفید است.
فرمت استفاده از دستور بهصورت زیر است:
)GotoIfTime(times,days_of_week,days_of_month,months?label
در این حالت اگر زمان و تاریخ سیســتم با آنچه که در دســتور آمده اســت ،مطابقت داشته باشد ،کنترل
207 برنامهنویسی پیشرفته در استریسک
اجرای برنامه به labelتعیینشده منتقل میشود .در ادامه به معرفی بیشتر دستور GotoIfTimeمیپردازیم.
: Timeدر این پارامتر ،بازه زمانی مورد نظر خود را براساس فرمت 24ساعته ،مشخص میکنیم .بهعنوان مثال
برای مشخص کردن زمان بین 9صبح تا 5عصر بهصورت زیر نمایش میدهیم.
09:00-17:00
: Day_of_weakلیست روزهای (ایام) هفته را مشخص میکند .بهعنوان مثال چنانچه بخواهیم ایام هفته را از
شنبه تا پنج شنبه مشخص کنیم ،باید بهصورت زیر نمایش دهیم:
sat-thu
در ایــن حالت همه روزهای هفته را مشــخص میکنیــم .اگر بخواهیم فقط روزهای خاصی را (مثال شــنبه و
پنجشنبه) را مشخص کنیم ،بهصورت زیر تعریف میکنیم :
sat&thu
همچنیــن میتــوان ایام هفته را بهصورت ترکیبی مشــخص نمود .مثال فرض کنید بخواهیم روزهای شــنبه تا
دوشنبه و چهارشنبه و جمعه را تعریف کنیم ،بنابراین داریم :
sat-mon&wed&fri
: Day_of_monthلیست روزهای ماه را بین 1تا 31مشخص میکند .بهعنوان مثال برای مشخص کردن بازه
زمانی هفتم تا دوازدهم هر ماه ،بهصورت زیر تعریف میکنیم:
7-12
بهعنوان مثالی دیگر برای مشخص کردن روزهای پانزدهم و سیام هرماه داریم:
15&30
در این مثال روزهای بین هفتم تا دوازدهم و پانزدهم و بیستم تا بیست و پنجم هر ماه در نظر گرفته میشود.
: Monthلیست ماههای سال را مشخص میکند .در اینجا باید اسم ماههای سال را به میالدی مشخص کنیم.
بهعنوان مثال:
jan-apr
میتوان برای هر بخش و به ازای هر پارامتر ،از مقادیر مشخص شده (عالمت * ) استفاده کنیم .در این صورت
تمام حالتهای ممکن برای آن بخش را شامل خواهد شد.
: Labelپارامتر labelبســیار شــبیه به destinationدر دســتور Gotoیا GotoIfو دستورات مشابه است که
پیشتر توضیح داده شد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 208
اکنون چنانچه بخواهیم ســاعتهای کاری شــرکتی را در قالب این دســتور قرار دهیم )مثال از ساعت ۹
صبح تا ۱8عصر ،از شنبه تا پنج شنبه( ،در تمام ایام ماه و ماههای سال عبارت است از:
;extensions.conf
][LocalSets
)(exten => s,1,NoOp
)same => n,GotoIfTime(09:00-17:59,sat-thu,*,*?open,s,1
همانطورکــه مالحظــه میکنید از عالمت » * « در دو پارامتر آخر )که به منزله همه روزهای ماه و همه
ماههای سال است( استفاده کردیم .اگر شرط فوق صادق نباشد ،اجرای برنامه به خط بعدی میرود و اجرای
ادامه دستورات انجام خواهدشد.
بهعنوان مثالی دیگر فرض کنید شــرکتی شــرایط زیر را برای ســاعت کاری خود داشــته باشد و از شما
بخواهد که برنامهی آن را بنویسید:
مسئله :ساعات کاری شرکت از ساعت 7:30دقیقه تا 16عصر است .روزهای پنج شنبه و جمعه شرکت تعطیل
است.
ساعت 12:30تا 13:30زمان استراحت (نماز و نهار) است.
;extensions.conf
)(exten => s,1,NoOp
)same => n,GotoIfTime(12:30-13:30,sat-wed,*,*?break-time,s,1
)same => n, GotoIfTime(7:30-16:00,sat-wed,*,*?open,s,1
)same => n,Goto(close,s,1
همانطورکه مالحظه میکنید ابتدا زمانهای breakمشخصشــد ،بعد زمانهای باز بودن .اگر اجرای برنامه
با هیچ یک از دســتورات منطبق نشــود ،یعنی شرکت خارج از بازه زمانی کاری است و ادامه دستورات اجرا
میشود.
اگر در برنامه قبل ،ابتدا زمانهای باز بودن و ســپس زمان breakرا بررســی میکردیم ،چه اشــکاالتی
ممکن بود بهوجود آید؟ در پاسخ برنامه زیر را در نظر بگیرید:
;extensions.conf
)(exten => s,1,NoOp
)same => n, GotoIfTime(7:30-16:00,sat-wed,*,*?open,s,1
)same => n,GotoIfTime(12:30-13:30,sat-wed,*,*?break-time,s,1
)same => n,Goto(close,s,1
همانطورکــه مالحظه میکنید ،در این حالت برای همیشــه شــرط اول درســت اســت و هیچگاه زمان
breakاجرا نمیشــود .بنابراین در این برنامهها دقت داشــته باشید که اولویت بر اساس آن ساعتهایی است
که محدودهی کمتری دارند .در ادامه چند مســئله طرح میشــود و از خواننده انتظــار میرود ،بتواند برنامه
زمانبندی آنها را بنویسد.
209 برنامهنویسی پیشرفته در استریسک
مســئله )1ســاعت کاری صبح از ســاعت 8تا 13و بعد ازظهرها ،روزهای فرد از ساعت 17تا 20و روزهای
زوج از ساعت 17تا 22است.
مسئله )2شرکتی در روزهای زوج هر ماه ،از ساعت 7:30تا 16فعال است .اگر این روزها با پنجشنبه برخورد
کند ،شــرکت تا ســاعت 14فعال اســت .در هر روز از ساعت 13الی 13:30برای اســتراحت در نظر گرفته
میشود.
مسئله )3شــرکتی در روزهای پایانی هفته (چهارشــنبه و پنجشــنبه) از تخفیف ویژهای برخوردار است .این
تخفیف در آخرین چهارشنبه و پنجشنبه هر فصل تا %50افزایش مییابد.
به نظر شما خروجی برنامه چگونه ارزیابی میشود؟ آیا مقدار متغیر TEST_1با مقدار متغیر TEST_2برابر
است؟
قبل از پاسخ به این پرسش ،ذکر این نکته الزم است که در استریسک نیازی نیست برای تعریف رشتهها
از عالمتهای ' یا " اســتفاده کنید ،ولی برای همه مقایســههای شــرطی بهتر است از این عالمتها استفاده
کنیــد .در ایــن مثال ،مقدار عبارت مورد نظر False ،در نظر گرفته میشــود و مقدار دو متغیر نیز با هم برابر
نخواهند بود.
مرجع آموزش ویپ با سافتسوئیچ استریسک 210
در این مثال ،چون ما متغیر TESTرا تعریف نکردیم ،مقدار آن Null ،در نظر گرفته میشود؛ ولی در مقایسه
نمیتوانیم از عبارت Nullاستفاده کنیم ،بلکه از عبارت خالی استفاده میکنیم.
پیشتر توضیح دادیم که بهتر است در همه عبارتهای شرطی از عالمتهای ' یا " استفاده کرد .اکنون
این پرسش مطرح میشود که اگر بخواهیم عملیات مقایسهای بین اعداد را در شرطی بررسی کنیم ،چه باید
کرد؟ در پاسخ به این سؤال ،مثال زیر را ببینید:
;extensions.conf
)(exten => 130,1,NoOp
)same => n,Set(TEST=1
)same => n,GotoIf($[ '${TEST}' = '1' ] ? error_handing
)(same => n(error_handing) ,NoOp
در این مثال از عملیات مقایســهای اســتفاده شده است .مســأله مهم این است که مقایسه باید برای اعداد
انجــام شــود؛ بنابراین ،باید از عدد صفر پیش از نام متغیر اســتفاده کنید .در ایــن حالت مقدار آن بهصورت
عددی در نظر گرفته میشود و پس از آن عملیات شرطی اجرا میشود.
آخرین مثال از این بخش را بررســی میکنیم .فرض کنید میخواهیم بر اســاس کالرآیدی ،شــمارهای
را بــالک کنیم .اینجا گرفتن شــماره از طریق تابع ) CALLERID(numاهمیــت دارد .برنامه زیر را در نظر
بگیرید:
;extensions.conf
)(exten => 131,1,NoOp
211 برنامهنویسی پیشرفته در استریسک
در این مثال ،ابتدا کالرآیدی بررسی میشود ؛ چنانچه شرط Trueباشد به دستور با برچسب blockرفته
و دستورات آن بخش اجرا میشوند.
پیش از ادامه بحث ،بهتر است درمورد تابع CALLERIDتوضیح دهیم .مهمترین آرگومانهای این تابع
بهصورت زیر است:
• : numشماره تماس گیرنده را برمیگرداند.
• : nameاســم تماس گیرنده را بر میگرداند (فقط در کاربران SIPقابل اســتفاده اســت .در خصوص
شبکههای مخابراتی PSTNهمان numاست).
• : allترکیب numو nameرا برمیگرداند .
برای مثال فرض کنید برای کاربری ،فیلد کالرآیدی را بهصورت زیر در فایل sip.confتعریف کرده باشیم:
;sip.conf
][Phone_1
>Callerid = Phone_1<1000
این نکته اهمیت دارد که عملیات را باید با تلفنی که کاربر Phone_ 1روی آن رجیسترشــده اســت ،تســت
کنیم.
از تکرار کدها در برنامه جلوگیری و کدهای خواناتر و منظمتری ایجاد کنیم .البته در استریسک نسخه ۱۱به
بعد ،استفاده از ماکروها کمتر توصیه شده است و بهجای آن دستور GoSubمعرفی شده است.
یکی از مشــکالت اساسی اســتفاده از ماکروها ،بکارگیری ماکروها بهصورت تو در تو است که ممکن
اســت به خطای » «stack over flow problemمنتهی شــود؛ هرچند که میتوان تا پنج سطح از ماکروهای
تو در تو داشت.
به منظور آشنایی بیشتر با ماکروها ،مثال زیر را ببینید:
;extensions.conf
][LocalSets
)(exten => 140,1,NoOp
)same => n,Set(JOHN=SIP/Phone_1
)same => n,Dial(${JOHN},10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail
)same => n(unavail),Playback(unavail
)(same => n,Hangup
)same => n(busy),Playback(busy
)(same => n,Hangup
در این مثال ،ابتدا ســعی میشــود که با JOHNتماس گرفتهشــود .چنانچه پس از ۱۰ثانیه پاسخی دریافت
نشود ،بسته به اینکه وضعیت » «busyیا » «unavailباشد ،پیام مشخصی پخش و به دنبال آن تماس نیز قطع
میگردد .متغیر ، DIALSTATUSوضعیت تماس را در دستور Dialمشخص میکند.
البته این برنامه برای یک کاربر )داخلی( تعریف شده است .چنانچه بخواهیم برنامه را برای هزاران کاربر
داشــته باشــیم ،باید انبوهی از کدهای تکراری را بهازای هر کاربر داشته باشیم که مشکالت زیادی را برای
ما به بار میآورد .اما برای جلوگیری از تکرار کدها ،میتوان درون یک ماکرو قطعه برنامهای را نوشــت و
سپس برای هر کاربر آن را فراخوانی نمود .بدین وسیله از تکرار کدهای اضافی در برنامه جلوگیری میشود.
تعریف ماکرو
برای تعریف یک ماکرو ،ابتدا باید یک نام برای آن مشخص کنیم:
][macro-name
1- prefix
213 برنامهنویسی پیشرفته در استریسک
البتــه این تعریف از ماکرو کامل نیســت و باید به گونه ای تغییــر پیدا کند که همه کاربران بتوانند از آن
استفاده کنند؛ ولی قبل از آن باید نکاتی را در خصوص استفاده از ماکرو توضیح دهیم .برای فراخوانی یک
ماکرو از دستور Macroاستفاده میکنیم:
)exten => 141,1,Macro(dial
][macro-lab
)(exten => s,1,NoOp
)}same => n,NoOP(${EXTEN
)} same => n,NoOp(${MACRO_ CONTEXT
)}same => n,NoOp(${MACRO_EXTEN
)}same => n,NoOp(${MACRO_PRIORITY
همانطورکه مالحظه میکنید همه متغیرهای تعریف شده در ماکرو ارزیابی شدهاند.
متغیر} ${EXTENهمان sاست.
متغیر} ${MACRO_ CONTEXTهمان کانتکست ] [LocalSetsاست.
متغیر} ${MACRO_ EXTENهمان اکستنشن ۱4۲است.
متغیر} ${MACRO_ PRIORITYاولویت فراخوانی ماکروست که اینجا ۲است.
اکنــون چنانچــه بخواهیم مثال قبلی را بهگونهای تغییر دهیم که بهصورت عمومی قابل اســتفاده باشــد؛
میتوانیم اکستنشــن را هم بهصورت پارامتر برای ماکرو ارســال کنیم و هم میتوانیم از متغیر}_MACRO
${EXTENاستفاده کنیم.
نخســت ماکرو را بهصورتی پیادهسازی میکنیم که شماره داخلی ،بهصورت پارامتر برای ماکرو ارسال
شود .این ماکرو بهصورت زیر تعریف میشود:
;extensions.conf
][macro-dial
)(exten => s,1,NoOp
)same => n,Dial(SIP/${ARG1},10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail
)same => n(unavail),Playback(unavail
)(same => n,Hangup
)same => n(busy),Playback(busy
)(same => n,Hangup
در این عملیات ،ماکرو با استفاده از الگوی تطابق برای هر اکستنشنی که با این الگو مطابقت داشته باشد،
فراخوانی میشــود .شــمارهی اکستنشن بهصورت پارامتر برای ماکرو ارسال میشــود .راه دیگری هم برای
پیادهسازی ماکرو وجود دارد .به مثال زیر توجه کنید:
;extensions.conf
][macro-dial
)(exten => s,1,NoOp
)same => n,Dial(SIP/${MACRO_EXTEN},10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail
215 برنامهنویسی پیشرفته در استریسک
در این مثال از متغیرهای ماکرو استفاده کردیم که بهصورت زیر فراخوانی میشود.
)exten => _NXX,1,Macro(dial
اکنون از این ماکرو میتوان برای کاربران مختلف استفاده کرد تا از تکرار نوشتن کدها جلوگیری شود.
چنانچــه بخواهیــم کد پیشــرفتهتر ومنظمتــری از تعریف macro-dialداشــته باشــیم ،آن را بهصورت زیر
مینویسیم:
;extensions.conf
][macro-dial
)(exten => s,1,NoOp
)same => n,Dial(SIP/${ARG1},20
)same => n,Goto(s-${DIALSTATUS},1
همانطورکــه مالحظه میکنید ،بهجای نوشــتن انبوهی از کدهای تکراری ،بــه کمک یک ماکرو کدهایی
ایجاد کردیم که سادهتر و قابل فهمتر باشند .چنانچه تغییری در کدها الزم باشد ،کافی است آن تغییرات را
در ماکرو نیز اعمال کنیم .همانطورکه پیش از این نیز گفته شد در نسخههای استریسک ۱۱به بعد ،استفاده
از ماکرو توصیه نمیشــود بلکه بهجای ماکرو بهتر اســت از دستور Gosubاستفاده کنید .بنابراین ،به دستور
Gosubمیپردازیم.
حافظه وجود ندارد ،برخالف ماکروها که تا پنج ســطح فراخوانی را پشتیبانی میکنند ،در این دستور امکان
فراخوانیهای تو در تو بهصورت نامحدود فراهم شده است.
برای تعریف یک ، Gosubبرخالف ماکرو به هیچ پیشوندی نیاز نداریم ،اما بهتر است برای خواناشدن
کدها در برنامهها و تفکیک بهتر کانتکست ،از پیشوند » «subدر ابتدای نام دستور استفاده کنیم.
در مثال زیر برنامه مربوط به SubDialرا بهصورت تابع با دستور Gosubمینویسیم:
;extensions.conf
][subDial
)(exten => s,1,NoOp
)same => n,Set(JOHN=SIP/Phone_1
)same => n,Dial(${JOHN},10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail
)same => n(unavail),Playback (unavail
)(same => n,Hangup
)same => n(busy),Playback(busy
)(same => n,Hangup
همانطورکه مالحظه میکنید ،تفاوت اصلی به تعریف نام Gosubدر برابر نام Macroمرتبط است .یکی از
تفاوتهای مهم دیگر این است که در ،Gosubمتغیرهایی مثل متغیرهای ماکرویی نداریم؛ بنابراین ،هر آنچه
که در بدنه Gosubنیاز داریم باید بهصورت پارامتر به بدنه Gosubارسال کنیم.
مثال تکمیل شده SubDialکه بهصورت زیر نوشته شده است:
;extensions.conf
][subDial
)(exten => s,1,NoOp
)same => n,Dial(SIP/${ARG1},10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail
)same => n(unavail),Playback(unavail
)(same => n,Hangup
)same => n(busy),Playback(busy
)(same => n,Hangup
برای بازگشت بهReturn در این صورت باید از دستور، تماس قطع نشــود و دستورات اجرا شــوندGoSub
. استفاده کنیمGosub دستور بعد از مرحله فراخوانی
:برای مثال برنامه زیر را در نظر بگیرید
;extensions.conf
[LocalSet]
exten => 101,1,NoOp()
same => n,Set(JOHN=SIP/Phone_1)
same => n,GoSub(subDialer,start,1(${JOHN},30))
same => n,GoSub(subVoicemail,start,1(${EXTEN},default,u))
[subDialer]
exten => start,1,NoOp()
same => n,Dial(${ARG1},${ARG2})
same => n,Return()
[subVoicemail]
exten => start,1,NoOp()
same => n,VoiceMail(${ARG1}@${ARG2},${ARG3})
same => n,Hangup()
چنانچه برای دستور. اجرا میشودGosub بهوســیلهsubDialer نخســت تابع،همانطورکه مالحظه میکنید
به اولویت بعدی در فراخوانیReturn ازطریق دستور، تماس پاسخ داده نشود، ثانیه۳۰ پس از گذشتDial
. را اجرا میکندsubVoicemail میرود و دستور بعدی تابعGosub
$}GOSUB_RETVAL{استفاده از متغیر
باید، بخواهیم مقادیری از تابع را بهعنوان خروجی برگردانیم، Gosub چنانچه پس از فراخوانی تابع بهوسیله
: برنامه زیر را در نظر بگیرید، برای مثال. استفاده کنیم${GOSUB_RETVAL}از متغیر
;extensions.conf
[LocalSet]
exten => 101,1,NoOp()
same => n,Set(JOHN=SIP/Phone_1)
same => n,GoSub(subDialer,start,1(${JOHN},30))
same => n,Set(VoicemailMessage=${IF($["${GOSUB_RETVAL}" = "BUSY"]?b:u)})
same => n,GoSub(subVoicemail,start,1(${EXTEN},default,${VoicemailMessage}))
[subDialer]
exten => start,1,NoOp()
same => n,Dial(${ARG1},${ARG2})
same => n,Return(${DIALSTATUS})
[subVoicemail]
مرجع آموزش ویپ با سافتسوئیچ استریسک 218
در این مثال ،نخست تابع subDialerبهوسیله Gosubاجرا میشود .در آن تابع مقدار متغیر}${DIALSTATUS
بهعنوان خروجی تابع ،به کمک دســتور Returnبرگشــت داده میشــود و در فراخوانی دستور بعدی )تابع
(subVoicemailاز مقدار آن استفاده میشود.
یکی از قابلیتهای منحصر به فرد استریســک ،کانالهای محلی هستند .شاید توضیح دادن در خصوص این
کانالها کمی دشوار باشد .برای فهم آسانتر با مثالهایی کاربرد آنها را شرح میدهیم.
با اســتفاده از کانالهای محلی میتوانید تماسهایی را به سمت استریسک شبیهسازی کنید ،بهطوریکه
این توانایی میتواند قابلیتهای خوبی را در استریســک برای ما ایجاد کند .مثال فرض کنید بخواهیم بهطور
همزمان با گروهی از افراد تماس بگیریم ،در این حالت بهصورت زیر عمل میکنیم:
;extensions.conf
][LocalSets
)(exten => 150,1,NoOp
)same => n,Verbose(2,Dialing multiple locations simultaneously
)same => n,Dial(SIP/Phone_1&DAHDI/g0/09151176713&SIP/MyITSP/31770000,40
)(same => n,Hangup
در این مثال ما بهصورت همزمان با سه نفر به مدت 4۰ثانیه تماس میگیریم .چنانچه یک نفر تماس را پاسخ
دهد ،تماس با سایر گوشیها قطع میشود.
فرض کنید بخواهیم اول SIP/Phone_1به مدت 4۰ثانیه زنگ بخورد و اگر پاســخ داده نشد آنگاه با
سایر افراد تماس بگیریم .در این صورت برنامه مورد نظر بهصورت زیر خواهد بود:
;extensions.conf
][LocalSets
)(exten => 151,1,NoOp
)same => n,Verbose(2,Dialing multiple locations simultaneously
)same => n,Dial(SIP/Phone_1,40
)same => n,Dial(DAHDI/g0/09151176713,40
)same => n,Dial(SIP/MyITSP/31770000,40
)(same => n,Hangup
اکنون در نظر بگیرید ســناریو این گونه تغییر کند :ابتدا با نفر اول تماس برقرار شــود ،چنانچه پس از ۱۰ثانیه
تماس برقرار نشــد ،نفر دوم هم شــروع به زنگ خوردن کند و اگر پس از گذشت ۲۰ثانیه پاسخی دریافت
نشد ،آنگاه نفر سوم شروع به زنگ خوردن کند .سناریوی این مثال بهصورت شکل ۱-8خواهد بود.
شکل 1-8
همانطورکه مالحظه میکنید ،اینجا تماسهای دوم و ســوم با فاصله زمانی معینی برقرار میشــوند؛ بنابراین،
باید از تکنیک کانالهای محلی در استریسک استفاده کنیم .برنامه زیر را در نظر بگیرید:
;extensions.conf
][LocalSets
)exten => 152,1,Verbose(2,Dialing multiple locations with time delay
same => n,Dial(Local/channel_1@TimeDelay&Local/channel_2@TimeDelay&Local/
)channel_3@TimeDelay,40
)(same => n,Hangup
اکنون باید کانتکســت TimeDelayرا بنویســیم .در این کانتکست باید اکستنشنهای channel_2 ، chan-
nel_1و channel_3را داشته باشیم.
;extensions.conf
][TimeDelay
)exten => channel_1,1,Verbose(2,Dialing the first channel
)same => n,Dial(SIP/Phone_1,40
)(same => n,Hangup
همانطورکه مالحظه میکنید با اجرای دستور ، Dialسه کانال محلی ایجاد و وارد کانتکست TimeDelay
میشود و سپس همانجا دستورات اجرا میشوند .این سناریو در استریسک بدون استفاده از کانالهای محلی،
به سختی پیش میرود.
)پلهای میانی( اســتفاده نمود ،بهطوریکــه پس از برقراری پل ،این واســطههای میانی بدون درنگ از بین
بروند .شــاید مطلب کمی نامفهوم بهنظر برســد ولی در برخی از ســناریوها ،آگاهی به این موضوع میتواند
بسیار مفید باشد .مثال زیر را ببینید.
فرض کنید TOMبخواهد با BOBتماس بگیرد و سناریوی تماس او بهصورت زیر باشد.
;extensions.conf
][LocalSets
)exten => 155,1,Dial(LOCAL/BOB@Locals
)exten => 156,1,Dial(LOCAL/TOM@Locals
)exten => 157,1,Dial(LOCAL/BOB@Locals/n
)exten => 158,1,Dial(LOCAL/TOM@Locals/n
][locals
)exten => BOB,1,Set(BOB=SIP/Phone_1
)}same => n,Dial(${BOB
درحالیکه از شــمارههای ۱۵۵و ۱۵۶اســتفاده میکنیم ،کانالهای محلی تماس را به سمت کاربر BOBیا
TOMارسال میکنند؛ اما به محض اینکه BOBیا TOMتماس را پاسخ دادند ،کانال محلی ایجاد شده میان
آنها قطع و کانالها مستقیماً به هم متصل میشوند .این فرایند در شکل ۲-8نشان داده شده است.
شکل 2-8
همانطورکــه مالحظــه میکنید پس از برقــراری تماس میــان BOBو ، TOMکانالهای محلی از بین
میرونــد .اکنون فرض کنید بنا به دالیلی بخواهیم این کانالهــای محلی تا زمانی که کانالهای اصلی فعال
هســتند ،از بین نروند .در این حالت باید از شــمارههای ۱۵7و ۱۵8استفاده کنیم .اینجا باید از پارامتر /nدر
221 برنامهنویسی پیشرفته در استریسک
شکل 3-8
هرچنــد بحث کمی پیچیده شــد اما در فصلهای بعدی به کاربردهــای متمایز و ویژهای از کانالهای محلی
خواهیم پرداخت.
1
استفاده از AstDB
یکی دیگر از ابزارهای قدرتمند استریســک برای کار با دیتابیسها ،استفاده از دیتابیس داخلی استریسک با
نام Asterisk Databaseاست .از AstDBبرای ذخیرهکردن دادهها استفاده میشود .استریسک از SQLite
بهعنوان دیتابیس داخلی استفاده میکند و دادهها در آن بهصورت key/valueذخیره میشوند.
در فصل یازدهم )ارتباط استریسک با پایگاههای دادهای( با نحوهی ارتباط استریسک با سایر دیتابیسها
از قبیــل MySQL ، PostgreSQLو MSSQLبیشــتر آشــنا خواهید شــد .در این بخــش دیتابیس داخلی
استریسک AstDBو کار با آن در برنامهنویسی بیشتر مدنظر است.
در AstDBدادههــا بهصورت گروهی دســتهبندی میشــوند که این گروه بنــدی familyنام دارد .این
دادهها در دیتابیس به صورت زیر دستهبندی میشوند:
><family> <key> <value
-2در محیط برنامهنویســی استریســک :هنگام برنامهنویســی در استریســک ،میتوان هر زمان که نیاز باشد
متغیرهایی را در دیتابیس ایجاد و از آنها اســتفاده نمود .برای ذخیرهســازی دادههای جدید ،از ترکیب دستور
Setو تابع DBاستفاده کنید.
)>Set(DB(<family>/<key>) = <value
مثال فرض کنید بخواهیم معادل دستور باال را به این روش بنویسیم.
;extensions.conf
)(exten => 201,1,NoOp
)same => n,Set(DB(test/COUNT) = 1
مثــا فــرض کنید بخواهیم مقدار دادهی ذخیره شــده test/COUNTرا از دیتابیس بخوانیم ،در این صورت
داریم:
CLI> database get test COUNT
.2در محیط برنامهنویســی استریسک :هنگام برنامهنویسی استریسک ،هر زمان که نیاز باشد میتوان متغیرهایی
را از دیتابیس خواند و از آنها استفاده کرد .برای خواندن دادهها از دیتابیس از DBاستفاده کنید.
})>${DB(<family>/<key
بخواهیم معادل دستور باال را به این روش بخوانیم. مثال فرض کنید
;extensions.conf
)(exten => 202,1,NoOp
)})same => n,NoOp (the value was ${DB(test/COUNT
• دستور :delبا این دستور یک دادهی خاص family/keyاز دیتابیس حذف میگردد .فرمت استفاده از
این دستور بهصورت زیر است:
>CLI> database del <family> <key
• دســتور :deltreeبا این دســتور یک دادهی خاص یا دادههایی که در یک گروه familyهســتند ،از
دیتابیس حذف میشــوند .در این دســتور مقدار keytreeاختیاری اســت .فرمت اســتفاده از این دستور
بهصورت زیر است:
]CLI> database deltree <family> [keytree
]CLI> database deltree <family> [/keytree
-2در محیط برنامهنویسی استریسک :میتوان در برنامهنویسی استریسک ،هر زمان که نیاز باشد متغیرهایی را
از دیتابیس حذف نمود .برای حذف دادهها از AstDBاز دو تابع زیر استفاده کنید:
• تابــع : DB_DELETEبا این تابــع ،دادهای که بهصورت family/keyدر AstDBذخیره شدهاســت،
حذف میشــود .این تابع معادل دســتور database delدر کامندالین استریسک است .به مثال زیر توجه
کنید:
;extensions.conf
)(exten => 203,1,NoOp
) }) same => n,NoOp(the value was ${DB_DELETE(test/COUNT
به کمک این دســتور ،داده test/COUNTاز AstDBحذف میشــود و مقدار آن در خروجی ،نمایش
داده میشود.
• تابع : DBdeltreeبا این تابع کلیه دادههایی که در یک گروه ( )familyهســتند ،حذف میشــوند .این
دستور معادل دستور database deltreeدر کامندالین استریسک است .به مثال زیر توجه کنید:
;extensions.conf
)(exten => 204,1,NoOp
)})same => n,NoOp(all data is deleted ${DBdeltree(test
با این دستور تمامی دادههایی که در گروه testقرار دارند ،از AstDBحذف میشوند.
ازآنجاکه دادهها در AstDBدر دیتابیس داخلی استریســک ذخیره میشــوند ،با stopشــدن ســرویس
استریسک و حتی restartشدن سرور ،این دادهها ازبین نمیروند.
برای آشنا شدن و نحوه کار با AstDBدر استریسک ،مثال زیر را در نظر بگیرید:
;extensions.conf
)(exten => 206,1,NoOp
)})same => n,Set(COUNT=${DB(test/COUNT
)same => n,GotoIf($[${ISNULL(${COUNT})}]?:continue
)same => n,Set(DB(test/COUNT)=1
)same => n,Goto(1
)(same => n(continue),NoOp
)same => n,Playback(silence/1
مرجع آموزش ویپ با سافتسوئیچ استریسک 224
در توضیحات این برنامه ،نخســت بررسی میشود که آیا دادهی test/COUNTقب ً
ال در AstDBذخیره
شدهاست یا نه .اگر تعریف نشده باشد ،آن را تعریف میکنیم و در یک حلقه ،loopهر بار یک واحد به آن
و دوباره در دیتابیس ذخیره میکنیم. اضافه
بهعنوان یک مثال کاربردی ،فرض کنید بخواهیم بر اســاس کالرآیدی شخصی که تماس گرفته است،
شــماره آن شــخص را بالک کنیم و اجازه ندهیم تماس بگیرد .در این حالت خیلی ســاده میتوانیم از تابع
Blacklistدر استریســک استفاده کنیم .در این صورت اگر شمارهای در Blacklistوجود داشته باشد ،این
تابع مقدار » «Trueرا برمیگرداند ،در غیر این صورت » «Falseرا برمیگرداند .به مثال زیر توجه کنید:
;extensions.conf
)(exten => 207,1,NoOp
)same => n,GotoIf($[${BLACKLIST()}]?blocked,1
)same => n,Goto(IVR,s,1
با اســتفاده از دســتور زیر میتوان از طریق کامند الین استریسک ،شــماره جدید به لیست Blacklistاضافه
کــرد .در این حالت مقدار valueاهمیتی ندارد .تنها کافی اســت کالرآیدی مورد نظر در گروه blacklist
اضافه شود.
CLI> database put blacklist <number> 1
مثال فرض کنید بخواهیم شماره ۱۰۰را در لیست شمارههای blacklistاضافه کنیم:
CLI> database put blacklist 100 1
اکنون اگر با این کالر آی دی ،تماس وارد کانتکست شود ،خروجی زیر را خواهد داشت:
>CLI
-- Executing [207@LocalSets:1] NoOp("SIP/100-00000002", "") in new stack
-- Executing [207@LocalSets:2] GotoIf("SIP/100-00000002", "1?blocked,1") in new stack
)-- Goto (LocalSets,blocked,1
-- Executing [blocked@LocalSets:1] NoOp("SIP/100-00000002", "") in new stack
-- Executing [blocked@LocalSets:2] Playback("SIP/100-00000002", "silence/1") in new stack
)›-- <SIP/100-00000002> Playing ‹silence/1.gsm› (language ‹en
-- Executing [blocked@LocalSets:3] Playback("SIP/100-00000002", "privacy-you-are-
blacklisted") in new stack
225 برنامهنویسی پیشرفته در استریسک
-1پیــام خوش آمدگویــی : 4معموالً هر صندوق صوتی ،بــا یک پیام خوشآمدگویی کار خود را شــروع
میکند .در این حالت یک پیام اولیه (که این پیام میتواند بر اساس zoneمنطقه تغییر کند) پخش میشود و
از کاربر میخواهد بخش بعدی را شروع کند.
-2ضبط پیام کاربر : 5در این حالت ،کاربر پس از شــنیدن صدای بوق ( ،)beepمیتواند پیام خود را بگذارد.
سیستم پیام او را ضبط میکند.
-3کنتــرل پیامها در صندوق صوتی : 6معموالً در سیســتمهای صندوق صوتی ایــن قابلیت وجود دارد که از
طریــق منوها ،عملیات مختلفی روی پیامها از راه دور صورت گیرد ،از جمله خواندن پیامهای جدید ،حذف
پیام قبلی ،ذخیره کردن پیامها در آرشیو ،تغییر رمز عبور و غیره.
در استریســک این قابلیت وجود دارد که با طراحی یک صندوق صوتی ،هر کاربر یک صندوق صوتی
و حائز اهمیتی است. مجزا و منحصر به فرد داشته باشد .طراحی و پیکربندی یک صندوق صوتی نکته مهم
برای طراحی و پیکربندی صندوق صوتی در استریســک باید از فایل voicemail.confدر مسیر زیر استفاده
کنید.
# vim /etc/asterisk/voicemail.conf
1- Voicemail
2- Telephony Answering Machine
3- Voice Message Exchange
4- Greeting Massage
5- Recording Message
6- Remote Control Voicemail
مرجع آموزش ویپ با سافتسوئیچ استریسک 226
اغلب این تنظیمات به مشخصههای صندوق صوتی و تعریف آن مرتبط:) تنظیمات عمومی صندوق صوتی1
حداکثر، مشخصههایی از قبیل فرمت پیام ضبط شده، برای مثال.] قرار میگیردgeneral[ اســت که در بخش
تنظیمات جلو و عقب بردن، ماکزیمم مدت ضبط هر پیام بر حســب ثانیــه،تعــداد پیامها در صندوق صوتی
تنظیمات مربوط به ایمیلکردن پیامهای صوتی دریافت، تنظیمات امنیتی برای ورود به صندوق صوتی،پیامها
تنظیمات برای همه صندوقهای، با تعریف این مشــخصهها.شــده و غیره از جمله تنظیمات عمومی هســتند
. فهرستی از این تنظیمات را ارائه نموده است3-8 جدول.صوتی اعمال میشود
pagerfromstring The Asterisk We don’t actually know anybody who uses pagers anymore (nor can
PBX we recall having seen one in many years), but if you have one of these
historical oddities and you want to customize what Asterisk sends
with its pager notification, presumably you can do that with this. A
very practical application of this feature for short-message voicemail
notifications is to send a message to an email-to-SMS gateway.
pagersubject New VM As above.
pagerbody New ${VM_DUR} The formatting for this uses the same rules as emailbody.
long msg in
box ${VM_MAIL
BOX}\nfrom $
{VM_CALLERID},
on ${VM_DATE}
emaildateformat %A, %d %B %Y This option allows you to specify the date format in emails. Uses the
at %H:%M:%S same rules as the C function STRFTIME.
pagerdateformat %A, %d %B %Y This option allows you to specify the date format in pagerbody. Uses
at %H:%M:%S the same rules as the C function STRFTIME.
pollmailboxes no, yes If the contents of mailboxes are changed by anything other than app_
voicemail (such as external applications or another Asterisk system),
setting this to yes will cause app_voicemail to poll all the mailboxes for
changes, which will trigger proper message waiting indication (MWI)
updates.
pollfreq 30 Used in concert with pollmailboxes, this option specifies the number of
seconds to wait between mailbox polls.
greetingsfolder INBOX If you’ve enabled imapgreetings, this parameter allows you to define
the folder your greetings will be stored in (defaults to INBOX).
imapparentfolder INBOX IMAP servers can handle parent folders in different ways. This field
allows you to specify the parent folder for your mailboxes. For more
details, see Chapter 7.
imapserver localhost Defines the IMAP server Asterisk should connect to.
imapport 143 Defines the port of the IMAP server to connect to.
مرجع آموزش ویپ با سافتسوئیچ استریسک 230
imapfolder INBOX The folder to store voicemail messages in on the IMAP server. The
default is INBOX.
authuser user If your IMAP server has been defined with an account that can access
all mailboxes, you can define that user for Asterisk to connect to the
server with.
authpassword password This option defines the password to be used with the authuser
attribute.
imapopentimeout 60 The TCP open timeout in seconds.
imapclosetimeout 60 The TCP close timeout in seconds.
imapreadtimeout 60 The TCP read timeout in seconds.
imapwritetimeout 60 The TCP write timeout in seconds.
3-8 جدول
، عالوه بر تنظیمات عمومی که برای همه صندوقهای صوتی اعمال میشــود: تنظیمات صنــدوق صوتی-2
بــه عبارت دیگر این.تنظیمات و مشــخصههای ایــن بخش برای هر صندوق صوتی میتواند متفاوت باشــد
از جمله مهمترین این.تنظیمات و مشخصهها را برای هر صندوق صوتی میتوان بهصورت مستقل تنظیم نمود
ارسال، اعالن طول پیام صوتی، اعالن شماره کالرآیدی،مشخصهها میتوان به تنظیمات زبان صندوق صوتی
فهرســتی از این4-8 جدول. اعالن تاریخ و ســاعت دریافت پیام و تنظیمات دیگر اشــاره نمود،پیام به ایمیل
.تنظیمات را ارائه کرده است
های مختلف برای صندوقzone در این بخش میتوان زمان را بر اساس:zonemessage تنظیمات بخش-3
با این قابلیت میتوان یک. تعریفشده مرتب شودzone بر اساس،صوتی تنظیم نمود تا تاریخ دریافت پیامها
.سرویس صندوق صوتی بین المللی ایجاد کرد
[zonemessages]
مرجع آموزش ویپ با سافتسوئیچ استریسک 234
. باید آن را در کانتکســتهای مورد نظر و دلخواه تعریف و ایجاد کنید،برای تعریف یک صندوق صوتی
فرمت.[ ایجاد کنیمdefault] بــرای مثال فرض کنیــد بخواهیم یک صندوق صوتــی جدید در کانتکســت
:تعریف این صندوق صوتی بهصورت زیر خواهد بود
;voicemail.conf
[default]
mailbox => password [,full name [,email address [,short email address [,options[|options]]]]]
Option Description
attach Whether to attach the voicemail to the notification email versus the pager email. If set to yes,
will attach to the email defined by the email address field.
attachfmt Sets the format to attach to the email. Normally this is the first value defined by the format
option, but you can override that per mailbox by using this option. Option can only be set per
mailbox.
callback If defined, this option will allow the receiver of the email to call back the sender of the voicemail
directly from the Voicemail() application. This option defines which context the call will be sent
from. If not set, calling the sender back will not be permitted.
cidinternalcon This is a very old option from 2004, but essentially, you can define multiple contexts (separated
texts by a comma) that will tell Asterisk to check if the call came from an internal context. If so, it will
play back the person’s name recording instead of saying their extension number. It is unclear if
this option is still valid or functional. Likely best used in the [general] section of voicemail rather
than per mailbox.
235 برنامهنویسی پیشرفته در استریسک
Option Description
delete After sending the voicemail via email, the voicemail is deleted from the server. This option
is useful for users who only want to receive voicemail via email. Valid options are yes or no.
Option can only be set per mailbox.
dialout If defined, option 4 from the advanced menu will allow you to dial out from the Voicemail Main()
application. The argument defines which context the dialing will be performed from. If not
defined, the option to dial out will not be prompted to the caller.
envelope Turns on or off envelope playback prior to playback of the voicemail message. Valid options
are yes or no. Default is yes.
exitcontext The context to exit to when pressing * or 0 from the Voicemail() application. Works in
conjunction with the operator option as well. Must have an extension a in the context forexiting
with *. Must have an extension o in the context for exiting with 0.
forcegreeting Forces the recording of a greeting for new mailboxes. A new mailbox is determined by the
mailbox number and password matching. Valid values are yes or no. Default is no.
forcename Forces the recording of the person’s name for new mailboxes. A new mailbox is determined by
the mailbox number and password matching. Valid values are yes or no. Default is no.
hidefromdir If set to yes, this mailbox will be hidden from the Directory() application. Default is no.
locale Allows you to set the locale for the mailbox in order to control formatting of the date/time
strings. See voicemail.sample.conf for more information.
messagewrap Allows the first and last messages to wrap around; e.g., allow last message to wrap back to
the first on the next message, or first message to wrap to the last message when going to the
previous message. Valid options are yes or no. Default is no.
minpassword Sets the minimum password length. Argument should be a whole number.
nextaftercmd Skips to the next message after pressing the 7 key (delete) or 9 key (save). Valid values are
yes or no. Default is yes.
operator Will allow the sender of a voicemail to hit 0 before, during, or after recording of a voicemail.
Will exit to the o extension in the same context, or the context defined by the exitcontext
option. Valid options are yes or no. Default is no.
passwordlocation By default, the password for voicemail is stored in the voicemail.conf file, and modified by
Asterisk whenever the password changes. This may not be desirable, especially if you
want to parse the password from an external location (or script). The alternate option for
passwordlocation is spooldir, which will place the password for the voicemail user in a file
called secret.conf in the user’s voicemail spool directory. Valid options are voicemail.conf and
spooldir. The default option if voicemail.conf.
review When enabled, will allow the user recording a voicemail message to re-record their message.
After pressing the # key to save their voicemail, they’ll be prompted whether they wish to re-
record or save the message. Valid options are yes or no. Default is no.
saycid If enabled, and a prompt exists in /var/spool/asterisk/voicemail/recordings/callerids, then
that file will be played prior to the message, playing the file instead of saying the digits of the
callerID number. Valid options are yes or no. Default is no.
sayduration Determines whether to play the duration of the message prior to message playback. Valid
options are yes or no. Default is yes.
saydurationm Allows you to set the minimum duration to play (in minutes). For example, if you set the value
to 2, you will not be informed of the message length for messages less than 2 minutes long.
Valid values are whole numbers. Default is 2.
searchcontexts For applications such as Voicemail(), VoicemailMain(), and Directory(), the
voicemail context is an optional argument. If the voicemail context is not specified, then the
default is to only search the default context. With this option enabled, all contexts will be
searched. This comes with a caveat that, if enabled, the mailbox number must be unique
across all contexts—
otherwise there will be a collision, and the system will not understand which mailbox to use.
Valid options are yes and no. Default is no.
مرجع آموزش ویپ با سافتسوئیچ استریسک 236
Option Description
sendvoicemail Allows the user to compose and send a voicemail message from within the VoicemailMain()
application. Available as option 5 under the advanced menu. If this option is disabled, then
option 5 in the advanced menu will not be prompted. Valid options are yes or no. Default is no.
tempgreetwarn Enables a notice to the user when their temporary greeting is enabled. Valid options are yes or
no. Default is no.
tz Sets the time zone for a voicemail user (or globally). See /usr/share/timezone for different
available time zones. Not applicable if envelope=no.
volgain The volgain option allows you to set volume gain for voicemail messages. The value is in
decibels (dB). The sox application must be installed for this to work.
5-8 جدول
این تعریف بهصورت زیر، تعریــف کنیم۱۲۳4 بــرای مثال چنانچه بخواهیم یک صندوق صوتی با شــماره
:است
;voicemail.conf
[default]
1234 => 4242,Example Mailbox,root@localhost
[voicemail]
6713 => 123123,Mojtaba Esfandiari.S, mespio@gmail.com
6033 => 123123,Mojtaba Najafi, seyedmnmf@gmail.com
: وارد محیط کامندالین شوید و دستورات زیر را اجرا کنید،برای مشاهده صندوقهای صوتی
CLI> voicemail reload
CLI> voicemail show users
زمان ثبت فایل و کالر آی دی شخص تماس گیرنده،اگر خواســته باشــیم در زمان بررســی صندوق صوتی
: به صورت زیر عمل کنیم، باید در زمان تعریف صندوق صوتی،پخش شود
[voicemail]
6713 => 123123,Mojtaba Esfandiari.S, mespio@gmail.com,,saycid=yes|envelope=yes
6033 => 123123,Mojtaba Najafi, seyedmnmf@gmail.com,,saycid=yes|envelope=yes
دستور VoiceMail
با این دستور میتوان صندوق صوتی مورد نظر را فراخوانی کرد .فرمت استفاده از این دستور بهصورت زیر
است:
CLI> core show application VoiceMail
][Syntax
)]VoiceMail(mailbox[@context][&mailbox[@context][&...]][,options
در این مثال اگر کاربر Phone_1تماس را پس از مدت ۲۰ثانیه پاسخ ندهد ،تماس به سمت صندوق صوتی
تعریفشده منتقل میشود .اکنون برنامه را کمی توسعه داده و بهصورت زیر تغییر میدهیم.
;extensions.conf
][LocalSets
)(exten => 6713,1,NoOp
)same => n,Dial(SIP/Phone_1,10
)same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy,1:unavail,1
دستور VoiceMailMain
در استریسک این قابلیت وجود دارد که کاربران بتوانند از راه دور ،پیامهای صندوق صوتی خود را مدیریت
و کنترل کنند .دســتور VoiceMailMainاین امکان را فراهم میکند .قابلیتهایی که این دســتور در اختیار
کاربران میگذارد به شرح ذیل است:
• امکان شنیدن پیامهای جدید؛
• امکان شنیدن مجدد پیامهای قبلی؛
• امکان حذف پیام از صندوق صوتی؛
• امکان ضبط پیام خوشآمدگویی جدید؛
• امکان عوضکردن رمز عبور برای صندوقصوتی.
فرمت استفاده از این دستور به این صورت خواهد بود:
CLI> core show application VoiceMailMain
][Syntax
)]VoiceMailMain([mailbox][@context][,options
برای مثال برنامه زیر این قابلیت را برای کاربران فراهم میکند تا بتوانند صندوق صوتی خود را بررسی کنند.
][services
)(exten => *98,1,NoOp
)(same => n,VoiceMailMain
][LocalSets
include => services
در این مسیر پیامهای صوتی با فرمتهای wavو gsmذخیره میشوند .ساختار یک پوشه در صندوق صوتی
بهصورت زیر است:
/var/spool/asterisk/voicemail/default/1234
./INBOX
./Old
./Old/msg0000.WAV
./Old/msg0000.txt
./Old/msg0001.WAV
239 برنامهنویسی پیشرفته در استریسک
./Old/msg0001.txt
./Urgent
./busy.WAV
./unavail.WAV
./greet.WAV
صندوق صوتی در استریســک و تنظیمات آن تا اینجا بررســی شد .گاهی باید یک سیستم تلفنی استریسک
را بــه گونــهای تنظیم و پیکربندی کنیم که بتواند فقط در قالب یک سیســتم صندوق صوتی فعالیت کند .به
عبارت دیگر در صورت لزوم ،برای تقسیم بار ترافیکی ورودی در یک شبکه ویپ ،میتوان از سیستم صندوق
صوتی بهصورت جداگانه استفاده کرد .برای روشنتر شدن موضوع ،شکل 4-8را ببینید.
شکل 4-8
همانطورکه مالحظه میکنید ،در این شــکل کاربر) (SIP Telephoneمســتقیما با سرور Proxy Serverدر
ارتباط اســت .ســرور صندوق صوتی اینجا بهصورت مجزا طراحی و پیکربندی شدهاســت .در صورتی که
کاربر بخواهد از صندوق صوتی اســتفاده کند ProxyServer ،آن را به سمت سرور صندوق صوتی هدایت
میکند.
در طراحی شــبکههای ویپ این نکته را مد نظر داشــته باشید که برای توزیع مناسب تماسها و ترافیک،
بهتر است اجزا را بهصورت مستقل طراحی و پیکربندی کنید.
1- endpoint
مرجع آموزش ویپ با سافتسوئیچ استریسک 240
تماس مقدور نخواهد بود مگر اینکه یکی از دو حالت زیر اتفاق بیافتد:
-۱تماس انتقال 1یابد .در این حالت استریسک تماس را دوباره مسیریابی میکند تا به مقصد برسد.
-۲استفاده از Feature Codeها باعث میشود که عملیات مورد نظر برای کانال مورد نظر اجرا شود.
در ادامه به معرفی انواع Features Codeها میپردازیم.
Call Parking
اصطــالح پارک کــردن تماس ها این امکان را میدهد که تماس را در مکانــی بهصورت موقت نگهداریم
تا بعدا بتوانیم پاســخ دهیم .همانطورکه در شــکل ۵-8مالحظه میکنید Caller ،با سیستم تلفنی استریسک
تماس میگیرد و به کاربر UAC1متصل میشود.
شکل 5-8
سپس کاربر UAC1با استفاده از قابلیت Call Parkingتماس را پارک میکند )شکل .(۶-8
شکل 6-8
1- Transfer
241 برنامهنویسی پیشرفته در استریسک
شکل 7-8
شکل 8-8
در نهایت تماس برقرار میشود و دو نفر میتوانند با هم مکالمه داشتهباشند )شکل .(۹-8
شکل 9-8
در استریسک برای استفاده از Call Parkingباید به کمک فایل زیر تنظیمات و پیکربندی را انجام دهید:
#vim /etc/asterisk/features.conf
][general
parkext => 700
parkpos => 701-720
context => parkedcalls
مرجع آموزش ویپ با سافتسوئیچ استریسک 242
در این حالت اگر کسی با شما تماس بگیرد و شما آن را به شماره 7۰۰فوروارد کنید ،تماس آن شخص
بــه Parking lotمنتقل میشــود و آنجا منتظر میماند .با دســتور زیر میتوانید وضعیــت Parking lotها را
بررسی کنید.
ســپس هنگام فراخوانی دســتور Dialدر برنامهنویســی استریسک ،باید از آپشــنهای kیا Kبهصورت زیر
استفاده کنید.
][LocalSets
)exten => 100,1,Dial(SIP/100,20,kK
)exten => 101,1,Dial(SIP/101,20,kK
در این حالت نیازی نیســت کانتکســت parkedcallsرا به کانتکســت جاری اضافه کنیــد .بنابراین ،بعد از
7۲#را )بدون فشردن کلید ترنسفر( reloadکردن استریســک ،چنانچه در ضمن مکالمه ،هر کاربر شــماره
شمارهگیری کند ،عملیات Call Parkingمیشود.
شکل 10-8
-۲سپس کاربر اول تماس را برای کاربر دوم ترنسفر میکند).شکل (۱۱-8
1- Transfer
مرجع آموزش ویپ با سافتسوئیچ استریسک 244
شکل 11-8
شکل 12-8
ب( :Attended Transferشکلهای زیراین نوع ترانسفز را بهطور کامل تشریح کردهاند.
-۱ابتدا مشترک با کاربر اول مکالمه میکند).شکل (۱۳-8
شکل 13-8
-۲ســپس کاربــر اول تماس را برای کاربر دوم ترنســفر میکند .در این حالت مشــترک به وضعیت انتظار
میرود و باید منتظر بماند )شکل .(۱4-8
245 برنامهنویسی پیشرفته در استریسک
شکل 14-8
-۳کاربر دوم گوشــی را برمــیدارد و با کاربر اول مکالمه میکند .در این حالت هم مشــترک همچنان در
حالت انتظار بهسر میبرد )شکل .(۱۵-8
شکل 15-8
-4چنانچه کاربر اول گوشی خود را بگذارد ،مشترک از حالت انتظار خارج و به کاربر دوم متصل میشود.
)شکل .(۱۶-8
شکل 16-8
برای فعال کردن این روشها باید تغییرات زیر را در استریسک ایجاد کنید.
ابتدا فایل features.confرا باز و تغییرات زیر را اعمال کنید:
;features.conf
][featuremap
blindxfer => #1
مرجع آموزش ویپ با سافتسوئیچ استریسک 246
atxfer => *2
. بهصورت زیر استفاده کنیدT یاt از آپشنهای، در برنامهنویسی استریسکDial هنگام فراخوانی دستور
[LocalSets]
exten => 100,1,Dial(SIP/100,20,tT)
exten => 101,1,Dial(SIP/101,20,tT)
فعال میشــود و اگر از کدBlind Transfer عملیات، اســتفاده کنید۱# اکنون اگر در زمان مکالمه از کد
هایی کهFeature Code انــواع۶-8 جدول. فعال میشــودAttended Transfer عملیات،* اســتفاده کنید۲
.بهصورت پیشفرض در استریسک تعریف شدهاند را نشان میدهد
6-8 جدول
1
های پویا در استریسکFeture Code استفاده از
های جدیدی تعریفFeature Code ،یکی دیگر از قابلیتهای استریسک این است که میتوان بسته به نیاز
با، نگاشــت کرد و در زمان مورد نیاز، در واقع میتوان اجرای برخی دســتورات را به کدهای خاصی.کرد
. آن دستورات را اجرا کرد،شمارهگیری کد مورد نظر
.فرمت تعریف این قابلیت در استریسک بهصورت زیر است
[applicationmap]
<FeatureName> = <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppAr
guments>[,MOH_Class]]
:پارامترها
. برای استفاده از آن یک نام به آن بدهید:FeatureName پارامتر
. شماره تعریفشده برای اجرای این ویژگی است:DTMF_Sequence پارامتر
: این پارامتر دو مقدار میتواند به خود بگیرد:ActiveOn پارامتر
1- Application Map (Custom Dynamic Features)
247 برنامهنویسی پیشرفته در استریسک
در این تعریف مشــخص کردهایم که اگر کد #9را شــماره گیری شــود ،فایل صوتی demo-thanksبرای
calleeپخش می شــود .نام آن را playdemoگذاشــتیم .اکنون برای اســتفاده از آن در استریســک ،باید
بهصورت زیر اقدام کنید:
;extensions.conf
][LocalSets
)exten => 100,1,Set(__DYNAMIC_FEATURES=playdemo
)same => n,Dial(SIP/100,20,tTkK
)exten => 101,1,Set(__DYNAMIC_FEATURES=playdemo
)same => n,Dial(SIP/101,20,tTkK
)exten => 102,1,Set(__DYNAMIC_FEATURES=playdemo
)same => n,Dial(SIP/102,20,tTkK
پس از انجام تغییرات فوق ،استریســک را مجددا reloadکنید .بعد از ایجاد تماس ،اگر کد #9گرفته شود،
پیام صوتی demo-thanksپخش میشــود .میتوانید از این قابلیتها در استریسک استفاده کنید و Feature
codeهای مختلفی برای سیستم تلفنی استریسک طراحی کنید.
1- Confferance
مرجع آموزش ویپ با سافتسوئیچ استریسک 248
فرمت تعریف یک کنفرانس در این فایل بهصورت زیر اســت .برای این منظور باید در کانتکست ][rooms
آن را تعریف کنید.
][rooms
]conf => confno[,pin][,adminpin
پارامترهای الزم:
پارامتر :confnoبا این پارامتر شماره کنفرانس را مشخص میکنیم.
پارامتر :pinمیتوان برای ورود به یک کنفرانس ،رمز عبور تعیین کرد.
پارامتر :adminpinمدیر کنفرانس میتواند با رمز تعیینشدهای ،وارد سیستم شود.
برای مثال فرض کنید قرار است یک کنفرانس جدید با شماره ۱۵۱۵در سیستم تلفنی استریسک ایجاد
کنیم .برای این منظور باید تغییرات زیر را اعمال کنیم.
;meetme.conf
][rooms
conf => 1515,123123,123321
][LocalSets
include => ConferenceRooms
در این حالت ،چنانچه کاربری شــماره ۱۵۱۵را شــماره گیری کند ،ابتدا رمز عبور کنفرانس از او پرســیده
249 برنامهنویسی پیشرفته در استریسک
میشــود و در صورت تایید رمز ،کاربر وارد کنفرانس میشــود .فرمت استفاده از این دستور بهصورت زیر
است:
CLI> core show application MeetMe
][Syntax
)]]MeetMe([confno][,options[,pin
مثال (۱فرضکنید قرار باشــد اعضای یک کنفرانس را شمارش کنیم .برای این منظور از دستور زیر استفاده
میکنیم:
;extensions.conf
)(exten => 1516,1,NoOp
)same => n,Playback(conf-thereare
)same => n,MeetMeCOUNT(1515
)same => n,Playback(conf-peopleinconf
مثال (۲فرض کنید یک کنفرانس با ظرفیت ۱۰نفر بهصورت زیر تعریف کردهباشــیم .با وارد شــدن هر نفر
به کنفرانس ،یک نفر به افراد حاضر در کنفرانس اضافه میشــود .پس از اینکه تعداد افراد حاضر به ۱۰نفر
رســید ،از ورود افراد بیشــتر به کنفرانس جلوگیری میشــود .در این برنامه از تکنیک متغیرهای سراسری و
ماکرو استفاده میشود.
;extensions.conf
][globals
CONFMAX => 10
][ConferenceRooms
))exten => 1517,1,Macro(MyConf,1515
مرجع آموزش ویپ با سافتسوئیچ استریسک 250
][LocalSets
include => ConferenceRooms
][macro-MyConf
)exten => s,1,MeetMeCOUNT(${MACRO_EXTEN},COUNT
)same => n,GotoIf($[${COUNT} >= ${CONFMAX}]?full
)}same => n,MeetMe(${MACRO_EXTEN
)(same => n,Hangup
)same => n(full),BackGround(conf-full
same => n,Hangup
][default_user
type=user
][default_bridge
type=bridge
Option Description
admin Determines if the user is marked as an administrator of the conference. Users marked as
administrators can be given different options only available to administrators in the user
menu. The menus are defined in confbridge.conf and selected when the ConfBridge()
application is called from the dialplan. Available options are yes or no. Default is no.
marked Sets whether user in this profile should be marked or not. Used to start a conference when
waiting on a marked user. See wait_marked and end_marked. Available options are yes or
no. Default is no
startmuted Sets users in this profile as muted when initially joining the conference. Available options
are yes or no. Default is no.
music_on_hold_when_ Determines whether MOH should be played when only one conference participant exists,
empty or when the conference is waiting on a marked user. Available options are yes or no.
Default is no.
music_on_hold_class Sets which MOH class should be used. Default value is default.
quiet If enabled, this option will limit the sounds played into the conference, such as join sounds
and user announcements. Available options are yes or no. Default is no
announce_user_count If enabled, the number of users in the conference are announced to the joining participant
prior to entering the conference. Available options are yes or no. Default is no.
announce_user_count_ Used for announcing the participant count to all members of the conference. If set to a
all number, then the announcement is only played when the number of participants is above
the set number. Available options are yes, no, or a whole number. Default is no
announce_only_user If enabled, a prompt will be played when the first participant of a conference joins, notifying
they are the only member of the conference. Available options are yes or no. Default is yes.
wait_marked If enabled, the participant of the conference must wait for a marked user to join. Available
options are yes or no. Default is no.
end_marked Determines if remaining users after the last marked user leaves the conference are
removed from the conference. Available options are yes or no. Default is no.
dsp_drop_silence When enabled, Asterisk will drop what it detects as silence from the conference, drastically
deducing the buildup of background noise in the conference. Recommended for large
conferences where background noise can become a problem. Available options are yes or
no. Default is no.
dsp_talking_ A value in milliseconds—the length of time sound has remained above the baseline value
threshold the DSP has established. The value should not be changed unless you are familiar with the
internals of how this number can affect your conference. See the conf bridge.conf.sample
file in the contribs directory of your Asterisk source for more information
dsp_silence_ Similar to dsp_talking_threshold, but looking for silence. Value in milliseconds. Not
threshold recommended to be tuned.
talk_detection_ If enabled, a notification of when a speaker begins and ends talking is sent as an event
events over AMI. Available options are yes or no. Default is no.
denoise The denoise option is useful if you’re using the speex codec, and the talker has an elevated
level of background noise. When enabled, this option will attempt to remove background
noise before the audio is mixed into the conference, while preserving the desired speech
audio. This option should not be confused with dsp_drop_silence. Additionally, this option
does come at a slight performance hit. Available options are yes or no. Default is no
مرجع آموزش ویپ با سافتسوئیچ استریسک 252
Option Description
jitterbuffer If enabled, then the jitterbuffer will be enabled on the user’s audio channel prior to mixing.
This is desirable in that it can help smooth out the audio played into the conference
bridge, at the expense of a slight delay. This option utilizes the JITTER BUFFER() dialplan
function’s adaptive mode. If fine-tuned configuration of the jitterbuffer is desired, then
disable this option, and use the JITTERBUFFER() function prior to calling the ConfBridge()
application. Available options are yes or
no. Default is no.
pin If set, then the person entering the conference will be prompted for a PIN. Valid value is
any integer
announce_join_leave If enabled, the person entering the conference will be prompted to record their name prior
to joining the conference. The name will then be played, announcing the person joining and
leaving the conference. Available options are yes or no. Default is no.
dtmf_passthrough When enabled, this option will allow DTMF to be passed through the conference. This
is useful when the conference bridge may be connected to an endpoint that you want
to receive DTMF; otherwise, it is absorbed by Asterisk. Available options are yes or no.
Default is no.
announcement If set, an announcement prompt is played to users when they join the conference. Value
should be a path to an announcement file
7-8 جدول
هنگام. این بخش مربوط به پیکربندی و تعریف سیاستهای کنفرانس است:]default_bridge[ • بخش
انواع پارامترهای8-8 جدول. از این پیکربندی و سیاســتها استفاده میشود،ایجاد یک کنفرانس جدید
.قابل تعریف در این بخش را نشان میدهد
Option Description
max_members Defines the maximum number of conference participants for a single conference. When the limit
is reached, the conference will be locked until a participant leaves. The only exception is that
administrators are always able to join the conference, regardless of the number of participants.
Value should be an integer. Default is unlimited participants.
record_confer When enabled, the conference will start being recorded when the first participant joins the
ence conference, and stop recording when the last participant leaves. The filename for the recording is
in the format confbridge-<name of the conference bridge>-<start time>.wav. The file by default will
be recorded in 8 kHz slinear. The recording will be saved in the monitoring directory configured in
asterisk.conf. Available options are yes or no.
record_file If record_conference is enabled, you can specify the filename for the recorded conference.
However, since multiple conferences could potentially use the same bridge profile, it is not
recommended to specify this option in the confbridge.conf file itself. Instead, use the CONF
BRIDGE() function to dynamically set the filename prior to entering the conference in the dialplan.
internal_sam This option will set the internal conference native sampling rate at which mixing will occur. By
ple_rate default, the sample rate is automatically selected; however, you can specify a value between
8,000 and 192,000. If you set a sample rate that Asterisk doesn’t support, the closest rate that
Asterisk does support will be used. Available values are auto or a value between 8000 and
192000. Default is auto.
253 برنامهنویسی پیشرفته در استریسک
Option Description
mixing_interval This option sets the internal mixing interval of the conference bridge, in milliseconds. Setting a
higher mixing interval can reduce the amount of load used by large conferences at the expense
of a more loosely coupled conference (e.g., delay). Valid values are 10, 20, 40, and 80. Default
value is 20.
video_mode The video_mode option is used for controlling how video is distributed to conference participants
who can source and/or view video feeds. Participants who want to view and be the source of
video must share the same video codec, such as H.264 (in sip.conf, use allow=h264 in addition
to your audio codecs). Additionally, it is recommended that you turn off the jitterbuffer, since the
jitterbuffer only works on the audio portion of the conference, and thus can cause the audio and
video to become out of sync.
none By default, no video sources are selected. You can still enable a video source for the conference
via DTMF or the AMI.
follow_talker The source video will be that of whoever is talking in the conference (loudest) and which has a
video source. The video source will see the last selected source of video, and not their own.
last_marked The source video will be the last marked user to have joined the conference. If multiple marked
conference participants joined the conference and the last marked user leaves, then the marked
participant who joined just prior to the last will become the source (and so forth).
first_marked Similar to last_marked, the first marked participant of a conference with a video source will be the
source of video for the conference. If that participant leaves, then the next marked participant with
a video source will become the source video for the conference.
8-8 جدول
میتوانید اعالن صوتی مورد نظر را.تمام اعالنهای صوتی درون کنفرانس قابل تنظیم در این بخش هســتند
.(۹-8 برای هر یک از پارامترها تعیین کنید )جدول
Option Description
sound_join Sound played when a participant joins the conference
sound_leave Sound played when a participant leaves the conference
sound_has_joined Sound played when announcing the name of a joining participant
sound_has_left Sound played when announcing the name of a leaving participant
sound_kicked Sound played to a participant when they have been removed from the conference
sound_muted Sound played to a participant when they have been muted
sound_unmuted Sound played to a participant when they have been unmuted
sound_only_person Sound played to a participant when they are the only member of the conference
sound_only_one Sound played to a joining participant when there is only one other participant in
the conference
sound_there_are Sound played when announcing how many participants are in the conference
sound_other_in_party The adjoining sound used with sound_there_are; the sound files are
concatenated like this: sound_there_are number_of_participants
sound_other_in_party
sound_place_into_ Sound played to the participant when being placed into a conference after waiting for the
conference marked user to join
sound_wait_for_leader Sound played to the participant notifying them they are waiting for a marked user to join the
conference
مرجع آموزش ویپ با سافتسوئیچ استریسک 254
Option Description
sound_leader_has_left Sound played when the last marked user has left the conference
sound_get_pin Sound played to the participant when requesting a PIN for the conference
sound_invalid_pin Sound played to the participant when they have entered an invalid PIN
sound_locked Sound played to the participant when they have attempted to join a locked
conference
sound_locked_now Sound played to an administrator after they have locked the conference
sound_unlocked_now Sound played to an administrator after they have unlocked the conference
sound_error_menu Sound played when an invalid menu option has been entered
. کنیدreload وارد محیط کامندالین استریسک شوید و ماژول مربوطه را،بعد از انجام تنظیمات موردنظر
CLI> module reload app_confbridge.so
1- Actions
255 برنامهنویسی پیشرفته در استریسک
Option Description
playback(<audio_file The playback option can be used to play audio to the participant entering the
name>[[&<audio_filename>]]) DTMF string. The audio cannot be interupted with this option. Similar in style to
the Playback() dialplan application.
playback_and_ Similar to playback except that it will listen for DTMF while the audio is being
continue(<audio_ played. This is useful in situations where you create an audio menu and wish to
filename>[[&<audio_ allow DTMF to be entered during playback. Similar in style to the Background()
filename>]]) dialplan application
toggle_mute Toggles mute between on and off states for the participant. While mute is
enabled, the participant’s audio will not play into the conference bridge, but she
will still be able to listen.
no_op The no_op option performs No Operation. Its purpose is simply for reserving
DTMF sequences in the menu
decrease_listening_volume Decrease the listening volume of the participant.
increase_listening_volume Increase the listening volume of the participant.
reset_listening_volume Reset the listening volume of the participant to the default value.
decrease_talking_volume Decrease the talking volume of the participant.
increase_talking_volume Increase the talking volume of the participant.
reset_talking_volume Reset the talking volume of the participant to the default value.
dialplan_exec(context,exten Use of the dialplan_exec option allows a participant to leave the conference,
sion,priority_label) execute a dialplan, and at the end of the dialplan be returned to the conference.
leave_conference Allows the participant to leave the conference through the use of a DTMF
sequence. Dialplan execution will continue after the ConfBridge() application.
admin_kick_last Allows an administrator to kick the last joining participant from the conference.
This option is only available to administrators so it can be safely enabled in a
common menu between users and admins.
admin_toggle_conference_ Allows an administrator to toggle the conference being locked between on and
lock off. Can only be utilized by admins even if enabled in a user menu.
set_as_single_video_src Allows a participant to set themselves as the single video source for the
conference. This enables video to be stuck to a single participant, regardless of
which mode video_mode is set to
release_as_single_video_src The denoise option is useful if you’re using the speex codec, and the talker has
an elevated level of background noise. When enabled, this option will attempt to
remove background noise before the audio is mixed into the conference, while
preserving the desired speech audio. This option should not be confused with
dsp_drop_silence. Additionally, this option does come at a slight performance hit.
Available options are yes or no. Default is no
admin_toggle_mute_ Allows an administrator to toggle between muting and unmuting all nonadmin
participants participants in the conference. Admins will still be able to speak to the
conference. When this option is toggled, all participants including administrators
will be notified that the conference has been muted.
participant_count When used, will tell the participant how many total participants are in the
conference.
۱۰-8 جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 256
:مثال( فرض کنید رولهای زیر را برای ایجاد یک کنفرانس بهصورت زیر داشته باشیم
;confbridge.conf
[sample_user_menu]
type=menu
*=playback_and_continue(conf-usermenu)
*1=toggle_mute
1=toggle_mute
*4=decrease_listening_volume
4=decrease_listening_volume
*6=increase_listening_volume
6=increase_listening_volume
*7=decrease_talking_volume
7=decrease_talking_volume
*8=leave_conference
8=leave_conference
*9=increase_talking_volume
9=increase_talking_volume
[LocalSets]
include => ConferenceRooms
. کاربر وارد کنفرانس میشــود،گرفته شــود۱۵۲۰ اگر شــماره، کردن ماژول مربوطهreload اکنون بعد از
،[sample_user_menu] کاربر پس از ورود به کنفرانس میتواند با گرفتن کدهای تعریف شده در قسمت
.با نحوه استفاده از آنها آشنا شود
( در هنگام ورود به کنفرانس استفادهPIN) میتوان از رمز عبورMeetMe در این دستور همانند دستور
. برای این منظور تغییرات زیر را در پیکربندی کنفرانس انجام دهید.نمود
;confbridge.conf
[general]
[default_user]
type=user
pin=123123
[default_bridge]
type=bridge
. باید بهصورت زیر تغییرات را در برنامه اعمال کنید،ConfBridge هنگام استفاده از دستور
[ConferenceRooms]
257 برنامهنویسی پیشرفته در استریسک
پس از آن ،تنظیمات زیر را هنگام تعریف سیاستهای کنفرانس ،انجام دهید:
;confbridge.conf
][default_bridge
type=bridge
video_mode=follow_talker
در اینجا منظور از ،follow_talkerکاربری است که در حال حاضر در کنفرانس در حال صحبت است.
نتیجهگیری
در این فصل با مفاهیم بیشــتری درخصوص برنامهنویســی در استریســک ،کتابخانهی قدرتمندی از توابع و
دســتورات ،تفاوت آنها با یکدیگر و چگونگی اســتفاده از آنها ،آشنا شدید .پس از بررسی فرمت استفاده
از دســتورات استریسک ،به معرفی قابلیتهای برجســتهای از قبیل Local Channelsها Feature Code ،ها
و ایجاد کنفرانس در استریســک پرداختیم .البته نمیتوان تمام دســتورات و توابع موجود در استریســک را
بهصورت مفصل شــرح داد .بنابراین ،در فصل بیستم )آشــنایی با دستورات و توابع پرکاربرد در استریسک(
بهطور مســتقل مهمترین دســتورات و توابع در استریســک را بررســی خواهیمکــرد .در فصلهای آینده با
ویژگیهای بیشتری از استریسک آشنا خواهیدشد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 258
فصل نهم
صف ()ACD
یکی از ویژگیهای مهم در سیستمهای تلفنی ،قابلیت استفاده از صفهاست .شاید استفاده از صف در معنای
عام چندان پر اهمیت نباشد ولی از چنان امتیازات برجستهای برخوردار است که به کمک آن میتوان کنترل
و مدیریت جامعی بر تماسهای ورودی یک سیســتم تلفنی داشت .به همین دلیل در معنای کاربردی ACD
۱نامیده میشوند.
امروزه استفاده از این توانمندیها در سیستمهای تلفنی رو به گسترش است؛ برای مثال وقتی با سازمانی
تماس میگیرید ،معموال پیش از ارتباط با اپراتور ،سیســتم تلفنی بهطور خودکار تماس را پاســخ میدهد و
ضمن تشکر ،از شما میخواهد که منتظر بمانید تا به اپراتور متصل شوید.
ممکن اســت این ســؤال در ذهن مخاطبان بهوجود آید که با استفاده از صفها ،چگونه کنترلی میتوان
بر تماس ورودی داشته باشیم .میتوان با مثالی ساده آن را توضیح داد:
فرض کنید تعداد منابع شــهری )خطوط ارتباطی شــبکه ویپ با شــبکه مخابراتی (PSTNبیش از تعداد
کاربران )اپراتورها( یک سازمان باشد .مسلماً در چنین وضعیتی اگر تماسهای ورودی مستقیماً به اپراتورها
متصل شــود ،تماسهای زیادی به دلیل »کمبود اپراتور در ســازمان« و عدم امکان پاســخگویی از دســت
خواهند رفت .در این حالت ،صرفنظر از »عدم رضایتمندی در پاسخگویی« نمیتوان بر سیستم مدیریت
و نظارت داشت .از طرف دیگر بدون استفاده از صف نمیتوان عملکرد اپراتورها را در کیفیت پاسخگویی
زیــر نظر داشــت .به همین دلیل ،با تکنیک ACDمیتوان همه تماسهــای ورودی را کنترل کرد و افزایش
رضایتمندی مشتریان از کیفیت پاسخگویی و سطح سرویسدهی را بهدست آورد.
موضوعات مطرح شــده در این فصل از کتاب ،برای طراحی یک کالســنتر 1بسیار بااهمیت و ارزشمند
اســت؛ بهطوریکه بــا مطالعه این فصل میتوانید بهراحتی یک سیســتم کالســنتر طراحــی و گزارشهای
ارزشــمندی تولید کنید .نکته مهم در طراحی یک کالســنتر خوب ،شناخت کافی و جامع نسبت به اجزای
طراحی آن است که در این کتاب به تفصیل بررسی شده است .در واقع هدف از این فصل ،آموزش طراحی
یک کالسنتر و تحلیل بخشهای مختلف آن ازطریق سیستم تلفنی استریسک است ،اما پیش از پرداختن به
بحث اصلی ،بهتر است انواع کالسنترها را معرفی نماییم:
:Inbound -1همان قابلیت ACDاست که کنترل تماسهای ورودی را برعهده دارد.
:Outbound -2تکنیک Predictive Dialerاست و کنترل تماسهای خروجی را برعهده دارد.
تمرکز ما در این فصل روی کالسنتر با تماسهای ورودی ۲ ACDخواهد بود.
ازآنجاکه مطالب این فصل بســیار ساده و کاربردی اســت ،بر مثالها و تمرینها تمرکز بیشتری صورت
گرفته است.
شکل 1-9
در نسخههای جدیدتر برنامه استریسک ،استفاده از agentها کمتر توصیه شده است ،به این دلیل که استفاده
از آنها در صف با مشکالتی همراه است و انعطافپذیری الزم را ندارند .بنابراین در این کتاب بیشتر روی
اگــر فایل را باز کنید ،یک راهنمای کامل از انواع پارامترهای موجود در صف را مشــاهده میکنید .برخی
از پارامترهای استریســک ،مفهومی کلی و جامع دارند و غالبا برای همه صفها قابلاســتفادهاند .همانطور
که قب ً
ال اشاره شد ،به دلیل کاربردی بودن مطالب این فصل ،و برای فهم بهتر کالسنتر ،این مفاهیم را تا حد
ممکن با یک مثال همراه خواهیم کرد.
برای مثال فایل queues.confرا از مســیر باال باز کنید ،همان طور که مالحظه می کنید در ابتدای فایل،
کانتکست ] [generalوجود دارد .تنظیمات این بخش بر همه صف ها اعمال خواهد شد.در ادامه هر یک از
این پارامترها را به تفصیل شرح خواهیم داد.
پارامتر :autofillیکی از پارامترهای مهم در تعریف صف autofillاســت .در نســخههای اولیه استریســک،
برای طراحی صفها یک چالش اصلی وجود داشت؛ تا زمانی که نفر اول صف بهوسیله اپراتورها پاسخ داده
نمیشــد ،نفرات بعدی بایــد در صف منتظر میماندند و این در حالی بود که تمــام اپراتورها در صف آزاد
1
بودند .پر واضح است که در چنین شرایطی ،زمان انتظار 2برای اتصال به اپراتورها افزایش مییابد.
در نسخههای جدید برنامه ،با تنظیم پارامتر autofill=yesدر صف ،این امکان فراهم میشود که به تعداد
اپراتورهای آزاد در صف ،تماسهای موجود در صف به اپراتورها متصل شوند.
autofill=yes
شکل 2-9
در این حالت اگر autofill=noباشــد ،صرفنظر از اینکه اپراتورها آزاد باشــند یا نباشــند؛ نفر اول از صف
برداشته و به اولین اپراتور وصل میشود .تا زمانی که این تماس به اپراتور متصل نشود ،نفرات بعدی در صف
منتظر میمانند .اما چنانچه autofill=yesباشد ،صف بهصورت همزمان ،به تعداد اپراتورهای آزاد ،تماسها
را به ترتیب اولویت برداشــته و به اپراتور متصل میکند .در چنین حالتی اگر اپراتور تماســی را پاسخ ندهد،
تماس بالفاصله به اپراتور بعدی منتقل میشود .در این شرایط واضح است که سرعت پاسخگویی در صف،
چندین برابر میشود .با یک مثال این وضعیت را نمایش میدهیم.
مثال( یک شرکت خدمات پس از فروش ،سناریویی شبیه زیر دارد:
یک خط ایوان دارای ۳۰کانال همزمان.
تعداد ۱۰اپراتور پاسخگو در سیستم که همگی فعالند ) آن را با متغیر mنشان میدهیم.(m =۱۰ ،
در این سیستم autofill=noتنظیم شدهاست.
نرخ سرعت پاسخ دادن به تماسها بهوسیله اپراتورها ،حداکثر ۲۰ثانیه است ).(AnswerTime=۲۰ s
متوسط سرعت پاسخگویی ۱۰ ،ثانیه است ).(Average Answer Time
متوسط مدت پاسخگویی هر اپراتور ۵ ،دقیقه است ).(Duration Time= ۵ min
مدت زمان انتظار در صف برای مشتریان:
زمان انتظار در صف برای نفر اول1 × 10s = 10s :
2 × 10s = 20s زمان انتظار در صف برای نفر دوم:
.
.
.
زمان انتظار در صف برای نفر nامn × 10s :
برای چنین سیســتمی اگر 10نفر همزمان در صف وجود داشتهباشــد ،نفر آخر باید بهطور متوســط
10×10ثانیه منتظر بماند تا به اپراتور متصل شود .چنانچه تعداد افراد منتظر در صف از این هم بیشتر باشد،
متوسط مدت زمان مکالمه هر اپراتور به همان نسبت افزایش مییابد.
اکنــون ســناریوی باال را با پارامتــر autofill=yesتکــرار کنید .در این حالت زمــان انتظار در صف
بهصورت زیر تغییر میکند.
• مدت زمان انتظار در صف برای مشتریان:
برای نفر اول ⌈1⁄m⌉ × 10s :
برای نفر دوم⌈2⁄m⌉ × 10s:
.
.
.
برای نفر nام⌈n⁄m⌉ × 10s :
مرجع آموزش ویپ با سافتسوئیچ استریسک 264
حالت فرض کنید تعداد اپراتورهای منتظر در صف m=۱۰نفر باشــد .واضح است که برای ۱۰نفر اول
مشتریان منتظر در صف ،زمان انتظار ثابت است؛ چون به تعداد اپراتورهای آزاد ،تماسها به اپراتورها منتقل
میشــود .اگر تعداد افراد منتظر در صف بیش از ۱۰نفر باشــد ،در این حالت متوسط زمان مکالمه هم اضافه
میشود.
پارامتــر :musicOnHoldپارامتر بعدی در تعریف صف musiconhold ،اســت .برای افرادی که در صف
منتظر ارتباط با اپراتور هســتند ،میتوان یک موزیک انتظار پخش کرد تا زمان انتظار برایشــان خســتهکننده
و ماللآور نباشــد .به کمک این پارامتــر ،یک موزیک برای زمان انتظار مشــخص میکنیم .پیشتر درباره
موزیک انتظار در فصل سوم توضیح داده شد.
musiconhold=default
پارامتر :strategyشاید این مطلب قبال در ذهن مخاطب خطور کردهباشد که بر چه معیاری تماسها از صف
به اپراتورها متصل میشــوند؟ در استریســک رولهای منظم و از پیش تعیین شدهای وجود دارد که میتوان
از آنها اســتفاده کرد .بهعنوان مثال استفاده از استراتژی round robinباعث میشود انتخاب اپراتور بهشکل
چرخشی انجام شود.
strategy=rrmemory
Strategy Description
ringall ring all available channels until one answers (default)
leastrecent ring interface which was least recently hung up by this queue
fewestcalls ring the one with fewest completed calls from this queue
random ring random interface
rrmemory round robin with memory, remember where we left off last ring pass
rrordered same as rrmemory, except the queue member order from config file is preserved
linear rings interfaces in the order specified in this configuration file.
- If you use dynamic members, the members will be rung in the order in which they were added
wrandom rings random interface, but uses the member's penalty as a weight when calculating their metric. So a
member with penalty 0 will have a metric somewhere between 0 and 1000, and a member with penalty
1 will have a metric between 0 and 2000, and a member with penalty 2 will have a metric between 0
and 3000. Please note, if using this strategy, the member penalty is not the same as when using other
queue strategies. It is ONLY used as a weight for calculating metric.
1-9 جدول
فرض کنید تمام اپراتورها از. اســتjoinempty پارامتر، پارامتر بعدی در تعریف صف:joinemptyپارامتر
واضح است که این تماس برای همیشه (یا تا.صف خارج شــده باشند؛ سپس یک مشــترک وارد صف شود
در. مشــخص شــده) در صف باقی میماند و هیچ اپراتوری نیست که تماس او را پاسخ دهدtimeout زمان
تماس، را به گونهای تنظیم مینماییم که اگر اپراتوری در صف وجود نداشتjoinempty این شرایط پارامتر
.جدیدی به داخل صف وارد نشود
joinempty=no
تماسی به این اپراتور، اگر اپراتوری در حال مکالمه باشــد و بر اســاس چرخه استراتژی:ringinuse پارامتر
اگر مایل نباشیم تماسهای جدید به اپراتورهای در حال. بهعنوان پشت خطی به اپراتور اعالم میشود،برسد
. این پارامتر را به صورت زیر تنظیم میکنیم،مکالمه ارسال شوند
ringinuse=no
بگذاریدmyqueue اسم صف را.پیش از ادامه بحث بهتر اســت یک صف جدید در استریسک ایجاد کنیم
:و تنظیمات زیر را انجام دهید
. یک فایل دیگر را برای ایجاد تغییرات اضافه کنید، را باز کنید و به انتهای آنqueues.conf ابتدا فایل
;queues.conf
#include queues_custom.conf
مرجع آموزش ویپ با سافتسوئیچ استریسک 266
][myqueue
musicclass=default
strategy=rrmemory
joinempty=no
leavewhenempty=yes
ringinuse=no
با تعریف پارامترهای باال ،یک صف با نام myqueueدر استریســک ایجاد میشــود .اکنون برای اعمال آن
باید ماژول صف را reloadکنیم .برای این منظور به محیط کامندالین استریســک بروید و دســتور زیر را
اجرا کنید.
CLI> module reload app_queue.so
یا
CLI> queue reload all
همانطورکه مالحظه میکنید با هر دو روش فوق میتوان ماژول صف را دوباره راهاندازی کرد .توجه داشته
باشــید که صف بهعنوان یک اپلیکیشن و بهصورت ماژول به استریسک اضافه شدهاست و میتوانید )اگر به
این ماژول نیازی ندارید( آن را غیر فعال یا حذف کنید.1
برای مشاهده وضعیت صفهای موجود در استریسک ،دستور زیر را اجرا کنید.
CLI>queue show
خروجی دستور فوق حاوی اطالعات مفید و ارزشمندی در خصوص صف خواهد بود.
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
No Members
No Callers
همانطورکه در خروجی دستورفوق مالحظه میکنید ،اطالعات زیر قابل استخراج است:
:Wوزن صف را نشان میدهد .صفهای با وزن بیشتر ،اولویت باالتری برای برقراری ارتباط دارند .در ادامه
درباره صفهای وزندار )با اولویت( مطالب بیشتری خواهد آمد.
:Cتعداد تماسهای وارد شده به داخل صف را نشان میدهد که پاسخ داده شده اند.
:Aتعداد تماسهای وارد شــده به داخل صف را نشــان میدهد که پاسخ داده نشده اند)قبل از اینکه اپراتور
تماس را پاسخ دهد تماس قطع شده است(.
-1جهت حذف کردن ماژولها از استریسک میتوانید به فصل سوم (نصب و راه اندازی استریسک) مراجعه کنید.
267 آشنایی با صفها در استریسک
در واقع این پارامتر تعداد تماسهای پاسخ دادهشده در یک زمان. استservice level نشــان دهندهی:SL
، هنگام تعریف صفservicelevel زمان را بهوســیله پارامتر.مشــخص را برحســب درصد نشــان میدهد
.مشخص میکنیم
. این پارامتر را لحاظ میکنیمmyqueue برای مثال در تعریف صف
servicelevel=60
[LocalSets]
include => Queues ; allow phones to call queues
: این دستور را اجرا کنید، برای تست برنامه. استفاده کردیمinclude context در این مثال از روش
CLI> console dial 7000@LocalSets
-- Executing [7000@LocalSets:1] Answer("Console/dsp", "") in new stack
-- Executing [7000@LocalSets:2] Verbose("Console/dsp", "2,"" <> entering the support
queue") in new stack
== "" <> entering the support queue
-- Executing [7000@LocalSets:3] Queue("Console/dsp", "myqueue") in new stack
[Aug 14 04:49:13] WARNING[4697][C-00000019]: app_queue.c:7049 queue_exec: Unable to
join queue 'myqueue'
-- Executing [7000@LocalSets:4] Hangup("Console/dsp", "") in new stack
CLI>
'myqueue'
حال اگر فرض کنیم. تنظیم شده بودjoinempty=no چون هیچ اپراتوری در صف وجود نداشت و پارامتر
. تماس وارد صفی خواهد شد که هیچ اپراتوری در آن وجود ندارد،پارامتر بهصورت زیر تنظیم شدهباشد
joinempty=yes
leavewhenempty=no
مرجع آموزش ویپ با سافتسوئیچ استریسک 268
همانطور که مالحظه میکنید در این حالت هیچ اخطاری وجود نداشت و تماس وارد صف شد هرچند
. وضعیت صف در این حالت بهصورت زیر است.که هیچ اپراتوری وجود نداشته باشد
CLI> queue show
myqueue has 1 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:6, SL:0.0% within 60s
No Members
Callers:
1. Console/dsp (wait: 0:02, prio: 0)
مشــاهده میکنید که یک نفر مشــترک در صف داریم ولی هیچ اپراتوری وجود ندارد که تماس را پاســخ
. اعالم میشودNo Members بنابراین عبارت.دهد
را شمارهگیری7۰۰۰ در سیســتم تلفنی استریسک رجیستر شدهایم و شماره۱۰۰ مثال( فرض کنید با داخلی
. بهصورت زیر خواهدبودqueue show در این صورت خروجی دستور.کردیم
CLI> queue show
myqueue has 1 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:8, SL:0.0% within 60s
No Members
Callers:
1. SIP/100-0000000f (wait: 0:09, prio: 0)
wait پارامتر.تعداد افراد منتظر در صف با عدد مشــخص میشوند که اینجا تنها یک نفر در صف قرار دارد
ثانیه بوده۹ زمان انتظار، نشان دهنده زمانیست که تماس مربوطه در صف منتظر مانده است که در این مثال
. خروجی دستور میتواند بهصورت زیر باشد.است
CLI> queue show
myqueue has 9 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:8, SL:0.0% within 60s
No Members
Callers:
1. SIP/self-00037dc8 (wait: 0:30, prio: 0)
2. SIP/self-00035da8 (wait: 0:25, prio: 0)
3. SIP/self-00045db8 (wait: 0:21, prio: 0)
4. SIP/self-00034dc8 (wait: 0:20, prio: 0)
269 آشنایی با صفها در استریسک
در این مثال ۹نفر در صف قرار دارند که نفرات اول زمان بیشتری منتظر بودهاند .در این مثال تمامی تماسها
از سمت ترانکی بهنام selfوارد سیستم استریسک شدهاند.
تا اینجا تماسهای جدیدی که اپراتوری برای پاسخگویی به آنها وجود نداشت ،بررسی شدند .در ادامه
انواع روشهای اضافهکردن اپراتور به صف را هم بررسی خواهیمکرد.
اضافه و حذف کردن اپراتور به صف بهصورت داینامیک از طریق محیط کامندالین استریسک
از طریق دســتورات مدیریتی و کنترلی در کامندالین استریســک میتوان اپراتور جدیدی به صف اضافه و
یا از آن حذف کرد .برای این کار باید وارد محیط کامند الین استریســک بشــوید و دستورات زیر را اجرا
نمایید.
بعد از اجرای دستور فوق ،دستور زیر را برای مشاهده اپراتورهای صف اجرا کنید.
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
مرجع آموزش ویپ با سافتسوئیچ استریسک 270
همانطورکه مالحظه میکنید این صف دارای یک اپراتور به نام Phone_1است که بهصورت داینامیک به
صف اضافه شده و در وضعیت Not in useقرار دارد.
مثــال( فرض کنید بخواهیم اپراتــور Phone_1حاضر در صف را در حالت pauseقرار دهیم .برای این کار
دستور زیر را اجرا کنید:
"CLI> queue pause member SIP/Phone_1 queue myqueue reason "on-break
'paused interface 'SIP/Phone_1' in queue 'myqueue' for reason 'on-break
همانطــور که مالحظه میکنیــد با اجرای این دســتور ،اپراتور Phone_1به حالــت pauseتغییر وضعیت
میدهد.
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:11, SL:0.0% within 60s
Members:
SIP/Phone_1 (ringinuse disabled) (dynamic) (paused) (Not in use) has taken no calls yet
No Callers
میتــوان از پارامتــر reasonبرای ثبت رویدادها و علت pauseشــدن اپراتــور در فایلها و گزارشها
استفاده کرد .پارامتر reasonبیشتر جنبه گزارش برای سیستم دارد.
و پذیرش تماسهای جدید ،دستور زیر را اجرا کنید. برای unpauseکردن اپراتور
"CLI> queue unpause member SIP/Phone_1 queue myqueue reason "off-break
'unpaused interface 'SIP/Phone_1' in queue 'myqueue' for reason 'off-break
SIP/Phone_1 (ringinuse disabled) (dynamic) (Not in use) has taken no calls yet
No Callers
مثــال( فرضکنید بخواهیم اپراتور Phone_1را از صف myqueueخارج کنیم .برای این کار ،دســتور زیر
اجرا کنید. را
CLI> queue remove member SIP/Phone_1 from myqueue
'Removed interface SIP/Phone_1 from queue 'myqueue
با اجرای دستور فوق ،اپراتور Phone_1از صف خارج میشود و خروجی دستور بهصورت زیر خواهد بود.
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:11, SL:0.0% within 60s
No Members
No Callers
نکته مهم خروجی دســتور queue showاین است که برای اپراتور Phone_1همیشه عبارت »«dynamic
مشاهده میشود که معنای آن این است که اپراتور مورد نظر بهصورت داینامیک به صف اضافه شده است.
][myqueue
musicclass=default
strategy=rrmemory
joinempty=no
leavewhenempty=yes
ringinuse=no
member => SIP/Phone_1
این روش یکی از سادهترین روشها برای اضافهکردن اعضای جدید به صف است .هر تعداد عضو را برای
صف الزم داشــته باشــید میتوانید بهصورت فوق تعریف کنید و سپس باید ماژول صف را reloadکنید تا
مرجع آموزش ویپ با سافتسوئیچ استریسک 272
همانطورکه مالحظه میکنید ،چون این روش اضافهکردن اپراتورها به صف بهصورت اســتاتیک است ،لذا
عبارت dynamicدر اینجا وجود ندارد.
البته این روش در کنار سادگی استفاده ،معایبی هم دارد .در طراحی کالسنترها برای سازمانها ،اپراتورها
باید بهراحتی بتوانند در سیستم login ،یا logoutشوند .لذا استفاده از این روش چندان مناسب نیست .روش
اول هم چندان کاربردی نیست ،چون عموما باید بهوسیله مدیر سیستم انجام شود و برای کاربران معمولی به
دلیل عدم دسترسی به محیط کامند الین استریسک ،امکان پذیر نیست .بهترین حالت این است که اپراتورها
بتوانند با شــمارهگیری یک عدد خاص ،به صف مربوطه وارد شــوند و هر زمان الزم باشــد با شــمارهگیری
مجدد ،از صف خارج شوند .در ادامه این روش بیشتر توضیح داده میشود.
مثال( فرضکنید بخواهیم امکان ورود به صف ،خروج از صف pause ،و unpauseکردن را برای اپراتورها
فراهم کنیم .در این صورت برنامه زیر را خواهیم داشت.
][Queues
273 آشنایی با صفها در استریسک
همانطــور که مالحظه میکنید ،اپراتور Phone_1به صف myqueueاضافه شــده اســت .خروجی صف
بهصورت زیر است.
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:11, SL:0.0% within 60s
Members:
SIP/Phone_1 (ringinuse disabled) (dynamic) (Not in use) has taken no calls yet
No Callers
در این روش نیز چون اپراتور بهصورت داینامیک اضافه شدهاست ،عبارت dynamicدیده میشود.
شاید این سوال مطرح شود که از کجا بدانیم کدام کاربر را به صف اضافه کردهایم؟ این مقادیر بهوسیله
تابع CHANNELبهصورت زیر دریافت میشود.
})${CHANNEL(channeltype)}/${CHANNEL(peername
بنابراین ،هر نوع گوشی که کدهای فوق را اجرا کند ،ابتدا باید }) ${CHANNEL(channeltypeمشخص
شده باشد و بعد شماره اپراتوری }) ${CHANNEL(peernameمشخص شود.
مثــال( فرض کنید اپراتوری با تلفن Phone_1یکی از کدهای باال را گرفتهباشــد .در این صورت خروجی
توابع فوق بهصورت زیر خواهد بود:
• }) :${CHANNEL(channeltypeخروجی این تابع SIPاست.
• }) : ${CHANNEL(peernameخروجی این تابع Phone_1است.
تا اینجا انواع روشهای ورود اپراتور به صف و یا حذف اپراتور از صف بررســی شــد .مســلماً روش آخر
بهعنوان یک روش کاربردی در مورد کالسنترها قابل استفاده است ،بهطوریکه اپراتورها میتوانند خودشان
به صف وارد و یا از آن خارج شوند .پیش از ادامه بحث ،بهتر است سناریویی را با هم بررسی کنیم.
تصمیم داریم یک کال ســنتر برای یک شرکت بسازیم .مطابق آنچه گفته شد ،استفاده از آخرین روش
برای ورود به صف یا خروج از آن ،بهترین انتخاب اســت؛ ولی اینجا یک ســوال پیش میآید :فرض کنید
این شــرکت تعداد ۱۵نفر پرســنل داشــته باشد که در سه شیفت کاری و در هر شــیفت ۵نفر به صورت ۲4
ســاعته خدمات ارائه میکنند .در این شرایط ۱۵اپراتور داریم ،اما پرسش این است که آیا برای هر نفر باید
۱۵گوشــی تلفن در نظر بگیریم یا اینکه با داشــتن ۵گوشــی تلفن هم میتوانیم یک کالســنتر راهاندازی
کنیم؟ مســلماً لزومی به داشــتن ۱۵گوشی تلفن نخواهد بود ،اما چگونه میتوان با تنها ۵گوشی ۱۵ ،اپراتور
را مدیریت و نظارت کرد؟
275 آشنایی با صفها در استریسک
راه حل این اســت که گوشــیها بین همه اپراتورها مشترک باشند .اینجا باید شرایطی فراهم شود که هر
اپراتور بتواند در سیســتم login/logoutکند .البته الگوی login/logoutبرای اپراتورها بهصورت پیشفرض
در استریســک وجود ندارد ولی اکنون بر اســاس دانشــی که به دســت آوردهاید باید بتوانیــد برنامه آن را
بنویســید .در این برنامه میتوان با اســتفاده از ترکیب مثال های قبلی و تکنیک AstDBدادههای الزم را در
از AstDBباعث میشود بتوان برنامهای بهتر و انعطافپذیرتر داشت. databaseذخیره نمود .استفاده
استریسک وضعیت اپراتور، تنظیم شــود و شرایط قبل دوباره تست شودyes اکنون چنانچه این پارامتر برابر
. نمایش میدهدIn use در صف را
;sip.conf
[Phone_1]
callcounter=yes
relaod ً باید لزوما، کل استریسک یا ماژول مورد نظر،نکته مهم این است که بعد از هر گونه تغییر در هر فایل
. چنین قابلیتی را دراختیار نداریم، هاchannel driver نکته مهم دیگر اینکه هنگام اســتفاده از ســایر.شــود
. مجموعهای از داخلیهای یک دســتگاه ســانترال باشــند،بهعنوان مثال فرض کنید اپراتورهای یک صف
چون داخلیهای،در این حالت ما هیچ کنترل و نظارتی روی داخلیهای دســتگاه ســانترال نخواهیم داشت
، در صف است؛ بنابراینunavailable هستند و وضعیت اپراتورها همیشه بهصورتDAHDI سانترال از نوع
Device State در یک چنین شــرایطی میتوان از قابلیت.استریســک نمیتواند وضعیت آنها را مانیتور کند
.در استریسک استفاده کرد که در فصل دهم در مورد آن توضیح داده خواهدشد
ایجادqueues.conf میتــوان صفهای مورد نیاز را درون فایــل،همانطــور کــه در ابتدای فصل آمد
، برای تعریف صف. در ابتدای فصل با برخی از پرکاربردترین پارامترهای تعریف صف آشــنا شــدیم.کرد
. ارائه شدهاند۲-۹ پارامترهای زیادی وجود دارد که اغلب آنها در جدول
musicclass Filename of the Sets the music class to be used by a particular queue. You
announcement can also override this value on a per-call basis using the
CHANNEL(musicclass) channel variable.
announce ringall, Used for playing an announcement to the agent that answers the
leastrecent, call, typically to let him know which queue the caller is coming from.
fewestcalls, Useful when the agent is in multiple queues, especially when calls
from the queue are set to autoanswer. Bear in mind that the length
random, of time it takes to play this recording is added to the length of time
rrmemory, the caller has to wait (since they cannot hear it). Also consider
linear, wrandom that your agents will hear this recording several times per day, and
aren’t going to benefit from a long-winded message. If you use this
option, keep the recordings short; one or two words at most (and no
more than a second in length).
context Value of 0 or Allows a caller to exit the queue by pressing a single DTMF digit.
greater If a context is specified and the caller enters a number, that digit
will attempt to be matched in the context specified, and dialplan
execution will continue there. Note that by doing this, the caller also
loses their place in line.
strategy Value in seconds ringall: Rings all available members (default). This distribution
strategy doesn’t really count as ACD (automatic call distribution). In
traditional telephony terms, this would be known as a Ring Group.
leastrecent: Rings the interface that least recently received a
call. In a queue where there are many calls of roughly the same
duration, this can work. It doesn’t work as well if an agent has been
on a call for an hour, and their colleagues all got their last call 30
minutes ago, because the agent who just finished the 60-minute
call will get the next one.
fewestcalls: Rings the interface that has completed the fewest
calls in this queue. This can be unfair if calls are not always of the
same duration. An agent could handle three calls of 15 minutes
each and her colleague had four 5-second calls; the agent who
handled three calls will get the next one.
random: Rings a random interface. This actually can work very
well and end up being very fair in terms of evenly distributing calls
among agents.
Rrmemory: Rings members in a round-robin fashion, remembering
where it left off last for the next caller. This can also work out to be
very fair, but not as much as random.
linear: Rings members in the order specified, always starting at
the beginning of the list. This works if you have a team where there
are some agents who are supposed to handle most calls, and other
agents who should only get calls if the primary agents are busy.
wrandom: Rings a random member, but uses the members’
penalties as a weight. Worth considering in a larger queue with
complex weighting among the agents.
مرجع آموزش ویپ با سافتسوئیچ استریسک 278
نوع فایلی که باید پخش4-۹ در جدول. زمان پخش اعالنهای صوتی مشــخص شــده است۳-۹ در جدول
. مشخص گردیده است،شود
[myqueue]
musicclass=default
strategy=rrmemory
joinempty=yes
leavewhenempty=no
ringinuse=no
;-------- Announcement Control --------
announce-frequency=30
min-announce-frequency=30
periodic-announce-frequency=45
random-periodic-announce=no
relative-periodic-announce=yes
announce-holdtime=once
announce-position=limit
announce-position-limit=10
announce-round-seconds=30
، اعالنهایی نیز در فواصل زمانی معین برای افراد حاضر در صف، عالوه بر آهنگ انتظار،مطابــق برنامه باال
خروجی زیر را خواهیم، با فراخوانی صف در برنامه. فرض کنید صف باال را داشته باشــید.پخش میشــود
:داشت
== Using SIP RTP CoS mark 5
-- Executing [7000@LocalSets:1] Answer("SIP/Phone_1-00000014", "") in new stack
-- Executing [7000@LocalSets:2] Verbose("SIP/Phone_1-00000014", "2,"Phone_1"
<Phone_1> entering the support queue") in new stack
== "Phone_1" <Phone_1> entering the support queue
-- Executing [7000@LocalSets:3] Queue("SIP/Phone_1-00000014", "myqueue") in new stack
-- Started music on hold, class 'default', on SIP/Phone_1-00000014
-- Stopped music on hold on SIP/Phone_1-00000014
-- <SIP/Phone_1-00000014> Playing 'queue-youarenext.gsm' (language 'en')
285 آشنایی با صفها در استریسک
)-- Told SIP/Phone_1-00000014 in myqueue their queue position (which was 1
)'-- <SIP/Phone_1-00000014> Playing 'queue-thankyou.gsm' (language 'en
-- Started music on hold, class 'default', on SIP/Phone_1-00000014
شکل 3-9
ازآنجاکه صفها دارای اولویتهای متفاوتی هستند ،تا زمانی که تماسی در صف support-priorityوجود
داشتهباشــد ،تماسهای صف supportبهوسیله این اپراتور پاسخ داده نمیشوند .اینجا ما دو صف داریم که
هر کدام اولویتهای متفاوتی دارند .تعریف این دو صف در استریسک بهصورت زیر است:
][general
autofill=yes
shared_lastcall=yes
مرجع آموزش ویپ با سافتسوئیچ استریسک 286
[support_template](!)
musicclass=default
strategy=rrmemory
joinempty=yes
leavewhenempty=no
ringinuse=no
;-------- Announcement Control --------
announce-frequency=30
min-announce-frequency=30
periodic-announce-frequency=45
random-periodic-announce=no
relative-periodic-announce=yes
announce-holdtime=once
announce-position=limit
announce-position-limit=10
announce-round-seconds=30
[support](support_template)
weight=0
member=>Phone_1
[support-priority](support_template)
weight=10
member=>Phone_1
support-priority has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime),
W:10, C:0, A:0, SL:0.0% within 0s
Members:
SIP/Phone_1 (ringinuse disabled) (Not in use) has taken no calls yet
No Callers
CLI>
weight هر چه. میتوان اولویت آن را تغییــر داد، هنــگام تعریف یک صفweight بــا اســتفاده از پارامتر
نحوهی استفاده از صفهای اولویتدار دقیقاً همانند صفهای. اولویت صف باالتر خواهد بود،بیشتر باشد
. اولویت صفها مشخص شدهاند، همانطورکه در خروجی دستور باال مشاهده میکنید.معمولی است
شــرایط گرســنگی اســت؛ به این مفهوم کــه تا زمانی که،نکته مهم اســتفاده از صفهای اولویتدار
287 آشنایی با صفها در استریسک
تماسهایی در صف با اولویت باالتر وجود داشــته باشــند ،اپراتورها آنها را پاســخ میدهند و این به منزله
شرایط گرسنگی یا عدم سرویسدهی به صفهای با اولویت پایینتر است .برای جلوگیری از چنین شرایطی
بهتر است اپراتورها بین صفها مشترک نباشند.
اکنون فرض کنید خروجی دستور queue showبهصورت زیر باشد:
CLI> queue show
support has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:1,
C:0, A:0, SL:0.0% within 0s
Members:
SIP/Phone_1 (ringinuse disabled) (Not in use) has taken no calls yet
SIP/Phone_2 (ringinuse disabled) (dynamic) (Not in use) has taken no calls yet
No Callers
support-priority has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime),
W:2, C:0, A:0, SL:0.0% within 0s
Members:
SIP/Phone_1 (ringinuse disabled) (Not in use) has taken no calls yet
SIP/Phone_3 (ringinuse disabled) (dynamic) (Not in use) has taken no calls yet
No Callers
>CLI
در این حالت اپراتور phone_1در هر دو صف عضو اســت و تماسهای صف support-priorityبرای این
اپراتور از اولویت باالتری برخوردار است .سایر اپراتورها در این حالت روال معمول خود را دارند و اولویت
صف برای آنها اعمال نخواهد شد.
][myqueue
musicclass=default
strategy=rrmemory
joinempty=yes
leavewhenempty=no
ringinuse=no
مرجع آموزش ویپ با سافتسوئیچ استریسک 288
در این صف ،دو اپراتور تعریف شدهاست .عددی که بعد از تعریف اپراتور آمده به معنی اولویت )جریمه(
است .هر چه این عدد بزرگتر باشد به منزله اولویت کمتر است.
در این صف ،صرف نظر از اینکه اســتراتژی تماس به چه صورت تعریف شــده است ،ابتدا اپراتورهایی
کــه از اولویت باالتری )عدد جریمه کمتــر( برخوردارند زنگ میخورند .بهعنوان مثال اگر اپراتور ۱۰۰در
وضعیت Not in useباشــد ،فقط این اپراتور زنگ میخورد؛ در غیر اینصورت ۱۰۱زنگ خواهد خورد و
به همین ترتیب عملیات ادامه خواهد یافت.
درصورتیکه اپراتور ۱۰۰تماس را پاســخ ندهد ،تماس به ســوی ســایر اپراتورهای با اولویت پایینتر
)اپراتور (۱۰۱نخواهد رفت .تنها در صورتی تماس به ســوی اپراتورهای اولویتپایین منتقل میشود که این
اپراتورها در وضعیت Busyیا In useو یا Unavailbleباشــند .این ســناریو میتواند برای برخی سازمانها
بسیار کاربردی باشــد .بهعنوان مثال فرض کنید یک صف پشتیبانی supportداشتهباشیم و تمام اپراتورهای
آن در یک اولویت قرار داشته باشند .مدیر پشتیبانی هم میتواند در این صف ،با اولویت کمتر عضو باشد تا
در مواردی که تمام اپراتورها مشغولند ،بتواند تماسها را پاسخ دهد .برای این منظور به مثال زیر توجه کنید:
][support
member=>SIP/operator1,1
member=>SIP/operator2,1
member=>SIP/operator3,1
…
member=>SIP/operatorn,1
member=>SIP/manager,10
در این حالت اگر تمامی اپراتورها مشغول باشند ،تماس به سمت مدیر پشتیبانی خواهد رفت.
مثال( فرض کنید ســه اپراتور با ســه صف متفاوت داشته باشــیم .در تعریف زیر ،هر کدام از این اپراتورها،
در هر ســه صف عضوند ،ولی اولویت ) (penaltyآنها در صف ،با هم متفاوت اســت .در این مثال اولویت
289 آشنایی با صفها در استریسک
[sales](StandardQueue)
member => SIP/Phone_2,0, Phone_2
member => SIP/Phone_3,10, Phone_3
member => SIP/Phone_1,20, Phone_1
[billing](StandardQueue)
member => SIP/Phone_3,0, Phone_3
member => SIP/Phone_1,10, Phone_1
member => SIP/Phone_2,20, Phone_2
به هیچ عنوان نمیتوانیم، بعد از اضافهکردن اپراتور با اولویت مشخص به صف،همانطورکه مالحظه میکنید
اما این هم یک. مگر اینکه اپراتور را از صف خارج و دوباره به صف اضافه کنیم،اولویت آن را تغییر دهیم
. بهتر است از قابلیت تعریف رولها در صف استفاده کنیم.روش مناسبی نیست
مرجع آموزش ویپ با سافتسوئیچ استریسک 290
][more_members
penaltychange => 60,5,1
پارامتر اول تعیین کنندۀ حداقل مدت زمانی اســت که باید ســپری شود تا تغییرات اولویت انجام پذیرد
)این پارامتر برای هر فردی که با مرکز تماس بگیرد و وارد صف شــود بهطور مســتقل محاسبه میشود( که
اینجا ۶۰ثانیه محاسبه شدهاست.
پارامتــر دوم برای متغیــر QUEUE_MAX_PENALTYدر نظر گرفته میشــود .این پارامتر میتواند
نسبی باشد .برای مثال ،اینجا پس از گذشت ۶۰ثانیه ،حداکثر سطح پاسخگویی به سطح ۵تغییر یافته است.
پارامتر ســوم برای متغیر QUEUE_MIN_PENALTYدر نظر گرفته میشود .این پارامتر هم میتواند
باشد .برای مثال ،اینجا پس از گذشت ۶۰ثانیه ،حداقل سطح پاسخگویی به سطح ۱تغییر یافته است. نسبی
پــس از تنظیم رولهای مشــخص در فایــل ، queuerules.confباید تغییــرات الزم در برنامه را هنگام
فراخوانی دستور queueداشتهباشیم .این تغییرات بهصورت زیر خواهند بود :
][Queues
)exten => 7000,1,Verbose(2,Entering the support queue
same => n,Set(QUEUE_MIN_PENALTY=2) ; set minimum queue member penalty
same => n,Set(QUEUE_MAX_PENALTY=4) ; set maximum queue member penalty
; Queue(queuename[,options[,URL[,announceoverride[,timeout[,AGI[,macro[,gosub[,rule[,po
)]]]]]]]]]sition
same => n,Queue(support,,,,,,,,more_members) ; enter queue with minimum and maximum
member penalties
برای مشاهده رولهای تعریف شده در ، queuerules.confمیتوانید دستور زیر را در کامند الین استریسک
وارد کنید.
CLI> queue show rules
در این شرایط چنانچه تماسی وارد سیستم شود ،بعد از گذشت ۳۰ثانیه ،رول اول اعمال می شود .سپس بعد
از گذشت ۱۵ثانیه) 4۵ثانیه از بدو ورود( رول دوم اعمال می شود و به همین ترتیب ادامه پیدا خواهد کرد.
با انجام این تنظیمات ،همه رویدادهایی که در کلیه صفها رخ دادهاند ،در فایلی در مسیر زیر ثبت میشوند.
#vim /var/log/asterisk/queue_log
برای درک بهتر ،بیایید با مثالی آن را بررســی کنیم .فرض کنید یک صف بهصورت زیر در سیســتم تلفنی
استریسک داریم:
][general
autofill=yes
shared_lastcall=yes
][myqueue
musicclass=default
strategy=rrmemory
joinempty=yes
leavewhenempty=no
ringinuse=no
;-------- Announcement Control --------
293 آشنایی با صفها در استریسک
announce-frequency=30
min-announce-frequency=30
periodic-announce-frequency=45
random-periodic-announce=no
relative-periodic-announce=yes
announce-holdtime=once
announce-position=limit
announce-position-limit=10
announce-round-seconds=30
همانطورکه مالحظه میکنید ،کاربرهای ۱۰۰و ۱۰۱به صف myqueueاضافه شدهاند .اکنون فرض کنید
یک تماس وارد صف شده است ،در این صورت گزارش ها بهصورت زیر خواهندبود:
1471179844|1471179843.59|myqueue|NONE|ENTERQUEUE|||1
1471179859|1471179843.59|myqueue|SIP/101|RINGNOANSWER|15000
1471179886|1471179843.59|myqueue|SIP/100|RINGNOANSWER|15000
1471179902|1471179843.59|myqueue|SIP/101|RINGNOANSWER|4000
1471179917|1471179843.59|myqueue|SIP/101|CONNECT|73|1471179915.64|1
1471179937|1471179843.59|myqueue|SIP/101|COMPLETEAGENT|73|20|1
بر اســاس این گزارش ها ،تماس وارد صفی به نام myqueueشدهاســت .ابتدا اپراتور ۱۰۱به مدت ۱۵ثانیه
زنگ خورده ،ولی پاســخی دریافت نشــده اســت .سپس تماس به ســمت اپراتور ۱۰۰رفته و ۱۵ثانیه زنگ
میخورد ولی باز هم تماس پاســخ داده نمیشــود .دوباره تماس به سمت اپراتور ۱۰۱میرود و در اینجا بعد
از 4ثانیه تماس پاسخ داده می شود .براساس گزارش های موجود ،تماس گیرنده به مدت 7۳ثانیه در صف
منتظر مانده و مکالمه او ۲۰ثانیه به طول انجامیده است.
اکنون سعی کنید با گرفتن کدهایی )مثل کد (*7۲که قب ً
ال تعریف کردهاید ،کاربرانی در صف به حالت
pauseتغییر وضعیت دهند .خروجی الگ در فایل بهصورت زیر است.
;queue_log
|1471188601|NONE|myqueue|SIP/101|PAUSE
|1471188605|NONE|myqueue|SIP/100|PAUSE
1471188702|NONE|myqueue|SIP/100|UNPAUSE|
البته.همانطورکه مالحظه میکنید از این الگها میتوان گزارش هایی در خصوص صفها بهدست آورد
.در فصل سیزدهم روشهای دیگری برای جمعآوری گزارش از سیستم را بررسی خواهیم کرد
. انواع رویدادهای موجود در صف را نشان میدهد۵-۹ جدول
5-9 جدول
بهتر است، اما پیش از آنکه به فصل بعدی بپردازیم، اینجا به پایان میرسدACD مطالب اصلی در خصوص
ACD این مورد شــاید جزو نکات کلیدی بحث.یک نکته کاربردی در خصوص صفها را بررســی کنیم
.نباشند ولی از اهمیت ویژهای برخوردار است
قیل از اینکه به، چنانچه اپراتوری تماســی را در صف پاســخ دهد،پــس از تنظیم پارامترهای فوق در صف
. مقداردهی میشودMEMBERINTERFACE یک متغیر کانال در استریسک به نام،مشترک متصل شود
مرجع آموزش ویپ با سافتسوئیچ استریسک 296
مقدار این متغیر ،شماره ی اپراتوری است که تماس را پاسخ داده است .ما باید بتوانیم از این متغیر در برنامه
خود استفاده کنیم.
این نکته مهم اســت که اعالن شــماره اپراتور باید بعد از پاســخ دادن اپراتور در صف باشــد .برای این
منظور پارامتری به نام AGIدر صف داریم که پس از پاسخدهی اپراتور ،ابتدا این فایل اجرا میشود و سپس
مشــترک به اپراتور متصل میشــود .پس ما باید در آن فایل ،AGIشــماره اپراتور را اعالن کنیم .برای مثال
نحوهی فراخوانی فایل AGIدر صف میتواند بهصورت زیر باشد.
;extensions.conf
][Queues
)(exten => 7001,1,NoOp
)(same => n,Answer
)same => n,Queue(myqueue,,,,,AgentNumber.php
)(same => n,Hangup
اینجــا ما فایل AgentNumber.phpرا برای اعالم شــماره اپراتوری بــهکار میبریم .این فایل بهصورت زیر
میتواند نوشته شود.
<?php
;)set_time_limit(30
;)"require("phpagi.php
;)error_reporting(E_ALL
البته برای پخش شــماره اپرتوری بهصورت فارســی باید از روش دیگری استفاده کرد ،ولی در این مثال
توانستهاید شمارهی اپراتوری که به تماس پاسخ داده است را دریافت و اعالم کنید.
در فصل چهاردهم )ابزارهای برنامه نویســی در استریسک( درباره برنامهنویسی AGIتوضیحات بیشتری
خواهیم داد.
نتیجهگیری
ابتدا با یک مثال ســاده ،فصل شــروع شــد و در ادامه بخشهای مختلف ایجاد یک صف توضیح داده شد.
مهمترین کاربرد صفها ،کنترل و مدیریت تماسهای ورودی اســت؛ بنابراین ،صفهای هوشمند میتوانند
بســیار پرکاربرد باشــند .نظارت و کنترل بر اپراتور نقش مهمی در سرویسدهی بهتر به مشتریان ایفا میکند
که چگونگی آن نیز شــرح داده شد .به این ترتیب انتظار میرود با اطالعاتی که در این فصل در اختیار شما
قرار داده شد ،بتوانید صفهایی هوشمند در سیستم استریسک ایجاد کنید.
فصل دهم
مقدمه
در سیستمهای تلفنی ،معموالً مشخصشدن وضعیت کاربران از اهمیت ویژهای برخوردار است .در شبکههای
مخابراتی این امکان وجود ندارد که متوجه شویم شخص مورد نظر ما در دسترس قرار دارد یا نه ،آیا در حال
Ring Back Tone مکالمه با شــخص دیگری است یا آزاد اســت .اما هنگام برقراری تماس میتوان از نوع
به این وضعیت پی برد.
این وضعیت قابل تعمیم به شبکههای داخلسازمانی و حتی شبکههای نسل جدید ویپ نیز هست .اهمیت
این ویژگی زمانی روشــن میشود که قصد نظارت و کنترل روی سیســتمهای تلفنی داشتهباشیم .برای مثال
چنانچه در یک ســازمان ،منشــی قصد داشته باشد تماسی را به فردی مشــخص متصل نماید ،بدون دراختیار
داشتن این سیستم ،صرف نظر از در دسترس بودن یا نبودن فرد ،ممکن است تماس از دست برود.
بــه کمــک وضعیت دیوایسهــا) ۱در اینجا منظــور از دیوایس ها همــان SIPPhoneها می باشــد( در
شــبکههای ویپ ،میتوان وضعیت تجهیزات ســختافزاری و حتی نرمافزاری را در شبکه بررسی و مانیتور
کنیــم .بــه عنوان یک مثال کاربردی در فصل قبــل راجع به صفها و اپراتورهای صــف توضیح دادیم که
چگونگی بررسی وضعیت اپراتورها در صف.چگونه وضعیت اپراتورها را در صف میتوانیم مشاهده کنیم
.از جمله مباحث این فصل است
این. نمایش دادهشودPhone_1 در برنامه خواســته شده که وضعیت دیوایس،همانطورکه مالحظه میکنید
.برنامه به دو روش فراخوانی میشود
:در روش اول برنامه به صورت زیر فراخوانی می شود
CLI> console dial 7001@LocalSets
-- Executing [7001@LocalSets:1] Answer("Console/dsp", "") in new stack
<< Console call has been answered >>
-- Executing [7001@LocalSets:2] Verbose("Console/dsp", "3,The state of SIP/Phone_1 is
NOT_INUSE") in new stack
-- The state of SIP/Phone_1 is NOT_INUSE
-- Executing [7001@LocalSets:3] Hangup("Console/dsp", "") in new stack
<< Hangup on console >>
CLI>
NOT_ ( در حالتPhone_1) همانطورکــه مالحظه میکنید در ایــن حالت وضعیت دیوایس مورد نظــر
، را شمارهگیری کنید7۰۰۱ ( شمارهPhone_1) در روش دوم چنانچه از طریق این دیوایس. اســتINUSE
:بهصورت زیر خواهد بود وضعیت آن
CLI>
== Using SIP RTP CoS mark 5
-- Executing [7001@LocalSets:1] Answer("SIP/Phone_1-00000000", "") in new stack
-- Executing [7001@LocalSets:2] Verbose("SIP/Phone_1-00000000", "3,The state of SIP/
Phone_1 is INUSE") in new stack
-- The state of SIP/Phone_1 is INUSE
-- Executing [7001@LocalSets:3] Hangup("SIP/Phone_1-00000000", "") in new stack
== Spawn extension (LocalSets, 7001, 3) exited non-zero on 'SIP/Phone_1-00000000'
CLI>
استریســک اســت .از این مفهوم باید بتوانیم برای موارد خاص استفاده کنیم و آن را توسعه دهیم .البته شاید
توضیح اولیه در این خصوص کمی با ابهام همراه باشــد ولی در ادامه به کمک چند مثال ،با قابلیتهای آن
در برنامهنویسی استریسک آشنا خواهید شد.
شکل 1-10
فــرض کنیــد Tomبخواهد وضعیت Bobرا بررســی کند کــه اگر در حال مکالمه نبــود ،با وی تماس
بگیرد .اینجا Bobدو دیوایس مختلف )دو دســتگاه تلفن( دارد که از هر دو اســتفاده میکند .اما اینکه Tom
بخواهد هر دو دیوایس را بررسی کند ،چندان جالب نخواهد بود .بنابراین ،هر دو دیوایس را به یک شماره
)اکستنشــن( مشــخص نگاشــت میدهیم .اکنون هر زمان که Tomبخواهد وضعیت Bobرا بررســی کند،
میتواند از آن اکستنشن استفاده نماید و وضعیت Bobرا بررسی نماید.
برای نگاشت دیوایسها در یک اکستنشن ،بهصورت زیر عمل کنید:
;extensions.conf
][Custom_hints
exten = 7002,hint,SIP/Bob-mobile&SIP/Bob-desk
][Tom
مرجع آموزش ویپ با سافتسوئیچ استریسک 302
شکل 2-10
type=friend
subscribecontext=Custom_hints
allowsubscribe=yes
][Bob-mobile
type=friend
busylevel=1
][Bob-desk
type=friend
busylevel=1
با انجام این تنظیمات در استریســک ،کاربر Tomمیتواند وضعیت کاربر Bobرا هر زمان که الزم باشــد،
بررســی کند .در محیط کامندالین استریسک با دســتور زیر میتوان وضعیت تمام Extension Statesها را
مشاهده نمود.
CLI> core show hints
تا اینجا شــرایطی فراهم شــد که هر زمان کاربر Tomتصمیم گرفت ،بتواند وضعیت کاربر Bobرا بررسی
کند.
برای بررســی وضعیت یک اکستنشــن در برنامهنویســی استریســک ،از تابع EXTENSION_STATE
303 بررسی وضعیت تجهیزات در شبکههای ویپ
اســتفاده کنید .این تابع بسیار شبیه به تابع DEVICE_STATEاست ،با این تفاوت که در پارامتر ورودی ،از
اکستنشن بهجای دیوایس استفاده میشود.
][LocalSets
)(exten => 7003,1,Answer
_same => n,Verbose(3,The state of 7002@default is ${EXTENSION_STATE(7002@Custom
)})hints
)(same => n,Hangup
d8754z-
Max-Forwards: 70
Contact: <sip:Tom@10.24.17.254:37509;transport=UDP>
To: <sip:7002@10.24.18.124;transport=UDP>
From: <sip:Tom@10.24.18.124;transport=UDP>;tag=f51e9632
Call-ID: ZjE2ZDAwYThiOTA2MzYxOWEwNTEwMjc1ZGIxNTk3NDU.
CSeq: 2 SUBSCRIBE
Expires: 1800
Accept: application/pidf+xml
Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE
Supported: replaces, norefersub, extended-refer, timer, X-cisco-serviceuri
User-Agent: Z 3.2.21357 r21103
Authorization:Digest username="Tom",realm="asterisk",nonce="522456f4",uri="sip:7002
@10.24.18.124;transport=UDP",response="6d66dcad8c176aa3ef7baec7680d2445",algorit
hm=MD5
Event: presence
Allow-Events: presence, kpml
Content-Length: 0
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.24.17.254:37509;branch=z9hG4bK-d8754z-c6908de6f0126edf-1---
d8754z-;received=10.24.17.254
From: <sip:Tom@10.24.18.124;transport=UDP>;tag=f51e9632
To: <sip:7002@10.24.18.124;transport=UDP>;tag=as46a6e039
Call-ID: ZjE2ZDAwYThiOTA2MzYxOWEwNTEwMjc1ZGIxNTk3NDU.
CSeq: 2 SUBSCRIBE
Server: Asterisk PBX SVN-branch-12-r413487
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH,
MESSAGE
Supported: replaces, timer
Expires: 1800
Contact: <sip:7002@10.24.18.124:5060>;expires=1800
Content-Length: 0
Content-Type: application/pidf+xml
Content-Length: 530
میتوانید توسط دستور زیر،هنگامی که درخواســت اعالن وضعیت در سیستم تلفنی استریسک صادر شود
:آن را مشاهده کنید
CLI> sip show subscriptions
Peer User CallID Extension Last state Type Mailbox Expiry
10.24.17.254 Tom ZjE2ZDAwYThiOTA 7002@Custom_hints Unavailable pidf+xml <none>
001800
1 active SIP subscription
در استریسکSUBSCRIBE-NOTIFY تنظیمات
پارامترهایی راsip.conf باید در فایــل، در استریســکSUBSCRIBE-NOTIFY برای اســتفاده از قابلیت
. این پارامترها به شرح زیرند.تنظیم کنید
مرجع آموزش ویپ با سافتسوئیچ استریسک 306
• : callcounterاز این پارامتر برای مشاهده وضعیت اپراتورها در صف استفاده میشود .در فصل قبل در
مورد آن صحبت شد.
• :busylevelمشخص میکند که چه زمانی استریسک باید وضعیت busyرا برای یک اپراتور نشان دهد.
درحالت پیشفرض ،استریســک وضعیت اپراتور در صف را INUSEنشان میدهد .اگر busylevel =1
باشد ،استریسک وضعیت را به حالت busyبرمیگرداند.
• :call-limitبا این پارامتر تعداد تماسهای همزمانی که یک کاربر میتواند داشتهباشد ،کنترل میگردد.
• : allowsubscribeبا این پارامتر قابلیت SUBSCRIBEرا برای یک اپراتور ،فعال یا غیرفعال میکنیم.
• : subscribecontextبا این پارامتر مشــخص میکنیم که در کدام کانتکست تعاریف مربوط به نگاشت
DeviceStateبه Extension_Stateانجام شدهاست یا به عبارت دیگر در کدام کانتکست تعاریف hint
انجام شدهاســت .اگر ایــن پارامتر را مقدار ندهیم ،بهطور پیشفرض همان مقدار پارامتر کانتکتســت در
تعریف کاربر در نظر گرفته خواهدشد.
• : notifyringingبا این پارامتر مشخص میکنیم که پیام ringingبرای اپراتورها اعالم شود.
• : notifyholdبا این پارامتر مشخص میکنیم که اگر اپراتور در وضعیت holdباشد ،پیام آن اعالم شود.
announce-holdtime=once
announce-position=limit
announce-position-limit=10
announce-round-seconds=30
member=>DAHDI/1
member=>DAHDI/2
اکنون دستور. در صف استفاده کردهایمDAHDI همانطورکه مالحظه میکنید اینجا ما از کاربرانی از نوع
.زیر را در محیط کامندالین استریسک اجرا میکنیم
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
Members:
DAHDI/2 (ringinuse disabled) (Unknown) has taken no calls yet
DAHDI/1 (ringinuse disabled) (Unknown) has taken no calls yet
No Callers
CLI>
قصد ما است که برای آنها یک.مالحظه میشود که وضعیت این اپراتورها برای استریسک مشخص نیست
ایجاد کنیم و این اپراتورها را به این پارامتر نگاشت دهیم تا امکان بررسی وضعیتCustom Device State
.آنها فراهم شود
تعریفCustom:mystate جدید بهنــامDevice state همانطورکه مالحظــه میکنید در این تعریف یک
اکنون آن را به یک. تنظیم شــده استNOT IN USE شــده اســت و وضعیت فعلی )پیشفرض( آن روی
.( نگاشت میدهیمmytest اکستنشن خاص )در اینجا
[Custom_hints]
exten => mystate,hint,Custom:mystate
. جدید در استریسک تعریف شودDevice state دستور زیر را اجرا کنید تا این،پس از تعریف فوق
CLI> console dial mystate@LocalSets
. دستور زیر را اجرا کنید، جدید و وضعیت آنDevice state برای مشاهده این
CLI> core show hints
Watchers 0
----------------
- 2 hints registered
>CLI
همانطورکه مالحظه میکنید ،وضعیت Device stateجدید در حالت NOT IN USEیا idleاست .از این
Device stateاســتفاده میکنیم و آن را به یکی از اپراتورهای صف نگاشــت میدهیم .برای رسیدن به این
هدف تغییرات زیر را در صف اعمال کنید.
member=>DAHDI/1,,,Custom:mystate
بعد از اعمال تغییرات و reloadکردن استریسک ،دستور زیر را در کامند الین استریسک اجرا کنید.
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
Members:
DAHDI/2 (ringinuse disabled) (Unknown) has taken no calls yet
DAHDI/1 (ringinuse disabled) (Not in use) has taken no calls yet
No Callers
>CLI
همانطورکه مالحظه میکنید ،اینجا با اســتفاده از Custom Device Stateو نگاشــت آن به یک دیوایس،
میتوانیم وضعیت آن را در صف مشــخص کنیم و از آن در بررسی وضعیت کاربران )در کل سیستم تلفنی
استریسک( استفاده کنیم.
قبل از ادامه بحث بهتر اســت به یک مثال بپردازیم .در این مثال هدف ما ،اســتفاده از اپراتورهایی است
که استریســک نمیتواند وضعیت آنها را در صف نشان دهد )استریسک فقط میتواند وضعیت اپراتورهایی
از نوع پروتکل SIPرا نشان دهد(؛ بنابراین ،باید بتوانیم با استفاده از Custom Device Stateوضعیت آنها
را شبیهســازی کنیم .این مثال در این بخش تنها جنبه آموزشــی دارد و برای اســتفاده در محصوالت توصیه
نمیشود.
مثال( فرض کنید صفی داریم که دارای اپراتورهایی از نوع پروتکل DAHDIاســت .ازآنجاکه استریســک
نمیتواند وضعیت این نوع اپراتورها را داشــته باشــد ،باید از Custom Device Stateاستفادهکنیم .تعریف
صف بهصورت زیر خواهد بود:
;queues.conf
][general
autofill=yes
shared_lastcall=yes
][myqueue
musicclass=default
strategy=rrmemory
309 بررسی وضعیت تجهیزات در شبکههای ویپ
joinempty=yes
leavewhenempty=no
ringinuse=no
;-------- Announcement Control --------
announce-frequency=30
min-announce-frequency=30
periodic-announce-frequency=45
random-periodic-announce=no
relative-periodic-announce=yes
announce-holdtime=once
announce-position=limit
announce-position-limit=10
announce-round-seconds=30
member=>Local/1@agents/n,,,Custom:op1
member=>Local/2@agents/n,,,Custom:op2
: بهصورت زیر داده شودCustom:op2 وCustom:op1 اکنون باید مقادیر پیشفرض به
[Custom_hints]
exten => op1,hint,Custom:op1
exten => op1,1,Set(DEVICE_STATE(Custom:op1)=NOT_INUSE)
ولی باید دســتکم، دادهایمCustom:op2 وCustom:op1 را بهNOT_INUSE مقدار اولیه،با این برنامه
. وضعیت صف را بررسی میکنیم، پیش از اجرای برنامه.اجرا کنیم یک بار برنامه باال را
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
Members:
Local/1@agents (ringinuse disabled) (Unknown) has taken no calls yet
Local/2@agents (ringinuse disabled) (Unknown) has taken no calls yet
No Callers
CLI>
. تعریف میشــوند و مقدار اولیــه به خود میگیرندCustom Device State دو،بــا اجرای دســتورات فوق
.مجددا وضعیت صف را بررسی میکنیم
CLI> queue show
myqueue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
Members:
مرجع آموزش ویپ با سافتسوئیچ استریسک 310
همانطورکه مالحظه میکنید ،اینجا وضعیت آنها تغییر کرده اســت و باید بتوانیم در صورت نیاز ،وضعیت
آنها را کنترل کنیم .به عبارت دیگر ،وقتی تماسی به سمت آنها ارسال میکنیم ،وضعیت آنها را بهصورت
دستی به Ringingتغییر میدهیم و یا زمانی که تماس جواب داده میشود ،وضعیت آنها را INUSEمیکنیم.
اکنون باید برنامه خود را تکمیل کنیم .نخست باید کانتکست ] [agentsرا بنویسیم .برنامه آن بهصورت
زیر است:
][agents
)exten => _X,1,NoOp(Agent calling
)}same => n,Set(DESK=Custom:op${EXTEN
)})}same => n,NoOp(${DEVICE_STATE(${DESK
)same => n,Set(DEVICE_STATE(${DESK})=RINGING
))}same => n,Dial(SIP/${EXTEN},20,U(subChangeState,${DESK
)(same => n(hang),Hangup
][subChangeState
)exten => s,1,Set(DEVICE_STATE(${ARG1})=INUSE
وقتی تماس به اپراتورهای صف متصل میشود ،به کانتکست ] [agentsوارد میشود .در این کانتکست اول
وضعیت اپراتور مورد نظر را Ringingو بعد تماس را به سمت اپراتور ارسال میکنیم .اگر اپراتور تماس را
پاسخ دهد ،با آپشن Uدر دستور ،Dialوضعیت اپراتور به حالت INUSEتغییر میکند و سپس تماس برقرار
میگردد .چنانچه تماس قطع شــود ،اکستنشن hاجرا میشــود و دوباره وضعیت به حالت NOT_INUSE
تغییر میکند.
برای فهم بهتر برنامه ،بهتر است آن را خط به خط تحلیل و اجرا کنید .چنانچه ابهامی در این مورد وجود
داشته باشد ،مفاهیم اولیه این فصل را مجددا ً مطالعه نمایید.
در ادامه به بررسی وضعیت کاربران در سیستمهای توزیع شده میپردازیم.
استریسک کاربران مخصوص به خودش را دارد و ما باید بتوانیم در چنین توپولوژیهایی ،وضعیت کاربران
یک ســرور را میان سایر ســرورها به اشتراک بگذاریم .برای این منظور ،سرورهای استریسک باید با هم در
ارتباط باشند .برای برقراری ارتباط میان سرورهای استریسک ،میتوان از روشهای زیر استفادهکرد:
-۱اگر سرورهای استریسک در یک شبکه LANباشند ،میتوان از Corosyncاستفاده کرد.
-۲اگر سرورهای استریسک در موقعیتهای جغرافیایی توزیع شده باشند ،میتوان از XMPPاستفاده نمود.
-۳از ابزارهای مدیریتی استریسک استفاده کرد.
در این فصل به روش اول )استفاده از (Corosyncخواهیم پرداخت.
;Ubuntu
# sudo apt-get install corosync corosync-dev
پس از نصب ،Corosyncبه مســیر نصب استریسک بروید و استریسک را مجددا ً نصب نمایید تا ماژول
res_corosyncبهوسیله استریسک شناسایی شود.
شکل 3-10
مرجع آموزش ویپ با سافتسوئیچ استریسک 312
:برای این منظور به مسیر نصب استریسک بروید و دستورات زیر را اجرا کنید
# cd path/to/asterisk13/
#./configure
#make menuselect
res_corosync باید ماژول، مراجعه کنیدResource Module چنانچه به قسمت،پس از اجرای این دستورات
. سپس ادامه دستورات را اجرا کنید.را فعالشده ببینید
#make & make install
Corosync پیکربندی
. نخست فایل زیر را باز کنیدCorosync برای پیکربندی
#vim /etc/corosync/corosync.conf
همانطورکــه مالحظه میکنید ،اینجا آدرس ســرورهای استریســک را آوردهایم .برای آشــنایی بیشــتر با
Corosyncدستور زیر را اجرا کنید:
# man corosync.conf
سپس مشخص کنید که کدام گروهها )منظور استریسک است( میتوانند به Corosyncمتصل شوند و به آن
دسترسی داشته باشند .برای مثال فایل زیر را باز کنید و تغییرات زیر را انجام دهید.
#vim /etc/corosync/uidgid.d/asterisk
{ uidgid
uid: asteriskpbx ; or uid: root
gid: asteriskpbx ; or gid: root
}
پس از انجام تغییرات الزم ،وارد کامندالین استریســک شــوید و دســتورات زیر را اجرا کنید .با اجرای این
دستورات میتوان مطمئن شد که تنظیمات بهدرستی انجام شده است.
CLI> corosync show config
به کمک دستور زیر میتوان اعضای موجود در corosync clusterرا مشاهدهکرد:
CLI> corosync show members
======== === Cluster members
Node 1
--> Group: asterisk
--> Address 1: 192.168.122.94
Node 2
--> Group: asterisk
--> Address 1: 192.168.122.250
همانطورکه مالحظه میکنید ،در این حالت دو ســرور استریســک داریم که آیپی هرکدام نمایش داده
شدهاست.
این دو ســرور در این شــرایط ،وضعیت کاربران خودرا برای یکدیگر ارســال میکنند .اکنون چنانچه
در یکی از ســرورها تغییــری در وضعیت یکی از کاربران یا دیوایسها رخ دهد ،این تغییر در ســرور دیگر
قابلمشاهده است .این تغییرات را میتوانید با دستور core show hintsدر سرور دیگر مالحظه کنید.
با فعال کردن مود دیباگ در استریسک ،پیامهای این تغییر وضعیت را در کامند الین استریسک مشاهده
خواهید کرد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 314
][101
…
cc_agent_policy = generic
cc_monitor_policy = generic
اکنون چنانچه کاربری *30را شــمارهگیری نماید ،با اجرای دستور ، CallCompletionRequestسرویس
CCSSبرای تماس گیرنده فعال میشود .عالوه بر این ،با گرفتن شماره *31دستور CallCompletionCancel
همانطورکه مالحظه میکنید وضعیت accepted by calleeنشــان میدهد که سرویس CCSSبرای کاربر
۱۰۰فعال شــده اســت و به محض در درســترس بودن کاربر ، ۱۰۱استریســک با او تماس میگیرد .پس از
اجرای سرویس ، CCSSوضعیت آن بهصورت CC offered to callerتغییر میکند.
نتیجهگیری
در این فصل در خصوص بررســی وضعیت کاربران در یک سیســتم تلفنی ،صحبت شد و اینکه چگونه این
اطالعات میتوانند ســودمند باشند .همچنین معلوم شــد که این قابلیت بهصورت پیش فرض در کاربرانی از
نوع SIPفعال اســت .برای توسعه این قابلیت به ســایر کاربران ،مفهوم Custom Device stateو چگونگی
نگاشــت آن به کاربران مورد نظر بررســی شد .سپس در سیستمهای توزیع شــده شرح داده شد که چگونه
سرورهای متعدد به اشتراک گذاشت. میتوان وضعیت اپراتورها را میان
فصل یازدهم
مقدمه
در این فصل قصد داریم ارتباط میان استریسک و پایگاه دادهای در لینوکس و ویندوز را بررسی کنیم.
در سیســتم عامل لینوکس ،پایگاههای دادهای زیادی وجود دارند ولی در این فصل روی پایگاه دادهای
PostgreSQLو MySQLتمرکز بیشــتری خواهیم داشــت و به نحوه ارتباط استریســک بــا پایگاه دادهای
MicrosoftSQLنیز خواهیم پرداخت.
اهمیت این فصل در این است که برای ارتباط با پایگاههای دادهای )صرف نظر از نوع پایگاه داده( باید
از ODBC Connectionها در لینوکس اســتفاده کنیم .اســتفاده از پایگاه دادهای و ارتباط آن با یک سافت
سوئیچ)مثل استریسک ،فری سوئیچ یا (Yateمیتواند یک سسیستمهای تلفنی بزرگ توزیع شده ایجاد کند.
همچنین میتوان از پایگاه دادهای برای ذخیره کردن دادههایی مانند موارد زیر استفاده کرد:
• گزارش جزئیات تماسها CDR
• گزارش رویدادها CEL
• گزارش صفها Queue
• استفاده از ARA
مســلماً برای هر سیستم تلفنی ضرورتی وجود ندارد که به پایگاه دادهای متصل شود .آشنا شدن با این بخش
و نحوه اتصال سیستم تلفنی استریسک با پایگاههای دادهای ،به ما کمک میکند که بتوانیم محصوالت بهتر
و کاربردیتــری ایجاد کنیم .در ادامه نحوه چگونگی این ارتباط در توزیعهای مختلف لینوکســی از جمله
RHELو Ubuntoبررسی میشوند.
319 ارتباط بین استریسک و پایگاه دادهای
نخست باید پایگاه دادهای مورد نیاز خود را نصب کنیم که در ادامه ،نصب پایگاه دادهای PostgreSQL
و MySQLبررسی میشوند.
برای راهاندازی سرویس پایگاه دادهای ،PostgreSQLاز دستور زیر استفاده کنید:
;RHEL
#sudo service postgresql start
ممکن است در ابتدای کار ،وضعیت نصب نیازمندیها پرسش شود .در این مرحله با تأیید لیست نیازمندی،
اجازه دهید تا مراحل نصب با موفقیت اجرا شود .پس از نصب PostgreSQLدر توزیع ،Ubuntuاین پایگاه
دادهای بهصورت خودکار initializeمیشود.
برای راهاندازی سرویس پایگاه دادهای PostgreSQLاز دستور زیر استفاده کنید:
;Ubuntu
#sudo service postgresql start
هنگام نصب ،پســورد rootاز شما پرسیده میشود)شــکل .(۱-۱۱با انتخاب صحیح پسورد ،اجازه دهید
مراحل نصب کامل شود.
مرجع آموزش ویپ با سافتسوئیچ استریسک 320
شکل 1-11
برای راهاندازی سرویس پایگاه دادهای MySQLدر توزیع لینوکس RHELاز دستور زیر استفاده کنید:
;RHEL
#sudo service mysql start
ممکن اســت لیســت نیازمندیها از شما پرسیده شود .در این صورت همانند قبل با تأیید لیست نیازمندیها،
اجازه دهید تا مراحل نصب با موفقیت کامل شود.
;ubuntu
]Do you want to continue? [Y/n
هنگام نصب ،پسورد rootاز شما پرسیده میشود .با انتخاب صحیح پسورد ،اجازه دهید مراحل نصب کامل
شــود .برای راهاندازی ســرویس پایگاه دادهای MySQLدر توزیع لینوکس Ubuntuاز دستور زیر استفاده
کنید:
;Ubuntu
#sudo service mysql start
تــا اینجا مراحل نصب و راهاندازی پایگاههای داداهای PostgreSQLو MySQLبررســی شــدند .در ادامه
مراحل پیکربندی هر یک از آنها توضیح داده میشود.
سپس برای ساختن کاربر ،asteriskاین دستور را اجرا و تنظیمات مشخص شده را انجام دهید.
postgres@ubuntu14:~$createuser –P asterisk
Enter password for new user:
Enter it again:
321 ارتباط بین استریسک و پایگاه دادهای
postgres@ubuntu14:~$
تغییرات زیر را اعمالpg_hba.conf باید در فایل، متصل شودPostgreSQL برای آنکه این کاربر بتواند به
:کنید
#vim /etc/postgresql/9.3/main/pg_hba.conf
باید خــط زیر را هم به فایل باال اضافه، انجام دهید۶ چنانچــه بخواهید ایــن تنظیمات را برای آی پی ورژن
.کنید
host all asterisk ::1/128 md5
یکPostgreSQL باید بتوانید در پایگاه دادهای،پس از ایجاد کاربر جدید و اعطای ســطح دسترسی به آن
: برای ایجاد این دیتابیس دستور زیر را اجرا کنید. ایجاد کنیدasterisk دیتابیس جدید بهنام
;RHEL
#sudo service postgresql restart
;ubuntu
# /etc/init.d/postgresql restart
* Restarting PostgreSQL 9.3 database server [ OK ]
: تست را انجام دادTCP/IP باPostgreSQL میتوان با اتصال به،برای بررسی درستی تنظیمات و پیکربندی
# psql -h 127.0.0.1 -U asterisk
Password for user asterisk:
psql (9.3.14)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
asterisk=>
مرجع آموزش ویپ با سافتسوئیچ استریسک 322
اکنون وارد محیط کامندالین MySQLشوید و یک کاربر جدید بهنام asteriskایجاد کنید.
# mysql -u root –p
>mysql
پس از ورود پسورد ،به کنسول MySQLوارد شوید .با اجرای دستور ،CREATE USERیک کاربر بهنام
asteriskبســازید .کاراکتر %مشــخص میکند کــه کاربر asteriskمیتواند از هر سیســتمی به دیتابیس
دسترسی داشته باشد.
;'mysql> CREATE USER 'asterisk'@'%' IDENTIFIED BY '123123
به دالیل امنیتی توصیه میشــود چنانچه استریســک و دیتابس روی یک سرور قرار دارند ،بهجای استفاده از
کاراکتر » «%از عبارت localhostاستفاده کنید .اما اگر مایلید دسترسی از راه دور ۱به دیتابیس داشتهباشید
my.confانجام دهید. باید تنظیمات زیر را در فایل
#vim /etc/mysql/my.cnf
bind-address = 0.0.0.0
;ubuntu
#/etc/init.d/mysqld restart
پس از ساخت یوزر asteriskو دیتابیس ،سطح دسترسیهای الزم به دیتابیس asteriskرا برای کاربر ایجاد
کنید.
;'mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'%
)Query OK, 0 rows affected (0.00 sec
برای تست کاربر جدید ،از محیط کامند الین MySQLخارج و دوباره با کاربر جدید وارد شوید.
mysql> exit
Bye
# mysql -u asterisk -p 123123
Enter password:
>mysql
شکل 2-11
همانطورکه مالحظه میکنید استریســک از طریق ماژول “ ”res_odbc.soو بهواسطه ،ODBC driver
به پایگاه دادهای متصل میشود.
در شکل ۳-۱۱نمایی از ODBC Config Stackارائه شده است.
ODBC همانطورکــه مالحظه میکنید ،برای برقراری یک ارتباط صحیح با پایگاه دادهای ،باید مطابق
Config Stackتنظیمات را انجام دهید .در ادامه هر بخش بیشتر توضیح داده میشود.
ابتدا باید ODBC Driverرا نصب کنید .اینجا از unixODBCاستفاده میکنیم.
مرجع آموزش ویپ با سافتسوئیچ استریسک 324
3-11 شکل
را پیادهسازی میکند و قابلیت استفاده در محیطODBC API برنامهای متن باز اســت کهunixODBC
یکی از. IBM OS/2 وUnix، Linux، Mac OS X از جمله سیستم عامل،بسیاری از سیستمعاملها را دارد
برای نصب آن دستورات. در سیستمهای غیرویندوزی استODBC استفاده ازunixODBC اهداف اصلی
:زیر را اجرا کنید
;RHEL
# sudo yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel
;Ubuntu
# sudo apt-get install unixODBC unixODBC-dev
مورد نیازODBC Connector ،اکنون باید با توجه به نوع پایگاه دادهای و توزیع لینوکســی مورد اســتفاده
.خود را نصب کنید
;To install the MySQL ODBC connector on RHEL
# sudo yum install mysql-connector-odbc
با پایگاهODBC باید تنظیمات مربوط به ایجاد ارتباطODBC Connection وunixODBC بعــد از نصــب
. با موفقیت به پایگاه دادهای متصل شودODBC بهطوریکه،دادهای را انجام دهید
325 ارتباط بین استریسک و پایگاه دادهای
;Ubuntu
[PostgreSQL]
Description = ODBC for PostgreSQL
Driver = /usr/lib/odbc/psqlodbca.so
Setup = /usr/lib/odbc/libodbcpsqlS.so
FileUsage = 1
درصورتیکه ارتباط بهدرستی. از دستور زیر استفاده کنید،برای اطمینان از درستی تنظیمات صورت گرفته
. نشان داده میشودPostgreSQL عبارت،برقرار شده باشد
#odbcinst -q –d
[PostgreSQL]
این فایل یک شناســه میســازد که استریســک. را باید انجام دهیدodbc.ini تنظیمات فایل،در مرحله بعد
تنها کافیست مقادیر این، درصورت تمایل به تعویض دیتابیس.بهواسطه آن به پایگاه دادهای متصل میشود
.فایل را تغییر دهید
#vim /etc/odbc.ini
[asterisk-connector]
Description = PostgreSQL connection to ‘asterisk’ database
Driver = PostgreSQL
Database = asterisk
Servername = localhost
Port = 5432
Protocol = 8.1
ReadOnly = No
RowVersioning = No
ShowSystemTables = No
ShowOidColumn = No
FakeOidIndex = No
ConnSettings =
مرجع آموزش ویپ با سافتسوئیچ استریسک 326
;Ubuntu
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so
FileUsage =1
در صورتی که ارتباط بهدرستی برقرار. دستور زیر را اجرا کنید،برای اطمینان از صحت تنظیمات انجامشده
: نمایش داده میشودMySQL عبارت،شده باشد
#odbcinst -q –d
[MySQL]
این فایل یک شناســه میســازد که استریســک. را انجام دهیدodbc.ini باید تنظیمات فایل،در مرحله بعد
تنها کافیست مقادیر این، درصورت تمایل به تعویض دیتابیس.بهواسطه آن به پایگاه دادهای متصل میشود
.فایل را تغییر دهید
#vim /etc/odbc.ini
;RHEL
[asterisk-connector]
Description = MySQL connection to ‘asterisk’ database
Driver = MySQL
Database = asterisk
Server = localhost
Port = 3306
Socket = /var/lib/mysql/mysql.sock
پس از نصب درایور فوق ،فایل odbcinist.iniرا باز کنید و تنظیمات آن را مطابق زیر انجام دهید.
# vim /etc/odbcinst.ini
][FreeTDS
Description = ODBC for Microsoft SQL
Driver = /usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
UsageCount =1
Threading =2
بــرای اطمینان از صحت تنظیمات صورتگرفته ،دســتور زیر را اجرا کنید .درصورتیکه ارتباط بهدرســتی
برقرار شدهباشد ،عبارت FreeTDSباز گردانده میشود.
#odbcinst -q –d
][FreeTDS
در مرحله بعد ،باید تنظیمات فایل odbc.iniرا انجام دهید .این فایل یک شناســه میســازد که استریســک
بهواســطه آن به پایگاه دادهای متصل میگردد .درصورت تمایل به تعویض دیتابیس ،تنها کافیســت مقادیر
این فایل را تغییر دهید.
#vim /etc/odbc.ini
][asterisk-connector
Description = MS SQL connection to ‘asterisk’ database
Driver = FreeTDS
Database = asterisk
Server = 192.168.100.1
Trace = No
TDS_Version = 7.0
Port = 1433
تا اینجا ارتباط پایگاه دادهای با ODBC Connectorبرقرار شد .برای تست این ارتباط از دستور زیر استفاده
کنید:
# isql -vvv asterisk-connector asterisk 123123
# echo "select 1" | isql -vvv asterisk-connector asterisk 123123
+---------------------------------------+
!| Connected |
| |
| sql-statement |
]| help [tablename |
| quit |
+---------------------------------------+
>SQL
مرجع آموزش ویپ با سافتسوئیچ استریسک 328
چنانچه همه تنظیمات بهدرســتی انجام شــده باشــند ،خروجی باال را مشــاهده خواهید کــرد .هم اکنون هر
دستوری را اجرا کنید ،در پایگاه دادهای شما نیز اعمال میشود.
چنانچه خطایی در برقراری این ارتباط وجود داشته باشد ،این پیام را مشاهده خواهید کرد:
بعد از نصب و پیکربندی ODBC Connectionو ارتباط آن با پایگاههای دادهای ،باید به مســیر نصب
استریسک وارد شوید و ماژول مورد نیاز ) (res_odbc.soرا فعال و سپس دوباره استریسک را کامپایل کنید.
ازآنجاکه ODBC Deriverقب ً
ال در سیستم نصب نشده است ،واضح است که استریسک آن را تشخیص
میدهد .پیشفرض تمامی ماژولهای مربوطه غیرفعال است.
با اجرای دســتور ، . /configureاستریسک مجددا ً تمامی Driverها و ماژولهای نصب شده در سیستم
لینوکس را بررسی میکند و چنانچه Driverها و ماژولهای جدیدی نصب شده باشند ،ماژولهای خود را
در استریسک فعال میکند.
#./configure
همانطورکــه مالحظه میکنید ،در این بخــش میتوان ماژولهای مورد نیاز را با فشــردن کلید “ ”spaceو
نمایــش عالمت]*[ فعال کرد و درصورت عدمنیاز به ماژولها ،با فشــردن مجــدد کلید " "spaceو نمایش
عالمت ] [ ،ماژول را غیرفعال کرد .در این بخش اطمینان پیدا کنید که ماژولهای res_odbc , func_odbc
حتماً فعال )عالمت ]*[( باشند.
چنانچه جلوی برخی ماژولها عالمت ] [XXXدیده شــد ،به منزله این است که ماژولها و Driverهای
الزم برای اســتفاده از این ماژول ،درسیستم لینوکس نصب نشدهاند .در این صورت ابتدا باید آنها را نصب
کنید و بعد استریسک را مجددا ً کامپایل کنید.
329 ارتباط بین استریسک و پایگاه دادهای
در این فایل تنظیمات برای ارتباط با ODBC Connectorبهصورت زیر خواهد بود:
][asterisk
enabled => yes
dsn => asterisk-connector
username => asterisk
password => 123123
pooling => no
limit => 1
pre-connect => yes
پرسشی که اینجا مطرح میشود این است که چه ارتباطی میان پیکربندی فایلهای odbc.int, odbcints.
intو ماژول res_odbcوجود دارد؟ برای روشن شدن این مطلب ،به شکل 4-۱۱دقت کنید:
مرجع آموزش ویپ با سافتسوئیچ استریسک 330
شکل 4-11
همانطورکه در شــکل مالحظــه میکنید ،بهوســیله odbcints.iniابتدا یک نمونه ۱از یــک پایگاه دادهای
ایجاد کردیم .ســپس بهوسیله فایل odbc.iniیک ODBC Connectionمیسازیم و در فایلهای پیکربندی
استریسک از این ODBC Connectionبرای ارتباط با پایگاه دادهای استفاده میکنیم.
وقتی با ODBC Connectorو استریسک کار میکنید ،ممکن است خطاهایی در سیستم رخ دهد که مربوط
به ارتباط با پایگاههای دادهای باشــد .بنابراین ،اطالعاتی که از طرف استریسک به طرف دیتابیس میرود را
با هدف یافتن خطاهای احتمالی باید بررسی کنید.
1- instance
331 ارتباط بین استریسک و پایگاه دادهای
برای مثال فرض کنید تصمیم داریم اطالعاتی را در یک جدول ذخیره کنیم که ساختارش با آن چیزی
که در استریســک انتظار میرود ،متفاوت اســت .در نتیجه استریســک هنگام افزودن اطالعات ،اعالم خطا
میکند .نیاز به سیستم الگگیری در این شرایط الزامی است.
SQL Injection
برای برنامههای تحت شبکه ،امنیت همیشه حرف اول را میزند و چنانچه این نرمافزارها با دیتابیس در ارتباط
باشند ،حفظ امنیت دیتابیس نیز باید تأمین گردد.
برای برنامههایی که با دیتابیس در ارتباطاند ،کنترل SQL Injectionبسیار حیاتی استSQL Injection .
عبارت است از انتقال اطالعات مخرب به طرف دیتابیس ،به این صورت که نفوذگر با یک سری دستورهای
SQLیک عملیات تهاجمی )متفاوت با عملیات عادی موردنظر طراح نرمافزار( در دیتابیس صورت میدهد.
اینگونه حمالت میتواند موجب پاکشدن کلیه اطالعات و به سرقت رفتن آنها شود.
]]ODBC_functionname(<arg1>[...[,<argN>]])[=[val1
اکنون برای استفاده از تابع تعریف شده در برنامه ،تابع زیر را اجرا کنید:
مرجع آموزش ویپ با سافتسوئیچ استریسک 332
[LocalSets]
exten => _5XXX,1,NoOp()
same => n,Set(CDR(accountcode)=pricall)
; Does this callerID appear in the database?
same => n,GotoIf($[${ODBC_ANIBLOCK(${CALLERID(number)})}]?busy)
same => n(dial),Dial(DAHDI/g1/${EXTEN})
same => n(busy),Busy(10) ; Yes, you are on the blacklist.
same => n,Hangup
استفادهODBC از پیشوند، ضرورتا باید پیش از نام تابع، در فرمت اصلی تابع،همانطورکه مالحظه میکنید
. مثال کاربردی زیر را انجام دهید، برای درک بهتر این موضوع.کنید
یک دیتابیس جدید ایجاد کنید و، PostgreSQL یاMySQL ،مثال( ابتدا در پایگاه دادهای مورد نظر خود
. استفاده میکنیمMySQL در این مثال از پایگاه دادهای. بگذاریدAsteriskDB نام آن را
mysql > CREATE DATABASE asteriskdb;
Query OK, 1 row affected (0.00 sec)
. ایجاد کنید که دارای فیلدهای زیر باشدuser سپس یک جدول جدید بهنام
1-11 جدول
و برای دیدن ساختار جدولهای موجود در دیتابیس ،دستور زیر را اجرا کنید:
;mysql> describe user
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| | userid | int(11) | NO | PRI | NULL | auto_increment
| password | int(11) | YES | | NULL | |
| callerid | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+----------------+
)3 rows in set (0.01 sec
اکنون باید یک تابع در فایل func_odbc.confبهنام ] [GET-PSWDبســازید .هدف این اســت که در این
تابع ،پسورد براساس کالرآیدی استخراج شود Query .دستورات SQLبهصورت زیر است:
#vim /etc/asterisk/func_odbc.conf
][GET_PSWD
dsn=asterisk
"}readsql=SELECT password FROM user WHERE callerid = "${ARG1
در این مثال ) CALLERID(numرا بهعنوان آرگومان ورودی به تابع ،ارســال میکنیم .هنگام تعریف
تابع ،مقدار پارامتر ارسالی را بهصورت } ${ARG 1میخوانیم.
مثال) فرض کنید از کاربر بخواهیم یک پســورد وارد کند و ســپس آن را ،با پسورد ذخیره شده در دیتابیس
مقایسه نماید .در صورت یکسان نبودن دو پسورد ،تماس را Hangupکنید .به مثال زیر توجه کنید:
;extensions.conf
][localSets
)exten => s,1,Read(UserInput,pls-enter-password
)same => n,GotoIf($[${ODBC_GET_PSWD(${CALLERID(num)})} = ${UserInput}]?:hangup
)same => n,VoiceMail(${EXTEN},s
)(same => n(hangup),Hangup
مرجع آموزش ویپ با سافتسوئیچ استریسک 334
بهوســیله دستور Readیک فایل صوتی پخش میشــود و از کاربر خواسته میشود که پسورد خود را وارد
نماید .پســورد وارد شده بهوسیله کاربر ،در متغیر UserInputذخیره میشود .سپس با پسورد ذخیره شده در
جدول مقایسه میشود.
مثال( فرض کنید بخواهیم دستوراتی را اجرا کنیم که مقداری را در دیتابیس ذخیره کند .بهعنوان مثال برنامه
زیر را در نظر بگیرید:
;extensions.conf
][localSets
)exten => s,1,Read(User_Pass,pls-enter-password
)}same => n,Set(OBDC_SET_PSWD(${CALLERID(num)})=${User_Pass
][PSWD2
prefix=GET
dsn=asterisk
"}readsql=SELECT password FROM user WHERE callerid = "${ARG1
نحوه فراخوانی کردن توابع تعریف شــده در باال به صورت زیر می باشــد ،به پیشــوند استفاده شده در زمان
فراخوانی کردن توابع دقت کنید.
;extensions.conf
)})})same => n,NoOp(${ODBC_PSWD1(${CALLERID(num
)})})same => n,NoOp(${GET_PSWD2(${CALLERID(num
;func_odbc.conf
[PSWD2]
synopsis=This function reads a password out of the database based on the CallerID number
prefix=GET
dsn=asterisk
readsql=SELECT password FROM user WHERE callerid = "${ARG1}"
توضیحاتی در خصوص تابع فوق در محیط کامندالین استریسک،دراینصورت میتوان بهوسیله دستور زیر
.مشاهدهکرد
CLI> core show function GET_PSWD2
[Synopsis]
This function reads a password out of the database based on the CallerID number
SQL:
SELECT password FROM user WHERE callerid = '${ARG1}'
[Syntax]
GET_PSWD2(<arg1>[...[,<argN>]])
در چنین شرایطی باید هنگام تعریف تابع در.در این حالت ممکن اســت بیش از یک خروجی داشــته باشید
. برای مثال به تعریف تابع زیر توجه کنید. را فعال کنیدmode = multirow پارامتر، func_odbc.conf فایل
;func_odbc.conf
[BLK_NUMBER]
mode=multirow
dsn=asterisk
readsql=SELECT blknumber FROM blacklist_table
مرجع آموزش ویپ با سافتسوئیچ استریسک 336
mode = پارامتر، بنابراین، ممکن اســت چند ســطر خروجی داشته باشیم،همانطورکه مالحظه میکنید
: نحوه استفاده از این تابع بهصورت زیر است. تعریف میکنیمmultirow
;extensions.conf
[multirow]
exten => _NXXX,1,NoOp()
same => n,Set(ID=${ODBC_BLK_NUMBER()})
same => n(loop_start),Set(ROW_VALUE=${ODBC_FETCH(${ID})})
same => n,GotoIF($[ "${ODBC_FETCH_STATUS}" = "FAILURE"]?End)
same => n,GotoIf($[ "${ROW_VALUE}" = "${EXTEN}"]?Number-Found)
same => n,Goto(loop_start)
same => n(End),ODBCFinish(${ODBC_ID})
same => n,Goto(outgoing,${EXTEN},1)
same => n,Hangup()
same => n(Number-Found),ODBCFinish(${ODBC_ID})
same => n,Playback(extension&privacy-backlisted)
same => n,Hangup()
این متغییر میتواند مقادیر زیر. ذخیره میشــودODBC_FETCH_STATUS در متغیر،نتیجه خروجی تابع
:را داشته باشد
. موفقیتآمیز باشدODBC_FETCH اگر نتیجه تابع:SUCCESS •
. موفقیتآمیز نباشدODBC_FETCH اگر نتیجه تابع:FAILURE •
، را پاک کردQuery میتوان نتایج حاصل از اجــرایODBCFinish بهوســیله دســتور،عــالوه بر این
ODBCFinish فرمت اســتفاده از دســتور. حافظه خالی باشــد،بهطوری که برای اجرای بعدی دســتورات
:بهصورت زیر است
CLI> core show application ODBCFinish
[Synopsis]
Clear the resultset of a sucessful multirow query.
[Syntax]
ODBCFinish(result-id)
اکنون میتوانیم بهطور مستقیم در برنامهنویسی استریسک از دستورات SQLاستفاده و Queryهای مختلفی
را اجرا کنیم.
مثال( فرض کنید ما در فایل func_odbc.confچنین مقادیری داشته باشیم:
][SQL
prefix=GENERIC
dsn=asterisk
})}readsql=${SQL_ESC(${ARG1
})}writesql=${SQL_ESC(${VAL1
در ایــن حالت هیچ دســتوری از نــوع SQLنداریم ،بلکه دســتورات SQLرا بهصــورت پارامتر برای تابع
SQL_ESCارسال میکنیم تا بهوسیله آن اجرا شوند.
به مثالهای زیر توجه کنید:
][LocalSets
)exten => 8811,1,Goto(odbcreadtest,1
)exten => 8822,1,Goto(odbcwritetest,1
همان طور که مالحظه می کنید ما از دســتورات SQLدر داخل برنامه استریسک استفاده کرده ایم.در ادامه
Asterisk Realtime Architectureمیپردازیم. به یکی از قابلیتهای منحصر به فرد استریسک بهنام
معماری ARA_Static
همانطورکه پیشتر توضیح داده شــد ،این روش به روش استفاده از تنظیمات پیکربندی استرسیک بهوسیله
فایلها شــباهت زیادی اســت؛ با این تفاوت که بهجای کار با یک فایل مشــخص ،از یک دیتابیس استفاده
میکنیم.
هنگام اســتفاده از معماری ARA_Staticباید مشخص کنید که با چه نوع دیتابیسی کار میکنید .فرمت
استفاده از این نوع تعریف در فایل extconfig.confبهصورت زیر است.
#vim /etc/asterisk/extconfig.conf
][settings
]filename.conf => driver,database[,table
ِ
تنظیمات کدام فایلها ،باید از دیتابیس استفاده کند. در این فرمت مشخص میشود که استریسک برای
مثال( فرض کنید استریســک ،برای پیکربندی موزیک انتظار قرار اســت از دیتابیس استفاده کند .برای این
منظور باید در فایل extconfig.confتنظیمات زیر ار انجام دهید.
;extconfig.conf
339 ارتباط بین استریسک و پایگاه دادهای
][settings
musiconhold.conf=>odbc,asterisk,ast_config
همانطورکــه مالحظه میکنید ،به کمک این تنظیمات ،از طریق ،ODBC Connectionبه پایگاه دادهای و
دیتابیس asteriskو جدول ast_configمتصل میشوید و تنظیمات پیکربندی را از آنجا میخوانید.
در تنظیمات باال میتوان از ذکر نام جدول خودداری کرد .در این صورت ،استریســک نام جدول و نام
فایل را یکسان در نظر میگیرد .برای مثال تنظیمات زیر یکساناند:
;extconfig.conf
][settings
musiconhold.conf=>odbc,asterisk
; musiconhold.conf=>odbc,asterisk,musiconhold
اکنون الزم اســت که یک جدول در دیتابیس داشته باشــید تا بتوانید تنظیمات فایل مربوطه را در آن ذخیره
کنید.
پرسشــی که ممکن است اینجا مطرح شود این است که جدول دیتابیس چه فیلدهایی باید داشته باشد و
چگونه باید تنظیمات فایل را درون یک جدول نگاشت داد؟
برای پاسخ به این پرسش ،نخست بهتر است فایل musiconhold.confرا بررسی کنیم .اگر این فایل را
باز کنید ،خواهید دید که یک کالس ] [defaultبرای musiconholdبهصورت پیشفرض تعریف شدهاست.
;musiconhold.conf
][default
mode=files
directory=moh
اکنون همین تنظیمات باال را به یک جدول در دیتابیس نگاشت میدهیم تا در نهایت جدول زیر را داشتهباشیم:
همانطورکــه مالحظه میکنید ،به ازای هر کالس جدید ،یک “ ”categoryجدید خواهیم داشــت .به ازای
هر پارامتر یک " "var_nameو به ازای هر مقدار در هر پارامتر نیز یک “ ”var_valخواهیم داشــت .شــکل
۵-۱۱مراحل نگاشت را نمایش میدهد.
بنابراین ،نگاشت موردنظر برای یک تعریف جدید از موزیک انتظار ،میتواند بهصورت زیر باشد:
;musiconhold.conf
][mymoh
mode=files
directory=mymoh
مرجع آموزش ویپ با سافتسوئیچ استریسک 340
شکل 5-11
][mymoh
mode=files
directory=mymoh
همانطورکه مالحظه میکنید ،پارامترهای الزم برای پیکربندی را میتوانید به صورت جدول 4-۱۱نگاشت
دهید .به این منظور باید جدولی با فیلدهای مشــابه جدول 4-۱۱داشــته باشــید .این جدول بهصورت زیر در
پایگاه دادهای ایجاد میشود:
( mysql> CREATE TABLE ast_config
id int(8) primary key auto_increment,
cat_metric int(8),
var_metric int(8),
filename varchar(128),
category varchar(128),
var_name varchar(128),
var_val varchar(128),
commented int default 0
;)
)Query OK, 0 rows affected (0.02 sec
>mysql
واضح اســت که میتوان هر فایلی از مســیر /etc/asteriskرا با این روش نگاشــت داد و تنظیمات آن را در
جدول ذخیره نمود .برای نمونه یک کاربر جدید با روش مذکور در استریســک ایجاد میکنیم .این کاربر
در فایل sip.confبهصورت زیر تعریف میشود:
;sip.conf
][Phone_1
qualify=yes
host=dynamic
nat=force_rport,comedia
port=5060
type=friend
disallow=all
allow=ulaw,alaw
canreinvite=no
directmedia=no
callcounter=yes
deny=0.0.0.0/0.0.0.0
permit=0.0.0.0/0.0.0.0
secret=123123
context=LocalSets
ایــن تعریــف را باید به یک جدول نگاشــت دهیم .این نگاشــت بهصــورت زیر خواهد بــود )ترتیب برای
پارامترهای Boldشده مهم است(:
ابتدا فایل sip.confرا باز کرده و در انتهای آن خط زیر را اضافه کنید.
;sip.conf
#include sip_custom.conf
پیشتر در فصل سوم )نصب استریسک و پیکربندی.ممکن است هنگام لود شدن مجدد با خطا مواجه شوید
.اولیه( توضیح داده شد که گاهی الزم است ترتیبی برای لود شدن ماژو لها در استریسک وجود داشته باشد
برای. پیش از سایر ماژول ها لود شوندres_config_odbc.so وres_odbc.so اینجا الزم اســت ماژولهای
: تغییرات زیر را اعمال کنیدmodules.conf در فایل،این منظور
; modules.conf
[modules]
autoload=yes
preload => res_odbc.so
preload => res_config_odbc.so
در استریسک ایجادPhone_2 چنانچه تصمیم داشــته باشــیم یک کاربر جدید با نام،بهعنوان نمونهای دیگر
. طراحی کنید۱۱-۶ ابتدا باید تغییرات زیر را در هر فایل انجام دهید و بعد جدول را مطابق جدول،کنیم
;extconfig.conf
sip_mytest.conf => odbc,asterisk,ast_config
;sip.conf
#include sip_mytest.conf
343 ارتباط بین استریسک و پایگاه دادهای
: به محیط کامندالین استریسک رفته و دستور زیر را اجرا کنید۱۱-۶ پس از تعریف جدول
CLI> sip reload
CLI> sip show peers
ARA_Dynamic معماری
از دیتابیس، روش دیگری اســت برای اجازه دادن به استریسک تا بهجای فایلهاARA_Dynamic معماری
با این تفاوت که، شباهت زیادی داردARA_Static این روش به روش.برای پیکربندی خود اســتفاده کند
کردن ســرویس استریسک و یا ماژول مربوطه نیازی نیست؛reload به،پس از انجام هر تغییری در دیتابیس
. آسانتر است، این روش نسبت به روش مشابه،بنابراین
. غالبا برای ماژولهایی در استریســک مناســب است که دائما در حال تغییرندARA_Dynamic روش
:مهمترین ماژولهای این سری عبارتند از
• SIP Module
• IAX2 Module
• Queue Module
مرجع آموزش ویپ با سافتسوئیچ استریسک 344
: باید بهصورت زیر عمل کنیدARA_Dynamic در استریسک برای استفاده از
; extconfig.conf
[settings]
sippeers => driver,database[,table]
نام جدول اختیاری است و استریسک درصورت لزوم میتواند از نامهای از قبل،ARA_Static مانند روش
.( استفاده کندSIP برای ماژولsippers تعریف شده )از قبیل
: از تنظیمات پیشفرض زیر میتواند استفاده کندARA_Dynamic استریسک برای،برای مثال
; extconfig.conf
[setting]
iaxusers => odbc,asterisk
iaxpeers => odbc,asterisk
sippeers => odbc,asterisk
sipregs => odbc,asterisk
ps_endpoints => odbc,asterisk
ps_auths => odbc,asterisk
ps_aors => odbc,asterisk
ps_domain_aliases => odbc,asterisk
ps_endpoint_id_ips => odbc,asterisk
voicemail => odbc,asterisk
extensions => odbc,asterisk
meetme => mysql,general
queues => odbc,asterisk
queue_members => odbc,asterisk
queue_rules => odbc,asterisk
acls => odbc,asterisk
musiconhold => mysql,general
queue_log => mysql,general
در این صورت تنظیمات. از دیتابیس استفاده کندSIP مثال( تصمیم داریم استریسک برای پیکربندی ماژول
: را باید بهصورت زیر انجام دهیمARA_Dynamic برای
; extconfig.conf
[settings]
sippeers => odbc,asterisk,ast_sippeers
.میشوند
ARA_Dynamic استریســک بهصورت پیشفرض از نامهــای زیر برای نامگذاری جــداول در روش
استریســک از،” مقدار ندهیمtable“ به پارامتر، در این صورت اگر هنگام تعریف جدول.اســتفاده میکند
:نامهای زیر استفاده خواهدکرد
• iaxusers—IAX users
• iaxpeers—IAX peers
• sippeers—SIP peers and users
• sipregs—SIP registrations
• voicemail—voicemail boxes
• extensions—dialplan
• meetme—MeetMe conferences
• queues—queues
• queues_members—members of queues
• acls—access control lists
• musiconhold—music on hold
• queue_log—queue logging
دســتور زیر را، اگر در محیط کامندالین استریســک،extconfig.conf پس از انجام تغییرات فوق در فایل
:” هایی )هشدارهایی( مواجه خواهید شدWARNING“ با،اجرا کنید
CLI> module unload chan_sip.so
CLI> module load chan_sip.so
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'name', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'ipaddr', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'port', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'regseconds', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'defaultuser', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'fullcontact', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'regserver', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'useragent', but that column does not exist!
res_config_odbc.c:1177 require_odbc: Realtime table ast_sippeers@asterisk requires
column 'lastms', but that column does not exist!
عالوه بر این.”ها مشاهده میشودWARNING“ در هر سطر از،فیلدهای مورد نیاز برای ساختن جدول
. فیلدهای دیگری نیز موردنیاز است،فیلدها
: ایجاد نماییدMySQL بهوسیله دستور زیر میتوانید این جدول را در
mysql>CREATE TABLE `ast_sippeers` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(80) NOT NULL default '',
`host` varchar(31) NOT NULL default '',
`nat` varchar(5) NOT NULL default 'no',
`type` enum('user','peer','friend') NOT NULL default 'friend',
`accountcode` varchar(20) default NULL,
`amaflags` varchar(13) default NULL,
`call-limit` smallint(5) unsigned default NULL,
`callgroup` varchar(10) default NULL,
`callerid` varchar(80) default NULL,
`cancallforward` char(3) default 'yes',
`canreinvite` char(3) default 'yes',
`context` varchar(80) default NULL,
`defaultip` varchar(15) default NULL,
`dtmfmode` varchar(7) default NULL,
`fromuser` varchar(80) default NULL,
`fromdomain` varchar(80) default NULL,
`insecure` varchar(4) default NULL,
`language` char(2) default NULL,
`mailbox` varchar(50) default NULL,
`md5secret` varchar(80) default NULL,
`deny` varchar(95) default NULL,
`permit` varchar(95) default NULL,
`mask` varchar(95) default NULL,
`musiconhold` varchar(100) default NULL,
`pickupgroup` varchar(10) default NULL,
`qualify` char(3) default NULL,
`regexten` varchar(80) default NULL,
`restrictcid` char(3) default NULL,
`rtptimeout` char(3) default NULL,
`rtpholdtimeout` char(3) default NULL,
`secret` varchar(80) default NULL,
`setvar` varchar(100) default NULL,
`disallow` varchar(100) default 'all',
`allow` varchar(100) default 'g729;ilbc;gsm;ulaw;alaw',
`fullcontact` varchar(80) NOT NULL default '',
`ipaddr` varchar(100) NOT NULL default '',
`port` int(11) unsigned NOT NULL default '0',
`regserver` varchar(100) default NULL,
`regseconds` int(11) NOT NULL default '0',
347 ارتباط بین استریسک و پایگاه دادهای
پس از ســاختن جدول ،چنانچه قصد داشته باشــید یک کاربر جدید تعریف کنید ،کافی است فیلدهای آن
را در یک ســطر از جدول پر کنید و بعد بهوســیله یک “ ”IP Phoneیا “ ”Soft Phoneدر سرور استریسک
رجیستر شوید.
نکته مهم آنکه پس از تعریف کاربر جدید ،نیازی به reloadکردن ماژول chan_sip.soوجود ندارد.
بــرای نمونه فرض کنید بخواهیم یک کاربر جدیــد در جدول ast_sippeersایجاد کنیم .برای این کار
کافی است فیلدهای زیر را مقداردهی کنیم.
اکنون ســعی کنید با اســتفاده از اطالعات فوق و به کمک یک “ ”IP Phoneیا “ ”Soft Phoneدر ســرور
استریسک رجیستر شوید .پس از آن ،به محیط CLIاستریسک وارد شوید و دستور زیر را اجرا کنید:
CLI>sip show peers
همانطورکه مالحظه میکنید ،اینجا هیچ نشــانی از یوزر تعریف شده در دیتابیس دیده نمیشود .ازآنجاکه
این یوزرها بهصورت “ ”realtimeبه استریســک معرفی شــدهاند ،نخســت باید در فایل ،sip.confتنظیمات
مربوط به Real Time Cachingرا فعال کنید .این تنظیمات بهصورت زیرند.
][general
rtcachefriends=yes
مرجع آموزش ویپ با سافتسوئیچ استریسک 348
پس از انجام تغییرات باال و reloadکردن ماژول ،chan_sip.soاکنون میتوانید مجددا عملیات رجیستر در
استریســک را از ســر بگیرید .پس از آن ،به محیط کامندالین استریسک وارد شوید و دستور زیر را مجددا ً
اجرا کنید.
CLI>sip show peers
Name/username Host Dyn Forcerport Comedia ACL Port Status Description Realtime
Phone_3/Phone_3 192.168.141.1 D No No 60319 OK (115 ms) Cached RT
همانطورکه مالحظه میکنید ،اطالعات کاربر دیده میشــود .در ســتون مربوط به ،Realtimeکاربرانی از
نوع Cached RTدیده میشــوند .با مشاهده جدول تعریفشده در دیتابیس ،خواهید دید که سایر فیلدهای
جدول در زمان عملیات رجیسترشدن ،مقداردهی شدهاند.
به کمک این روش ،میتوان برای ســایر کاربران نیز از روش ARA_Dynamicاســتفاده کرد .در ادامه
ســایر ماژولهایی را بررســی خواهیم کرد که قرار اســت با این روش به دیتابیس متصل شــوند .برای مثال
میتوان از ARA_Dynamicبرای ایجاد صف در استریسک ،استفاده کرد.
ساختن صف در دیتابیس
ذخیره کردن صف در دیتابیس میتواند ازطریق هر دو روش ARA_Staticو ARA_Dynamicانجام شود.
روش ARA_Staticبسیار ساده است .با داشتن ساختار جدولی بهصورت زیر ،بهراحتی میتوان تنظیمات
را در دیتابیس ذخیره نمود .برای مثال در فایل extconfig.confداریم:
;extconfig.conf
][settings
queues_ara.conf => odbc,asterisk,ast_config
اکنون اگر تصمیم بگیرید یک صف جدید بهنام ara_queueدر جدول تعریف کنید ،ابتدا باید تنظیمات
زیر را در انتهای فایل queues.confاضافه کنید.
#include queues_ara.conf
ara_queue صف جدید،اکنون چنانچه وارد محیط کامند الین استریسک شوید و دستور زیر را اجرا کنید
.را مشاهده میکنید
CLI> core reload
CLI> queue show
ara_queue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0,
C:0, A:0, SL:0.0% within 0s
No Members
No Callers
. میتوان یک صف در دیتابیس ذخیره کرد، به کمک ساختار جدولی زیرARA_Dynamic در روش
mysql>CREATE TABLE Queues (
`QueueID` mediumint(8) unsigned NOT NULL auto_increment,
`name` varchar(128) NOT NULL COMMENT 'Asterisk name for the queue',
`description` varchar(128) default NULL,
`maxlen` tinyint(4) default NULL,
`reportholdtime` varchar(3) default 'no',
`periodic_announce_frequency` varchar(4) default NULL,
`periodic_announce` varchar(128) default NULL,
`strategy` varchar(20) NOT NULL default 'rrmemory',
`joinempty` varchar(35) default 'no',
مرجع آموزش ویپ با سافتسوئیچ استریسک 350
. در دیتابیس مراجعه میکندQueues به جدول، استریسک برای پیکربندی تنظیمات صف،با این کار
برای این کار فیلدهای. در استریسک ایجاد کنیمara2_queue اکنون قصد داریم یک صف جدید بهنام
وارد، کنیدreload ســپس بدون اینکه استریســک را.موردنیــاز جدول را مطابق با جدول قبلی مقدار دهید
.کامندالین استریسک شوید و دستور زیر را اجرا نمایید
CLI> queue show
351 ارتباط بین استریسک و پایگاه دادهای
ara2_queue has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime),
W:0, C:0, A:0, SL:0.0% within 60s
No Members
No Callers
برای. میخواهیم گزارشات مربوط به صفها را در دیتابیس ذخیره کنیم،بهعنوان آخرین مثال از این بخش
:این منظور ابتدا باید یک جدول بهصورت زیر ایجاد کنید
mysql> CREATE TABLE queue_log (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
time char(26) default NULL,
callid varchar(32) NOT NULL default '',
queuename varchar(32) NOT NULL default '',
مرجع آموزش ویپ با سافتسوئیچ استریسک 352
queue_logثبت خواهد شد. اکنون چنانچه تماس جدیدی ایجاد شود ،گزارشات مربوطه در جدول
نتیجهگیری
در ایــن بخــش ،چندین حــوزه مختلف و کاربردی در استریســک مطرح شــد .ابتدا به معرفــی پایگاههای
دادهای و چگونگی اتصال به آنها پرداختیم .ســپس اجرای دســتورات SQLدر برنامهنویسی استریسک را
بررســی نمودیم .در نهایت درباره Asterisk Realtime Artichetureو روشهای ARA_Staticو _ARA
Dynamicتوضیحاتــی دادیم و برای هر کــدام از مفاهیم فوق ،مثالهایی ارائه نمودیم .مطمئنا اطالعات این
فصل میتواند بسیار کاربردی باشد و شما را در تولید محصوالت مرتبط با این زمینه تخصصی ،یاری رساند.
فصل دوازدهم
فکس
مرجع آموزش ویپ با سافتسوئیچ استریسک 354
فکس چیست
فکس دســتگاهی اســت که میتواند از یک صفحه کاغذ ،یک تصویر بســازد و به کمک خط تلفن ارسال
نماید .دســتگاه فکس در مبدأ ،تصویر را به یک ســری کدهای قابل انتقال روی خط تلفن ،تبدیل میکند و
این کدها در مقصد بهوسیله دستگاه فکس مخاطب ،مجددا به تصویر تبدیل و روی کاغذ چاپ میشود.
فکس در ســال ۱۲۲۲هجری شمسی معادل ســال ۱84۳میالدی بهوســیله یک مخترع اسکاتلندي بهنام
الکساندربین ســـاخته شـــد .دستگاههای ابتدایی تصویر را به خطوط عرضی کوچک تقسیم میکردند و هر
نقطه را با رنگهای سیاه و سفید نشان میدادند ،سپس این نقاط بهوسیله تلگراف بهصورت خط و نقطه )کد
مورس( منتقل میشــد .تا ســال ۱۳۳۹هجری شمسی برابر با ۱۹۶۰میالدی ،هر شرکت به روش خاص خود
ارســال و دریافت فکس را انجام میداد تا اینکه در همین ســال قانون یکسانسازی به روش آمریکایی آغاز
و تجاری گردید.
همچنین ارتباط با یک نیروی انسانی برای دریافت و یا ارسال فکس ضروری است.
یکی دیگر از چالشها و مشکالت فکسهای سنتی ،وابستگی آنها به موقعیت مکانی برای ارسال فکس
و مشاهده فکس است .به عبارت دیگر برای ارسال فکس باید در اداره یا سازمان خود باشید تا بتوانید فکس
را ارسال یا دریافت کنید.
1
فکسهای اینترنتی
فکسهــای اینترنتی که از آنها با اســمهایی چون MyFax، eFaxو onlineFaxنام برده میشــود ،امروزه
رشــد چشمگیری داشتهاند .این نوع فکسها اغلب با عناوینی چون Web-Fax، Email-Faxو یا VoIP-Fax
معرفی میشــوند ،بهطوریکه هر یک از این عناوین ،ســهولت اســتفاده از فکس را در شبکههای اینترنتی و
نســل جدید مخابراتی ارائه میدهند .برای مثال » «Fax-To-Mailیک عنوان جالب برای استفاده از این نوع
سرویسهاست تا قادر باشید فکسهای دریافتی خود را بهراحتی از طریق ایمیل ارسال و دریافت نمایید.
از جمله مزایای استفاده از فکسهای اینترنتی میتوان به موارد زیر اشاره نمود:
-1به نرمافزارها و سختافزارهای جدید نیاز ندارند؛
-2به خطوط تلفنی برای ارسال فکس نیاز ندارند؛
-3از قابلیت اتصال به سایر سرویسها برخوردارند؛
-4توانایی ارسال دریافت همزمان چندین فکس (بهصورت انبوه) را دارند؛
-5هزینههای ارسالی فکس در تعداد باال زیاد نیست؛
-6ارسال و دریافت فکس از طریق گوشیهای هوشمند امکانپذیر است.
شکل 1-12
)2استفاده از روش کامپیوتر به فکس :در این روش ،یک طرف ارتباط یک دستگاه کامپیوتر است که مجهز به
کارت تلفن با پورت RJ11و یک نرم افزار ارسال و دریافت فکس است و در طرف دیگر یک دستگاه ماشین
فکس داریم .شکل 2-12و 3-12ارسال فکس به این روش را نمایش میدهد.
شکل 2-12
یا
شکل 3-12
)3اســتفاده از فکس گیتوی :در این روش یک Fax-Gatewayفکسهای دریافتی را برای یک ســرویس
معین (مثال ســرویس ایمیل) ارســال مینماید .در این روش میتوان از ســرویسهای دیگر (از جمله ایمیل)
اطالعات گرفت و بهصورت فکس ارسال کرد.
شکل 4-12
یا
شکل 5-12
)4اســتفاده از : VoIPیکی دیگر از قابلیتهای اســتفاده از شــبکه های ویپ امکان ارسال و دریافت فکس
اســت .در سیســتم تلفنی استریســک این قابلیت وجود دارد که بتوان به ســهولت به ارسال یا دریافت فکس
پرداخت.
پروتکل T.38
این پروتکل اســتاندارد ارسال و دریافت فکس در شــبکههای کامپیوتری است .ازآنجاکه دادهها در فکس،
بهصورت آنالوگ منتقل میشــود ،پروتکلهای رایج در شــبکهی دیجیتــال ،اطالعات فکس را به کمک
357 فاکس
ایــن پروتکل ،از آنالوگ به دیجیتال تبدیل میکنند ایــن پروتکل ،در مبدأ دادههای آنالوگ را به دادههای
دیجیتال تبدیل و به شــبکهی IPارسال میکند؛ ســپس در مقصد نیز به کمک همین پروتکل ،این عملیات
بهصورت وارونه )یعنی تبدیل دادههای دیجیتالی به دادههای آنالوگ( صورت میگیرد.
این اســتاندارد در سال ۱۹۹8تحت عنوان اســتاندارد RFC3362و زیر نظر سازمان ITUمنتشر گردید.
یکی از تفاوتهای اصلی این پروتکل با پروتکل T.37در این اســت که این پروتکل اطالعات را بهصورت
RealTimeارسال میکند ،در صورتی که پروتکل ، T.37دادهها را نخست ذخیره و سپس ارسال میکند.
یکی از قابلیتهای مهم پروتکل ،T.38مکانیســم Multi-Level-Redundancyاســت .با توجه به اینکه
در شبکه Packet Lostو یا Jitter ارســال اطالعات در شــبکهی IPبهصورت UDPاست ،در صورتی که
رخ دهد ،احتمال از بین رفتن دادهها وجود دارد .این استاندارد به گونهای تعریف شده که به ازای هر بستهی
اطالعاتی ،تعدادی رونوشــت تهیه میکند تا در صورتی که یکی از بستهها به مقصد نرسید ،از رونوشت آن
استفاده شود.
ماژول SpanDSP
ماژول ،۱ DSPکتابخانهای از پردازش سیگنالهای دیجیتالی است که بهوسیله آن میتوان تصاویر یا متنهایی
را به ســیگنال )صدا( تبدیل کــرد و پس از انتقال آنها ،مجددا ً این ســیگنالها )صداها( را به متن یا تصویر
برگرداند .از این کتابخانه استریسک میتوان برای ارسال و دریافت فکس استفاده کرد.
الزم به ذکر است که در سیستم تلفنی استریسک ،این ماژول تحت عنوان res_fax_spandsp.soوجود
دارد ،ولی استفاده از آن به الیسنس خاصی نیاز دارد .اگر در محیط کامندالین استریسک دستور زیر را اجرا
کنید ،متوجه فعالیت این ماژولها خواهید شد.
CLI> module show like res_fax
Module Description Use Count Status Support Level
res_fax.so Generic FAX Applications 1 Running core
res_fax_spandsp.so Spandsp G.711 and T.38 FAX Technologies 0 Running extended
• ماژول :res_fax_spandspبهوســیله این ماژول ،میتوان از کتابخانهی پردازش سیگنالهای دیجیتالی در
استریسک استفاده کرد تا بتوان بوق فکس را شبیهسازی نمود.
• ماژول :res_faxاز این ماژول برای ارسال و دریافت فکس در برنامهنویسی استریسک استفاده میشود .با
فعال بودن این ماژول ،دستورات زیر در برنامهنویسی استریسک قابل استفاده خواهند بود.
CLI> core show application SendFAX
][Syntax
)]SendFAX([filename2[&...]][,options
در ادامه ،مراحل نصب این ماژول در توزیعهای لینوکس توضیح داده میشوند.
;ubuntu
#apt-get install libtiff-dev
بعــد از نصــب ماژول ،spandspبرای اســتفاده از کتابخانه های آن بهوســیله ســایر ســرویسها (از جمله
استریسک) در لینوکس ،باید مسیر فایلهای کتابخانه ای آن را به مسیر فایلهای کتابخانه ای لینوکس معرفی
کنید.
#echo /usr/local/lib >> /etc/ld.so.conf.d/usrlocallib.conf
اکنون استریســک را مجــددا ً کامپایل نمایید تا اســتفاده از توابع کتابخانهای مــاژول res_fax_spandspرا
بهدســت آورید .برای این منظور به مســیر نصب فایلهای استریســک بروید و مراحل کامپایل برنامه را طی
کنید.
;source_asterick
#./configure
#make menuselect
همانطورکــه مالحظــه میکنیــد در قســمت ،Resource Modulesمــاژول فــوق بایــد بــه صــورت
[*] res_fax_spandspباشد.
شکل 6-12
چنانچه پس از نصب استریســک به محیط کامند الین استریسک وارد شوید ،میتوانید از نصب ماژول فوق
اطمینان حاصل کنید:
CLI> module show like res_fax_spandsp.so
Module Description Use Count Status Support Level
res_fax_spandsp.so Spandsp G.711 and T.38 FAX Technologies 0
Running extended
1 modules loaded
>CLI
هم اکنون در استریســک میتوانید از دستورات SendFAXو ReceiveFAXبرای ارسال و دریافت فکس
استفاده کنید.
مرجع آموزش ویپ با سافتسوئیچ استریسک 360
پس از نصب بستهها ،میتوانید با فراخوانی دستور زیر ،فایلها را از فرمت TIFFبه فرمت pdfتبدیل کنید.
#tiff2pdf filename.tiff > filename.pdf
مثال( فرض کنید در یک سیستم تلفنی ،داخلی ۹را برای دریافت فکس تعیین کردهاید .اکنون اگر فردی با
شما تماس بگیرد و کلید شماره ۹را فشار دهد ،سیستم شما آماده دریافت فکس میشود .مثال زیر را ببینید:
][form-pstn
)(exten => _X. ,1,NoOp
)(same => n,Answer
)same => n,BackGround(Welcome
)same => n,waitExten(5
)(exten => 1,1,NoOp
)(exten => 2,1,NoOp
)exten => 9,1,Goto(fax-incoming,s,1
)exten => i,1,Goto(operator,1
][fax-incoming
)exten => s,1,Verbose(3,Incoming fax
)same => n,Set(FAXDEST=/tmp
)})same => n,Set(TEMPFAX=${STRFTIME(,,%C%y%m%d%H%M
)same => n,ReceiveFax(${FAXDEST}/${ TEMPFAX }.tif
)}same => n,Verbose(3,- Fax receipt completed with status: ${FAXSTATUS
همانطورکه مالحظه میکنید فکس بهوســیله دستور ReceiveFaxدر مسیر تعیینشده ،ذخیره میشود .بعد
از دریافت فکس ،میتوان بهوسیله متغیر FAXSTATUSوضعیت آن را مشاهده کرد .توجه داشته باشید که
تا وقتی فکس دریافت نشود )یا خطایی در دریافت فکس مشاهده نشود( ،کنترل اجرای برنامه به خط بعدی
نخواهد رفت.
میتــوان بالفاصله بعــد از دریافت موفقیتآمیز فکــس ،آن را به فرمت pdfتبدیل کــرد .این عملیات
بهوسیله دستور Systemدر استریسک اجرا میشود .به مثال زیر توجه کنید:
)same => n,System (tiff2pdf ${FAXDEST}/${ TEMPFAX }.tiff > ${FAXDEST}/${ TEMPFAX }.pdf
شکل 7-12
نکتــه مهم :نرم افزار IAXModemبهتنهایی نمیتواند فکس ارســال یا دریافت کنــد .برای این کار باید از
فکس ســرور )در اینجا (HylaFAXاســتفاده کنید .به عبارت دیگر ،با استفاده از مودمهای مجازی و فکس
سرور ،میتوانید اقدام به ارسال و دریافت فکس کنید.
#cd iaxmodem-1.2.0/lib/spandsp/
#./configure
#make
#make install
#cd ..
#cd libiax2/
#./configure
#make
#make install
#cd ..
#./configure
#make
بعد از نصب ،IAXModemباید بتوانید آن را بهصورت سرویس دربیاورید .دستورات زیر را انجام دهید:
#cp iaxmodem /usr/sbin/
#cp iaxmodem.init.debian /etc/init.d/iaxmodem
#chmod 755 /etc/init.d/iaxmodem
سپس فایل iaxmodemرا از مسیر زیر باز و تغییرات الزم را وارد کنید:
#vim /etc/init.d/iaxmodem
DAEMON=/usr/sbin/iaxmodem
سپس باید به مقدار مورد نیاز ،مودم مجازی ایجاد کنیم و آنها را پیکربندی نماییم:
عالوه بر این ،برای ثبت گزارشــات و الگهای مودم مجازی ) ،(IAXModemباید یک پوشهی جدید
در مسیر الگهای سیستم بهصورت زیر ایجاد کنید:
# mkdir /var/log/iaxmodem
peername iaxmodem
secret password
cidname John Doe
cidnumber 8005551212
codec slinear
][v-fax2
deny=0.0.0.0/0.0.0.0
permit=0.0.0.0/0.0.0.0
secret=123123
transfer=no
context=incoming-fax
host=dynamic
type=friend
مرجع آموزش ویپ با سافتسوئیچ استریسک 364
port=4569
qualify=yes
disallow=all
allow=ulaw,alaw
آماده دریافتv-fax۱ فکس مجازی، گرفته شــود8۰۰۰ در تعریف باال مشــخص کردیم که اگر شــماره
. آماده دریافت فکس خواهد بودv-fax۲ فکس مجازی، گرفته شود8۰۰۱ فکس خواهد بود و اگر شماره
: نماییدreload وارد محیط کامندالین استریسک شوید و ماژول فوق را،پس از تعریف کاربران جدید
CLI> iax2 reload
CLI> iax2 show peers
Name/Username Host Mask Port Status Description
v-fax1 (null) (D) (null) (null) UNKNOWN
v-fax2 (null) (D) (null) (null) UNKNOWN
2 iax2 peers [0 online, 2 offline, 0 unmonitored]
CLI>
:این تنظیمات برای مودم مجازی دوم بهصورت زیر خواهد بود
# vim /etc/iaxmodem/iaxmodem-cfg.ttyIAXModem2
device /dev/ttyIAX2
owner uucp:uucp
mode 660
port 4570
refresh 300
365 فاکس
server 127.0.0.1
peername v-fax2
secret 123123
cidname v-fax2
cidnumber 8005551212
codec slinear
پس از انجام تغییرات الزم در هر دو فایل ،سرویس IAXModemرا مجددا ً راه اندازی نمایید.
# /etc/init.d/iaxmodem stop
# /etc/init.d/iaxmodem start
با اجرای دستور باال ،باید هر دو مودم مجازی v-fax۱و v-fax۲در استریسک رجیستر شوند.
اگر هیچیک از مودمها در استریسک رجیستر نبودند ،تنظیمات زیر را در فایل iax.confانجام دهید:
; iax.conf
calltokenoptional=127.0.0.1/255.255.255.255
requirecalltoken=no
در اینجا باید آدرس ســرور استریســک را وارد نماییم .شــما مــی توانید این آدرس را بــه صورت عمومی
0.0.0.0/0.0.0.0در نظر بگیرید.
ســپس سرویس استریسک و بعد ســرویس مودمهای مجازی را مجددا ً راهاندازی نمایید .در نهایت وضعیت
مودمهای مجازی در استریسک بهصورت زیر خواهد بود:
CLI> iax2 show peers
Name/Username Host Mask Port Status Description
v-fax1 )127.0.0.1 (D) (null) 4570 OK (1 ms
v-fax2 )127.0.0.1 (D) (null) 57121 OK (1 ms
]2 iax2 peers [2 online, 0 offline, 0 unmonitored
>CLI
تا اینجا مودمهای مجازی نصب و فعال شدند؛ اکنون برای دریافت و ارسال فکس باید فکس سرور را نصب
نمایید.
با اجرای این دستور ،هنگام نصب سؤاالتی از شما پرسیده میشود .به سؤاالت عموما پاسخ پیشفرض دهید.
یکی از این سؤاالت بهصورت زیر است:
?]Do you want to run faxaddmodem to configure another modem [yes
ازآنجاکه دو مودم مجازی وجود دارد ،با تأیید سؤال باال ،به قسمت تنظیمات فکسهای مجازی وارد شوید.
ابتدا این سؤال از شما پرسیده میشود:
?]Serial port that modem is connected to [ttyS0
ســؤال باال از شما درخواســت میکند که سریال پورت درنظرگرفتهشــده برای مودم مجازی را وارد کنید.
ازآنجاکه در تنظیمات فایلهای مودم مجازی ،ســریال پورت ها را ttyIAX1و ttyIAX2درنظر گرفتهایم؛
به سؤال فوق بهصورت زیر پاسخ دهید.
Serial port that modem is connected to [ttyS0]? ttyIAX1
پس از وارد کردن ســریال پورت مودم مجازی اول ) ،(ttyIAX1ســایر سؤاالت را نیز بهصورت پیشفرض
پاســخ دهید و دکمه Enterرا بزنید .این ســؤال برای تنظیمکردن سایر مودمهای مجازی ،تکرار خواهدشد،
بنابراین برای مودم مجازی دوم هم سریال پورت ttIAX2را بهصورت زیر وارد کنید.
Serial port that modem is connected to [ttyS0]? ttyIAX2
پس از تنظیم هر دو مودم ،چنانچه سؤال تکرار شد ،پاسخ noداده و مراحل نصب را تکمیل نمایید.
Do you want to run faxaddmodem to configure another modem [yes]? n
ِ
تنظیمات مربوط به فکسهای ساخته شده در مسیر زیر خواهند بود: با تکمیل دستور ،faxsetup
#ls /etc/hylafax/config.ttyIAX1
#ls /etc/hylafax/config.ttyIAX2
با اجرای دســتور فوق ،ســرویس فکس اجرا میشــود و دو فکس تعریف شــده در مودمهای مجازی فعال
میشوند .برای مشاهده فکسهای فعال ،دستور زیر را اجرا نمایید:
# faxstat
HylaFAX scheduler on ubuntu14: Running
Modem ttyIAX2 (+1.999.555.1212): Running and idle
Modem ttyIAX1 (+1.999.555.1212): Running and idle
# faxstat
HylaFAX scheduler on ubuntu14: Running
Modem ttyIAX2 (+1.999.555.1212): Running and idle
Modem ttyIAX1 (+1.999.555.1212): Receiving facsimile
خــوب تــا اینجا ما تنظیمات مربوط به مودمهای مجازی و ســرور فکس را انجام دادیــم .اما چنانچه تصمیم
داشتید از این طریق ،فکس دریافت کنید ،برنامه زیر را اجرا کنید:
][form-pstn
)(exten => _X. ,1,NoOp
)(same => n,Answer
)same => n,BackGround(Welcome
)same => n,waitExten(5
)(exten => 1,1,NOOP
)(exten => 2,1,NOOP
)exten => 9,1,Goto(fax-incoming,s,1
)exten => i,1,Goto(operator,1
][fax-incoming
)exten => fax,1,Verbose(3,Incoming fax
)same => n,Dial(IAX2/v-fax1,20
)same => n,Dial(IAX2/v-fax2,20
همانطورکه مالحظه میکنید ،با ارسال تماس به مودم مجازی v-fax1و ،v-fax2تماس بهوسیله آنها پاسخ
داده میشود و به دریافت فکس اقدام میکنند.
شکل 8-12
در حالت اول بهوسیله یک ،FXS ATAدستگاه فکس به شبکه VoIPمتصل شده است .در حالت دوم با یک
FXS Moduleاتصال دستگاه فکس به شبکه VoIPبرقرار گردیده است.
متأســفانه در هر دو حالت ،نتایج نمیتواند مورد قبول واقع شــوند .به دلیــل خطاهایی که این روش در
ارســال و دریافت فکس دارد ،این روش بهعنوان یک روش غیر مطمئن و غیر پایدار محسوب میشود .البته
با افزایش تعداد برگهای ارسالی فکس ) ،(Multi Pagesاثر این ناپایداری ،قابللمستر خواهدبود.
در خصــوص فعال کردن پروتکل T.38برای دســتگاه ،FXS ATAباید به تنظیمات آن رجوع کنید ) دقت
کنید ممکن اســت دســتگاه FXS ATAاز پروتکل T.38پشــتیبانی نکند ،در این صورت باید از تجهیزاتی
استفاده کنید که پروتکل T.38را پشتیبانی میکنند(.
از آنجــا کــه در DAHDIاز کدک G711اســتفاده میشــود و در این نوع کــدک ،هر 8msیکبار
1- Jitter
369 فاکس
نمونهبــرداری انجام میشــود ،مثال برای تعدیل در تغییرات ،باید نمونه بــرداری را به ۱۲برابر افزایش دهیم.
بنابراین طول بافر از 8msبه ۹۶msافزایش مییابد.
Buffer = 12(buffer)*8ms=96ms
مثال( چنانچه در سیســتم تلفنی خود داخلی ۹را برای ارســال فکس در نظر گرفته باشــید ،اگر فردی با شما
تماس بگیرد و عدد ۹را فشــار دهد ،سیســتم شما آماده ارســال یک فایل بهصورت فکس خواهد شد .مثال
زیر را ببینید:
][form-pstn
)(exten => _X. ,1,NoOp
)(same => n,Answer
)same => n,BackGround(Welcome
)same => n,waitExten(5
)(exten => 1,1,NoOp
)(exten => 2,1,NoOp
)exten => 9,1,Goto(outboundfax,s,1
)exten => i,1,Goto(operator,1
][outboundfax
)exten => s,1,NoOp(send a fax
)same => n,Wait(5
)}same => n,Set(FAXOPT(filename)=${FAXFILE
)same => n,Set(FAXOPT(ecm)=yes
)}same => n,Set(FAXOPT(headerinfo)=${FAXHEADER
)}same => n,Set(FAXOPT(localstationid)=${LOCALID
)same => n,Set(FAXOPT(maxrate)=14400
)same => n,Set(FAXOPT(minrate)=2400
)same => n,SendFAX(${FAXFILE},df
مرجع آموزش ویپ با سافتسوئیچ استریسک 370
سپس میتوانید اطالعاتی در خصوص ارسال موفق یا ناموفق فکس بهصورت زیر داشته باشید:
)})exten => h,1,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm
)}same => n,NoOp(FaxStatus : ${FAXSTATUS
)}same => n,NoOp(FaxStatusString : ${FAXSTATUSSTRING
)}same => n,NoOp(FaxError : ${FAXERROR
)}same => n,NoOp(RemoteStationID : ${REMOTESTATIONID
)}same => n,NoOp(FaxPages : ${FAXPAGES
)}same => n,NoOp(FaxBitRate : ${FAXBITRATE
)}same => n,NoOp(FaxResolution : ${FAXRESOLUTION
پارامتــر :Fax-Machineبهوســیله این پارامتر مشــخص میکنیم از کدام فکس مجازی برای ارســال فکس
میخواهیم اســتفاده کنیم .اینجا منظور فکسهای v-fax1و v-fax2اســت که ســریال پورت مجازی آنها
( ttyIAX1و )ttyIAX2است.
پارامتر :Destination-Numberبهوسیله این پارامتر شماره مقصد را مشخص میکنیم.
پارامتر :Filenameبهوسیله این پارامتر فایلی را که میخواهیم فکس کنیم ،ارسال میکنیم.
مثــال( قصد داریم از طریق مودم مجازی ، v-fax1یک فکس برای مودم مجازی v-fax2ارســال کنیم .در
این صورت باید دستور زیر را اجرا کنید .اینجا فایل /etc/passwdرا ارسال خواهید کرد .برای مشاهده این
فایل میتوانید دستور زیر را اجرا نمایید.
#cat /etc/passwd
همانطورکــه مالحظه میکنید ،یک درخواســت جدید برای ارســال فکس ) (group id 1ایجاد و ارســال
میشود .در این شرایط ،گزارشات در کامندالین استریسک بهصورت زیر خواهد بود:
>CLI
Accepting AUTHENTICATED call from 127.0.0.1:54932:
> requested format = slin,
> requested prefs = (),
> actual format = ulaw,
> host prefs = (ulaw|alaw),
> priority = mine
Executing [8001@incoming-fax:1] NoOp("IAX2/v-fax1-1172", "This is v-fax2") in new stack
Executing [8001@incoming-fax:2] Dial("IAX2/v-fax1-1172", "IAX2/v-fax2") in new stack
)Call accepted by 127.0.0.1:4570 (format ulaw
371 فاکس
Called IAX2/v-fax2
Format for call is (ulaw)
IAX2/v-fax2-14515 is ringing
IAX2/v-fax2-14515 answered IAX2/v-fax1-1172
Channel IAX2/v-fax2-14515 joined 'simple_bridge' basic-bridge <38a8e23d-74a4-4023-
b5f4-bd0440d7f72b>
Channel IAX2/v-fax1-1172 joined 'simple_bridge' basic-bridge <38a8e23d-74a4-4023-b5f4-
bd0440d7f72b>
CLI>
. فکس دریافت شده را بهصورت زیر نشان میدهد۹-۱۲ برای مثال شکل
9-12 شکل
. تبدیل کنیدpdf در صورت نیاز شما میتوانید فرمت آن را به. ذخیره شدهاستtif این فکس با فرمت
#tiff2pdf /var/spool/hylafax/recvq/fax000000003.tif > /tmp/fax000000003.pdf
مرجع آموزش ویپ با سافتسوئیچ استریسک 372
در این حالت بهوســیله دســتور ،ReceiveFaxفکس مورد نظر دریافت و در مســیر مشــخص شده ذخیره
میگردد وپس از آن با دستور tiff2pdfبه pdfتبدیل میشود.
Value Description
Enables fax detection on inbound calls. When a fax is detected, applies the
incoming faxbuffers option if it has been set and redirects the call to the fax extension
in the dialplan.
Enables fax detection on outbound calls. The dialplan is not executing on an
outbound channel. If a fax is detected, the faxbuffers option will be applied,
outgoing
and the channel will be redirected and start executing the dialplan at the fax
extension.
both Enables fax detection for both incoming and outgoing calls.
no Disables fax detection. This is the default.
1-12 جدول
sip. را در فایلfaxdetect باید پارامتر،SIPبرای تشــخیص استریســک از دریافت فکس از طریق پروتکل
. تنظیم کنید۲-۱۲ با یکی از مقادیر جدولconf
Value Description
Enables fax detection by watching the audio for a CNG tone. If a CNG tone is
cng
detected, redirects the call to the fax extension in the dialplan.
Redirects the call to the fax extension in the dialplan if a T.38 reinvite is
t.38
received.
yes Enables both cng and t38 fax detection.
no Disables fax detection. This is the default.
2-12 جدول
در این روش میتوان فکس را از طریق مودمهای مجازی نیز دریافت کرد.
][from-pstn
)(exten => _X.,1,Answer
)same => n,Wait(3 //if fax, then goto fax extension
)same => n,Playback(welcome
)same => n,Goto(IVR,s,1
همانطورکه مالحظه میکنید ،ابتدا استریســک تماس را پاســخ میدهد و برای مدتی منتظر میماند تا بوق
فکس را تشخیص دهد ،اگر بوق فکس بهوسیله استریسک تشخیص داده شد ،کنترل برنامه به اکستنشن fax
منتقل و دســتورات آن اجرا میشوند ،ولی اگر در مدت زمان مشخص شده ،بوق فکس تشخیص داده نشد،
دستورات با اولویت بعدی اجرا و به کانتکست ] [IVRمنتقل میشوند.
نتیجهگیری
امروزه علیرغم پیشــرفت تکنولوژی ،فکس هنوز هم کاربردهای ویژهای دارد .لذا سیســتمهای نسل جدید
مخابراتی باید بتوانند با این تکنولوژی ســازگاری داشــته باشند .استریسک بهعنوان یک سافت سوئیچ تلفنی
میتواند در زمینههای مختلفی این سازگاری را ایجاد نماید .در این فصل با نحوه چگونگی ایجاد یک فکس
سرور ) (Hylafaxو کاربرد آن آشنا شدید.
فصل سیزدهم
یکی از ابزارهای قدرتمند استریســک برای مانیتورینگ و مدیریت استریسک ،واسط مدیریتی AMIاست.
با اســتفاده از این ابزار میتوان رویدادهای استریسک و رفتار استریسک را بهصورت لحظهای مشاهده کرد.
این رویدادها بهشکل پیامهایی در استریسک ایجاد میشوند.
ســرویس استریسک ،یک سرویس رویدادگراست و در سیستمهای رویدادگرا ،رویدادها غالبا بهشکل
پیامهای متنی ) (Messagingهستند .استریسک برای هر فعالیتی که انجام میدهد یک رویداد ۲صادر میکند
که میتوان با گوشدادن به این رویدادها و تحلیل آنها ،رفتار استریسک را بازبینی کرد.
در استریســک رویدادهای متفاوتی داریم که هر کدام رفتار منحصر به فرد خود را دارند .در ادامه این
رویدادها بررسی میشوند.
شکل 1-13
همانطورکه مالحظه میکنید ،در این روش استریسک صرفا در حال ارسال رویدادها به کالینت ۱است )به
عبارت دیگر ،یوزر اکانت AMIدرحال گوش دادن به تمام رویدادهای استریسک است(.
شکل 2-13
در شکل ۲-۱۳یوزر اکانت ،AMIبا ایجاد یک رویداد Manager Actionو ارسال آن به سمت استریسک،
یک پاســخ Action Responseاز طرف استریســک دریافت میکند .برای مثال ،چنانچه رویداد بررســی
1- AMI-Client
مرجع آموزش ویپ با سافتسوئیچ استریسک 378
وضعیت یک اپراتور برای استریســک ارســال شود ،در پاسخ ،استریســک وضعیت اپراتور مربوطه را نشان
خواهد داد.
نوع دیگری از رویداد وجود داردکه باعث میشوند چندین پاسخ از طرف استریسک برای یوزر اکانت
ارسال شود .شکل ۳-۱۳را در نظر بگیرید.
شکل 3-13
در شکل ،۳-۱۳یوزر اکانت AMIیک درخواست برای استریسک ارسال میکند .سپس چند پاسخ از
طرف استریســک برای یوزر اکانت ارســال میشود .برای مثال چنانچه فرمان » «Active Channelبهوسیله
یوزر اکانت به سمت استریسک ارسال شود ،چون احتمال دارد بیش از یک » «Active Channelدر سیستم
موجود باشد ،استریسک رویدادهایی را برای یوزر اکانت به عنوان پاسخ برمیگرداند.
پیــش از ورود بــه بحث اصلی ،نخســت با تنظیمات اولیه ابــزار مدیریتی AMIدر استریســک و چگونگی
فعالشدن آن در استریسک آشنا شوید .در استریسک برای استفاده از ابزار مدیریتی ،AMIباید آن را فعال
کنید .برای این منظور در مسیر فایلهای پیکربندی استریسک ،فایل زیر را باز کنید:
#vim /etc/asterisk/manager.conf
همانطورکــه مالحظه میکنید ،این ابزار بهصورت پیشفرض غیرفعال اســت .بنابراین آن را بهصورت زیر
فعال کنید.
enabled = yes
با فعال کردن این ابزار در استریســک ،در همه اینترفیسهای شــبکه و در پورت ، ۵۰۳8قابلیت AMIفعال
379 ابزار مدیریتی استریسک
میشود.
درصورت لزوم میتوان برای امنیت بیشت ِر سرور استریسک ،آن را به اینترفیسهای خاصی محدود کرد
و یا پورت آن را از پورت پیشفرض تغییر داد .برای مثال چنانچه تصمیم داشــته باشــید ابزار AMIرا صرفا
روی اینترفیس لوکال در سرور استریسک فعال و پورت آن را تعویض کنید ،تنظیمات زیر را انجام دهید:
;manager.conf
][general
enabled = yes
port = 8305
bindaddr = 127.0.0.1
پس از انجام تنظیمات عمومی ،باید برای اتصال به AMIدر استریسک ،یک یوزر اکانت ایجاد کنید .برای
ساختن یوزر اکانت AMIدر استریسک ،در فایل manager.confبه شکل زیر عمل کنید:
;manager.conf
][hello
secret=world
read=all ; Receive all types of events
write=all ; Allow this user to execute all actions
اینجا یک یوزر اکانت AMIجدید بهنام helloبا پســورد worldســاختید .در قســمت پارامتر ، readمقدار
allبه این معنی است که کلیه رویدادهای مبتنی بر ، Manager Eventقابل دریافت است .در پارامتر write
مقدار allبه معنی اجرای همه رویدادهای مبتنی بر Manager Actionاست.
اکنون به محیط کامندالین استریسک بروید و دستور زیر را اجرا نمایید.
CLI> manager reload
برای نمایش همه یوزر اکانتهای استریسک ،دستور زیر را اجرا کنید.
CLI> manager show users
username
--------
hello
-------------------
1 manager users configured.
یوزر اکانت AMIجدید تعریف شــد .اکنون باید ازطریق این یوزر اکانت به استریســک متصل شوید .دو
روش برای اتصال به استریسک ازطریق یوزر اکانت وجود دارد:
AMI over TCP -۱
AMI over HTTP -۲
برای برقراری اتصال انجام میدهیم .ابتدا بهوسیله دستور telnetروی سرور استریسک به آیپی )(127.0.0.1
و پورت پیش فرض 5038متصل میشویم:
#telnet 127.0.0.1 5038
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Asterisk Call Manager/1.1
با اجرای دستور فوق ،به محیط AMIاستریسک وارد شوید و با اطالعات یوزر اکانت ،مراحل اعتبارسنجی
۱
را انجام دهید .اطالعات یوزر اکانت AMIرا وارد کنید و کلید enterرا دوبار بزنید.
Action: Login
Username: hello
Secret: world
پــس از ورود اطالعات الزم )هرکدام در ســطری جداگانه( ،درصورت صحــت اطالعات ،پیامی از طرف
استریسک مبنی بر اتصال موفق به AMIبه شما نمایش داده میشود.
Response: Success
Message: Authentication accepted
در این لحظه میتوان هر رویداد موجود در استریسک را مشاهده و بازبینی کرد .به عنوان تمرین سعی کنید
یک تماس در استریســک ایجاد کنید .کلیه رویدادهای استریســک قابل مشاهده خواهد بود .ازآنجاکه در
گزارش رویدادها هیچ فیلتری مشخص نشده است ،استریسک کلیه رویدادها را برای این یوزر اکانت ارسال
میکند.
ازآنجاکه این یوزر اکانت ،مجوز writeدارد میتوانید یک Actionخیلی ساده برای استریسک ارسال
کنید .پس از آن استریسک پاسخ رویداد را خواهد فرستاد .برای مثال فرمان زیر را در نظر بگیرید.
Action:ping
Response: Success
Ping: Pong
Timestamp: 1472378967.990017
اینجا فرمان pingازطریق یوزر اکانت AMIبرای استریســک ارســال شــده است ،و استریسک در پاسخ به
فرمان فوق ،رویداد )پاسخ( pongرا ارسال میکند.
،AMIفرمان » « logoffرا برای استریسک ارسال کنید: برای خروج از یوزر اکانت
Action:logoff
Response: Goodbye
Message: Thanks for all the fish.
Connection closed by foreign host.
AMI over HTTP
در استریسک این قابلیت وجود دارد که برای ارتباط با AMIاز پروتکل HTTPبهجای TCPاستفاده کرد.
1- Authentication
381 ابزار مدیریتی استریسک
. برای استفاده از این پروتکل تنظیمات بیشتری نیاز است.نحوه ارتباط برای هر دو روش کامال یکسان است
پارامترmanager.conf نخست در فایل، برای انجام آن.این تنظیمات در دو فایل مســتقل صورت میگیرند
.زیر را فعال کنید
;manager.conf
webenabled=yes
. میتوان از دستورات زیر استفاده نمود، HTTP برای ارتباط با یوزر اکانت از طریق
wget "http://localhost:8088/rawman?action=login&username=hello&secret=world" --save-
cookies cookies.txt -O –
آنچه در تمامی رویدادها دیده میشــود این اســت که بعد از هر key:valueبرای اجرای دســتور باید کلید
" "enterفشرده شود .برای نمونه به رویداد زیر توجه کنید:
Event: Hangup
Privilege: call,all
Channel: SIP/Phone_1-00000000
Uniqueid: 1283108164.0
CallerIDNum: 5131770
CallerIDName: 5131770
Cause: 16
Cause-txt: Normal Clearing
همانطورکه مالحظه میکنید ،هر رویداد با کلمه کلیدی Eventایجاد میشود که در ادامه نام آن را مشاهده
میکنید .نکته مهم بعدی اینکه کالس این رویداد بهوســیله پارامتر Privilegeنشــان داده میشود و این بیان
میکنــد که برای نمایش رویداد مورد نظــر ،یوزر اکانت AMIباید مجوز read=call , allرا داشتهباشــد،
درغیر اینصورت این رویداد نمایش داده نمیشود .سایر پارامترها هرکدام مقادیری را خواهند داشت.
برای مشاهده کلیه رویدادهای استریسک ،به محیط کامندالین بروید و دستور زیر را اجرا کنید:
CLI > manager show events
>CLI > manager show event <event name
با این دستور میتوانید با ساختار رویدادها )پارامترهای ورودی و خروجی( آشنا شوید و در برنامههای خود
از آن استفاده کنید .به عنوان تمرین و برای آشنایی با رویداد Hangupدستور زیر را اجرا کنید:
Cli > manager show event hangup
برای مشاهده تمامی Actionها در استریسک کافی است در محیط کامندالین استریسک دستور زیر را اجرا
کنید:
Cli > manager show commands
>Cli > manager show command <Action-name
با استفاده از این دستور شما میتوانید با ساختار Manager Actionها و پارامترهای ورودی و خروجی آن ها
آشنا شده و در برنامههای خود از آن استفاده کنید .برای مثال فرمت Action=Loginبهصورت زیر است:
Cli > manager show command Login
][Syntax
Action: Login
>[ActionID:] <value
>Username: <value
>[Secret:] <value
][Synopsis
Login Manager.
مرجع آموزش ویپ با سافتسوئیچ استریسک 386
][Description
Login Manager.
][Arguments
ActionID
ActionID for this transaction. Will be returned.
Username
Username to login with as specified in manager.conf.
Secret
Secret to login with as specified in manager.conf.
][See Also
Not available
#main function
if __name__ == "__main__":
#########################################################
# if(len(sys.argv) < 3) :
# print 'Usage : python telnet.py hostname port'
# sys.exit()
# host = sys.argv[1]
# port = int(sys.argv[2])
#########################################################
host = 'localhost'
port = 5038
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
while 1:
]socket_list = [sys.stdin, s
# Get the list sockets which are readable
)][ read_sockets, write_sockets, error_sockets = select.select(socket_list , [],
for sock in read_sockets:
#incoming message from remote server
if sock == s :
if runlevel == 0 :
runlevel = 1
;" msg = "action:login\nusername:hello\nsecret:world\r\n\n
) s.send(msg
)data = sock.recv(4096
if not data :
)(sys.exit
else :
#listen data and handle it with threading function
))t = threading.Thread(target=handler,args=(data,
)threads.append(t
)(t.start
)(t.join
#user entered a message
else :
)(msg = sys.stdin.readline
)s.send(msg
در ایــن برنامه ابتدا از طریق پروتکل TCPدر ســرور یک ارتباط ایجــاد مینماییم تا اطالعات یوزر اکانت
،AMIبرای احراز هویت در استریســک ،ارائه شــوند .اگر اطالعات درست باشــند ،برنامه وارد یک حلقه
میشــود و دائماً روی این کانکشــنِ ایجاد شــده ،در انتظار خواندن رویدادها میمانــد و بهمحض دریافت
رویدادی جدید ،یک threadایجاد میکند که وظیفهی اصلی آن تحلیل رویداد دریافتشده است و سپس
کنترل اصلی برنامه مجددا منتظر دریافت رویداد جدید میماند .تابع تحلیل رویداد )تابع (handlerبهصورت
»همزمان« شــروع به تحلیل رویدادها و اجرای دســتورات مربوطه میکند .در این تابع بر اساس نام رویداد،
توابع مربوطه فراخوانی میشوند .همانطورکه در برنامه ،مشخص ) (Boldشدهاست ،ما رویدادها را براساس
نامشان تشخیص میدهیم و توابع متفاوتی را فراخوانی میکنیم.
در این برنامه رویدادهای زیر بررسی میشوند.
رویداد :agentcalledزمانی اتفاق میافتد که تماس برای یک اپراتور به صف ارسال شود.
رویداد :agentringnoanswerزمانی اتفاق میافتد که اپراتور تماس را پاسخ ندهد.
رویداد :queuecallerabandonزمانی اتفاق میافتد که اپراتور تماس خود را رد کند.
رویداد :agentconnectزمانی اتفاق میافتد که اپراتور تماس خود را پاسخ دهد.
389 ابزار مدیریتی استریسک
رویداد :agentcompleteزمانی اتفاق میافتد که اپراتور تماس خود را با موفقیت به پایان رساند.
روال اصلی کالسها در زبانهای سطح باال برای کنترل مدیریت استریسک بهوسیله ،AMIبه همین صورت
اســت ولی کار با آنها بسیار آسانتر اســت .به عنوان تمرین فرض کنید بخواهیم برنامه باال را با کالسی در
Pythonبنویسیم .در این حالت برنامه بهصورت زیر خواهد بود.
* from asterisk.manager import
from logger import logger
import time
'HOST = 'localhost
'PORT = '5038
'USERNAME = 'hello
'SECRET = 'world
)(ami = Manager
)ami.connect(HOST, PORT
)ami.login(USERNAME, SECRET
)ami.register_event('agentcalled', event_AgentCalledEvent
)ami.register_event('agentringnoanswer', event_AgentRingNoAnswerEvent
)ami.register_event('queuecallerabandon', event_QueueCallerAbandonEvent
)ami.register_event('agentconnect', event_AgentConnectEvent
)ami.register_event('agentcomplete', event_AgentCompleteEvent
while true:
pass
اینجــا از کالس asterisk.managerدر زبــان برنامه نویســی Pythonاســتفاده کردیم .این کالس شــامل
مجموعــهای از توابع کتابخانهای اســت که به برنامهنویســان اجازه میدهد بتوانند بــه راحتی ازطریق آن به
استریسک متصل شوند و برنامههای خود را اجرا نمایند.
همانطورکه مالحظه میکنید ،در این روش کافی است پارامترهای مورد نیاز را بهصورت متغیر تعریف
کنید .ســپس از کالس Managerیک نمونه ایجاد کنید و بهوســیله تابع connectو loginبه AMIمتصل
شوید .در انتها رویدادهای الزم را بهوسیله تابع )( register_eventمشخص و دستورات الزم را اجرا کنید.
همانطورکه مالحظه میکنید در هر دو روش ،رویدادهای خاصی درنظر گرفته شد ،ولی کار با کالسها
در برنامهنویســی بســیار سادهتر اســت .اکنون چگونه میتوان از این کالسها استفاده کرد .برای این منظور
ابتدا باید بســتههای مورد نیاز را دانلود و نصب کنید .برای نصب بسته pystو استفاده از آن در برنامه نویسی
Pythonابتدا آن را از مسیر زیر دانلود کنید:
#cd /usr/src/
#svn co svn://svn.code.sf.net/p/pyst/svn/pyst/trunk pyst
پس از اجرای دســتور فوق ،کالس pystبا موفقیت در سیســتم نصب میشود و میتوان با اضافه کردن
خط زیر در در برنامه ،Pythonاز کالس pystاستفاده نمود:
* from asterisk.manager import
استفاده از سایر کالسها در سایر زبانهای برنامهنویسی نیز به همین صورت است که بررسی آنها به خواننده
واگذار میشود.
بعد از اجرای Call Filesها ،این فایلها از مسیر حذف )یا آرشیو( میشوند.
در استریســک برای اســتفاده از Call Filesها باید ماژول pbx_spoolفعال باشد .برای مشاهده وضعیت
این ماژول دستور زیر را اجرا کنید:
Cli > module show like pbx_spool.so
بهعنوان یک تمرین ساده ،برای استفاده از Call Filesهای استریسک ،ابتدا فایلی با نام sample.callایجاد و
موارد زیر را در آن کپی کنید .در این مثال از پارامتر Applicationو Dataاستفاده میکنیم.
channel : SIP/Phone_1
Application : playback
Data : demo_congrats
اینجــا به دنبال این هســتیم که ابتدا با کاربر Phone_1تماس برقرار شــود و بهمحــض برقراری تماس ،فایل
391 ابزار مدیریتی استریسک
بالفاصلــه پس از اجرای دســتور فوق ،داخلی موردنظــر )که در پارامتر channelمقــدار آن را داده بودید(
شروع به زنگ خوردن میکند .چنانچه تماس را پاسخ دهید ،فایل صوتی demo_congratsبرای شما پخش
خواهدشد.
این تمرین را میتوان به روش دیگری هم نوشت .فایل sample2.callرا ایجاد کنید و موارد زیر را در
آن کپی کنید.
channel : SIP/Phone_1
context: callfiles
extension:s
priority:1
پس از ســاختن فایل باال ،باید یک کانتکســت ] [callfilesدر فایل extensions.confبهصورت زیر ایجاد
کنید.
][callfiles
)exten => s,1,NoOp(Call Files
)same => n,Playback(demo-congrats
)(same => n,Hangup
ســپس تغییرات را ذخیره و استریســک را reloadکنید .اکنون به محض کپیشــدن فایل در مسیر مشخص
شــده ،تماس با SIP/Phone_1برقرار میشــود .اگر کاربر تماس را پاسخ دهد ،اجرای کنترل برنامه به مسیر
کانتکست میرود و دستورات باال اجرا میشوند.
همانطورکــه مالحظــه میکنید ،این یک تمرین خیلی ســاده از هر دو روش ایجــاد Call Filesها در
استریسک بهوســیله قابلیت » «Auto Dialerاست .برای ســاختن Call Filesها در استریسک ،پارامترهای
زیادی وجود دارد .در زیر این پارامترها شرح داده شدهاند:
:Channelمقصــد تمــاس خروجی را مشــخص میکند .به عبارت دیگر ،استریســک ابتــدا تالش میکند
با مقصد مشــخص شــده تماس برقــرار کند .این مقصد میتوانــد هر چیزی )از هر نــوع تکنولوژی از قبیل
) (SIP,DAHDI,IAXباشد.
:Contextزمانی که تماس با مقصد مشــخصی برقرار شــد ،اجرای برنامه از جانب این کانتکســت ادامه پیدا
میکنــد .اگر از این پارامتر اســتفاده میکنیــد ،باید پارامترهــای Extensionو Priorityرا هم مقدار دهید.
Applicationو Dataاستفاده شود ،نباید از پارامتر Contextاستفاده کنید. چنانچه از پارامترهای
مرجع آموزش ویپ با سافتسوئیچ استریسک 392
مالحظه میشود که از متغیرهایی که در Call Filesها تعریف کردهایم ،در برنامه ما استفاده شده است.
بهعنــوان یک تمرین دیگــر فرض کنید بخواهیم با خارج از مجموعه تمــاس بگیریم و پس از برقراری
تماس ،آن را به اپراتور وصل کنیم .میتوان این کار را بهوسیله Call Filesها بهصورت زیر انجام دهیم.
393 ابزار مدیریتی استریسک
بعد از اجرای دستور فوق ،استریسک شروع به ایجاد تماس با شماره داده شده از طریق کانالهای مخابراتی
PSTNمیکند .اگر تماس پاســخ داده شود ،کنترل اجرای برنامه به کانتکست ] [Callfilesرفته و دستورات
اجرا میشوند.
در فایل extensions.confچنین مقادیری داریم:
;extensions.conf
][callfiles
)exten => s,1,NoOp(Call Files
)same => n, Queue(support
)(same => n,hangup
اکنون اگر فرد مورد نظر پس از گذشــت ۳۰ثانیه تماس را پاســخ ندهد ،استریســک به مدت ۶۰ثانیه صبر
میکنــد و دوباره تمــاس ایجاد میکند و این بار هم ۳۰ثانیه منتظر پاســخ فرد مورد نظــر میماند .این کار
بهوسیله استریسک ،سهبار )تماس برای بار اول به همراه دو بار تالش مجدد( تکرار میشود.
همانطورکه مالحظه میکنید ،میتوان بهراحتی از طریق یک پایگاه دادهای ،شمارههای مورد نظر را خواند
و بهوســیله زبان برنامهنویســی phpیا pythonفایلهایی ایجاد کرد و در مســیر مشخص شده کپی نمود .در
این صورت یک برنامه Auto Dialerساخته میشود که به ازای هر شماره ،عملیات برقراری تماس را آغاز
میکند.
نکته مهم در خصوص Auto Dialerها و ماژول pbx_spoolاین است که در این ماژولها هیچ کنترلی
روی تعداد کانالهای دردســترس وجــود ندارد .برای مثال چنانچه از یک لینــک E۱که دارای ۳۰کانال
همزمان اســت ،از طریق auto-dilerبرای تماس اســتفاده کنید ،در چنین حالتی نمیتوانید بیش از ۳۰فایل
در مسیر /var/spool/asterisk/outgoingقرار دهید .با توجه به اینکه تعداد کانالهای موجود محدود است،
تماسهای اضافی بالفاصله از بین خواهند رفت.
البته روش دیگری برای تولید تماس وجود دارد که با ابزار AMIصورت میگیرد .دراین روش میتوان
تماسهایی دقیقاً مانند Call Filesها ایجاد کرد .برای تمرین تماســی را با ابزار AMIایجاد میکنیم .برنامه
مرجع آموزش ویپ با سافتسوئیچ استریسک 394
'HOST = 'localhost
'PORT = '5038
'USERNAME = 'hello
'SECRET = 'world
)(ami = Manager
)ami.connect(HOST, PORT
)ami.login(USERNAME, SECRET
'CHANNEL = 'DAHDI/g0/09151176713
'EXTEN = 's
'CONTEXT = 'callfiles
PRIORITY = 1
TIMEOUT = 30000
CALLERID = 31770
'SYNC = 'true
}'VARIABLES = {'age': '10
)(ami.logoff
)(ami.close
همانطورکــه مالحظه میکنید ،راه دیگر اســتفاده از Auto Dialerبرای برقراری تماس ،اســتفاده از AMI
اســت .بهوســیله دســتور originateمیتوان تماسهایی در استریســک ایجاد کرد .برای آشــنا شدن با این
Actionدستور زیر را اجرا کنید:
CLI > manger show command originate
در هر یک از زبانهای برنامهنویسی ،کالسهایی برای استفاده و کار با AMIطراحی شدهاند که میتوانید با
توجه به نیاز خود ،از آنها در زبانهای برنامهنویسی استفاده کنید .در این کتاب بیشتر روی زبان برنامهنویسی
Pythonتمرکز میکنیم.
نتیجهگیری
ابزار AMIدر استریســک یکی از ابزارهای مهم برای مدیریت ،کنترل و مانیتورینگ سرورهای استریسکی
است .به کمک این ابزار ،میتوان پنلهای مانیتورینگ طراحی کرد .بهعنوان مثال Flash oprator panelیا
FOPاز جمله پنلهای مدیریتیای است که بهوسیله AMIطراحی شدهاست.
فصل چهاردهم
ابزارهای برنامهنویسی
استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 396
1
ابزارهای برنامهنویسی استریسک
برنامهنویسی در استریســک ،مرکز اصلی تصمیمگیری ،کنترل و مدیریت تماسهاست .هر تماس جدیدی
که وارد سیســتم تلفنی میشــود ،بهوسیله برنامهنویسی در مســیر اجرایی قرار میگیرد .از طرف دیگر ،کلیه
تماسهای خروجی هم بهوسیله برنامهنویسی کنترل و مدیریت میشوند .نوشتن برخی برنامهها در استریسک
خیلی ساده است و با چند عبارت محاسباتی و منطقی ،میتوان تماسها را کنترل و مدیریت کرد ،ولی هدف
برخی از برنامهها در استریســک ،ایجاد برقراری تماس با شخص خاصی نیست ،بلکه هدف ،اجرای یکسری
از دستورات محاسباتی و تراکنشها با دیتابیس است.
در استریسک دو مفهوم مهم و کاربردی بهنامهای 2 AAو 3 IVRوجود دارد که در ادامه به آنها خواهیم
پرداخت.
مفهوم AA
در اغلب سیستمهای تلفنی ،سیستم پاسخگوی خودکار که به همه تماسهای ورودی اجازه میدهد مستقیماً
به شخص مورد نظر متصل شوند ،وجود دارد .به عبارت دیگر ،یک سیستم پاسخگویی خودکار ،این قابلیت
را فراهم میآورد که بر اساس یک منوی انتخاب ،افراد به مقصدهای متفاوتی مرتبط شوند .به این سیستم ها
در اصطالح AAمیگویند .این مفهوم گاهی به اشتباه IVRنامیده میشود .در طراحی منو برای AAمعموالً
از گزینههای مشابه زیر استفاده میشود.
-برای ارتباط با مدیریت عدد...؛
مثال باال یک مثال ساده. در هر مورد ارتباط با فردی خاص صورت میگیرد،همانطورکه مالحظه میکنید
. در سیستم تلفنی استریسک استAA و معمولی از طراحی
چیست؟IVR حال ممکن است این سوال مطرح شود که
مرجع آموزش ویپ با سافتسوئیچ استریسک 398
;extensions.conf
[LocalSets]
exten => 500,1,NoOp(hello-world)
same => n,Playback(hello-world)
خودAGI کافی است فایلextensions.conf در فایل. ایجاد کنیمAGI میخواهیم این برنامه را بهصورت
.را فراخوانی کنیم تا اجرای دستورات به آن فایل منتقل و دستورات آن اجرا شوند
;extensions.conf
[LocalSets]
exten => 500,1,NoOp(hello-world)
same => n,AGI(hello-world.sh)
read RESPONSE
# Say the letters of "Hello World"
echo "STREAM FILE hello-world \"\" "
read RESPONSE
exit 0
hello-world.sh به دلیل دردسترس نبودن مجوز الزم برای اجرای فایل، WARNING این بار نمایش پیام
. این فایلها مجوزهای الزم را داشته باشند، AGI باید پیش از استفاده از فایلهای، بنابراین.است
.دستور زیر را برای تغییر سطح دسترسی و مجوز دادن به فایلها در لینوکس اجرا کنید
#chmod 655 /var/lib/asterisk/agi-bin/hello-world.sh
میتوانید هر مجوزی را. دادهایمhello-world.sh ما اینجا حداقل مجوز الزم برای اجرا شدن را به فایل
. برای مثال با دستور زیر مجوز کامل به این فایل میدهیم. در نظر بگیرید،که مطلوب بدانید
#chmod 777 /var/lib/asterisk/agi-bin/hello-world.sh
. با موفقیت اجرا خواهد شدhello-world.sh فایل،اکنون اگر دوباره دستور زیر را اجرا کنید
CLI> console dial 500@LocalSets
-- Executing [500@LocalSets:1] NoOp("Console/dsp", "") in new stack
-- Executing [500@LocalSets:2] AGI("Console/dsp", "hello-world.sh") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/hello-world.sh
-- <Console/dsp> Playing 'hello-world.gsm' (escape_digits=) (sample_offset 0) (language
'en')
-- <Console/dsp>AGI Script hello-world.sh completed, returning 0
-- Executing [500@LocalSets:3] Hangup("Console/dsp", "") in new stack
<< Hangup on console >>
CLI>
نکته مهم در خصوص. استفاده کردیمAGI برای ساختن فایل۱در این مثال ما از زبان برنامهنویسی لینوکس
دارد که باید ازAGI این است که استریسک یکسری دستورات مهم برای برنامهنویسیAGI برنامهنویســی
کمی دشوارAGI این گونه استفاده از دستورات، همانطور که در مثال باال مشاهده کردید.آنها استفاده کرد
1- Shell Script
401 ابزارهای برنامهنویسی استریسک
اســت .در اکثر زبانهای برنامهنویسی سطح باال ،برای اســتفاده از دستورات ،AGIکالسی طراحی شده که
میتوانید با استفاده از آن ،کدهای خواناتری ایجاد کنید.
بهعنوان تمرین فرض کنید بخواهیم تمرین قبلی را دوباره با زبان phpبنویســیم .در این صورت باید از
کالس PHPAGIاســتفاده کنیم .در واقع این کالس از همان دســتورات مثال قبلی استفاده میکند ولی کار
با آن برای ما راحتتر است.
در این تمرین فرض کنید فایل hello-world.phpزیر را داشته باشیم:
;hello-world.php
#!/usr/bin/php -q
<?php
;)'require_once('phpagi.php
;)error_reporting(E_ALL
همانطور که مالحظه میکنید ،ابتدا فایل phpagi.phpرا که حاوی کالس برای استفاده از دستورات AGI
در زبان برنامهنویسی PHPاست ،در برنامه خود استفاده نمودیم .ابتدا دو فایل زیر را در مسیر فایلهای AGI
قرار میدهیم .این فایلها را میتوانید از اینترنت دانلود و یا از یک سرور الستیکس کپی کنید:
• phpagi.php
• phpagi-asmanager.php
سپس یک نمونه از کالس AGIمیسازیم و بهوسیله تابع ، stream_fileیک فایل صوتی مشخص را پخش
میکنیم .برای تست برنامه AGIدر محیط لینوکس ،دستور زیر را اجرا کنید:
#php /var/lib/asterisk/agi-bin/hello-world.php
این پیام نشان میدهد که باید ابزار مورد نیاز برای اجرای دستور را قبال کرده باشید .برای نصب آن ،دستور
زیر را اجرا کنید.
# apt-get install php5-cli
برنامه AGIشــروع به اجرا میکند .اینجا منظور از اجرا شــدن ،اجرای خط به خط دســتورات اســت .ابتدا
مرجع آموزش ویپ با سافتسوئیچ استریسک 402
تماس Answerمیشــود و سپس دستور Stream Fileاجرا میشود .با اینکار از صحت برنامه خود مطمئن
میشوید .حال میخواهیم از این فایل AGIدر برنامه خود استفاده کنیم.
;extensions.conf
][LocalSets
)exten => 500,1,NoOp(hello-world
)same => n,AGI(hello-world.php
اگر از طریق یک داخلی ،شماره ۵۰۰را شمارهگیری کنید ،متوجه پخش فایل صوتی خواهید شد.
>CLI
-- Executing [500@LocalSets:1] NoOp("SIP/100-00000022", "") in new stack
-- Executing [500@LocalSets:2] AGI("SIP/100-00000022", "hello-world.php") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/hello-world.php
)-- <SIP/100-00000022> Playing 'hello-world.gsm' (escape_digits=#) (sample_offset 0
)'(language 'en
-- <SIP/100-00000022>AGI Script hello-world.php completed, returning 4
'== Spawn extension (LocalSets, 500, 2) exited non-zero on 'SIP/100-00000022
>CLI
تــا اینجــا ما به ســاختن یک فایل AGIســاده پرداختیــم و مهمترین دســتورات قابل اســتفاده در AGIرا
معرفینمودیم .اکنون به این موضوع میپردازیم که چگونه یک فایل AGIفراخوانی میشود و کار میکند.
شکل 1-14
403 ابزارهای برنامهنویسی استریسک
همانطورکه مالحظه میکنید این ارتباط بهوســیله جریانهای دادهای) ۱هر دادهای که از طرف استریســک
بهسمت فایل AGIوارد شود بهصورت جریانهای داده ورودی و هر دادهای که از طرف فایل AGIبه طرف
استریســک ارسال شــود بهصورت جریان دادهای خروجی( معرفی میشــوند .ایدهی استفاده از جریانهای
دادهای stdin/stdoutدر برنامههای کاربردی ،یک تکنولوژی قدیمی محســوب میشود .بهعنوان مثال حتی
در زبانهای برنامه نویســی cیــا ،c#از جریانهای دادهای stdin/stdoutازطریق توابع کتابخانهای اســتفاده
میشود.
شکل 2-14
همانطورکــه مالحظه میکنید ،مراحل ) (۳-۲-۱در فایل AGIبرای برقراری ارتباط بین استریســک و
فایل AGIانجام میشوند .در مراحل 4و ، ۵ارتباط بین استریسک و فایل AGIبرقرار شده و اطالعات الزم
برای تبادل بین این دو ،ازطریق stdin/stdoutفراهم میشــود .مراحل ۶و 7برای پایان تماس و بازگشــت
کنترل اجرای برنامه به استریسک انجام میشود.
دستورات AGI
بهوسیله دستور زیر میتوان لیست همه دستورات AGIرا با توضیحات مربوطه مشاهده نمود:
CLI> agi show commands
جدول ۱-۱4لیست کاملی از دستورات AGIرا نشان میدهد .به کمک این دستورات و با استفاده از واسط
،AGIبرنامهنویسان میتوانند برنامههای خود را اجرا نمایند.
1-14 جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 406
نکته مهم :هنگام فراخوانی ،فایلها باید مجوزهای الزم برای اجرا را داشتهباشند.
همانطورکه مالحظه میکنید ،هنگام قطع تماس ،کنترل اجرای دستورات به اکستنشن hمنتقل و دستورات
آنجا اجرا میشــود .بــرای فایلهای AGIکه در کانالهای فیزیکی غیرفعال فراخوانی میشــوند ،باید دقت
شــودکه کانال ،دوباره Answerنشــود ،بلکه در این نوع از فایلها ،باید دستورات مورد نیاز و گزارشهای
الزم ،استخراج شوند و تماس فورا قطع گردد.
فراخوانی فایلهای AGIو ارتباط با آن ،ازطریق جریانهای دادهای stdin/stdoutبســیار ســاده اســت؛
ولی به ازای هربار فراخوانی ،یک پروســهی جدید ازسوی سرور ایجاد میشود .اجرای این روش فراخوانیِ
فایلهای AGIدر حجمهای باالی تماس ،میتواند به افت کارایی سیستم تلفنی استریسک منتهی شود .برای
جلوگیری از بروز چنین مشکالتی باید از FastAGIاستفاده کرد.
پورت پیشفرض در این روش ،پورت 4۵74اســت .در این روش میتوان ازهر پورت دلخواهی اســتفاده
نمود .همانند فراخوانی فایل AGIبهوسیله دستور AGIمیتوان پارامترهایی در زمان فراخوانی ،به سوی فایل
FastAGIارسال کرد.
فرمت زیر نحوه ارسال پارامترها را نشان میدهد:
)exten => 1234,1,AGI(agi://127.0.0.1,arg1,arg2,….
نکتــه مهــم دیگر در این روش این اســت کــه میتوان از یک ســرور دیگر برای راه انــدازی فایل AGIو
فراخوانی آن بهوســیله استریسک استفاده کرد .همچنین میتوان با بهرهگیری از 2 DNSبهجای ،IPافزایش
کارایی سیستم تلفنی را نتیجه گرفت.
از جمله مزایای استفاده از DNSبه جای IPمیتوان به موارد زیر اشاره کرد:
– ۱اختصاص چندین آیپی به یک .DNS
– ۲افزایش HAبرای سرویس اجرا شده بهوسیله فایل . AGI
– ۳اجرای سرویس فایل FastAGIروی سرورهای مختلف و ایجاد یک loadbalancingدر سطح . DNS
: به یکی از صورت های زیر است، IP بهجایDNS از طریقFastAGI شیوه فراخوانی فایل
exten => 1234,1,AGI(hagi://localhost)
exten => 1234,1,FastAGI(Mydomain.com)
برای نصب آن وارد. روی سیســتم شما نصب شده باشدPython2.7 باید نســخه،پیش از نصب این ماژول
خروجی آن بهصورت زیر، درصورت نصب موفق ماژول. شــوید و دســتور زیر را اجرا کنیدpystrix فولدر
.خواهد بود
#cd /usr/src/pystrix/
# python2.7 setup.py install
running install
running build
running build_py
running install_lib
running install_egg_info
Writing /usr/local/lib/python2.7/dist-packages/pystrix-0.9.7.egg-info
برای اســتفاده از آنها ابتدا از مســیر زیر. وجود داردFastAGI نمونه مثالهایی از،pystrix در فولدر اصلی
. را در مسیر دیگری کپی کنیدfastagi.rst فایل
# cp /usr/src/pystrix/doc/examples/fastagi.rst /root/fastagi.py
. شدهاندBold پارامترهای مهم برنامه. را باز و تغییرات زیر را اعمال کنیدfastagi.py سپس فایل
import re
import threading
import time
import pystrix
class FastAGIServer(threading.Thread):
"""
A simple thread that runs a FastAGI server forever.
"""
_fagi_server = None #The FastAGI server controlled by this thread
def __init__(self):
threading.Thread.__init__(self)
self.daemon = True
self._fagi_server = pystrix.agi.FastAGIServer()
409 ابزارهای برنامهنویسی استریسک
self._fagi_server.register_script_handler(re.compile('incoming'), self._demo_handler)
def kill(self):
self._fagi_server.shutdown()
def run(self):
self._fagi_server.serve_forever()
if __name__ == '__main__':
fastagi_core = FastAGIServer()
fastagi_core.start()
while fastagi_core.is_alive():
time.sleep(1)
fastagi_core.kill()
میتوان همه،AGI هنگام فراخوانیِ یک فایل،اگر در محیط کامندالین استریسک دستور زیر را اجرا کنید
:متغیرها را به همراه مقادیرشان مشاهده کرد
CLI> AGI set debug on
استفادهAGI میتوان از هر زبان برنامهنویسیای برای ایجاد فایلهای،همانطورکه پیشتر نیز اشاره شد
، در زبانهای برنامهنویســی مختلفframework برای مثال فهرســت کالسهای تعریف شــده بــرای.کرد
: آورده شدهاست۳-۱4 درجدول
411 ابزارهای برنامهنویسی استریسک
این برنامه به. را در یک برنامه نوبتدهی اینترنتی بررسی میکنیمAGI بخشی از فایل،بهعنوان یک تمرین
در این برنامه هر فرد میتواند انتخاب کند که آیا مایل است از مشاورهی تلفنی. نوشته شده استPHP زبان
این برنامه بیشتر. شــدهاندBold پارامترهای مهمAGI در برنامه.اســتفاده کند یا از سیســتم نوبتدهی تلفنی
.جنبه آموزشی دارد و برای اهداف کاربردی طراحی نشده است
#!/usr/bin/php -q
<?php
set_time_limit(30);
require('phpagi.php');
error_reporting(E_ALL);
$agi = CreateAGI();
WelcomeToHospital($agi);
return;
?>
<?php
function CreateAGI()
{
$agi = new AGI();
$agi->answer();
return $agi;
}
function WelcomeToHospital($agi)
{
$maxtry = 3;
$loop = 0;
do{
$agi->stream_file("record/welcometohospitalannounce");
$choose = $agi->get_data('record/chooseconsultorreservationannoun
ce', 5000, 1);
if (is_numeric($choose['result'])) {
if($choose['result'] == 1){
$result = ConsultWithDoctor($agi);
مرجع آموزش ویپ با سافتسوئیچ استریسک 412
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 2){
$result = ChooseDoctor($agi);
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 0){
$loop = 3;
break;
}else{
$loop++;
}
} else {
$loop++;
}
}while($loop < $maxtry);
$agi->stream_file("record/thank");
return;
}
function ConsultWithDoctor($agi)
{
$maxtry = 3;
$loop = 0;
do{
$choose = $agi->get_data('record/counsultwithdoctorannounce', 5000,
1);
if (is_numeric($choose['result'])) {
if($choose['result'] == 1){
$agi->stream_file("record/waiting");
$agi->exec_dial("SIP/annoucement2","09151176713");
$loop = 3;
} elseif($choose['result'] == 9){
$loop = 3;
return 9;
} else{
$loop++;
}
} else {
$loop++;
}
}while($loop < $maxtry);
413 ابزارهای برنامهنویسی استریسک
return 0;
}
function ChooseDoctor($agi)
{
$maxtry = 3;
$loop = 0;
do{
$choose = $agi->get_data('record/choosedoctorannounce', 5000, 1);
$doctorId = $choose['result'];
if (is_numeric($choose['result'])) {
if($choose['result'] == 1){
//Doctor 1
$result = Reservation($agi,$doctorId);
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 2){
//Doctor 2
$result = Reservation($agi,$doctorId);
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 3){
//Doctor 3
$result = Reservation($agi,$doctorId);
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 4){
//Doctor 4
$result = Reservation($agi,$doctorId);
if($result == 9)
$loop = 0;
else
$loop = 3;
} elseif($choose['result'] == 5){
//Doctor 5
$result = Reservation($agi,$doctorId);
if($result == 9)
$loop = 0;
else
$loop = 3;
مرجع آموزش ویپ با سافتسوئیچ استریسک 414
در فصل قبل ،از کالس pystبرای ارتباط استریســک با AMIاســتفاده شــد .اینجا نیز از همان کالس برای
ساخت فایلهای AGIاستفاده میشود .به عنوان تمرین ،برنامه سادهای که در شروع فصل آوردیم را با زبان
برنامهنویسی Pythonدوباره مینویسیم:
#!/usr/bin/env python
* from asterisk.agi import
#import Queue
)(agi=AGI
)"agi.stream_file("hello-world
)(agi.hangup
به عنوان یک مثال دیگر ،نمونه ای از برنامهنویسی AGIبه زبانهای phpو pythonرا بررسی میکنیم.
مثال( فرض کنید تصمیم داریم برنامهای بنویسیم که همه متغیرهای AGIدر آن بهکار روند .این برنامه را با
زبانهای برنامهنویسی PHPو Pythonمینویسیم.
این برنامه در زبان PHPبهصورت زیر است:
;Php, show-var.php
#!/usr/bin/php -q
<?php
;)set_time_limit(30
;)'require('phpagi.php
;)error_reporting(E_ALL
;)]"$agi->conlog($agi->request["agi_request
;)]"$agi->conlog($agi->request["agi_channel
415 ابزارهای برنامهنویسی استریسک
$agi->conlog($agi->request["agi_language"]);
$agi->conlog($agi->request["agi_uniqueid"]);
$agi->conlog($agi->request["agi_callerid"]);
$agi->conlog($agi->request["agi_dnid"]);
$agi->conlog($agi->request["agi_rdnis"]);
$agi->conlog($agi->request["agi_context"]);
$agi->conlog($agi->request["agi_extension"]);
$agi->conlog($agi->request["agi_priority"]);
$agi->conlog($agi->request["agi_enhanced"]);
$agi->conlog($agi->request["agi_accountcode"]);
$agi->conlog($agi->request["agi_network"]);
$agi->conlog($agi->request["agi_network_script"]);
agi = AGI()
agi.answer()
agi_request = agi.env['agi_request']
agi_channel = agi.env["agi_channel"]
agi_language = agi.env["agi_language"]
agi_uniqueid = agi.env["agi_uniqueid"]
agi_callerid = agi.env["agi_callerid"]
agi_dnid = agi.env["agi_dnid"]
agi_rdnis = agi.env["agi_rdnis"]
agi_context = agi.env["agi_context"]
agi_extension = agi.env["agi_extension"]
agi_priority = agi.env["agi_priority"]
agi_enhanced = agi.env["agi_enhanced"]
agi_accountcode = agi.env["agi_accountcode"]
agi_threadid = agi.env["agi_threadid"]
نتیجهگیری
ابتدای فصل ،در خصوص دو مفهوم مهم AAو IVRشرح داده شد و سپس با توجه به مفهوم IVRو طراحی
آن بهوســیله زبانهای برنامهنوسی ،با ابزار AGIآشنا شــدید .انواع فایلهای AGIو کالسهای متعددی از
آن بررســی شدند و نشان داده شــد که چگونه استریسک با فایلهای AGIارتباط برقرار میکند .دستورات
مهم AGIو استفاده از آنها در انواع زبانهای برنامهنویسی ،در این فصل از اهمیت باالیی برخوردارند .سایر
امور به تجربه برنامهنویس و تســلط وی به نوشــتن برنامهها و IVRهای هوشــمند ،بازمیگردد .در این فصل
صرفا آشنایی و نحوه استفاده از دستورات مهم برنامهنویسی AGIدر زبانهای سطح باال مورد نظر است.
فصل پانزدهم
ابزارهای RESTful
در استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 418
همانطور که در فصل دوم )معماری استریســک( درباره استریســک به تفصیل بیان شد ،ساختار استریسک
بهصورت ماژوالر طراحی شدهاست یعنی کلیه برنامهها و دستورات استریسک بهصورت ماژول به آن اضافه
شــدهاند .این قابلیت باعث میشود که اکثر توسعهدهندگان قادر باشند بهراحتی برنامههای خود را طراحی و
سپس آن را بهصورت ماژول به استریسک اضافه کنند.
اکثر برنامهها در استریسک به زبان برنامهنویسی Cنوشته شدهاست و طبعاً چنانچه توسعهدهندهای تصمیم
بگیرد برنامهای جدید برای استریسک طراحی کند ،باید بتواند این برنامه را با زبان برنامهنویسی Cپیادهسازی
کند .این کار کمی دشوار بهنظر میرسد .به همین دلیل ،در طراحی استریسک از واسطههایی برای سهولت
در برنامهنویسی استفاده میشود.
در ادامه بحث ،مهمترین واســطههای استریسک برای سهولت در برنامهنویسی و توسعهی راحتتر آن،
شرح داده میشوند.
تکنولوژی RESTful
RESTیک وب ســرویس بر پایهی معماری وب اســت .این معماری برای برنامههای تحت شــبکه طراحی
گردیدهاست .ایده اصلی ایجاد RESTاین است که بهجای استفاده از روشهای پیچیدهای همچون COR-
2
BA، 3RPC ، SOAPبــرای ارتبــاط بین نــرم افزارها و انتقال دادهها بین آنها؛ میتوان از پروتکل ســادهی
HTTPاستفادهکرد .برنامههای تحت RESTfulاز پروتکل HTTPبرای ارسال اطالعات ،خواندن اطالعات
و حذف اطالعات استفاده میکند RESTful .جایگزینی سبک و کارآمد برای مکانیزمهایی همچون RPC
و وب سرویسهایی مانند SOAP ، 4WSDLو غیره است REST .با وجود سادگی ،قابلیتهای بسیار زیادی
دارد .تقریباً هیچ سیســتمی وجود ندارد که با وب ســرویس قابل پیادهسازی باشد ،اما با معماری RESTful
اجرا نشود.
تکنولوژی WebSocket
بر طبق استاندارد RFC6455یک پروتکل ارتباطی دوطرفه بین سرور و کالینت است .در این ارتباط ،دادهها
میان ســرور و کالینت بهصورت JSONمنتقل میشــوند .در برنامهنویســی ،ARIابتدا کالینت باید ازطریق
،WebSocketبا سرور )استریسک( ارتباط برقرار کند ،سپس سرور تمام وقایع و رویدادهای خود را ازطریق
این کانکشن و بهصورت JSONبرای کالینت ارسال میکند .این رویدادها میتوانند به صورت زیر باشند:
{
"application": "hello-world",
"args": [],
{ "channel":
"accountcode": "",
{ "caller":
"name": "100",
""number": "100
},
{ "connected":
"name": "",
"" "number":
},
"creationtime": "2016-09-13T21:25:21.027+0430",
{ "dialplan":
"context": "LocalSets",
"exten": "1000",
"priority": 3
},
"id": "1473785721.135",
"language": "en",
"name": "SIP/100-00000010",
""state": "Up
},
"timestamp": "2016-09-13T21:25:21.085+0430",
""type": "StasisStart
}
Stasis
بــا این مکانیزم ،استریســک میتوانــد روال مدیریتی و کنتــرل تماسها را به یک برنامــه ARIانتقال دهد.
در ادامــه با Stasisآشــنایی بیشــتری خواهید یافت .به عنــوان تمرین ،برای فراخوانی یــک برنامه ARIدر
421 ابزارهای RESTfulدر استریسک
برای ایجاد یک اکانت جدید و اتصال کالینت ،اطالعات زیر را وارد نمایید:
][hello
type = user
read_only = no
password = world
ازآنجاکه برای اجرا شــدن برنامههای ARIو انتقال دادهها ،بایــد بتوان ابتدا از طریق WebSocketو اکانت
ایجاد شده ،به استریسک متصل شد ،چند نمونه از این روشها را در ادامه بررسی میکنیم.
استفاده از wscat
wscatیکی از سادهترین روشها برای بررسی و درستی تنظیمات پیکربندی است .برای این منظور باید آن
را نصب کنید .برای نصب wscatدستورات زیر را اجرا کنید:
# npm install -g wscat
مرجع آموزش ویپ با سافتسوئیچ استریسک 422
در. ایجاد میشودWebSocket ارتباط با استریسک از طریق،همانطورکه مالحظه میکنید با اجرای دستور
: این پیام نمایش داده خواهد شد،محیط کامندالین استریسک
CLI>
Activating Stasis app 'hello-world'
== WebSocket connection from '127.0.0.1:49512' for protocol '' accepted using version '13'
Activating Stasis app 'hello-world'
CLI>
import json
import sys
import websocket
423 در استریسکRESTful ابزارهای
import threading
import Queue
import requests
class ARIInterface(object):
def __init__(self, server_addr, username, password):
self._req_base = "http://%s:8088/ari/" % server_addr
self._username = username
self._password = password
class ARISample(object):
def __init__(self, server_addr):
app_name = 'hello-world'
username = 'hello'
password = 'world'
url = "ws://%s:8088/ari/events?app=%s&api_key=%s:%s" % (server_addr, app_name,
username, password)
ari = ARIInterface(server_addr, username, password)
ws = websocket.create_connection(url)
if __name__ == "__main__":
app = ARIApp('localhost')
شما می توانید آن را با آدرس. در نظر گرفته شده استlocalhost در اینجا آدرس ســرور استریســک:نکته
.سیستم تلفنی استریسک خود جایگزین نمایید
در اینجــا خروجی زیر را به. را شــمارهگیری کنید۱۰۰۰ شــماره، با یک تلفن،اکنــون برای اجرای برنامه
.تفکیک خواهیم داشت
: خروجی در کامندالین استریسک-
CLI>
== Using SIP RTP CoS mark 5
مرجع آموزش ویپ با سافتسوئیچ استریسک 424
• :POSTبرای ایجاد یک مدل جدید از این متد اســتفاده میشود .با فراخوانی این متد در ،REST APIیک
مدل جدید و مشخصشدهای ایجاد میشود.
• :DELETEبرای حذف یک مدل از این متد اســتفاده میشــود .با فراخوانی این متد در ،REST APIیک
مدل حذف میشود.
• :PUTبــرای آپدیتکــردن اطالعات یک مدل اســتفاده میشــود .با فراخوانی این متــد در ،REST API
اطالعات یک مدل آپدیت میشود.
تا اینجا ارتباط برنامه ما از طریق WebSocketبا استریســک برقرار شــد و برنامه ARIهم فعال اســت.
اکنون از طریق RESTfulو WebSocketبه استریسک فرمان میدهیم تا یک فایل را پخش کند .این فرآیند
میتواند درون خود برنامه ARIاجرا شود .اینجا ما یک روش ساده )استفاده از (curlرا بررسی میکنیم.
توجه داشــته باشید که باید بهجای ،CHANNEL-IDیک مقدار برای هر کانال جایگزین کنید .برای کانال
ایجاد شده در مثال قبل ،دستور بهصورت زیر باید اجرا شود.
#curl -v -u hello:world -X POST http://localhost:8088/ari/channels/1473797662.191/
play?media=sound:hello-world
با اجرای دســتور بــاال ،فایل صوتــی hello-worldبرای کاربر پخش خواهد شــد .خروجــی این اجرا در
کامندالین استریسک و رویدادهای دریافت شده از طریق WebSocketدر برنامه ARIبهصورت زیر است:
-خروجی در کامندالین استریسک:
>CLI
)'-- <SIP/100-00000015> Playing 'hello-world.gsm' (language 'en
>CLI
"language": "en",
""state": "playing
},
""application": "hello-world
}
{<
"type": "PlaybackFinished",
{ "playback":
"id": "9769c8c6-7864-442c-9863-18bacfe49d5f",
"media_uri": "sound:hello-world",
"target_uri": "channel:1473797662.191",
"language": "en",
""state": "done
},
""application": "hello-world
}
توجه داشــته باشید که نوع فراخوانی RESTfulاســت .میتوانید از همین الگو در برنامههای ARIاستفاده
کنید.
شکل 1-15
427 ابزارهای RESTfulدر استریسک
همانطورکه در شــکل مالحظه میکنید ،نوع ارســال دســتور بهصورت POSTمشخص شدهاست .در
قســمت Paramsدادههای مورد نیاز و از قســمت Autorizationاطالعات نام کاربری و رمز عبور را وارد
میکنیم .سپس درصورتیکه ارتباط WebSocketبرقرار باشد ،فایل صوتی hello-worldپخش خواهد شد.
تا اینجا ســاختار مهم برنامهنویســی ARIخیلی ساده شرح داده شد .در ادامه درباره ساختار برنامهنویسی
ARIتوضیحات بیشتری خواهد آمد.
بــرای مثال مدل AsteriskInfoرا بررســی میکنیم .هــدف از طراحی این مدل آمادهســازی اطالعاتی در
خصوص سیستم تلفنی استریسک در قالب مدل است .این مدل بهصورت زیر تعریف میشود:
{
مرجع آموزش ویپ با سافتسوئیچ استریسک 428
"properties": {
"status": {
"required": false,
"type": "StatusInfo",
"description": "Info about Asterisk status"
},
"config": {
"required": false,
"type": "ConfigInfo",
"description": "Info about Asterisk configuration"
},
"build": {
"required": false,
"type": "BuildInfo",
"description": "Info about how Asterisk was built"
},
"system": {
"required": false,
"type": "SystemInfo",
"description": "Info about the system running Asterisk"
}
},
"id": "AsteriskInfo",
"description": "Asterisk system information"
}
: از چهار مدل دیگر نیز استفاده شدAsterisk Info همانطورکه مالحظه میکنید در تعریف مدل
last_relaod_ سرویس استریسک و وضعیتstartup_time بهوسیله این مدل وضعیت:StatusInfo • مدل
: بهصورت زیر ارائه شوند، برای مثال این اطالعات میتواند ازطریق مدل. استریسک مشخص میشودtime
"status": {
"startup_time": "2016-09-14T01:26:36.408+0430",
"last_reload_time": "2016-09-14T01:26:36.408+0430" }
اطالعاتی در خصوص پیکربندی و تنظیمات استریســک تعیین، بهوســیله این مــدل:ConfigInfo • مدل
. برای مثال مدل زیر پیکربندی سیستم تلفنی استریسک را نشان میدهد.میشود
"config": {
"name": "",
"default_language": "en",
"setid": {
"user": "",
"group": ""
},
"max_channels": 10
},
429 در استریسکRESTful ابزارهای
دیده میشود که اطالعاتی در خصوص نامکاربری و نام گروهی که مجوزSetId اینجا یک مدل دیگر بنام
. مشخص میکند،اجرای استریسک دارند
زمان و تاریخ نصب استریسک، کرنل، این مدل اطالعاتی در خصوص نســخه لینوکس:BuildInfo • مدل
.را نشان میدهد
"build": {
"os": "Linux",
"kernel": "3.19.0-25-generic",
"machine": "x86_64",
"options": "LOADABLE_MODULES, OPTIONAL_API",
"date": "2016-08-21 09:13:09 UTC",
"user": "root"
},
. این مدل اطالعاتی در خصوص نسخه نصب شده استریسک را نشان میدهد:SystemInfo • مدل
"system": {
"version": "13.10.0",
"entity_id": "00:0c:29:f1:95:8e"
},
1-15 جدول
431 ابزارهای RESTfulدر استریسک
پیشتــر هم توضیح داده شــد یک برنامــه ARIاز طریق ، WebSocketدادهها را از استریســک دریافت و
درخواستهای خود را بهصورت RESTfulبه سمت استریسک ارسال میکند )شکل .(۲-۱۵
شکل 2-15
نکته مهم در انواع فراخوانیها بهصورت ،RESTfulآدرس محل مورد اســتفاده اســت که همانطورکه در
فراخوانی با دستور curlیا افزونه Postmanگفته شد ،آدرس فراخوانی بهصورت زیر است:
http://IP-ADDRESS:8088/ari/
در ادامه در خصوص انواع REST APIها در استریسک مطالبی ذکر خواهد شد .در راهنمای استفاده از هر
، REST APIنوع متد مورد استفاده مشخص شده است.
به عنوان تمرین فرض کنید برای فراخوانی متد Infoبهصورت زیر عمل کنیم.
"#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/asterisk/info
بــا فراخوانی ایــن ،RESTfulخروجی زیر بهصــورت مــدل دادهای AsteriskInfoاز طریق WebSocket
دریافت میشود.
{
{ "build":
"os": "Linux",
"kernel": "3.19.0-25-generic",
"machine": "x86_64",
"options": "LOADABLE_MODULES, OPTIONAL_API",
مرجع آموزش ویپ با سافتسوئیچ استریسک 432
"variable?variable=CONSOLE
درواقع بهوســیله این نوع فراخوانی ،مقدار متغیر سراســری CONSOLEدر استریســک را میتوان خواند.
مقدار هر متغیر سراسری را که در برنامه ARIبه آن نیاز داشته باشید ،با این روش میتوانید بخوانید.
باال بهصورت مدل زیرRESTful خروجی، تماس بگیرد و با هم صحبت کنند۱۰۱ با کاربر۱۰۰اگــر کاربر
: دریافت میشودWebSocket از طریق
[
{
"id": "99af098c-44d2-4038-a9c4-a00203f4da12",
"technology": "simple_bridge",
"bridge_type": "mixing",
"bridge_class": "basic",
"creator": "",
"name": "",
"channels": [
"1473808263.43",
"1473808263.40"
]
}
]
را بهصورت زیر فراخوانیchannels مثال برای گرفتن لیســت کلیه کانالهای فعال در استریســک باید متد
:کنید
#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/channels"
435 در استریسکRESTful ابزارهای
: بهصورت زیر است، در صورتی که کانال فعال در استریسک وجود داشته باشدRESTful خروجی
[
{
"id": "1473809017.84",
"name": "SIP/100-0000000a",
"state": "Up",
"caller": {
"name": "100",
"number": "100"
},
"connected": {
"name": "",
"number": ""
},
"accountcode": "",
"dialplan": {
"context": "LocalSets",
"exten": "1000",
"priority": 3
},
"creationtime": "2016-09-14T03:53:37.048+0430",
"language": "en"
}
]
. را بهصورت زیر فراخوانی کنیدEndpoints REST باید،برای مثال جهت گرفتن لیست همه کاربران
#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/endpoints"
مرجع آموزش ویپ با سافتسوئیچ استریسک 436
در این خروجی همه داخلیهای تعریف شــده در استریسک نشان. بهصورت زیر اســتRESTful خروجی
.داده میشوند
[
{
"technology": "SIP",
"resource": "100",
"state": "online",
"channel_ids": []
},
{
"technology": "SIP",
"resource": "101",
"state": "online",
"channel_ids": []
},
{
"technology": "IAX2",
"resource": "demo",
"state": "unknown",
"channel_ids": []
},
{
"technology": "SIP",
"resource": "op100",
"state": "unknown",
"channel_ids": []
},
{
"technology": "SIP",
"resource": "op101",
"state": "unknown",
"channel_ids": []
},
{
"technology": "SIP",
"resource": "op102",
"state": "unknown",
"channel_ids": []
}
]
برای مثال با فراخوانی. در استریسک استفاده میشودRecording ها غالبا برای مدیریت و کنترلAPI از این
. فهرست همه فایلهای رکورد شده نمایش داده میشود، storedمتد
#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/recordings/stored"
مرجع آموزش ویپ با سافتسوئیچ استریسک 438
را بهصورت زیر فراخوانیsounds باید متد،مثال برای مشــاهده فهرست همه فایلهای صوتی در استریسک
:کنید
#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/sounds"
. قسمتی از خروجی را نمایش میدهیم، طوالنی استREST API چون خروجی این
[
{
"id": "vm-review",
"text": "press 1 to accept this recording press 2 to listen to it press 3 to rerecord your
message",
"formats": [
{
"language": "en",
"format": "gsm"
}
]
},
{
"id": "vm-nomore",
"text": "No more messages.",
"formats": [
{
"language": "en",
"format": "gsm"
}
]
},
{
"id": "conf-now-unmuted",
"text": "The conference is now unmuted.",
"formats": [
{
"language": "en",
"format": "gsm"
439 در استریسکRESTful ابزارهای
}
]
},
{
"id": "enter-num-blacklist",
"text": "Please enter the number to be blacklisted.",
"formats": [
{
"language": "en",
"format": "gsm"
}
]
}
]
. همه فایلهای صوتی یک به یک بهصورت مدل نمایش داده میشوند،همانطورکه مالحظه میکنید
. در استریسک نمایش داده میشودARI فهرست برنامه های، زیرApplications به عنوان مثال با متد
#curl -X GET -u hello:world "http://IP-ADDRESS:8088/ari/applications"
نشــانARI فایلهای صوتیِ در حال اجرا در برنامهی، بهصورت زیرPlayback بــرای مثال با فراخوانی متد
. را وارد کنیدplaybackId باید،REST API هنگام استفاده از این.داده میشوند
#curl -X GET -u hello:world "http:// IP-ADDRESS:8088/ari/playbacks/6597563f-cb8d-4c3b-
96ad-0683dbf91819"
با اجرای متد. ایجاد کنیمREST API جدید بهوســیلهDevicestates بــرای مثال فرض کنید بخواهیم یک
. ایجاد میکنیمStasis:mystate جدید بهنامDeviceStates یک، DeviceStates
441 ابزارهای RESTfulدر استریسک
همچنین میتوان با استفاده از متد DeviceStatesزیر ،وضعیت انواع Devicestatesها را مشاهده کرد.
#curl -X GET -u hello:world "http:// IP-ADDRESS:8088/ari/devicestates
نتیجه گیری
در شــروع فصل در خصوص تکنیکهای انتقال دادهها بین ســرویسهای مختلف مطالبی ذکر شــد ،سپس
بیان شــد که ابزار ARIاین بســتر را برای ما فراهم میکند که بتوانیم از طریق WebSocketو RESTfulو
تکنولوژیهای وابسته ،با استریسک ارتباط برقرار کنیم .برنامهنویسی ARIدر استریسک این قابلیت را برای
مــا فراهم میآورد که بتوانیم از قابلیتهای برنامهنویســی AGIو AMIبا هــم و در کنار هم ،اما بهصورت
سادهتر استفاده کنیم .هدف این فصل ،آشنایی با سبک نوشتن برنامه نویسی ARIدر استریسک بود و چون
این روش برنامهنویســی در استریسک نسبتاً جدید اســت برای دریافت آخرین تغییرات و اطالعات بیشتر به
آدرس زیر مراجعه کنید:
https://wiki.asterisk.org/wiki/display/AST/Getting+Started+with+ARI
مرجع آموزش ویپ با سافتسوئیچ استریسک 442
فصل شانزدهم
مقدمه
در فصل دوم )معماری استریســک( شرح داده شــد که به واسطه ماژولهای Channel Driversمیتوان از
پروتکلهای مختلفی برای ایجاد تماس در استریســک اســتفاده کرد .به عنــوان مثال میتوان ماژولهایی از
قبیل chan_sip ، chan_iax ، chan_H323و غیره را نام برد که هر کدام قابلیتهایی دارند و ویژگیهایی
را به استریسک اضافه میکنند.
در نسخههای جدیدتر استریسک ) نسخه ۱۲به بعد( ،یک ماژول به نام res_pjsipاضافه شده است .هدف
و کاربرد اصلی این ماژول ،اضافه کردن قابلیت پروتکل SIPدر استریسک است .شاید این سوال مطرح شود
که این پروتکل بهوســیله ماژول chan_sipدر استریســک وجود دارد ،بنابراین طراحی و اضافهشدن ماژول
جدید res_pjsipچه دلیلی دارد؟
درباره pjsip
pjsipیک کتابخانه برای انتقال دادههای رســانهای اســت که از پروتکلهای SIP ، SDPو RTPپشــتیبانی
میکند .این پروتکل بهوســیله شرکت Teluu.Ltdطراحی شده است .ازآنجاکه این کتابخانه رایگان است،
میتوانید از آن در طراحی نرمافزارهای رسانهای استفاده کنید.
445 استفاده از ماژول PJSIPدر استریسک
در این روش ممکن است دستور snvدر سیستم لینوکس نصب نشده باشد .با استفاده از دستور زیر ابتدا آن
را نصب کنید.
;RHEL
yum install subversion
;ubuntu
apt-get install subversion
در این روش ممکن اســت دســتور gitدر سیستم لینوکس نصب نشده باشد .با استفاده از دستور زیر ابتدا آن
را نصب کنید.
;RHEL
yum install git
;ubuntu
apt-get install git
مرجع آموزش ویپ با سافتسوئیچ استریسک 446
: شده و دستورات زیر را اجرا کنیدpjproject وارد فولدر، pjsip بعد از دانلود
#cd pjproject
#./configure --prefix=/usr --enable-shared --disable-sound --disable-resample --disable-video
--disable-opencore-amr CFLAGS='-O2 -DNDEBUG'
خروجی. را بررســی نمودpjsip با اســتفاده از دســتورات زیر میتوان صحــت نصبpjsip بعــد از نصب
:دستورات مانند زیر خواهد بود
#ldconfig
#ldconfig -p | grep pj
libpjsua2.so.2 (libc6,x86-64) => /usr/local/lib/libpjsua2.so.2
libpjsua2.so (libc6,x86-64) => /usr/local/lib/libpjsua2.so
libpjsua.so.2 (libc6,x86-64) => /usr/local/lib/libpjsua.so.2
libpjsua.so (libc6,x86-64) => /usr/local/lib/libpjsua.so
libpjsip.so.2 (libc6,x86-64) => /usr/local/lib/libpjsip.so.2
libpjsip.so (libc6,x86-64) => /usr/local/lib/libpjsip.so
libpjsip-ua.so.2 (libc6,x86-64) => /usr/local/lib/libpjsip-ua.so.2
libpjsip-ua.so (libc6,x86-64) => /usr/local/lib/libpjsip-ua.so
libpjsip-simple.so.2 (libc6,x86-64) => /usr/local/lib/libpjsip-simple.so.2
libpjsip-simple.so (libc6,x86-64) => /usr/local/lib/libpjsip-simple.so
libpjnath.so.2 (libc6,x86-64) => /usr/local/lib/libpjnath.so.2
libpjnath.so (libc6,x86-64) => /usr/local/lib/libpjnath.so
libpjmedia.so.2 (libc6,x86-64) => /usr/local/lib/libpjmedia.so.2
libpjmedia.so (libc6,x86-64) => /usr/local/lib/libpjmedia.so
libpjmedia-videodev.so.2 (libc6,x86-64) => /usr/local/lib/libpjmedia-videodev.so.2
libpjmedia-videodev.so (libc6,x86-64) => /usr/local/lib/libpjmedia-videodev.so
libpjmedia-codec.so.2 (libc6,x86-64) => /usr/local/lib/libpjmedia-codec.so.2
libpjmedia-codec.so (libc6,x86-64) => /usr/local/lib/libpjmedia-codec.so
libpjmedia-audiodev.so.2 (libc6,x86-64) => /usr/local/lib/libpjmedia-audiodev.so.2
libpjmedia-audiodev.so (libc6,x86-64) => /usr/local/lib/libpjmedia-audiodev.so
libpjlib-util.so.2 (libc6,x86-64) => /usr/local/lib/libpjlib-util.so.2
libpjlib-util.so (libc6,x86-64) => /usr/local/lib/libpjlib-util.so
libpj.so.2 (libc6,x86-64) => /usr/local/lib/libpj.so.2
libpj.so (libc6,x86-64) => /usr/local/lib/libpj.so
برای این منظور به فولدرنصب استریسک بروید. استریســک باید مجددا ً کامپایل شود، pjsip پس از نصب
:و دستور زیر را اجرا کنید
#./configure
اطمینانmake menuselect ابتدا بهوسیله دســتور،بعد از اجرای دســتور و قبل از نصب مجدد استریســک
: به درستی نصب و بهوسیله استریسک شناخته شده باشدpjsip حاصل کنید که ماژول
#make menuselect
447 استفاده از ماژول PJSIPدر استریسک
شکل 1-16
بعد از ویرایش فایل مدیریت و پیکربندی ماژولها ،باید استریسک را مجددا ً راهاندازی نمایید.
# /etc/init.d/asterisk restart
بــا فعال کردن ماژول ، pjsipمیتــوان از طریق فایل ،pjsip.confماژول pjsipرا پیکربندی کرد .ازآنجاکه
ماژول chan_sip.soغیرفعال شــده اســت ،نمیتوان برای تعریف کاربران جدید از فایل sip.confاستفاده
نمود .با توجه به اینکه فرمت و نوع پیکربندی این دو ماژول ) chan_sipو (pjsipبا هم متفاوت اســت ،ابتدا
باید با ساختار و نوع پیکربندی فایل pjsip.confآشنا شوید.
ابتدا برای آشــنایی اولیه با ســاختار فایل ،pjsip.confمثالهایی از پیکربندیهای یکسان در هر دو فایل
را نشان خواهیم داد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 448
[6001]
type=friend
host=dynamic
disallow=all
allow=ulaw
context=internal
secret=1234
[6002]
type=friend
host=192.0.2.1
disallow=all
allow=ulaw
context=internal
secret=1234
[6001]
type = endpoint
transport = simpletrans
context = internal
disallow = all
allow = ulaw
aors = 6001
auth = auth6001
[6001]
type = aor
max_contacts = 1
[auth6001]
type=auth
449 در استریسکPJSIP استفاده از ماژول
auth_type=userpass
password=1234
username=6001
[6002]
type = endpoint
transport = simpletrans
context = internal
disallow = all
allow = ulaw
aors = 6002
auth = auth6002
[6002]
type = aor
contact = sip:6002@192.0.2.1:5060
[auth6002]
type=auth
auth_type=userpass
password=1234
username=6001
[MyTrunk]
type=friend
secret=1234567890
username=myaccountname
host=203.0.113.1
disallow=all
allow=ulaw
context=from-external
protocol=udp
bind=0.0.0.0
[MyTrunk]
type=registration
transport=simpletrans
outbound_auth=mytrunk
server_uri=sip:myaccountname@203.0.113.1:5060
client_uri=sip:myaccountname@192.0.2.1:5060
[MyTrunk]
type=auth
auth_type=userpass
password=1234567890
username=myaccountname
[MyTrunk]
type=aor
contact=sip:203.0.113.1:5060
[MyTrunk]
type=endpoint
transport=simpletrans
context=from-external
disallow=all
allow=ulaw
outbound_auth=mytrunk
aors=mytrunk
[MyTrunk]
type=identify
endpoint=mytrunk
match=203.0.113.1
ولی جای هیچ گونه نگرانی، کمی دشوار به نظر برسدpjsip شــاید این تفاوت در ســاختار پیکربندی ماژول
تبدیلpjsip.conf را بهsip.conf در استریسک اسکریپتی وجود دارد که پیکربندی و تنظیمات فایل.نیست
: فایل در مسیر زیر قرار دارد.میکند
# /path/to/asterisk/source/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py --help
Usage: sip_to_pjsip.py [options] [input-file [output-file]]
input-file defaults to 'sip.conf'
output-file defaults to 'pjsip.conf'
Options:
-h, --help show this help message and exit
-p PREFIX, --prefix=PREFIX
451 در استریسکPJSIP استفاده از ماژول
با تنظیماتsip_user.conf فرض کنید فایلی به نام. مثالی را بررســی میکنیم،برای روشــنتر شــدن مطلب
:زیر داشتهباشیم
;sip_user.conf
[user](!)
qualify=yes
host=dynamic
nat=force_rport,comedia
port=5060
type=friend
context=python_agi
disallow=all
allow=ulaw,alaw
canreinvite=no
directmedia=no
callcounter=yes
permit=0.0.0.0/0.0.0.0
deny=0.0.0.0/0.0.0.0
[Phone_1](user)
secret=123123
context=LocalSets
[Phone_2](user)
secret=123123
context=LocalSets
pjsip ایجاد خواهدشــد که معادل تنظیمات ماژولpjsip_user.conf فایلی با نام،با اســتفاده از دســتور زیر
:خواهد بود
#cd /usr/src/asterisk-13.10.0/contrib/scripts/sip_to_pjsip/
#python sip_to_pjsip.py /etc/asterisk/sip_user.conf /etc/asterisk/pjsip_user.conf
Reading /etc/asterisk/sip_user.conf
Converting to PJSIP...
Writing /etc/asterisk/pjsip_user.conf
pjsip.conf برای این منظور فایل. اضافه کنیدpjsip.conf را به فایل اصلیpjsip_user.conf اکنون باید فایل
: فایل جدید را اضافه کنید،را باز و در انتهای آن
;pjsip.conf
#include pjsip_user.conf
pjsip. را به پیکربندی فایلsip.conf این اســکریپت میتواند پیکربندیهای فایل،با توجه به توضیحات باال
: بهصورت زیر خواهد بودpjsip_user.conf محتویات فایل. تبدیل و از آن استفاده کندconf
;pjsip_user.conf
مرجع آموزش ویپ با سافتسوئیچ استریسک 452
[transport-udp]
type = transport
protocol = udp
bind =
[Phone_1]
type = aor
max_contacts = 1
[Phone_1]
type = auth
username = Phone_1
password = 123123
[Phone_1]
type = endpoint
context = LocalSets
disallow = all
allow = ulaw,alaw
rtp_symmetric = yes
force_rport = yes
rewrite_contact = yes
direct_media = no
auth = Phone_1
outbound_auth = Phone_1
aors = Phone_1
[acl]
type = acl
deny = 0.0.0.0/0.0.0.0
permit = 0.0.0.0/0.0.0.0
[Phone_2]
type = aor
max_contacts = 1
[Phone_2]
type = auth
username = Phone_2
password = 123123
[Phone_2]
type = endpoint
context = LocalSets
disallow = all
allow = ulaw,alaw
453 استفاده از ماژول PJSIPدر استریسک
rtp_symmetric = yes
force_rport = yes
rewrite_contact = yes
direct_media = no
auth = Phone_2
outbound_auth = Phone_2
aors = Phone_2
برای مثال با اجرای دستور زیر ،کاربرهای Phone_1و Phone_2نشان داده میشوند:
همانطورکه مالحظه میکنید استفاده از ماژول pjsipدر برنامهنویسی استریسک ،هیچ فرقی با سایر Channel
Driveها )از قبیل (… ,SIP,DAHDI,IAXندارد.
در ادامه درباره پیکربندی فایل pjsip.confبیشتر شرح خواهیم داد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 454
در هر بخش پارامتری بنام typeوجود دارد که مشــخصکننده نوع بخش و پارامترهای وابسته به پیکربندی
است .در ادامه به بررسی انواع مقادیر پارامتر typeمیپردازیم.
• :Endpointدر حالت پیشفرض ،اگر تصمیم داشــته باشــیم یک کاربر از نوع پروتکل SIPتعریف کنیم،
باید از مقدار type=endpointاســتفاده کنیم .در این حالت کاربر به عنوان یک عضو جدید در استریســک
درنظر گرفته میشــود (این روش همانند تعریف یک کاربر معمولی در فایل sip.confبا مقدار type=friend
است).
][6001
type=endpoint
context=internal
disallow=all
allow=ulaw
transport=simpletrans
auth=auth6001
aors=6001
• :Transportمیتوان نحوهی انتقال بستهها را برای یک کاربر خاص ،با پارامتر Transportمشخص کرد.
در این صورت پارامترهای این بخش ،معرفیکنندهی نوع پروتکل ارتباطی هســتند .میتوان از پروتکلهای
TCP،UDPو TLSبرای این بخش اســتفاده نمود .بهعنوان مثال چنانچه یک بخش جدید ایجاد و در آن از
پروتکل ارتباطی UDPاستفاده کنیم ،داریم:
][transport-udp
type=transport
protocol=udp
bind=0.0.0.0
• :AUTHاین بخش پارامترهای مرتبط با اعتبارسنجی تماسهای ورودی و خروجی را نگهداری میکند .در
این بخش ،اعتبارسنجی تماسهای ورودی و خروجی مرتبط با یک کاربر میتواند براساس IPو یا براساس
نام کاربری و رمز عبور (یا هر دو) صورت گیرد .به مثال زیر توجه کنید.
][auth6001
type=auth
auth_type=userpass
455 استفاده از ماژول PJSIPدر استریسک
password=6001
username=6001
چنانچه بخواهیم کلمه عبور را بهصورت MD5ذخیره کنیم ،در این صورت خواهیم داشت:
][auth6001
type=auth
auth_type=md5
md5_cred=51e63a3da6425a39aecc045ec45f1ae8
username=6001
همانطورکه مالحظه میکنید در این مثال ،اعتبارسنجی براساس الگوریتم MD5مشخص میشود.
• :AORعبارت Address Of Recordبیانگر آدرس کاربر در شــبکه اســت که بهوسیله آن به سیستم تلفنی
استریســک رجیســتر شــده اســت .به عبارت دیگر AOR ،معرف آدرس آیپی یک کاربر است که سرور
استریســک در صورت نیاز ،از طریق آن به کاربر دسترســی خواهد داشــت .بدون ،AORدسترسی به کاربر
امکانپذیر نیست .هنگام رجیستر شدن یک کاربر ،اطالعات AORبرای کاربر در استریسک ذخیره میگردد.
مثالهایی از کاربر AORدر نمونه زیر آمده است:
][6001
type=aor
max_contacts=1
در این نمونه ،رجیســتر شــدن داخلی ۶۰۰۱به یک دیوایس محدود شده اســت)در اینجا منظور از دیوایس
همان SIPPhoneمی باشــد( ،یعنــی در هر لحظه فقط یک AORبرای کاربر ۶۰۰۱در استریســک ذخیره
میشــود .به عبارت دیگر ،اگر بهوســیله یک دیوایس روی ۶۰۰۱رجیستر شــویم ،بهوسیله سایر دیوایسها
امکان رجیستر شدن وجود ندارد )در واقع مشکل Multi Registrationدر پروتکل chan_sipدر این ماژول
برطرف شده است( .برای روشنتر شدن موضوع ،دو مثال را با هم بررسی میکنیم.
فرض کنید تنظیمات زیر را برای کاربر ۶۰۰۱داشته باشیم:
][6001
type=aor
max_contacts=1
ازآنجاکــه پارامتر max_contacts=1تنظیم شدهاســت ،تنها از روی یک دیوایس میتوان کاربر ۶۰۰۱
را رجیســتر نمود .پس از رجیسترشــدن اولین دیوایس ،اطالعات آن در کامندالین استریسک قابل مشاهده
خواهدبود:
>CLI
-- Added contact 'sip:6001@192.168.1.20:50982;rinstance=01c89ee48803955d' to AOR
'6001' with expiration of 120 seconds
== Contact 6001/sip:Phone_2@192.168.1.20:50982;rinstance=01c89ee48803955d has
been created
== Endpoint 6001 is now Reachable
>CLI
مرجع آموزش ویپ با سافتسوئیچ استریسک 456
همانطورکه مالحظه میکنید آدرس کاربر در شبکه ،در پارامتر Contactنمایش داده میشود .استریسک
از این آدرس برای ارسال تماس به ،۶۰۰۱استفاده میکند.
در مثال بعدی برای کاربر ۶۰۰۲پارامتر max_contacts=2تنظیم میشود .در این وضعیت ،کاربر ۶۰۰۲
میتواند تا حداکثر دو بار از دیوایسهای متفاوت رجیســتر شــود aor .هم شــامل دو رکورد از اطالعات
رجیستر است .این تنظیمات برای کاربر ۶۰۰۲به این صورت خواهد بود:
][6002
type=aor
max_contacts=2
خروجی دستور pjsip show endpointsنیز بهصورت زیر نمایش داده میشود:
>CLI
Endpoint: 6002 Not in use 0 of inf
OutAuth: 6002/6002
InAuth: 6002/6002
Aor: 6002 2
Contact: 6002/sip:6002@192.168.1.22:5060;rins 1fa557280a Unknown nan
Contact: 6002/sip:6002@192.168.1.27:5060;rins 81941ac707 Unknown nan
>CLI
همانطورکه مالحظه میکنید ،اطالعات AORمربوط به هر دو دیوایس ،در استریســک ذخیره شده است.
در این حالت اگر استریسک به ارسال تماسی برای ۶۰۰۲اقدام کند ،مالک آخرین دیوایسی خواهد بود که
AORآن برای استریسک ارسال شده است.
بهعنوان آخرین تمرین از این بخش ،میتوان عملیات رجیسترشدن روی یک کاربر را برای یک آدرس
آیپی محدود کرد .یعنی چنانچه درخواســت رجیسترشــدن از سوی یک آدرس آیپی معلوم ارسال شود،
درخواستی مورد قبول خواهد بود که مشابه پارامتر hostدر فایل sip.confباشد .برای مثال تنظیمات زیر را
برای کاربر ۶۰۰۳در نظر بگیرید:
][6003
type=aor
contact=sip:6003@192.1681.32:5060 ; or contact=sip:192.1681.32:5060
دراین حالت اگر درخواست رجیسترشدن برای کاربر ۶۰۰۳از طرف آدرس آیپی 192.168.1.32دریافت
شود ،مورد قبول واقع خواهد شد.
457 استفاده از ماژول PJSIPدر استریسک
• :Registrationگاهی نیاز است برای ایجاد تماس خروجی ،عملیات رجیسترشدن را قبال انجام داده باشیم.
این نوع عملیات غالبا در شرایطی پیش میآید که بخواهیم از ITSPهایی استفاده کنیم که ازطریق عملیات
1
،registrationتماسها را میپذیرند .در غیر این صورت هیچ تماسی را نخواهند پذیرفت.
][mytrunk
type=registration
transport= transport-udp
outbound_auth=mytrunk
server_uri=sip:myaccountname@203.0.113.1:5060
client_uri=sip:myaccountname@192.0.2.1:5060
retry_interval=60
• :Domain_Aliasمیتــوان برای Domainها در تعریف پیکربندی ،از aliasاســتفاده کرد .بهعنوان مثال
فرض کنید بخواهیم در مثال قبل برای example.comیک aliasجدید ایجاد کنیم :
][example2.com
type=domain_alias
domain=example.com
• :ACLگاهی نیاز اســت تماسهای ورودی به استریســک کنترل و مدیریت شود ،در این صورت میتوان
از ACLاستفاده نماییم.
][acl
type=acl
deny=0.0.0.0/0.0.0.0
permit=209.16.236.0
permit=209.16.236.1
همچنین میتوان بهجای استفاده از آدرس آی پی ،از contact headrsدر فیلدهای ذخیره شده پروتکل SIP
استفاده نمود .در این صورت ACLبهصورت زیر تعریف میشود:
][acl
type=acl
contactdeny=0.0.0.0/0.0.0.0
contactpermit=209.16.236.0
contactpermit=209.16.236.1
ازآنجاکه فیلد headerدر پروتکل SIPاز آی پی محلی کاربر استفاده میکند ،در این نوع از سیاستگذاری
1- Internet Telephony Service Provider
مرجع آموزش ویپ با سافتسوئیچ استریسک 458
تعیینشده ،تماس وارد شود ،پذیرفته خواهد شد. در این حالت اگر از طرف کاربر ۶۰۰۱و آی پی
• : Contactدر بخــش مربــوط بــه AORتوضیح داده شــد که میتــوان صریحاً آدرس آی پــی را برای
کاربر تعیین کرد ،بهطوریکه در تماسهای ورودی ،در صورتی که درخواســتی از ســوی این آی پی باشد،
استریســک آن را بهصورت Trust IPدرنظر بگیرد و تماس ورودی را ثبت نماید .میتوان بهصورت کام ً
ال
مســتقل ،یک بخش مرتبط با contactبرای هر کاربر در نظر گرفت و اطالعات مورد نیاز را در آن قرار داد.
در واقــع در ایــن بخش ،اطالعاتی در خصوص اعتبارســنجی تماسهای ورودی به استریســک قرار خواهد
گرفت.
تا اینجا انواع بخشهایی بررســی شــدکه در پیکربندی فایل pjsipازآنها استفاده میشود .برای درک
بهتر هر یک از این مفاهیم ،باید پیکربندیهای مختلفی را در فایل sip.confایجاد وسپس بهوسیله اسکریپت
sip_to_pjsip.pyبه فایل pjsip.confتبدیل کرد .در این روش ،هر بخش بهتر درک میشود.
شکل 2-16ارتباط میان انواع typeها در پیکربندی فایل pjsipرا نمایش میدهد.
شکل 2-16
459 استفاده از ماژول PJSIPدر استریسک
نتیجهگیری
همانطورکه پیشتر توضیح دادیم ،ماژول pjsipاز نســخه استریســک ۱۲به بعد اضافه شدهاست .استفاده از
این ماژول قابلیتهای بسیاری را در اختیار ما قرار میدهد و میتوان از آن بهجای ماژول chan_sipاستفاده
کرد .این فصل نصب و راهاندازی ماژول pjsipدر استریسک بررسی شد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 460
فصل هفدهم
مانیتورینگ و بررسی گزارشها
در استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 462
مقدمه
در گذشتههای نه چندان دور تنها دو نوع شبکه داشتیم :شبکههای مخابراتی 1و شبکههای کامپیوتری. 2
شبکههای مخابراتی عمدتاً برای ارائه سرویسهای مخابراتی استفاده میشدند و کاربرد دیگری نداشتند،
در مقابل ،شبکههای کامپیوتری عمدتاً برای انتقال دیتا استفاده میشوند.
در چند ســال اخیر با رشــد هر دو شــبکه ،این دو با هم ،همگرا ۳و به هم نزدیکتر شــدهاند ،بهطوریکه
تکنولوژیای که در هر شــبکه مورد اســتفاده قرار میگیرد ،در سایر شبکهها نیز استفاده میشود و میتوانند
از سرویسهای یکدیگر اســتفاده کنند .بهعنوان مثال سرویس ،Voiceقب ً
ال بهوسیله شبکههای مخابراتی ارائه
شده بود ،ولی امروزه از سرویس ) (Voice Over IPدر شبکههای IPاستفاده میشود.
ادغام شبکهها با یکدیگر باعث شده مدیریت این شبکهها پیچیدهتر شود .در سیستم مدیریت شبکه باید
تجهیزات ســختافزاری و سرویسهای داخل شبکه را دائماً مانیتور کرد تا عملکرد صحیحی داشته باشند و
شبکهها در حالت » «Up&Runningقرار گیرند.
اصطالح » «Up&Runningدر یک شــبکه ،به معنای زنده بودن و فعالبودن شــبکه اســت .برای مثال
روترها ،ســرورها و ســرویسها و کلیه ارتباطات میان آنها باید عملکرد صحیحی داشته باشند تا شبکهها به
درســتی کار کنند .مثال فرض کنید یک شــبکه ویپ طراحی کرده باشید .ابتدا به علت تعداد کم مشتری و
نبود ترافیک باال ،شــبکه دائما در حال » «Up&Runningاســت .پس از گذشت مدتی ،با افزایش مشتریان،
شبکه نمیتواند به خوبی سرویس دهد و منجر به نارضایتی مشتریان از سرویسهای ارائه میشود و در نهایت
شــبکه ،کارایی خود را از دســت میدهد .در چنین شــرایطی مدیریت شــبکه باید بتواند به درستی شبکه را
مدیریت کند تا شبکه در وضعیت » «Up&Runningبماند.
تعریــف ســاده ای از Up&Runningبودن یک شــبکه را اصطالحــا OAM&Pمیگویند که در ادامه
بررسی خواهد شد.
مدیریت شــبکه شامل همه ابزارها و امکانات ،پروتکلها و فرآیندهایی است که با استفاده از آنها ،عملیات
OAM&Pانجام میشود).شکل (۱-۱7
شکل 1-17
نکته مهم برای مدیریت شبکه این است که تعاریف و دستهبندیهای دیگری از مدیریت شبکهها نیز میتوان
مرجع آموزش ویپ با سافتسوئیچ استریسک 464
داشــت که هر یک از زاویهای خاص ،مدیریت شــبکه را بررسی میکنند ،ولی همگی یک هدف مشترک
را دنبال میکنند.
در این فایل میتوان کلیه گزارشها و الگهای سرویس استریسک را در سطوح مختلف تنظیم و سپس در
فایلهای مشخصی ذخیره نمود .فرمت تعریف این گزارشها در این فایل بهصورت زیر است:
]]]filename => type[,type[,type[,...
1- function
2- layers
3- business
465 مانیتورینگ و بررسی گزارشها در استریسک
: گزارشها در سطح زیر نمایش داده میشوند، استریسکconsole در محیط،همانطورکه مالحظه میکنید
• notice
• warning
• error
• dtmf
/var/log/asterisk/ همچنین میتوان گزارشهایی )در ســطوح مختلف و مورد نظر( در فایلهایی در مســیر
در، فرض کنید بخواهیم گزارشهای کاملی از استریســک در تمامی ســطوح، بهعنوان تمرین.ذخیره کرد
. داشته باشیم/var/log/asterisk در مسیرfull فایل
: وارد کنیمlogger.conf در این صورت باید تغییرات زیر را در فایل
full => notice,warning,error,debug,verbose,dtmf,fax
reload راlogger ماژول، باید در محیط کامندالین استریســکlogger.conf پس از ورود تغییرات در فایل
:نماییم
CLI> loger reload
گزارش های کاملی از استریســک در تمامی ســطوح در فایل زیر ایجاد، کردن ماژول فوقreload بعد از
.خواهد شد
/var/log/asterisk/full
انواع گزارشها را نشان۱-۱7 جدول. ســطوح متفاوتی برای ایجاد گزارشها و الگ داریمlogger در فایل
.میدهد
Type Description
notice You will see a lot of these during a reload, but they will also happen during normal call flow. A notice is
simply any events that Asterisk wishes to inform you.
warning A warning represents a problem that could be severe enough to affect a call (including disconnecting a call
because call flow cannot continue). Warnings need to be addressed.
error Errors represent significant problems in the system that must be addressed immediately.
debug Debugging is only useful if you are troubleshooting a problem with the asterisk code itself. You would not
use debug to troubleshoot your dialplan, but you would use it if the Asterisk developers asked you to provide
logs for a problem you were reporting. Do not use debug in production, as the amount of detailes stored can
fill up a hard drive in matter of days.
verbose This is the most useful of the logging type, but it is also one of the more risky to leave unattended, due to
the possibility of the output filling your hard drive.
dtmf Logging DTMF can be helpful if you are getting complaints that calls are not routing from the auto attendant
correctly
fax This type of logging causes fax-related messages from the fax technology backend (res_fax_spandsp or
res_fax_digium) to be logged to the fax logger.
* This will log EVERYTHING (and we mean everything). Do not use this unless you understand the
implication of storing this amount of data. It will not end well.
1-17 جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 466
در استریســک برای مشــاهده وضعیت loggerها میتوانید از دســتور زیر در کامندالین استریسک استفاده
نمایید:
CLI> logger show channels
Channel Type Status Configuration
------- ---- ------ -------------
/var/log/asterisk/full File Enabled - DEBUG NOTICE WARNING ERROR VERBOSE
DTMF FAX
/var/log/asterisk/messages File Enabled - NOTICE WARNING ERROR
Console Enabled - NOTICE WARNING ERROR
>CLI
همچنیــن میتوانید در فایل logger.confتنظیماتی صورت دهید تا گزارشهایی از عملکرد سیســتم تلفنی
استریسک را در syslogبه شما نمایش دهد .برای مثال این تنظیمات را در فایل logger.confانجام دهید.
syslog.local0 => notice,warning,error
اکنون اگر بهوســیله دســتور tailمحتویات فایل syslogرا بررسی کنید ،گزارشات زیر از طرف استریسک
در این فایل ثبت خواهدشد.
# tail -f /var/log/syslog
Aug 29 06:40:50 ubuntu14 asterisk[1099]: NOTICE[64124][C-00000034]: chan_sip.c:6812 in
update_call_counter: Call to peer '100' rejected due to usage limit of 1
Aug 29 06:40:54 ubuntu14 asterisk[1099]: NOTICE[64126][C-00000035]: chan_sip.c:6812 in
update_call_counter: Call to peer '100' rejected due to usage limit of 1
Aug 29 06:41:07 ubuntu14 asterisk[1099]: NOTICE[64127][C-00000036]: app_queue.c:7733
'in aqm_exec: Added interface 'SIP/100' to queue 'myqueue
Aug 29 06:41:15 ubuntu14 asterisk[1099]: NOTICE[64128][C-00000037]: app_queue.c:7659
'in rqm_exec: Removed interface 'SIP/100' from queue 'myqueue
همانطورکه مالحظه میکنید ،در استریسک گزارشهای این ماژول میتواند در سطوحی متفاوت ،اطالعات
در اختیار ما قرار دهد.
# vim /var/log/asterisk/cdr-csv/Master.csv
کلیه اطالعات و فیلدهای مربوط به هر تماس ثبت شده،از اطالعات این فایل مشاهده میشود که در هر سطر
.است که در ادامه به بررسی سطرها و فیلدهای موجود در آنها خواهیم پرداخت
channel SIP/0004F2040808 - The calling party's channel. This held is set automaticaly and is read-only.
ab1bc23et
dstchannel SIP/ The called part channel_ This field is set automatically and is read-only.
0004F2046969-9786b0b0
lastapp Dial The last dialpian application that was executed. This field is set automatically
and is read-only.
lastdata SIP/ The arguments passed to the las t app. This field is set automatically and is
0004F2046969,30,tT read-only.
start 2010-10-26 12:00:00 The start tune of the cal. This field is set automatically and is read-only.
answer 2010-10-26 12:00:15 The answered time of the call This field is set automatxally and is read-only.
end 2010-10-26 12:03:15 The end time of the call. This field is set automatically and is read-only.
duration 195 The nurnber of seconds between the start and end times for the call. This
field is set automatically and is read-only.
billsec 180 The number of seconds between the answer and end times for the call This
field is set automatically and is read-only.
disposition ANSWERED An indication of what happened to the call. This may be NO ANSWER,
FAILED, BUSY, ANSWERED, or UNKNOWN.
amaflags DOCUMENTATION The Automatic Message Accounting (AMA) flag associated with this call.
This may be one of the followng. WIT, BILL INC, DOCUME N TAT ION, or
Unknown.
userfield PerMinuteCharge:0.02 A vneral-purpose use field. This field is empty by default and can be set to a
user -defined string.'
Uniqueid 1288112400.1 The unique ID for the sr c channel This field is set automatically and is
read-only.
2-17 جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 468
گزارشهای ذخیره شــده در هر ســطر از فایل ، Master.csvدر واقع مقادیر تعریف شــده برای هر یک از
فیلدهای جدول ۲-۱7است که با عالمت "کاما" از هم جدا شدهاند.
در برنامهنویســی استریسک میتوان با استفاده از تابع ،CDRبه هر یک از فیلدها دسترسی داشت .برای
آشــنایی بیشتر با نحوهی اســتفاده از این تابع در برنامهنویسی ،دســتور زیر را در کامندالین استریسک اجرا
نمایید:
CLI> core show function CDR
همانطورکه مالحظه میکنید ،میتوان هر فیلد مورد نیاز را با استفاده از این تابع در برنامه استریسک بهکار
برد .برای مثال فرض کنید برنامه زیر را داشته باشیم.
;extensions.conf
][LocalSets
)(exten => 600,1,Answer
)})same => n,NoOp(Call start time:${CDR(start
)same => n,Wait(5
)})same => n,NoOp(Call duration:${CDR(duration
در این مثال از برنامه خواســتیم که زمان شــرو ِع تماس و مدت زمانی که تماس طول کشــیده را نشان دهد.
بــا این روش میتوان بــه راحتی هر کدام از فیلدهای مورد نیاز از تابع CDRرا در برنامه داشــت و از آنها
استفاده کرد.
نکتــه مهم در خصوص فیلدهای ماژول CDRاین اســت که اکثر آنها خاصیــت Readonlyدارند و ما
نمیتوانیم در برنامههای خود مقدار آنها را تغییر دهیم .برای مثال برنامهی زیر را در نظر بگیرید.
;extensions.conf
][LocalSets
)(exten => 601,1,Answer
)})same => n,NoOp(Call start time:${CDR(start
)same => n,Wait(5
)})same => n,NoOp(Call duration:${CDR(duration
)same => n,Set(CDR(duration)=0
)})same => n,NoOp(Call duration after reset:${CDR(duration
469 مانیتورینگ و بررسی گزارشها در استریسک
نمایش داده، استReadonly مبنی بر اینکه این تابع بهصورتERROR پیام،همانطورکه مالحظه میکنید
.شده است
برای مثال. اضافه کنیمMaster.csv و فایلCDR گاهی الزم میشــود که فیلدهای جدید را به جــدول
تصمیم داریم تماسهای خاصی را که مسیر از قبل تعیینشدهای را در،تصور کنید که در برنامه استریســک
هرچند. بهتر اســت مثال را کمی واضحتر و ســادهتر مطرح کنیم. مشــخص کنیمCDR در،پیش میگیرند
اینجا بیشــتر کاربرد فیلد،این فرایند خیلی ســاده اســت و حتماً روشهای بهتری برای انجام آن وجود دارد
. مد نظر استCDR در ماژولuserfield
و چند درصد به،فرضکنیــد قصد داریم تعییــن کنیم که چند درصد از تماسهای ما به بخــش فروش
فیلد، اینجا سادهترین کار این اســت که ابتدای اجرای برنامه در هر بخش.بخش پشــتیبانی متصل میشــود
: برای مثال این برنامه را در نظر بگیرید. را با مقداری مناسب مقداردهی کنیمuserfiled
[from-pstn]
exten => start,1,Answer()
same => n,BackGround(welcome)
same => n,WaitExten(5)
در ایــن مثال ،مقدار فیلــد userfiledرا قبل از اجرای برنامه در هر بخــش ،مقداردهی کردیم .اینجا از فیلد
userfiledاستفاده شد .حتی میتوان یک فیلد جدید در ماژول CDRایجاد و آنها را مقداردهی کرد .برای
اینکار باید از CDR backendاستفاده کنید.
همانطور که قب ً
ال توضیح داده شــد ،در یک سیســتم تلفنی ،داشتن گزارش کامل از تماسهای ورودی
و خروجــی و همچنین نحوهی اســتفاده از ایــن گزارشها ،از اهمیت باالیی برخوردار اســت .ازآنجاکه در
استریســک بهصورت پیشفرض گــزارش کلیهی تماسها در فایــل master.csvذخیره میشــود ،بازیابی
اطالعات و نحوه اســتفاده از آنها ،کاری دشوار و پیچیده است .برای انجام اینکار باید از CDR backend
استفادهکنید.
بــرای پیکربندی گزارشــات جزئیات تمــاس در پایگاههــای دادهای ) (CDR Backendمیتوان از دو فایل
استفاده کرد؛ ) (۱استفاده از فایل cdr_mysql.confو ) (۲استفاده از فایل .cdr_adaptive_odbc.conf
اســتفاده از روش دوم بسیار مرسومتر اســت .همانطور که از اسم آن ) (adaptiveپیداست ،دارای یک
ساختار انطباقی است .در این روش اگر فیلدهایی از CDRدر جدول وجود نداشته باشد و یا یک فیلد اضافه
در جدول وجود داشته باشد ،ماژول از آنها صرفنظر کرده و سایر فیلدهای موجود در جدول را مقداردهی
میکند .در مقابل ،در روش اول چنین انطباقی وجود ندارد که شــما را با مشکالتی مواجه میکند .بنابراین،
در این فصل از روش دوم استفاده خواهیم کرد.
قبل از ادامه بحث ،باید یک جدول بهنام cdrدر دیتابیس asteriskایجاد کنید .دستورات زیر را در کامندالین
MySQLانجام دهید:
# mysql –uroot –p
Enter password:
;mysql>CREATE DATABASE asterisk
با اجرای این دستور یک دیتابیس جدید بهنام asteriskدر MySQLایجاد شد .اکنون باید جدول cdrرا در
آن ایجاد کنید .بنابراین ،دستورات زیر را اجرا کنید:
;mysql>use asterisk
Database changed
( mysql> CREATE TABLE cdr
>- calldate datetime NOT NULL default '0000-00-00 00:00:00',
>- clid varchar(80) NOT NULL default '',
>- src varchar(80) NOT NULL default '',
>- dst varchar(80) NOT NULL default '',
>- dcontext varchar(80) NOT NULL default '',
>- channel varchar(80) NOT NULL default '',
>- dstchannel varchar(80) NOT NULL default '',
>- lastapp varchar(80) NOT NULL default '',
>- lastdata varchar(80) NOT NULL default '',
>- duration int(11) NOT NULL default '0',
>- billsec int(11) NOT NULL default '0',
>- disposition varchar(45) NOT NULL default '',
مرجع آموزش ویپ با سافتسوئیچ استریسک 472
اینجا جدول cdrساخته شد .برای مشاهده جدول دستور زیر را اجرا کنید:
;mysql> describe cdr
همانطورکه مالحظه میکنید ،نمایش کاملی از مشخصات جدول cdrنشان داده میشود.
اکنــون به ادامه پیکربندی CDR Backendدر استریســک برمیگردیم .بــرای این منظور از فایل _cdr
adaptive_odbcبرای پیکربندی CDR Backendاستفاده میکنیم.
; cdr_adaptive_odbc.conf
][cdr_backend
connection=asterisk
table=cdr
usegmtime=yes
در سیستم تلفنی استریسک این قابلیت وجود دارد که بهصورت همزمان چندین ارتباط ODBCبا پایگاههای
دادهای مختلف ایجاد شود ،بهطوریکه برای هر کدام باید مستقال تنظیمات پیکربندی انجام شود.
فایل cdr_adaptive_odbc.confدارای پارامترهای مهمی اســت که در ادامه مهمترین آنها را توضیح
خواهیم داد.
• :connectionنام شناسه تعریف شده در فایل res_odbc.confاست.
• :tableنام جدولی که دادهها در آن باید ذخیره شوند.
• :usegmtimeبرای ذخیرهکردن تاریخ و زمان براساس استاندارد .GMT
• :aliasاگــر بخواهیم فیلدهــای موجود در ماژول CDRبا نام دیگری در جدول ذخیره شــود ،از این فیلد
استفاده میکنیم.
فرمت استفاده از پارامتر aliasبهصورت زیر است:
>alias <CDR filed> => <column name
بــرای مثــال فرض کنید بخواهیم فیلد srcاز ماژول CDRرا در ســتونی بهنــام sourceذخیره کنیم؛ در این
صورت باید آن را بهصورت زیر بنویسید:
][cdr_backend
connection=asterisk
table=cdr
usegmtime=yes
alias src => source
473 مانیتورینگ و بررسی گزارشها در استریسک
اینجا دادههای مربوط به فیلد srcدر ماژول CDRدر ستون مربوط به sourceدر جدول نگاشت می شود.
• :filterگاهی الزم است گزارش های خاصی از CDRدر جدول پایگاه داده ذخیره شود .در این صورت
از پارامتر filterبهصورت زیر استفاده کنید:
>filter <CDR variable> => <content
بهعنــوان مثال فرض کنید در تمرین قبل بخواهیم فقط رکوردهایی از CDRرا در جدول پایگاه داده ذخیره
کنیم که فیلد » «accountCodeآن برابر» «۱۲۳باشد .در این صورت ،باید تنظیمات زیر را انجام دهید:
][cdr_backend
connection=asterisk
table=cdr
usegmtime=yes
alias src => source
alias start =>calldate
filter accountcode=>123
با مشــاهده جدول و اطالعات ذخیره شــدهی آن ،مشــاهده خواهید کرد که فیلد accountcodeدر تمامی
رکوردها ۱۲۳است.
از این تکنیک میتوان برای دستهبندی و ذخیرهسازی گزارشها ،در جداول مورد نظر استفاده نمود )در
واقع میتوان viewهای متفاوتی از جدول CDRبراساس فیلترهای متفاوت ایجاد نمود(.
• :staticگاهی نیاز است یک فیلد خاص در جدول با مقدار «پیشفرض» وجود داشته باشد .در این حالت
از پارامتر staticبهصورت زیر استفاده کنید.
static "My Content" => my_identifier
بهعنوان مثال فرض کنید بخواهیم در ستونی از جدول به نام mycolumnمقدار پیشفرض »«my_column
را برای همه رکوردها داشته باشیم .در این صورت خواهیم داشت:
][cdr_backend
connection=asterisk
table=cdr
usegmtime=yes
alias src => source
alias start =>calldate
filter accountcode=>123
static "My Content" => my_column
در استریسک بهصورت پیشفرض ،تمام گزارش ها در فایل Master.csvذخیره میشوند .همچنین بهصورت
پیشفرض فقط گزارش های پاسخ دادهشده ۱ذخیره میشوند.
برای تنظیم و پیکربندی ماژول ،CDRاین فایل را باز کنید و تنظیمات زیر را انجام دهید:
;cdr.conf
][general
enable=yes
unanswered=yes
congestion=yes
همچنین تنظیمات مخصوص به ثبت گزارش ها در فایل را در قسمت زیر از فایل cdr.confمشاهده کنید.
;cdr.conf
][csv
usegmtime=yes
loguniqueid=yes
loguserfield=yes
accountlogs=yes
اگر فایل Master.csvرا با یک ویرایشــگر باز کنید ،متوجه میشــوید که در ایــن فایل متنی تمامی فیلدها
بهوسیله کاما از هم جدا شدهاند .ترتیب فیلدهای ذخیره شده در این فایل بهصورت زیر است:
<accountcode>,<src>,<dst>,<dcontext>,<clid>,<channel>,<dstchannel>,<lastapp>,
<lastadata>,<start>,<answer>,<end>,<duration>,<billsec>,<disposition>,
]><amaflags>[,<uniqueid>][,<userfield
بعد از انجام تغییرات ،اگر تماس جدیدی ایجاد شود ،در مسیر زیر و در فایل sample.csvایجاد و گزارش
ها در آنجا درج میشوند.
#vim /var/log/asterisk/cdr-custom/sample.csv
1- Answered
475 مانیتورینگ و بررسی گزارشها در استریسک
(۲فایل cdr_manager.confبرای مدیریت و کنترل کلیه رویدادهای مرتبط با CDRدر استریســک است.
با فعال کردن این بخش از تنظیمات استریسک ،میتوان گزارشهای مرتبط با CDRرا بهوسیله یوزر اکانت
AMIمشاهده کرد.
;cdr_manager.conf
][general
enabled = yes
اکنون اگر به واســطه یوزر اکانت AMIبه استریســک متصل شویم ،رویدادهای مربوط به CDRرا مشاهده
خواهیــم کرد .معموالً رویداد CDRبه همراه رویداد Hangupظاهر میشــود .به عبارت دیگر ابتدا رویداد
Hangupرخ میدهد و سپس به دنبال آن رویداد CDRرخ خواهد داد:
Event: Hangup
Privilege: call,all
Channel: Console/dsp
ChannelState: 6
ChannelStateDesc: Up
>CallerIDNum: <unknown
>CallerIDName: <unknown
>ConnectedLineNum: <unknown
>ConnectedLineName: <unknown
Language: en
AccountCode:
Context: LocalSets
Exten: 600
Priority: 5
Uniqueid: 1472729355.20
Linkedid: 1472729355.20
مرجع آموزش ویپ با سافتسوئیچ استریسک 476
Cause: 0
Cause-txt: Unknown
Event: Cdr
Privilege: cdr,all
AccountCode:
Source:
Destination: 600
DestinationContext: LocalSets
CallerID: "" <>
Channel: Console/dsp
DestinationChannel:
LastApplication: NoOp
LastData: Call duration:5
StartTime: 2016-09-01 15:59:15
AnswerTime: 2016-09-01 15:59:15
EndTime: 2016-09-01 15:59:20
Duration: 5
BillableSeconds: 5
Disposition: ANSWERED
AMAFlags: DOCUMENTATION
UniqueID: 1472729355.20
UserField:
: تماس جدیدی را ایجاد کنید،سپس بهوسیله دستور زیر در محیط کامندالین استریسک
CLI> console dial 700@LocalSets
477 مانیتورینگ و بررسی گزارشها در استریسک
: مشاهده کنیدCDR فیلدهای جدید را در رویدادهای،AMI اکنون باید در گزارشهای ایجاد شده در
Event: Cdr
Privilege: cdr,all
AccountCode:
Source:
Destination: 700
DestinationContext: LocalSets
CallerID: "" <>
Channel: Console/dsp
DestinationChannel:
LastApplication: Hangup
LastData:
StartTime: 2016-09-01 16:15:57
AnswerTime: 2016-09-01 16:15:57
EndTime: 2016-09-01 16:15:58
Duration: 0
BillableSeconds: 0
Disposition: ANSWERED
AMAFlags: DOCUMENTATION
UniqueID: 1472730357.24
UserField:
Rate: 0.02
Carrier: BS&S
اضافهCDR بهعنوان فیلدهای جدید در رویدادCarrier وRate اینجا دو فیلد،همانطورکه مالحظه میکنید
.شدهاند که پیش از این در برنامه استریسک تعریف و مقداردهی شده بودند
: را از مسیر فایلهای پیکربندی استریسک باز و تغییرات زیر را انجام دهیدcdr_syslog.conf سپس فایل
#vim /etc/asterisk/cdr_syslog.conf
[cdr]
facility = local4
priority = info
template = "We received a call from ${CDR(src)}"
مرجع آموزش ویپ با سافتسوئیچ استریسک 478
بعد از انجام این تغییرات و reloadکردن استریسک ،میتوان گزارشها را بهصورت زیر مشاهده نمود:
#cat /var/log/asterisk/asterisk-cdr.log
"Sep 16 10:45:36 pbx cdr: "We received a call from 100
گزارشهای ایجاد شــده در سیســتم تلفنی استریسک تا اینجا بررسی شــدند .عالوه بر این ،انواع متفاوت و
ضروری از گزارش های CDRرا در استریسک می توان ایجاد و از آنها استفاده کرد .همچنین مثالهایی
که در این بخش از کتاب آمد ،جملگی بر اساس پایگاه دادهای MySQLبود .میتوانید از هر پایگاه دادهای
که نیاز دارید اســتفاده کنید .نحوهی پیکربندی سایر پایگاههای دادهای مشابه پایگاه دادهای MySQLاست
که به خواننده کتاب واگذار میشود.
در ادامه فصل به معرفی گزارشهای CELدر استریسک و کاربرد آنها میپردازیم.
همانطورکه پیشتر نیز آمد ،استریســک یک ســرویس رویدادگراســت که در فصل ســیزدهم )ابزارهای
مدیریتی در استریســک( بهصورت مفصل شــرح دادهشــد .بهوســیله ماژول گزارشگیــری CELمیتوان
رویدادهایی را که در استریسک اتفاق میافتد ،ذخیره نمود .با توجه به اینکه این ماژول گزارشهای بیشتری
را نســبت به ماژول CDRایجاد میکند ،از آن در سیســتمهایی میتوان استفاده کرد که محاسبات billing
را دقیقتر انجام میدهند.
برای روشنتر شدن مطلب بهتر است به یک مثال بپردازیم .فرض کنید برنامهی ساده زیر را داشته باشید:
;extensions.conf
][LocalSets
)(exten => 701,1,Answer
)same => n,Playback(hello-world
)(same => n,Hangup
اکنون گزارشهای CDRو CELاین برنامه را در استریســک بررســی میکنیم .اگر گزارش ایجاد شــده
بهوسیله ماژول CDRرا مالحظه کنید ،این گزارش بهصورت زیر خواهد بود:
"","100","701","LocalSets","""100"" <100>","SIP/100-0000000b","","Hangup","","2016-09-01
12:53:27","2016-09-01 12:53:27","2016-09-01 12:53:29",1,1,"ANSWERED","DOCUMENTATI
""ON","1472734407.51",
گزارشهای ایجاد شده بهوسیله ماژول CDRبه سواالت زیر پاسخ میدهند:
• شماره کالر آی دی چیست؟
• شماره مقصد تماس چیست؟
همانطورکــه مالحظه میکنید ،گزارشهای ایجاد شــده بهوســیله ماژول CELدر واقع نشــان دهنده رفتار
استریسک در هر مرحله است .گزارشهای ایجاد شده بهوسیله ماژول CELبه سؤاالت زیر پاسخ میدهند:
• کانال مربوط به تماس گیرنده ،چه زمانی در استریسک ایجاد شده است؟
• این کانال بهوسیله استریسک چه زمانی پاسخ داده شده است؟
• این کانال بهوسیله استریسک چه زمانی قطع شده است؟
• این کانال چه زمانی در استریسک از بین رفته است؟
همانطورکه مالحظه میکنید ،در گزارش ایجاد شــده بهوســیله ماژول CDRخالصهای از ایجاد تماس
نشان داده میشود ،ولی در گزارش تولید شده بهوسیله ماژول CELجزئیات مربوط به زمان ایجادشدن کانال
در استریسک ،زمان پاسخ دادن به کانالها ،زمان اجرای دستورها بر روی کانال ،زمان خاتمه یافتن دستور در
کانال ،زمان قطع شدن تماس و زمان از بین رفتن کانال در استریسک ،مشخص میشود.
ازآنجاکه در استریســک رویدادهای زیادی داریم ،میتوانیم در گزارش های ایجاد شده بهوسیله ماژول
،CELنوع رویدادهایی را که نیاز داریم مشــخص کنیم .در ادامه به معرفی انواع رویدادها در ماژول CEL
میپردازیم.
3-17 جدول
برای آشــنا شــدن با. این ماژول در استریســک نصب شــده و فعال اســت،همانطورکه مشــاهده میکنید
. دستور زیر را در کامندالین استریسک اجرا کنید، CELGenUserEvent
CLI> core show application CELGenUserEvent
[Syntax]
CELGenUserEvent(event-name[,extra])
مرجع آموزش ویپ با سافتسوئیچ استریسک 482
][Arguments
extra
Extra text to be included with the event.
برای روشــنتر شــدن موضوع بهتر اســت در مثالی از آن اســتفاده کنیم .فرض کنید بــرای الگگیری در
برنامههای خود ،در بخشی از برنامه تصمیم داشته باشیم رویدادهایی ایجاد کنیم .این کار بهوسیله استریسک
ِ
اجرای دســتورات نوشتهشــده صورت میگیرد .اینجــا رویدادی با نــام » «my-Event-logرا ایجاد هنگام
خواهیم کرد.
;extensions.conf
][LocalSets
)(exten => 702,1,NoOp
…
)”same => n,CELGenUserEvent(My-EVENT-Log,”Here is my logger in asterisk dialplan
درصورتیکه استریســک به اجرای این خط برســد وآن را اجرا نماید ،رویدادی با نام » «My-Eventرا در
گزارشهای خود ثبت خواهد کرد.
مهمترین پارامترهای این ماژول برای پیکربندی ،در زیر توضیح داده شدهاند:
• پارامتــر :enableاین پارامتر برای فعالکردن گزارشها در CELاســت که بهصورت پیشفرض غیرفعال
است.
• پارامتر :Appsبهوســیله این پارامتر میتوان مشــخص نمود که برای اجرای کدامیک از دســتورات باید
گزارشهای CELتولید شود.
• پارامتر :eventsاین پارامتر مشخص میکند که چه نوع رویدادی باید بهوسیله ماژول CELگزارش شود.
لیست انواع رویدادها در جدول 5-17آورده شده است.
• پارامتر :dateformatاین پارامتر تاریخ و زمان اجرا شــدن رویداد را نشــان میدهد .بهعنوان مثال فرمت«
»%F %Tزمان را بهصورت « » year-manth-day h:m:sنمایش میدهد.
گزارشهای ایجاد شده بهوسیله ماژول ، CELهمانند ماژول CDRبهصورت پیشفرض در فایل Master.
csvدر مسیر /var/log/asterisk/cel_customذخیره میشوند .میتوان این گزارشها را در پایگاههای داده
با استفاده از CEL Backendذخیره نمود.
483 مانیتورینگ و بررسی گزارشها در استریسک
mysql برای این منظــور به کامندالین. ایجاد کنیدMySQL را در پایــگاه دادهایcel اکنــون بایــد جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 484
:بروید
# mysql -uroot -p
Enter password:
mysql>
: جدول را مشاهده کنید، میتوانید به کمک دستور زیرcel بعد از ساختن جدول
mysql> describe cel;
cel_odbc. به این منظــور باید هنگام پیکربندی فایل.میتوان نام فیلدها را هنگام ســاختن جداول تغییر داد
485 مانیتورینگ و بررسی گزارشها در استریسک
بهعنــوان مثال فرض کنید بخواهیم به جای فیلد » «eventtypeدر ســاخت جــدول از فیلد »«eventname
استفاده کنیم .در این صورت باید آن را به شکل زیر در فایل cel_odbc.confتغییر دهید:
;cel_odbc.conf
][cel_backend
connection = asterisk
table = cel
alias eventtype => evenename
همچنیــن میتوانید از پارامتر filterدر صورت نیاز به فیلترکردن گزارشهای ماژول CELدر جدول پایگاه
داده ،استفاده کنید:
>filter <CEL field> => <content
چنانچه بخواهیم فقط گزارشهای مربوط به دستور » «Dialرا در جدول ذخیره کنیم ،در این صورت داریم:
;cel_odbc.conf
][cel_backend
connection = asterisk
table = cel
filter appname => dial
پارامتر staticبرای اســتفاده از یک فیلد خاص در جدول گزارشهای CELبا مقادیر پیشفرض بهصورت
زیر بهکار برده میشود:
>static <"Static Content Goes Here"> => <column name
بعــد از انجام تغییرات و reloadکردن استریســک ،خروجی گزارش رویداد CELدر AMIبهصورت زیر
خواهد بود:
Event: CEL
Privilege: call,all
EventName: CHAN_END
AccountCode:
CallerIDnum: 100
CallerIDname: 100
CallerIDani: 100
CallerIDrdnis:
CallerIDdnid: 702
Exten: 702
Context: LocalSets
Channel: SIP/100-00000013
Application:
AppData:
EventTime: 2016-09-01 19:27:51
AMAFlags: DOCUMENTATION
UniqueID: 1472741871.99
LinkedID: 1472741871.99
!Userfield: I like waffles
Peer:
PeerAccount:
Extra:
همانطورکــه مالحظه میکنید ،گزارش رویداد CELایجاد میشــود و بهوســیله یــوزر اکانت AMIقابل
مشاهده است.
تا اینجا در خصوص گزارشهای سیســتمی از قبیل ، logger ، syslogگزارش جزئیات تماس )(CDR
و گزارش رویدادهای استریســک ) (CELتوضیحات الزم داده شــد .در ادامه به یکی از پروتکلهای مهم
مدیریتی در شبکه خواهیم پرداخت و نحوه اتصال آن به استریسک را شرح خواهیم داد.
تحت پروتکل مدیریت شبکه ،به سرور مدیریت شبکه منتقل نمایند .هر بخش شامل وظایفی می باشد که در
ذیل به آنها ارشاره شده است:
SNMP Community
برای اســتفاده از پروتکل ، SNMPویژگی آن باید بهوســیله تجهیزات مورد نیاز فعال شــود و گزارشها به
ســرور مدیریت شبکه ارســال گردند .ولی فقط اطالعاتی معتبرند که از طرف تجهیزات مشخص شده برای
ســرور ارســال شوند .به همین منظور از یک نام اشتراکی با عنوان SNMP Communityاستفاده میشود و
تا زمانی که در انتقال اطالعات از این نام استفاده نشود ،آن ارتباط غیرمعتبر شناخته میشود و ارزشی ندارد.
با این تکنیک از جایگزینی ســرور مدیریت شبکه بهجای ســرورهای جعلی و یا تجهیزات جعلی جلوگیری
میشود .شکل ۲-۱7چگونگی ارتباط تجهیزات در شبکه ،سرور مدیریت شبکه و پروتکل SNMPرا نشان
می دهد.
شکل 2-17
مرجع آموزش ویپ با سافتسوئیچ استریسک 488
;Ubuntu
#apt-get install snmp snmpd libsnmp-dev snmp-mibs-downloader
بعد از نصب ماژول ،SNMPباید استریسک را مجددا ً کامپایل کنید تا این ماژول بهوسیله استریسک شناخته
و نصب شود.
#cd ~/src/asterisk-complete/
#./configure
#make menuselect
چنانچه این دستور اجرا شود ،مشاهده میکنید که ماژول res_snmp.soدر استریسک فعال شدهاست).شکل
(۳-۱7
شکل 3-17
در ادامه ،دستورات زیر را برای نصب مجدد استریسک اجرا کنید:
#make
#make install
489 مانیتورینگ و بررسی گزارشها در استریسک
را از مســیر زیرres_snmp.conf باید فایل، در استریســکSNMP بــرای پیکربنــدی و فعال کردن ماژول
:ویرایش نمایید
# vim /etc/asterisk/res_snmp.conf
[general]
subagent=yes
enabled=yes
برای این منظور باید فایل. بروید و تنظیمات زیر را انجــام دهیدSNMP اکنــون بایــد به فایلهای پیکربندی
: را از مسیر زیر باز و این موارد را به انتهای آن اضافه کنیدsnmpd.conf
#vim /etc/snmpd/snmpd.conf
#agentAddress udp:<local ip- agent ip>:161
#rocommunity public <remote ip- nms ip>
agentAddress udp:192.168.1.6:161
rocommunity public 192.168.1.4
master agentx
agentXSocket /var/agentx/master
agentXPerms 0660 0775 nobody root
مرجع آموزش ویپ با سافتسوئیچ استریسک 490
sysObjectID .1.3.6.1.4.1.22736.1
در این تنظیمات دقت داشــته باشــید کــه پارامترهــای agentAddressو rocommunityرا لزوما با آدرس
آیپیهای متناســب مقداردهی کنید .همچنین جهت امنیت بیشــتر rocommunityرا از مقدار پیش فرض
publicتغییر دهید.
برای اینکه ماژول SNMPبتواند استریســک را مانیتور و مدیریت نماید ،باید فایلهای MIBمرتبط به
استریسک را در مسیر فایلهای MIBسیستم ،در مسیر زیر اضافه کنید ،هرچند که با درنظرگرفتن توزیعهای
متفاوت لینوکس ،این مسیر میتواند متفاوت باشد:
;REHL
/usr/share/snmp/mibs/
;Ubuntu
/usr/share/snmp/mibs/
سپس باید فایلهای MIBمربوط به استریسک را از اینترنت دانلود و در مسیر فایل های MIBکپی نمایید:
# mv DIGIUM_MIB.txt /usr/share/snmp/mibs/
# mv Asterisk_MIB.txt /usr/share/snmp/mibs/
تا اینجا ســرویس مدیریت شبکه snmpdدر لینوکس نصب شد و ماژول res_snmp.soدر استریسک فعال
گردید .اکنون برای تست مدیریت استریسک بهوسیله SNMPمیتوان از ابزار snmpwalkاستفاده کرد.
در زیر مثالهایی را بررسی میکنیم:
برای مشاهده نسخه لینوکس دستور زیر را اجرا کنید:
;Linux uname -a
#snmpget -OQv -v2c -c public 127.0.0.1 SNMPv2-MIB::sysDescr.0
برای مشاهده ساختار درختی SNMPدر استریسک ،دستور زیر را اجرا کنید:
;Walk Asterisk SNMP tree
#snmpwalk -v2c -c public 127.0.0.1 ASTERISK-MIB::asterisk
برای مشاهده ورژن استریسک نصب شده روی سیستم ،دستور زیر را اجرا نمایید:
;Asterisk Version
#snmpget -OQv -v2c -c public 127.0.0.1 ASTERISK-MIB::astVersionString.0
491 مانیتورینگ و بررسی گزارشها در استریسک
برای مشاهده لیست کلیه کانالهای استریک ،دستور زیر را اجرا کنید:
;List active channels
#snmpwalk -OQv -v2c -c public 127.0.0.1 ASTERISK-MIB::astChanName
همانطور که مالحظه میکنید کلیه این دســتورات برای تســت ماژول SNMPدر خود سیســتم بهصورت
لوکال اجرا شدهاست .دقت کنید در صورتی که در تنظیمات مقدار rocommunityرا تغییر داده باشید ،باید
مقدار آن را با publicدر دستورات فوق جایگزین نمایید.
ازآنجاکه برای مدیریت و نظارت بر شــبکه از نرمافزارهای مدیریت شــبکه اســتفاده میشود ،میتوانید
ســرور استریســک خود را با یکی از این نرمافزارها پیکربندی کنید تا اطالعات برای آن نرمافزار مدیریت
شبکه ارسال شود.
نرم افزارهای مدیریت شبکه زیادی وجود دارند و میتوانید از هر یک از آنهایی که قابلیت SNMPرا
دارا هستند ،استفاده کنید .ازآنجاکه توضیح در خصوص نرمافزارهای مدیریت شبکه ،خارج از بحث کتاب
اســت ،آن را به خواننده کتاب واگذار میکنیم .بهعنوان مثال نمودارهایی از سیستم نرم افزار مدیریت شبکه
openNMSرا در شکل ) (4-۱7مشاهده میکنید.
شکل 4-17
شــکل 4-۱7تعداد تماس همزمان در واحد زمان را نمایش میدهد .همانطور که پیداست میانگین ،حداقل،
و حداکثر طول مکالمات نسبت به ساعت نمایش داده میشود.
در استریسک به ازای هر دو Active Channelیک Brdidgeاتفاق میافتد .این اتفاق غالبا زمانی رخ
میدهد که داخلیهای یک سیســتم با هم مکالمه داشتهباشــند .شــکل ۵-۱7گزارشهای آماری هر دو نوع
کانال را نمایش میدهد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 492
شکل 5-17
شکل 6-17
در شکل ۶-۱7تعداد مکالمه همزمان نسبت به ساعت ،نمایش داده شده و در شکل 7-۱7مکالمات بر اساس
ساعت/طول مدت مکالمه ،نمایش داده شده است.
شکل 7-17
گاهی ممکن اســت سیستم تلفنی استریسک crash ،کند و ســرویس بهطور ناخواسته stopکند .پیدا کردن
چنین خطاهایی به ســادگی نخواهد بود .حتی برخی از خطاها ممکن اســت بــه دلیل بروز یک خطا در کد
برنامه )ســورس کد استریســک( باشــد .همچنین برخی از خطاها به دلیل عدم اســتفاده صحیــح از توابع و
دستورات در استریسک بهوجود میآید که منجر به crashکردن استریسک میشود.
493 مانیتورینگ و بررسی گزارشها در استریسک
معموالً اولین کاری که در چنین شــرایطی باید صورت گیرد ،استفاده از الگهای استریسک و syslog
لینوکس اســت .ولی چنین خطاهایی هیچ الگی را در گزارشــات استریسک ایجاد نمیکنند .تنها میتوانید
به گزارشهای syslogلینوکس اکتفا کنید .برای مثال فرض کنید سیســتم تلفنی استریســک شما بهصورت
ناخواســته و بدون هیچ دلیلی crashکرده و هیچ الگی هم در گزارشهای استریســک دیده نمیشود .تنها
الگ قابل مشاهده در گزارشهای syslogالگ زیر است:
15:17:05 root kernel: [39097649.573062] asterisk[13835] segfault at 0 ip (null) sp
]00007f309d4da3f8 error 14 in asterisk[400000+209000
با یک جستجوی ساده در اینترنت متوجه میشوید که با راه اندازی مجدد استریک مشکل موقتا رفع خواهد
هیچ تضمینی در crashنکردن دوباره سیستم استریسک وجود ندارد. شد .ولی
قابلیــت BackTraceاین امکان را فراهم مــیآورد که درصورت مواجهه با چنین خطاهایی ،بتوان آنها
را پیدا و برطرف کرد.
اولین اقدام برای حل چنین مشــکالتی این است که به استریسک بگویید چنانچه خطایی در سورسها و
یا هر جای دیگری اتفاق افتاد ،آن را الگ کند و در اختیارتان بگذارد .برای این منظور باید از آپشن –gدر
اجرای سرویس استریسک استفاده کنید .برای مثال دستور زیر را اجرا کنید:
# ps -C asterisk u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
? root 32675 106 4.7 2881000 47780 Rsl 15:27 0:05 /usr/sbin/asterisk
همانطورکه مالحظه میکنید ،در این شــرایط سرویس استریسک از آپشن –gاستفاده نکرده است .لذا
باید سرویس استریسک را stopو مجددا ً آن را با روش زیر startکنید.
# /etc/init.d/asterisk stop
# safe_asterisk
در این وضعیت ،ســرویس استریســک با آپشــن –gاجرا شــده اســت .اکنون باید منتظر بمانید تا سرویس
استریســک دوباره بهصورت ناخواسته crashکند .در این حالت استریسک یک فایل الگ در مسیر /tmp/
ذخیره میکند .فایل الگ ممکن است بهصورت زیر باشد.
/tmp/ core.Asterisk-2016-07-25T21_56_40+0000
سپس از دستور دیباگر gdbدر لینوکس استفاده کنید تا بتوانید محتویات فایل را بهصورت متنی مشاهده
کنید .برای مثال دستور زیر یک فایل متنی در مسیر /tmp/backtrace.txtایجاد میکند.
# gdb -se "asterisk" -ex "bt full" -ex "thread apply all bt" --batch -c /tmp/ core.Asterisk-2016-
07-25T21_56_40+0000
مرجع آموزش ویپ با سافتسوئیچ استریسک 494
> /tmp/backtrace.txt
بهطور حتم با مطالعه و بررســی فنی این فایل ،میتوانید علت crashکردن استریســک را بفهمید و آن را
برطرف کنید.
نتیجهگیری
مدیریت سیســتمهای شــبکه از جمله وظایف مهم یک مدیر شبکه اســت .در این امر شبکههای ویپ استثنا
نیســتند و یک مدیر شــبکه ویپ باید بتواند بهصورت کامل ،شــبکهی خود را زیر نظر داشته باشد .مدیریت
در شــبکههای ویپ از جنبههای متفاوتی بســیار حســاس اســت ،چون عالوه بر مدیریت بر عملکرد صحیح
تجهیزات ،باید روی گزارشهای صورت حسابها و billingها نیز نظارت کامل و دقیقی داشت .پارهای از
حمالت در شبکههای ویپ به قصد اختالل در صورتحسابهای کاربران روی میدهد ،بنابراین باید بتوانید
گزارشهای متعددی در سطوح مختلف ایجاد کنید و سیستم را از این لحاظ ،به درستی پیکربندی کنید.
فصل هجدهم
مقدمه
تا اینجا در خصوص آشــنایی با قابلیتها و تواناییهای سیســتم تلفنی استریســک مطالبی ذکر شــد .در این
فصل همانطور که از نام آن پیداست ابتدا به معرفی و شناخت انواع حملهها به شبکههای ویپ میپردازیم،
زیرا تا شناختی نسبت به شبکههای ویپ و انواع حملههای ممکن به آنها نداشته باشیم ،نمیتوانیم امنیت را
تضمین کنیم.
از ایــن رو ،در شــروع فصل مقدمهای در خصوص امنیت و بررســی انواع حملهها در شــبکههای ویپ
خواهیم داشت ،سپس در ادامه ،فرآیندهای امن کردن یک سیستم تلفنی استریسک را معرفی خواهیم کرد.
پرواضح اســت که برقراری امنیت در یک شبکه ،تشکیل شــده است از مجموعه اقداماتی که هر یک،
بخشی از برقراری امنیت را برعهده دارد .صرفا با برخورداری از یک فایروال قدرتمند یا استفاده از » SBC
«1در مرزهای ورودی شبکه ،نمیتوان امنیت یک شبکه ویپ را تضمین نمود.
خرید یک SBCقدرتمند در شبکههای ویپ نیست ،بلکه امنیت یک سیاست است که افرادی باید آنها را
وضع و افرادی هم باید آنها را اجرا کنند.
پــس در یک تعریف صحیــح از امنیت ،میتوان گفت امنیت یک فرآیند اســت که در این فرآیند ،هر
اقدامی که در آن صورت گیرد باعث میشــود بخشــی از سیستم امن شود .در تعاریف باال عنوان کردیم که
برقراری امنیت یک سیاســت است .منظور از سیاست امنیتی ،بیان رسمیای از قوانینی است که باید بهوسیله
مدیران ITمطرح شوند .در RFC2196سیاستهای کلی امنیت در شبکههای کامپیوتری بیان شدهاست.
6
شنود
این حمله ،ویژگی محرمانگی 7را در معرض خطر قرار میدهد .حمله به شنود یعنی گوش دادن به مکالمات،
دادهها یا دورنگارهای فرد موردنظر بهصورت نامحسوس و با اهداف جاسوسی .در شبکههای PSTNبه دلیل
استفاده از خط خصوصی برای هر نفر و استفاده از یک بستر امن ،امکان شنود بسیار پایین است.
8
تغییر در جریان صدا
۹
این حمله ،دو ویژگی محرمانگی و صحت را در معرض خطر قرار میدهد .یکنوع حمله از نوع MITM
اســت که هکر میتواند به گفتگوی دو نفر گوش بدهد و این دادهها را تغییر دهد ،مانند تبدیل کردن بله به
خیر و بالعکس یا واژه فروش به خرید و بالعکس ،ولی به دلیل غیرقابلپیشبینی بودن گفتگوی انسانها ،فقط
بخش کمی از این دادهها قابلتغییر اســت .نوع دیگر این حمله بدین گونه اســت؛ زمانی که برداشت وجهی
از حساب کاربر صورت میگیرد تلفن گویا بهجای گفتن حساب فعلی ،حساب قبلی را به کاربر میگوید و
کاربر تصور میکند که برداشت وجهی از حساب او صورت نگرفته است.
1
سوء استفاده رایگان از حساب
این حمله صحت را در معرض خطر قرار میدهد .در این حمله هکر با ســوء استفاده از حساب و شمارههای
دیگران ،سعی در برقراری تماس میکند .مث ً
ال فرد هکر با سوء استفاده از شماره ۹۰۰که در مالکیت مخاطب
دیگری است ،تماس برقرار میکند ولی قبض شارژ آن را باید صاحب آن شماره پرداخت کند ،این حملهها
در شــبکههای مخابراتی مرسوم است و یکی از راههای جلوگیری از آن ،استفاده از دستگاههای تشخیص و
جلوگیری از نفوذ به نام ۲ IDSاست.
3
تغییر مسیر تماسها
این حمله ،دو ویژگی صحت و محرمانگی را در معرض خطر قرار میدهد .یکی از ویژگیهای خوب شبکه
تلفن ویپ ،دارابودن یک شــماره و انتقال تماس به نقاط مختلف جهان با همان شــماره است .هکر میتواند
شماره فرد موردنظر را به مکان خود منتصب کند و تماسهای گرفتهشده به آن شماره ،به گوشی هکر تغییر
مسیر یابد .این قابلیت در تلفنهای قدیمی نیست ،بنابراین این نوع حملهها برای شبکههای قدیمی بیمعناست.
4
دستکاری در دادههای حساب کاربر
ایــن حمله ،دو ویژگی صحت و محرمانگی را در معرض خطر قرار میدهد .در بانک اطالعاتی حســابها
برای هر شمارهی متعلق به یک فرد ،رکوردی به نام ۵ CDRوجود دارد که شامل این اطالعات است :شماره
کســی که تماس گرفته ) ،(srcشــماره کسی که با وی تماس گرفتهشــده ) ،(dstزمان تماس ،طول تماس و
اطالعات دیگر که با دسترسی به این بانک ،هکر میتواند الگوی تماسها را آنالیز و به مسائل مهمی دست
ال میتواند به تماس بین دو فرد یا شرکت تجاری مهم دست پیدا کند .اگر حق دسترسی نوشتن پیدا کند .مث ً
را نیــز روی پایگاه بهدســت بیاورد ،میتواند دادههــای خاصی را نیز پاک کند .ایــن کار میتواند بهمنظور
سوءاســتفاده از شــارژ حســاب یا پوشــاندن کارهای مجرمانه صورت پذیرد .این نوع حملهها در شبکههای
مخابراتی صورت میگیرد ولی به دلیل جدا بودن داده از صدا و قرار داشتن بانک داده در یک محل امن و
شبکه اختصاصی ،دسترسی به آن برای هکر بسیار مشکل است.
این حمله ،صحت را در معرض خطر قرار میدهد .هر تلفن ،یک شناســه دارد که همان شــماره تلفن است.
در این حمله ،هکر شــماره تلفن مخاطب را جعل میکند و میتواند از شماره تلفن جعلشده با مخاطبهای
مختلف تماس بگیرد یا تماسهای گرفتهشــده به آن شــماره را به گوشــی خود انتقال دهد .این حمله برای
سیســتمهای بانکی که با ســرویس شناســه مخاطب میتواند به حســابهای او دسترســی پیدا کنند ،بسیار
مخاطرهآمیز اســت .در سیستمهای تلفن قدیمی ،احتمال این حمله بسیار ضعیف است ،به دلیل اینکه در این
شبکهها یک ناظر مرکزی وجود دارد که جلوی این حملهها را میگیرد .در شبکههای تلفن ویپ نیز باید از
این نوع حملهها جلوگیری شود.
در ادامه به بررسی انواع حملهها روی پروتکل SIPو RTPدر شبکههای ویپ میپردازیم.
MAC Spoofing X X X
Malformed Packets X
Transport TCP or UDP Floods X
DHCP Starvation X
ICMP Floods X
Buffer Overflow X X X
Operating System X X X
Databas Attacks X X
SIP Attack:
Registeration HiJacking X X X
Message Modification X X
Cancel/Bye Attack X
Malformed Command X
Redirect X X
RTP Attacks:
RTP Playload X
RTP Tampering X X X
2-18 جدول
مرجع آموزش ویپ با سافتسوئیچ استریسک 502
1
ربودن ثبتنام در پروتکل SIP
پروتکل SIPبرای نظارت بر الیهی برنامه کاربردی در شــبکه اســت و وظیفه آن در شبکه ویپ ،برقراری،
تغییر و خاتمه جلسات در تماسهای تلفنی است .یک کاربر )تلفن( برای استفاده از شبکه ویپ ابتدا باید در
ســرور استریسک یا سرور پراکسی ثبتنام کند .ربودن ثبتنام ،زمانی رخ میدهد که هکر ،خود را بهجای
یک شــخص قانونی در شــبکه جا بزند و آدرس خود را در شــبکه ثبت کند .این حمله باعث میشــود که
تماسهای دریافتی با مخاطب ،به تلفن هکر منتقل شــود و تماسهای ارسالی به تلفن مخاطب را از بین ببرد.
این حمله میتواند برای یک فرد یا گروهی از افراد واقع شــود و شــمارههای آنها را بلوکه کند تا نتوانند از
افــراد مختلف ،تماس دریافت کنند .درحالحاضــر ،اطالعات ثبتنام روی پروتکلهای حمل مانند TCPو
UDPانجام میشود که با استفاده از امنسازی الیه حمل ،پروتکل TLSپدیدۀ حمل ارتباطات امن با احراز
هویت در یک فضای باز ناامن برای مقابله با ربوده شدن ثبتنام را ایجاد میکند.
2
تغییر پیام پروتکل SIP
پروتکل ، SIPمکانیســم کاری صحیحی برای ارزیابی ندارد و با انجام حملههای MITMمانند دستکاری
در آدرس سختافزاری شبکه ،آدرس ،IPاطالعات ثبتنام در پروتکل ،SIPهکر میتواند پیامهای SIPرا
قطع یا دستکاری کند؛ مانند متصل کردن تماس یک فرد یا گروه به فرد یا گروه دلخواه دیگر ،خط روی
خــط انداختــن که با محافظت از پروتکلهای الیه حمل TCPو UDPو اســتفاده از پروتکل TLSمیتوان
از محتوای پیامهای SIPمحافظت کرد .با این کار هکر قادر به خواندن یا تغییر محتوای پیام SIPنیست.
3
حمله لغو /خداحافظی در SIP
در این حمله ،هکر پیام لغو یا خداحافظی را در بســتههای SIPمیســازد و آن را به گرهها و نودهای انتهایی
)تلفنها( مخاطب میفرســتد .این پیام باعث قطع تماس مخاطبین حین مکالمه میشــود .اگر هکر بهصورت
ثابت و مداوم این پیامها را به تلفن قربانی بفرستد ،فرد قربانی دیگر قادر به گرفتن یا دریافت تماس نخواهد
بــود .ایــن حمله اگر به تعــداد زیادی از تلفنهــا صورت گیرد میتواند سیســتم تلفنی یا قســمتی از آن را
مختل کند .با ســختکردن احــراز هویت میتوان از این حمله جلوگیری کــرد ،بهطوریکه پیامهای لغو و
خداحافظی فقط از گرههایی که صالحیت آنها تأییدشده قبول شود و بقیه رد شوند .شکل ۱-۱8این حمله
را به تصویر کشیده است.
شکل 1-18
1
حمله بازگشت در SIP
در حملــه بازگشــت در ، SIPدو گــروه داور و ارجاعکننده داریم که گروه داور بــه گروه ارجاعکننده
۳ ۲
میتواند متصل شــود یا پیام بفرســتد .هنگام ردوبدلشدن پیام میان این دو گروه ،حملههای MITMو شنود
میتوانــد صــورت گیرد و اطالعاتی از هر دو گــروه را به هکر بدهد .یکی از راههــای اجتناب از این کار،
استفاده از روش رمز نگاری SMIMEاست که بستههای پیام را بهصورت رمزینه میفرستد تا هکر نتواند آن
را بخواند و در آن تغییر صورت دهد.
4
حمله دعوت مجدد در SIP
زمانی که اولین جلسه میان دو مخاطب برقرار شود ،در درخواستهای بعدی ممکن است بخواهند تغییراتی
در پارامترهای این جلســه کاری بدهند؛ مانند تغییر در آدرس آی پی و درگاه که ممکن است بهوسیله یک
هکر صورت گرفته باشد ،به همین علت ،تغییرات غیرمجاز بهوسیله پیامهای دعوت مجدد در SIPامکان از
کار انداختن سیستم تلفنی را دارند .این حمله در شکل ۲-۱8نشان دادهشده است.
5
حمله بهروزرسانی در SIP
خاصیت بهروزرســانی ،به کاربر امکانات مختلفی را میدهد ،ازجمله بیصدا کردن تلفن ،گذاشــتن گوشی
روی حالت انتظار و تطبیق کیفیت ســرویس و دیگر صفات یک جلسه .این حمله مانند حمله دعوت مجدد
اســت ،با این تفاوت که دعوت مجدد پس از برقراری یک جلســه صورت میگیرد ولی بهروزرسانی برای
تغییر پارامترهای جلســه ،پیش از ارسال اولین پیام دعوت صورت میگیرد .این حمله در شکل ۳-۱8نمایش
دادهشــده اســت .حمله بهروزرســانی عموماً برای تغییر در کیفیت ســرویس یا عوض کــردن آدرس IPیا
درگاهها صورت میگیرد.
شکل 2-18
شکل 3-18
1
حمله اطالعات
گاهی پروتکل SIPممکن است واسط دو شبکه PSTNباشد که به آن فناوری SIP-Tگفته میشود .روش
حمل اطالعات ،مکانیســمی برای حمل اطالعات الیه برنامه کاربردی از طریق ســیگنالینگ SIPاســت که
یک تونل اطالعاتی میسازد .اطالعات مبادله شده ازطریق STP-Tشامل اطالعات شبکه ،PSTNاطالعات
1- Re-INVITE ATTACK
505 امنیت در سیستم تلفنی استریسک
صورتحساب مشتری و ...است که هکر میتواند به این اطالعات در شبکه واسط SIPحمله کند .پیامدهای
این حمله ،اشتباه شدن صورتحساب کاربران ،از کار انداختن سیستم و دسترسی غیرمجاز به تماسهاست.
1
ایجاد ناهنجاری در دستورات SIP
محتــوای پیــام در ، SIPمتنی و مانند پروتکل HTMLاســت کــه از مزایــای آن ،انعطافپذیری و وجود
ویژگیهای زیاد اســت .از معایب آن پیادهســازی دشــوار تجزیهگر اســت که یک نقطــه ضعف برای آن
محســوب میشــود و هکرها از همین نقطهضعف اســتفاده میکننــد و پیام SIPرا تغییــر میدهند ،ورودی
نامعتبر به تجزیهگر میفرســتند و گره مربوطه یا کل سیســتم تلفنی را دچار مشــکل میکنند .اعتبارســنجی
تجزیهگرها بســیار دشوار اســت .یکی از راههای آزمودن ،استفاده از دستگاههای آزمایشی فازی است که با
تولید درخواست نامعتبر سعی در کشف اشکاالت و خطاهای دستوری تجزیهگر دارند.
2
حمله تغییر مسیر در SIP
یکی از قابلیتهای شــبکههای SIPاین اســت که شخص Aمیتواند به شــخص Bبدون توجه به موقعیت
جغرافیایی او و فقط با دانســتن شماره تلفن شــخص Bارتباط برقرار کند که این ارتباط از طریق تغییر مسیر
در سرورهای پراکسی صورت میگیرد .حال اگر فرد هکر تماسهای فرد Aرا به تلفن خودش یا یک جای
نامعتبر تغییر مســیر دهد میتواند سیســتم را از کار بیاندازد .علت این حمله ضعف در مکانیسم احراز هویت
در SIPاست که با بهکارگیری پروتکل TLSو داشتن پسورد پیچیده میتوان از این حمله پیشگیری کرد.
3
حمله با ِر کاری RTP
پروتکل RTPبرای حمل صدا بین دو گره است که از پروتکل الیه حمل UDPاستفاده میکند .با حملههای
MITMمیتوان دسترســی به پروتکل RTPبین دو گره را پیــدا کرد و هکر میتواند با ِر کاری در پروتکل
RTPرا شــنود کند یا تغییر دهد .دســتکاری در با ِر کاری ،مانند اضافه کردن نویز در مکالمات و کاهش
کیفیت سرویس است .با استفاده از پروتکل RTPامن شده SRTPمیتوان جلوی این حملهها را گرفت.
4
دستکاری RTP
با دستکاری در شماره ،ترتیب یا تاریخ سرآیند بستهها ،میتوان ارتباط بین دو گره بهوسیله پروتکل RTP
را ناپایدار کرد یا در برخی از پیادهسازیها میتوان باعث خراب شدن گره دریافتکننده پیام شد .با استفاده
از پروتکل SRTPمیتوان مطمئن شد که سرآیند بستهها در RTPتغییر نکردهاند .راه دیگر جداسازی مسیر
داده از مســیر صوت است که با اســتفاده از فناوری VLANدر شبکه انجام میگیرد؛ یعنی برای هر یک از
داده و صوت ،مسیر جداگانه مجازی در نظر گرفته میشود.
این حملهها ،حملههای خاص ویپ نیستند بلکه حملههایی هستند که در شبکههای مبتنی بر آی پی مشترکاند
و چون بستر ارتباطی شبکههای ویپ هم روی آی پی است ،این نوع حملهها نیز مورد توجه است .انواع این
حملهها عبارتند از:
1
حمله فیزیکی
دســتکاری فیزیکی اجزای شبکه ویپ مانند اتصاالت ،گوشیها ،پروکسی ها .این حمله ،قابلیت استفاده و
محرمانگی را از بین میبرد .اجزای فیزیکی شــبکه مانند اتصاالت ،پروکسی ها و سوئیچها نباید در دسترس
همه باشــند و باید از وسایل امنیتی فیزیکیای همچون دربهای قفلدار ،محافظ اتصاالت و کابلها استفاده
کرد.
حمله ARP
هکر با ســاختن بسته ARPجعلی و فرستادن آن به شبکه ،ســعی میکند آدرس سختافزاری کارت شبکه
خود را به آدرس آی پی فرد موردحمله نسبت دهد تا بتواند خود را در ظاهر او درآورد و در تلفن و سیستم
تلفنی وی اختالل ایجاد کند.
2
جعل آدرس سختافزاری
ســاخت یک گره با یک آدرس سختافزاری تکراری در شبکه است .این حمله باعث از کار انداختن گره
اصلی با آدرس ســختافزاری مشــابه میگردد و میتواند خود را بهجای آن گره که قب ً
ال در شــبکه احراز
هویت شده ،جا بزند .یکراه حل برای مقابله با این حمله این است که نگذاریم گره جدیدی به شبکه اضافه
شود ،قبل از اینکه از طریق درگاه ارتباطی احراز هویت شود.
3
جعل آدرس IP
با این حمله ،هکر میتواند بدون احراز هویت به شــبکه یا رایانه دیگری با جعل آدرس آی پی متصل شــود.
این فن برای به دســتگرفتن کنترل گرههای انتهایی در شــبکه ویپ به کار میرود .برای جلوگیری از این
حمله ،مســیریاب نباید به بســتههایی آی پی دهد که آدرس مقصد آنها شبکه داخلی است و بستهها چنانچه
آدرس مبدأ در آنها ذکر نشده باشد ،نباید اجازه مسیریابی به بیرون را داشته باشند.
بستههای نامعتبر
1
در این روش ،هکر در شــبکه ســعی در تولید بســتههای معیوب میکند ،به نحوی که پردازش این بستههای
معیوب باعث مصرف منابع شبکه شود .جلوگیری از این حمله شامل دو فاز است .فاز اول ،تمام تلفنها باید
دارای نرمافزار بهروز باشــند و در فاز دوم ،شبکه باید دارای یک دیوار آتشین با قابلیت باال برای جلوگیری
از ورود بستههای معیوب باشد.
2
حمله سیلآسای پیام SYNدر پروتکل TCP
در این حمله ،هکر بســتههای زیادی با آدرسهای مقصد تصادفــی تولید میکند که در همگی آنها پرچم
SYNبه گونهای تنظیمشــده است که درخواســت بافر از گره پذیرنده این پیامها را داشته باشند .با پر شدن
فضــای بافــر گره ،قربانی قادر به برقــراری تماس نخواهد بود .راهحل مقابله با این حمله ،اســتفاده از دیواره
آتش با توانایی باال و داشتن پیامهای تصدیق پیام ACKبر اساس ترتیب ارسال ،پیش از پر شدن فضای بافر
گره مربوطه است.
3
حمله بازپخش پروتکل UDPو TCP
در این حمله ،هکر بســتههای اطالعاتیای نظیر احراز هویت ،مکالمات صوتی و ...را به دســت میآورد و
میتواند این پیامها را در شــبکه دوباره بازپخش کند .یکی از راههای جلوگیری از این حمالت ،رمزنگاری
شماره ترتیب جلسات و بازگشایی رمز در مقصد برای به دست آوردن شماره مقصد درست است.
حمله TFTP
تلفنهای ویپ در شــبکه ،تنظیمات و نرمافزارهای بهروز خود را از فایل سرور با پروتکل TFTPمیگیرند.
هکر میتواند با ســاختن یک فایل در ســرور مجازی ،تنظیمات اشــتباهی را به کاربران اختصاص دهد که
ممکن است باعث دستکاری صورتحسابها شود .یکی از راههای جلوگیری از این حمالت ،استفاده از
پروتکل TLSو امنسازی ارتباطات بهوسیله پروتکل SSLاست.
حمله DHCP
در این حمله ،هکر با تولید تصادفی آدرسهای سختافزاری شبکه و گرفتن آی پی از سرور DHCPسعی
در پر کردن استخر آی پی در سرور DHCPدارد و هیچیک ازتجهیزات دیگر نمیتوانند از سرور ،DHCP
آی پــی بگیرند .یکراه جلوگیری از این حمله ،احراز هویت آدرس ســختافزاری کارت شــبکه هنگام
فرستادن درخواست آی پی است.
حمله ICMP
در این حمله ،هکر با فرســتادن بستههای زیاد ICMPســعی در پایین آوردن کارایی گره قربانی دارد .یکی
از راههای جلوگیری از این حمله ،بلوک کردن بستههای ICMPغیرضروری است و یکی دیگر از راههای
مقابله ،جداسازی شبکه داده از صدا بهوسیله ایجاد شبکه مجازی ۱جداگانه است.
حمله به سیستمعامل
بســیاری از حملهها ،شــناخته و ناشــناخته روی تلفنهای ویپ به علت ضعف در سیستمهای عامل است که
میتوان تلفنهای نرمافزاری را روی میز کار این سیســتمعاملها نصب کرد .برای جلوگیری از این حملهها
باید از وصلههای امنیتی بهروز برای سیستمعامل استفاده کرد.
ویروسها
ویروسها نیز از ضعف سیســتمعامل استفاده میکنند ،به سیســتم گرههای انتهایی و دروازهها نفوذ میکنند
و باعث کاهش کارایی گره مربوطه میشــوند .روش مقابله با این حمله ،اســتفاده از وصلههای امنیتی بهروز
برای سیستمعامل است.
1- VLAN
509 امنیت در سیستم تلفنی استریسک
حملههای شناختهشــده به پایگاههای معروف میتوان بهراحتی دادههای CDRرا دســتکاری کرد به همین
منظور یکی از راههای مقابله با این حملهها ،جداســازی پایگاه داده و قرار دادن آن در یک شــبکه مجازی
جداگانه است .این جداسازی جلوی ارسال و دریافت دادههای غیرمجاز را میگیرد.
پروتکل SIPیک پروتکل متنی و قابل خواندن است ،بهطوریکه اگر محتویات آن را مشاهده کنیم ،متوجه
نوع درخواست و sessionآن خواهیم شد .برای مثال برنامه زیر را در نظر بگیرید:
INVITE sip:marconi@radio.org SIP/2.0
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bKf
Max -Forwards: 70
>To: G. Marconi <sip:MarconiOradio.org
From: Nikola Tesla <sip:n.teslaehigh-voltage.org>;tag=7634
Call -ID: 123456789@lab.high-voltage.org
CSeq: 1 INVITE
Subject: About That Power Outage...
>Contact: <sip:n.tesla@lab.high-voltage.org
Content -Type: application/sdp
Content -Length: 158
v=0
o=Tesla 2890844526 2890844526 IN IP4 lab.high-voltage.org
s=Phone Call
c=IN 1P4 100.101.102.103
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
در بدنه پروتکل ،SIPپروتکل SDPهم وجود دارد .به واسطه این پروتکل ،میتوان نیازمندیهای الزم برای
برقراری sessionرا مشــاهده کرد؛ همچنین اطالعاتی نظیر نوع کدک مورد اســتفاده ،پورت برای دریافت
دادههای صوتی و تصویری و ...در این نوع پروتکل بهصورت متنی ذخیره میشوند .همین امر سبب میشود
که هکرها بهراحتی بتوانند این پروتکل را مورد حمله و نفوذ قرار دهند.
پروتــکل SIPمیتوانــد در الیه انتقال ،از پروتکلهای TCPو UDPاســتفاده کنــد .در صورت نیاز به
کدگــذاری این پروتــکل ،بهگونهایکه دیگر قابل خواندن نباشــند ،باید از پروتــکل ۱ TLSدر الیه انتقال
استفاده کرد.
برای انتقال سیگنالینگ در شبکههای ویپ باعث میشود این پروتکل رمزنگاری شود؛ از طرف دیگر برای
انتقال دادههای صوت ) (RTPباید از پروتکل رمزنگاری RTPبه نام SRTPیا ZRTPاستفاده کرد .در این
صورت هم سیگنالیک و هم مدیا در شبکههای ویپ رمزنگاری میشوند.
ابتدا برای استفاده از پروتکل TLSدر شبکههای ویپ باید بستههای مورد نیاز را نصب کنید:
;RHEL
yum install openssl-devel
;Ubuntu
apt-get install libssl-dev
بعد از نصب نیازمندیهای فوق باید در فایل sip.confاستفاده از پروتکل TLSرا فعال کنید:
;sip.conf
][general
tlsenable = yes
;tlsbindaddr = ::
را تولید و به استریسک معرفی نمایید. در مرحله بعد باید کلیدهای رمز نگاری
اجــازه دهیــد اینجا دو ســناریوی متفاوت را بررســی کنیم .در حالــت اول فرض کنید بخواهیم دو ســرور
استریســک با هم یک ارتباط امن داشــته باشــند و در حالت دوم کالینتهایی هستند که قرار است با سرور
استریسک ارتباط امن داشته باشند.
در هر دو حالت به این نیاز داریم که کلیدهای رمزنگاری تولید شــوند و از آنها در ســرورهای استریسک
و کالینتها اســتفاده کنیم .در مســیر فایلهای اصلی استریســک ،اســکریپتی وجود دارد که به واسطه آن
میتوان فایلها و کلیدهای رمزنگاری را تولید نمود .همچنین میتوان از ابزار openSSLبرای ایجاد فایلها
و کلیدهای رمزنگاری استفاده کرد .اینجا از روش اول استفاده میکنیم.
ابتدا یک فایل با نام دلخواه ایجاد کنید تا بتوانید فایلها و کلیدهای رمزنگاری را در آن ذخیره کنید.
# mkdir /etc/asterisk/certificates
با اجرای دســتور باال ،از شــما درخواست میشــود که رمز عبوری را مشخص و وارد نمایید .اینجا باید یک
رمز عبور به دلخواه وارد کنید .در ادامه مهمترین پارامترهای استفاده از اسکریپت فوق را شرح میدهیم.
511 امنیت در سیستم تلفنی استریسک
• پارامتر : -Cبرای مشــخص کردن آدرس آی پی یا DNSســرور استریسک است(این پارامتر اختیاری می
باشد و در صورت لزوم باید آدرس آی پی سرور استریسک خود را جایگزین نمایید).
• پارامتر : -Oبرای مشخص کردن نام شرکت استفاده میشود.
• پارامتر : -dآدرس مسیر برای ذخیره کردن فایلها و کلیدهای رمزنگاری است.
پس از اجرای دستور فوق ،باید فایلهای زیر در مسیر مشخص شده ایجاد شده باشند.
#ls /etc/asterisk/certificates/
asterisk.crt asterisk.csr asterisk.key asterisk.pem ca.cfg ca.crt ca.key tmp.cfg
پس از انجام تغییرات فوق ،باید سرور استریسک را مجددا راه اندازی کنید .برای این منظور در کامند الین
استریسک دستور زیر را اجرا کنید.
CLI> sip reload
Reloading SIP
== Parsing '/etc/asterisk/sip.conf': Found
== Parsing '/etc/asterisk/sip_custom.conf': Found
== Parsing '/etc/asterisk/users.conf': Found
== Using SIP CoS mark 4
== TLS/SSL ECDH initialized (secp256r1), faster PFS cipher-suites enabled
== TLS/SSL certificate ok
== Parsing '/etc/asterisk/sip_notify.conf': Found
همانطورکه مالحظه میکنید TLSفعال شده است .همچنین میتوانید صحت فعال بودن TLSدر استریسک
بهصورت زیر بررسی نمایید. را روی پورت ۵۰۶۱
#netstat -nlpt | grep 5061
tcp 0 0 0.0.0.0:5061 *0.0.0.0: LISTEN 1275/asterisk
با اجرای دستور فوق ،باید رمز عبور قبلی را وارد کنید .در این مرحله بر اساس فایلها و کلیدهای رمزنگاری،
فایلهایی ایجاد میشــوند که کالینتها به واســطه آنها ،اطالعات خود را رمزنگاری و برای سرور ارسال
میکنند.
در ادامه به مهمترین پارامترهای استفاده از اسکریپت فوق میپردازیم.
• پارامتــر : –m clientبــا ایــن پارامتر مشــخص میکنیم که کلید تولید شــده برای کالینتها (نه ســرور
استریسک) قابل استفاده است.
• پارامتر : –cنام فایل CAتولیدشده بهوسیله اسکریپت در استریسک را مشخص میکند.
• پارامتر : –kنام فایل حاوی کلید برای فایل CAرا مشخص میکند.
• پارامتر : –Cمیتوانیم آدرس آیپی کالینت را بهوســیله این پارامتر مشخصکنیم(این پارامتر اختیاری می
باشد و در صورت لزوم باید آدرس آی پی کالینت خود را جایگزین نمایید).
• پارامتر : –Oبرای مشخص کردن نام شرکت استفاده میشود.
• پارامتر : –dآدرس مسیر برای ذخیره کردن فایلها و کلیدهای رمزنگاری است.
• پارامتر : –oنام فایلها و کلیدهای جدید بهوسیله این پارامتر مشخص میشود و برای کالینت قابل استفاده
است.
اکنون اگر فایل certificatesرا مجددا ً بررسی کنیم ،محتویات آن بهصورت زیر خواهد بود:
# ls /etc/asterisk/certificates/
asterisk.crt asterisk.csr asterisk.key asterisk.pem ca.cfg ca.crt ca.key Phone_1.crt
Phone_1.csr Phone_1.key Phone_1.pem tmp.cfg
پارامتر مهم برای تعریف این کاربر ،مشــخص کردن پروتکل TLSبرای ارتباط با ســرور استریسک ،پورت
و اســتفاده از SRTPبرای رمز کردن صداست .در نظر داشتهباشید که باید فایلهای Phone_1.pem ۵۰۶۱
513 امنیت در سیستم تلفنی استریسک
و ca.crtرا در اختیار کالینت قرار دهید .با این تنظیمات کاربر Phone_1از طریق پروتکل tlsباید به سرور
استریسک رجیستر شود.
اینجا باید آدرس ســرور دوم استریســک ) (192.168.1.102را وارد نمایید .فایلها و کلیدهای رمزنگاری
با نام serverBایجاد خواهند شــد .اکنون باید تنظیمات تعریف ترانک را در هر ســرور بهصورت جداگانه
انجام دهید.
نحوهی تنظیمات برای سرور استریسک را قب ً
ال توضیح دادهایم .این تنظیمات بهصورت زیر است:
;ServerA
;sip.conf
tlsenable=yes
tlsbindaddr=0.0.0.0
tlscertfile=/etc/asterisk/certificates/asterisk.pem
tlscafile=/etc/asterisk/certificates/ca.crt
tlscipher=ALL
tlsclientmethod=tlsv1
پس از انجام تنظیمات فوق در هر دو ســرور ،باید یک ترانک بین دو ســرور ایجاد کنید و نوع پروتکل را
TLSانتخاب نمایید .برای مثال در سمت سرور استریسک تنظیمات تعریف ترانک بهصورت زیر است:
;serverA
;sip.conf
][serverB
type = peer
host = 192.168.1.102
مرجع آموزش ویپ با سافتسوئیچ استریسک 514
defaultuser = serverA
secret = apples
context = incoming
disallow = all
allow = ulaw,alaw
transport = tls
canreinvite=no
directmedia=no
deny=0.0.0.0/0.0.0.0
permit=0.0.0.0/0.0.0.0
insecure=invite,port
qualify=yes
encryption=yes
به این منظور در محیط. کنیمreload راchan_sip باید ماژول،پس از انجام تنظیمات فوق برای هر دو سرور
:کامندالین استریسک دستور زیر را برای هر دو سرور اجرا کنید
CLI> sip reload
چنین خطایی در کامندالین استریسک در هر دو سرور، کردن ماژولreload ممکن است بعد از:نکته مهم
:مشاهده شود
[Oct 26 15:07:47] ERROR[1899]: tcptls.c:209 handle_tcptls_connection: Certificate did not
verify: certificate signature failure
[Oct 26 15:04:30] ERROR[2401]: tcptls.c:666 handle_tcptls_connection: Certificate common
name did not match (192.168.1.26)
515 امنیت در سیستم تلفنی استریسک
ایــن خطــا زمانــی رخ میدهد که آدرس ســرورها را هنگام تعریف کلید رمزنگاری به درســتی مشــخص
نکردهباشید .برای حل این خطا یا باید دوباره کلیدهای رمزنگاری را بر اساس آدرس سرورها ایجاد کنید و
یا از طریق فایل ، sip.confتنظیمات بررسی آی پی سرورها را در هر دو سرور استریسک غیرفعال نمایید:
;sip.conf
tlsdontverifyserver=yes
سپس باید مجددا ً ماژول chan_sipرا reloadکنید .پس از انجام تنظیمات فوق برای هر دو سرور ،باید یک
ارتباط سیگنالینگ از نوع رمز شده ایجاد شدهباشد.
اکنون میتوان دربرنامهنویســی استریســک از طریق تنظیم کردن تابع CHANNELارتباط رمزشده را
بهصورت زیر ایجاد کرد:
;serverA
;extensions.conf
][LocalSets
)exten => 800,1,Set(CHANNEL(secure_bridge_signaling)=1
)same => n,Dial(SIP/1234@serverB
در ســمت دیگر میتوان بررســی کرد که آیا ارتباط تماس ورودی جدید از نوع رمزنگاری شده است یا نه.
این کار بهوسیله تابع CHANNELبهصورت زیر انجام میشود:
;serverB
;extensions.conf
][incoming
)(exten => _X.,1,Answer
)same => n,GotoIf($["${CHANNEL(secure_signaling)}" = "1"]?secure:insecure
)same => n(secure),NoOp(Signaling is encrypted.
)(same => n,Hangup
)same => n(insecure),NoOp(Signaling is not encrypted.
)(same => n,Hangup
تا اینجا سیگنالیگ را در سرور استریسک رمزنگاری کردیم .اکنون فرض کنید بخواهیم مدیا )صدا( را هم
رمزنگاری کنیم .ازآنجاکه دادهها از طریق پروتکل RTPدر شــبکه جابجا میشوند ،در ادامه به آن خواهیم
پرداخت.
استفاده از res_srtp.so
با توجه به اینکه ماژول res_srtp.soبهصورت پیشفرض غیرفعال اســت ،بنابراین برای اســتفاده از آن ابتدا
باید آن را فعال کنید .به همین منظور ابتدا نیازمندیهای ماژول را نصب وسپس استریسک را مجددا ً کامپایل
کنید:
;RHEL
yum install libsrtp-devel
;Ubuntu
apt-get install libsrtp-dev
چنانچه هم اکنون ماژول را بررســی کنید ،مشــاهده خواهید کرد که ماژول به درستی نصب شده و بهوسیله
استریسک قابل شناسایی است )شکل .(4-۱8
شکل 4-18
سپس ادامه نصب استریسک را انجام دهید:
#make
#make install
پس از نصب استریسک ،به محیط کامندالین استریسک بروید و قسمت نصب ماژول res_srtp.soرا بررسی
کنید:
CLI> module show like res_srtp.so
Module Description Use Count
res_srtp.so Secure RTP (SRTP) 0
1 modules loaded
517 امنیت در سیستم تلفنی استریسک
همانطور که مشاهده میکنید ،بهوسیله تابع CHANNELدادههای RTPرا میتوان بهصورت رمزنگاریشده
SRTPانتقال داد.
در نمونههای قبل ،ارتباطات را میان دو »ســرور استریسک« بهصورت رمزنگاری شده انتقال دادیم .این
سرویس میتواند بین »یک سرور استریسک« و »کالینتها« نیز انجام پذیرد.
بــرای فعال کردن رمزنگاری در پروتکل ، IAX۲مراحل کار به مراتب ســادهتر از دو پروتکل قبلی خواهد
بود .این سرویس با تنظیم پارامترهای زیر در فایل iax.confفعال میشود.
iax.canf
][general
encryption = yes
forceencryption = yes
همانطــور کــه مالحظه میکنید ،پیــام » « No matching peer foundبیان میکنــد که چنین کاربری در
مرجع آموزش ویپ با سافتسوئیچ استریسک 518
سیستم تلفنی تعریف نشده است .پس هکر بهراحتی میتواند متوجه این موضوع شود و نوع حملههای خود
را هوشمندانهتر انجام دهد.
شــاید این ســوال مطرح شــود که خروجی در محیط کامندالین استریسک اســت و شخص هکر نمیتواند
دسترسی به این صفحه مدیریتی داشته باشد ،پس چطور متوجه این موضوع خواهد شد؟ در پاسخ باید گفت
که اگر با وایرشارک 1پیامها را بررسی کنیم ،خروجی بهصورت زیر خواهد بود )شکل .(۵-۱8
شکل 5-18
همانطور که مالحظه میکنید ،استریســک پیام » « SIP 2.0 404 not foundرا ارسال میکند که مشخص
کننده این است که کاربر در سیستم تلفنی استریسک نامعتبر است.
اکنون اگر پارامتر alwaysauthreject=yesباشد ،نتیجه دستورات در کامندالین استریسک و وایرشارک
بهصورت زیر خواهد بود:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 81.18.114.4:33292;branch=z9hG4bK-d8754z-c7410756b53dfb75-1---
d8754z-;received=81.18.114.4;rport=33292
From: "221"<sip:221@XXX.XXX.XXX.XXX>;tag=0b6ed73e
To: "221"<sip:221@XXX.XXX.XXX.XXX:5060>;tag=as3ca2a3e1
Call-ID: ODQyZjQyM2FlZWE1NmUzYWIyZTNmMGE0Nzk0Yjk4YjQ.
CSeq: 1 REGISTER
User-Agent: Asterisk PBX
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY
Supported: replaces
"WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="484340d0
Content-Length: 0
1- wireshark
519 امنیت در سیستم تلفنی استریسک
شکل 6-18
-۳حتماًَ از پسوردهای دشوار استفاده کنید .نرم افزارهایی هستند که پسوردهای پیچیده تولید میکنند.
-4اگر از پروتکل SIPاســتفاده میکنید حتما TLSرا فعال کنید و اگر از پروتکل IAX۲اســتفاده میکنید
حتما از key-base authenticationاستفاده کنید.
-۵از نرم افزار fail2banاستفاده کنید .این نرم افزار syslogاستریسک را میخواند و براساس آن firewall
سیستم را updateمیکند )نصب fail2banرا به خواننده واگذار میکنیم(.
-۶برای رمزنگاری دادههای ، RTPحتماً از SRTPاستفاده کنید و یا اگر از پروتکل IAX2استفاده میکنید
حتماً پارامترهای encryption=yesو forceencryption = yesرا فعال نمایید.
-7در برنامهنویســی استریسک ،سطوح دسترسی را در تعریف کانتکستها رعایت کنید .به این صورت که
امکان دسترسی غیرقانونی برای داخلیهای سیستم و سایر افراد وجود نداشته باشد.
-8بــرای جلوگیری از حمله » ، «dialplan injectionحتما از تابع )( FILTERدر برنامههای خود اســتفاده
نمایید .نحوه استفاده از این تابع بهصورت زیر خواهد بود:
CLI> core show function FILTER
][Syntax
)FILTER(allowed-chars,string
;extensions.conf
][LocalSets
)})}exten => _X.,1,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN
)same => n,Dial(IAX2/otherserver/${SAFE_EXTEN},30
-۹اگر از FastAGIو یا AMIاســتفاده میکنید ،چون دادهها روی شــبکه منتقل میشــوند ،حتماً آنها را
رمزنگاری کنید و یا در شــبکهای امن آنها را انتقال دهید )بهعنوان مثال دسترســی به FastAGIرا محدود
کنید و برای انتقال رویدادها از طریق AMIاز پروتکل TLSاستفاده کنید(.
-۱۰در پروتکل IAXپارامترهایی برای کنترل حملههای DDOSوجود دارد ،بهتر است آنها را بسته به نیاز
خود تنظیم کنید .این پارامتر در زیر لیست شدهاند.
• Calltokenoptional
• Maxcallnumbers
• Maxcallnumber
• Nonvalidated
مرجع آموزش ویپ با سافتسوئیچ استریسک 520
-۱۱حتما پارامترهای denyو permitرا در تعریف داخلیها تنظیم کنید )برای راحتی کار و پرهیز از تکرار
میتوانید از ACLها استفاده کنید( .بهعنوان مثال فرض کنید بخواهیم برای داخلیها ،یک رول تعریفکنیم.
برای تعریف رولها از فایل acl.confدر مسیر زیر استفاده کنید.
#vim /etc/asterisk/acl.conf
][local_phones
deny=0.0.0.0/0.0.0.0
permit=192.168.1.0/255.255.255.0
اکنون در تعریف کاربران ،نیازی به تعریف پارامترهای denyو permitوجود ندارد .به جای آنها ،پارامتر
aclرا مقدار دهید .فرض کنید بخواهیم داخلی phoneAرا تعریف کنیم:
;sip.conf
][phoneA
;deny=0.0.0.0/0.0.0.0
;permit=192.168.1.0/255.255.255.0
acl= local_phones
type=friend
-۱۲از پارامتــر call-limitبــرای محدودکردن تعداد تماسهای همزمان اســتفاده کنید )این پارامتر هنگام
تعریف ترانکها مورد اســتفاده قرار میگیرد( .الزم به توضیح است که استفاده از این پارامتر در نسخههای
جدید استریســک کمتر توصیه شده است و بهجای آن اســتفاده از توابع Groupو Group_Countپیشنهاد
میشــود .در فصل بیستم )آشنایی با دستورات و توابع پرکاربرد استریسک( با این توابع آشنایی بیشتری پیدا
خواهید کرد.
;sip.conf
][SIPTrunklimit
type=friend
host=server2_IP_add
call-limit=1
context=from-Trunk
-۱۳دسترسی به محیط کامندالین استریسک برای همگان فعال نباشد و فقط در اختیار مدیر سیستم باشد.
نتیجهگیری
از مهمترین ســرفصلهای امنیت ،امنیت تجهیزات مخابراتی و شبکههای ویپ است .عدم رعایت مالحظات
امنیتی در این نوع شــبکهها ،میتواند خســارات جبرانناپذیری بهوجود آورد .ازآنجاکه نفوذ به یک شــبکه
ویــپ به منزله دسترســی کامل به شــبکه و ایجاد تماسهــای بدون محدودیت اســت ،از جنبههای مختلف
اقتصادی ،سیاسی و امنیتی میتواند آسیبهای جدی به شبکه وارد شود .متأسفانه امروزه به دلیل عدم رعایت
مالحظات امنیتی در سافتسوئیچهای نرمافزاری ،شاهد هزینههای هنگفت در قبوض مشتریان هستیم .در این
فصل سعی کردیم مهمترین مالحظات امنیتی در خصوص سافتسوئیچ استریسک را مطرح کنیم.
فصل نوزدهم
ازریابیعملکردسیستمهایتلفنی
IPPBXو تجهیزات وابسته
مرجع آموزش ویپ با سافتسوئیچ استریسک 522
مقدمه
انتقــال صــدا ازطریق اینترنت یا فنــاوری ویپ نه تنها باعث بهوجود آمدن نســلی جدیــد در زمینه برقراری
ارتباطات با هزینههای کمتر شده بلکه به یک ابزار ضروری و سودمند برای بسیاری از بازارهای تجاری دنیا
و کمپانیهای تولید کننده تجهیزات ویپ ،تبدیل شدهاست.
یکی از دالیل اصلی توســعه و رشــد ســریع شــبکههای ویپ ،کاهش هزینههای مکالمات تلفنی است.
ویژگیهایی مانند قابل حمل بودن ،دســترسپذیری و همگرایی این شــبکهها ،از مهمترین دالیلی است که
شــبکههای ویپ را بســیار جذاب و ســودمند کرده اســت .پروتکلهای SIP، IAXو H.323از مهمترین
پروتکلهایی هســتند که در شــبکه های ویپ استفاده میشوند .همچنین با گســترش استفاده از آی پی در
شبکههای مخابراتی و افزایش قابلیت این شبکهها در پشتیبانی از تماسهای چندرسانهای ،استفاده از پروتکل
SIPنیز رواج بیشتری یافته اســت و به دلیل سادگی و پتانســیلی که دارد ،برای توسعهی پهناور ،قابل قبول
اســت SIP .پروتکل الیهکاربرد اســت که برای نگهداری و به پایان رساندن جلسههای چندرسانهای استفاده
میشود .از همین رو اکثر کمپانیها برای تولید تجهیزات خود از این پروتکل پشتیبانی میکنند.
کیفیت سرویس در تجهیزات ویپ از دیگر مسائلی است که از اهمیت ویژهای برخوردار است .از یک
طرف چون ویپ از بســتر آی پی برای برقراری یک نشســت ارتباطی اســتفاده میکند ،هیچ گونه تضمینی
در خصــوص کیفیت ســرویس ارائه نمیدهد و از طــرف دیگر اگر تجهیزات ویپ از اســتانداردهای الزم
برخوردار نباشند ،کارایی و کیفیت سرویس را کاهش میدهند .بنابراین ،استفاده از محصوالت و تجهیزات
ویپ که دارای استانداردهای الزم باشند از اهمیت ویژهای برخوردار است.
523 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
اکنون این ســؤال مطرح میشود که چگونه میتوان کیفیت ســرویس تجهیزات در شبکه های ویپ را
بررسی کرد؟ و یا اینکه چگونه میتوان مطمئنشد تجهیزات دارای استانداردهای الزم هستند؟
• تســت انطباق با تســت کارکرد و کارایی چه تفاوتی دارد و هر یک برای کدامیک از تجهیزات انجام
خواهد شد؟
• مدت زمان تعریف شده برای تست تجهیزات چگونه تعریف میشود؟
• توزیع ارالنگ ۱برای یک سوئیچ تلفنی چگونه تعریف میشود؟ آیا برای تست کارکرد و کارایی ،این
توزیع الزم است؟
پرواضح اســت که اینگونه ســؤاالت و صدها سؤال دیگر مستلزم داشــتن یک بستر مطمئن و امن برای
برآوردن نیازهای اولیه و سنجش دقیق سوئیچهای تلفنی تحت شبکه خواهد بود.
-1توزیع ارالنگ :این توزیع از انواع توزیعهای احتمال پیوسته است که مدت زمان الزم برای وقوع nرویداد کام ً
ال تصادفی را
نشان میدهد .این توزیع بیشتر در مباحث تئوری صف ،ترافیک (مکالمات تلفنی) ،تعداد تماسهای همزمان به یک مرکز سوئیچ
مخابرات استفاده میشود.
525 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
دیگر تغییر مجوز PAPبه FCPهمگی نزدیکشدن به یک تحول و انقالب در زمینه مخابرات و سیستمهای
تلفنی را نوید میدهند.
در همین راستا ،تحقیق و پژوهش در این عرصه نیز سرعت بیشتری به خود گرفته و وجود آزمایشگاههای
مجهز به تجهیزات تســت و آزمایش ،امری بدیهی به حســاب میآید .سازمان تنظیم مقررات که مجری اول
و قانونگذار در این عرصه اســت ،مراکزی تحقیقاتی در بدنه خود دارد که هرکدام در حوزهای تخصصی
در این زمینه فعالیت میکنند.
آزمایشــگاه تســت تجهیزات IPPBXدانشگاه فردوسی مشهد یکی از آزمایشــگاههای معتبر در کشور
است که با مجوز سازمان تنظیم مقررات و ارتباطات کشور ،در این راستا تحقیقات و فعالیت میکند .مسلماً
چنین آزمایشگاههایی مجهز به تجهیزات پیشرفته و البته گران قیمت خواهد بود .برای مثال آزمایشگاه تست
تجهیزات IPPBXدانشــگاه فردوســی مشــهد از تجهیزات Spirentبرای تست سیســتمهای تلفنی IPPBX
استفاده میکند.
در این فصل قصد داریم به بررسی و ارزیابی عملکرد سیستمهای تلفنی IPPBXو تست تجهیزات ویپ
بپردازیم .یکی از عوامل مؤثر در بررسی و ارزیابی عملکرد شبکههای تلفنی و تجهیزات ویپ این است که
بتوان یک شبکه ویپ را بهصورت یک »مدل« معرفی کرد.
برای مثال میخواهیم در یک سیســتم تلفنی طراحی شــده ،حداکثر تعداد تماس قابل پذیرش بهوســیله
سیســتم را اندازهگیری کنیم .آنچه بهعنوان هدف در طراحی ،مطرح میشود حداکثر تعداد تماسهای قابل
پذیرش است که باید آن را بهصورت مدل بیان کنیم.
Goal: Max Call
∀ all states is normal conditions
در تعریف مدل باال ،هدف طراحی سیستم را بهصورت مدل ریاضی بیان کردهایم.
«حداکثر تعداد تماس در شرایطی که همه پارامترهای وضعیت در سیستم در حالت نرمال باشند».
ابزارهای شبیهسازی
واضح اســت که استفاده از ابزارهای مناسب برای شبیهسازی یک سیســتم ،میتواند در طراحی یک سیستم
کمک شایانی کند.
ابزارهای شبیهسازی به سه دسته تقسیم میشوند:
-1استفاده از نرمافزارهای برنامهنویسی چند منظوره ،از قبیل C , C++ , javaو . ...
. GPSS , SIM Script II.5 -2استفاده از زبانهای برنامهنویسی شبیهسازی ،از قبیل
-3استفاده از ابزارهای شبیهسازی ،از قبیل . ns2, opnet, network II.5
در این فصل عمدتا با ابزارهای تست سیستمهای تلفنی IPPBXآشنا میشوید .الزمه ایجاد چنین تستهایی،
شــناخت کافی از سیستمهای تلفنی و پروتکلهای وابسته اســت .برای مثال فرض کنید بخواهیم یک تست
انطباق )بررســی سیگنالیگ SIPروی تجهیزات( را طراحی کنیم .مسلماً بدون شناختن پروتکل سیگنالینگ
،SIPنمیتوانیم این سناریوهای تست را طراحی کنیم.
برای مثال فرض کنید یک سیستم تلفنی IPPBXدر اختیار دارید و میخواهید آن را تست کنید .تست
شما در دو حالت قابل تعریف است:
• تســت کارآمدی 1سیستم :در این حالت ،سیســتم تلفنی را بر اســاس نیازهای موجود (شبیهسازی محیط
استفاده کننده) تست و نتایج را بررسی میکنید.
1- Performance
مرجع آموزش ویپ با سافتسوئیچ استریسک 528
• تست انطباق 1سیســتم :در این حالت ،عملکرد سیستم را بر اســاس متابعــت از پروتکل مورد نظر بررسی
میکنید .برای مثال تست عملکرد صحیح سیستم برای پروتکل SIPبه منزله این است که پیامهای سیگنالینگ
پروتکل SIPبرای سیستم ارسال میشود و انتظار میرود که سیستم تلفنی پاسخهای مناسبی بدهد.
ابزارهای زیادی برای شبیهسازی سناریوها وجود دارد .در این کتاب از ابزار SIPPاستفاده خواهیم کرد.
ولی پیش از آن باید با پیامهای سیگنالینگ پروتکل SIPآشنا شوید.
پروتکل SIPیک پروتکل مبتنی بر ایجاد نشســت در شــبکههای ویپ است که بهوسیله 2 IETFبهصورت
یک استاندارد در RFC3261درآمده است .در این پروتکل آدرس کاربران در شبکه بهصورت زیر تعریف
میشود.
• User1@SipDomainA.com
• 552548@SipDomainB.com
• 5131770@SipDomainC.com
در این پروتکل ،هر کاربر شبکه میتواند پیامهایی را ارسال و دریافت کند .مهمترین پیامها در جدول ۱-۱۹
لیست شدهاند.
پیام :ACKاین پیام به منزله تأیید برقراری نشســت بین دو کاربر اســت .زمانی که کاربری تماس را پاســخ
میدهد ،بعد از ارســال پیام 200OKباید منتظر پیام ACKباشــد .اگر این پیام دریافت نشود ،تماس بعد از
1- Conformance
2- Internet Engineering Task Force
529 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
شکل 1-19
همانطورکه مالحظه میکنید ،ابتدا یک پیام REGISTERاز طرف کاربر برای استریســک ارسال میشود.
استریســک با به چالش کشــیدن کاربر ،از او درخواســت اطالعات امنیتی )نام کاربری و رمزعبور( میکند.
مرجع آموزش ویپ با سافتسوئیچ استریسک 530
اگر. را به همراه اطالعات نام کاربری و رمزعبور ارســال کندREGISTER ســپس کاربر باید دوباره پیــام
باRegistration از طرف استریســک ارسال خواهد شــد و عملیات200OK پیام،اطالعات درســت باشــد
. در زیر لیست این پیامها به ترتیب شکل نمایش داده میشود.موفقیت انجام میشود
REGISTER sip:192.168.141.128:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.141.1:61668;branch=z9hG4bK-d8754z-2a10d04cd243b01e-1---
d8754z-;rport
Max-Forwards: 70
Contact: <sip:100@192.168.141.1:61668;rinstance=57e8c42255f0c484>
To: "100"<sip:100@192.168.141.128:5060>
From: "100"<sip:100@192.168.141.128:5060>;tag=257afb7c
Call-ID: OGZhNWM4OWY2MjkxZjA3Nzc1NjdhYmEyZTk4NDViMWU.
CSeq: 1 REGISTER
Expires: 120
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO,
MESSAGE
Supported: replaces
User-Agent: 3CXPhone 6.0.20943.0
Content-Length: 0
MESSAGE
Supported: replaces
User-Agent: 3CXPhone 6.0.20943.0
Authorization: Digest username="100",realm="asterisk",nonce="7bfa9049",uri="sip:192.168.
141.128:5060",response="bf4f7fdc6c060e0c8818886d7a6e0509",algorithm=MD5
Content-Length: 0
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.141.1:61668;branch=z9hG4bK-d8754z-b517fd12c8731669-1---
d8754z-;received=192.168.141.1;rport=61668
From: "100"<sip:100@192.168.141.128:5060>;tag=257afb7c
To: "100"<sip:100@192.168.141.128:5060>;tag=as5a1ea03c
Call-ID: OGZhNWM4OWY2MjkxZjA3Nzc1NjdhYmEyZTk4NDViMWU.
CSeq: 2 REGISTER
Server: Asterisk PBX 13.10.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH,
MESSAGE
Supported: replaces, timer
Expires: 120
Contact: <sip:100@192.168.141.1:61668;rinstance=57e8c42255f0c484>;expires=120
Date: Tue, 13 Sep 2016 04:32:10 GMT
Content-Length: 0
2-19 شکل
کاربر یک درخواست جدید برای ایجاد تماس )پیام، هنگام شروع یک تماس،همانطورکه مالحظه میکنید
از او درخواست اطالعات، استریسک با به چالش کشیدن کاربر.( برای استریسک ارسال میکندINVITE
به استریسک این موضوع را تاییدACK کاربر با ارسال پیام،احراز هویت )نام کاربری و رمز عبور( می کند
مرجع آموزش ویپ با سافتسوئیچ استریسک 532
( به همراه اطالعاتINVITE می کند و مجددا اقدام به ارســال درخواســت جدید برای ایجاد تماس )پیــام
به طرف استریسک100Trying پیام،اگر اطالعات درســت باشــد،هویتی)نام کاربری و رمز عبور( می کند
نمایش داده شده است )فیلدهای مهم در پیام، در زیر فهرســت این پیامها بهترتیب شکل.ارســال خواهدشد
.( شده نمایش داده شده استBold بصورت
v=0
o=3cxVCE 28455225 295798545 IN IP4 192.168.141.1
s=3cxVCE Audio Call
c=IN IP4 192.168.141.1
t=0 0
m=audio 40024 RTP/AVP 0 8 3 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:20
a=sendrecv
m=video 40022 RTP/AVP 34
c=IN IP4 192.168.141.1
a=rtpmap:34 H263/90000
a=fmtp:34 QCIF=1;CIF=1;SQCIF=1;CIF4=1;
a=sendrecv
Call-ID: MjgzODcxZmVkMzIwZTUzMjMxYThkOThiMGZmM2MxNjc.
CSeq: 1 INVITE
Server: Asterisk PBX 13.10.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH,
MESSAGE
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="7cf5b422"
Content-Length: 0
v=0
o=3cxVCE 28455225 295798545 IN IP4 192.168.141.1
s=3cxVCE Audio Call
c=IN IP4 192.168.141.1
t=0 0
m=audio 40024 RTP/AVP 0 8 3 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:20
مرجع آموزش ویپ با سافتسوئیچ استریسک 534
a=sendrecv
m=video 40022 RTP/AVP 34
c=IN IP4 192.168.141.1
a=rtpmap:34 H263/90000
a=fmtp:34 QCIF=1;CIF=1;SQCIF=1;CIF4=1;
a=sendrecv
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.141.1:61668;branch=z9hG4bK-d8754z-dc159e3e28332601-1---
d8754z-;received=192.168.141.1;rport=61668
From: "100"<sip:100@192.168.141.128:5060>;tag=e4125f3a
To: <sip:101@192.168.141.128:5060>;tag=as557be705
Call-ID: MjgzODcxZmVkMzIwZTUzMjMxYThkOThiMGZmM2MxNjc.
CSeq: 2 INVITE
Server: Asterisk PBX 13.10.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH,
MESSAGE
Supported: replaces, timer
Contact: <sip:101@192.168.141.128:5060>
Content-Type: application/sdp
Content-Length: 292
535 و تجهیزات وابستهIPPBX ارزیابی عملکرد سیســتمهای تلفنی
v=0
o=root 1403396204 1403396204 IN IP4 192.168.141.128
s=Asterisk PBX 13.10.0
c=IN IP4 192.168.141.128
t=0 0
m=audio 13418 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=maxptime:150
a=sendrecv
m=video 0 RTP/AVP 34
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.141.128:5060;branch=z9hG4bK196959c9;rport=5060
Contact: <sip:100@192.168.141.1:61668;rinstance=57e8c42255f0c484>
To: "100"<sip:100@192.168.141.128:5060>;tag=e4125f3a
From: <sip:101@192.168.141.128:5060>;tag=as557be705
مرجع آموزش ویپ با سافتسوئیچ استریسک 536
Call-ID: MjgzODcxZmVkMzIwZTUzMjMxYThkOThiMGZmM2MxNjc.
CSeq: 102 BYE
User-Agent: 3CXPhone 6.0.20943.0
Content-Length:
ابزار SIPPیکی از ابزارهای مهم و پرکاربرد برای تســت سیســتمهای تلفنی IPPBXاســت .در SIPPاین
قابلیت وجود دارد که بتوان ســناریوهای خود را با جزئیات )نزدیک به واقعیت( طراحی کرد و سیســتمهای
تلفنی را تست و مورد ارزیابی قرار داد.
ســناریوها در SIPPبا زبان XMLطراحی میشــوند که در ادامه درباره آنها توضیح خواهیم داد ولی
پیش از آن باید ابزار SIPPرا نصب کنیم.
برای نصب SIPPابتدا نیازمندیهای آن را نصب میکنیم:
#apt-get install dh-autoreconf ncurses-dev build-essential libssl-dev libpcap-dev libncurses5-
dev libsctp-dev lksctp-tools
: -infدر صورت تمایل به اســتفاده از دادههای پویا در ســناریو ،میتــوان دادهها را در یک فایل بهصورت
CSVذخیره کرد:
>-inf <filename.csv
: -rسرعت اجرای سناریو در واحد زمان بهوسیله این پارامتر مشخص میشود .بهصورت پیشفرض اجرای
سناریو در هر یک ثانیه ) (۱۰۰۰msاست.
>-r <rate in ms
: -rpاجرای ســناریو در فواصل زمانی را مشــخص میکند .برای مثال دســتور زیر یعنی در هر ثانیه ۱۰ ،بار
537 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
: -tدر صورت تمایل به اســتفاده از پروتکل TCPبه جای ،UDPمیتوان آن را بهوسیله این آپشن مشخص
نمود.
-t tcp
: -mحداکثر تعداد کل تماسهایی که بهوســیله SIPPایجاد میشــود را مشــخص میکند .برای مثال یک
سیستم تلفنی را برای 100تماس به صورت زیر تست میکنیم:
-m 100
همانطور که مالحظه میکنید ،با اجرای این دستور ،شرح سناریو بهصورت شکل ۳-۱۹نمایش داده خواهد
شد.
شکل 3-19
ابتدا یک پیام INVITEدریافت میشــود ،ســپس پیام ) 180Ringingبه منزلهی این که گوشی در حال
زنگ خوردن است( ارسال خواهدشد .بعد از آن پیام ) 200OKبه منزلهی اینکه تماس پاسخ داده شدهاست(
مرجع آموزش ویپ با سافتسوئیچ استریسک 538
ارسال میشود .پس از آن باید منتظر دریافت پیام ) ACKتأیید تماس( باشیم .اکنون تماس برقرار شده است.
در این ســناریو تا زمانی که پیام ) BYEخاتمه تماس( دریافت نشــود ،تماس فعال باقی میماند .بعد از
دریافت پیام ،BYEپیام ۲۰۰OKارسال و بعد از 4ثانیه تماس قطع میشود.
همانطورکه مالحظه میکنید ،در طراحی سناریوها ،باید تکتک پیامها را با دقت طراحی کرد و آنها
را در زمان تعیین شده ارسال کرد .هر گونه نقصان در طراحی سناریو ،باعث میشود نتوانیم سیستمهای تلفنی
IPPBXو سایر تجهیزات را دقیقاً تست و بررسی کنیم.
سناریوی :uacبرای استفاده از سناریوی ،uacاین دستور را اجرا کنید:
# cd sipp-3.4.1
># ./sipp -sn uac <remote-server><:remot-port
شکل 4-19
در این سناریو ،ابتدا پیام INVITEایجاد میشود و برای سرور با پورت مشخصی ) (۱۲7,۰,۰,۱:۵۰۶۱ارسال
میگردد .پس از ارســال آن ،ســناریو منتظر دریافت پیامهــای 100Trying، 180Ringing، 183Session
Progressو 200OKبه ترتیب میماند و پس از دریافت پیامهای باال ،پیام ACKرا ارســال میکند .ســپس
)به منزله اینکه تماس ۱۰ثانیه طول میکشــد( و بالفاصله بهوســیله ارســال پیام BYE برای ۱۰ثانیه توقف
تماس را قطع میکند.
اکنون اگر ابتدا ســناریوی uasو سپس ســناریوی uacرا اجرا کنید ،متوجه میشوید که این شبیهسازی
بهوسیله خود ابزار SIPPدر حال اجرا و تولید تماس است.
539 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
شکل 5-19
در این سناریو باید یک پیام OPTIONSایجاد و سپس آن را برای سیستم تلفنی IPPBXارسال کنیم .در
پاســخ باید پیام 200OKرا از ســمت سرور دریافت کنیم .لذا ابتدا یک فایل به اسم OPTIONS.xmlایجاد
و سناریوی خود را در آن طراحی میکنیم.
#vim OPTIONS.xml
>? "<?xml version="1.0" encoding="utf-8
>"<!DOCTYPE scenario SYSTEM "sipp.dtd
>"<scenario name="OPTIONS
><send
[<![CDATA
OPTIONS sip:[remote_ip] SIP/2.0
]Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch
]From: <sip:sipp@[local_ip]>;tag=[call_number
>]To: <sip:sipp@[remote_ip
]Call-ID: [call_id
CSeq: [cseq] OPTIONS
]Contact: sip:sipp@[local_ip]:[local_port
Max-Forwards: 10
User-Agent: SIPp/Linux
Content-Length: 0
Accept: text/plain
>]]
></send
>"<recv response="200
></recv
></scenario
در فایــل ســناریو ،در تگ > <sendدر فایل ،xmlپیــام OPTIONSرا در قالب پروتکل SIPپیادهســازی
میکنیم .در تگ > <recvپیامهایی که باید از طرف مقابل )ســرور ویپ( ارســال شود ،دریافت خواهد شد.
در اکثر ســناریوهای ،SIPPاز تگ> <sendبرای ارســال پیام SIPو از تگ > <recvبرای دریافت پیامهای
مرجع آموزش ویپ با سافتسوئیچ استریسک 540
SIPاستفاده میشود.
در این مثال ســرور استریسک ما دارای آی پی 192.168.141.128است .بعد از تکمیل سناریو ،آن را
بهصورت زیر اجرا کنید .خروجی دستور بهصورت زیر خواهد بود:
#./sipp -sf OPTIONS.xml 192.168.141.128:5060 -r 1
شکل 6-19
میتوان ســرعت اجرای ســناریو را بهصورت زیر افزایش داد .برای مثال در سیستم تلفنی خود بررسی کنید
که تا چه اندازه میتوانید سرعت سناریو را افزایش دهید.
#./sipp -sf OPTIONS.xml 192.168.141.128:5060 -r 100
شکل 7-19
اگر سرعت اجرای سناریو را باال ببرید ،بعد از سپری شدن زمانی محدود ،اکثر پیامها ارسال مجدد )(Retrans
میشوند و این به منزله شروع رسیدن به حد آستانه ظرفیت سیستم تلفنی است و میتواند شرایط بحرانی برای
سیستم تلفنی ایجاد کند.
8-19 شکل
( در سیستم تلفنی استریسک ایجاد و سپس سناریوی زیر راSIP ابتدا تعدادی داخلی )کاربر،در این سناریو
.اجرا میکنیم
#vim register_ok_example_book.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<scenario name="REGISTER">
<send retrans="500">
<![CDATA[
REGISTER sip:[field0]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
To: <sip:[field0]@[local_ip]>
Call-ID: [call_id]
CSeq: [cseq] REGISTER
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Expires: 120
User-Agent: SIPp/Win32
Content-Length: 0
]]>
</send>
][field1
Max-Forwards: 10
Expires: 12000
User-Agent: SIPp/Win32
Content-Length: 0
>]]
></send
><recv response="100" optional="true"></recv
><recv response="200" ></recv
></scenario
همانطور که در فایل مالحظه میکنید ،پارامترهای پیام ] [field0و ] [field1را داریم .قرار است این پارامترها
در اجرای ســناریو مقداردهی شوند .برای مقداردهی این پارامترها ،از فایل register_ok_example_book.
csvبهصورت زیر استفاده میکنیم:
# vim register_ok_example_book.csv
SEQUENTIAL
;]op100;[authentication username=op100 password=op100
در هر بار اجرای ســناریو ،یک رکــورد از فایل register_ok_example_book.csvبرداشــته و مقادیر آن
جایگزین پارامترهای فایل register_ok_example_book.xmlمیشوند.
برای اجرای سناریو از دستور زیر استفاده کنید:
#./sipp -sf REGISTER.xml –inf REGISTER.csv 192.168.141.128:5060 -m 10
شکل 9-19
با اجرای این سناریو در سرعت و تعداد باال ،میتوانید سیستم تلفنی IPPBXرا در عملیات رجیستر شدن
کاربران ،تحلیل و آنالیز نمایید.
بهعنوان مثال فرض کنید بخواهیم عملکرد ســرور استریســک را در عملیات رجیســتر شدن برای ۱۰۰۰
کاربر ،بهطوری که در هر لحظه ۱۰نفر در سیستم رجیستر شوند را بررسی کنیم.
543 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
برای تســت ۱۰۰۰کاربر لزومی ندارد حتماً ۱۰۰۰کاربر تعریف کنید ،بلکه میتوانید همان دســتور باال
را ۱۰۰۰بار اجرا کنید.
#./sipp -sf REGISTER.xml –inf REGISTER.csv –r 10 –rp 1000 192.168.141.128:5060 -m 1000
با اجرای این دستور ،در هر ثانیه ۱۰کاربر در سیستم تلفنی رجیستر میشوند .این کار برای ۱۰۰۰کاربر
اجرا خواهد شد .میتوانید با تغییر پارامترهای وضعیت ،نتایج حاصل را ارزیابی کنید.
شکل 10-19
ابتدا یک فایل ایجاد و ســناریوی INVITEرا بهوسیله SIPPبهصورت زیر طراحی میکنیم )فیلدهای مهم
در پیام بهصورت Boldنمایش داده شده است(:
#vim invite_auth_book_example.xml
>? "<?xml version="1.0" encoding="ISO-8859-1
>"<scenario name=" INVITE + BYE
>"<send retrans="500
[<![CDATA
INVITE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
]Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch
]From: sipp <sip:[field0]@[local_ip]>;tag=[call_number
>]To: <sip:[field2]@[local_ip]:[remote_port
مرجع آموزش ویپ با سافتسوئیچ استریسک 544
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 0
a=rtpmap:0 PCMU/8000
]]>
</send>
<recv response="100" optional="true"></recv>
<recv response="180" optional="true"></recv>
<recv response="183" optional="true"></recv>
<recv response="401" auth="true"></recv>
<send>
<![CDATA[
ACK sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
INVITE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:[field0]@[local_ip]>;tag=[call_number]
To: <sip:[field2]@[local_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: sip:[field0]@[local_ip]:[local_port]
[field1]
Max-Forwards: 10
Content-Type: application/sdp
545 و تجهیزات وابستهIPPBX ارزیابی عملکرد سیســتمهای تلفنی
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 0
a=rtpmap:0 PCMU/8000
]]>
</send>
<recv response="100" optional="true"></recv>
<recv response="180" optional="true"></recv>
<recv response="183" optional="true"></recv>
<recv response="200"></recv>
<send>
<![CDATA[
ACK sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
BYE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] BYE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<recv response="100" optional="true"></recv>
<recv response="200" crlf="true"></recv>
</scenario>
مرجع آموزش ویپ با سافتسوئیچ استریسک 546
شکل 11-19
طبق آنچه انجام دادیم ،سناریو به ترتیب اجرا و یک تماس ازطریق کاربر op۱۰۰شبیهسازی میشود.
قبل از ادامه بحث بهتر است درباره این سناریو بیشتر صحبت کنیم .همانطور که مالحظه میکنید در این
سناریو ،تنها عملیات ایجاد تماس جدید پیادهسازی شده است .واقعیت این است که بعد از ایجاد تماس ،ما
باید بتوانیم دادههای RTPرا تولید کنیم .اینکه چگونه این دادهها را ایجاد کنیم ،در قسمت بعد توضیح داده
میشود ولی قبل از آن بهتر است این سناریو را در حجم باال بررسی کنیم.
فرض کنید بخواهیم عملیات Call Setupرا در حجم باال برای یک سیســتم تلفنی IPPBXبررســی و
ارزیابی کنیم .هدف سناریو میتواند به صورت زیر تعریف شود:
• بررسی و ارزیابی فرایند Call Setupدر سیستم تلفنی IPPBX
• بررسی و ارزیابی فرایند اعتبارسنجی در سیستم تلفنی IPPBX
به عبارت دیگر هردو هدف باال به دنبال این هستند که سیستم تلفنی IPPBXدر شرایطی سخت ارزیابی
شود تا مشخص شود که سیستم ،در هر ثانیه حداکثر چه تعداد میتواند فرایند ایجاد تماس جدید را پوشش
دهد .برای مثال ســرعت ســناریوی قبل را بهصورت مرحله به مرحله افزایش دهید و این کار را تا زمانی که
547 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
پیامها ارسال مجدد نشدهاند ،ادامه دهید .ولی قبل از آن باید تغییر کوچکی در استریسک انجام دهید.
ابتدا پارامتر کانتکست برای کاربر op۱۰۰را بهصورت زیر تغییر دهید:
;sip.conf
][op100
Context=sip_test
اینجا تماس به ســمت استریســک میرود و استریسک آن را پاســخ میدهد ولی به محض پاسخ دادن ،پیام
ِ
تماس جدید و BYEارسال و تماس قطع میشود .در این سناریو ،هدف صرفا بهوجود آوردن فرآیند ایجاد
قطع آن اســت .اکنون ســرعت اجرای سناریو را باال برده و سیستم تلفنی خود را تست کنید .در مثال زیر در
هر ثانیه ۱۰تماس جدید خواهیم داشت .این سناریو برای ۲۰۰تماس اجرا خواهد شد.
#./sipp -sf invite_auth_book_example.xml -inf invite_auth_book_example.csv -r 10 -rp 1000
192.168.141.128 -m 200
همانطــور کــه پیشتر نیز توضیح دادیم ،برای ایجاد یک تماس واقعی بایــد بتوانیم دادههای RTPرا ایجاد
کنیم .ازآنجاکه در سناریو قبل به محض ایجاد تماس جدید ،تماس را قطع میکردیم ،دادههای RTPتولید
نمیشدند .لذا باید تغییراتی را در سناریو ایجاد کنیم .برای ایجاد دادههای RTPاز کد زیر در سناریو SIPP
استفاده میکنیم:
><nop
><action
><exec play_pcap_audio="pcap/g711a.pcap"/
></action
></nop
>"<send retrans="500
[<![CDATA
مرجع آموزش ویپ با سافتسوئیچ استریسک 548
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 0
a=rtpmap:0 PCMU/8000
]]>
</send>
<recv response="100" optional="true"></recv>
<recv response="180" optional="true"></recv>
<recv response="183" optional="true"></recv>
<recv response="401" auth="true"></recv>
<send>
<![CDATA[
ACK sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
INVITE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:[field0]@[local_ip]>;tag=[call_number]
To: <sip:[field2]@[local_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: [cseq] INVITE
549 و تجهیزات وابستهIPPBX ارزیابی عملکرد سیســتمهای تلفنی
Contact: sip:[field0]@[local_ip]:[local_port]
[field1]
Max-Forwards: 10
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 0
a=rtpmap:0 PCMU/8000
]]>
</send>
<recv response="100" optional="true"></recv>
<recv response="180" optional="true"></recv>
<recv response="183" optional="true"></recv>
<recv response="200"></recv>
<send>
<![CDATA[
ACK sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact: sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<pause milliseconds="2000"/>
<nop>
<action>
<exec play_pcap_audio="pcap/g711a.pcap"/>
</action>
</nop>
<pause milliseconds="10000"/>
<send retrans="500">
<![CDATA[
BYE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[field0]@[local_ip]>;tag=[call_number]
[last_To:]
مرجع آموزش ویپ با سافتسوئیچ استریسک 550
]Call-ID: [call_id
CSeq: [cseq] BYE
]Contact: sip:sipp@[local_ip]:[local_port
Max-Forwards: 10
Content-Length: 0
>]]
></send
></scenario
با اجرای دستور باال ،تماس ایجاد میشود و دادههای RTPبین SIPPو استریسک بهصورت دو طرفه ارسال
میشوند .برای مشاهده دادههای RTPدستور زیر را در محیط کامندالین استریسک اجرا کنید.
CLI> rtp set debug on
شکل 12-19
میتوان با ایجاد تماسهای بیشتر ،سیستم تلفنی IPPBXرا در تعداد تماسهای همزمان تست کرد .برای مثال
در دستور زیر در هر ثانیه ۱۰ ،تماس جدید )به همراه انتقال دادههای (RTPایجاد میکنیم.
# ./sipp -sf invite_auth_book_example.xml -inf invite_auth_book_example.csv -r 10 -rp 1000
192.168.141.128 -i 192.168.141.129 -m 100
551 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
شکل 13-19
همانگونهکــه در شــکل ۱۳-۱۹مالحظه میشــود ،زمان Pauseرا صفــر در نظر گرفتهایم تــا فع ً
ال در این
آزمایش درگیر ارســال مدیا نشــویم .همانطور که پیشتر هم توضیح داده شد ،با افزایش مقدار پارامتر ، r
میزان تماسهای ورودی افزایش مییابد .تأثیر این پارامتر بر میزان مصرفی RAMو CPUبهصورت شــکل
۱4-۱۹است:
با توجه به شکل ۱4-۱۹میتوان فهمید که افزایش بار ورودی ،به میزان بیشتری بر CPUو با شیب کمتری
بر RAMتأثیرگذار اســت .همچنین میتوان حدس زد که ظرفیت این ســرور مشخص ،حدود ۲۰۰تا ۲۵۰
تماس بر ثانیه اســت ،چرا که با افزایش rبه بیش از این مقدار ،پیامهای ســیگنالینگ به طرف سرور سرازیر
میشوند و این بدین معنی است که سرور ظرفیت و بهعبارتی منابع الزم برای پاسخگویی به همهی تماسها
را نداشته و ناچار به رد آنهاست ،در نتیجه SIPPنیز آنها را دوباره ارسال میکند.
مرجع آموزش ویپ با سافتسوئیچ استریسک 552
شکل 14-19
تأثیر مدیا ( )RTPبر منابع سیستم تلفنی
در این آزمایش فرض میکنیم که rیا تعداد تماسهای ارسالی در ثانیه برابر با یک باشد تا بتوانیم تنها تأثیر
RTPبــر منابع را بســنجیم .تأثیر تعداد تماسهای همزمان )با در نظر گرفتــن انتقال دادههای (RTPبر میزان
مصرفی RAMو CPUبهصورت شکل ۱۵-۱۹است.
شکل 15-19
553 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
همانگونه که در شــکلهای ۱4-۱۹و ۱۵-۱۹مشــاهده میشــود ،با افزایش RTPمنابع مصرفی نیز بیشــتر
میشود ،اما این افزایش بهطور چشمگیری در CPUبیشتر از RAMاست.
1
از بین رفتن بستهها
تعداد بستههایی که در میانه راه از بین میروند.
شکل 16-19
1
تاخیر
مدت زمانی که طول میکشــد ،بسته از فرســتنده به گیرنده برسد را delayمینامند .در شبکههای ویپ این
تاخیر تا حدی قابل قبول است ولی اگر مقدار آن زیاد شود ،اثرات نامطلوبی روی شبکه خواهد داشت .برای
مثال به شکل ۱7-۱۹توجه کنید.
شکل 17-19
2
تغییرات تأخیر
یکی دیگر از پارامترهای کیفیت ســرویس ،تغییرات تأخیر ) (jitterاســت .به عبارت دیگر تغییرات آماری
در فاصلهی بین بستههای دریافتی در واحد زمان را تغییرات تأخیر میگویند .در پروتکل ،RTPاین محاسبه
1- delay
2- Jitter
555 ارزیابی عملکرد سیســتمهای تلفنی IPPBXو تجهیزات وابسته
بر اســاس زمان ارسال و دریافت بستهها انجام میشود .برای مثال ،اگر نرخ نمونهبرداری از فرکانس صدا در
واحد زمان 8۰۰۰بار باشد ، ۱اینجا باید زمان واحد را بر 8۰۰۰تقسیم کنیم.
پارامتر Jitterدر شــبکههای ویپ بسیار حساس است و تاحدی تغییرات آن قابل قبول است .برای اینکه
تغییرات دقیقتر محاســبه شــود ،آن را بر عدد ( 16که نشان دهنده تغییرات تأخیر برای 16بسته قبلی دریافت
شده است) تقسیم میکنند .فرمول زیر ،محاسبه jitterرا برای نمونههای مختلف نشان میدهد.
J(i)= J(i-1)+(| D(i-1,i) | - J(i-1)) / 16
جدول ۱۹-۲تاخیر و تغییرات تاخیر را برای siو Riهای مختلف نشان میدهد.
همچنین جدول ،4-۱۹حد قابل قبول برای انواع پارامترها و MOSرا در شبکههای ویپ بر اساس کدکهای
مختلف نشان میدهد.
پرواضح اســت که با بهدست آوردن این پارامترها برای یک سیستم تلفنی ،IPPBXمیتوان بهصورت دقیق
کیفیت ســرویس آن را ارزیابی کــرد و اقدامات الزم برای بهبود کیفیت ســرویس را انجام داد .برای مثال
میتوان سرویسی طراحی کرد که پس از اجرای آن بهوسیله ابزار ،SIPPکلیه اطالعات الزم را جمعآوری
کند و کیفیت سرویس مطلوبی را برای ما فراهم آورد.
نتیجهگیری
در این فصل ابتدا مفاهیم اولیه و انواع مدلسازی بررسی شدند و پس از آن به اهداف مدلسازی و نتایج آن
در طراحی یک سیســتم تلفنی پرداخته شد .سپس ابزار SIPPمعرفی شد .در مرحله بعد ،مهمترین سناریوها
بررسی شدند و نمونههایی از آنها نیز انجام شد .در انتها به بررسی کیفیت سرویس در شبکههای ویپ اشاره
شد و انواع پارامترهای آن بررسی گردید .امید است با شناخت کامل از این سیستم ،بتوانید سناریوهای موفق
و درستی طراحی و اجرا کنید.
فصل بیستم
آشنایی با دستورات و توابع مهم
و پرکاربرد در استریسک
مرجع آموزش ویپ با سافتسوئیچ استریسک 558
مقدمه
در استریســک دســتورات و توابع زیادی وجود دارد که میتوان از آنها در برنامهنویسی استریسک و یا در
برنامهنویسی AGIاستفاده کرد .در فصل پنجم )برنامهنویسی مقدماتی در استریسک( و هشتم )برنامه نویسی
پیشــرفته در استریســک( با برخی از آنها آشنا شدید .ازآنجاکه برخی دســتورات و توابع در برنامهنویسی،
کاربرد زیادی دارند ،در این فصل ســعی داریم برخی از مهمترین آنها را بررســی کنیم و مثالیهایی انجام
دهیم.
همانطورکه پیشتر هم توضیح دادهشــد ،برای مشاهده انواع دستورات و توابع در استریسک میتوانید
از دستورات زیر در کامندالین استریسک استفاده کنید:
CLI> core show applications
با اجرای هر یک از دســتورات باال ،لیستی از دستورات و توابع در استریسک نمایش داده میشود .نکته
مهم این است که اگر ماژولی در استریسک غیرفعال باشد ،نام دستور و یا تابع آن در استریسک نمایش داده
نخواهد شــد .پس بهتر اســت جمله قبلی را به این شکل اصالح کنیم که با اجرای هر یک از دستورات باال،
لیستی از دستورات و توابع ماژولهای فعال در استریسک نمایش داده خواهد شد.
559 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
ابتدا به معرفی دســتورات مهم در استریســک میپردازیم .ازآنجاکه دســتورات استریســک را میتوان
دستهبندی کرد ،لذا آنها را دستهبندی و مرتبکرده و شرح میدهیم.
دستور console
بهوسیله این دستور بهراحتی میتوانید یک تماس ایجاد کنید تا یک برنامه تعیینشده را اجرا نماید .برای مثال
فرض کنید برنامهای بهصورت زیر در استریسک داشته باشیم:
][my-sample
)(exten => wait,1,Answer
)same => n,Wait(300
)(same => n,Hangup
برای تست برنامه ،در کامندالین استریسک دستورات زیر را اجرا کنید:
CLI>console dial wait@my-sample
CLI>console dial newexten@my-sample
دستور originate
بهوسیله این دستور ،یک تماس برای مقصد مشخصی ایجاد میشود .چنانچه تماس پاسخ داده شود ،برنامهای
که تعیین کردهاید ،اجرا خواهد شد .برای مثال ،برنامه قبل را با روش زیر تست میکنیم.
CLI>channel originate SIP/100 extension wait@my-sample
CLI> channel originate SIP/100 extension newexten@my-sample
مرجع آموزش ویپ با سافتسوئیچ استریسک 560
اینجا یک تماس با کاربر ۱۰۰گرفته میشود .چنانچه او تماس را پاسخ دهد ،برنامهی مورد نظر اجرا میشود.
میتوان هر برنامهی دیگری را که مایل باشید بهوسیله این دستور اجرا کنید .در زیر مثالهایی از استفاده
از این دستور آورده شده است.
CLI>channel originate SIP/100 application Playback demo-congrats
CLI>channel originate SIP/100 application Dial DAHDI/g0/09151176713
CLI>channel originate Local/wait@default extension newexten@dafault
دستور ([Busy([Timeout
بهوسیله این دستور ،استریسک میتواند بوق مشغولی ) (Busy Dial Toneبرای تماس ایجاد کند .برای مثال
در برنامه زیر در صورتی که کاربر Phone_1در حال مکالمه باشــد ،استریســک بوق مشغولی را برای یک
زمان مشخص شده ،پخش خواهد کرد.
)exten => 100,1,Verbose(3,Calling SIP/Phone_1
)same => n,Dial(SIP/Phone_1,20
)same => n,Goto(s-${DIALSTATUS},1
دستور Progress
این دســتور همانند دســتور Answerاست .با این تفاوت که در دســتور Answerپیام سیگنالینگ ۲۰۰OK
ارســال خواهد شد و تماس بهصورت واقعی پاسخ داده میشــود ولی در دستور Progressپیام سیگنالینگ
561 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
183Session Progressارسال میشود و کانال برای انتقال مدیا )صوت( آماده خواهد شد ولی هنوز تماس
پاسخ داده نشده است .این دستور در شبکههای سیگنالینگ پروتکل SIPقابل استفاده است.
)exten => _XXX,1,NoOp(Calling local extensions
)(same => n,Progress
)same => n,Dial(SIP/${EXTEN},30
)(same => n,Hangup
][LocalSets
)}exten => _XXX,1,Dial(SIP/${EXTEN
همانطورکه مالحظه میکنید ،باید پســورد را برای اجرا شــدن دســتور DISAوارد کنید .همچنین میتوان
در فراخوانی دستور DISAنام فایلی که پسوردها در آن ذخیره شده است را بهصورت زیر استفاده کنید.
][from-pstn
)(exten => 1010,1,Answer
)same => n,DISA(/usr/src/passdisa.txt
دستور FollowMe
همانطورکه از نام آن پیداســت FollowMe ،برای پیگیری افراد در سیستم تلفنی استریسک بهکار میرود.
بــرای مثال فرضکنید بخواهیم با یک کاربر در سیســتم تماس بگیریم .چنانچه کاربر تماس خود را پاســخ
ندهد ،میتوان ازطریق دستور FollowMeبا او تماس برقرار کرد .برای درک بهتر ،مثال زیر را ببینید.
مثال( ابتدا فایل FollowMe.confرا از مسیر زیر باز و تغییرات زیر را در انتهای فایل وارد کنید.
# vim /etc/asterisk/followme.conf
][100
context=followme
number=100,20
number=Phone_1,20
number=09151176713,20
][followme
)exten => 100,1,Dial(SIP/100
)exten => Phone_1,1,Dial(SIP/Phone_1
)}exten => _0X.,1,Dial(DAHDI/g0/${EXTEN
در این صورت ،دستور FollowMeاجرا میشود و شمارههای تعیینشده بر اساس اولویت ،به ترتیب شروع
به زنگ خوردن میکنند.
چنانچه قصد داشــته باشــید از حلقه خارج شوید ،باید از دســتور ExitWhileاستفاده کنید .این دستور مانند
استفاده از Breakدر برنامهنویسی است.
دستور Exec
این دســتور کاربرد بســیار زیادی در برنامهنویســی AGIدارد .بهوسیله این دســتور میتوان کلیه دستورات
استریسک را اجرا کرد .شاید استفاده از آن در برنامهنویسی استریسک کاربرد زیادی نداشته باشد ولی از آن
در برنامهنویسی AGIبه وفور استفاده میشود .برای مثال برنامه زیر را ببینید:
)(exten => 1013,1,Answer
))same => n,Set(app=Playback(demo-congrats
)}same => n,Exec(${app
برای مثال فرض کنید بخواهیم برنامه باال را بهصورت AGIداشته باشیم.
#!/usr/bin/php -q
<?php
;)'require_once('phpagi.php
;)error_reporting(E_ALL
ازآنجاکه دســتورات موجود در برنامهنویســی AGIمحدودند ،میتوان از کلیه دستورات استریسک به این
شکل در برنامهنویسی AGIاستفاده کرد.
دستور TryExec
این دســتور همانند دســتور Execاســت ،با این تفاوت که اگر خطایی در اجرای برنامه اتفاق بیفتد ،تماس
قطع نخواهد شــد و دستورات بعدی اجرا میشــوند .بهوسیله متغیر } ${TRYSTATUSمیتوان وضعیت آن
را بررسی نمود.
• :Successدر این حالت مقدار متغیر برابر 0خواهد بود.
• :Failedدر این حالت مقدار متغیر برابر 1خواهد بود.
مرجع آموزش ویپ با سافتسوئیچ استریسک 564
دستور MacroExclusive
این دستور همانند دستور قبل است ،با این تفاوت که در هر لحظه تنها یک نمونه از آن قابل اجراست .برای
مثال برنامه زیر را در نظر بگیرید.
;extensions.conf
][LocalSets
)(exten => 142,1,NoOp
)same => n,MacroExclusive(lab
)(same => n,Hangup
][macro-lab
)(exten => s,1,NoOp
)}same => n,NoOP(${EXTEN
)} same => n,NoOp(${MACRO_ CONTEXT
)}same => n,NoOp(${MACRO_EXTEN
)}same => n,NoOp(${MACRO_PRIORITY
در این شرایط در هر لحظه تنها یک تماس میتواند دستورات داخل ماکرو را اجرا کند.
دستور MacroIf
بهوســیله این دستور ،ابتدا عبارتی محاسبه میشــود و سپس در صورتی که مقدار آن » «Trueارزیابی شود،
ماکرو فراخوانی میشود .نحوهی استفاده از این دستور بهصورت زیر است:
)]]MacroIf(expression?macronameA[,argA1][:macronameB[,argB1
565 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
دستور ResetCDR
بهوســیله اجرای این دستور ،مقادیر فعلی CDRهمگی ریست میشــوند .میتوان قبل از ریستشدن CDR
ابتدا آن را ذخیره و سپس ریست کرد .برای این منظور از آپشن wاستفاده کنید.
دستور NoCDR
بهوسیله اجرای این دستور ،به استریسک اعالم میکنیم که گزارش CDRرا برای تماس فعلی ایجاد نکند.
دستور SayDigits
بهوســیله ایــن دســتور ،عدد وارد شــده ،بهصــورت آرگومان و رقــم به رقم پخش میشــود .بــرای مثال
) ۱۲۳)SayDigitsبهصورت )یک دو سه( پخش خواهد شد.
)exten => 1018,1,SayDigits(123
دستور SayNumber
بهوســیله این دستور ،عدد وارد شــده ،بهصورت آرگومان و کامل پخش میشــود .برای مثال )SayNum-
ber(123بهصورت )صد و بیست و سه( پخش میشود.
; Say in English:
)exten => 1019,1,Set(LANGUAGE=en
)same => n,SayNumber(1234
"; "one - thousand - two - hundred - and - thirty - four
مرجع آموزش ویپ با سافتسوئیچ استریسک 566
دستور SayPhonetic
بهوســیله این دســتور ،رشــته واردشــده ،بهصورت آرگومان و کلمــهی کامل پخش میشــود .برای مثال
) SayPhonetic(helloبهصورت کلمهی کامل ) (helloپخش خواهد شد.
)exten => 1021,1,Set(LANGUAGE=en
)same => n,SayPhonetic(asterisk
دستور MusicOnHold
بهوسیله این دستور ،موزیک انتظار برای کاربر پخش میشود.
)(exten => 1023,1,Answer
)same => n,Playback(tt-allbusy
)same => n,MusicOnHold(default
)same => n,Goto(2
در این مثال ،با اجرای دســتور ،Readابتدا فایل صوتی تعیینشــده در متغیر AUDIOFILEپخش میشود و
همزمــان منتظر دریافت اطالعات )حداکثر ۱رقم( از طرف کاربر میماند .بعد از اتمام فایل صوتی حداکثر
۵ثانیه منتظر میماند تا کاربر اطالعات را وارد کند .اطالعات وارد شده در متغیر VOTEذخیره میشود.
567 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
دستور SendDTMF
بهوسیله این دستور میتوان دادههایی را بهصورت DTMFدر کانال ،ایجاد و ارسال کرد:
CLI> core show application SendDTMF
][Syntax
)]]]SendDTMF(digits[,timeout_ms[,duration_ms[,channel
آپشنهایی که این دستور در اختیار ما میگذارد بسیار مهم هستند .این آپشنها عبارتند از:
:bفقــط کانالهایی که bridgeشدهباشــند را در نظر میگیرد .به عبارت دیگــر فقط تماسهایی که هر دو
طرف در حال مکالمه باشند ،در نظر گرفتهمیشود.
:qدر این حالت بوق beepدر زمان شروع شنود پخش نخواهد شد.
: gاگــر این پارامتر فعال باشــد ،هنگام جابجا شــدن کانالها برای شــنود ،هیچگونه پیــام یا آالرمی پخش
نمیشود.
: wدر این حالت فردی که در حال شنود است ،میتواند با فردی که در حال مکالمه است ،صحبت کند ولی
remote userصدای او را نخواهد شنید .میتوان از این قابلیت برای مشاورهدادن استفاده کرد.
البته این دســتور پارامترهای زیادی دارد که برای آشنایی بیشتر با آنها میتوانید دستور باال را در محیط
کامندالین استریسک اجرا کنید.
)exten => 1026,1,Read(SPYNUM,extension
)same => n,ChanSpy(SIP/${SPYNUM},q
هنگام شنود ،میتوان برای باال بردن صدا ،دکمه #و برای شنود سایر کانالها دکمه * را ارسال کرد.
مرجع آموزش ویپ با سافتسوئیچ استریسک 568
دستور ExtenSpy
بهوســیله این دستور میتوان یک اکستنشن خاص را مشخص و شنود نمود .البته مثالی که در باال آمد ،دقیقا
همین سناریو را انجام میدهد.
دستور MixMonitor
بهوســیله این دســتور میتوان مکالمات مورد نظر را ضبط کرد .فرمت اســتفاده از این دستور بهصورت زیر
است:
CLI> core show application MixMonitor
][Syntax
)]]MixMonitor(filename.extension[,options[,command
اســتفاده از فرمت wavدر ضبط مکالمات ،باعث افزایش فضای مصرفی میشــود .بهتر اســت پس از اتمام
wavبه mp۳ ضبط مکالمات ،آن را به فرمت mp۳تبدیل کنید .روشهای زیادی برای تبدیل فایل صوتی
وجود دارد .اینجا از دستور ساده lameاستفاده میکنیم .برای نصب آن ابتدا باید دستور زیر را در لینوکس
اجرا کنید:
# apt-get install lame
برای مثال فرض کنید بخواهیم یک فایل صوتی با پسوند wavرا به فایل mp۳تبدیل کنیم:
#lame -f file.wav file.mp3
برای اســتفاده از این دســتور در استریســک میتوان بهصورت زیر ،پس از تمام شدن مکالمه ،این دستور را
اجرا کرد:
;extensions.conf
][LocalSets
)exten => h,1,NoOp(Hangup calls, Convert wav audio to mp3 audio
569 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
دستور Record
بهوســیله این دســتور میتــوان صدا را ازطریق یــک کانال ضبط کــرد .برای مثال با مشــخص کردن یک
اکستنشــن ،صدا شروع به ضبط شدن میکند .معموالً از این دســتور برای ضبط اعالنها و پیامها در سیستم
تلفنی استریسک استفاده میشود .این دستور بیشتر شبیه به یک رکوردر عمل میکند .فرمت استفاده از این
زیر است: دستور بهصورت
CLI> core show application Record
][Syntax
)]]]Record(filename.format[,silence[,maxduration[,options
نکته مهم هنگام استفاده از دستور Recordاین است که باید بعد از اتمام ضبط صدا ،دکمه #را بزنید.
برای مثال فرض کنید برای اســتفاده از دســتور ChanSpyنیاز به رمز عبور داشته باشیم .برنامه زیر را در نظر
بگیرید:
)exten => 1025,1,Authenticate(1234
)same => n,Read(SPYNUM,extension
)same => n,ChanSpy(SIP/${SPYNUM},q
مرجع آموزش ویپ با سافتسوئیچ استریسک 570
دستور VMAuthenticate
این دســتور همانند دســتور Authenticationاســت ،با این تفاوت که عملیات اعتبارســنجی را بر اســاس
VoiceMailانجام میدهد .فرمت استفاده از این دستور بهصورت زیر است:
CLI> core show application VMAuthenticate
][Synopsis
Authenticate with Voicemail passwords.
برای مثال برنامه زیر برای اعتبارسنجی ،از اطالعات ) VoiceMailرمزعبور( استفاده میکند:
][Authentication
)exten => 1026,1,Verbose(2,Attempting to authenticate caller with voicemail creds.
)same => n,Playback(silence/1
)same => n,VMAuthenticate(@default
)}same => n,SayDigits(${AUTH_MAILBOX
)same => n,Verbose(2,The caller was authenticated if we execute this line.
اینجا اگر هر پســوردی از VoiceMailوارد کنید ،درصورتیکه درســت باشد ،آن را تأیید میکند .در این
صورت بهوســیله متغیر } ${AUTH_MAILBOXمیتــوان فهمید که از اطالعات کدام VoiceMailبرای
اعتبارسنجی استفاده شده است:
)same => n,VMAuthenticate(${EXTEN}@default
دستور System
گاهی الزم اســت برخی دستورات لینوکســی را در برنامهنویسی استریسک استفاده کنیم .در این صورت از
دستور Systemاستفاده میکنیم .فرمت بهکارگیری این دستور بهصورت زیر است:
CLI> core show application System
][Syntax
)System(command
همانطورکه مالحظه میکنید ،باید کامند مورد نظر خود را بهصورت آرگومان برای دســتور ارســال کنید.
بــرای مثال فرض کنید بخواهیم برخی از اطالعات تمــاس را در فایلی ذخیره کنیم .در این صورت میتوان
از دستور زیر استفاده نمود:
)(exten => s,1,Answer
same => n,System(echo '${DATETIME} - ${CALLERID} - ${CHANNEL}' >> /var/log/asterisk/
)myinfo
یا به عنوان یک مثال کاربردی ،گاهی نیاز داریم که کانالها بعد از اتمام تماس ،آزاد شــوند .این برنامه
غالبا در مواقعی اســتفاده میشــود که کانالهای FXOداشته باشیم یا از گیتویهای FXOاستفاده کنیم و
نیاز داریم که کانالها بعد از اســتفاده ،حتما آزاد شــوند .ازآنجاکه این دستورات باید در زمان خاتمه تماس
اجرا شوند ،آنها را در اکستنشن hدر برنامه خود قرار میدهیم.
571 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
تابع ARRAY
بهوســیله این تابع میتوان بهصورت همزمان ،چند متغییــر را مقدار دهی کرد .برای مثال برنامه زیررا در نظر
بگیرید.
)exten => 2000,1,Set(VAR1=1
)same => n,Set(VAR2=2
)same => n,Set(VAR3=3
)same => n,Set(VAR4=4
تابع CALLERID
بهوســیله این تابع ،میتوان اطالعاتی درباره کالرآیدی شخصی که تماس گرفته است ،بهدست آورد .برنامه
زیر کاربردهایی از این تابع را نشان میدهد.
)exten => 2002,1,NoOp(Info about caller
)})same => n,NoOp(name=${CALLERID(name
)})same => n,NoOp(num=${CALLERID(num
)})same => n,NoOp(all=${CALLERID(all
)})same => n,NoOp(dnid=${CALLERID(dnid
تابع CDR
بهوســیله این تابع میتوان به کلیه فیلدهای موجود در ماژول CDRدسترســی پیدا کرد .برنامه زیر ،کاربرد
مرجع آموزش ویپ با سافتسوئیچ استریسک 572
CURL تابع
برنامه زیر، برای نمونه.بهوســیله این تابع میتوان یک صفحه ســایت را باز و اطالعاتی از آن استخراج کرد
.را در نظر بگیرید
exten => 2004,1,Set(CID=${CALLERID(num)})
same => n,Set(foo=${CURL(http://example.com/page.php?cid=CID)})
CUT تابع
فرمت استفاده از این تابع. از هم جدا کرد،بهوســیله این تابع میتوان یک رشــته را بر اســاس یک کاراکتر
.بهصورت زیر است
CLI> core show function CUT
[Syntax]
CUT(varname,char-delim,range-spec)
جدا میشــود و دسترسی به بخش اول یا ســایر بخشها ازطریقchar-delim رشــته بر اســاس،در این تابع
. برقرار میشودrange-spec
.برای نمونه برنامه زیر را در نظر بگیرید. .این تابع کاربردهای فراوانی دارد
exten => 2006,1,NoOp()
same => n,NoOp(TOPOLOGY=${CUT(CHANNEL,/,1)})
same => n,NoOp(OPERATOR=${CUT(TOPOLOGY,-,1)})
ENV تابع
.بهوسیله این تابع میتوان به متغیرهای محیطی در لینوکس دسترسی پیدا کرد
573 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
;read HOME
)})exten => 2007,1,Set(foo=${ENV(HOME
تابع EXIST
بهوســیله این تابع میتوان بررســی نمود که آیا متغییری در استریسک تعریف شده است یا نه .خروجی این
تابع بهصورت " "Trueو یا " "Falseدر نظر گرفته میشود.
)exten => 2007,1,Set(VAR1=test
)})}same => n,Set(foo=${EXISTS(${VAR1
)})}same => n,Set(foo=${EXISTS(${VAR2
در نسخههای جدید استریسک ،بهجای پارامتر call-limitدر پیکربندی فایل ،sip.confاستفاده از این توابع
توصیه شده است .میتوانید بهراحتی تعداد تماسهای همزمان برای تماسهای ورودی و خروجی به سیستم
تلفنی استریسک را کنترل و مدیریت نمایید.
تابع IF
بهوسیله این تابع میتوان شرطهایی در برنامه استریسک برقرار کرد.
; If ${VAR}=123456, return yes, otherwise return no:
)})exten => 123,1,Set(foo=${IF($[ ${VAR} = 123456]?yes:no
تابع ISNULL
بهوسیله این تابع میتوان بررسی کرد که آیا مقدار یک متغیر Nullاست یا نه.
)(exten => 2009,1,NoOp
)})same => n,Set(COUNT=${DB(test/count
مرجع آموزش ویپ با سافتسوئیچ استریسک 574
IFTIME تابع
. خروجی دستور متفاوت خواهد بود،بهوسیله این تابع بر اساس زمان سیستم
exten => 2010,1,Set(foo=${IFTIME(08:00-18:00|mon|1-15|dec?5:0)})
exten => 2010,1,Set(foo=${IFTIME(*|sat-sun|*|*?5:0)})
LEN تابع
. طول رشتهی وارد شده به تابع را بر میگرداند،این تابع
exten => 2011,1,Set(TEST="Hello, Wolrd")
same => n,Set(foo=${LEN(${TEST})})
same => n,NoOp(${foo})
RAND تابع
.این تابع یک عدد تصادفی بین دو عدد تعیینشده را انتخاب میکند
; Game of chance:
exten => 2012,1,GotoIf($[${RAND(0,100)} < 25]?won:lost)
exten => won,1,Playback(won)
same => n,Goto(123,1)
exten => lost,1,Playback(lost)
same => n,Goto(123,1)
SIP_HEADER تابع
یک پروتکل متنی اســت و از فیلدهایی تشکیلSIP پیشتر نیز توضیح داده شــد که پروتکل ســیگنالینگ
.شده است
: زیر را در نظر بگیریدINVITE برای نمونه پیام
INVITE sip:2013@192.168.141.128:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.141.1:53138;branch=z9hG4bK-d8754z-0d576a0e86274001-1---
d8754z-;rport
Max-Forwards: 70
Contact: <sip:100@192.168.141.1:53138;rinstance=bd162d0f928961cf>
To: <sip:2013@192.168.141.128:5060>
From: "100"<sip:100@192.168.141.128:5060>;tag=be129c0a
Call-ID: ZTE3ZGQ5NWQ4NGYyYTNiYzRmZDczMzA5ODhkNDE4ZjU.
CSeq: 1 INVITE
575 آشــنایی با دستورات و توابع مهم و پرکاربرد در استریسک
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO,
MESSAGE
Content-Type: application/sdp
Supported: replaces
User-Agent: 3CXPhone 6.0.20943.0
Content-Length: 407
اکنون چنانچه بخواهیم مقدار پارامتر Toرا در برنامه استریسک خود داشته باشیم.
)})exten => 2013,1,Set(DN=${SIP_HEADER(TO
تابع REGEX
بهوســیله این تابع میتوان از Reqular Experssionها در استریســک اســتفاده کرد .فرمت اســتفاده از این
دستور بهصورت زیر است.
CLI> core show function REGEX
][Syntax
)REGEX("regular expression" string
نتیجهگیری
مسلما توضیح در خصوص همه دستورات و توابع در استریسک بسیار وقتگیر است .در این بخش به معرفی
دستورات و توابع پرکاربرد در برنامهنویسی استریسک پرداختیم؛ با وجود این ،استفاده از راهنمای استریسک
برای آشــنایی بیشتر با این دستورات و توابع ،امری ضروری است .در واقع هدف اصلی این فصل چگونگی
استفاده از استریسک و آشنایی با دستورات و توابع آن است .امیدواریم با اطالعاتی که از این کتاب دریافت
نمودید ،بتوانید به سهولت از دستورات و توابع استریسک ،در برنامههای خود استفاده کنید.