База знаний

Введение

Я приведу простой пример, подразумевая, что вы выполнили настройку asterisk по моей статье или схожим образом. Классическая конфигурация для среднестатистического офиса. Представим, что у вас 2 таких офиса в разных городах. Пусть этими городами будут Москва (условное имя сервера moscow) и Санкт-Петербург (условное имя сервера piter) Вы хотите звонить на внутренние номера этих офисов напрямую, как-будто они обслуживаются вашим сервером. Допустим, на сервере moscow у вас номера начинаются на 100 и 200, а в piter на 300 и 400. Я считаю, что между серверами у вас настроен vpn канал и они видят друг друга без проблем.

Если у вас номера пересекаются, например, и там и там начинаются на 100, то задача немного усложняется, но не сильно. Просто придется добавить какую-нибудь еще цифру к набору, а в диалплане ее отсекать. Но я не буду рассматривать этот вариант. Если вы одна организация, то логично сделать такую нумерацию, чтобы она не пересекалась. Если это не так, то лучше ее переделать, чем городить костыли.

Для отладки и тестирования работы voip я рекомендую сервис Zadarma. Плюс его в том, что после регистрации вы получите настройки пира для внутренней сети оператора. И внутри этой сети вы можете бесплатно звонить. Например, я одного пира регистрирую на sip клиенте смартфона и с него звоню на второй аккаунт, пир от которого настроен в астериске. Таким образом эмулирую внешний звонок. Удобно отлаживать различные конфигурации звонков, не требуя платного подключения.

Наша задача будет разбита на 2 этапа:

  1. Готовим пиры и регистрации для связи двух серверов между собой.
  2. Настраиваем dialplan, чтобы распределять звонки по серверам.

Может возникнуть вопрос: «А зачем вообще соединять 2 сервера, если можно сделать один сервер asterisk и подключить к нему абонентов обоих офисов?». Причины могут быть разными. Мне видятся несколько, например:

  • В каком-то филиале нестабильный интернет. Офис не хочет терять возможность внутренних звонков при проблемах с интернетом. А если сервер с астериском будет находиться не у них, то даже между собой не смогут созвониться.
  • Разные люди администрируют сервера. В рамках одного сервера сложнее настроить разделение доступа. Более того, я даже не знаю, как это реализовать. А в случае с разными серверами никаких проблем. Главное не трогать часть диалплана, которая отвечает за звонки друг к другу, а дальше можно конфигурировать как душе угодно.
  • Нужна раздельная статистика и запись звонков. Конечно, можно все это реализовать в рамках одного сервера, но нужно будет либо покупать какое-то коммерческое решение, либо переделывать бесплатное. Я не знаю простого, бесплатного и удобного средства, которое позволит это реализовать в рамках одного сервера. А так ставишь любой cdr viewer и ограничиваешь доступ к web панели любым удобным способом.

Пошаговая установка сервера телефонии FreePBX Distro и настройка для работы с 1C и не только. Промо

И так приступим…. У меня старый компьютер с конфигурацией :
CPU-Intel Pentium 4, 3000 MHz, DDR SDRAM-2048 Mb, Video GF 9400 512 Mb, HDD 80 Gb, CD-ROM, сетевая встроенная карта 100 м/бит. Можно еще проще конфигурацию…… Хватит для фирмы 1-50 SIP абонентов, GSM trunk, Skype и т.д. Так же у меня две аналоговых линии местной АТС FXO (Grandstream HT-503 и Unicorn 3112) и 4-е оператора GSM (MTS ,Megafon, BeeLine, Tele 2) . В качестве GSM-шлюза использую модемы Huawei E171 и USB HUB D-Link DUB-H7. К серверу можно прикрутить видео наблюдение, домофон или другое устройство имеющее IP адрес, но это в следующей статье, если хватит сил и терпения.

1 стартмани

Определение пользователя IAX2 типа user.

Пользователь, типа user — принимает вызовы. Следующие параметры необходимо указать в файле iax.conf на машине с пользователем типа user для проверки (авторизации) перед тем, как позволить ему нас вызвать.

type=user
auth=md5
secret=secretword
context=iax2users

Определение пользователя IAX2 типа peer.

