1 //----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 by the FRESCOR consortium:
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
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org
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
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // This file is part of FNA (Frescor Network Adaptation)
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.
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 // -----------------------------------------------------------------------
53 //==============================================
54 // ******** **** ** **
55 // **///// /**/** /** ****
56 // ** /**//** /** **//**
57 // ******* /** //** /** ** //**
58 // **//// /** //**/** **********
59 // ** /** //****/**//////**
60 // ** /** //***/** /**
63 // FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
64 //==============================================================
67 * unix fna implementation
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
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.
77 * The main tricks of the implementation are the following:
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.
90 #include <malloc.h> /* for malloc and free */
92 #include <string.h> /* for string functions: strtok, strcpy, ... */
94 #include "frsh_distributed_types.h" /* for frsh_network_address_t, frsh_stream_id_t */
95 #include "unix_fna.h" /* function prototypes */
97 #include <sys/socket.h>
100 /* DEBUGGING FLAGS and MACROS */
102 #define DEBUG(enable,x,args...) if(enable) printf("\t>> Called %s: " x, __func__ , ##args)
103 #define DBG_UNIX_FNA_NOT_IMPLEMENTED true
110 static int to_unix_path(const frsh_network_address_t addr,
111 const frsh_stream_id_t stream,
115 return snprintf(str, mx_size, "/tmp/unix_fna-%d-%d", addr, stream);
123 static int to_addr_stream(frsh_network_address_t *addr,
124 frsh_stream_id_t *stream,
131 token = strtok(str, search);
132 token = strtok(NULL, search);
134 token = strtok(NULL, search);
135 *stream = atoi(token);
140 //////////////////////////////////////////////////////////////////////
142 //////////////////////////////////////////////////////////////////////
144 int the_unix_sockets[MX_UNIX_STREAM_IDS];
149 * for each stream_id create a socket and bind it to the address obtained
150 * from "/tmp/unix_fna-addr-stream"
154 int unix_fna_init(const frsh_resource_id_t resource_id)
157 struct sockaddr_un sock_addr;
159 DEBUG(true, "creating unix sockets\n");
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);
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,
170 sizeof(sock_addr.sun_path));
173 err = bind(the_unix_sockets[i],
174 (struct sockaddr *)&sock_addr,
182 ///////////////////////////////////////////////////////////////////
184 ///////////////////////////////////////////////////////////////////
187 * unix_fna_contract_negotiate()
191 int unix_fna_contract_negotiate(const frsh_resource_id_t resource_id,
192 const frsh_contract_t *contract,
195 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
200 * unix_fna_contract_renegotiate_sync()
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)
208 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
213 * unix_fna_contract_renegotiate_async()
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)
223 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
228 * unix_fna_vres_get_renegotiation_status()
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)
236 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
241 * unix_fna_vres_destroy()
245 int unix_fna_vres_destroy(const frsh_resource_id_t resource_id,
246 const fna_vres_id_t vres)
248 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
253 * unix_fna_vres_get_contract()
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)
261 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
266 * unix_fna_vres_get_usage()
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)
274 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
279 * unix_fna_vres_get_remaining_budget()
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)
287 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
292 * unix_fna_vres_get_budget_and_period()
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)
301 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
305 ///////////////////////////////////////////////////////////////////
306 // SPARE CAPACITY FUNCIONS
307 ///////////////////////////////////////////////////////////////////
310 * unix_fna_resource_get_capacity()
314 int unix_fna_resource_get_capacity(const frsh_resource_id_t resource_id,
315 const int importance,
318 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
323 * unix_fna_resource_get_total_weight()
327 int unix_fna_resource_get_total_weight(const frsh_resource_id_t resource_id,
328 const int importance,
331 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
336 * unix_fna_vres_decrease_capacity()
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)
345 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
349 ///////////////////////////////////////////////////////////////////
350 // SEND RECEIVE OPERATIONS
351 ///////////////////////////////////////////////////////////////////
354 * unix_fna_send_sync()
358 int unix_fna_send_sync(const fna_endpoint_data_t *endpoint,
362 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
367 * unix_fna_send_async()
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
375 int unix_fna_send_async(const fna_endpoint_data_t *endpoint,
380 struct sockaddr_un to;
383 DEBUG(true, "send async\n");
385 assert(endpoint->is_bound);
387 memset(&to, 0, sizeof(to));
388 to.sun_family = AF_UNIX;
390 err = to_unix_path(endpoint->destination,
393 sizeof(to.sun_path));
396 sent_bytes = sendto(the_unix_sockets[0],
400 (struct sockaddr *) &to,
402 assert(sent_bytes >= 0);
408 * unix_fna_receive_sync()
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.
415 int unix_fna_receive_sync(const fna_endpoint_data_t *endpoint,
417 const size_t buffer_size,
418 size_t *received_bytes,
419 frsh_network_address_t *from)
422 struct sockaddr_un sender_addr;
425 frsh_network_address_t addr;
426 frsh_stream_id_t stream;
428 DEBUG(true, "receive sync\n");
430 from_len = sizeof(sender_addr);
431 recv_bytes = recvfrom(the_unix_sockets[endpoint->stream_id],
435 (struct sockaddr *)&sender_addr,
438 assert(recv_bytes >= 0);
439 *received_bytes = recv_bytes;
441 err = to_addr_stream(&addr,
443 sender_addr.sun_path,
444 sizeof(sender_addr.sun_path));
452 * unix_fna_receive_async()
456 int unix_fna_receive_async(const fna_endpoint_data_t *endpoint,
458 const size_t buffer_size,
459 size_t *received_bytes,
460 frsh_network_address_t *from)
462 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
467 * unix_fna_send_endpoint_get_status()
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)
476 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
481 * unix_fna_receive_endpoint_created()
484 int unix_fna_receive_endpoint_created(fna_endpoint_data_t *endpoint)
486 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
491 * unix_fna_receive_endpoint_get_pending_messages
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)
500 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
504 //////////////////////////////////////////////////////////////////////
505 // NETWORK CONFIGURATION FUNCTIONS
506 //////////////////////////////////////////////////////////////////////
509 * unix_fna_network_get_max_message_size()
513 int unix_fna_network_get_max_message_size(const frsh_resource_id_t resource_id,
514 const frsh_network_address_t destination,
517 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
522 * unix_fna_network_bytes_to_budget()
526 int unix_fna_network_bytes_to_budget(const frsh_resource_id_t resource_id,
528 struct timespec *budget)
530 DEBUG(true, "let's put 1 microsecond for all\n");
532 budget->tv_nsec = 1000;
537 * unix_fna_network_budget_to_bytes()
541 int unix_fna_network_budget_to_bytes(const frsh_resource_id_t resource_id,
542 const struct timespec *budget,
545 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
550 * unix_fna_network_get_min_eff_budget()
554 int unix_fna_network_get_min_eff_budget(const frsh_resource_id_t resource_id,
555 struct timespec *budget)
557 DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
561 // GLOBAL variable to install the network protocol in FRESCOR
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