Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lectures / lecture12.ppt
Скачиваний:
8
Добавлен:
06.06.2015
Размер:
286.72 Кб
Скачать

Сеанс звонка

process авторизацияПутиЗвонок( : #nextcall | #stop) {

$sAuthNum: receive

{

 

AuthPath(): авторизацияПути( : #yes2| #nextcall | #stop);

yes2:

сеансЗвонка( : #nextcall | #stop)

case

StartCall():

звонок( : #nextcall | #stop)

case

Stop():

#stop

}

 

 

}

process сеансЗвонка( : #nextcall | #stop) {

$sCall: receive

{

StartCall():

звонок( : #nextcall | #stop)

}

case

 

Stop():

#stop

 

 

 

 

 

}

 

 

 

 

 

process звонок( : #nextcall | #stop) {

 

$sStartCall:

receive {

StartTalk():

 

$sTalk:

 

 

 

 

receive StopTalk();

$sStopTalk:

 

 

 

 

receive StopCall();

 

 

 

 

 

БС ! CallBilling()

 

};

case

StopCall():

БС ! CallBilling();

 

 

 

 

 

if (Stop()) #stop else #nextcall

Сеанс исходящего звонка

process сеансИсходящегоЗвонка(ID id: #end) { авторизацияВнутреннегоАбонента( : #key | #num | #stop);

key: авторизацияПоКоду( : #key | #num| #stop); num:авторизацияНомераПутиЗвонок( : #num| #stop); stop: БС ! StopBilling(); удалитьСеанс(id) #end

}

process авторизацияНомераПутиЗвонок( : #nextcall | #stop) { $sAuthNumPath:

receive {

AuthNum(): авторизацияНомера( : #yes1| #nextcall | #stop); yes1: авторизацияПутиЗвонок( : #nextcall | #stop)

case Stop(): #stop

}

}

Авторизация внутреннего абонента

process авторизацияВнутреннегоАбонента( : #key | #num | #stop) { БС ! AuthOutgoingBilling();

$sAuth: receive AuthOutgoingBillingReply(bool ответ); СИТ ! AuthOutgoingReply(ответ);

if (Stop()) #stop ;

if (ответ) #num else #key

}

process авторизацияПоКоду( : #key | #num | #stop) {

$sKey:

receive {

Key():

БС ! KeyBilling();

$sKeyBilling:

 

 

receive KeyBillingReply(bool ответ);

 

 

 

СИТ ! KeyReply(ответ);

 

 

 

if (Stop()) #stop ;

 

case

Stop():

if ( ответ) #key

 

#stop

 

}

 

 

 

#num

 

 

}

 

 

 

Свойства спецификации сеанса

сообщение Stop() может придти в любой момент, но его обработка реализуется не всегда в порядке поступления

остальные сообщения упорядочены

Цепочки следования сообщений:

AuthIncomingPath StartCal StartTalk StopTalk StopCall Stop AuthIncoming AuthPath StartCall …

AuthOutgoing Key AuthNum AuthPath StartCall …

Правило: пока не завершена авторизация (посылкой ответного сообщения на СИТ) другие сообщения этого сеанса, в том числе сообщение Stop(), не обрабатываются.

Вхождения сообщения Stop() в спецификации являются источником недетерминизма

дедлок ?

Реализация скелета радиус-сервера

Неэффективность:

использование параллельных процессов

блокировка исполнения на операторах receive

Этап1. Фиксация специальных внутренних состояний

$sAuth:

 

$sAuth: state := sAuth;

Этап2. Вынос обработки сообщений Stop()

type STATE = enum sAuthNum, sCall, sKey, sAuthNumPath, sAuthIncoming, sAuthNumBilling, sAuthPathBilling, sStartCall, sTalk, sStopTalk, sAuth, sKeyBilling;

class SEANCE {

 

STATE state;

// текущее специальное состояние данного сеанса

bool stop = false; // = true поступило сообщение Stop() для данного сеанса

} to be continued

process обработкаОчередногоСообщения( : #loop) { receive { AuthIncoming(ID j):

……………………………………………

case Stop(ID j):

// сеанс(j) ! Stop( )

se = сеанс(j);

if (se.state in {sAuthNum, sCall, sKey, sAuthNumPath}) { БС ! StopBiling(); удалитьСеанс(se.id) }

else se.stop = true

};

! После этапа 2 порядок поступления сообщений в процесс сеанса радиус-сервера совпадает с порядком их обработки.

Этап3. Замена процесса сеанса на сопрограмму

Специальное внутреннее состояние точка сопрограммного прерывания

! После этапа 3 всякий оператор receive выполняется без ожидания

Этап4. Замена receive на if

receive {<сообщение1>: <оператор1> casecase <сообщениеN>: <операторN>}

if (<сообщение1>) <оператор1> else ifelse if (<сообщениеN>) <операторN>

Этап5. Замена создания параллельного процесса сеанса на непосредственный вызов процесса

receive AuthIncoming(ID j):

se= new SEANSE(j);

 

создатьСеанс(j, se);

 

сеансВходящегоЗвонка1(j)

! После этапа 5 нет параллельных процессов. Программа исполняется в сопрограммном режиме.

Обработчик сообщения фрагмент программы, соответствующий обработке одного сообщения

Этап6. Сборка обработчика из разных кусков сопрограммы

На примере AuthIncoming() и AuthPathBillingReply(). AuthIncoming() БС ! AuthIncomingBilling(); $sAuthIncoming: AuthPathBillingReply()

СИТ ! AuthPathReply(ответ);

if (Stop()) #stop else if (ответ) #yes else #no ; Необходимо продолжить для #yes и #no авторизацияПути авторизацияВнешнегоНомераПути

сеансВходящегоЗвонка2 сеансЗвонка (#yes #yes3 #call $sCall ) авторизацияПути авторизацияПутиЗвонок сеансЗвонка

(#yes #yes2l $sCall ) #yes $sCall

авторизацияПути авторизацияПутиЗвонок сеансВходящегоЗвонка1 (#no #nextcall #stop ) авторизацияПутиЗвонок авторизацияНомераПутиЗвонок сеансИсходящегоЗвонка авторизацияНомераПутиЗвонок (#no #nextcall #num $sAuthNumPath )

авторизацияПути авторизацияВнешнегоНомераПути (#no #stop )#no #stop, $sCall вводится новое поле outgoing

#no if (se.outgoing) $sAuthNumPath else #stop

конструктор сеанса радиус-сервера для сеанса СИТ с идентификатором j

class SEANCE {

bool outgoing = false; // = true для сеанса исходящего звонка

bool incomingPath = false; // = true если первым приходит сообщение // AuthIncomingPath()

SEANCE(ID j, bool outgoing, bool incomingPath);

//

bool completedlAll(); // = true в случае, когда все звонки в серии звонков // завершены либо серия пуста

}

SEANCE se; // текущий сеанс в радиус-сервере process собработкаОчередногоСообщения(: #loop) {

if (AuthIncoming(ID j))

{ se = new SEANCE(j, false, false); БС ! AuthIncomingBilling(); $sAuthIncoming } else if (AuthIncomingPath(ID j))

{ se = new SEANCE(j, false, true); БС ! AuthIncomingBilling(); $sAuthIncoming } else if (AuthOutgoing(ID j))

{se = new SEANCE(j, true, false); БС ! AuthOutgoingBilling(); $sAuth } else if (AuthIncomingBillingReply(ID j, bool ответ))

{СИТ ! AuthIncomingReply(ответ);

if (se.stop ответ) #stop

else { БС ! AuthNumBilling(); $sAuthNumBilling }

}

else if (AuthNumBillingReply(ID j, bool ответ)) { СИТ ! AuthNumReply(ответ);

if (se.stop) #stop

else if ( ответ) if (se.outgoing) $sAuthNumPath else #stop else if (se.outgoing se.incomingPath) $sAuthNum

else { БС ! AuthPathBilling(); $sAuthPathBilling }

}

Соседние файлы в папке lectures