Пользователь, типа peer совершает вызовы. Следующие параметры необходимо указать в файле iax.conf на машине с пользователем типа peer для своей идентификации (авторизации) на машине с пользователем типа user, перед тем, как совершить вызов.

type=peer
host=hostname.domain.tld (или "dynamic, при этом требуется указать команду 
"register" для пользователя типа user.)
auth=md5
secret=secretword ; избыточно, если включено в состав команды Dial.
username=username-at-the-peer ; избыточно, если включено в состав команды Dial.

Обратите внимание:

  • тип type=user — авторизирует входящий вызов.
  • тип type=peer — это кто-то, кто совершает исходящие вызовы.
  • type=friend — это, конечно, и то и другое.

Использование типа «type=friend» делает жизнь проще, но не долго. Если вы добавите одновременно: «type=friend» и «[email protected]», то этим вы ограничите одним хостом, число тех серверов, с которых эта учетная запись может принять вызов на обработку, что, возможно, совсем не то, что Вам нужно.

Для инструкций по поводу использования директивы «auth=rsa», см: Asterisk IAX RSA авторизация?.

Теперь, когда мы завершили шаги 1 и 2, осталось только настроить план набора. Прочитайте нижеприведенные примера, для того, чтобы понять, как это лучше сделать.

Реализация

Считаем, что админ уже все настроил и можно приступать.Все, что нам нужно – это HTTPСоединение и ровные руки, чтобы отправлять ровные запросы.Код работы с Asterisk настолько тривиальный, что его нет смысла здесь приводить. Все сводится к элементарной отправке и чтению HTTP-запросов. Не верите? Смотрите сами:

Организация соединения:

Соединение=Новый HTTPСоединение(IP,Port,,,,Таймаут,);Отправка и чтение запроса:

ТекстКоманды=»/asterisk/rawman?action=…бла-бла-бла»;Запрос=Новый HTTPЗапрос();Запрос.АдресРесурса=ТекстКоманды;Ответ=Соединение.Получить(Запрос);

Это все :)

Пример sip.conf


externip=1.2.3.4:50666
localnet=192.168.0.0/24 ; локальная подсеть
localnet=192.168.5.0/24 ; локальная подсеть SIP провайдера 1
localnet=192.168.100.0/24 ; локальная подсеть SIP провайдера 2
directmedia=no ; запрещаем прямые соединения клиентов (только через asterisk)

;———————————
; локальный клиент (в одной сети с asterisk):

type=friend
secret=12345
host=dynamic

nat=no
;———————————

;———————————
; клиент подключен через NAT:

type=friend
secret=12345
host=dynamic

qualify=yes ; поддерживаем SIP каждые 300 мс
rtpkeepalive=10 ; поддерживаем RTP каждые 10 сек
nat=force_rport,comedia ; указываем, что клиент подключен через nat
;———————————

Кроме изменений в asterisk (в файле sip.conf) необходимо также в настройках самого SIP клиента прописать STUN сервер.

Удачи!

Метод с использованием SIP протокола.

Когда мы рассматриваем файл sip.conf, то возможно стоит начать с указания типа клиента, как type=friend, на обоих серверах, и, если при этом все начнет нормально работать, Вам, возможно, захочется разделить эту запись по типам: peer — для исходящих вызовов и user — для входящих вызовов

Также, стоит обратить внимание в файле sip.conf на параметры «insecure=very» («insecure=port,invite» в версии 1.4) и, возможно, на параметр: «autocreatepeer=yes».

  • Сервер A — имеет статический IP адрес, сервер B — динамический IP адрес: Тогда для сервера B нужно прописать строку регистрации на сервере A в sip.conf.
  • Оба сервера имеют статические IP адреса: Тут нам вообще не нужна регистрация.
  • Оба сервера имеют динамические IP адреса: Тут есть одна хитрость, которую можно использовать, можно воспользоваться динамическим DNS сервисом, например, dyndns.org, для регистрации каждого сервера на другом. В любом случае, это не самое удачное решение, использовать динамические адреса для обоих серверов, т.к. при смене IP адреса, соединение может быть потеряно, до тех пор пока информация не обновиться на динамическом DNS сервере.
  • Оба сервера имеют доступ друг к другу через NAT: Не используйте SIP протокол, вместо этого попробуйте использовать IAX2.

Раздел для тех, кто не в теме.

