final.docx
-
Upload
trinh-phi-hung -
Category
Documents
-
view
23 -
download
3
Transcript of final.docx
Techniques for Protocol Programming 2013
Họ và tên sinh viên:
Trịnh Phi Hùng
Nguyễn Chí Nhân
Nguyễn Đăng Khoa
Final : Techniques for Protocol Programming
(Các kĩ thuật của giao thức lập trình)
Mạng cảm biến không dây thường được dùng trong các ứng dụng trong đo
đạc, phát hiện, dự báo như : đo nhiệt độ, đo độ ẩm, cảm nhận độ rung … Hầu hết
các nút cảm biến thường được dùng như một cơ sở dữ liệu hoặc phát hiện sự kiện
trong tự nhiên, truyền thông đóng vai trò quan trọng trong việc xác định thời gian
sống của các nút cảm biến, tốc độ định tuyến và bản chất của dữ liệu truyền đi
trong mạng. Do đó mà chúng ta cần quan tâm tới các tính năng, các giao thức được
sử dụng trong lớp phân rã IP , đó là lớp MAC.
S-MAC là giao thức điều khiển truy nhập trung bình trong mạng cảm biến,
nó được phát triển từ mạng 802.11 truyền thống có ưu điểm là giảm năng lượng
tiêu thụ và khả năng tự cấu hình cho mạng. Trong sự phát triển người ta đã xác
định được 2 trong 3 nguồn tiêu tốn năng lượng và đã cải thiện nó nhằm khắc phục.
Hai trong ba nguồn tiêu thụ năng lượng được đề cấp đến dưới đây:
- Cộng tuyến : khi 2 hay nhiều nút cùng gửi một gói tin về nút trung tâm, sự
va chạm có thể xảy ra làm sai hỏng các gói tin. Vì thế phải tiêu tốn năng
lượng vô ích để truyền lại các gói tin bị hỏng.
Techniques for Protocol Programming 2013
- Nghe lỏm : trong trường hợp các nút nghe nhiều hơn những gói tin không
dùng cho mình thì nó phải tiêu tốn năng lượng hơn. Với việc sử dụng giao
thức S-MAC thì các nút sẽ ở trạng thái ngủ theo lịch trình vì thế sẽ giảm
năng lượng do nghe lỏm đi.
I. THE MEDIATION DEVICE PROTOCOL( các thiết bị trung gian)
Bây giờ ta sẽ xem xét một giao thức nổi tiếng là thiết bị hòa giải trung gian,
trong giao thức này nút A muốn truyền tải một gói tin tới nút B.
1. Nút A thông báo cho thiết bị trung gian biết bằng định kì gửi một gói tin
RTS (request-to-send), các thiết bị trung gian sẽ bắt các gói tin này. Nút A
gửi gói RTS của nó thay vì cảnh báo truy vấn nó
2. Nút A sau đó ở chế độ nhận (lắng nghe )
3. Các thiết bị trung gian phải chờ nút B truy vấn nó và sẽ gửi lại một gói tin
trả lời truy vấn nó, cho biết địa chỉ của nút A và khoảng thời gian bù đắp cho
thời gian truyền
4. Nút B bây giờ sẽ bít B sẽ nghe một lần nữa và gửi một CTS tới nút A (Bây
giờ, nút B cũng biết thời gian của nút A, và do đó biết ở thời điểm t nút A là
chế độ truyền sẽ xảy ra một lần nữa.)
5. Nút B đợi tại t’ để nhận dử liệu từ nút A.
6. Tại t” nút B sẽ gửi một gói tin báo xác nhận (nút B biết t” vì nó với nút A có
cùng chu kỳ )
7. Sau khi nút A và nút B đã truyền xong nó lại lặp lại quá trình phát đi các tín
hiệu truy vấn mới.
8. Nút B cũng khôi phục lại chu kì định kì và nó tách biệt với chu kì của nút A.
II. CONTENTION-BASED PROTOCOLS
Techniques for Protocol Programming 2013
Giao thức contention-based đề cập đến một lớp trong giao thức truyền thông,
khi đó một số quy tắc trong việc thu, phát sóng được đề xuất cho các nút cảm biến
trong mạng bắt buộc phải tuân thủ.
1. Carrier Sense Multiple Access Protocol (CSMA):
Trước khi có bất kì thông tin nào được truyền đi, nút truyền phải xác nhận
không hoạt động truyền đồng thời hay chia sẽ thông tin đang diễn ra
III. PROGRAMMING WITH LINK-LAYER PROTOCOLS( lập trình với
giao thức link-layer) :
Trong phần này chúng ta cùng xem xét các thách thức đặt ra trong việc lập trình
tại lớp liên kết dữ liệu, chúng ta sử dụng kĩ thuật ARQ (automatic repeat request –
Techniques for Protocol Programming 2013
tự động lặp lại yêu cầu). Giao thức này cố gắng gửi lại gói tin có độ tin cậy hơn
bằng cách sử dụng các báo nhận và gửi lại.
IV. AUTOMATIC REPEAT REQUEST (ARQ) PROTOCOL (giao thức
ARQ)
Ý tưởng cơ bản của giao thức ARQ có thể hiểu như sau :
Nút truyền dữ liệu sử dụng giao thức link-layer chấp nhận một gói dữ liệu, sẽ tạo
ra một gói tin mới bằng cách thêm vào một header và check sum và truyền gói tin
đã được đóng gói đó tới máy thu. Bên máy thu sẽ kiểm tra check sum có đúng
không, nếu đúng nó sẽ gửi một bản tin ACK(báo nhận) dương tới máy phát, còn
nếu kiểm tra bị sai thì máy thu sẽ gửi môt ACK âm tới máy phát. Máy phát nếu
nhận lại được một ACK dương thì nó biết là đã gửi được gói tin thành công còn
nếu nó nhận được một bản tin ACK âm thì nó sẽ gửi lại một gói tin mới cho máy
thu.
V. TRANSMITTER ROLE ( kịch bản của máy phát)
Lưu ý rằng thời gian để máy phát từ lúc gửi gói tin đến lúc thoát ra để vào chế
độ ngủ là nhất định và có giới hạn. Nếu máy phát không nhận được tín hiệu ACK
âm thì nó sẽ vẫn tiếp gửi những tin nhắn tới các nút khác trong mạng.
{
//Let p be a data packet coming from the MAC layer.
frame = Header++data packet p++check sequence (FCS);
// Construct the link layer packet
repeat forever
{
transmit (frame, to receiver node j);
// Can be done using Receive.receive( ).
parallel
{
Techniques for Protocol Programming 2013
P1: {wait-for (ack);
if (ack == positive) exit repeat loop;
else
continue; // it is negative ack
// waited long enough.
P2: {if time-out() exit repeat loop; }
} // end of parallel
} // end of repeat;
sleep( ) until woken-up( );
}
{
Receiver
node
j
{
repeat for ever
{
// Can be done using Receive.receive ( ).
p = receive-packet( );
result = checksum-test (p);
if (result == success)
{send ("success"); exit repeat loop;}
else send ("failure");
} // end of repeat loop
sleep ( ) until woken-up( );
}
}
Nút nhận(máy thu) dữ liệu sẽ vào chế độ ngủ sau khi nó gửi một tín hiệu ACK
dương (nếu check sum đúng - dữ liệu đúng), còn nếu không nó sẽ gửi tín hiệu
ACK âm cho máy phát rồi đợi máy phát gửi lại gói tin.
{
TRANSMITTER(ARQ)
FSM Model
Transmitter:
s0: frame = getFrame ( );
transmit ( frame );
go to s1;
s1:
Techniques for Protocol Programming 2013
receive( );
if acktype = +ve then {frame = getFrame( );
transmit (frame)}
else
{ transmit (frame);}
upon ack go to s1;
// Use Receive.receive( ) for this.
----------------------
global: frame, acktype = +ve;
booted( ):
frame = getFrame( ); transmit (frame)
receive( ):
actype = extract ack type( );
if acktype = + ve then {frame = getFrame( );
transmit (frame)}
else
{ transmit (frame); }
}
{
RECEIVER
fired( ):
{NULL}
receive( ):
if checksum is valid then
send +ve ack else send -ve ack;
}
Nếu tín hiệu ACK âm bị mất và bên máy phát đã quá thời gian time out, vì vậy
bên máy thu sẽ phải chờ bên máy phát gửi lại gói tin bị hỏng nhưng bên máy phát
lại không có tín hiệu ACK âm. Để kết thúc sự chờ đợi mãi mãi như vậy thì bên
máy phát sẽ thực hiện lệnh receive-packet(). Kết quả là lãng phí thời gian chờ đợi
quá nhiều làm tiêu hao thời lượng pin.
VI. ALTERNATING-BIT-BASED ARQ PROTOCOLS
Một biến thể nhỏ của giao thức trên là giao thức alternating-bit-based. Trong giao
thức này máy phát sẽ sử dụng một bít gọi là bit điều khiển, được thiết lập luân
phiên là 0 hoặc 1, để truyền tải gói tin p1, máy phát sẽ thêm vào bit 0 rồi đến gói
Techniques for Protocol Programming 2013
tin P1 khi đó gói tin mới có dạng 0:P1 sau đó truyền tới cho máy thu, đặt thời gian
s và chờ đợi tín hiệu báo nhận ACK, nếu thời gian timeout xảy ra trước khi nhận
được tín hiệu ACK từ máy thu thì máy phát sẽ gửi lại gói tin 0:P1. Khi nhận được
tín hiệu ACK từ máy thu thì máy phát sẽ gửi gói tin tiếp theo p2, khi đó ta sẽ thêm
bit điều khiển 1 vào trước p2 khi đó p2 có dạng 1:P2. Nếu máy thu nhận được gói
tin p2 và báo nhận lại thì ta truyền tiếp gói tin p3 có dạng 0:P3. Như vậy giao thức
này có thể quản lý việc truyền dữ liệu ngay cả khi mất tín hiệu ACK.
{
Transmitter i Control bit b = 0;
REPEAT: repeat for ever
{
read-packet-to-send (p);
RESEND: transmit (b:p);
PARALLEL:
P1: { wait-for-ack( );
p = p+1 mod 2;}
// Receive.receive( );
no clock necessary .
P2: { time-out( );
goto RESEND;
}
}
{
Receiver j
Control bit b = 0;
repeat for ever
{
receive-packet (p);
// Receive.receive( );
is adequate to handle this situation.
b1 = extract-control-bit (p);
d = extract-data (p);
if (b1 = b) && checksum-valid (p) then
{send-ack( ); b = b+1 mod 2;};
// No -ve ack is sent.
// Go back and wait for the
// next transmission of the same data.
Techniques for Protocol Programming 2013
}
}
{
TRANSMITTER _ alternating bit
FSM Model
Transmitter
s0: bit =1; c bit = 1;
frame = getFrame( );
transmit (frame);
// c bit is control bit (sent by receiver)
go to s1;
s1: receive( );
if c bit == bit
{ bit = bit + 1 mod 2; frame = bit: packet };
transmit (frame); upon ack: goto s1;
--------------------------
Pseudo code for nesC:
global: bit = 1, c bit = 1;
booted( ):
frame = getFrame( ); transmit (frame)
receive( ):
actype = extract acktype( );
if acktype = + ve then
{frame = getFrame( ); transmit (frame)}
else { transmit (frame);}
}
{
Receiver _ alternating bit
s0: control bit = 0; goto s1;
s1: receive( );
b1 = extract-control-bit (p);
d = extract-data (p);
if (b1 = b) & checksum-valid (p) then
{send-ack( ); b = b+1 mod 2;};
// No -ve ack is sent.
}
1. A Generalized Version of the Previous Protocol:
Techniques for Protocol Programming 2013
Chúng ta có thể khái quát các giao thức trên được trình bày ở trên bằng cách quay
lại bước truyền n và bắt đầu truyền lại chúng. Chúng tôi sẽ minh họa điều này với
một ví dụ dưới đây.
2. Ví dụ:
Đặt N= e4, ta sẽ dùng một bộ đệm lưu lại các gói tin. Bắt đầu ta sẽ thêm vào bộ
đệm 8 gói tin, thêm vào mỗi gói tin một byte(8 bit) điều khiển, do đó ta có bộ đệm
có dạng buff = 0:p0,1:p1,2p2,3p3,4p3,5p4,6p5,7p6, bắt đầu gửi gói tin từ trái trở đi
0:p0,1:p1,2:p2, . . . . (cùng một thời điểm), đồng thời nhận tín hiệu ACK gửi về và
xử lí chúng, đặt b là byte điều khiển của gói tin đã gửi. Bên máy thu giả sử luôn
gửi một tín hiệu ACK dương ( các gói tin đã gửi thành công)
{
transmitter
A
{
// Let Nmax = 4.
repeat forever{
load buffer [0:7] = 0: packet0: 1: packet1:.. .: 7: packet7;
i = -1; // j is number of packets for which acks received.
go = 1;
PAR
P1: while (i < 7 )
{
shared:
if (go) i = i +1;
send (i: packet);
go = 1;
if (i ==7) wait( );
}
P2:
wait-for-ack( );
// Receive.receive( ); should solve this problem.
j = extract-control-digit (ack);
delete j: packet j from the buffer;
shared: { i = j +1; go = 0}
Techniques for Protocol Programming 2013
} // for ever;
{
receiver B
while (1) {
receive ( from node a, packet p); // Receive.receive( ).
contorl-digit j = extract-control-digit (from packet p);
send-ack (control-digit);
data = extract-data (from packet p);
process (data);
}
}
{
Transmitter _ GENERALIZED VERSION
Transmitter:
s0: c=0, k=0; goto s1;
s1: while (k < 7) { send a[ k ]; k ++; };
s2: receive( );
cbit = extract cbit( );
if (cbit == c) then (c=c+1 mod 8)
else k = c; go to s1;
nesC code
booted( )
c=0; k =0;
transmit( );
transmit( ):
while (k < 7) {send a [ k ]; k ++; };
receive( ):
cbit = extract cbit( );
if (cbit == c) then (c=c+1 mod 8) else k = c;
call transmit( );
}
{
Receiver _ GENERALIZED VERSION
s0: receive ( from node a, packet p);
contorl-digit j = extract-control-digit (from packet p);
send-ack (control-digit);
data = extract-data (from packet p);
process (data);
}
Techniques for Protocol Programming 2013
VII. SELECTIVE REPEAT/SELECTIVE REJECT (lựa chọn lặp lại/ lựa chọn
từ chối)
Phương pháp này đơn giản hơn các phương pháp đã nêu trên đó, trong cách truyền
dữ liệu này thì cả máy phát và máy thu đều sử dụng một bộ nhớ đệm dùng để lưu
các giá trị được gửi đến mà chưa kịp truyền đi, hay nhớ các báo nhận ACK gửi
đến… Các máy phát gửi liên tiếp các gói tin cho máy thu, máy thu kết thúc nhận
dữ liệu khi có tín hiệu +ACK (ACK dương) và nếu gói bị hỏng hoặc gửi thiếu nó
sẻ gửi cho máy phát một –ACK(ACK âm), từ đó máy phát sẽ so sánh và gửi lại cái
gói tin bị hỏng theo chỉ số của báo nhận ACK tương ứng. Phương pháp này có lợi
thế hơn các phương pháp kia vì có bộ đệm nên khi có bị mất gói tin và cần gửi lại
thì máy phát sẽ lấy như bộ đệm, song do có bộ đệm nên sẽ tiêu tốn nhiều không
gian bộ nhớ hơn trong mạng, từ đó sẽ dẫn đến chi phí hạ tầng mạng tăng cao.
Transmitter A
{
bufer1 [0 .. 7 ] = 0: p0 ++ 1: p1 ++ 2:
p2 ++ ... ++ 7: p7;
send-now [ 0 .. 7 ] = 0, 1 ,.., 7;
send-next [ 0 .. 7 ] = non empty junk;
j = -1; end =0;
// initially start sending from buffer1 [ ].
while (send-next [ ] != empty)
{
PARALLEL:
{
PAR1:{
Techniques for Protocol Programming 2013
for ( i = 0, i < size; i ++)
{
i1 = send-now[i];
send (to node B, buffer1 [i1]); }
end = 1;
}
PAR2:{
while (end != 1)
{
wait-for (ack, from node B);
packet-id pid =
extract-control-byte (ack);
ack-type = extract-ack-type (ack);
if (ack-type = negative)
{ send-next [++ j] = pid; }
} // end while
send-now [ ] = send-next [ ];
size = size of send-next [ ];
} // end PAR2
} // end PARALLEL.
} // end while.
}
{
receiver B
buffer [ 0 .. 7 ] = empty;
Techniques for Protocol Programming 2013
i = 0;
while (i < 7)
{
receive (packet p, from node A);
packet-id = get-packet-id (packet p);
data = get-data (packet p);
if (packet-id == i)
{ buffer [ i ] = data; i = i + 1; send (+ve ack)}
else
send (-ve ack, i);
}
}
{
Transmitter-Selective
Repeat/Selective Reject
s0: k = 0;
s1: while (k < 7) send (a [k]); goto s2;
s2: receive( );
c = control bit( );
if ack-for (c) is -ve then send a [c];
}
{
Receiver-Selective Repeat/Selective Reject
s0: i =0;
while (i < 7)
Techniques for Protocol Programming 2013
{
receive (packet p, from node A);
packet-id = get-packet-id (packet p);
data = get-data (packet p);
if (packet-id == i)
{
buffer [i] = data;
i = i +1;
send (+ve ack)
}
else
send (-ve ack, i);
}
nesC code:
booted( ):
i = 0;
receive( ):
}
Trong một số ứng dụng thực tế, phương pháp này tỏ ra có lợi hơn
VIII. NAMING AND ADDRESSING
Trong môi trường bên ngoài thì các nút trong mạng cảm biến có thể hư hỏng bất cứ
khi nào. Vì vậy trong một WSN thì các nút phân bố trong mạng phải được gán
một địa chỉ duy nhất, việc này để dể dàng trong việc quản lí các nút trong khi phát
sinh các trường hợp mới. Ví dụ một nút trong mạng làm cầu nối(nút trung gian)
giữa hai mạng con, và nút này vì một lý do nào đó mà nó không hoạt động, khi đó
Techniques for Protocol Programming 2013
thì cả hai mạng con này sẽ bị mất kết nối, việc đó khiến cho các nút trong mạng sẽ
không hoạt động được. Trong khi để quản lí địa chỉ là một vấn đề khó khăn. Chúng
ta sẽ tìm hiểu một số kĩ thuật trong lập trình cách đặt tên và gán địa chỉ cho các nút
trong mạng.
IX. DISTRIBUTED ASSIGNMENT OF NETWORKWIDE ADDRESSES
(phân cấp và gán địa chỉ cho mạng rộng )
Đây là kĩ thuật đơn giản gán mỗi địa chỉ cho mỗi nút, tuy nhiên chi phí cho kĩ thuật
này là rất khó. Trong kĩ thuật này mỗi nút tạo ra một địa chỉ ngẫu nhiên, sau đó đặt
địa chỉ đó như là địa chỉ riêng của mình, sau đó nó sẽ phát tín hiệu để kiểm tra các
nút kế cận xem có bị trùng lặp với địa chỉ riêng không. Nếu có sự trùng lặp với địa
chỉ của nút bên cạnh thì nó sẽ cố gắng chọn một địa chỉ ngẫu nhiên rồi tiếp tục
kiểm tra với các nút bên cạnh một lần nữa. Công việc này được lặp lại cho đến khi
không còn có sự trùng lặp địa chỉ với nút bên cạnh.
module algorithm2C
{
uses interface Boot;
uses interface Random;
uses interface Leds;
uses interface AMPacket;
uses interface Packet;
uses interface AMSend;
uses interface ActiveMessageAddress as AMA;
uses interface PacketAcknowledgements;
uses interface Receive;
uses interface SplitControl as RadioCont rol;
uses interface Timer <TMilli> as Timer0;
}
implementation
{
void generateAddress( );
void broadcastAddress( );
am group t my group = 1;
Techniques for Protocol Programming 2013
am addrt myaddress;
bool conflict;
event void Boot.booted( )
{
call RadioControl.start( );
}
/**************************************************
Compute global addresss for each specific node and
test if the address is in use
**************************************************/
event void RadioCont rol.startDone (error t err)
{
// First we generate the address of the mote
generateAddress( );
// The initial address broadcast
call Timer0.startOneShot (6000);
// At this point, we can set the generated address
call AMA. setAddress (my group, my address);
}
event void AMSend.sendDone (message t* msg, error t err)
{
if (err == FAIL)
{
call Leds.led0On( );
}
}
event void Timer0.fired()
{
message t msg;
am addr t* temp;
temp = (am addr t*) call AMSend.getPayload (&msg);
temp = &my address;
call AMSend.send (0 x ffff, &msg, sizeof (am addr t));
}
/****************************************************
A simple function that randomly generates an address
for a mote
Techniques for Protocol Programming 2013
****************************************************/
void generateAddress( )
{
call Leds.set (0);
my address = (31071334523 % (call Random.rand16( )));
}
void broadcastAddress( )
{
message t msg;
am addr t* temp;
temp = (am addr t*) (call AMSend.getPayload (&msg));
*temp = call AMA.amAddress( );
call AMSend. send (0 x ffff,&msg, sizeof (am addr t));
}
async event void AMA.changed( )
{
}
event void RadioControl.stopDone (error t err)
{
}
event message t* Receive.receive (message t *msg,
void* payload,... uint8 t len)
{
am addr t broadcasted addr;
broadcasted addr = (am addr t*) payload;
Techniques for Protocol Programming 2013
call Leds.set (0); // Clear debug leds
if (*broadcasted addr ==
(call AMA.amAddress( ))) // Generate a new
// addr
{
call Leds.led0On( );
// A collision has occured
generateAddress( );
call AMA.setAddress
(my group, my address);
broadcastAddress( );
// Only broadcast new address
// after a collision
}
else
{
call Leds.led1On( ); // No collison yet
}
return msg;
}
}
Các công việc để triển khai giao thức này, một bộ giao diện sẻ được khởi động các
thành phần như: đưa ra các hệ số ngẫu nhiên, việc gửi nhận các thông tin cho các
nút kế cận, tự động hẹn giờ để phát sóng ra cho các nút lân cận, tạo ra một địa chỉ
ngẫu nhiên…
#define MOTE AM ID 10
configuration algorithm2AppC { }
implementation
{
components MainC;
Techniques for Protocol Programming 2013
components RandomC;
components LedsC;
components new AMSenderC(MOTE AM ID);
components new AMReceiverC(MOTE AM ID);
components ActiveMessageAddressC;
components algorithm2C;
components ActiveMessageC;
components new TimerMilliC( );
algorithm2C.Boot->MainC. Boot;
algorithm2C.Random->RandomC;
algorithm2C.Leds->LedsC;
algorithm2C.AMPacket->AMSenderC;
algorithm2C.Packet->AMSenderC;
algorithm2C.AMSend->AMSenderC;
algorithm2C.AMA->ActiveMessageAddressC;
algorithm2C.PacketAcknowledgements->AMSenderC;
algorithm2C.Receive->AMReceiverC;
algorithm2C.RadioControl->ActiveMessageC;
algorithm2C.Timer0->TimerMilliC;
}
void generateAddress( )
{
call Leds.set (0);
my address = (31071334523 % (c a l l Random. rand16( )));
}
Techniques for Protocol Programming 2013
void broadcastAddress( )
{
message t msg;
am addr t* temp;
temp = (am addr t*) (call AMSend. getPayload (&msg));
*temp = call AMA. amAddress( );
call AMSend. send (0 x ffff,&msg, sizeof (am addr t));
}
Ngoài ra để kiểm soát và các sự kiến xảy ra trong quá trình giao tiếp trong mạng,
khi đó ta có thể dùng nhiều hơn hai địa điểm để tạo ra các địa chỉ ngẫu nhiên và
phát sóng các địa chỉ ra các nút lân cận.
event void Boot.booted( )
{
call RadioCont rol.start( );
}
event void RadioCont rol.startDone (error t err)
{
// puts the address in my address.
generateAddress( );
// The initial address broadcast
call Timer0.startOneShot (6000);
// Check once if any one else has my address.
// If not, at this point, we can set the
generated address
call AMA.setAddress (my group, my address);
}
Địa chỉ của tôi là một biến số toàn cục trong các địa chỉ ngẫu nhiên được lưu trữ,
sau đó được phát ra cho các nút lân cận.
Ngay sau khi các thành phần được nêu trên được bật bởi lệnh RadioControl.start()
thì chúng ta sẽ thực hiện các nhiệm vụ sau đây. Đầu tiên sẽ tạo ra một địa chỉ ngẫu
Techniques for Protocol Programming 2013
nhiên và đặt vào trong biến toàn cục của tôi. Chúng ta sẽ kiểm tra tất cả các nút có
cùng địa chỉ với mình (các địa chỉ trùng lặp), các trùng lặp được bắt đầu bằng một
one-shot (monoshot) xảy ra sẻ gây ra các chậm trể (6000ms) trong chương trình
của tôi. Nếu không có sự trùng lặp thì ta thiết lập được địa chỉ riêng cho mỗi nút
trong mạng. Nhiệm vụ còn lại là chờ đợi và trả lời các truy vấn nếu có sự trùng lặp
địa chỉ.
event void Timer0.fired( )
{
message t msg;
am addr t *temp;
temp = (am addr t *) call AMSend. getPayload (&msg);
// storing the address of my address in temp.
*temp = my address;
call AMSend.send (0 x ffff, &msg, sizeof (am addr t));
}
event void AMSend. sendDone (message t *msg, error t err)
{
if(err == FAIL)
{
// If send fails, switch on red led
call Leds.led0On( );
}
}
event message t *Receive.receive(message t* msg, void*
payload, uint8 t len)
{
am addr t* broadcasted addr;
broadcasted addr = (am addr t*)payload;
call Leds.set (0); // Clear debug leds
if(*broadcasted addr == (call AMA.amAddress( )))
// Generate a new addr
{
call Leds.led0On( ); // A collision has occured
generateAddress( );
call AMA.setAddress (my group, my address);
broadcastAddress( ); // Only broadcast
Techniques for Protocol Programming 2013
new address after// a collision
}
else
{
call Leds.led1On( ); // No collison yet
}
return msg;
}
Các xung đột monoshot gây nên sự kiên fired() nơi mà chúng ta gửi gói tin tới nút
lân cận, ta thiết lập một trọng tải và lưu trữ địa chỉ của tôi như một phần của các
gói tin, sau đó gửi các gói tin đi. Sau khi gửi các gói tin nếu có bất kì báo cáo về lỗi
gửi thì chúng ta sẽ bật một đèn LED, sau này ta sẽ không cố gắng gửi lại gói tin
nữa mà nếu nhận được mốt gói tin bất kì thì ta sẽ tách lấy địa chỉ của người gửi rồi
so sánh với địa chỉ của mình để xem có bị trùng lặp không. Nếu không có trùng lặp
ta sẽ tự thiết lập và nhớ địa chỉ của mình và đánh dấu bằng cách đặt một cờ báo( từ
giờ trở đi sẽ không trả lời tin nhắn từ các nút khác gửi đến và cũng không thay đổi
địa chỉ của mình nữa. Điều này đạt được bằng thiết lập cờ báo TRUE). Tuy nhiên
nếu ta nhận thấy địa chỉ bị trùng lặp thì ta sẽ tạo ra một địa chỉ và gán đó là địa chỉ
của mình, sau đó phát đi báo cho các nút lân cận và chờ các nút đó trả lời. Ta cứ
tiếp tục như thế cho đến khi tìm thấy địa chỉ của mình. Trước khi làm xong công
việc ta cần thêm vào một số chi tiết dưới đây.
void generateAddress( )
{
call Leds. set (0);
my address = (31071334523 \% (call Random. rand16( )));
}
async event void AMA.changed( ) { }
event void RadioControl.stopDone (error t err) { }