Statistics
| Revision:

root / logic / trunk / src / startup / main.c @ 60

History | View | Annotate | Download (8.4 KB)

1
/*
2
 * main.c
3
 *
4
 * 2011, Aleksander Besir (alex.besir@gmail.com)
5
 *
6
 */
7

    
8
#include "../hci_comm/hci_comm.h"
9
#include "../init/scenariolist.h"
10
#include "../init/devicelist.h"
11
#include "../logics/device_threads.h"
12
//#include "../logics/scenario_threads.h"
13
#include <stdio.h>
14
#include <pthread.h>
15
#include <syslog.h>
16
#include "../hci_comm/hciChanged.h"
17

    
18
// Inter-thread shared variables
19
// TODO: These variables could be configuration variables
20
//       (eg: static boolean loggingEnabled)
21
static device           *hDevice;   //device list
22
static scenario         *hScenario; //scenario list
23
static thread_id_holder *hThrIDhold_dev;//holds IDs of running threads (devices)
24
static thread_id_holder *hThrIDhold_scn;//holds IDs of running threads (scenarios)
25
//extern scenario *test;   //device list
26

    
27
// Crtitical section mutual exclusion security
28
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
29
pthread_t       decisionMakingThread;
30
pthread_t       hciConnectionThread;
31

    
32
// Global variable to check, if HCI made any changes that need
33
// to be updated by the logic.
34
// Changing this variable's value must be done using the
35
// mutex mtx declared before.
36
// To change variables value you should do this:
37
//    pthread_mutex_lock(&mtx);
38
//    hciChanged = 0;
39
//    pthread_mutex_unlock(&mtx);
40
// The meaning of hciChanged possible values is in hci_comm/hciChanged.h.
41
// HCI should always reset hciChanged value to HCI_CHANGED_RESET after
42
// checking it's value.
43
// To use mtx and hciChanged variables in other .c files, write
44
//    extern int hciChanged;
45
//    extern pthread_mutex_t mtx;
46
// on top of the class.
47

    
48
int hciChanged = HCI_CHANGED_RESET;
49

    
50
void *decisionMakingThread_routine(void *dummy);
51
void *hciConnectionThread_routine(void *dummy);
52
void *randomValThread_routine(void *dummy);
53
void *scenarioThread_routine(void *dummy);
54
int  reinitialiseLogic(); // on HCI request
55

    
56
// Application entry point
57
int main(int argc, char *argv[]) {
58

    
59
    /* initialisation */
60
    hDevice   = setDeviceList();
61
    hScenario = setNewScenarioList(hDevice);
62

    
63
    printf("Devices present:\t%d\n",   getNumberOfDevices());
64
    printf("Scenarios present:\t%d\n", getNumberOfScenarios());
65

    
66
    /* regular work */
67
    //*
68
        pthread_create(&hciConnectionThread, NULL,hciConnectionThread_routine, NULL);
69
        pthread_create(&decisionMakingThread,NULL,decisionMakingThread_routine,NULL);
70

    
71
        pthread_join(hciConnectionThread,NULL);
72
        //pthread_join(decisionMakingThread,NULL);
73
    /**/
74
        exit(0);
75
}
76

    
77
// Decision-making thread routine
78
// Should just call a function that implements decision making module of the logic
79
void *decisionMakingThread_routine(void *dummy) {
80
    printf("-- decisionMakingThread_routine started --\n");
81

    
82
    /**dummy threads for input devices (sensors)**/
83
    hThrIDhold_dev = NULL;
84
    thread_id_holder *t_holder, *t_holder_old; //just for list of IDs creation, for both scenarios and devices
85
    t_holder_old = NULL;
86

    
87
    int i;
88
    for(i=0; i<getNumberOfDevices(); i++)
89
    {
90
        t_holder = (thread_id_holder *)malloc(sizeof(thread_id_holder));
91
        pthread_create(&t_holder->pthr_idx,NULL,randomValThread_routine,NULL);
92

    
93
        t_holder->nxt=NULL;
94
        if(t_holder_old!=NULL)
95
            t_holder_old->nxt=t_holder;
96
        t_holder_old=t_holder;
97

    
98
        if(hThrIDhold_dev==NULL)
99
            hThrIDhold_dev=t_holder_old;
100
    }
101

    
102
    /**start scenario threads**/
103
    t_holder_old = NULL;
104
    hThrIDhold_scn=NULL;
105

    
106
    for(i=0; i<getNumberOfScenarios(); i++)
107
    {
108
        t_holder = (thread_id_holder *)malloc(sizeof(thread_id_holder));
109
        pthread_create(&t_holder->pthr_idx,NULL,scenarioThread_routine,NULL);
110

    
111
        t_holder->nxt=NULL;
112
        if(t_holder_old!=NULL)
113
            t_holder_old->nxt=t_holder;
114
        t_holder_old=t_holder;
115

    
116
        if(hThrIDhold_scn==NULL)
117
            hThrIDhold_scn=t_holder_old;
118
    }
119

    
120
    /*start some sort of control over scenarios? - hmm morda ne...bom jutri :)*/
121
    printf("Exiting main thread\n");
122
        pthread_exit(0);
123
}
124

    
125
// HCI connection thread routine
126
// Start listening to some port
127
void *hciConnectionThread_routine(void *dummy) {
128
    printf("hciConnectionThread_routine started\n");
129
        int hciErrorCode = listenTo(1100);
130

    
131
        pthread_exit(0);
132
}
133

    
134
// scenario thread routine
135
void *scenarioThread_routine(void *dummy)
136
{
137
    scenario *scen;
138
    device   *inDev;
139
    int      active = 0;
140
    float    scenarioBuffer;
141
    //printf("My scen ID> %ld\n",pthread_self());
142

    
143
    /*load scenario*/
144
    scen = getAvailableScenario(hScenario);
145
    if(!scen) pthread_exit(0);
146

    
147
    // TODO add pointer to this device (all of them actually) to scenario structure - problems with segfault
148
    //indev = scen->inDev;
149
    inDev = getDevice(hDevice, scen->inDevice_id);
150
    scen->buf=inDev->buf;
151
    printf("Scenario %s buffer updated to %.2f!\n", scen->scen_id, inDev->buf);
152
    //set its value
153
    //*
154
    while(1) //TODO signal == true
155
    {
156
        /// main scenario loop
157
        //printf("inDev->buf %.2f\n", 1.0f*inDev->buf);
158
        if(active)
159
            sleep(scen->actvChkItv);
160
        else
161
            sleep(scen->idleChkItv);
162
        //checking primary condition
163
        if(scen->buf) // is not null
164
        {
165
            scen->buf = scen->buf*scen->alpha+inDev->buf*(1-scen->alpha);
166
            //printf("Scenario %s buffer updated to %f, alpha: %.2f!\n", scen->scen_id, scenarioBuffer, scen->alpha);
167
            syslog(LOG_MAIL, "%s:%.2f", scen->inDevice_id, scen->buf);
168
            active = 1;
169

    
170
            if((scen->buf > scen->optval + scen->tolval) ||
171
               (scen->buf < scen->optval - scen->tolval))
172
            {
173
                if(evaluateAdditionalConditions(scen->cond_l, hDevice))
174
                {
175
                    // TODO syslog - "action:scen_ID:power_percentage"
176
                    int power = getPowerPercentage(scen->minval, scen->maxval, scen->optval, &scen->buf, scen->func);
177
                    syslog(LOG_MAIL, "%s:%s:%.2f", scen->action, scen->scen_id, power);
178
                    printf("Zaganjam napravo %s z mocjo %d\n", scen->scen_id, power);
179
                    /*TODO execute action with parameter(s)*/
180
                }
181
                else
182
                    printf("Scenario %s not updated!\n", scen->scen_id);
183
            }
184
            else
185
                active = 0;
186
        }
187
        /*
188
        if(active)
189
            printf("%s main buffer %.2f, sleeping %d\n",scen->scen_id, scen->buf, scen->actvChkItv);
190
        else
191
            printf("%s main buffer %.2f, sleeping %d\n",scen->scen_id, scen->buf, scen->idleChkItv);
192
        /**/
193
    }
194
    /**/
195
           pthread_exit(0);
196
}
197

    
198
void *randomValThread_routine(void *dummy)
199
{
200
    //get device
201
    device *dev;
202
    dev = getAvailableDevice(hDevice);
203
    if(dev){}
204
    else
205
        pthread_exit(0);
206
    //set its value
207
    while(1) //TODO signal == true
208
    {
209
        dev->buf=random(100)%10+20;// random 20-30
210
        //printf("device %s buf = %d\n", dev->id, dev->buf);
211
        sleep(dev->readitv);
212
    }
213
           pthread_exit(0);
214
}
215

    
216
void freeDeviceList(device *dev)
217
{
218
    if(dev->nxt!=NULL)
219
        freeDeviceList(dev->nxt);
220
    free(dev);
221
}
222

    
223
void freeScenarioList(scenario *scn)
224
{
225
    if(scn->nxt!=NULL)
226
        freeScenarioList(scn->nxt);
227
    free(scn);
228
}
229

    
230
void freeThreadIDList(thread_id_holder *tih)
231
{
232
    if(tih->nxt!=NULL)
233
        freeThreadIDList(tih->nxt);
234
    free(tih);
235
}
236

    
237
int reinitialiseLogic()
238
{
239
    thread_id_holder *hold;
240
    hold = hThrIDhold_dev;
241
    //hThrIDhold_dev = NULL;
242

    
243
    //kill device threads
244
    printf("Attempting to cancel threads!\n");
245
    while(hold)
246
    {
247
        printf("Cancelling dev thread %ld with return state %d\n", hold->pthr_idx,pthread_cancel(hold->pthr_idx));
248
        //TODO free thread_id_holder list too!
249
        hold=hold->nxt;
250
    }
251

    
252
    //kill scenario threads
253
    hold = hThrIDhold_scn;
254
    //hThrIDhold_scn = NULL;
255
    while(hold)
256
    {
257
        printf("Cancelling scn thread %ld with return state %d\n", hold->pthr_idx,pthread_cancel(hold->pthr_idx));
258
        //TODO free thread_id_holder list too!
259
        hold=hold->nxt;
260
    }
261

    
262
    //free memory
263
    printf("Freeing memory!\n");
264
    freeDeviceList(hDevice);
265
    freeScenarioList(hScenario);
266
    freeThreadIDList(hThrIDhold_dev);
267
    freeThreadIDList(hThrIDhold_scn);
268

    
269
    //reinit devices
270
    printf("Reinitializing devices!\n");
271
    hDevice   = setDeviceList();
272

    
273
    //reinit scenarios
274
    printf("Reinitializing scenarios!\n");
275
    hScenario = setNewScenarioList(hDevice);
276

    
277
    //restart main thread
278
    printf("Restarting main thread!\n");
279
        pthread_create(&decisionMakingThread,NULL,decisionMakingThread_routine,NULL);
280

    
281
        return 1; //sucess, TODO add fail conditions
282
}