Кто уже читал мои предыдущие статьи и знает про AMI (Asterisk Manager Interface) и AJAM, может смело пропустить этот раздел.

AMI – это интерфейс управления Asterisk-ом. Но, подключения к AMI, как и девушки, бывают разные. Два основных:

  1. AMI поверх TCP, который часто называют просто AMI
  2. AMI поверх HTTP, его еще называют AJAM (Asynchronous Javascript Asterisk Manager). Хотя, особой асинхронности я там не увидел.

Если объяснять на пальцах, то разница между 1 и 2, как между толстым и веб-клиентом. Ссылка для тех, кто-то хочет накуриться правильных английских мануалов.Внешняя компонента ROM-Asterisk может использовать оба способа подключения.Внешняя компонента от МИКО использует только AJAM. Но нам, они пока не нужны – мы будем подключаться без них.

И что с этим делать?

Думаю, нужно подбирать решение по конкретной ситуации. Обращайтесь – помогу, если смогу.

В качестве абстрактных рекомендаций, могу сказать следующее:

  1. Ищите, тестируйте и найдете. Весь инструмент во вложенной к статье обработке. Поиграйтесь с частотой запросов и с таймаутом ответа.
  2. Пофильтруйте события – хотя бы уберите лишние классы событий. Об этом написано в других моих статьях.

Если пользователь использует толстый клиент, то скорее всего, он сидит внутри сети. Тогда нечего заморачиваться, можно использовать обычный AMI через TCP. Подключаем этого пользователя через ROM-Asterisk и пусть себе работает.

Если пользователь использует тонкий клиент и сидит внутри сети, тогда тоже самое – AMI поверх TCP и ROM-Asterisk. Кстати, тонкому клиенту удаленному, но с хорошим каналом, это тоже подойдет.

Если пользователь использует веб-клиент или же тонкий клиент на нестабильном канале, тогда однозначно AJAM.

Команда register.

Когда ip адрес клиента типа user неизвестен, пользователь типа peer не знает, куда совершать вызов (например, при вызове из офиса сотрудника, который работает на дому, когда у него имеется только динамически назначаемый ip адрес или он находиться за NAT.) Для решения этой задачи, домашний работник активно регистрируется на сервере в офисе, предоставляя свои данные и местоположение в сети.

register => user:[email protected]

При этом непрерывно, через некоторые интервалы, будет обновляться информация о пользователе, и сервер всегда будет знать, как вызвать пользователя, даже если его IP адрес будет меняться.

~~socialite~~

PUSH уведомления. Регистрация и управление из типовых конфигураций 1С

Расширение конфигурации предназначено для отправки push уведомлений для подписчиков сайта. Может быть использовано для обеспечения оповещения Ваших клиентов, Ваших сотрудников. Имеет законченный функционал, но может быть легко расширено под любую бизнес логику. НЕ использует сторонних сервисов.
Есть возможность рассылки , как массовой , так и индивидуально. Массовая подписка может быть отфильтрована по 5 параметрам. Данная разработка может использоваться как в составе любой конфигурации на базе платформе 8.3.12 и выше, так и как самостоятельная конфигурация.

10 стартмани

Соединение планов набора.

Пример 1

extensions.conf:

exten => _7XXX,1,Dial(IAX2/myserver:passwordA@IAXserverA/${EXTEN:1},30,r)
exten => _7XXX,2,Dial(SIP/myserver:passwordA@SIPserverA/${EXTEN:1},30,r)
exten => _7XXX,3,Congestion

exten => _8XXX,1,Dial(IAX2/myserver:passwordB@IAXserverB/${EXTEN:1},30,r)
exten => _8XXX,2,Dial(SIP/myserver:passwordB@SIPserverB/${EXTEN:1},30,r)
exten => _8XXX,3,Congestion

Конечно, нам нужно вместо записей типа и т.д., указать те, что мы прописали в файлах iax.conf и sip.conf, чтобы все работало как нужно

В этом примере, SIP используется как резервный канал, в случае проблем соединения по IAX протоколу.
Обратите внимание, что в этом примере имя пользователя и пароль попадает в CDR записи (Вам возможно захочется использовать второй пример или использовать ключевые выражения вместо комбинаций имя пользователя/пароль)!. Пример 2

