1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
package examples.pilib
/**
* Mobile phone protocol.
* Equivalent to a three-place buffer.
* @see Bjoern Victor "A verification tool for the polyadic pi-calculus".
*/
object mobilePhoneProtocol {
import concurrent.pilib._
val random = new java.util.Random()
// Internal messages exchanged by the protocol.
trait Message
// Predefined messages used by the protocol.
case class Data() extends Message;
case class HoCmd() extends Message; // handover command
case class HoAcc() extends Message; // handover access
case class HoCom() extends Message; // handover complete
case class HoFail() extends Message; // handover fail
case class ChRel() extends Message; // release
case class Voice(s: String) extends Message; // voice
case class Channel(n: Chan[Message]) extends Message; // channel
def MobileSystem(in: Chan[String], out: Chan[String]): unit = {
def CC(fa: Chan[Message], fp: Chan[Message], l: Chan[Channel]): unit =
choice (
in * (v => { fa.write(Data()); fa.write(Voice(v)); CC(fa, fp, l) })
,
l * (m_new => {
fa.write(HoCmd());
fa.write(m_new);
choice (
fp * ({ case HoCom() => {
System.out.println("Mobile has moved from one cell to another");
fa.write(ChRel());
val Channel(m_old) = fa.read;
l.write(Channel(m_old));
CC(fp, fa, l)
}})
,
fa * ({ case HoFail() => {
System.out.println("Mobile has failed to move from one cell to another");
l.write(m_new);
CC(fa, fp, l)
}})
)
})
);
/*
* Continuously orders the MSC to switch the MS to the non-used BS.
*/
def HC(l: Chan[Channel], m: Chan[Message]): unit = {
Thread.sleep(1 + random.nextInt(1000));
l.write(Channel(m));
val Channel(m_new) = l.read;
HC(l, m_new)
}
/**
* Mobile switching center.
*/
def MSC(fa: Chan[Message], fp: Chan[Message], m: Chan[Message]): unit = {
val l = new Chan[Channel];
spawn < HC(l, m) | CC(fa, fp, l) >
}
/**
* Active base station.
*/
def BSa(f: Chan[Message], m: Chan[Message]): unit =
(f.read) match {
case Data() => {
val v = f.read;
m.write(Data());
m.write(v);
BSa(f, m)
}
case HoCmd() => {
val v = f.read;
m.write(HoCmd());
m.write(v);
choice (
f * ({ case ChRel() => {
f.write(Channel(m));
BSp(f, m)
}})
,
m * ({ case HoFail() => {
f.write(HoFail());
BSa(f, m)
}})
)
}
};
/**
* Passive base station.
*/
def BSp(f: Chan[Message], m: Chan[Message]): unit = {
val HoAcc = m.read
f.write(HoCom())
BSa(f, m)
}
/**
* Mobile station.
*/
def MS(m: Chan[Message]): unit =
(m.read) match {
case Data() => {
val Voice(v) = m.read;
out.write(v);
MS(m)
}
case HoCmd() =>
(m.read) match {
case Channel(m_new) => {
if (random.nextInt(1) == 0)
choice ( m_new(HoAcc()) * (MS(m_new)) );
else
choice ( m(HoFail()) * (MS(m)) );
}
}
};
def P(fa: Chan[Message], fp: Chan[Message]): unit = {
val m = new Chan[Message];
spawn < MSC(fa, fp, m) | BSp(fp, m) >
}
def Q(fa: Chan[Message]): unit = {
val m = new Chan[Message];
spawn < BSa(fa, m) | MS(m) >
}
val fa = new Chan[Message];
val fp = new Chan[Message];
spawn < Q(fa) | P(fa, fp) >;
}
//***************** Entry function ******************//
def main(args: Array[String]): unit = {
def Producer(n: Int, put: Chan[String]): unit = {
Thread.sleep(1 + random.nextInt(1000));
val msg = "object " + n;
put.write(msg);
System.out.println("Producer gave " + msg);
Producer(n + 1, put)
}
def Consumer(get: Chan[String]): unit = {
Thread.sleep(1 + random.nextInt(1000));
val msg = get.read;
System.out.println("Consumer took " + msg);
Consumer(get)
}
val put = new Chan[String];
val get = new Chan[String];
spawn < Producer(0, put) | Consumer(get) | MobileSystem(put, get) >
}
}
|