THIS PROGRAM FOR ZIGBEE IS IN 3 PART SAVE ALL THREE PART IN DIFFERENT EDITOR FILE AND THEN RUN
%>>>>>>>>PROGRAM 1>>>>>>>>>>>>>>
%>>>>>>>>PROGRAM 1>>>>>>>>>>>>>>
% Input parameters
clear
% Parameters for ZigBee network topology generator
tranRange=25;
Cm=3; Lm=6;
% bs1=1093;
n=31;
rseed = 1;
rnseed = 1;
s=1;
drawFigure = 3;
% Generate ZigBee network
% ZigBee physical network topology generator
rand('state', rseed);
randn('state', rnseed);
bSize=(Cm^(Lm+1)-1)/(Cm-1);
maxN=min([65536/16, bSize]); % the maximal number of node can be supported <= 4096
% maxn is the actual number of nodes in the simulation
maxn=min([n, maxN]);
maxX=100; maxY=100;
% We may later need to specify how many leaves and non-leaves out of maxn
% Internal parameters
for i=0: Lm
cSkip(i+1) = (Cm^(Lm-i+1)-1)/(Cm-1);
end
maxNeighbor=maxn-1;
maxInfo=6;
% node information includes:
% 1: id
% 2: position x
% 3: position y
% 4: number of children (at most Cm)
% 5: number of neighbors (at most maxNeighbor)
% 6: level
cc = zeros(1, 4);
% Output parameters
info=zeros(maxn, maxInfo);
neighbor=zeros(maxn, maxNeighbor) - 1;
tneighbor=zeros(maxn, Cm+1) - 1;
neighbor2=zeros(maxn, maxNeighbor+1);
% First, initialize the root (WPAN coordinator) at the center
x=1/2*maxX;
y=1/2*maxY;
info(1 , :) = [0, x, y, 0, 0, 0];
% tneighbor(1, 1) = -1; % the root does not have on-tree parent
% Associate new nodes
for i = 2: maxn
while(1)
successSign = 0;
x=rand * maxX;
y=rand * maxY;
for j = 1: (i-1)
if (sqrt((info(j,2)-x)^2+(info(j,3)-y)^2) > tranRange) % j is out of range
continue;
else
[level, child] = zblevel(Cm, Lm, info(j, 1)); % we only need 'level' here
if (info(j, 4) < min([Cm, cSkip(level+1)-1])) % j can have more children
% if level >= Lm % j is a leaf, cannot have any children
% continue;
% end
t1 = info(j, 1) + 1 + info(j, 4) * cSkip(level+1+1); % new address
if t1 >= maxN
continue;
end
info(i, 1) = t1;
info(i, 2:5) = [x, y, 0, 0];
info(i, 6) = level + 1;
tneighbor(i, 1) = j; % j is i's on-tree parent
info(j, 4) = info(j, 4) + 1;
tneighbor(j, 1+info(j, 4)) = i; % i is j's new child
successSign = 1;
break;
end
end
end
if successSign == 1
break;
end
end % while
end
if drawFigure >= 1
% colordef none, whitebg
figure(1);
axis equal
hold on;
set(gca,'Box','on');
plot(info(:, 2), info(:, 3), 'ko', 'MarkerSize', 5);
plot(info(1, 2), info(1, 3), 'k*');
title('Physical network topology');
xlabel('X');
ylabel('Y');
axis([0, maxX, 0, maxY]);
set(gca, 'XTick', [0; maxX]);
set(gca, 'YTick', [maxY]);
end
if drawFigure >= 2
% Draw on-tree links
for i = 1 : maxn
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
line([info(i, 2), info(k, 2)], [info(i, 3), info(k, 3)], 'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.5);
end
end
end
end
% Construct neighbor table
for i = 1: maxn
k=0;
for j = 1: maxn
if i == j
continue;
end
if (sqrt((info(j,2)-info(i,2))^2+(info(j,3)-info(i,3))^2) > tranRange) % j is out of range
if (sqrt((info(j,2)-info(i,2))^2+(info(j,3)-info(i,3))^2) <= tranRange)
neighbor2(i, 1) = neighbor2(i, 1) + 1;
neighbor2(i, neighbor2(i, 1) + 1) = j;
end
continue;
else
k = k + 1;
neighbor(i, k) = j;
end
end
info(i, 5) = k;
end
if drawFigure >= 3
% Draw other links
for i = 1 : maxn
if info(i, 5) > 0
nt = neighbor(i, 1:info(i, 5));
nt = setdiff(nt, tneighbor(i, 1: info(i, 4) + 1));
t1 = length(nt);
if t1 > 0
for j = 1 : t1
k = nt(j);
if i < k
line([info(i, 2), info(k, 2)], [info(i, 3), info(k, 3)], 'Color', 'k', 'LineStyle', ':', 'LineWidth', 0.5);
end
end
end
end
end
end
% Draw logical ZigBee topology
% ZigBee network topology generator
% Draw the logical tree
% Parameters
tmaxX = 100;
tmaxY = 100;
tystep = (tmaxY - 10) / Lm; % y step between two levels
txstep = zeros(1+Lm, 1); % x step at each level
tx = zeros(maxn, 1) - 1;
ty = zeros(maxn, 1) - 1;
txstep(1) = tmaxX - 10;
for i = 1 : Lm
txstep(i + 1) = txstep(i) / Cm;
end
tx(1) = tmaxX / 2;
ty(1) = 5;
for i = 2 : maxn
if tx(i) <= 0
parent = tneighbor(i, 1);
if tx(parent) <= 0
continue;
else
[level, child] = zblevel(Cm, Lm, info(i, 1));
tx(i) = tx(parent) - txstep(level-1+1) / 2 + txstep(level+1) / 2 + (child-1) * txstep(level+1);
ty(i) = 5 + tystep * level;
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
tx(k) = tx(i) - txstep(level+1) / 2 + txstep(level+1+1) / 2 + (j-1) * txstep (level+1+1);
ty(k) = 5 + tystep * (level + 1);
end
end
end
end
end % for
ty = tmaxY - ty;
if drawFigure >= 1
% Draw nodes
% Figure
figure(2);
axis equal
hold on;
set(gca,'Box','on');
plot(tx, ty, 'ko', 'MarkerSize', 5);
plot(tx(1), ty(1), 'k*');
title('Logical network topology');
xlabel('X');
ylabel('Y');
axis([0, tmaxX, 0, tmaxY]);
set(gca, 'XTick', []);
set(gca, 'YTick', []);
end
if drawFigure >= 2
% Draw on-tree links
for i = 1 : maxn
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
line([tx(i), tx(k)], [ty(i), ty(k)], 'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.5);
end
end
end
% pause;
end
if drawFigure >= 3
% Draw other links
for i = 1 : maxn
if info(i, 5) > 0
nt = neighbor(i, 1:info(i, 5));
nt = setdiff(nt, tneighbor(i, 1: info(i, 4) + 1));
t1 = length(nt);
if t1 > 0
for j = 1 : t1
k = nt(j);
if i < k
line([tx(i), tx(k)], [ty(i), ty(k)], 'Color', 'k', 'LineStyle', ':', 'LineWidth', 0.5);
end
end
end
end
end
end
% Parameters for broadcast algorithms
drawzb = 1; % used for zbbroadcast.m
useu = 1; % use 'u' for selection?
useFu = 1; % use 'F(u)' for selection?
useLQI = 1;
% approach = 4; approach2 = 1;
approach = 1; approach2 = 1;
% approach = 1; approach2 = 2;
% approach = 2; approach2 = 4;
% ZigBee broadcast
if useLQI == 1
ps=100; % sent power
afa=2; % path loss exponential
k1=1;
k2=10;
gama=1; % threshold to compare LQI and LQI0
cigma = 5; % standard deviation of lognormal shadowing
lasttime=zeros(maxn, 1);
kscale = 1/500;
end
% Timer parameters
etimer=zeros(maxn, 1);
etimercount = 1; % used when approach2 == 3, no timer case, not included in this code
etimerscale = 1; % maximum random time out
% Self-pruning parameters:
tocover=[];
todegree=[];
if approach2 == 2
tocover = tneighbor;
todegree = info(: , 4)' + 1;
elseif approach2 == 4 | approach2 == 1
tocover = neighbor;
todegree = info(: , 5)';
end
% Internal parameters
whilesign = 1;
toforward=[];
t1=0;
t2=0;
F = [];
NF = [];
% Output parameters
forward=zeros(maxn, maxNeighbor+3);
% 1: status (0: initial; 1: non forward; 2: forward; 3: already forward)
% 2: if status > 0, who asked me to non-forward or forward
% 3: number of forward nodes
% 4-: my forward nodes
% numSend = 0;
numReceive = 0;
numInitial = 0;
numNonforward = 0;
numAlreadyforward = 0;
numForwardoverhead = 0;
lmine = [];
lgreedy = [];
% Draw source
if drawzb == 1
% Physical topology
figure(3);
axis equal
hold on;
set(gca,'Box','on');
plot(info(s, 2), info(s, 3),'k.', 'MarkerSize', 25);
title('Broadcast on ZigBee physical network topology');
xlabel('X');
ylabel('Y');
axis([0, maxX, 0, maxY]);
set(gca, 'XTick', [0; maxX]);
set(gca, 'YTick', [maxY]);
% Logical topology: tree
figure(5);
axis equal
hold on;
set(gca,'Box','on');
plot(tx(s), ty(s),'k.', 'MarkerSize', 25);
title('Broadcast on ZigBee logical network topology');
axis([0, tmaxX, 0, tmaxY]);
set(gca, 'XTick', []);
set(gca, 'YTick', []);
end
% Global greedy selection, no source needed
if approach == 4
% F = [];
ggS = [];
ggS = zeros(maxn, 3);
% 1: index
% 2: network ID
% 3: degree
ggS(:, 1)=[1:maxn]';
for j = 1: size(ggS, 1)
ggS(j, 2) = info(ggS(j, 1), 1);
end
ggC = [];
ggC = [1:maxn]';
while(length(ggC)>0)
for j = 1: size(ggS, 1)
u=ggS(j, 1);
tn1 = [u, neighbor(u, 1:info(u, 5))]';
ggS(j, 3) = maxNeighbor + 1 - length(intersect(tn1, ggC));
end
ggS = sortrows(ggS, [3, 2]);
u = ggS(1, 1); % the highest degree with the lowest network ID
% info(u, 5) + 1 - ggS(1, 3)
tn1 = [u, neighbor(u, 1:info(u, 5))]';
ggS = ggS(2:size(ggS, 1), :);
ggC = setdiff(ggC, tn1);
if length(intersect(F, u)) > 0
disp('********Global greedy: a forward node already chosen');
end
% F = union(F, u); % sorted
F = [F, u];
forward(u, 1) = 3;
end
if drawzb == 1
for i = 1:length(F)
if F(i) ~= s
figure(3);
plot(info(F(i), 2), info(F(i), 3), 'k.', 'MarkerSize', 25); % o', 'MarkerSize', 3, 'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'k');
figure(5);
plot(tx(F(i)), ty(F(i)), 'k.', 'MarkerSize', 25); % o', 'MarkerSize', 3, 'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'k');
end
for j = 1:info(F(i), 5)
if forward(neighbor(F(i), j), 1) > 0
continue;
end
forward(neighbor(F(i), j), 1) = 1;
figure(3);
line([info(F(i), 2), info(neighbor(F(i), j), 2)], [info(F(i), 3), info(neighbor(F(i), j), 3)], 'Color', 'k');
plot(info(neighbor(F(i), j), 2), info(neighbor(F(i), j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(F(i)), tx(neighbor(F(i), j))], [ty(F(i)), ty(neighbor(F(i), j))], 'Color', 'k');
plot(tx(neighbor(F(i), j)), ty(neighbor(F(i), j)), 'ko', 'MarkerSize', 3);
end
end
end
% Result
numAlreadyforward = length(F);
numInitial = size(find(forward(:, 1)==0), 1);
numNonforward = size(find(forward(:, 1)==1), 1);
for i = 1:length(F)
etimer(F(i)) = rand;
end
timeDelay = max(etimer);
numAlreadyforward
timeDelay
return
end
% Other localized broadcast algorithms
forward(s, 1) = 2; % source is the first to forward
etimer(s) = 1;
etimercount = etimercount + 1;
while(whilesign)
toforward = find(etimer > 0);
t1=length(toforward);
if t1 <= 0
break;
end
t2 = inf;
for i0 = 1 : t1
i = toforward(i0);
if etimer(i) < t2
t2 = etimer(i);
end
end
% 0 < t2 < inf, t2 is the minimum positive time
toforward = find(etimer==t2); % toforward has at least 1 node
etimer = etimer - t2;
for i0 = 1 : length(toforward)
i = toforward(i0);
% Determine forwarding nodes F
F = [];
NF = [];
if approach2 == 1
% ZigBee: every tree neighbor will rebroadcast, but self-prune if all neighbors are covered
F = tneighbor(i, 1 : info(i, 4) + 1);
NF = setdiff(neighbor(i, 1 : info(i, 5)), F);
elseif approach2 == 2
% OSR: every neighbor will rebroadcast, but self-prune if all tree neighbors are covered
F = neighbor(i, 1:info(i, 5));
NF = [];
else % Forward node selection
% OOS, step 1, find S and C
C = [];
% C = TN(i)
C = tneighbor(i, 1: info(i, 4) + 1);
% C = TN(N(i))
if info(i, 5) > 0
S = neighbor(i, 1: info(i, 5));
for j = 1 : info(i, 5)
if tneighbor(S(j), 1) > 0 | info(S(j), 4) > 0
C = union(C, tneighbor(S(j), 1:info(S(j), 4)+1));
end
end
else
S = [];
end
% C is already sorted, remove first ids that < 0.
t1=find(C < 0);
t2=length(t1);
if t2 > 0
if t2 < length(C)
C = C(t2+1 : length(C));
else
C = [];
end
end
% C = TN(N(i)) - N(i)
C = setdiff(C, [i , S]);
if useu == 1
% S -= TN(u), C -= TN2(u)
u = forward(i, 2);
if u > 0 % u is valid
tn1u = [u , tneighbor(u, 1: info(u, 4) + 1)];
S = setdiff(S, tn1u);
for j = 1: length(tn1u)
if tn1u(j) <= 0 | info(tn1u(j), 1) < 0
continue;
end
C = setdiff(C, [tn1u(j) , tneighbor(tn1u(j), 1: info(tn1u(j), 4) + 1)]);
end
end
end
if useu == 1 & useFu == 1 & u > 0 & forward(u, 3) > 1 % F(u)-i is valid
% S -= F(u), C -= TN(F(u))
Fu = setdiff(forward(u, 4: 4+forward(u, 3)-1), i);
S = setdiff(S, Fu);
for j = 1: forward(u, 3)-1
tn1f = [Fu(j) , tneighbor(Fu(j), 1: info(Fu(j), 4) + 1)];
C = setdiff(C, tn1f);
end
end
if length(S) <= 0 | length(C) <=0
forward(i, 1) = 3; % still need to forward, but no selected forward nodes
if info(i, 5) > 0 % must be true: at least have a parent, except root
NF = neighbor(i, 1: info(i, 5));
for j = 1 : info(i, 5)
numReceive = numReceive + 1;
if forward(NF(j), 1) <= 0
forward(NF(j), 1) = 1; % non-forward
forward(NF(j), 2) = i;
if drawzb == 1
figure(3);
plot(info(NF(j), 2), info(NF(j), 3), 'k.');
line([info(i, 2), info(NF(j), 2)], [info(i, 3), info(NF(j), 3)], 'color', 'k');
figure(5);
plot(tx(NF(j)), ty(NF(j)), 'k.');
line([tx(i), tx(NF(j))], [ty(i), ty(NF(j))], 'color', 'k');
end
end
end
end
end
% OOS, Step 2, construct the trees
forest = [];
forest = zeros(length(C), 4);
% 1: index
% 2: network ID
% 3: level
% 4: status: 0: not processed, 1: processed
forest(:, 1)=C'; % S*C should be empty
for j = 1: size(forest, 1)
forest(j, 2) = info(forest(j, 1), 1);
forest(j, 3) = Lm - info(forest(j, 1), 6);
end
forest = sortrows(forest, [3, 2]);
% OOS, Step 3, select forward nodes
F = [];
for j = 1:size(forest, 1)
if forest(j, 4) > 0
continue;
end
t1 = forest(j, 1);
t2 = tneighbor(t1, 1); % parent of t1
if t2 > 0 & length(find(S==t2)) > 0
if length(intersect(F, t2)) > 0
disp('*********My approach: a forward node already chosen');
end
F = union(F , t2);
% F = [F, t2];
t3 = tneighbor(t2, 1); % parent of t2
if t3 > 0
t4 = find(forest(:, 1)==t3);
if length(t4) > 0 % at most 1 item in t4
% length(t4)
forest(t4(1), 4) = 1;
end
end
k = j + 1;
while(k <= size(forest, 1))
if tneighbor(forest(k, 1), 1) ~= t2
break;
end
forest(k, 4) = 1; % processed
k = k + 1;
end
else
t3 = intersect(tneighbor(t1, 2:(info(t1, 4)+1)), S);
if length(intersect(F, t3)) > 0
disp('*********My approach: a forward node already chosen');
end
F = union(F, t3(1));
% F = [F, t3(1)];
end
forest(j, 4) = 1;
end
NF = [];
NF = setdiff(neighbor(i, 1 : info(i, 5)), F);
end
% Forwarding
forward(i, 1) = 3; % already forward
if drawzb == 1 & i ~= s
figure(3);
plot(info(i, 2), info(i, 3), 'k.', 'MarkerSize', 25);
figure(5);
plot(tx(i), ty(i), 'k.', 'MarkerSize', 25);
end
t1 = length(F);
if t1 > 0
forward(i, 4: 4 + t1 - 1) = F;
forward(i, 3) = t1;
for j = 1 : t1
if F(j) <= 0
continue;
end
numReceive = numReceive + 1;
if forward(F(j), 1) == 1 | forward(F(j), 1) == 3
continue;
end
% Self-pruning
tt = [];
tt = tocover(F(j), 1:todegree(F(j)));
tt = setdiff(tt, [i, tneighbor(i, 1:info(i, 4)+1)]);
todegree(F(j)) = length(tt);
if todegree(F(j)) <= 0 % self-pruning
forward(F(j), 1) = 1;
if drawzb == 1
figure(3);
line([info(i, 2), info(F(j), 2)], [info(i, 3), info(F(j), 3)], 'Color', 'k');
plot(info(F(j), 2), info(F(j), 3), 'k.');
figure(5);
line([tx(i), tx(F(j))], [ty(i), ty(F(j))], 'Color', 'k');
plot(tx(F(j)), ty(F(j)), 'k.');
end
etimer(F(j)) = 0;
if approach2 == 4
disp('This forward node is self-pruned and does not need to forward');
end
continue;
end
tocover(F(j), 1:todegree(F(j))) = tt;
if forward(F(j), 1) == 0
% Update status
forward(F(j), 2) = i;
forward(F(j), 1) = 2;
% Add timer for a candidate forward node
if useLQI == 0
% Random waiting time
etimer(F(j)) = rand * etimerscale;
end
if drawzb == 1
figure(3);
line([info(i, 2), info(F(j), 2)], [info(i, 3), info(F(j), 3)], 'Color', 'k');
plot(info(F(j), 2), info(F(j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(i), tx(F(j))], [ty(i), ty(F(j))], 'Color', 'k');
plot(tx(F(j)), ty(F(j)), 'ko', 'MarkerSize', 3);
end
end
if useLQI == 1
lqi0 = ps-afa*10*log10(sqrt((info(i, 2)-info(F(j), 2))^2 + (info(i, 3)-info(F(j), 3))^2));
% lqi0
lqi = lqi0-cigma*randn;
% lqi
if lqi>=(lqi0-gama)
time1 = k2 * lqi0 / todegree(F(j));
else
time1 = k1*(lqi0-lqi) + k2*lqi0 / todegree(F(j));
% time2 = time1;
end
time1 = time1 * kscale;
if forward(F(j), 1) == 0
etimer(F(j)) = time1;
lasttime(F(j)) = time1;
else
forward(F(j), 2) = i;
etimer(F(j)) = time1 - (lasttime(F(j)) - etimer(F(j))); % t > 0
if etimer(F(j)) <= 0
% disp('new timer less than 0');
etimer(F(j)) = 0.001 * rand;
end
lasttime(F(j)) = etimer(F(j));
end
end
end
end
t1 = length(NF);
if t1 > 0
for j = 1 : t1
numReceive = numReceive + 1;
if approach2 ~= 1 % on-tree flooding receive it and drop it
if forward(NF(j), 1) == 0
forward(NF(j), 1) = 1; % non-forward
forward(NF(j), 2) = i;
if drawzb == 1
figure(3);
line([info(i, 2), info(NF(j), 2)], [info(i, 3), info(NF(j), 3)], 'Color', 'k');
plot(info(NF(j), 2), info(NF(j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(i), tx(NF(j))], [ty(i), ty(NF(j))], 'Color', 'k');
plot(tx(NF(j)), ty(NF(j)), 'ko', 'MarkerSize', 3);
end
elseif forward(NF(j), 1) == 2
% Self-pruning
tt = [];
tt = tocover(NF(j), 1:todegree(NF(j)));
tt = setdiff(tt, [i, tneighbor(i, 1:info(i, 4)+1)]);
todegree(NF(j)) = length(tt);
if todegree(NF(j)) <= 0 % self-pruning
forward(NF(j), 1) = 1;
% if drawzb == 1
% figure(3);
% plot(info(NF(j), 2), info(NF(j), 3), 'k.');
% figure(5);
% plot(tx(NF(j)), ty(NF(j)), 'k.');
% end
etimer(NF(j)) = 0;
% disp('This forward node does not need to forward');
continue;
end
tocover(NF(j), 1:todegree(NF(j))) = tt;
end
end
end
end
% fishish a forward
end % for
end % while
% Output results
numInitial = size(find(forward(:, 1)==0), 1); % should be zero if network is connected
numNonforward = size(find(forward(:, 1)==1), 1);
numAlreadyforward = size(find(forward(:, 1)==3), 1);
timeDelay = -etimer(s); % = -min(etimer) - 1;
numForwardoverhead = 0;
for i = 1:maxn
if forward(i, 1) ~= 3
continue;
end
numForwardoverhead = numForwardoverhead + forward(i, 3);
% numReceive = numReceive + info(i, 5);
end
numAlreadyforward
numNonforward
numReceive
timeDelay
%>>>>>>>>>>>>>>PROGRAM 2>>>>>>>>>>>>>>>>>>>>>>>>>>
%>>>>>>>>>>>>>>PROGRAM 2>>>>>>>>>>>>>>>>>>>>>>>>>>
%.............................BUT THIS PROGRAM WILL SHOW ERROR WITHOUT THESE %TWO FUNCTION FILE SO FIRSTLY SAVE THESE FUNCTION IN DIFFERENT %EDITOR AND THEN RUN ABOVE %PROGRAM..................................................................................>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%............FUNCTION FOR CSKIP.......
function cskip = cskip(Cm, Lm, i)
% cskip: return the cskip of level i
% cskip of level i means the total number of ids a node at level i has,
% inlucding the node itself
cskip = (Cm^(Lm-i+1)-1)/(Cm-1);
return
%>>>>>>>>>>>>>>PROGRAM 3>>>>>>>>>>>>>>>>>>>>>>>>>>
%>>>>>>>>>>>>>>PROGRAM 3>>>>>>>>>>>>>>>>>>>>>>>>>>
function [level, child] = zblevel(Cm, Lm, id)
% return the level of id in the ZigBee tree, and it is the 'child'th child of its parent
if id == 0
level = 0;
child = 1;
return
end
i=1;
while(mod(id-1, cskip(Cm, Lm, i)))
id=mod(id-1, cskip(Cm, Lm, i));
i=i+1;
end
level = i;
child = floor((id-1)/cskip(Cm, Lm, i)) + 1;
return
%>>>>>>>>>>>>>>END>>>>>>>>>>>>>>>>>>>>>>>>>>
%>>>>>>>>PROGRAM 1>>>>>>>>>>>>>>
%>>>>>>>>PROGRAM 1>>>>>>>>>>>>>>
% Input parameters
clear
% Parameters for ZigBee network topology generator
tranRange=25;
Cm=3; Lm=6;
% bs1=1093;
n=31;
rseed = 1;
rnseed = 1;
s=1;
drawFigure = 3;
% Generate ZigBee network
% ZigBee physical network topology generator
rand('state', rseed);
randn('state', rnseed);
bSize=(Cm^(Lm+1)-1)/(Cm-1);
maxN=min([65536/16, bSize]); % the maximal number of node can be supported <= 4096
% maxn is the actual number of nodes in the simulation
maxn=min([n, maxN]);
maxX=100; maxY=100;
% We may later need to specify how many leaves and non-leaves out of maxn
% Internal parameters
for i=0: Lm
cSkip(i+1) = (Cm^(Lm-i+1)-1)/(Cm-1);
end
maxNeighbor=maxn-1;
maxInfo=6;
% node information includes:
% 1: id
% 2: position x
% 3: position y
% 4: number of children (at most Cm)
% 5: number of neighbors (at most maxNeighbor)
% 6: level
cc = zeros(1, 4);
% Output parameters
info=zeros(maxn, maxInfo);
neighbor=zeros(maxn, maxNeighbor) - 1;
tneighbor=zeros(maxn, Cm+1) - 1;
neighbor2=zeros(maxn, maxNeighbor+1);
% First, initialize the root (WPAN coordinator) at the center
x=1/2*maxX;
y=1/2*maxY;
info(1 , :) = [0, x, y, 0, 0, 0];
% tneighbor(1, 1) = -1; % the root does not have on-tree parent
% Associate new nodes
for i = 2: maxn
while(1)
successSign = 0;
x=rand * maxX;
y=rand * maxY;
for j = 1: (i-1)
if (sqrt((info(j,2)-x)^2+(info(j,3)-y)^2) > tranRange) % j is out of range
continue;
else
[level, child] = zblevel(Cm, Lm, info(j, 1)); % we only need 'level' here
if (info(j, 4) < min([Cm, cSkip(level+1)-1])) % j can have more children
% if level >= Lm % j is a leaf, cannot have any children
% continue;
% end
t1 = info(j, 1) + 1 + info(j, 4) * cSkip(level+1+1); % new address
if t1 >= maxN
continue;
end
info(i, 1) = t1;
info(i, 2:5) = [x, y, 0, 0];
info(i, 6) = level + 1;
tneighbor(i, 1) = j; % j is i's on-tree parent
info(j, 4) = info(j, 4) + 1;
tneighbor(j, 1+info(j, 4)) = i; % i is j's new child
successSign = 1;
break;
end
end
end
if successSign == 1
break;
end
end % while
end
if drawFigure >= 1
% colordef none, whitebg
figure(1);
axis equal
hold on;
set(gca,'Box','on');
plot(info(:, 2), info(:, 3), 'ko', 'MarkerSize', 5);
plot(info(1, 2), info(1, 3), 'k*');
title('Physical network topology');
xlabel('X');
ylabel('Y');
axis([0, maxX, 0, maxY]);
set(gca, 'XTick', [0; maxX]);
set(gca, 'YTick', [maxY]);
end
if drawFigure >= 2
% Draw on-tree links
for i = 1 : maxn
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
line([info(i, 2), info(k, 2)], [info(i, 3), info(k, 3)], 'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.5);
end
end
end
end
% Construct neighbor table
for i = 1: maxn
k=0;
for j = 1: maxn
if i == j
continue;
end
if (sqrt((info(j,2)-info(i,2))^2+(info(j,3)-info(i,3))^2) > tranRange) % j is out of range
if (sqrt((info(j,2)-info(i,2))^2+(info(j,3)-info(i,3))^2) <= tranRange)
neighbor2(i, 1) = neighbor2(i, 1) + 1;
neighbor2(i, neighbor2(i, 1) + 1) = j;
end
continue;
else
k = k + 1;
neighbor(i, k) = j;
end
end
info(i, 5) = k;
end
if drawFigure >= 3
% Draw other links
for i = 1 : maxn
if info(i, 5) > 0
nt = neighbor(i, 1:info(i, 5));
nt = setdiff(nt, tneighbor(i, 1: info(i, 4) + 1));
t1 = length(nt);
if t1 > 0
for j = 1 : t1
k = nt(j);
if i < k
line([info(i, 2), info(k, 2)], [info(i, 3), info(k, 3)], 'Color', 'k', 'LineStyle', ':', 'LineWidth', 0.5);
end
end
end
end
end
end
% Draw logical ZigBee topology
% ZigBee network topology generator
% Draw the logical tree
% Parameters
tmaxX = 100;
tmaxY = 100;
tystep = (tmaxY - 10) / Lm; % y step between two levels
txstep = zeros(1+Lm, 1); % x step at each level
tx = zeros(maxn, 1) - 1;
ty = zeros(maxn, 1) - 1;
txstep(1) = tmaxX - 10;
for i = 1 : Lm
txstep(i + 1) = txstep(i) / Cm;
end
tx(1) = tmaxX / 2;
ty(1) = 5;
for i = 2 : maxn
if tx(i) <= 0
parent = tneighbor(i, 1);
if tx(parent) <= 0
continue;
else
[level, child] = zblevel(Cm, Lm, info(i, 1));
tx(i) = tx(parent) - txstep(level-1+1) / 2 + txstep(level+1) / 2 + (child-1) * txstep(level+1);
ty(i) = 5 + tystep * level;
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
tx(k) = tx(i) - txstep(level+1) / 2 + txstep(level+1+1) / 2 + (j-1) * txstep (level+1+1);
ty(k) = 5 + tystep * (level + 1);
end
end
end
end
end % for
ty = tmaxY - ty;
if drawFigure >= 1
% Draw nodes
% Figure
figure(2);
axis equal
hold on;
set(gca,'Box','on');
plot(tx, ty, 'ko', 'MarkerSize', 5);
plot(tx(1), ty(1), 'k*');
title('Logical network topology');
xlabel('X');
ylabel('Y');
axis([0, tmaxX, 0, tmaxY]);
set(gca, 'XTick', []);
set(gca, 'YTick', []);
end
if drawFigure >= 2
% Draw on-tree links
for i = 1 : maxn
if info(i, 4) > 0
for j = 1 : info(i, 4)
k = tneighbor(i, j + 1);
line([tx(i), tx(k)], [ty(i), ty(k)], 'Color', 'k', 'LineStyle', '-', 'LineWidth', 1.5);
end
end
end
% pause;
end
if drawFigure >= 3
% Draw other links
for i = 1 : maxn
if info(i, 5) > 0
nt = neighbor(i, 1:info(i, 5));
nt = setdiff(nt, tneighbor(i, 1: info(i, 4) + 1));
t1 = length(nt);
if t1 > 0
for j = 1 : t1
k = nt(j);
if i < k
line([tx(i), tx(k)], [ty(i), ty(k)], 'Color', 'k', 'LineStyle', ':', 'LineWidth', 0.5);
end
end
end
end
end
end
% Parameters for broadcast algorithms
drawzb = 1; % used for zbbroadcast.m
useu = 1; % use 'u' for selection?
useFu = 1; % use 'F(u)' for selection?
useLQI = 1;
% approach = 4; approach2 = 1;
approach = 1; approach2 = 1;
% approach = 1; approach2 = 2;
% approach = 2; approach2 = 4;
% ZigBee broadcast
if useLQI == 1
ps=100; % sent power
afa=2; % path loss exponential
k1=1;
k2=10;
gama=1; % threshold to compare LQI and LQI0
cigma = 5; % standard deviation of lognormal shadowing
lasttime=zeros(maxn, 1);
kscale = 1/500;
end
% Timer parameters
etimer=zeros(maxn, 1);
etimercount = 1; % used when approach2 == 3, no timer case, not included in this code
etimerscale = 1; % maximum random time out
% Self-pruning parameters:
tocover=[];
todegree=[];
if approach2 == 2
tocover = tneighbor;
todegree = info(: , 4)' + 1;
elseif approach2 == 4 | approach2 == 1
tocover = neighbor;
todegree = info(: , 5)';
end
% Internal parameters
whilesign = 1;
toforward=[];
t1=0;
t2=0;
F = [];
NF = [];
% Output parameters
forward=zeros(maxn, maxNeighbor+3);
% 1: status (0: initial; 1: non forward; 2: forward; 3: already forward)
% 2: if status > 0, who asked me to non-forward or forward
% 3: number of forward nodes
% 4-: my forward nodes
% numSend = 0;
numReceive = 0;
numInitial = 0;
numNonforward = 0;
numAlreadyforward = 0;
numForwardoverhead = 0;
lmine = [];
lgreedy = [];
% Draw source
if drawzb == 1
% Physical topology
figure(3);
axis equal
hold on;
set(gca,'Box','on');
plot(info(s, 2), info(s, 3),'k.', 'MarkerSize', 25);
title('Broadcast on ZigBee physical network topology');
xlabel('X');
ylabel('Y');
axis([0, maxX, 0, maxY]);
set(gca, 'XTick', [0; maxX]);
set(gca, 'YTick', [maxY]);
% Logical topology: tree
figure(5);
axis equal
hold on;
set(gca,'Box','on');
plot(tx(s), ty(s),'k.', 'MarkerSize', 25);
title('Broadcast on ZigBee logical network topology');
axis([0, tmaxX, 0, tmaxY]);
set(gca, 'XTick', []);
set(gca, 'YTick', []);
end
% Global greedy selection, no source needed
if approach == 4
% F = [];
ggS = [];
ggS = zeros(maxn, 3);
% 1: index
% 2: network ID
% 3: degree
ggS(:, 1)=[1:maxn]';
for j = 1: size(ggS, 1)
ggS(j, 2) = info(ggS(j, 1), 1);
end
ggC = [];
ggC = [1:maxn]';
while(length(ggC)>0)
for j = 1: size(ggS, 1)
u=ggS(j, 1);
tn1 = [u, neighbor(u, 1:info(u, 5))]';
ggS(j, 3) = maxNeighbor + 1 - length(intersect(tn1, ggC));
end
ggS = sortrows(ggS, [3, 2]);
u = ggS(1, 1); % the highest degree with the lowest network ID
% info(u, 5) + 1 - ggS(1, 3)
tn1 = [u, neighbor(u, 1:info(u, 5))]';
ggS = ggS(2:size(ggS, 1), :);
ggC = setdiff(ggC, tn1);
if length(intersect(F, u)) > 0
disp('********Global greedy: a forward node already chosen');
end
% F = union(F, u); % sorted
F = [F, u];
forward(u, 1) = 3;
end
if drawzb == 1
for i = 1:length(F)
if F(i) ~= s
figure(3);
plot(info(F(i), 2), info(F(i), 3), 'k.', 'MarkerSize', 25); % o', 'MarkerSize', 3, 'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'k');
figure(5);
plot(tx(F(i)), ty(F(i)), 'k.', 'MarkerSize', 25); % o', 'MarkerSize', 3, 'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'k');
end
for j = 1:info(F(i), 5)
if forward(neighbor(F(i), j), 1) > 0
continue;
end
forward(neighbor(F(i), j), 1) = 1;
figure(3);
line([info(F(i), 2), info(neighbor(F(i), j), 2)], [info(F(i), 3), info(neighbor(F(i), j), 3)], 'Color', 'k');
plot(info(neighbor(F(i), j), 2), info(neighbor(F(i), j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(F(i)), tx(neighbor(F(i), j))], [ty(F(i)), ty(neighbor(F(i), j))], 'Color', 'k');
plot(tx(neighbor(F(i), j)), ty(neighbor(F(i), j)), 'ko', 'MarkerSize', 3);
end
end
end
% Result
numAlreadyforward = length(F);
numInitial = size(find(forward(:, 1)==0), 1);
numNonforward = size(find(forward(:, 1)==1), 1);
for i = 1:length(F)
etimer(F(i)) = rand;
end
timeDelay = max(etimer);
numAlreadyforward
timeDelay
return
end
% Other localized broadcast algorithms
forward(s, 1) = 2; % source is the first to forward
etimer(s) = 1;
etimercount = etimercount + 1;
while(whilesign)
toforward = find(etimer > 0);
t1=length(toforward);
if t1 <= 0
break;
end
t2 = inf;
for i0 = 1 : t1
i = toforward(i0);
if etimer(i) < t2
t2 = etimer(i);
end
end
% 0 < t2 < inf, t2 is the minimum positive time
toforward = find(etimer==t2); % toforward has at least 1 node
etimer = etimer - t2;
for i0 = 1 : length(toforward)
i = toforward(i0);
% Determine forwarding nodes F
F = [];
NF = [];
if approach2 == 1
% ZigBee: every tree neighbor will rebroadcast, but self-prune if all neighbors are covered
F = tneighbor(i, 1 : info(i, 4) + 1);
NF = setdiff(neighbor(i, 1 : info(i, 5)), F);
elseif approach2 == 2
% OSR: every neighbor will rebroadcast, but self-prune if all tree neighbors are covered
F = neighbor(i, 1:info(i, 5));
NF = [];
else % Forward node selection
% OOS, step 1, find S and C
C = [];
% C = TN(i)
C = tneighbor(i, 1: info(i, 4) + 1);
% C = TN(N(i))
if info(i, 5) > 0
S = neighbor(i, 1: info(i, 5));
for j = 1 : info(i, 5)
if tneighbor(S(j), 1) > 0 | info(S(j), 4) > 0
C = union(C, tneighbor(S(j), 1:info(S(j), 4)+1));
end
end
else
S = [];
end
% C is already sorted, remove first ids that < 0.
t1=find(C < 0);
t2=length(t1);
if t2 > 0
if t2 < length(C)
C = C(t2+1 : length(C));
else
C = [];
end
end
% C = TN(N(i)) - N(i)
C = setdiff(C, [i , S]);
if useu == 1
% S -= TN(u), C -= TN2(u)
u = forward(i, 2);
if u > 0 % u is valid
tn1u = [u , tneighbor(u, 1: info(u, 4) + 1)];
S = setdiff(S, tn1u);
for j = 1: length(tn1u)
if tn1u(j) <= 0 | info(tn1u(j), 1) < 0
continue;
end
C = setdiff(C, [tn1u(j) , tneighbor(tn1u(j), 1: info(tn1u(j), 4) + 1)]);
end
end
end
if useu == 1 & useFu == 1 & u > 0 & forward(u, 3) > 1 % F(u)-i is valid
% S -= F(u), C -= TN(F(u))
Fu = setdiff(forward(u, 4: 4+forward(u, 3)-1), i);
S = setdiff(S, Fu);
for j = 1: forward(u, 3)-1
tn1f = [Fu(j) , tneighbor(Fu(j), 1: info(Fu(j), 4) + 1)];
C = setdiff(C, tn1f);
end
end
if length(S) <= 0 | length(C) <=0
forward(i, 1) = 3; % still need to forward, but no selected forward nodes
if info(i, 5) > 0 % must be true: at least have a parent, except root
NF = neighbor(i, 1: info(i, 5));
for j = 1 : info(i, 5)
numReceive = numReceive + 1;
if forward(NF(j), 1) <= 0
forward(NF(j), 1) = 1; % non-forward
forward(NF(j), 2) = i;
if drawzb == 1
figure(3);
plot(info(NF(j), 2), info(NF(j), 3), 'k.');
line([info(i, 2), info(NF(j), 2)], [info(i, 3), info(NF(j), 3)], 'color', 'k');
figure(5);
plot(tx(NF(j)), ty(NF(j)), 'k.');
line([tx(i), tx(NF(j))], [ty(i), ty(NF(j))], 'color', 'k');
end
end
end
end
end
% OOS, Step 2, construct the trees
forest = [];
forest = zeros(length(C), 4);
% 1: index
% 2: network ID
% 3: level
% 4: status: 0: not processed, 1: processed
forest(:, 1)=C'; % S*C should be empty
for j = 1: size(forest, 1)
forest(j, 2) = info(forest(j, 1), 1);
forest(j, 3) = Lm - info(forest(j, 1), 6);
end
forest = sortrows(forest, [3, 2]);
% OOS, Step 3, select forward nodes
F = [];
for j = 1:size(forest, 1)
if forest(j, 4) > 0
continue;
end
t1 = forest(j, 1);
t2 = tneighbor(t1, 1); % parent of t1
if t2 > 0 & length(find(S==t2)) > 0
if length(intersect(F, t2)) > 0
disp('*********My approach: a forward node already chosen');
end
F = union(F , t2);
% F = [F, t2];
t3 = tneighbor(t2, 1); % parent of t2
if t3 > 0
t4 = find(forest(:, 1)==t3);
if length(t4) > 0 % at most 1 item in t4
% length(t4)
forest(t4(1), 4) = 1;
end
end
k = j + 1;
while(k <= size(forest, 1))
if tneighbor(forest(k, 1), 1) ~= t2
break;
end
forest(k, 4) = 1; % processed
k = k + 1;
end
else
t3 = intersect(tneighbor(t1, 2:(info(t1, 4)+1)), S);
if length(intersect(F, t3)) > 0
disp('*********My approach: a forward node already chosen');
end
F = union(F, t3(1));
% F = [F, t3(1)];
end
forest(j, 4) = 1;
end
NF = [];
NF = setdiff(neighbor(i, 1 : info(i, 5)), F);
end
% Forwarding
forward(i, 1) = 3; % already forward
if drawzb == 1 & i ~= s
figure(3);
plot(info(i, 2), info(i, 3), 'k.', 'MarkerSize', 25);
figure(5);
plot(tx(i), ty(i), 'k.', 'MarkerSize', 25);
end
t1 = length(F);
if t1 > 0
forward(i, 4: 4 + t1 - 1) = F;
forward(i, 3) = t1;
for j = 1 : t1
if F(j) <= 0
continue;
end
numReceive = numReceive + 1;
if forward(F(j), 1) == 1 | forward(F(j), 1) == 3
continue;
end
% Self-pruning
tt = [];
tt = tocover(F(j), 1:todegree(F(j)));
tt = setdiff(tt, [i, tneighbor(i, 1:info(i, 4)+1)]);
todegree(F(j)) = length(tt);
if todegree(F(j)) <= 0 % self-pruning
forward(F(j), 1) = 1;
if drawzb == 1
figure(3);
line([info(i, 2), info(F(j), 2)], [info(i, 3), info(F(j), 3)], 'Color', 'k');
plot(info(F(j), 2), info(F(j), 3), 'k.');
figure(5);
line([tx(i), tx(F(j))], [ty(i), ty(F(j))], 'Color', 'k');
plot(tx(F(j)), ty(F(j)), 'k.');
end
etimer(F(j)) = 0;
if approach2 == 4
disp('This forward node is self-pruned and does not need to forward');
end
continue;
end
tocover(F(j), 1:todegree(F(j))) = tt;
if forward(F(j), 1) == 0
% Update status
forward(F(j), 2) = i;
forward(F(j), 1) = 2;
% Add timer for a candidate forward node
if useLQI == 0
% Random waiting time
etimer(F(j)) = rand * etimerscale;
end
if drawzb == 1
figure(3);
line([info(i, 2), info(F(j), 2)], [info(i, 3), info(F(j), 3)], 'Color', 'k');
plot(info(F(j), 2), info(F(j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(i), tx(F(j))], [ty(i), ty(F(j))], 'Color', 'k');
plot(tx(F(j)), ty(F(j)), 'ko', 'MarkerSize', 3);
end
end
if useLQI == 1
lqi0 = ps-afa*10*log10(sqrt((info(i, 2)-info(F(j), 2))^2 + (info(i, 3)-info(F(j), 3))^2));
% lqi0
lqi = lqi0-cigma*randn;
% lqi
if lqi>=(lqi0-gama)
time1 = k2 * lqi0 / todegree(F(j));
else
time1 = k1*(lqi0-lqi) + k2*lqi0 / todegree(F(j));
% time2 = time1;
end
time1 = time1 * kscale;
if forward(F(j), 1) == 0
etimer(F(j)) = time1;
lasttime(F(j)) = time1;
else
forward(F(j), 2) = i;
etimer(F(j)) = time1 - (lasttime(F(j)) - etimer(F(j))); % t > 0
if etimer(F(j)) <= 0
% disp('new timer less than 0');
etimer(F(j)) = 0.001 * rand;
end
lasttime(F(j)) = etimer(F(j));
end
end
end
end
t1 = length(NF);
if t1 > 0
for j = 1 : t1
numReceive = numReceive + 1;
if approach2 ~= 1 % on-tree flooding receive it and drop it
if forward(NF(j), 1) == 0
forward(NF(j), 1) = 1; % non-forward
forward(NF(j), 2) = i;
if drawzb == 1
figure(3);
line([info(i, 2), info(NF(j), 2)], [info(i, 3), info(NF(j), 3)], 'Color', 'k');
plot(info(NF(j), 2), info(NF(j), 3), 'ko', 'MarkerSize', 3);
figure(5);
line([tx(i), tx(NF(j))], [ty(i), ty(NF(j))], 'Color', 'k');
plot(tx(NF(j)), ty(NF(j)), 'ko', 'MarkerSize', 3);
end
elseif forward(NF(j), 1) == 2
% Self-pruning
tt = [];
tt = tocover(NF(j), 1:todegree(NF(j)));
tt = setdiff(tt, [i, tneighbor(i, 1:info(i, 4)+1)]);
todegree(NF(j)) = length(tt);
if todegree(NF(j)) <= 0 % self-pruning
forward(NF(j), 1) = 1;
% if drawzb == 1
% figure(3);
% plot(info(NF(j), 2), info(NF(j), 3), 'k.');
% figure(5);
% plot(tx(NF(j)), ty(NF(j)), 'k.');
% end
etimer(NF(j)) = 0;
% disp('This forward node does not need to forward');
continue;
end
tocover(NF(j), 1:todegree(NF(j))) = tt;
end
end
end
end
% fishish a forward
end % for
end % while
% Output results
numInitial = size(find(forward(:, 1)==0), 1); % should be zero if network is connected
numNonforward = size(find(forward(:, 1)==1), 1);
numAlreadyforward = size(find(forward(:, 1)==3), 1);
timeDelay = -etimer(s); % = -min(etimer) - 1;
numForwardoverhead = 0;
for i = 1:maxn
if forward(i, 1) ~= 3
continue;
end
numForwardoverhead = numForwardoverhead + forward(i, 3);
% numReceive = numReceive + info(i, 5);
end
numAlreadyforward
numNonforward
numReceive
timeDelay
%>>>>>>>>>>>>>>PROGRAM 2>>>>>>>>>>>>>>>>>>>>>>>>>>
%>>>>>>>>>>>>>>PROGRAM 2>>>>>>>>>>>>>>>>>>>>>>>>>>
%.............................BUT THIS PROGRAM WILL SHOW ERROR WITHOUT THESE %TWO FUNCTION FILE SO FIRSTLY SAVE THESE FUNCTION IN DIFFERENT %EDITOR AND THEN RUN ABOVE %PROGRAM..................................................................................>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%............FUNCTION FOR CSKIP.......
function cskip = cskip(Cm, Lm, i)
% cskip: return the cskip of level i
% cskip of level i means the total number of ids a node at level i has,
% inlucding the node itself
cskip = (Cm^(Lm-i+1)-1)/(Cm-1);
return
%>>>>>>>>>>>>>>PROGRAM 3>>>>>>>>>>>>>>>>>>>>>>>>>>
%>>>>>>>>>>>>>>PROGRAM 3>>>>>>>>>>>>>>>>>>>>>>>>>>
function [level, child] = zblevel(Cm, Lm, id)
% return the level of id in the ZigBee tree, and it is the 'child'th child of its parent
if id == 0
level = 0;
child = 1;
return
end
i=1;
while(mod(id-1, cskip(Cm, Lm, i)))
id=mod(id-1, cskip(Cm, Lm, i));
i=i+1;
end
level = i;
child = floor((id-1)/cskip(Cm, Lm, i)) + 1;
return
%>>>>>>>>>>>>>>END>>>>>>>>>>>>>>>>>>>>>>>>>>
Contact:
Mr. Roshan P. Helonde
Mobile: +91-7276355704
WhatsApp: +91-7276355704
Email: roshanphelonde@rediffmail.com