Пример 2

В этом примере в CDR записях не показывается поле username и secret.

(сервер A)
iax.conf

register => <username>:<password>@<имя или IP адрес сервера B>


type=friend
user=<username>
secret=<password>
host=<имя или IP адрес сервера B>

extensions.conf
exten => _7XXX,1,Dial(IAX2/serverB/${EXTEN:1},30,r)
exten => _7XXX,2,Congestion

(сервер B)
iax.conf

type=friend
user=<username>
secret=<password>
host=<dynamic> | <имя или IP адрес сервера A>

extensions.conf
exten => _8XXX,1,Dial(IAX2/serverA/${EXTEN:1},30,r)
exten => _8XXX,2,Congestion

В некоторых случаях, параметры serverA и serverB, должны содержать имя пользователя сервера.

Пример 3

С помощью объекта Switch в файле extensions.conf Вы можете соединить два сервера Asterisk и план набора другова сервера. В данном случае, наш «server C» или соединяется с «server A» или с «server B»:

exten => _801XXX,1,Goto,srvA|${EXTEN}|1
exten => _802XXX,1,Goto,srvB|${EXTEN}|1


exten => _801XXX,1,StripMSD,3
exten => _XXX,2,Goto,1
switch => IAX/serverA


exten => _802XXX,1,StripMSD,3
exten => _XXX,2,Goto,1
switch => IAX/serverB

Замечания: Вы не можете установить замкнутую цепочку, используя switch с serverA на serverB и с serverB на serverA! Также, обратите внимание на (новую) установку в файле iax.conf «autokill=», которая предотвращает длительное зависание, если удаленный сервер не работает или отсоединился.

Пример 4

В файле extensions.conf (на master):

switch => IAX2/master:[email protected]/outbound

В файле iax.conf (на master):

type=user
auth=plaintext
context=outbound
context=outbound2 ; (по вашему желанию, их может быть несколько)
secret=secret
host=dynamic
callerid="slave"
trunk=yes
notransfer=yes


type=peer
auth=plaintext
context=outbound-nuphone
secret=secret
host=dynamic
trunk=yes
notransfer=yes

В файле extensions.conf (на slave):

; Выберете механизм вызова, первый вызывает указанный екстеншен,
; второй вызывает специальный екстеншен - s.

;exten => 7046446999,1,Dial,IAX2/master@slave/${EXTEN}
;exten => 7046446999,1,Dial,IAX2/master@slave

В файле iax.conf (на slave):

register => slave:[email protected]


type=peer
host=iax-gw1.company.net
secret=secret
context=outbound
trunk=yes
canreinvite=no


type=user
secret=secret
context=acontext
trunk=yes
canreinvite=no

SIP телефон(софтфон) для 1С:Предприятия 8 и IP АТС (виртуальная и офисная) Промо

«АТС.Ринголайн» и «Ringophone» — это современный взгляд, комплексное решение для организации телефонии в офисе, которое работает прямо из коробки. Решения направлены на организации, где главный упор сделан на коммуникацию и взаимоотношения с клиентами.
RingoPhone 1С — это бесплатный sip телефон, выполненный в виде внешней обработки для 1С. Данная панель телефонии разработана для любых конфигураций 1С:Предприятия 8. RingoPhone работает с АТС на базе Asterisk и провайдерами, которые поддерживают SIP протокол. IP телефония набирает огромную популярность и всё больше возможностей открывается при объединении телефонии и CRM системы. Возможность встроить телефон в свою CRM систему, позволяет осуществлять управление не только на уровне АТС, но и на уровне самого телефона.
АТС.RingoLine изначально создавалась с учётом интеграции с современными CRM системами. CRM системам доступно менять любые настройки АТС. Такие как: создание пользователей, добавление и удаление операторов колл-центра, возможность задавать переадресацию сотрудникам, получать информацию о звонках с АТС, а возможность доработки позволит заложить новые алгоритмы распределения звонков по сотрудникам в зависимости от данных в CRM системе.

1 стартмани

Мульти рассылка СМС из 1С для типовых и нетиповых конфигураций, на управляемых и обычных формах Промо

