]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_unix/unix_fna.c
Unified header for FNA
[frescor/fna.git] / src_unix / unix_fna.c
1 //----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2009 by the FRESCOR consortium:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politecnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org
17 //
18 //        The FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 // This file is part of FNA (Frescor Network Adaptation)
32 //
33 // FNA is free software; you can redistribute it and/or modify it
34 // under terms of the GNU General Public License as published by the
35 // Free Software Foundation; either version 2, or (at your option) any
36 // later version.  FNA is distributed in the hope that it will be
37 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 // General Public License for more details. You should have received a
40 // copy of the GNU General Public License along with FNA; see file
41 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
42 // Cambridge, MA 02139, USA.
43 //
44 // As a special exception, including FNA header files in a file,
45 // instantiating FNA generics or templates, or linking other files
46 // with FNA objects to produce an executable application, does not
47 // by itself cause the resulting executable application to be covered
48 // by the GNU General Public License. This exception does not
49 // however invalidate any other reasons why the executable file might be
50 // covered by the GNU Public License.
51 // -----------------------------------------------------------------------
52
53 //==============================================
54 //  ******** ****     **     **
55 //  **///// /**/**   /**    ****
56 //  **      /**//**  /**   **//**
57 //  ******* /** //** /**  **  //**
58 //  **////  /**  //**/** **********
59 //  **      /**   //****/**//////**
60 //  **      /**    //***/**     /**
61 //  /       //      /// //      //
62 //
63 // FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
64 //==============================================================
65
66 /**
67  * unix fna implementation
68  *
69  * In the following functions we implement a DUMMY FNA implementation without
70  * contracts or real-time requirements just for testing purposes. We provide
71  * send/receive capabilities between Linux processes through UNIX domain
72  * datagram sockets.
73  *
74  * The goal is to run FRSH on several processes by using the Linux_lib arch
75  * of MaRTE OS or Partikle to simulate a distributed system in a single PC.
76  *
77  * The main tricks of the implementation are the following:
78  *
79  *   - We encode the address and stream in the Unix socket path as:
80  *                    '/tmp/unix_fna-address-stream'
81  *   - At initialization we create MX_UNIX_STREAM_IDS sockets for our address
82  *     (our address number is defined by FRSH_CPU_ID_DEFAULT)
83  *   - When the user SENDS we obtain the address creating the mentioned string
84  *     from the destination address and the stream.
85  *   - When the user RECEIVES we use the appropiate socket by using the
86  *     stream_id information.
87  *
88  **/
89
90 #include <malloc.h>   /* for malloc and free */
91 #include <assert.h>
92 #include <string.h>   /* for string functions: strtok, strcpy, ... */
93
94 #include "frsh_distributed_types.h" /* for frsh_network_address_t, frsh_stream_id_t */
95 #include "unix_fna.h" /* function prototypes */
96
97 #include <sys/socket.h>
98 #include <sys/un.h>
99
100 /* DEBUGGING FLAGS and MACROS */
101 #include <stdio.h>
102 #define DEBUG(enable,x,args...) if(enable) printf("\t>> Called %s: " x, __func__ , ##args)
103 #define DBG_UNIX_FNA_NOT_IMPLEMENTED true
104
105 /**
106  * to_unix_path()
107  *
108  **/
109
110 static int to_unix_path(const frsh_network_address_t addr,
111                         const frsh_stream_id_t       stream,
112                         char                         *str,
113                         size_t                       mx_size)
114 {
115         return snprintf(str, mx_size, "/tmp/unix_fna-%d-%d", addr, stream);
116 }
117
118 /**
119  * to_addr_stream()
120  *
121  **/
122
123 static int to_addr_stream(frsh_network_address_t *addr,
124                           frsh_stream_id_t       *stream,
125                           char                   *str,
126                           size_t                 size)
127 {
128         char *token;
129         char *search = "-";
130
131         token = strtok(str, search);
132         token = strtok(NULL, search);
133         *addr = atoi(token);
134         token = strtok(NULL, search);
135         *stream = atoi(token);
136
137         return 0;
138 }
139
140 //////////////////////////////////////////////////////////////////////
141 //           INITIALIZATION
142 //////////////////////////////////////////////////////////////////////
143
144 int the_unix_sockets[MX_UNIX_STREAM_IDS];
145
146 /**
147  * unix_fna_init()
148  *
149  * for each stream_id create a socket and bind it to the address obtained
150  * from "/tmp/unix_fna-addr-stream"
151  *
152  **/
153
154 int unix_fna_init(const frsh_resource_id_t resource_id)
155 {
156         int i, err;
157         struct sockaddr_un sock_addr;
158
159         DEBUG(true, "creating unix sockets\n");
160
161         for(i=0; i<MX_UNIX_STREAM_IDS; i++) {
162                 the_unix_sockets[i] = socket(AF_UNIX, SOCK_DGRAM, 0);
163                 assert(the_unix_sockets[i] >= 0);
164
165                 memset(&sock_addr, 0, sizeof(sock_addr));
166                 sock_addr.sun_family = AF_UNIX;
167                 err = to_unix_path(FRSH_CPU_ID_DEFAULT,
168                                    (frsh_stream_id_t) i,
169                                    sock_addr.sun_path,
170                                    sizeof(sock_addr.sun_path));
171                 assert(err >= 0);
172
173                 err = bind(the_unix_sockets[i],
174                            (struct sockaddr *)&sock_addr,
175                            sizeof(sock_addr));
176                 assert(err >= 0);
177         }
178
179         return 0;
180 }
181
182 ///////////////////////////////////////////////////////////////////
183 //           VIRTUAL RESOURCES
184 ///////////////////////////////////////////////////////////////////
185
186 /**
187  * unix_fna_contract_negotiate()
188  *
189  **/
190
191 int unix_fna_contract_negotiate(const frsh_resource_id_t resource_id,
192                                 const frsh_contract_t *contract,
193                                 fna_vres_id_t *vres)
194 {
195         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
196         return 0;
197 }
198
199 /**
200  * unix_fna_contract_renegotiate_sync()
201  *
202  **/
203
204 int unix_fna_contract_renegotiate_sync(const frsh_resource_id_t resource_id,
205                                        const fna_vres_id_t vres,
206                                        const frsh_contract_t *new_contract)
207 {
208         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
209         return 0;
210 }
211
212 /**
213  * unix_fna_contract_renegotiate_async()
214  *
215  **/
216
217 int unix_fna_contract_renegotiate_async(const frsh_resource_id_t resource_id,
218                                         const fna_vres_id_t vres,
219                                         const frsh_contract_t *new_contract,
220                                         frsh_signal_t signal_to_notify,
221                                         frsh_signal_info_t signal_info)
222 {
223         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
224         return 0;
225 }
226
227 /**
228  * unix_fna_vres_get_renegotiation_status()
229  *
230  **/
231
232 int unix_fna_vres_get_renegotiation_status(const frsh_resource_id_t resource_id,
233                                            const fna_vres_id_t vres,
234                                            frsh_renegotiation_status_t *renegotiation_status)
235 {
236         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
237         return 0;
238 }
239
240 /**
241  * unix_fna_vres_destroy()
242  *
243  **/
244
245 int unix_fna_vres_destroy(const frsh_resource_id_t resource_id,
246                           const fna_vres_id_t vres)
247 {
248         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
249         return 0;
250 }
251
252 /**
253  * unix_fna_vres_get_contract()
254  *
255  **/
256
257 int unix_fna_vres_get_contract(const frsh_resource_id_t resource_id,
258                                const fna_vres_id_t vres,
259                                frsh_contract_t *contract)
260 {
261         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
262         return 0;
263 }
264
265 /**
266  * unix_fna_vres_get_usage()
267  *
268  **/
269
270 int unix_fna_vres_get_usage(const frsh_resource_id_t resource_id,
271                             const fna_vres_id_t vres,
272                             struct timespec *usage)
273 {
274         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
275         return 0;
276 }
277
278 /**
279  * unix_fna_vres_get_remaining_budget()
280  *
281  **/
282
283 int unix_fna_vres_get_remaining_budget(const frsh_resource_id_t resource_id,
284                                        const fna_vres_id_t vres,
285                                        struct timespec *remaining_budget)
286 {
287         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
288         return 0;
289 }
290
291 /**
292  * unix_fna_vres_get_budget_and_period()
293  *
294  **/
295
296 int unix_fna_vres_get_budget_and_period(const frsh_resource_id_t resource_id,
297                                         const fna_vres_id_t vres,
298                                         struct timespec *budget,
299                                         struct timespec *period)
300 {
301         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
302         return 0;
303 }
304
305 ///////////////////////////////////////////////////////////////////
306 //           SPARE CAPACITY FUNCIONS
307 ///////////////////////////////////////////////////////////////////
308
309 /**
310  * unix_fna_resource_get_capacity()
311  *
312  **/
313
314 int unix_fna_resource_get_capacity(const frsh_resource_id_t resource_id,
315                                    const int importance,
316                                    uint32_t *capacity)
317 {
318         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
319         return 0;
320 }
321
322 /**
323  * unix_fna_resource_get_total_weight()
324  *
325  **/
326
327 int unix_fna_resource_get_total_weight(const frsh_resource_id_t resource_id,
328                                        const int importance,
329                                        int *total_weight)
330 {
331         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
332         return 0;
333 }
334
335 /**
336  * unix_fna_vres_decrease_capacity()
337  *
338  **/
339
340 int unix_fna_vres_decrease_capacity(const frsh_resource_id_t resource_id,
341                                     const fna_vres_id_t vres,
342                                     const struct timespec new_budget,
343                                     const struct timespec new_period)
344 {
345         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
346         return 0;
347 }
348
349 ///////////////////////////////////////////////////////////////////
350 //           SEND RECEIVE OPERATIONS
351 ///////////////////////////////////////////////////////////////////
352
353 /**
354  * unix_fna_send_sync()
355  *
356  **/
357
358 int unix_fna_send_sync(const fna_endpoint_data_t *endpoint,
359                        const void *msg,
360                        const size_t size)
361 {
362         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
363         return 0;
364 }
365
366 /**
367  * unix_fna_send_async()
368  *
369  * To send we use one of our sockets (it doesn't matter which one so we use
370  * the first one). The destination is obtained from the endpoint values for
371  * dest and stream.
372  *
373  **/
374
375 int unix_fna_send_async(const fna_endpoint_data_t *endpoint,
376                         const void *msg,
377                         const size_t size)
378 {
379         int err;
380         struct sockaddr_un to;
381         ssize_t sent_bytes;
382
383         DEBUG(true, "send async\n");
384
385         assert(endpoint->is_bound);
386
387         memset(&to, 0, sizeof(to));
388         to.sun_family = AF_UNIX;
389
390         err = to_unix_path(endpoint->destination,
391                            endpoint->stream_id,
392                            to.sun_path,
393                            sizeof(to.sun_path));
394         assert(err >= 0);
395
396         sent_bytes = sendto(the_unix_sockets[0],
397                             msg,
398                             size,
399                             0,
400                             (struct sockaddr *) &to,
401                             sizeof(to));
402         assert(sent_bytes >= 0);
403
404         return 0;
405 }
406
407 /**
408  * unix_fna_receive_sync()
409  *
410  * We call recvfrom using the socket associated to the corresponding stream_id.
411  * The "from" address is obtained by parsing the unix address path.
412  *
413  **/
414
415 int unix_fna_receive_sync(const fna_endpoint_data_t *endpoint,
416                           void *buffer,
417                           const size_t buffer_size,
418                           size_t *received_bytes,
419                           frsh_network_address_t *from)
420 {
421         int err;
422         struct sockaddr_un sender_addr;
423         ssize_t recv_bytes;
424         socklen_t from_len;
425         frsh_network_address_t addr;
426         frsh_stream_id_t       stream;
427
428         DEBUG(true, "receive sync\n");
429
430         from_len = sizeof(sender_addr);
431         recv_bytes = recvfrom(the_unix_sockets[endpoint->stream_id],
432                               buffer,
433                               buffer_size,
434                               0,
435                               (struct sockaddr *)&sender_addr,
436                               &from_len);
437
438         assert(recv_bytes >= 0);
439         *received_bytes = recv_bytes;
440
441         err = to_addr_stream(&addr,
442                              &stream,
443                              sender_addr.sun_path,
444                              sizeof(sender_addr.sun_path));
445         assert(err == 0);
446         *from = addr;
447
448         return 0;
449 }
450
451 /**
452  * unix_fna_receive_async()
453  *
454  **/
455
456 int unix_fna_receive_async(const fna_endpoint_data_t *endpoint,
457                            void *buffer,
458                            const size_t buffer_size,
459                            size_t *received_bytes,
460                            frsh_network_address_t *from)
461 {
462         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
463         return 0;
464 }
465
466 /**
467  * unix_fna_send_endpoint_get_status()
468  *
469  **/
470
471 int unix_fna_send_endpoint_get_status(const fna_endpoint_data_t *endpoint,
472                                       int *number_of_pending_messages,
473                                       frsh_endpoint_network_status_t *network_status,
474                                       frsh_protocol_status_t *protocol_status)
475 {
476         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
477         return 0;
478 }
479
480 /**
481  * unix_fna_receive_endpoint_created()
482  *
483  **/
484 int unix_fna_receive_endpoint_created(fna_endpoint_data_t *endpoint)
485 {
486         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
487         return 0;
488 }
489
490 /**
491  * unix_fna_receive_endpoint_get_pending_messages
492  *
493  **/
494
495 int unix_fna_receive_endpoint_get_status(const fna_endpoint_data_t *endpoint,
496                                          int *number_of_pending_messages,
497                                          frsh_endpoint_network_status_t *network_status,
498                                          frsh_protocol_status_t *protocol_status)
499 {
500         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
501         return 0;
502 }
503
504 //////////////////////////////////////////////////////////////////////
505 //           NETWORK CONFIGURATION FUNCTIONS
506 //////////////////////////////////////////////////////////////////////
507
508 /**
509  * unix_fna_network_get_max_message_size()
510  *
511  **/
512
513 int unix_fna_network_get_max_message_size(const frsh_resource_id_t resource_id,
514                                           const frsh_network_address_t destination,
515                                           size_t *max_size)
516 {
517         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
518         return 0;
519 }
520
521 /**
522  * unix_fna_network_bytes_to_budget()
523  *
524  **/
525
526 int unix_fna_network_bytes_to_budget(const frsh_resource_id_t resource_id,
527                                      const size_t nbytes,
528                                      struct timespec *budget)
529 {
530         DEBUG(true, "let's put 1 microsecond for all\n");
531         budget->tv_sec  = 0;
532         budget->tv_nsec = 1000;
533         return 0;
534 }
535
536 /**
537  * unix_fna_network_budget_to_bytes()
538  *
539  **/
540
541 int unix_fna_network_budget_to_bytes(const frsh_resource_id_t resource_id,
542                                      const struct timespec *budget,
543                                      size_t *nbytes)
544 {
545         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
546         return 0;
547 }
548
549 /**
550  * unix_fna_network_get_min_eff_budget()
551  *
552  **/
553
554 int unix_fna_network_get_min_eff_budget(const frsh_resource_id_t resource_id,
555                                         struct timespec *budget)
556 {
557         DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
558         return 0;
559 }
560
561 // GLOBAL variable to install the network protocol in FRESCOR
562
563 fna_operations_t unix_fna_operations = {
564         .fna_init = unix_fna_init,
565         .fna_contract_negotiate = unix_fna_contract_negotiate,
566         .fna_contract_renegotiate_sync = unix_fna_contract_renegotiate_sync,
567         .fna_contract_renegotiate_async = unix_fna_contract_renegotiate_async,
568         .fna_vres_get_renegotiation_status = unix_fna_vres_get_renegotiation_status,
569         .fna_vres_destroy = unix_fna_vres_destroy,
570         .fna_vres_get_contract = unix_fna_vres_get_contract,
571         .fna_vres_get_usage = unix_fna_vres_get_usage,
572         .fna_vres_get_remaining_budget = unix_fna_vres_get_remaining_budget,
573         .fna_vres_get_budget_and_period = unix_fna_vres_get_budget_and_period,
574         .fna_resource_get_capacity = unix_fna_resource_get_capacity,
575         .fna_resource_get_total_weight = unix_fna_resource_get_total_weight,
576         .fna_vres_decrease_capacity = unix_fna_vres_decrease_capacity,
577         .fna_send_sync = unix_fna_send_sync,
578         .fna_send_async = unix_fna_send_async,
579         .fna_receive_sync = unix_fna_receive_sync,
580         .fna_receive_async = unix_fna_receive_async,
581         .fna_send_endpoint_get_status = unix_fna_send_endpoint_get_status,
582         .fna_receive_endpoint_created = unix_fna_receive_endpoint_created,
583         .fna_receive_endpoint_get_status = unix_fna_receive_endpoint_get_status,
584         .fna_network_get_max_message_size = unix_fna_network_get_max_message_size,
585         .fna_network_bytes_to_budget = unix_fna_network_bytes_to_budget,
586         .fna_network_budget_to_bytes = unix_fna_network_budget_to_bytes,
587         .fna_network_get_min_eff_budget = unix_fna_network_get_min_eff_budget
588 };