-
Notifications
You must be signed in to change notification settings - Fork 0
/
sensor.c
286 lines (236 loc) · 8.32 KB
/
sensor.c
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*
FIT3143 Assignment 2
Members:
29906164 Sulthan De Neiro Raihan Syah Bungin
29458021 Nicholas Yeo Wei Ming
This file contain the program to run the sensor nodes.
*/
/*
*Note .h files describe what the code does, .c files describe how the code works
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/time.h>
#include <mpi.h>
#include <unistd.h>
#include <math.h>
#include "sensor.h"
#include "basestation.h"
int slave(int rank, int size, int sizePack, int n, int m, int threshold, int tolerance, MPI_Comm comm_all, MPI_Comm comm_sensor, int end)
{
// Initiate local communicator
MPI_Comm comm_wsn;
MPI_Status status;
// Initally: left,right,top,bottom
int dir[4];
int dims[2], coord[2], wrap[2];
// Initialize local ranks
int rank_local;
// Initiate variable for creating dimension later
dims[0] = n;
dims[1] = m;
wrap[0] = wrap[1] = 0;
// Create MPI Cart Dimension
MPI_Dims_create(size, 2, dims);
MPI_Cart_create(comm_sensor, 2, dims, wrap, 1, &comm_wsn);
// Allocate local rank for local communicator
MPI_Comm_rank(comm_wsn, &rank_local);
// Coordinates and Rank for local communicator
MPI_Cart_coords(comm_wsn, rank_local, 2, coord);
MPI_Cart_rank(comm_wsn, coord, &rank_local);
// Initiate variables for iteration later
int run = 0;
int notified = 0;
int infinite = 0;
// Initiate variables for holding the value of IP address later
char hostbuffer[256],IPEndbuffer[20];
char *IPbuffer;
struct hostent *host_entry;
int hostname;
// Get the IP address of the current rank and convert the buffer string into string
hostname = gethostname(hostbuffer, sizeof(hostbuffer));
host_entry = gethostbyname(hostbuffer);
IPbuffer = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
strncpy(IPEndbuffer,IPbuffer,20);
// If the end value is -1, then the iteration of the sensor node will be infinite
if(end == -1){
infinite = 1;
}
// The main while loop that will iterate until reach the end value or until it being notified by the base station to stop
while (run < end || infinite == 1)
{
MPI_Barrier(comm_wsn);
//printf(">>> %d %d\n",rank,run);
int flag = 0;
// Check the timing to determine if the sensor nodes should be terminated or not
double delay = 0.1 * CLOCKS_PER_SEC;
delay = ceil(delay);
clock_t start = clock();
clock_t endT = start + delay;
// Check for termination message from the base station
while (clock() < endT && flag == 0){
MPI_Iprobe(n*m, 24, comm_all, &flag, &status);
}
// If there are termination message, terminate the main while loop
if (flag != 0){
MPI_Recv(¬ified, 1, MPI_INT, n*m, 24, comm_all, &status);
if(notified == 2){
printf(">>> %d \n",rank_local);
break;
}
}
// Increment the value
run += 1;
// Initialize variable for counting comparison and holding adjacent values
int match = 0;
int adj[4] = {-1, -1, -1, -1};
int adj_x[4] = {-1, -1, -1, -1};
int adj_y[4] = {-1, -1, -1, -1};
int adj_temperature[4] = {-1, -1, -1, -1};
char adj_ip[4][20];
// Check the top and left of the current node/process
MPI_Cart_shift(comm_wsn, 0, 1, &dir[2], &dir[3]);
MPI_Cart_shift(comm_wsn, 1, 1, &dir[0], &dir[1]);
// Generate random temperature for the current node/process
int temperature = generateRandom(run + rank_local);
int temperatureCompare = -1;
// Send the current process's temperature to adjacent nodes
for (int i = 0; i < 4; i++)
{
if (dir[i] != -1)
{
MPI_Send(&temperature, 1, MPI_INT, dir[i], 23, comm_wsn);
}
}
// Check the bottom and right of the current node/process
MPI_Cart_shift(comm_wsn, 0, -1, &dir[2], &dir[3]);
MPI_Cart_shift(comm_wsn, 1, -1, &dir[0], &dir[1]);
// Receive the temperature from adjacent nodes
for (int i = 0; i < 4; i++)
{
int flagRec = 0;
int termiRec = 0;
double timeRec = MPI_Wtime();
while(flagRec == 0 && termiRec == 0){
MPI_Iprobe(MPI_ANY_SOURCE, 23, comm_wsn, &flagRec, &status);
termiRec = checkEnd(timeRec,2);
}
MPI_Recv(&temperatureCompare, 1, MPI_INT, dir[i], 23, comm_wsn, &status);
// If the temperature is above threshold, under the range of the tolerance and exist
if (temperature > threshold)
{
if (temperatureCompare != -1)
{
if (temperatureCompare >= temperature - tolerance && temperatureCompare <= temperature + tolerance)
{
// Store the values in the allocated arrays
adj[i] = dir[i];
adj_temperature[i] = temperatureCompare;
hostname = gethostname(hostbuffer, sizeof(hostbuffer));
host_entry = gethostbyname(hostbuffer);
IPbuffer = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
strncpy(IPEndbuffer,IPbuffer,20);
strncpy(adj_ip[i],IPEndbuffer,20);
// Increment the match counter, implies that there is adjacent node that fulfill the requirement
match += 1;
}
}
}
// Reset the value for future comparison
temperatureCompare = -1;
// Store the coords of the adjacent nodes inside the allocated array
if (adj[i] != -1)
{
if (i == 0)
{
adj_x[i] = coord[0];
adj_y[i] = coord[1] + 1;
}
else if (i == 1)
{
adj_x[i] = coord[0];
adj_y[i] = coord[1] - 1;
}
else if (i == 2)
{
adj_x[i] = coord[0] + 1;
adj_y[i] = coord[1];
}
else if (i == 3)
{
adj_x[i] = coord[0] - 1;
adj_y[i] = coord[1];
}
}
}
// Initiate variable for MPI_Pack later
int posBase = 0;
char packBase[sizePack];
// If there are 2 or more adjacent nodes with similarity temperature
if (match >= 2)
{
// CGet timestamp for event logging and message sending
time_t timeCheck = time(NULL);
struct tm t = *localtime(&timeCheck);
struct timeval time_send;
gettimeofday(&time_send, NULL);
// Split the time structure into seperate integers for Packing later
int t_year = t.tm_year + 1900;
int t_month = t.tm_mon + 1;
int t_day = t.tm_mday;
int t_day_name = t.tm_wday;
int t_hour = t.tm_hour;
int t_min = t.tm_min;
int t_sec = t.tm_sec;
// Pack all the information
MPI_Pack(&run, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&match, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&temperature, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&rank, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&coord[0], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&coord[1], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&IPEndbuffer, 20, MPI_CHAR, packBase, sizePack, &posBase,comm_all);
for (int j = 0; j < 4; j++)
{
MPI_Pack(&adj_temperature[j], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&adj[j], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&adj_x[j], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&adj_y[j], 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&adj_ip[j], 20, MPI_CHAR, packBase, sizePack, &posBase,comm_all);
}
MPI_Pack(&t_year, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_month, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_day, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_day_name, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_hour, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_min, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&t_sec, 1, MPI_INT, packBase, sizePack, &posBase, comm_all);
MPI_Pack(&time_send.tv_usec, 1, MPI_LONG, packBase, sizePack, &posBase, comm_all);
// Send the message contain the packed information to the base station
MPI_Send(packBase, sizePack, MPI_PACKED, n * m, 23, comm_all);
}
}
// Terminate local communicator
MPI_Comm_free(&comm_wsn);
return 0;
}
int generateRandom(int value)
{
// Get timestamp to increase variety on seed generation for randomization
struct timeval time_val;
gettimeofday(&time_val, NULL);
// Improve randomization based on the input value of the rank and timing
int added = (int) (time_val.tv_usec * 1000000);
srand(value+added);
int valueRandom = rand() % 30;
return valueRandom+70;
}