Очень часто в торговых организациях проводятся рассылки своим покупателям об акциях, скидках, новых поступлениях и т.д.
Для этих целей была создана одна универсальная обработка, которая поможет осуществить рассылку в любой конфигурации 1С.
Для отправки используется несколько сервисов на выбор: sms.ru, smsc.ru, p1sms.ru, smsgorod.ru, terasms.ru которые по нашему мнению являются одними из самых функциональных в интернете. Так же есть возможность для юридических лиц заключения договора и оплата безналичным расчетом.
Наша обработка не просто может отправлять СМС, но и позволяет автоматически заполнять сотовые(!) телефонные номера из базы 1С, делать как общие рассылки так и персонализированные, подставляя значения переменных, которые вычисляются для каждого адресата, будь то его долг или фамилия имя, например, узнать баланс и т.д. Но обо всем по порядку…

1 стартмани

Настройка dialplan для работы с 2-мя серверами

Теперь нам нужно в диалплане на каждом из серверов указать, куда звонить по разным номерам. На сервере moscow укажем, что звонить по маскам 300 и 400 нужно в питер. Добавляем в extentions.conf правило перед основным правилом звонка на внутренние номера с маской _XXX.

exten => _XX,1,Dial(SIP/piter/${EXTEN},15,Tt)

И добавим контекст для приема входящих звонков с сервера piter

exten => _XXX,1,Dial(SIP/${EXTEN},15,Tt)

Делаем то же самое на сервере piter.

exten => _XX,1,Dial(SIP/moscow/${EXTEN},15,Tt)

Не забываем поменять маску. И добавляем контекст приема звонков с moscow.

exten => _XXX,1,Dial(SIP/${EXTEN},15,Tt)

Вот и все. Мы связали между собой 2 астериск сервера. Можно звонить друг другу, используя внутренние номера. Не забудьте перезагрузить план набора.

> dialplan reload

Можно проверять звонки. Не обязательно делать в точности, как я показал. У вас может быть по-другому организован диалплан. Можно в контекст для входящих заинклюдить ваш существующий контекст для внутренних звонков, например так.

include => office

Если у вас настроена запись звонков так же, как я рассказал в своей статье про настройку астериска, которую привел в начале, то не забудьте добавить запись по обоим направлениям. Примерно так для сервера moscow на исходящие.

exten => _XX,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _XX,n,Dial(SIP/piter/${EXTEN},15,Tt)

И вот так на входящие:

exten => _XXX,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _XXX,n,Dial(SIP/${EXTEN},15,Tt)

На этом все. Пример написал по горячим следам. Сегодня настраивал такую тему, конфиги взял с реальных серверов.

Если есть необходимость, то можно расширить эту конфигурацию и настроить звонки в Питер из Москвы через сервер piter, если там более выгодный тариф для локальных звонков. Для этого нужно добавить маски питерских номеров в dialplan на сервере moscow, а на сервере piter в контекст входящих звонков с moscow настроить набор через свой питерский транк.

Другие материалы по asterisk:

Онлайн курс «DevOps практики и инструменты»

Если у вас есть желание научиться строить и поддерживать высокодоступные и надежные системы, научиться непрерывной поставке ПО, мониторингу и логированию web приложений, рекомендую познакомиться с онлайн-курсом «DevOps практики и инструменты» в OTUS. Курс не для новичков, для поступления нужны базовые знания по сетям и установке Linux на виртуалку. Обучение длится 5 месяцев, после чего успешные выпускники курса смогут пройти собеседования у партнеров.

Проверьте себя на вступительном тесте и смотрите программу детальнее по .

  • Установка и настройка астериск с нуля
  • Мониторинг asterisk в zabbix
  • Соединение двух серверов астериск
  • Анализ SIP трафика
  • Замена +7 на 8 и наоборот
  • Ограничение на звонки для группы номеров

Параметры asterisk и SIP клиента

Прописываем STUN сервер у SIP клиента

