Merge branch 'master' of https://github.com/szmoore/MCTX3420.git
[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         //TODO: Surely we'll need to do something here?
52         // Maybe move the binary file into long term file storage?
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         if (s->id >= pow(10, FILENAMESIZE))
68         {
69                 Fatal("Too many sensors! FILENAMESIZE is %d; increase it and recompile.", FILENAMESIZE);
70         }
71         sprintf(s->filename, "%d", s->id);
72         unlink(s->filename); //TODO: Move old files somewhere
73
74         Log(LOGDEBUG, "Initialised sensor %d; binary file is \"%s\"", id, s->filename);
75 }
76
77
78 /**
79  * Run the main sensor polling loop
80  * @param arg - Cast to Sensor* - Sensor that the thread will handle
81  * @returns NULL (void* required to use the function with pthreads)
82  */
83 void * Sensor_Main(void * arg)
84 {
85         Sensor * s = (Sensor*)(arg);
86
87         while (true) //TODO: Exit condition
88         {
89                 // The sensor will write data to a buffer until it is full
90                 // Then it will open a file and dump the buffer to the end of it.
91                 // Rinse and repeat
92
93                 // The reason I've added the buffer is because locks are expensive
94                 // But maybe it's better to just write data straight to the file
95                 // I'd like to do some tests by changing SENSOR_DATABUFSIZ
96
97                 while (s->write_index < SENSOR_DATABUFSIZ)
98                 {
99                         s->buffer[s->write_index] = GetData(s->id);
100                         s->write_index += 1;
101                 }
102
103                 //Log(LOGDEBUG, "Filled buffer");
104
105                 // CRITICAL SECTION (no threads should be able to read/write the file at the same time)
106                 pthread_mutex_lock(&(s->mutex));
107
108                         // Open binary file in append mode and dump buffer into it
109                         FILE * file = fopen(s->filename, "ab");
110                         if (file == NULL)
111                         {
112                                 Fatal("Couldn't open file \"%s\" mode ab - %s", s->filename, strerror(errno));
113                         }
114                         int amount_written = fwrite(s->buffer, sizeof(DataPoint), SENSOR_DATABUFSIZ, 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
120                         Log(LOGDEBUG, "Wrote %d data points for sensor %d", amount_written, s->id);
121
122                         fclose(file);
123
124                 pthread_mutex_unlock(&(s->mutex));
125                 // End of critical section
126
127                 s->write_index = 0; // reset position in buffer
128                 
129         }
130         return NULL;
131 }
132
133

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