Merge pull request #15 from jtanx/master
[matches/MCTX3420.git] / server / sensor.c
1 /**
2  * @file sensor.c
3  * @purpose Implementation of sensor thread
4  * TODO: Finalise implementation
5  */
6
7
8
9 #include "sensor.h"
10 #include "log.h"
11 #include <math.h>
12
13 /**
14  * Read a data value from a sensor; block until value is read
15  * @param sensor_id - The ID of the sensor
16  * @returns The current value of the sensor
17  */
18 DataPoint GetData(int sensor_id)
19 {
20         // switch based on the sensor_id at the moment for testing;
21         // might be able to just directly access ADC from sensor_id?
22         //TODO: Implement for real sensors
23
24         DataPoint d;
25         //TODO: Deal with time stamps properly
26         static int count = 0;
27         d.time = count++;
28         switch (sensor_id)
29         {
30                 case SENSOR_TEST0:
31                         d.value = count;
32                         break;
33                 case SENSOR_TEST1:
34                         d.value = (float)(rand() % 100) / 100;
35                         break;
36                 default:
37                         Fatal("Unknown sensor id: %d", sensor_id);
38                         break;
39         }       
40         usleep(100000); // simulate delay in sensor polling
41         return d;
42 }
43
44
45 /**
46  * Destroy a sensor
47  * @param s - Sensor to destroy
48  */
49 void Destroy(Sensor * s)
50 {
51         // Maybe move the binary file into long term file storage?
52         fclose(s->file);
53 }
54
55
56
57 /**
58  * Initialise a sensor
59  * @param s - Sensor to initialise
60  */
61 void Sensor_Init(Sensor * s, int id)
62 {
63         s->write_index = 0;
64         s->read_offset = 0;
65         s->id = id;
66
67         #define FILENAMESIZE 4
68         char filename[FILENAMESIZE];
69         if (s->id >= pow(10, FILENAMESIZE))
70         {
71                 Fatal("Too many sensors! FILENAMESIZE is %d; increase it and recompile.", FILENAMESIZE);
72         }
73
74         pthread_mutex_init(&(s->mutex), NULL);
75                 
76         sprintf(filename, "%d", s->id);
77         unlink(filename); //TODO: Move old files somewhere
78
79         s->file = fopen(filename, "a+b"); // open binary file
80         Log(LOGDEBUG, "Initialised sensor %d; binary file is \"%s\"", id, filename);
81 }
82
83
84 /**
85  * Run the main sensor polling loop
86  * @param arg - Cast to Sensor* - Sensor that the thread will handle
87  * @returns NULL (void* required to use the function with pthreads)
88  */
89 void * Sensor_Main(void * arg)
90 {
91         Sensor * s = (Sensor*)(arg);
92
93         while (true) //TODO: Exit condition
94         {
95                 // The sensor will write data to a buffer until it is full
96                 // Then it will open a file and dump the buffer to the end of it.
97                 // Rinse and repeat
98
99                 // The reason I've added the buffer is because locks are expensive
100                 // But maybe it's better to just write data straight to the file
101                 // I'd like to do some tests by changing SENSOR_DATABUFSIZ
102
103                 while (s->write_index < SENSOR_DATABUFSIZ)
104                 {
105                         s->buffer[s->write_index] = GetData(s->id);
106                         s->write_index += 1;
107                 }
108
109                 //Log(LOGDEBUG, "Filled buffer");
110
111                 // CRITICAL SECTION (no threads should be able to read/write the file at the same time)
112                 pthread_mutex_lock(&(s->mutex));
113                         fseek(s->file, 0, SEEK_END);
114                         int amount_written = fwrite(s->buffer, sizeof(DataPoint), SENSOR_DATABUFSIZ, s->file);
115                         if (amount_written != SENSOR_DATABUFSIZ)
116                         {
117                                 Fatal("Wrote %d data points and expected to write %d to \"%s\" - %s", amount_written, SENSOR_DATABUFSIZ, strerror(errno));
118                         }
119                         Log(LOGDEBUG, "Wrote %d data points for sensor %d", amount_written, s->id);
120                 pthread_mutex_unlock(&(s->mutex));
121                 // End of critical section
122
123                 s->write_index = 0; // reset position in buffer
124                 
125         }
126         return NULL;
127 }
128
129

UCC git Repository :: git.ucc.asn.au