Это необходимо для того, чтобы как asterisk, так и сам клиент могли определить внешний IP адрес клиента. Для этого в SIP клиенте достатоно прописать STUN сервер. По умолчанию для протокола STUN используется UDP порт 3478 (если необходимо задавать порт для STUN сервера, используйте этот порт). Во многих SIP клиентах настройка STUN сервера может задаваться не в самих параметрах SIP аккаунта, а в глобальных настройках программы
Примеры STUN серверов (можно прописать любой из них):
stun.ekiga.net
stun.3cx.com
stun.ideasip.com
stun.iptel.org
stun.rixtelecom.se
stunserver.org
stun.softjoys.com
stun.voipbuster.com
stun.voipstunt.com
stun.voxgratia.org
Проверить STUN сервер на работоспособность, и получить информацию о NAT можно с помощью утилиты client: http://prdownloads.sourceforge.net/stun/client.exe?download. Описание ее можно найти здесь: http://www.interface.ru/home.asp?artId=22409

Осуществляем проброс портов к asterisk с внешнего IP адреса

Эту задачу решает маршрутизатор (у кого-то — прокси-сервер ISA/TMG/Kerio, у кого-то — Cisco, у кого-то — точка доступа Zyxel/D-Link/TP-Link/…). Вам необходимо обеспечить проброс портов как для протокола SIP (звонки), так и для протокола RTP (сам разговор):

  1. Выход в интернет для сервера asterisk через NAT. Открыты для выхода должны быть порты UDP 5060 (по умолчанию, SIP), и 10000-20000 (UDP по умолчанию, RTP).
  2. подключение извне (проброс портов) с UDP порта 5060 (по умолчанию) на сервер asterisk, и UDP 10000-20000 (по умолчанию). Несколько моментов:
    1. даже если asterisk в Вашей сети работает на порту 5060, вовсе не обязательно из интернета давать доступ к порту 5060. Можно указать (например) такой маппинг портов: с внешнего IP, UDP порт 50600, на локальный IP сервера asterisk, порт 5060;
    2. не обязательно открывать все 10000 RTP портов. Для каждого подключения asterisk требует 2 открытых RTP порта. И если в настройках asterisk (в файле rtp.conf) предварительно ограничить количество RTP портов (например 1000 портов обеспечит до 500 одновременных разговоров), то на сервере также можно ограничить количество внешних портов для подключения

Указываем в конфигурации asterisk внешний IP и порт

На удивление, тут все достаточно просто (во всяком случае, что касается asterisk версии 11.4): в sip.conf прописать несколько параметров в секции general:

Указываем внешний реальный ip адрес сервера asterisk. Если порт, открытый в интернет, не совпадает с внутренним портом астериска, не забываем указать его:
или

Разумеется, после создания/изменения подобных параметров в sip.conf может оказаться недостаточным сделать команду sip reload или даже reload. Может потребоваться перезагрузка самого сервиса asterisk:

Указываем в конфигурации asterisk диапазоны локальной сети

Для этого в sip.conf в секции general прописываем диапазоны локальных IP адресов

Обратите внимание: если у Вас подключены SIP провайдеры не через интернет, а по отдельным линиям связи, то подсети этих провайдеров тоже нужно указать как локальные сети:. Разумеется, после создания/изменения подобных параметров в sip.conf может оказаться недостаточным сделать команду sip reload или даже reload

Может потребоваться перезагрузка самого сервиса asterisk:

Разумеется, после создания/изменения подобных параметров в sip.conf может оказаться недостаточным сделать команду sip reload или даже reload. Может потребоваться перезагрузка самого сервиса asterisk:

Запрещаем прямые соединения клиентов, разрешаем только через asterisk

Прописываем в sip.conf, в секции general опцию:
В старых версиях asterisk (до версии 1.6.2) для этого необходимо было использовать опцию canreinvite, для запрещения повторной отправки пакетов INVITE. В более новых версиях эта опция была переименована.

Поддерживаем соединение со стороны asterisk

Необходима поддержка двух видов соединений: для SIP и для RTP. Параметры для обоих протоколов можно указать как для всех клиентов (в этом случае параметр прописывается в sip.conf в секции general), так и для конкретного клиента (в этом случае параметр прописывается в sip.conf в настройках конкретного клиента).

Для протокола SIP:
Вместо XXX можно указать число , в этом случае asterisk будет посылать SIP пакет клиенту каждые XXX миллисекунд, а можно указать просто yes, в этом случае XXX=300 .

Для протокола RTP:
Вместо YYY нужно указать число, в этом случае asterisk будет посылать RTP пакет клиенту каждые YYY секунд, по умолчанию этот параметр равен 0 (то есть выключен).

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Техноарена
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: