Statistics
| Revision:

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

History | View | Annotate | Download (6.74 KB)

1 10 Janez1
/*
2
 * main.c
3
 *
4
 * 2011, Aleksander Besir (alex.besir@gmail.com)
5
 *
6
 */
7
8
#include "../hci_comm/hci_comm.h"
9 37 Janez1
#include "../init/scenariolist.h"
10
#include "../init/devicelist.h"
11 40 Janez1
//#include "../logics/device_threads.h"
12
//#include "../logics/scenario_threads.h"
13 10 Janez1
#include <stdio.h>
14
#include <pthread.h>
15 44 Janez1
#include <syslog.h>
16 57 alexbesir
#include "../hci_comm/hciChanged.h"
17 10 Janez1
18
// Inter-thread shared variables
19
// TODO: These variables could be configuration variables
20
//       (eg: static boolean loggingEnabled)
21 40 Janez1
static device   *hDevice;   //device list
22
static scenario *hScenario; //scenario list
23 10 Janez1
24 40 Janez1
//extern scenario *test;   //device list
25
26 10 Janez1
// Crtitical section mutual exclusion security
27 57 alexbesir
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
28 10 Janez1
29 57 alexbesir
// Global variable to check, if HCI made any changes that need
30
// to be updated by the logic.
31
// Changing this variable's value must be done using the
32
// mutex mtx declared before.
33
// To change variables value you should do this:
34
//    pthread_mutex_lock(&mtx);
35
//    hciChanged = 0;
36
//    pthread_mutex_unlock(&mtx);
37
// The meaning of hciChanged possible values is in hci_comm/hciChanged.h.
38
// HCI should always reset hciChanged value to HCI_CHANGED_RESET after
39
// checking it's value.
40
// To use mtx and hciChanged variables in other .c files, write
41
//    extern int hciChanged;
42
//    extern pthread_mutex_t mtx;
43
// on top of the class.
44
45
int hciChanged = HCI_CHANGED_RESET;
46
47 10 Janez1
void *decisionMakingThread_routine(void *dummy);
48
void *hciConnectionThread_routine(void *dummy);
49 40 Janez1
void *randomValThread_routine(void *dummy);
50
void *scenarioThread_routine(void *dummy);
51 10 Janez1
52
// Application entry point
53
int main(int argc, char *argv[]) {
54
55 31 Janez1
    /* initialisation */
56 37 Janez1
    hDevice   = setDeviceList();
57 44 Janez1
    hScenario = setNewScenarioList(hDevice);
58 31 Janez1
59 37 Janez1
    printf("Devices present:\t%d\n",   getNumberOfDevices());
60
    printf("Scenarios present:\t%d\n", getNumberOfScenarios());
61
62 31 Janez1
    /* regular work */
63 21 Janez1
    //*
64 10 Janez1
        pthread_t hciConnectionThread;
65
        pthread_t decisionMakingThread;
66
67 37 Janez1
        pthread_t *decisionMakingThread2;
68
69
        pthread_create(&hciConnectionThread, NULL,hciConnectionThread_routine, NULL);
70 10 Janez1
        pthread_create(&decisionMakingThread,NULL,decisionMakingThread_routine,NULL);
71
72
        pthread_join(hciConnectionThread,NULL);
73
        pthread_join(decisionMakingThread,NULL);
74 21 Janez1
    /**/
75 10 Janez1
        exit(0);
76
}
77
78
// Decision-making thread routine
79
// Should just call a function that implements decision making module of the logic
80
void *decisionMakingThread_routine(void *dummy) {
81 40 Janez1
    printf("-- decisionMakingThread_routine started --\n");
82 10 Janez1
83 37 Janez1
    /**dummy threads for input devices (sensors)**/
84
    // TODO check for possible BUG involving declaring pthread_t as pointer!
85
    pthread_t *deviceThread, *deviceThreadHead;
86
    deviceThreadHead = NULL;
87 10 Janez1
88 37 Janez1
    int i;
89
    for(i=0; i<getNumberOfDevices(); i++)
90
    {
91
        deviceThread = (pthread_t *)malloc(sizeof(pthread_t));
92
        pthread_create(&deviceThread,NULL,randomValThread_routine,NULL);
93
94
        if(deviceThreadHead==NULL)
95
            deviceThreadHead=deviceThread;
96
    }
97
98
    /**start scenario threads**/
99
    pthread_t *scenarioThread, *scenarioThreadHead;
100
    scenarioThreadHead = NULL;
101
102
    for(i=0; i<getNumberOfScenarios(); i++)
103
    {
104
        scenarioThread = (pthread_t *)malloc(sizeof(pthread_t));
105
        pthread_create(&scenarioThread,NULL,scenarioThread_routine,NULL);
106
107
        if(scenarioThreadHead==NULL)
108
            scenarioThreadHead=scenarioThread;
109
    }
110
111
    /**wait for threads to finish**/
112
    // TODO bad position of both for loops below, joining of theese threads should be handled in a different way
113
    deviceThread = deviceThreadHead;
114
    for(i=0; i<getNumberOfDevices(); i++)
115
    {
116
        pthread_join(deviceThread,NULL);
117
        deviceThread++;
118
    }
119
120
    scenarioThread = scenarioThreadHead;
121
    for(i=0; i<getNumberOfScenarios(); i++)
122
    {
123
        pthread_join(scenarioThread,NULL);
124
        scenarioThread++;
125
    }
126
127
    /*start some sort of control over scenarios? - hmm morda ne...bom jutri :)*/
128
129 10 Janez1
        pthread_exit(0);
130
}
131
132
// HCI connection thread routine
133
// Start listening to some port
134
void *hciConnectionThread_routine(void *dummy) {
135 37 Janez1
    printf("hciConnectionThread_routine started\n");
136 10 Janez1
        int hciErrorCode = listenTo(1100);
137
138
        pthread_exit(0);
139 37 Janez1
}
140 10 Janez1
141 40 Janez1
// scenario thread routine
142 37 Janez1
void *scenarioThread_routine(void *dummy)
143
{
144
    scenario *scen;
145 40 Janez1
    device   *inDev;
146
    int      active = 0;
147 44 Janez1
    float    scenarioBuffer;
148
149 40 Janez1
    /*load scenario*/
150 37 Janez1
    scen = getAvailableScenario(hScenario);
151
    if(!scen) pthread_exit(0);
152
153 40 Janez1
    // TODO add pointer to this device (all of them actually) to scenario structure - problems with segfault
154 44 Janez1
    //indev = scen->inDev;
155 40 Janez1
    inDev = getDevice(hDevice, scen->inDevice_id);
156 44 Janez1
    scen->buf=inDev->buf;
157
    printf("Scenario %s buffer updated to %.2f!\n", scen->scen_id, inDev->buf);
158 37 Janez1
    //set its value
159 40 Janez1
    //*
160 37 Janez1
    while(1) //TODO signal == true
161
    {
162 40 Janez1
        /// main scenario loop
163
        //printf("inDev->buf %.2f\n", 1.0f*inDev->buf);
164
        if(active)
165
            sleep(scen->actvChkItv);
166
        else
167
            sleep(scen->idleChkItv);
168
        //checking primary condition
169 44 Janez1
        if(scen->buf) // is not null
170 40 Janez1
        {
171 44 Janez1
            scen->buf = scen->buf*scen->alpha+inDev->buf*(1-scen->alpha);
172
            //printf("Scenario %s buffer updated to %f, alpha: %.2f!\n", scen->scen_id, scenarioBuffer, scen->alpha);
173
            syslog(LOG_MAIL, "%s:%.2f", scen->inDevice_id, scen->buf);
174 40 Janez1
            active = 1;
175
176 44 Janez1
            if((scen->buf > scen->optval + scen->tolval) ||
177
               (scen->buf < scen->optval - scen->tolval))
178 40 Janez1
            {
179
                if(evaluateAdditionalConditions(scen->cond_l, hDevice))
180 41 Janez1
                {
181 44 Janez1
                    // TODO syslog - "action:scen_ID:power_percentage"
182
                    int power = getPowerPercentage(scen->minval, scen->maxval, scen->optval, &scen->buf, scen->func);
183
                    syslog(LOG_MAIL, "%s:%s:%.2f", scen->action, scen->scen_id, power);
184
                    printf("Zaganjam napravo %s z mocjo %d\n", scen->scen_id, power);
185 40 Janez1
                    /*TODO execute action with parameter(s)*/
186 41 Janez1
                }
187 40 Janez1
                else
188
                    printf("Scenario %s not updated!\n", scen->scen_id);
189
            }
190
            else
191
                active = 0;
192
        }
193 44 Janez1
        /*
194 40 Janez1
        if(active)
195 44 Janez1
            printf("%s main buffer %.2f, sleeping %d\n",scen->scen_id, scen->buf, scen->actvChkItv);
196 40 Janez1
        else
197 44 Janez1
            printf("%s main buffer %.2f, sleeping %d\n",scen->scen_id, scen->buf, scen->idleChkItv);
198
        /**/
199 37 Janez1
    }
200 40 Janez1
    /**/
201 37 Janez1
           pthread_exit(0);
202 10 Janez1
}
203 37 Janez1
204
void *randomValThread_routine(void *dummy)
205
{
206
    //get device
207
    device *dev;
208
    dev = getAvailableDevice(hDevice);
209
    if(dev){}
210
    else
211
        pthread_exit(0);
212
    //set its value
213
    while(1) //TODO signal == true
214
    {
215
        dev->buf=random(100)%10+20;// random 20-30
216 40 Janez1
        //printf("device %s buf = %d\n", dev->id, dev->buf);
217 37 Janez1
        sleep(dev->readitv);
218
    }
219
           pthread_exit(0);
220
}