1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Sampo Saaristo
5 : * Contact e-mail: DG.MIN-Support@nokia.com
6 : *
7 : * This program is free software: you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation, version 2 of the License.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details. You should have received a copy of the GNU General Public
15 : * License along with this program. If not, see
16 : * <http://www.gnu.org/licenses/>.
17 : */
18 :
19 :
20 : /**
21 : * @file min_test_event_if.c
22 : * @version 0.1
23 : * @brief This file contains implementation of Event System for
24 : * Test Process
25 : */
26 :
27 : /* ------------------------------------------------------------------------- */
28 : /* INCLUDE FILES */
29 : #include <signal.h>
30 : #include <errno.h>
31 : #include <tmc.h>
32 : #include <tmc_ipc.h>
33 : #include <min_logger.h>
34 : #include <min_test_event_if.h>
35 :
36 : /* ------------------------------------------------------------------------- */
37 : /* EXTERNAL DATA STRUCTURES */
38 : /* None */
39 :
40 : /* ------------------------------------------------------------------------- */
41 : /* EXTERNAL FUNCTION PROTOTYPES */
42 : /* None */
43 :
44 : /* ------------------------------------------------------------------------- */
45 : /* CONSTANTS */
46 : /* None */
47 :
48 : /* ------------------------------------------------------------------------- */
49 : /* MACROS */
50 :
51 : /* ------------------------------------------------------------------------- */
52 : /* LOCAL CONSTANTS AND MACROS */
53 : /* None */
54 :
55 : /* ------------------------------------------------------------------------- */
56 : /* MODULE DATA STRUCTURES */
57 : static int mqid = -1;
58 :
59 : /* ------------------------------------------------------------------------- */
60 : /* LOCAL FUNCTION PROTOTYPES */
61 :
62 : /** Check that the event paramter seems valid.
63 : * @param e event to be validate
64 : * @return 0 if the event is valid, 1 if not
65 : */
66 : LOCAL int validate_event (minEventIf * e);
67 : /** Sends event request towards the engine.
68 : * @param event the event.
69 : */
70 : LOCAL void send_event (minEventIf * e);
71 :
72 : /** Get the event request type from the event,
73 : * @param e the event
74 : * @returns the event request type
75 : */
76 : inline LOCAL TEventReq_t get_event_req_type (minEventIf * e);
77 :
78 : /** Set the event request type for the event.
79 : * @param e the the event
80 : * @param aReqType the event request type
81 : */
82 : inline LOCAL void set_event_req_type (minEventIf * e, TEventReq_t aReqType);
83 :
84 : /** Get the name from event.
85 : * @param e the event name of which is to be returned
86 : * @returns event name or INITPTR if name is not set for the event
87 : */
88 : inline LOCAL TEventName_t get_event_name (minEventIf * e);
89 :
90 : /** Set the name for the event.
91 : * @param e the event
92 : * @param aName event name
93 : */
94 : inline LOCAL void set_event_name (minEventIf * e, TEventName_t aName);
95 :
96 : /** Get event type from event
97 : * @param e the event
98 : * @returns event type
99 : */
100 : inline LOCAL TEventType_t get_event_type (minEventIf * e);
101 :
102 : /** Set the event type for event.
103 : * @param e the event
104 : * @param aType the event type
105 : */
106 : inline LOCAL void set_event_type (minEventIf * e, TEventType_t aType);
107 :
108 : /** Set request type, name and even type for event.
109 : * @param e the event
110 : * @param aType event requst type
111 : * @param aName event name
112 : * @param aEventType event type
113 : */
114 : LOCAL void set_event_stuff (minEventIf * e, TEventReq_t aType,
115 : TEventName_t aName, TEventType_t aEventType);
116 :
117 :
118 : /* ------------------------------------------------------------------------- */
119 : /* FORWARD DECLARATIONS */
120 : /* None */
121 :
122 : /* ==================== LOCAL FUNCTIONS ==================================== */
123 :
124 : int validate_event (minEventIf * e)
125 7 : {
126 :
127 7 : if (!e || e == INITPTR)
128 : goto invalid_event;
129 :
130 7 : if (e->event_type_ != EIndication && e->event_type_ != EState)
131 0 : goto invalid_event;
132 :
133 7 : if (!e->event_name_ ||
134 : e->event_name_ == INITPTR || strlen (e->event_name_) == 0)
135 : goto invalid_event;
136 :
137 6 : if (e->event_req_type_ < EReqEvent
138 : || e->event_req_type_ > EUnsetEvent)
139 : goto invalid_event;
140 :
141 6 : return 0;
142 1 : invalid_event:
143 1 : return 1;
144 : }
145 :
146 : /* ------------------------------------------------------------------------- */
147 :
148 : LOCAL void send_event (minEventIf * e)
149 5 : {
150 5 : int retval = -1;
151 : MsgBuffer buff;
152 :
153 5 : buff.receiver_ = getppid ();
154 5 : buff.sender_ = getpid ();
155 5 : buff.special_ = getpid ();
156 5 : buff.type_ = MSG_EVENT;
157 5 : buff.param_ = e->event_req_type_ | (e->event_type_ << 8);
158 :
159 5 : STRCPY (buff.message_, e->event_name_, MaxUsrMessage);
160 :
161 5 : if (mqid == -1)
162 3 : mqid = mq_open_queue ('a');
163 5 : if (mqid != -1) {
164 5 : retval = 0;
165 5 : retval = mq_send_message_block (mqid, &buff);
166 : }
167 5 : }
168 :
169 : LOCAL void wait_event (minEventIf * e)
170 0 : {
171 : int retval;
172 : MsgBuffer msg;
173 :
174 0 : again:
175 0 : retval = mq_read_message (mqid, getpid ()
176 : , &msg);
177 0 : if (retval == -1) {
178 0 : switch (errno) {
179 : case EINTR:
180 0 : MIN_WARN ("Reading MQ interrupted by signal");
181 0 : goto again;
182 : return;
183 :
184 : case EIDRM:
185 0 : MIN_FATAL ("MQ id removed from the system");
186 0 : return;
187 :
188 : case E2BIG:
189 0 : MIN_WARN ("Recieved message too big");
190 0 : return;
191 :
192 : case EINVAL:
193 0 : MIN_ERROR ("Invalid value: mq_read_message");
194 0 : return;
195 : }
196 0 : } else if (retval < 8) {
197 : /* ignore too short messages */
198 0 : MIN_WARN ("Recieved message is too small");
199 0 : goto again;
200 : }
201 :
202 0 : if (msg.type_ == MSG_EVENT_IND) {
203 0 : e->event_status_ = msg.param_;
204 : } else {
205 0 : MIN_WARN ("%s: unexpected message type %d", __FUNCTION__,
206 : msg.type_);
207 0 : goto again;
208 : }
209 0 : return;
210 : }
211 :
212 :
213 : inline LOCAL TEventReq_t get_event_req_type (minEventIf * e)
214 1 : {
215 1 : return e->event_req_type_;
216 : }
217 :
218 : inline LOCAL void set_event_req_type (minEventIf * e, TEventReq_t aReqType)
219 7 : {
220 7 : e->event_req_type_ = aReqType;
221 7 : }
222 :
223 : inline LOCAL TEventName_t get_event_name (minEventIf * e)
224 3 : {
225 3 : return e->event_name_;
226 : }
227 :
228 : inline LOCAL void set_event_name (minEventIf * e, TEventName_t aName)
229 5 : {
230 5 : if (e->event_name_ != INITPTR) {
231 0 : DELETE (e->event_name_);
232 0 : e->event_name_ = NULL;
233 : }
234 5 : e->event_name_ = NEW2 (char, strlen (aName) + 1);
235 5 : STRCPY (e->event_name_, aName, strlen (aName) + 1);
236 5 : }
237 :
238 : inline LOCAL TEventType_t get_event_type (minEventIf * e)
239 1 : {
240 1 : return e->event_type_;
241 : }
242 :
243 : inline LOCAL void set_event_type (minEventIf * e, TEventType_t aType)
244 2 : {
245 2 : e->event_type_ = aType;
246 : return;
247 : }
248 :
249 :
250 : LOCAL void set_event_stuff (minEventIf * e, TEventReq_t aType,
251 : TEventName_t aName, TEventType_t aEventType)
252 1 : {
253 1 : set_event_type (e, aEventType);
254 1 : set_event_name (e, aName);
255 1 : set_event_req_type (e, aType);
256 1 : }
257 :
258 : /* ======================== FUNCTIONS ====================================== */
259 :
260 : minEventIf *min_event_create (const TEventName_t aName,
261 : TEventType_t aType)
262 7 : {
263 : minEventIf *event;
264 :
265 7 : event = NEW (minEventIf);
266 7 : event->event_name_ = INITPTR;
267 7 : event->event_status_ = EventStatOK;
268 7 : event->dont_block_ = 0;
269 :
270 7 : if (!aType)
271 4 : event->event_type_ = EIndication;
272 : else
273 3 : event->event_type_ = aType;
274 :
275 7 : if (aName != NULL)
276 3 : set_event_name (event, aName);
277 : else
278 4 : event->event_name_ = INITPTR;
279 :
280 7 : event->event_req_type_ = EEnable;
281 :
282 7 : event->Type = get_event_req_type;
283 7 : event->Name = get_event_name;
284 7 : event->EventType = get_event_type;
285 7 : event->SetType = set_event_req_type;
286 7 : event->SetName = set_event_name;
287 7 : event->SetEventType = set_event_type;
288 7 : event->Set = set_event_stuff;
289 :
290 7 : return event;
291 : }
292 :
293 : /* ------------------------------------------------------------------------- */
294 :
295 : void min_event_destroy (minEventIf * event)
296 6 : {
297 6 : if (event->event_name_ && event->event_name_ != INITPTR)
298 4 : DELETE (event->event_name_);
299 6 : DELETE (event);
300 6 : }
301 :
302 : /* ------------------------------------------------------------------------- */
303 :
304 : void Event (minEventIf * e)
305 5 : {
306 : sigset_t waitset;
307 :
308 : /* 1) see that the event seems ok */
309 5 : if (validate_event (e)) {
310 0 : MIN_WARN ("invalid event\n");
311 0 : return;
312 : }
313 5 : sigemptyset (&waitset);
314 5 : sigaddset (&waitset, SIGUSR1);
315 5 : sigprocmask (SIG_BLOCK, &waitset, NULL);
316 :
317 : /* 2) send the event to engine */
318 5 : send_event (e);
319 :
320 : /* 3) wait for the event */
321 5 : if (!e->dont_block_) /* unless dont_block_ is set (the scripter) */
322 0 : wait_event (e);
323 :
324 5 : return;
325 : }
326 :
327 : /* ------------------------------------------------------------------------- */
328 :
329 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
330 : /* None */
331 :
332 :
333 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
334 : #ifdef MIN_UNIT_TEST
335 : #include "min_test_event_if.tests"
336 : #endif /* MIN_UNIT_TEST */
337 :
338 : /* End of file */
|