]> rtime.felk.cvut.cz Git - frescor/fna.git/commitdiff
add group negotiations to frescan and change all the requests and messages to map...
authorsangorrin <sangorrin@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Mon, 17 Nov 2008 17:33:36 +0000 (17:33 +0000)
committersangorrin <sangorrin@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Mon, 17 Nov 2008 17:33:36 +0000 (17:33 +0000)
git-svn-id: http://www.frescor.org/private/svn/frescor/fna/trunk@1398 35b4ef3e-fd22-0410-ab77-dab3279adceb

33 files changed:
src_frescan/Makefile
src_frescan/TODO
src_frescan/frescan.c
src_frescan/frescan.h
src_frescan/frescan_bwres.c
src_frescan/frescan_bwres.h
src_frescan/frescan_bwres_analysis.c
src_frescan/frescan_bwres_analysis.h
src_frescan/frescan_bwres_fna.c
src_frescan/frescan_bwres_messages.c
src_frescan/frescan_bwres_messages.h
src_frescan/frescan_bwres_mode_change.c
src_frescan/frescan_bwres_mode_change.h
src_frescan/frescan_bwres_requests.c
src_frescan/frescan_bwres_requests.h
src_frescan/frescan_bwres_robjs.c
src_frescan/frescan_bwres_robjs.h
src_frescan/frescan_bwres_threads.c
src_frescan/frescan_bwres_threads.h
src_frescan/frescan_config.h
src_frescan/frescan_data.c
src_frescan/frescan_data.h
src_frescan/frescan_debug.h
src_frescan/frescan_hw_buffer.c
src_frescan/frescan_hw_buffer.h
src_frescan/frescan_packets.h
src_frescan/frescan_queues.c
src_frescan/frescan_queues.h
src_frescan/frescan_servers.c
src_frescan/frescan_servers.h
src_frescan/frescan_servers_replenishments.c
src_frescan/frescan_servers_replenishments.h
src_frescan/frescan_types.h [new file with mode: 0644]

index 1af38c0142c30968f064bc98ca2beedba10eba1f..af1fd60a2f94e73b9061a63012aa0128e0859e9a 100644 (file)
@@ -11,8 +11,6 @@ libfrescan:  $(OBJS)
        @exec echo -e "\n>> Building FRESCAN:";
        ld -r -o libfrescan.o *.o
        @mv libfrescan.o $(FNA_PATH)/lib
-#      ar -rc libfrescan.a *.o
-#      @mv libfrescan.a $(FNA_PATH)/lib
        @exec echo ">> [OK]"
 
 %.o: %.c $(SRCS) $(HDRS)
index 3559dcf5caea297a80a018c97af97093908c1cbd..f4fae0b059eddf9ca10a9e8d6339b77deda7fe0c 100644 (file)
@@ -4,4 +4,5 @@
        * CTU corrections
        * fna_vres_id_t will be frsh_vres_index_T
 - integrate with frsh_sa scheduling analysis module and spare capacity
-- oh, i forgot CAN priorities are assigned inversely!! map them!
\ No newline at end of file
+- oh, i forgot CAN priorities are assigned inversely!! map them!
+- when linking, hide symbols that are not needed externally (objcopy -G..)
\ No newline at end of file
index 3c6fc8ba5ec23dc3d8fa49e1f035dea30b1ba788..69f3a2396e0f96db5c1a9ce15b72855500657f10 100644 (file)
@@ -75,7 +75,7 @@
 #include <drivers/can.h>       // can_chip_t, can_frame_t
 #include "frescan.h"           // frescan_init_params_t, frescan_send_params_t
 #include "frescan_queues.h"    // init, enqueue, requeue
-#include "frescan_data.h"      // init, the_networks
+#include "frescan_data.h"      // init, frescan_data
 #include "frescan_servers.h"   // init, frame_sent
 #include "frescan_debug.h"     // DEBUG
 #include "frescan_id.h"        // frescan_id_set_field, frescan_id_get_field
@@ -183,7 +183,7 @@ int frescan_init(frescan_init_params_t *params)
                 return -1;
         }
 
-        ret = frescan_queues_init(&the_networks[params->net].queues, params);
+        ret = frescan_queues_init(&frescan_data[params->net].queues, params);
         if (ret != 0) {
                 FRESCAN_ERROR("could not initialize the queues\n");
                 return -1;
@@ -227,9 +227,9 @@ int frescan_send(const frescan_send_params_t *params,
 
         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a packet\n");
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
         packet = frescan_packets_alloc();
-        FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
         if (packet == NULL) {
                 FRESCAN_ERROR("could not allocate packet\n");
@@ -239,9 +239,9 @@ int frescan_send(const frescan_send_params_t *params,
 
         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a frame\n");
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
         packet->frame = can_framespool_alloc();
-        FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
         if (packet->frame == NULL) {
                 FRESCAN_ERROR("could not allocate frame\n");
@@ -276,7 +276,7 @@ int frescan_send(const frescan_send_params_t *params,
 
         frescan_id_set_field(&packet->frame->id,
                              FRESCAN_FIELD_SRC,
-                             (uint32_t)the_networks[params->net].local_node);
+                             (uint32_t)frescan_data[params->net].local_node);
 
         frescan_id_set_field(&packet->frame->id,
                               FRESCAN_FIELD_CHAN,
@@ -296,22 +296,22 @@ int frescan_send(const frescan_send_params_t *params,
 
         packet->buffer_read_pointer = packet->buffer_head;
         packet->buffer_pending_bytes = size;
-        pqueue = the_networks[params->net].queues.tx_fp_queue;
+        pqueue = frescan_data[params->net].queues.tx_fp_queue;
 
         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "enqueue the packet\n");
         if (packet->flags & FRESCAN_FP) {
-                FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+                FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
                 ret = frescan_pqueue_enqueue(pqueue, packet, params->prio);
-                FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+                FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
                 if (ret != 0) {
                         FRESCAN_ERROR("could not enqueue the packet\n");
                         return -1;
                 }
         } else {
-                FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+                FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
                 ret = frescan_servers_enqueue(params->net, params->ss, packet);
-                FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+                FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
                 if (ret != 0) {
                         FRESCAN_ERROR("could not enqueue the packet\n");
@@ -319,9 +319,9 @@ int frescan_send(const frescan_send_params_t *params,
                 }
         }
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
         ret = frescan_hw_buffer_update(params->net);
-        FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
         if (ret != 0) {
                 FRESCAN_ERROR("could not update hw buffer\n");
@@ -367,7 +367,7 @@ int frescan_recv(const frescan_recv_params_t *params,
                 blocking = false;
         }
 
-        pqueue = the_networks[params->net].queues.rx_channel_queues
+        pqueue = frescan_data[params->net].queues.rx_channel_queues
                                                              [params->channel];
 
         ret = frescan_pqueue_dequeue(pqueue, &head, prio, blocking);
@@ -393,7 +393,7 @@ int frescan_recv(const frescan_recv_params_t *params,
 
         *recv_bytes = 0;
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
 
         list_for_each_entry(packet, &head->msg_list, msg_list) {
                 // TODO: memory checks, delete the packets
@@ -423,7 +423,7 @@ int frescan_recv(const frescan_recv_params_t *params,
 
         ret = frescan_packets_free(head);
 
-        FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
 
         if (ret != 0) {
                 FRESCAN_ERROR("could not free head packet\n");
@@ -490,9 +490,9 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip,
         packet->frame = frame;
 
         if (frag_id == FRESCAN_MX_IDS) {
-                head = the_networks[net].id_fp_queues[src][prio];
+                head = frescan_data[net].id_fp_queues[src][prio];
         } else {
-                head = the_networks[net].id_queues[src][frag_id];
+                head = frescan_data[net].id_queues[src][frag_id];
         }
 
         if (head == NULL) {
@@ -503,9 +503,9 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip,
                 INIT_LIST_HEAD(&head->msg_list);
 
                 if (frag_id == FRESCAN_MX_IDS) {
-                        the_networks[net].id_fp_queues[src][prio] = head;
+                        frescan_data[net].id_fp_queues[src][prio] = head;
                 } else {
-                        the_networks[net].id_queues[src][frag_id] = head;
+                        frescan_data[net].id_queues[src][frag_id] = head;
                 }
         }
 
@@ -516,7 +516,7 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip,
                                 FRESCAN_FRAG_ENABLE_DEBUG,
                 "message complete, move msg to channel\n");
                 // TODO: select the highest priority??
-                pqueue = the_networks[net].queues.rx_channel_queues[channel];
+                pqueue = frescan_data[net].queues.rx_channel_queues[channel];
                 ret = frescan_pqueue_enqueue(pqueue, head, prio);
                 if (ret != 0) {
                         FRESCAN_ERROR("could not enqueue message in channel queue\n");
@@ -524,9 +524,9 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip,
                 }
 
                 if (frag_id == FRESCAN_MX_IDS) {
-                        the_networks[net].id_fp_queues[src][prio] = NULL;
+                        frescan_data[net].id_fp_queues[src][prio] = NULL;
                 } else {
-                        the_networks[net].id_queues[src][frag_id] = NULL;
+                        frescan_data[net].id_queues[src][frag_id] = NULL;
                 }
 
         } else {
@@ -557,7 +557,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip)
         frescan_prio_t prio;
         frescan_ss_t id;
 
-        packet = the_networks[chip->minor].last_packet;
+        packet = frescan_data[chip->minor].last_packet;
 
         id = frescan_id_get_field(packet->frame->id,
                                   FRESCAN_FIELD_FRAG_ID);
@@ -589,7 +589,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip)
                         DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
                               "requeue fp packet, prio:%u\n", prio);
 
-                        pqueue = the_networks[chip->minor].queues.tx_fp_queue;
+                        pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
                         ret = frescan_pqueue_requeue(pqueue, packet, prio);
                         if (ret != 0) {
                                 FRESCAN_ERROR("could not requeue the packet\n");
@@ -626,7 +626,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip)
                 // TODO: signal semaphore for send_sync
         }
 
-        the_networks[chip->minor].last_packet = NULL;
+        frescan_data[chip->minor].last_packet = NULL;
 
         ret = frescan_hw_buffer_update(chip->minor);
         if (ret != 0) {
@@ -653,7 +653,7 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
         frescan_prio_t prio;
         frescan_ss_t id;
 
-        packet = the_networks[chip->minor].last_packet;
+        packet = frescan_data[chip->minor].last_packet;
 
         id = frescan_id_get_field(packet->frame->id,
                                   FRESCAN_FIELD_FRAG_ID);
@@ -669,7 +669,7 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
                       "requeue fp packet, prio:%u\n", prio);
 
-                pqueue = the_networks[chip->minor].queues.tx_fp_queue;
+                pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
                 ret = frescan_pqueue_requeue(pqueue, packet, prio);
                 if (ret != 0) {
                         FRESCAN_ERROR("could not requeue the packet\n");
@@ -689,7 +689,7 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
                 return -1;
         }
 
-        the_networks[chip->minor].last_packet = NULL;
+        frescan_data[chip->minor].last_packet = NULL;
 
         ret = frescan_hw_buffer_update(chip->minor);
         if (ret != 0) {
index 57676af66645dc4583ffb0bd90841d68e0c6a8dd..e2f59dab34dfb1072249a1b2abf1734a19d1ec4c 100644 (file)
  *
  */
 
-#ifndef _MARTE_FRESCAN_H_
-#define _MARTE_FRESCAN_H_
+#ifndef _FRESCAN_H_
+#define _FRESCAN_H_
 
-#include <stdint.h>  // uint8_t
-#include <stdbool.h> // bool
-#include <unistd.h>  // size_t
-
-typedef uint8_t frescan_network_t;
-typedef uint8_t frescan_node_t;
-typedef uint8_t frescan_channel_t;
-typedef uint8_t frescan_prio_t;
-typedef uint8_t frescan_ss_t;
-typedef uint32_t frescan_budget_t;
-
-/**
- * frescan_flags_t - frescan flags
- *
- * @FRESCAN_SS: send the message using sporadic servers
- * @FRESCAN_FP: send the message using fixed priorities
- * @FRESCAN_POLL: no buffer copy, only pointer and use the ID to poll status
- * @FRESCAN_SYNC: no buffer copy, only pointer and block until it is sent
- * @FRESCAN_ASYNC: use buffer copy and return immediately
- */
-
-typedef enum {
-        FRESCAN_SS    = 1<<4,  // sporadic server
-        FRESCAN_FP    = 1<<3,  // fixed priorities
-        FRESCAN_POLL  = 1<<2,  // polling
-        FRESCAN_SYNC  = 1<<1,  // synchronous
-        FRESCAN_ASYNC = 1      // asynchronous
-} frescan_flags_t;
-
-/**
- * frescan_send_params_t - send parameters
- *
- * @net: the network to use
- * @to: the node where the message shoud be sent to
- * @channel: the channel in 'to' where the message shoud be sent to
- * @flags: the flags (see frescan_flags_t)
- * @prio: the priority for the message if (flags & FRESCAN_FP)
- * @ss: the sporadic server for the message if (flags & FRESCAN_SS)
- */
-
-typedef struct {
-        frescan_network_t net;
-        frescan_node_t to;
-        frescan_channel_t channel;
-        frescan_flags_t flags;
-        union {
-                frescan_prio_t prio;
-                frescan_ss_t ss;
-        };
-} frescan_send_params_t;
-
-/**
- * frescan_recv_params_t - receive parameters
- *
- * @net: the network to use
- * @channel: the channel from which we want to extract a message
- * @flags: FRESCAN_SYNC/ASYNC
- */
-
-typedef struct {
-        frescan_network_t net;
-        frescan_channel_t channel;
-        frescan_flags_t flags;
-} frescan_recv_params_t;
-
-/**
- * frescan_init_params_t - initialization parameters
- *
- * @net: network to initialize (minor number ie: /dev/can0 -> 0)
- * @node: set the local node identificator
- * @tx_fp_max_prio: maximum number of priorities for the fixed priority
- *                  transmission queues. (prio = 0 .. max_prio - 1)
- * @rx_num_of_channels: number of rx channels (0 .. rx_num_of_channels - 1)
- * @rx_channel_max_prio: array (range rx_num_of_channels) saying the number
- *                       of priorities for each channel. If this parameter is
- *                       NULL tx_fp_max_prio will be used for all queues.
- */
-
-typedef struct {
-        frescan_network_t net;
-        frescan_node_t node;
-        uint32_t tx_fp_max_prio;
-        uint32_t rx_num_of_channels;
-        uint32_t *rx_channel_max_prio;
-} frescan_init_params_t;
+#include "frescan_types.h"
 
 /**
  * frescan_init - initializes the network and the internal structures
@@ -199,4 +115,4 @@ int frescan_recv(const frescan_recv_params_t *params,
                  frescan_node_t *from,
                  frescan_prio_t *prio);
 
-#endif // _MARTE_FRESCAN_H_
+#endif // _FRESCAN_H_
index ccc5a7156f1c9758021ccd8510d18d2eb45c25a9..23bc3c9a18aa19d24e338e3411390bc425f52801 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "frescan_bwres.h"
 #include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_threads.h"
 #include "frescan_bwres_analysis.h"
@@ -84,14 +85,16 @@ int frescan_bwres_init(frescan_network_t net)
 {
         int ret;
         frescan_server_params_t  server_params;  // TODO: improve this...
-        frescan_sa_init_params_t sa_init_params; // TODO: improve this...
+        frescan_bwres_sa_init_params_t init_params; // TODO: improve this...
 
-        sa_init_params.max_prio = 30;
-        sa_init_params.min_prio = 1;
+        init_params.max_prio = 30;
+        init_params.min_prio = 1;
 
-        ret = frescan_sa_init(&the_networks[net].scenario,
-                              &sa_init_params);
-        if (ret != 0) return ret;
+        if (frescan_data[net].local_node == FRESCAN_BWRES_MASTER_NODE) {
+            ret = frescan_bwres_sa_init(&frescan_data[net].scenario,
+                                        &init_params);
+            if (ret != 0) return ret;
+        }
 
         server_params.budget = 5;
         server_params.period.tv_sec = 1;
@@ -99,15 +102,15 @@ int frescan_bwres_init(frescan_network_t net)
         server_params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
 
         ret = frescan_servers_create(net, &server_params,
-                                     &the_networks[net].neg_messages_ss_id);
+                                     &frescan_data[net].neg_messages_ss_id);
         if (ret != 0) return ret;
 
         // TODO: we have to add this negotiation contracts to the sa table
 
-        ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
+        ret = frescan_bwres_robjs_init(FRESCAN_BWRES_ROBJS_MX_CEILING);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
+        ret = frescan_bwres_requests_init(FRESCAN_BWRES_REQ_MX_CEILING);
         if (ret != 0) return ret;
 
         ret = frescan_messages_init(net);
@@ -123,55 +126,54 @@ int frescan_bwres_init(frescan_network_t net)
 }
 
 /**
- * frescan_bwres_negotiate()
+ * frescan_bwres_group_change_mode_sync()
  *
- * to negotiate a contract we follow the next steps:
- *
- * 1.- prepare a request
+ * 1.- allocate and prepare the GN request
  * 2.- enqueue the request
  * 3.- wait in the reply object for a reply
- * 4.- return the final values and free the request
+ *     (unless there are only cancellations)
+ * 4.- free the request
  */
 
-int frescan_bwres_negotiate(frescan_network_t net,
-                            const frsh_contract_t *contract,
-                            frescan_ss_t *ss,
-                            bool *accepted)
+int frescan_bwres_group_change_mode_sync
+                (frescan_network_t            net,
+                 const frsh_contracts_group_t *contracts_to_neg,
+                 const frsh_contracts_group_t *contracts_to_reneg,
+                 const frescan_ss_group_t     *ss_to_reneg,
+                 const frescan_ss_group_t     *ss_to_cancel,
+                 frescan_ss_group_t           *ss_new,
+                 bool                         *accepted)
 {
         int ret;
-        frescan_request_id_t   req;
-        frescan_request_data_t *req_data;
-        frescan_server_params_t server_params;
+        frescan_bwres_request_id_t req;
+        frescan_bwres_request_data_t *req_data;
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
+        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a GN request\n");
 
-        ret = frescan_requests_alloc(&req);
+        ret = frescan_bwres_requests_alloc(&req);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_get_data(req, &req_data);
+        ret = frescan_bwres_requests_get_data(req, &req_data);
         if (ret != 0) return ret;
 
-        req_data->type         = FRESCAN_REQ_NEG;
-        req_data->req          = req;
-        req_data->contract     = (frsh_contract_t *)contract;
-        req_data->request_node = the_networks[net].local_node;
         req_data->net          = net;
+        req_data->type         = FRESCAN_BWRES_REQ_GN;
+        req_data->req          = req;
+        req_data->request_node = frescan_data[net].local_node;
+        req_data->contracts_to_neg   = (frsh_contracts_group_t *)
+                                                        contracts_to_neg;
+        req_data->contracts_to_reneg = (frsh_contracts_group_t *)
+                                                        contracts_to_reneg;
+        req_data->ss_to_reneg        = (frescan_ss_group_t *)ss_to_reneg;
+        req_data->ss_to_cancel       = (frescan_ss_group_t *)ss_to_cancel;
+        req_data->ss_new             = ss_new;
 
         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
         if (ret != 0) return ret;
 
-        // NOTE: we preallocate a server for the negotiation process
-        server_params.budget = 0;
-        server_params.period.tv_sec = 0;
-        server_params.period.tv_nsec = 0;
-        server_params.prio   = 0;
-
-        ret = frescan_servers_create(net, &server_params, &req_data->ss);
-        if (ret != 0) return ret;
-
         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
 
-        ret = frescan_requests_enqueue(req);
+        ret = frescan_bwres_requests_enqueue(req);
         if (ret != 0) return ret;
 
         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
@@ -183,90 +185,74 @@ int frescan_bwres_negotiate(frescan_network_t net,
         if (ret != 0) return ret;
 
         switch (req_data->return_value) {
-        case FRESCAN_REQ_ACCEPTED:
-                DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
-                *accepted = true;
-                *ss       = req_data->ss;
-                break;
-
-        case FRESCAN_REQ_NOT_ACCEPTED:
-                DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
-                *accepted = false;
-                ret = frescan_servers_destroy(net, req_data->ss);
-                if (ret != 0) return ret;
-                break;
-
-        default:
-                FRESCAN_ERROR("return_value unknown\n");
-                return -1;
+                case FRESCAN_BWRES_REQ_ACCEPTED:
+                        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
+                        *accepted = true;
+                        break;
+
+                case FRESCAN_BWRES_REQ_NOT_ACCEPTED:
+                        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
+                        *accepted = false;
+                        break;
+
+                default:
+                        FRESCAN_ERROR("return_value unknown\n");
+                        return -1;
         }
 
-        frescan_requests_free(req);
+        frescan_bwres_requests_free(req);
         return 0;
 }
 
 /**
- * frescan_bwres_renegotiate()
+ * frescan_bwres_negotiate()
  */
 
-int frescan_bwres_renegotiate(frescan_network_t net,
-                              const frsh_contract_t *contract,
-                              frescan_ss_t ss,
-                              bool *accepted)
+int frescan_bwres_negotiate(frescan_network_t net,
+                            const frsh_contract_t *contract,
+                            frescan_ss_t *ss,
+                            bool *accepted)
 {
         int ret;
-        frescan_request_id_t   req;
-        frescan_request_data_t *req_data;
+        frsh_contracts_group_t contracts_to_neg;
+        frescan_ss_group_t ss_new;
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing renegotiation request\n");
+        contracts_to_neg.size = 1;
+        contracts_to_neg.contracts[0] = *contract;
 
-        ret = frescan_requests_alloc(&req);
+        ret = frescan_bwres_group_change_mode_sync
+                        (net, &contracts_to_neg, NULL, NULL,
+                         NULL, &ss_new, accepted);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_get_data(req, &req_data);
-        if (ret != 0) return ret;
-
-        req_data->type         = FRESCAN_REQ_RENEG;
-        req_data->req          = req;
-        req_data->contract     = (frsh_contract_t *)contract;
-        req_data->request_node = the_networks[net].local_node;
-        req_data->net          = net;
-        req_data->ss           = ss;
-
-        ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
-        if (ret != 0) return ret;
-
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue renegotiation request\n");
+        if (*accepted) {
+                *ss = ss_new.ss[0];
+        }
 
-        ret = frescan_requests_enqueue(req);
-        if (ret != 0) return ret;
+        return 0;
+}
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
+/**
+ * frescan_bwres_renegotiate()
+ */
 
-        ret = frescan_bwres_robjs_wait(req_data->robj);
-        if (ret != 0) return ret;
+int frescan_bwres_renegotiate(frescan_network_t net,
+                              const frsh_contract_t *contract,
+                              frescan_ss_t ss,
+                              bool *accepted)
+{
+        frsh_contracts_group_t contracts_to_reneg;
+        frescan_ss_group_t ss_to_reneg;
 
-        ret = frescan_bwres_robjs_free(req_data->robj);
-        if (ret != 0) return ret;
+        contracts_to_reneg.size = 1;
+        contracts_to_reneg.contracts[0] = *contract;
 
-        switch (req_data->return_value) {
-        case FRESCAN_REQ_ACCEPTED:
-                DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "renegotiation OK\n");
-                *accepted = true;
-                break;
-
-        case FRESCAN_REQ_NOT_ACCEPTED:
-                DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "renegotiation FAIL\n");
-                *accepted = false;
-                break;
-
-        default:
-                FRESCAN_ERROR("return_value unknown\n");
-                return -1;
-        }
+        ss_to_reneg.size = 1;
+        ss_to_reneg.ss[0] = ss;
 
-        frescan_requests_free(req);
-        return 0;
+        return frescan_bwres_group_change_mode_sync
+                (net, NULL, &contracts_to_reneg, &ss_to_reneg,
+                 NULL, NULL, accepted);
 }
 
 /**
@@ -276,43 +262,11 @@ int frescan_bwres_renegotiate(frescan_network_t net,
 int frescan_bwres_cancel(frescan_network_t net,
                          frescan_ss_t      ss)
 {
-        int ret;
-        frescan_request_id_t   req;
-        frescan_request_data_t *req_data;
-
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing cancel request\n");
-
-        ret = frescan_requests_alloc(&req);
-        if (ret != 0) return ret;
-
-        ret = frescan_requests_get_data(req, &req_data);
-        if (ret != 0) return ret;
-
-        req_data->type         = FRESCAN_REQ_CANCEL;
-        req_data->req          = req;
-        req_data->request_node = the_networks[net].local_node;
-        req_data->net          = net;
-        req_data->ss           = ss;
-
-        ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
-        if (ret != 0) return ret;
-
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue cancel request\n");
-
-        ret = frescan_requests_enqueue(req);
-        if (ret != 0) return ret;
+        frescan_ss_group_t ss_to_cancel;
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a signal\n");
+        ss_to_cancel.size = 1;
+        ss_to_cancel.ss[0] = ss;
 
-        ret = frescan_bwres_robjs_wait(req_data->robj);
-        if (ret != 0) return ret;
-
-        ret = frescan_bwres_robjs_free(req_data->robj);
-        if (ret != 0) return ret;
-
-        ret = frescan_servers_destroy(net, ss);
-        if (ret != 0) return ret;
-
-        frescan_requests_free(req);
-        return 0;
+        return frescan_bwres_group_change_mode_sync
+                        (net, NULL, NULL, NULL, &ss_to_cancel, NULL, NULL);
 }
index dc87d4dccf82083f83825f19ba7a02e672fe941b..5cd5328a8e5f5a731264626b3c5ab9b42252720c 100644 (file)
  *
  */
 
-#ifndef _FRESCAN_BANDWIDTH_RESERVATION_H_
-#define _FRESCAN_BANDWIDTH_RESERVATION_H_
+#ifndef _FRESCAN_BWRES_H_
+#define _FRESCAN_BWRES_H_
 
-#include "frescan.h"
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 extern int frescan_bwres_init(frescan_network_t net);
 
+extern int frescan_bwres_group_change_mode_sync
+                (frescan_network_t            net,
+                 const frsh_contracts_group_t *contracts_to_neg,
+                 const frsh_contracts_group_t *contracts_to_reneg,
+                 const frescan_ss_group_t     *ss_to_reneg,
+                 const frescan_ss_group_t     *ss_to_cancel,
+                 frescan_ss_group_t           *ss_new,
+                 bool *accepted);
+
 extern int frescan_bwres_negotiate(frescan_network_t net,
                                    const frsh_contract_t *contract,
                                    frescan_ss_t *ss,
@@ -85,6 +93,6 @@ extern int frescan_bwres_renegotiate(frescan_network_t net,
 extern int frescan_bwres_cancel(frescan_network_t net,
                                 frescan_ss_t      ss);
 
-// TODO: add other functions: renegotiate_async
+// TODO: add functions for reservation requests
 
-#endif // _FRESCAN_BANDWIDTH_RESERVATION_H_
+#endif // _FRESCAN_BWRES_H_
index e55b835691370d7beafaf3e0735217489528f0e7..c77d616b66c05e5546ebc29cb9d6126afc871496 100644 (file)
 #include "frescan_debug.h"
 
 /**
- * frescan_sa_init() - init the scenario
+ * frescan_bwres_sa_init() - init the scenario
  *
  * Initialize the vres list and copy the initialization parameters
  */
 
-int frescan_sa_init(frescan_sa_scenario_t *scenario,
-                    const frescan_sa_init_params_t *params)
+int frescan_bwres_sa_init(frescan_bwres_sa_scenario_t          *scenario,
+                          const frescan_bwres_sa_init_params_t *params)
 {
         int ret;
         frsh_sa_scenario_init_data_t fsa_scenario_init_data;
@@ -93,7 +93,7 @@ int frescan_sa_init(frescan_sa_scenario_t *scenario,
         INIT_LIST_HEAD(&scenario->vres_head.list);
         scenario->init_params = *params;
 
-        ret = freelist_init(&scenario->fsa_id_freelist,
+        ret = freelist_init(&scenario->fsa_vres_global_id_freelist,
                             FRESCAN_MX_NODES*FRESCAN_MX_IDS);
         if (ret != 0) return ret;
 
@@ -110,25 +110,25 @@ int frescan_sa_init(frescan_sa_scenario_t *scenario,
 }
 
 /**
- * frescan_sa_add_contract() - add a contract to the scenario
+ * frescan_bwres_sa_add_contract() - add a contract to the scenario
  *
  * create the corresponding vres structure and set its values, and add the
  * vres to the vres list
  */
 
-int frescan_sa_add_contract(frescan_sa_scenario_t *scenario,
-                            frescan_ss_t          ss,
-                            frescan_node_t        node,
-                            const frsh_contract_t *contract)
+int frescan_bwres_sa_add_contract(frescan_bwres_sa_scenario_t *scenario,
+                                  frescan_ss_t          ss,
+                                  frescan_node_t        node,
+                                  const frsh_contract_t *contract)
 {
         int ret;
-        frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+        frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
 
         sa_vres->contract = *contract;
         sa_vres->node     = node;
         sa_vres->ss       = ss;
 
-        ret = freelist_alloc(&scenario->fsa_id_freelist);
+        ret = freelist_alloc(&scenario->fsa_vres_global_id_freelist);
         if (ret < 0) return -1;
 
         sa_vres->fsa_vres_global_id = (frsh_sa_vres_id_t)ret;
@@ -145,17 +145,17 @@ int frescan_sa_add_contract(frescan_sa_scenario_t *scenario,
 }
 
 /**
- * frescan_sa_update_contract() - update a contract in the scenario
+ * frescan_bwres_sa_update_contract() - update a contract in the scenario
  */
 
-int frescan_sa_update_contract(frescan_sa_scenario_t  *scenario,
-                               frescan_ss_t           ss,
-                               frescan_node_t         node,
-                               const frsh_contract_t  *contract,
-                               frsh_contract_t        *old_contract)
+int frescan_bwres_sa_update_contract(frescan_bwres_sa_scenario_t  *scenario,
+                                     frescan_ss_t           ss,
+                                     frescan_node_t         node,
+                                     const frsh_contract_t  *contract,
+                                     frsh_contract_t        *old_contract)
 {
         int ret;
-        frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+        frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
 
         if (old_contract != NULL) {
                 *old_contract = sa_vres->contract;
@@ -172,21 +172,26 @@ int frescan_sa_update_contract(frescan_sa_scenario_t  *scenario,
 }
 
 /**
- * frescan_sa_remove_contract() - remove a contract from the scenario
+ * frescan_bwres_sa_remove_contract() - remove a contract from the scenario
  */
 
-int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario,
-                               frescan_ss_t          ss,
-                               frescan_node_t        node)
+int frescan_bwres_sa_remove_contract(frescan_bwres_sa_scenario_t *scenario,
+                                     frescan_ss_t                ss,
+                                     frescan_node_t              node,
+                                     frsh_contract_t             *contract)
 {
         int ret;
-        frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+        frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+
+        if (contract != NULL) {
+                *contract = sa_vres->contract;
+        }
 
         ret = frsh_sa_scenario_del_vres(&scenario->fsa_scenario,
                                         sa_vres->fsa_vres_global_id);
         if (ret != 0) return -1;
 
-        ret = freelist_free(&scenario->fsa_id_freelist,
+        ret = freelist_free(&scenario->fsa_vres_global_id_freelist,
                             sa_vres->fsa_vres_global_id);
         if (ret < 0) return -1;
 
@@ -196,12 +201,12 @@ int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario,
 }
 
 /**
- * frescan_sa_sched_test() - perform a scheduling test on the scenario
+ * frescan_bwres_sa_sched_test() - perform a scheduling test on the scenario
  *
  */
 
-int frescan_sa_sched_test(frescan_sa_scenario_t *scenario,
-                          bool *is_schedulable)
+int frescan_bwres_sa_sched_test(frescan_bwres_sa_scenario_t *scenario,
+                                bool                        *is_schedulable)
 {
         int ret;
 
@@ -218,10 +223,10 @@ int frescan_sa_sched_test(frescan_sa_scenario_t *scenario,
 }
 
 /**
- * frescan_sa_spare_capacity() - distribute the spare capacity
+ * frescan_bwres_sa_spare_capacity() - distribute the spare capacity
  */
 
-int frescan_sa_spare_capacity(frescan_sa_scenario_t *scenario)
+int frescan_bwres_sa_spare_capacity(frescan_bwres_sa_scenario_t *scenario)
 {
         int ret;
 
index e932601bdfc665cb7812f1e3235b07b22ffe708c..8b721bbe149265cc5dfcd9e919e4732790fa768d 100644 (file)
 #ifndef _FRESCAN_BWRES_ANALYSIS_H_
 #define _FRESCAN_BWRES_ANALYSIS_H_
 
-#include "frescan.h"
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 /**
- * frescan_sa_init() - init the scenario
+ * frescan_bwres_sa_init() - init the scenario
  *
  * @scenario: the scenario (in out)
  * @params: init params (in)
  */
 
-extern int frescan_sa_init(frescan_sa_scenario_t *scenario,
-                           const frescan_sa_init_params_t *params);
+extern int frescan_bwres_sa_init
+                          (frescan_bwres_sa_scenario_t *scenario,
+                           const frescan_bwres_sa_init_params_t *params);
 
 /**
- * frescan_sa_add_contract() - add a contract to the scenario
+ * frescan_bwres_sa_add_contract() - add a contract to the scenario
  *
  * @scenario: the scenario (in out)
  * @ss: the preallocated ss identificator (in)
@@ -96,13 +96,14 @@ extern int frescan_sa_init(frescan_sa_scenario_t *scenario,
  * @contract: the new contract (in)
  */
 
-extern int frescan_sa_add_contract(frescan_sa_scenario_t *scenario,
+extern int frescan_bwres_sa_add_contract
+                                  (frescan_bwres_sa_scenario_t *scenario,
                                    frescan_ss_t          ss,
                                    frescan_node_t        node,
                                    const frsh_contract_t *contract);
 
 /**
- * frescan_sa_update_contract() - update a contract in the scenario
+ * frescan_bwres_sa_update_contract() - update a contract in the scenario
  *
  * @scenario: the scenario (in out)
  * @ss: the ss identificator (in)
@@ -112,40 +113,45 @@ extern int frescan_sa_add_contract(frescan_sa_scenario_t *scenario,
  *                no contract is returned (out)
  */
 
-extern int frescan_sa_update_contract(frescan_sa_scenario_t  *scenario,
+extern int frescan_bwres_sa_update_contract
+                                     (frescan_bwres_sa_scenario_t  *scenario,
                                       frescan_ss_t           ss,
                                       frescan_node_t         node,
                                       const frsh_contract_t  *contract,
                                       frsh_contract_t        *old_contract);
 
 /**
- * frescan_sa_remove_contract() - remove a contract from the scenario
+ * frescan_bwres_sa_remove_contract() - remove a contract from the scenario
  *
  * @scenario: the scenario (in out)
  * @ss: the ss to remove (in)
  * @node: the node this contract belongs to (in)
+ * @contract: if not null, returns a copy of the contract (out)
  */
 
-extern int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario,
-                                      frescan_ss_t          ss,
-                                      frescan_node_t        node);
+extern int frescan_bwres_sa_remove_contract
+                                     (frescan_bwres_sa_scenario_t *scenario,
+                                      frescan_ss_t                ss,
+                                      frescan_node_t              node,
+                                      frsh_contract_t             *contract);
 
 /**
- * frescan_sa_sched_test() - perform a scheduling test on the scenario
+ * frescan_bwres_sa_sched_test() - perform a scheduling test on the scenario
  *
  * @scenario: the scenario (in out)
  * @is_schedulable: if the scenario is schedulable or not (out)
  */
 
-extern int frescan_sa_sched_test(frescan_sa_scenario_t *scenario,
-                                 bool *is_schedulable);
+extern int frescan_bwres_sa_sched_test(frescan_bwres_sa_scenario_t *scenario,
+                                       bool *is_schedulable);
 
 /**
- * frescan_sa_spare_capacity() - distribute the spare capacity
+ * frescan_bwres_sa_spare_capacity() - distribute the spare capacity
  *
  * @scenario: the scenario (in out)
  */
 
-extern int frescan_sa_spare_capacity(frescan_sa_scenario_t *scenario);
+extern int frescan_bwres_sa_spare_capacity
+                (frescan_bwres_sa_scenario_t *scenario);
 
 #endif // _FRESCAN_BWRES_ANALYSIS_H_
index 995e436c5fb1f4b0074e476f5b880afd0b65ffe5..98f564b8d9aa3e4c071d07ed6ed22f404d806239 100644 (file)
@@ -68,6 +68,7 @@
 #include "frsh.h" /* frsh_resource_id_t, .. */
 #include "frescan.h" /* frescan_init, ... */
 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
+#include "frescan_types.h"
 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
 
@@ -105,12 +106,13 @@ int frescan_fna_init(const frsh_resource_id_t resource_id)
         init_params.rx_num_of_channels = 10;
         init_params.rx_channel_max_prio = NULL;
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+              "Initializing FRESCAN FNA node%u\n", FRSH_CPU_ID_DEFAULT);
 
         ret = frescan_init(&init_params);
         if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
 
         ret = frescan_bwres_init(init_params.net);
         if (ret != 0) FRESCAN_ERROR ("could not init BWRES");
@@ -122,6 +124,86 @@ int frescan_fna_init(const frsh_resource_id_t resource_id)
 //           VIRTUAL RESOURCES
 ///////////////////////////////////////////////////////////////////
 
+int frescan_fna_group_change_mode_sync
+                (const frsh_resource_id_t     resource_id,
+                 const frsh_contracts_group_t *contracts_to_neg,
+                 const frsh_contracts_group_t *contracts_to_reneg,
+                 const fna_vres_group_t       *vres_to_reneg,
+                 const fna_vres_group_t       *vres_to_cancel,
+                 fna_vres_group_t             *new_vres)
+{
+        int ret, i;
+        bool accepted;
+        frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
+
+        // convert fna_vres to ss
+        if (vres_to_reneg == NULL) {
+                ss_to_reneg.size = 0;
+        } else {
+                ss_to_reneg.size = vres_to_reneg->size;
+                if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+                        FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+                        return -1;
+                }
+
+                for(i=0; i<ss_to_reneg.size; i++) {
+                        ss_to_reneg.ss[i] =
+                                        (frescan_ss_t)vres_to_reneg->vres[i];
+                }
+        }
+
+        if (vres_to_cancel == NULL) {
+                ss_to_cancel.size = 0;
+        } else {
+                ss_to_cancel.size = vres_to_cancel->size;
+                if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+                        FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+                        return -1;
+                }
+
+                for(i=0; i<ss_to_cancel.size; i++) {
+                        ss_to_cancel.ss[i] =
+                                        (frescan_ss_t)vres_to_cancel->vres[i];
+                }
+        }
+
+        if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
+                FRESCAN_ERROR("new_vres is NULL\n");
+                return -1;
+        }
+
+        // negotiate
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+              "calling frescan_bwres_group_change_mode_sync\n");
+
+        ret = frescan_bwres_group_change_mode_sync
+                                        ((frescan_network_t)resource_id,
+                                         contracts_to_neg,
+                                         contracts_to_reneg,
+                                         &ss_to_reneg,
+                                         &ss_to_cancel,
+                                         &ss_new,
+                                         &accepted);
+        if (ret != 0) return -1;
+
+        if (accepted == false) {
+                DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
+                return -1; // TODO: change to constant FNA_REJECTED
+        }
+
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
+
+        // convert new ss to fna_vres
+        if (contracts_to_neg != NULL) {
+                new_vres->size = ss_new.size;
+                for(i=0; i<new_vres->size; i++) {
+                        new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
+                }
+        }
+
+        return 0;
+}
+
 /**
  * frescan_fna_contract_negotiate()
  *
@@ -161,24 +243,18 @@ int frescan_fna_contract_negotiate
                  fna_vres_id_t *vres)
 {
         int ret;
-        bool accepted;
-        frescan_ss_t ss;
+        frsh_contracts_group_t contracts_to_neg;
+        fna_vres_group_t       new_vres;
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
-        ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
-                                       contract,
-                                       &ss,
-                                       &accepted);
-        if (ret != 0) return -1;
+        contracts_to_neg.size = 1;
+        contracts_to_neg.contracts[0] = *contract;
 
-        if (accepted == true) {
-                DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
-                *vres = (fna_vres_id_t)ss;
-                return 0;
-        } else {
-                DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
-                return -1; // TODO: change to constant FNA_REJECTED
-        }
+        ret = frescan_fna_group_change_mode_sync
+                (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
+        if (ret != 0) return ret;
+
+        *vres = new_vres.vres[0];
+        return 0;
 }
 
 /**
@@ -216,8 +292,17 @@ int frescan_fna_contract_renegotiate_sync
                  const fna_vres_id_t vres,
                  const frsh_contract_t *new_contract)
 {
-        FRESCAN_ERROR("not implemented\n");
-        return -1;
+        frsh_contracts_group_t contracts_to_reneg;
+        fna_vres_group_t       vres_to_reneg;
+
+        contracts_to_reneg.size = 1;
+        contracts_to_reneg.contracts[0] = *new_contract;
+        vres_to_reneg.size = 1;
+        vres_to_reneg.vres[0] = vres;
+
+        return frescan_fna_group_change_mode_sync
+                                (resource_id, NULL, &contracts_to_reneg,
+                                 &vres_to_reneg, NULL, NULL);
 }
 
 /**
@@ -334,8 +419,13 @@ int frescan_fna_vres_destroy
                 (const frsh_resource_id_t resource_id,
                  const fna_vres_id_t vres)
 {
-        FRESCAN_ERROR("not implemented\n");
-        return -1;
+        fna_vres_group_t  vres_to_cancel;
+
+        vres_to_cancel.size = 1;
+        vres_to_cancel.vres[0] = vres;
+
+        return frescan_fna_group_change_mode_sync
+                       (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
 }
 
 /**
@@ -638,7 +728,7 @@ int frescan_fna_send_async
         int ret;
         frescan_send_params_t params;
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
               "net:%u dest:%u chan:%u size:%u ss:%u\n",
               endpoint->resource_id, endpoint->destination,
               endpoint->stream_id, size, endpoint->vres);
@@ -711,7 +801,7 @@ int frescan_fna_receive_sync
         params.channel  = (frescan_channel_t)endpoint->stream_id;
         params.flags    = FRESCAN_SYNC;
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
               "net:%u chan:%u size:%u\n",
               endpoint->resource_id, endpoint->stream_id, buffer_size);
 
@@ -725,7 +815,7 @@ int frescan_fna_receive_sync
 
         *from = (frsh_network_address_t)frescan_from;
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
               "msg received, from:%u bytes:%u prio:%u\n",
               *from, *received_bytes, prio);
 
@@ -819,7 +909,7 @@ int frescan_fna_send_endpoint_get_status
 int frescan_fna_receive_endpoint_created
                 (fna_endpoint_data_t *endpoint)
 {
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
         return 0;
 }
 
@@ -930,7 +1020,7 @@ int frescan_fna_network_bytes_to_budget
         *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
                                               number_of_packets);
 
-        DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
               "bytes: %d -> budget: %ld us\n",
                nbytes, frsh_rel_time_to_usec(*budget));
 
@@ -1021,6 +1111,7 @@ int frescan_fna_network_get_min_eff_budget
 
 fna_operations_t frescan_fna_operations = {
         .fna_init = frescan_fna_init,
+        .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
         .fna_contract_negotiate = frescan_fna_contract_negotiate,
         .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
         .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
index b8f745554a5a47f5aac2f4418d942c86bb6005b6..7bef5f0de4275783142796d5e4aa714b4f3a7e14 100644 (file)
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_requests.h"
 #include "frescan.h"
+#include "frescan_data.h"
 #include "frescan_config.h"
 #include "frescan_debug.h"
+#include "frsh_distributed.h"
 
-#define FRESCAN_BWRES_MX_MSG_SIZE 3000  // TODO: adjust to the minimum
+#define FRESCAN_BWRES_MX_MSG_SIZE 5000  // TODO: adjust to the accurate value
 
 /**
  * frescan_messages_init()
@@ -83,394 +85,440 @@ static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
 
 int frescan_messages_init(frescan_network_t net)
 {
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "initialization\n");
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "initialization\n");
 
         send_params[net].net     = net;
-        send_params[net].channel = FRESCAN_NEG_CHANNEL;
+        send_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
         send_params[net].flags   = FRESCAN_SS | FRESCAN_ASYNC;
-        send_params[net].ss      = the_networks[net].neg_messages_ss_id;
-        send_params[net].to      = FRESCAN_NEG_MASTER_NODE;
+        send_params[net].ss      = frescan_data[net].neg_messages_ss_id;
+        send_params[net].to      = FRESCAN_BWRES_MASTER_NODE;
 
         recv_params[net].net     = net;
-        recv_params[net].channel = FRESCAN_NEG_CHANNEL;
+        recv_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
         recv_params[net].flags   = FRESCAN_SYNC;
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REQ_NEG MESSAGE
- *  =======================
+ *  FRESCAN_BWRES_REQ_GN
+ *  ====================
  *  This message is sent from a SLAVE to the MASTER when the slave wants
- *  to negotiate a new contract. It contains the type (a negotiation 'NEG'
- *  request), the LOCAL request id (so the MASTER can use it in the reply
- *  to identify to which request is replying), a preallocated sporadic
- *  server id (the MASTER will store it in its table together with the
- *  node so we can perform renegotiations and spare capacity distribution
- *  in the future) and the contract.
- *
- *      1     2     2      N
- *  +-----------------------------+
- *  | 'NEG' | REQ | SS | CONTRACT |
- *  +-----------------------------+
- *
+ *  to make a negotiation (including creating new vres, renegotiations and
+ *  cancellations).
  */
 
-struct frescan_req_neg_message_t {
-        frescan_request_type_t   type;
-        frescan_request_id_t     req;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_neg_message(const frescan_request_data_t *data,
-                                          uint8_t *msg)
+static int frescan_request_to_gn_message
+                                (const frescan_bwres_request_data_t *data,
+                                 uint8_t *msg,
+                                 size_t  *size)
 {
-        int ret;
-        struct frescan_req_neg_message_t *neg_msg;
-        size_t req_size, contract_size;
-
-        neg_msg = (struct frescan_req_neg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        neg_msg->type     = FRESCAN_REQ_NEG;
-        neg_msg->req      = data->req;
-        neg_msg->ss       = data->ss;
-
-        ret = frsh_contract_marshal(data->contract,
-                                    msg + req_size,
-                                    FRESCAN_BWRES_MX_MSG_SIZE - req_size,
-                                    &contract_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_marshal return -1\n");
-                return -1;
-        }
+        int ret, i;
+        uint8_t *msg_begin, *msg_tmp;
+        size_t bytes_written;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n",
-              neg_msg->type, neg_msg->req, neg_msg->ss, contract_size);
+        msg_begin = msg;
 
-        return req_size + contract_size;
-}
+        // type: FRESCAN_GN_MESSAGE
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_GN;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-static int frescan_neg_message_to_request(const uint8_t *msg,
-                                          frescan_request_data_t *data,
-                                          size_t size)
-{
-        int ret;
-        struct frescan_req_neg_message_t *neg_msg;
-        size_t req_size;
-
-        neg_msg = (struct frescan_req_neg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        data->type        = FRESCAN_REQ_NEG;
-        data->req         = neg_msg->req;
-        data->ss          = neg_msg->ss;
-
-        ret = frsh_contract_unmarshal(data->contract,
-                                      msg  + req_size,  // pointer to contract
-                                      size - req_size); // size marshal '   '
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
-                return -1;
-        }
+        // req
+        *((frescan_bwres_request_id_t *)msg) = data->req;
+        bytes_written = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_written;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
-              data->type, data->req, data->ss);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "GN message req:%u\n", data->req);
 
-        return 0;
-}
+        // NEG-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
 
-/**
- *
- *  FRESCAN_REQ_RENEG MESSAGE
- *  =========================
- *  This message is sent from a SLAVE to the MASTER when the slave wants
- *  to renegotiate a contract. It contains the type (a renegotiation 'RENEG'
- *  request), the LOCAL request id (so the MASTER can use it in the reply
- *  to identify to which request is replying), the sporadic server id
- *  (the MASTER will look up its table together with the node to find the
- *  appropiate entry) and the contract.
- *
- *      1       2     2      N
- *  +-------------------------------+
- *  | 'RENEG' | REQ | SS | CONTRACT |
- *  +-------------------------------+
- *
- */
+        *((uint8_t *)msg) = (uint8_t)data->contracts_to_neg->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-struct frescan_req_reneg_message_t {
-        frescan_request_type_t   type;
-        frescan_request_id_t     req;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
+        for (i=0; i<data->contracts_to_neg->size; i++) {
+                // reserve 2 bytes for the size of the marshalled contract
+                msg_tmp = msg;
+                msg     = msg + sizeof(uint16_t);
+                // marshal the contract
+                ret = frsh_contract_marshal
+                                (&data->contracts_to_neg->contracts[i],
+                                 msg,
+                                 FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+                                 &bytes_written);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+                        return -1;
+                }
+                // write the size and update the message pointer msg
+                *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+                msg = msg + bytes_written;
 
-static int frescan_request_to_reneg_message(const frescan_request_data_t *data,
-                                            uint8_t *msg)
-{
-        int ret;
-        size_t req_size, contract_size;
-        struct frescan_req_reneg_message_t *reneg_msg;
-
-        reneg_msg = (struct frescan_req_reneg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_reneg_message_t);
-
-        reneg_msg->type     = FRESCAN_REQ_RENEG;
-        reneg_msg->req      = data->req;
-        reneg_msg->ss       = data->ss;
-
-        ret = frsh_contract_marshal(data->contract,
-                                    msg + req_size,
-                                    FRESCAN_BWRES_MX_MSG_SIZE - req_size,
-                                    &contract_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_marshal return -1\n");
-                return -1;
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u\n", i, bytes_written);
         }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n",
-              reneg_msg->type, reneg_msg->req, reneg_msg->ss, contract_size);
+        // RENEG-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
 
-        return req_size + contract_size;
-}
+        *((uint8_t *)msg) = (uint8_t)data->contracts_to_reneg->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-static int frescan_reneg_message_to_request(const uint8_t *msg,
-                                            frescan_request_data_t *data,
-                                            size_t size)
-{
-        int ret;
-        struct frescan_req_reneg_message_t *reneg_msg;
-        size_t req_size;
-
-        reneg_msg = (struct frescan_req_reneg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        data->type        = FRESCAN_REQ_RENEG;
-        data->req         = reneg_msg->req;
-        data->ss          = reneg_msg->ss;
-
-        ret = frsh_contract_unmarshal(data->contract,
-                                      msg  + req_size,
-                                      size - req_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
-                return -1;
+        for (i=0; i<data->contracts_to_reneg->size; i++) {
+                // write the ss
+                *((uint16_t *)msg) = (uint16_t)data->ss_to_reneg->ss[i];
+                bytes_written = sizeof(uint16_t);
+                msg = msg + bytes_written;
+                // reserve 2 bytes for the size of the marshalled contract
+                msg_tmp = msg;
+                msg     = msg + sizeof(uint16_t);
+                // marshal the contract
+                ret = frsh_contract_marshal
+                                (&data->contracts_to_reneg->contracts[i],
+                                 msg,
+                                 FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+                                 &bytes_written);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+                        return -1;
+                }
+                // write the size and update the message pointer msg
+                *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+                msg = msg + bytes_written;
+
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u ss[%d]:%u\n",
+                      i, bytes_written, i, data->ss_to_reneg->ss[i]);
         }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
-              data->type, data->req, data->ss);
+        // CANCEL-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "CANCEL-GROUP num ss:%u\n",
+              data->ss_to_cancel->size);
 
-        return 0;
-}
+        *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-/**
- *  FRESCAN_REQ_CANCEL MESSAGE
- *  ==========================
- *  This message is sent from a SLAVE to the MASTER to cancel a contract.
- *  It contains the type, 'CANCEL' and the sporadic server id (the MASTER will
- *  have to look it up in the table). The MASTER doesnt need to reply this
- *  message.
- *
- *  +---------------+
- *  | 'CANCEL' | SS |
- *  +---------------+
- *
- */
+        for (i=0; i<data->ss_to_cancel->size; i++) {
+                // write the ss
+                *((uint16_t *)msg) = (uint16_t)data->ss_to_cancel->ss[i];
+                bytes_written = sizeof(uint16_t);
+                msg = msg + bytes_written;
+
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "ss[%d]:%u\n", data->ss_to_cancel->ss[i]);
+        }
+
+        *size = msg - msg_begin;
 
-struct frescan_req_cancel_message_t {
-        frescan_request_type_t   type;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
 
-static int frescan_request_to_cancel_message(const frescan_request_data_t *data,
-                                             uint8_t *msg)
+        return 0;
+}
+
+static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct frescan_req_cancel_message_t *cancel_msg;
+        int ret, i;
+        uint8_t *msg;
+        size_t bytes_read, contract_size;
+
+        msg = (uint8_t *)msg_to_parse;
+
+        data->contracts_to_neg   = &data->contracts_to_neg_data;
+        data->contracts_to_reneg = &data->contracts_to_reneg_data;
+        data->ss_to_reneg        = &data->ss_to_reneg_data;
+        data->ss_to_cancel       = &data->ss_to_cancel_data;
+        data->ss_new             = &data->ss_new_data;
+
+        // req
+        data->req = *((frescan_bwres_request_id_t *)msg);
+        bytes_read = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "GN message req:%u\n", data->req);
+
+        // NEG-GROUP
+        data->contracts_to_neg->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
+
+        for (i=0; i<data->contracts_to_neg->size; i++) {
+                contract_size = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                // unmarshal the contract
+                ret = frsh_contract_unmarshal
+                                (&data->contracts_to_neg->contracts[i],
+                                 msg,
+                                 contract_size);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+                        return -1;
+                }
+
+                bytes_read = contract_size;
+                msg = msg + bytes_read;
 
-        cancel_msg = (struct frescan_req_cancel_message_t *)msg;
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u\n", i, contract_size);
+        }
 
-        cancel_msg->type     = FRESCAN_REQ_CANCEL;
-        cancel_msg->ss       = data->ss;
+         // RENEG-GROUP
+        data->contracts_to_reneg->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
+
+        for (i=0; i<data->contracts_to_reneg->size; i++) {
+                data->ss_to_reneg->ss[i] = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                contract_size = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                // unmarshal the contract
+                ret = frsh_contract_unmarshal
+                                (&data->contracts_to_reneg->contracts[i],
+                                 msg,
+                                 contract_size);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+                        return -1;
+                }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
-              cancel_msg->type, cancel_msg->ss);
+                bytes_read = contract_size;
+                msg = msg + bytes_read;
 
-        return sizeof(struct frescan_req_cancel_message_t);
-}
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u ss[%d]:%u\n",
+                      i, contract_size, i, data->ss_to_reneg->ss[i]);
+        }
 
-static int frescan_cancel_message_to_request(const uint8_t *msg,
-                                             frescan_request_data_t *data)
-{
-        struct frescan_req_cancel_message_t *cancel_msg;
+        // CANCEL-GROUP
+        data->ss_to_cancel->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
 
-        cancel_msg = (struct frescan_req_cancel_message_t *)msg;
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
 
-        data->type        = FRESCAN_REQ_CANCEL;
-        data->ss          = cancel_msg->ss;
+        for (i=0; i<data->ss_to_cancel->size; i++) {
+                // write the ss
+                data->ss_to_cancel->ss[i] = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
-              data->type, data->ss);
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "ss[%d]:%u\n", data->ss_to_cancel->ss[i]);
+        }
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REP_INC_BUDGET / FRESCAN_REP_DEC_BUDGET
- *  ===============================================
+ *  FRESCAN_BWRES_REQ_MC
+ *  ====================
  *  This message is sent from the MASTER to a slave when there is a change
  *  in the budget value assigned by the spare capacity algorithm.
- *
- *  +---------------------------------------------------+
- *  | 'INC/DEC' | SS | NEW_B | SS | NEW_B |  SS | NEW_B |
- *  +---------------------------------------------------+
- *
  */
 
-static int frescan_request_to_repchange_message
-                (const frescan_request_data_t *data, uint8_t *msg)
+static int frescan_request_to_mc_message
+                                (const frescan_bwres_request_data_t *data,
+                                 uint8_t *msg,
+                                 size_t  *size)
 {
-        int bytes_written;
-        struct list_head *the_mode_change_list;
-        frescan_sa_vres_t *vres;
+        frescan_bwres_vres_t *vres;
         uint8_t *msg_begin;
-
-        if (data->type == FRESCAN_REP_INC_BUDGET) {
-                the_mode_change_list = &the_networks[data->net].
-                                        mode_change_budget_inc_list_head
-                                                        [data->request_node];
-        } else {
-                the_mode_change_list = &the_networks[data->net].
-                                mode_change_budget_dec_list_head
-                                                        [data->request_node];
-        }
-
-        if (list_empty(the_mode_change_list)) {
-                return 0; // nothing to send
-        }
+        size_t bytes_written;
 
         msg_begin = msg;
 
-        *((frescan_request_type_t *)msg) = data->type;
-        bytes_written = sizeof(frescan_request_type_t);
+        // type: FRESCAN_GN_MESSAGE
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_MC;
+        bytes_written = sizeof(uint8_t);
         msg = msg + bytes_written;
 
+        // write the SS-mode_change_type-values fields
         list_for_each_entry(vres,
-                            the_mode_change_list,
+                            &frescan_data[data->net].mode_change_list
+                                                        [data->request_node],
                             mode_change_list)
         {
+                if ((vres->mode_change_type & data->mode_change_type) !=
+                     data->mode_change_type) continue;
+
                 *((frescan_ss_t *)msg) = vres->ss;
                 bytes_written = sizeof(frescan_ss_t);
                 msg = msg + bytes_written;
 
-                *((frsh_sa_time_t *)msg) = vres->old_c;
-                bytes_written = sizeof(frsh_sa_time_t);
+                *((uint8_t *)msg) = (uint8_t)data->mode_change_type;
+                bytes_written = sizeof(uint8_t);
                 msg = msg + bytes_written;
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+                                              FRESCAN_BWRES_MC_BUDGET_DEC)) {
+                        *((frsh_sa_time_t *)msg) = vres->old_c;
+                        bytes_written = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_written;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+                                              FRESCAN_BWRES_MC_PERIOD_DEC)) {
+                        *((frsh_sa_time_t *)msg) = vres->old_t;
+                        bytes_written = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_written;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+                                              FRESCAN_BWRES_MC_PRIO_DEC)) {
+                        *((frsh_sa_prio_t *)msg) = vres->old_p;
+                        bytes_written = sizeof(frsh_sa_prio_t);
+                        msg = msg + bytes_written;
+                }
         }
 
-        return (msg - msg_begin);
+        *size = msg - msg_begin;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
+
+        return 0;
 }
 
-static int frescan_repchange_message_to_request(const uint8_t *msg,
-                                                frescan_request_data_t *data,
-                                                size_t size)
+static int frescan_mc_message_to_request(const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct list_head *the_mode_change_list;
-        frescan_node_t me = the_networks[data->net].local_node;
-        frescan_sa_vres_t *vres;
-        int bytes_read;
-        uint8_t *msg_pointer;
+        uint8_t *msg;
+        size_t bytes_read;
         frescan_ss_t ss;
+        frescan_bwres_vres_t *vres;
+        frescan_node_t me;
 
-        data->type = *((frescan_request_type_t *)msg);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "MC message\n");
 
-        if (data->type == FRESCAN_REP_INC_BUDGET) {
-                the_mode_change_list = &the_networks[data->net].
-                                        mode_change_budget_inc_list_head[me];
-        } else {
-                the_mode_change_list = &the_networks[data->net].
-                                        mode_change_budget_dec_list_head[me];
-        }
-
-        INIT_LIST_HEAD(the_mode_change_list);
-
-        msg_pointer = (uint8_t *)msg;
+        msg = (uint8_t *)msg_to_parse;
+        me = frescan_data[data->net].local_node;
+        data->mode_change_type = 0;
 
-        while(msg_pointer < msg + size) {
-                ss = *((frescan_ss_t *)msg_pointer);
+        while(msg < msg_to_parse + size) {
+                ss = *((frescan_ss_t *)msg);
                 bytes_read = sizeof(frescan_ss_t);
-                msg_pointer = msg_pointer + bytes_read;
-
-                vres = &the_networks[data->net].scenario.vres_pool[me][ss];
-
-                vres->old_c = *((frsh_sa_time_t *)msg_pointer);
-                bytes_read = sizeof(frsh_sa_time_t);
-                msg_pointer = msg_pointer + bytes_read;
+                msg = msg + bytes_read;
+
+                vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
+
+                vres->mode_change_type = *((uint8_t *)msg);
+                bytes_read = sizeof(uint8_t);
+                msg = msg + bytes_read;
+
+                if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+                                              FRESCAN_BWRES_MC_BUDGET_DEC)) {
+                        vres->old_c = *((frsh_sa_time_t *)msg);
+                        bytes_read = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+                                              FRESCAN_BWRES_MC_PERIOD_DEC)) {
+                        vres->old_t = *((frsh_sa_time_t *)msg);
+                        bytes_read = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+                                              FRESCAN_BWRES_MC_PRIO_DEC)) {
+                        vres->old_p = *((frsh_sa_prio_t *)msg);
+                        bytes_read = sizeof(frsh_sa_prio_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (vres->mode_change_type != 0) {
+                        list_add_tail(&(vres->mode_change_list),
+                                      &(frescan_data[data->net].
+                                                      mode_change_list[me]));
+                }
+
+                data->mode_change_type |= vres->mode_change_type;
         }
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REP_NEG MESSAGE
- *  =======================
+ *  FRESCAN_BWRES_REP_GN
+ *  ====================
  *  This message is sent from the MASTER to a slave as a reply to a
- *  FRESCAN_REQ_NEG or a FRESCAN_REQ_RENEG, to say if they were admited.
- *  It contains the type 'REPNEG', the request ID of the slave, a
- *  return value to say if the contract is admited or not, and the final
- *  values if it was admited
- *
- *  +-------------------------------------------+
- *  | 'REPNEG' | REQ | RET_VALUE | FINAL_VALUES | + FRESCAN_REP_INC/DEC_BUDGET
- *  +-------------------------------------------+
- *
+ *  FRESCAN_BWRES_REQ_GN message
  */
 
-struct frescan_rep_neg_message_t {
-        frescan_request_type_t    type;
-        frescan_request_id_t      req;
-        frescan_request_retval_t  return_value;
-        frescan_server_params_t   final_values;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
-                                             uint8_t *msg)
+static int frescan_request_to_rep_gn_message
+                        (const frescan_bwres_request_data_t *data,
+                         uint8_t *msg,
+                         size_t  *size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
+        uint8_t *msg_begin;
+        size_t bytes_written;
+
+        msg_begin = msg;
 
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+        // type
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-        repneg_msg->type         = FRESCAN_REP_NEG;
-        repneg_msg->req          = data->req;
-        repneg_msg->return_value = data->return_value;
-        repneg_msg->final_values = data->final_values;
+        // req
+        *((frescan_bwres_request_id_t *)msg) = data->req;
+        bytes_written = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_written;
 
-        if (data->return_value == FRESCAN_REQ_ACCEPTED) {
-        }
+        // return value
+        *((uint8_t *)msg) = data->return_value;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
+        *size = msg - msg_begin;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              repneg_msg->type, repneg_msg->req, repneg_msg->return_value);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
 
-        return sizeof(struct frescan_rep_neg_message_t);
+        return 0;
 }
 
-static int frescan_repneg_message_to_request(const uint8_t *msg,
-                                             frescan_request_data_t *data)
+static int frescan_rep_gn_message_to_request
+                                        (const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
+        uint8_t *msg;
+        size_t bytes_read;
 
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+        msg = (uint8_t *)msg_to_parse;
 
-        data->type         = FRESCAN_REP_NEG;
-        data->req          = repneg_msg->req;
-        data->return_value = repneg_msg->return_value;
-        // TODO: use final values only if it was accepted!
-        data->final_values = repneg_msg->final_values;
+        // req
+        data->req = *((frescan_bwres_request_id_t *)msg);
+        bytes_read = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_read;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              data->type, data->req, data->return_value);
+        // return_value
+        data->return_value = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
 
         return 0;
 }
@@ -485,35 +533,38 @@ static int frescan_repneg_message_to_request(const uint8_t *msg,
  *
  */
 
-int frescan_messages_send_request(const frescan_request_data_t *req_data)
+int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
 {
         int ret;
         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
         size_t size;
 
         switch(req_data->type) {
-                case FRESCAN_REQ_NEG:
-                        size = frescan_request_to_neg_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
+                case FRESCAN_BWRES_REQ_GN:
+                        ret = frescan_request_to_gn_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
+                        send_params[req_data->net].to =
+                                                FRESCAN_BWRES_MASTER_NODE;
                         break;
-                case FRESCAN_REQ_RENEG:
-                        size = frescan_request_to_reneg_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
-                        break;
-                case FRESCAN_REQ_CANCEL:
-                        size = frescan_request_to_cancel_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
-                        break;
-                case FRESCAN_REP_DEC_BUDGET:
-                case FRESCAN_REP_INC_BUDGET:
-                        size = frescan_request_to_repchange_message
-                                        (req_data, msg);
+                case FRESCAN_BWRES_REQ_MC:
+                        ret = frescan_request_to_mc_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
                         send_params[req_data->net].to = req_data->request_node;
                         break;
-                case FRESCAN_REP_NEG:
-                        size = frescan_request_to_repneg_message(req_data, msg);
+                case FRESCAN_BWRES_REP_GN:
+                        ret = frescan_request_to_rep_gn_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
                         send_params[req_data->net].to = req_data->request_node;
                         break;
+                case FRESCAN_BWRES_REQ_RES:
+                case FRESCAN_BWRES_REQ_RES_GET:
+                case FRESCAN_BWRES_REP_RES_GET:
+                case FRESCAN_BWRES_REQ_RES_SET:
+                case FRESCAN_BWRES_REQ_RES_COMMIT:
+                case FRESCAN_BWRES_REQ_RES_CANCEL:
                 default:
                         FRESCAN_ERROR("request type not supported\n");
                         return -1;
@@ -522,8 +573,8 @@ int frescan_messages_send_request(const frescan_request_data_t *req_data)
         ret = frescan_send(&send_params[req_data->net], msg, size);
         if (ret != 0) return ret;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%d\n",
-              *(frescan_request_type_t *)msg, size);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%u\n",
+              *(frescan_bwres_request_type_t *)msg, size);
 
         return 0;
 }
@@ -539,19 +590,20 @@ int frescan_messages_send_request(const frescan_request_data_t *req_data)
  */
 
 int frescan_messages_recv_request(frescan_network_t    net,
-                                  frescan_request_id_t *req)
+                                  frescan_bwres_request_id_t *req)
 {
         int ret;
         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
+        uint8_t *msg_to_parse;
         size_t recv_bytes;
         frescan_node_t from;
         frescan_prio_t prio;
-        frescan_request_data_t *req_data;
+        frescan_bwres_request_data_t *req_data;
 
-        ret = frescan_requests_alloc(req);
+        ret = frescan_bwres_requests_alloc(req);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_get_data(*req, &req_data);
+        ret = frescan_bwres_requests_get_data(*req, &req_data);
         if (ret != 0) return ret;
 
         ret = frescan_recv(&recv_params[net],
@@ -562,35 +614,40 @@ int frescan_messages_recv_request(frescan_network_t    net,
                             &prio);
         if (ret != 0) return ret;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
               "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
               from, recv_bytes, prio, recv_params[net].channel,
               recv_params[net].flags);
 
         req_data->request_node = from;
-        req_data->net = net;
-
-        switch(*((frescan_request_type_t *)msg)) {
-                case FRESCAN_REQ_NEG:
-                        return frescan_neg_message_to_request(msg,
-                                                              req_data,
-                                                              recv_bytes);
-                case FRESCAN_REQ_RENEG:
-                        return frescan_reneg_message_to_request(msg,
-                                                                req_data,
-                                                                recv_bytes);
-                case FRESCAN_REQ_CANCEL:
-                        return frescan_cancel_message_to_request(msg, req_data);
-                case FRESCAN_REP_DEC_BUDGET:
-                case FRESCAN_REP_INC_BUDGET:
-                        return frescan_repchange_message_to_request(msg,
-                                                                    req_data,
-                                                                    recv_bytes);
-                case FRESCAN_REP_NEG:
-                        return frescan_repneg_message_to_request(msg, req_data);
+        req_data->net          = net;
+        req_data->type         = *((uint8_t *)msg);
+
+        msg_to_parse = msg + sizeof(uint8_t);
+        recv_bytes   = recv_bytes - sizeof(uint8_t);
+
+        switch(req_data->type) {
+                case FRESCAN_BWRES_REQ_GN:
+                        return frescan_gn_message_to_request(msg_to_parse,
+                                                             req_data,
+                                                             recv_bytes);
+                case FRESCAN_BWRES_REQ_MC:
+                        return frescan_mc_message_to_request(msg_to_parse,
+                                                             req_data,
+                                                             recv_bytes);
+                case FRESCAN_BWRES_REP_GN:
+                        return frescan_rep_gn_message_to_request(msg_to_parse,
+                                                                 req_data,
+                                                                 recv_bytes);
+                case FRESCAN_BWRES_REQ_RES:
+                case FRESCAN_BWRES_REQ_RES_GET:
+                case FRESCAN_BWRES_REP_RES_GET:
+                case FRESCAN_BWRES_REQ_RES_SET:
+                case FRESCAN_BWRES_REQ_RES_COMMIT:
+                case FRESCAN_BWRES_REQ_RES_CANCEL:
                 default:
-                        FRESCAN_ERROR("request type %X not supported\n",
-                              *(frescan_request_type_t *)msg);
+                        FRESCAN_ERROR("request type %d not supported\n",
+                                      req_data->type);
                         return -1;
         }
 }
index 99bd6399286edc414b2bafcc23867119198115da..1191219d6964d2a355e38fc863d20679a7336059 100644 (file)
@@ -68,9 +68,7 @@
 #ifndef _FRESCAN_BWRES_MESSAGES_H_
 #define _FRESCAN_BWRES_MESSAGES_H_
 
-#include <stdint.h>
-#include "frescan_bwres_requests.h"
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 /**
  * frescan_messages_init() - initialization function for the module
@@ -88,7 +86,8 @@ extern int frescan_messages_init(frescan_network_t net);
  *
  */
 
-extern int frescan_messages_send_request(const frescan_request_data_t *req_data);
+extern int frescan_messages_send_request
+                        (const frescan_bwres_request_data_t *req_data);
 
 /**
  * frescan_messages_recv_request()
@@ -102,6 +101,6 @@ extern int frescan_messages_send_request(const frescan_request_data_t *req_data)
  */
 
 extern int frescan_messages_recv_request(frescan_network_t    net,
-                                         frescan_request_id_t *req);
+                                         frescan_bwres_request_id_t *req);
 
 #endif // _FRESCAN_BWRES_MESSAGES_H_
index 0bfb7e989c9052c45689269e798521ee9d7b2930..e4eb1a56136d2e37edb8b84948dd3e01f3ba6a1d 100644 (file)
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_mode_change.h"
 #include "frescan_debug.h"
+#include "frescan_config.h"
 
-int frescan_bwres_budget_change(frescan_request_data_t *req_data,
-                                frescan_node_t node,
-                                frescan_sa_mode_change_type_t mode_change_type);
+static int frescan_bwres_send_mc_messages
+                        (frescan_network_t net,
+                         frescan_bwres_mode_change_type_t mode_change_type);
 
 /**
- * frescan_bwres_mode_change_protocol() - performs the mode change
- *
- * Follow the mode change protocol described in the paper.
- *
+ * frescan_bwres_mode_change_protocol() - performs the mode change protocol
  */
 
-int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data)
+int frescan_bwres_mode_change_protocol(frescan_bwres_request_data_t *req_data)
 {
-        int ret, i;
+        int ret;
         frescan_node_t node;
-        frescan_sa_vres_t *vres;
+        frescan_bwres_vres_t *vres;
         frsh_sa_vres_data_t *sa_vres_data;
         frsh_sa_time_t max_period_in_budget_dec;
         frsh_sa_time_t max_period_in_budget_inc;
         struct timespec start_timestamp, next_activation;
 
-        DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG, "starting mode change\n");
+        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "START MODE CHANGE PROTOCOL\n");
 
         for(node=0; node<FRESCAN_MX_NODES; node++) {
-                INIT_LIST_HEAD(&the_networks[req_data->net].
-                                mode_change_budget_inc_list_head[node]);
+                INIT_LIST_HEAD(&frescan_data[req_data->net].
+                                                mode_change_list[node]);
 
-                INIT_LIST_HEAD(&the_networks[req_data->net].
-                                mode_change_budget_dec_list_head[node]);
+                frescan_data[req_data->net].mode_change_type[node] = 0;
         }
 
         max_period_in_budget_dec = (frsh_sa_time_t)0;
         max_period_in_budget_inc = (frsh_sa_time_t)0;
 
+        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "1.- adding vres to mc list\n");
+
         list_for_each_entry
                         (vres,
-                         &the_networks[req_data->net].scenario.vres_head.list,
+                         &frescan_data[req_data->net].scenario.vres_head.list,
                          list)
         {
-                sa_vres_data = &the_networks[req_data->net].
+                sa_vres_data = &frescan_data[req_data->net].
                                 scenario.fsa_scenario.sa_vres_alloc
                                                 [vres->fsa_vres_global_id];
-
                 vres->mode_change_type = 0;
 
                 if (sa_vres_data->c > vres->old_c) {
-                        vres->mode_change_type |= FRESCAN_SA_BUDGET_INC;
-
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_BUDGET_INC;
                         if (sa_vres_data->t > max_period_in_budget_inc) {
                                 max_period_in_budget_inc = sa_vres_data->t;
                         }
-
-                        list_add_tail
-                            (&(vres->mode_change_list),
-                             &(the_networks[req_data->net].
-                               mode_change_budget_inc_list_head[vres->node]));
                 } else if (sa_vres_data->c < vres->old_c) {
-                        vres->mode_change_type |= FRESCAN_SA_BUDGET_DEC;
-
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_BUDGET_DEC;
                         if (sa_vres_data->t > max_period_in_budget_dec) {
                                 max_period_in_budget_dec = sa_vres_data->t;
                         }
-
-                        list_add_tail
-                            (&(vres->mode_change_list),
-                             &(the_networks[req_data->net].
-                               mode_change_budget_dec_list_head[vres->node]));
                 }
 
                 if (sa_vres_data->t > vres->old_t) {
-                        vres->mode_change_type |= FRESCAN_SA_PERIOD_INC;
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_PERIOD_INC;
                 } else if (sa_vres_data->t < vres->old_t) {
-                        vres->mode_change_type |= FRESCAN_SA_PERIOD_DEC;
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_PERIOD_DEC;
                 }
 
                 if (sa_vres_data->p > vres->old_p) {
-                        vres->mode_change_type |= FRESCAN_SA_PRIO_INC;
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_PRIO_INC;
                 } else if (sa_vres_data->p < vres->old_p) {
-                        vres->mode_change_type |= FRESCAN_SA_PRIO_DEC;
+                        vres->mode_change_type |= FRESCAN_BWRES_MC_PRIO_DEC;
                 }
 
+                if (vres->mode_change_type == 0) continue;
+
                 vres->old_c = sa_vres_data->c;
                 vres->old_t = sa_vres_data->t;
                 vres->old_p = sa_vres_data->p;
 
-                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                      "vres: %u type: %X budget_change: %s\n",
-                      vres->fsa_vres_global_id,
-                      vres->mode_change_type,
-                      ((vres->mode_change_type & FRESCAN_SA_BUDGET_INC) ==
-                       FRESCAN_SA_BUDGET_INC) ? "inc" : "dec");
-        }
+                list_add_tail(&(vres->mode_change_list),
+                              &(frescan_data[req_data->net].
+                                        mode_change_list[vres->node]));
 
-        // 1.- mode change for B- members
-        for(i=(FRESCAN_MX_NODES-1); i>=0; i--) {
-                ret = frescan_bwres_budget_change(req_data,
-                                                  (frescan_node_t)i,
-                                                  FRESCAN_SA_BUDGET_DEC);
-                if (ret != 0) return -1;
+                frescan_data[req_data->net].mode_change_type[vres->node] |=
+                                vres->mode_change_type;
+
+                DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                      "vres:%u node:%u ss:%u mc_type:0x%X\n",
+                      vres->fsa_vres_global_id, vres->node,
+                      vres->ss, vres->mode_change_type);
         }
 
-        // 2.- wait the time needed to keep schedulability
-        ret = clock_gettime(CLOCK_MONOTONIC,
-                            &start_timestamp);
+        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "2.- Budget decrease\n");
+
+        ret = frescan_bwres_send_mc_messages(req_data->net,
+                                             FRESCAN_BWRES_MC_BUDGET_DEC);
+        if (ret != 0) return -1;
+
+        ret = frescan_bwres_mode_change_local(req_data->net,
+                                              FRESCAN_BWRES_MC_BUDGET_DEC);
+        if (ret != 0) return -1;
+
+        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "3.- Wait max_period\n");
+
+        ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
         if (ret != 0) return -1;
 
         add_timespec(next_activation,
@@ -188,56 +183,83 @@ int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data)
 
         incr_timespec(next_activation, start_timestamp);
 
-        ret = clock_nanosleep(CLOCK_MONOTONIC,
-                              TIMER_ABSTIME,
-                              &next_activation,
-                              NULL);
+        ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+                              &next_activation, NULL);
         if (ret != 0) return -1;
 
-        // 3-. mode change for B+ members
-        for(i=(FRESCAN_MX_NODES-1); i>=0; i--) {
-                ret = frescan_bwres_budget_change(req_data,
-                                                  (frescan_node_t)i,
-                                                  FRESCAN_SA_BUDGET_INC);
+        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "4.- Budget increase\n");
+
+        ret = frescan_bwres_send_mc_messages(req_data->net,
+                                             FRESCAN_BWRES_MC_BUDGET_INC);
+        if (ret != 0) return -1;
+
+        ret = frescan_bwres_mode_change_local(req_data->net,
+                                              FRESCAN_BWRES_MC_BUDGET_INC);
+        if (ret != 0) return -1;
+
+        return 0;
+}
+
+/**
+ * frescan_bwres_send_mc_messages()
+ *
+ * This function is executed at the master node to send mode change
+ * messages to the slaves
+ */
+
+static int frescan_bwres_send_mc_messages
+                        (frescan_network_t net,
+                         frescan_bwres_mode_change_type_t mode_change_type)
+{
+        int ret;
+        frescan_node_t node;
+        frescan_bwres_request_data_t tmp_req_data;
+
+        tmp_req_data.net              = net;
+        tmp_req_data.type             = FRESCAN_BWRES_REQ_MC;
+        tmp_req_data.mode_change_type = mode_change_type;
+
+        for(node=0; node<FRESCAN_MX_NODES; node++) {
+                if (node == FRESCAN_BWRES_MASTER_NODE) continue;
+
+                if ((frescan_data[net].mode_change_type[node] &
+                     mode_change_type) != mode_change_type) continue;
+
+                DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                      "send MC message to node:%u\n", node);
+
+                tmp_req_data.request_node = node;
+
+                ret = frescan_messages_send_request(&tmp_req_data);
                 if (ret != 0) return -1;
         }
 
         return 0;
 }
 
-int frescan_bwres_budget_change
-                (frescan_request_data_t *req_data,
-                 frescan_node_t node,
-                 frescan_sa_mode_change_type_t mode_change_type)
+/**
+ * frescan_bwres_mode_change_local()
+ *
+ * This function updates local vres. When a slave receives a change mode
+ * message to change the values of any vres this function is called.
+ */
+
+int frescan_bwres_mode_change_local
+                (frescan_network_t net,
+                 frescan_bwres_mode_change_type_t mode_change_type)
 {
         int ret;
         frescan_server_params_t server_params;
-        frescan_sa_vres_t *vres;
-        frescan_request_data_t tmp_req_data;
+        frescan_bwres_vres_t *vres;
         struct timespec start_timestamp, next_activation;
-        struct list_head *the_mode_change_list;
-        frescan_node_t me = the_networks[req_data->net].local_node;
-        bool is_increase;
-
-        is_increase = (mode_change_type & FRESCAN_SA_BUDGET_INC) ==
-                       FRESCAN_SA_BUDGET_INC;
-
-        DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-              "budget change node: %u (me: %u) type: '%s'\n",
-               node, me, is_increase ? "inc" : "dec");
-
-        if (is_increase) {
-                the_mode_change_list = &the_networks[req_data->net].
-                                mode_change_budget_inc_list_head[node];
-        } else {
-                the_mode_change_list = &the_networks[req_data->net].
-                                mode_change_budget_dec_list_head[node];
-        }
+        frescan_node_t me = frescan_data[net].local_node;
 
-        list_for_each_entry(vres, the_mode_change_list, mode_change_list)
+        list_for_each_entry(vres,
+                            &frescan_data[net].mode_change_list[me],
+                            mode_change_list)
         {
-                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                      "vres %u\n", vres->fsa_vres_global_id);
+                if ((vres->mode_change_type & mode_change_type) !=
+                     mode_change_type) continue;
 
                 server_params.budget = frsh_rel_time_to_usec(
                                 frsh_sa_time_to_rel_time(vres->old_c)) /
@@ -245,77 +267,51 @@ int frescan_bwres_budget_change
                 server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
                 server_params.prio   = vres->old_p;
 
-                if (node == me) {
-                        if (is_increase) {
-                                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                                      "Local: update server\n");
-                                ret = frescan_servers_update(req_data->net,
-                                                             &server_params,
-                                                             vres->ss);
-                                if (ret != 0) return ret;
-                        } else {
-                                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                                      "Local: set perceived\n");
-                                ret = frescan_servers_set_perceived
-                                     (req_data->net, &server_params, vres->ss);
-                                if (ret != 0) return ret;
-                        }
+                if (mode_change_type == FRESCAN_BWRES_MC_BUDGET_INC) {
+                        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                              "commit ss:%u\n", vres->ss);
+                        ret = frescan_servers_update(net,
+                                                     &server_params,
+                                                     vres->ss);
+                        if (ret != 0) return ret;
                 } else {
-                        if ((node == req_data->request_node) &&
-                            (vres->ss == req_data->ss)) {
-                                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                                      "External: send reply to reneg\n");
-                                req_data->type = FRESCAN_REP_NEG;
-                                req_data->final_values = server_params;
-
-                                ret = frescan_messages_send_request(req_data);
-                                if (ret != 0) return -1;
-                        } else {
-                                DEBUG(FRESCAN_MODECHANGE_ENABLE_DEBUG,
-                                      "External: send SC change update\n");
-                                tmp_req_data.net  = req_data->net;
-                                tmp_req_data.request_node = node;
-
-                                if (is_increase) {
-                                        tmp_req_data.type =
-                                                        FRESCAN_REP_INC_BUDGET;
-                                } else {
-                                        tmp_req_data.type =
-                                                        FRESCAN_REP_DEC_BUDGET;
-                                }
-
-                                ret = frescan_messages_send_request
-                                                               (&tmp_req_data);
-                                if (ret != 0) return -1;
-                        }
+                        DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                              "set perceived ss:%u\n", vres->ss);
+                        ret = frescan_servers_set_perceived(net,
+                                                            &server_params,
+                                                            vres->ss);
+                        if (ret != 0) return ret;
                 }
         }
 
-        if (is_increase) return 0;
+        if (mode_change_type == FRESCAN_BWRES_MC_BUDGET_INC) return 0;
+
+        ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
+        if (ret != 0) return -1;
+
+        list_for_each_entry(vres,
+                            &frescan_data[net].mode_change_list[me],
+                            mode_change_list)
+        {
+                if ((vres->mode_change_type & mode_change_type) !=
+                     mode_change_type) continue;
+
+                DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                      "wait ss:%u period\n", vres->ss);
+
+                add_timespec(next_activation, start_timestamp,
+                                frsh_rel_time_to_timespec(
+                                       frsh_sa_time_to_rel_time(vres->old_t)));
 
-        if (node == me) {
-                ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
+                ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+                                      &next_activation, NULL);
                 if (ret != 0) return -1;
 
-                list_for_each_entry
-                        (vres, the_mode_change_list, mode_change_list)
-                {
-                        add_timespec(next_activation,
-                                     start_timestamp,
-                                     frsh_rel_time_to_timespec
-                                                (frsh_sa_time_to_rel_time
-                                                        (vres->old_t)));
-
-                        ret = clock_nanosleep(CLOCK_MONOTONIC,
-                                              TIMER_ABSTIME,
-                                              &next_activation,
-                                              NULL);
-                        if (ret != 0) return -1;
-
-                        ret = frescan_servers_commit_perceived(req_data->net,
-                                                               vres->ss);
-                        if (ret != 0) return ret;
-                }
+                DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+                      "commit ss:%u\n", vres->ss);
+
+                ret = frescan_servers_commit_perceived(net, vres->ss);
+                if (ret != 0) return ret;
         }
 
         return 0;
index 117ba51a09f91ae7a77ce88764c0650c52445339..9e635d52c54a090b39bad0b502640b6b110450c1 100644 (file)
 #ifndef _FRESCAN_BWRES_MODE_CHANGE_H_
 #define _FRESCAN_BWRES_MODE_CHANGE_H_
 
-#include "frescan.h"
-#include "frescan_data.h"
-#include "frescan_bwres_requests.h"
+#include "frescan_types.h"
 
 /**
- * frescan_bwres_budget_change() - performs the budget change
+ * frescan_bwres_mode_change_protocol()
+ *
+ * Performs the mode change protocol. This function is called by the master
+ * node who coordinates all the process.
  */
 
-extern int frescan_bwres_budget_change
-                        (frescan_request_data_t *req_data,
-                         frescan_node_t node,
-                         frescan_sa_mode_change_type_t mode_change_type);
+extern int frescan_bwres_mode_change_protocol
+                                (frescan_bwres_request_data_t *req_data);
 
 /**
- * frescan_bwres_mode_change_protocol() - performs the mode change
+ * frescan_bwres_mode_change_local()
+ *
+ * This function updates local vres. When a slave receives a change mode
+ * message to change the values of any vres this function is called.
  */
 
-extern int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data);
+extern int frescan_bwres_mode_change_local
+                (frescan_network_t net,
+                 frescan_bwres_mode_change_type_t mode_change_type);
 
 #endif // _FRESCAN_BWRES_MODE_CHANGE_H_
index b32b227cf30e2dfdc543ec399ee2da7e97d45d3e..16a1b00b1f46cd32b11a37a580db2fba870bdf7b 100644 (file)
@@ -83,7 +83,7 @@ static bool is_initialized = false;
  **/
 
 struct request_t {
-        frescan_request_data_t request_data;
+        frescan_bwres_request_data_t request_data;
         struct list_head       request_list;
         int pool_pos;
 };
@@ -91,19 +91,19 @@ struct request_t {
 static fosa_mutex_t requests_mutex;
 static fosa_cond_t  requests_cond;
 
-static struct request_t the_requests_pool[FRESCAN_MX_REQUESTS];
+static struct request_t the_requests_pool[FRESCAN_BWRES_MX_REQUESTS];
 static freelist_t freelist;
 
 static struct request_t the_requests_list;
 
 /**
- * frescan_requests_init()
+ * frescan_bwres_requests_init()
  *
  * Init the freelist, requests list, cond var and mutex.
  *
  **/
 
-int frescan_requests_init(int max_ceiling)
+int frescan_bwres_requests_init(int max_ceiling)
 {
         int err;
 
@@ -113,7 +113,7 @@ int frescan_requests_init(int max_ceiling)
         err = fosa_cond_init(&requests_cond);
         if (err != 0) return err;
 
-        err = freelist_init(&freelist, FRESCAN_MX_REQUESTS);
+        err = freelist_init(&freelist, FRESCAN_BWRES_MX_REQUESTS);
         if (err != 0) return err;
 
         INIT_LIST_HEAD(&the_requests_list.request_list);
@@ -123,17 +123,17 @@ int frescan_requests_init(int max_ceiling)
 }
 
 /**
- * frescan_requests_alloc()
+ * frescan_bwres_requests_alloc()
  *
  * Allocate a request with the mutex locked
  *
  **/
 
-int frescan_requests_alloc(frescan_request_id_t *req)
+int frescan_bwres_requests_alloc(frescan_bwres_request_id_t *req)
 {
         int err, pos;
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "alloc\n");
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "alloc\n");
 
         if (is_initialized == false) return -1;
 
@@ -157,17 +157,17 @@ locked_error:
 }
 
 /**
- * frescan_requests_free()
+ * frescan_bwres_requests_free()
  *
  * free the request from the pool
  *
  **/
 
-int frescan_requests_free(frescan_request_id_t req)
+int frescan_bwres_requests_free(frescan_bwres_request_id_t req)
 {
         int err;
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "free\n");
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "free\n");
 
         if (is_initialized == false) return -1;
 
@@ -188,38 +188,38 @@ locked_error:
 }
 
 /**
- * frescan_requests_get_data() - gets the data of the request
+ * frescan_bwres_requests_get_data() - gets the data of the request
  *
  */
 
-int frescan_requests_get_data(frescan_request_id_t   req,
-                              frescan_request_data_t **data)
+int frescan_bwres_requests_get_data(frescan_bwres_request_id_t   req,
+                              frescan_bwres_request_data_t **data)
 {
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
         *data = &the_requests_pool[req].request_data;
         return 0;
 }
 
 /**
- * frescan_requests_enqueue()
+ * frescan_bwres_requests_enqueue()
  *
  **/
 
-int frescan_requests_enqueue(frescan_request_id_t req)
+int frescan_bwres_requests_enqueue(frescan_bwres_request_id_t req)
 {
         int err;
 
         err = fosa_mutex_lock(&requests_mutex);
         if (err != 0) return err;
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
               "is list empty A? %d\n",
               list_empty(&the_requests_list.request_list));
 
         list_add_tail(&the_requests_pool[req].request_list,
                       &the_requests_list.request_list);
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
               "is list empty B? %d\n",
               list_empty(&the_requests_list.request_list));
 
@@ -237,11 +237,11 @@ locked_error:
 }
 
 /**
- * frescan_requestqueue_dequeue()
+ * frescan_bwres_requestqueue_dequeue()
  *
  **/
 
-int frescan_requests_dequeue(frescan_request_id_t *req)
+int frescan_bwres_requests_dequeue(frescan_bwres_request_id_t *req)
 {
         int err;
         struct list_head *pos;
@@ -250,15 +250,15 @@ int frescan_requests_dequeue(frescan_request_id_t *req)
         err = fosa_mutex_lock(&requests_mutex);
         if (err != 0) return err;
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "entering\n");
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "entering\n");
 
         while (list_empty(&the_requests_list.request_list)) {
                 err = fosa_cond_wait(&requests_cond, &requests_mutex);
                 if (err != 0) goto locked_error;
-                DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "received signal\n");
+                DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "received signal\n");
         }
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
 
         list_for_each(pos, &the_requests_list.request_list) {
                 request = list_entry(pos, struct request_t, request_list);
@@ -269,7 +269,7 @@ int frescan_requests_dequeue(frescan_request_id_t *req)
 
         *req = request->pool_pos;
 
-        DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
               "is list empty now? %d\n",
               list_empty(&the_requests_list.request_list));
 
index 002dd913a1b16f5f54e033486b2da38b25863ff5..207d3259449fd4f628475d6bff51ce75592e730b 100644 (file)
 #ifndef _FRESCAN_BWRES_REQUESTS_H_
 #define _FRESCAN_BWRES_REQUESTS_H_
 
-#include <stdint.h>
-#include "frescan_bwres_robjs.h" // frescan_robj_id_t
-#include "frescan_data.h" // frescan_ss_t
+#include "frescan_types.h"
 
-/**
- * frescan_request_data_t
- *
- * This are the data contained in a request to perform the negotiation of
- * contracts.
- *
- * @type: indicates the type of the request
- * @contract: a pointer to the contract to (re)negotiate
- * @ss: the local sporadic server ID
- * @request_node: the node that performed the request
- * @req: the request id of the SLAVE to identify the request in the reply
- * @return_value: the value returned in a Reply (accepted or not)
- * @final_values: the values for the ss after the negotiation
- * @net: the network instance where this request belongs to
- * @robj: a reply object to wait until a negotiation is completed
- *
- */
-
-typedef uint16_t frescan_request_id_t; /* 0 .. MX_REQUESTS */
-
-typedef enum {
-        FRESCAN_REQ_NEG    =  0,  // Negotiate a contract
-        FRESCAN_REQ_RENEG  =  1,  // Renegotiate a contract
-        FRESCAN_REQ_CANCEL =  2,  // Cancel a contract
-        FRESCAN_REP_DEC_BUDGET =  3,  // Mode Change B-
-        FRESCAN_REP_INC_BUDGET =  4,  // Mode Change B+
-        FRESCAN_REP_NEG    =  5,  // Reply to (Re)Negotiate a contract
-} frescan_request_type_t;
-
-typedef enum {
-        FRESCAN_REQ_ACCEPTED      =  0,  // the (re)negotiation is accepted
-        FRESCAN_REQ_NOT_ACCEPTED  =  1,  // the (re)negotiation is not accepted
-} frescan_request_retval_t;
-
-typedef struct {
-        frescan_request_type_t    type;
-        frsh_contract_t           *contract;
-        frescan_ss_t              ss;
-        frescan_node_t            request_node;
-        frescan_request_id_t      req;
-        frescan_request_retval_t  return_value;
-        frescan_server_params_t   final_values;
-        frescan_network_t         net;
-        frescan_robj_id_t         robj;
-} frescan_request_data_t;
+extern int frescan_bwres_requests_init(int max_ceiling);
+extern int frescan_bwres_requests_alloc(frescan_bwres_request_id_t *req);
+extern int frescan_bwres_requests_free(frescan_bwres_request_id_t req);
+extern int frescan_bwres_requests_enqueue(frescan_bwres_request_id_t req);
+extern int frescan_bwres_requests_dequeue(frescan_bwres_request_id_t *req);
 
 /**
- * frescan_requests_init() - initializes the requests
- *
- * This function must be called at initialization time, before the rest of
- * functions of this module.
- *
- * @max_ceiling: the max priority of the threads using this module
- */
-
-extern int frescan_requests_init(int max_ceiling);
-
-/**
- * frescan_requests_alloc() - allocates a request
- */
-
-extern int frescan_requests_alloc(frescan_request_id_t *req);
-
-/**
- * frescan_requests_free() - frees a request
- */
-
-extern int frescan_requests_free(frescan_request_id_t req);
-
-/**
- * frescan_requests_get_data() - gets the data of the request
+ * frescan_bwres_requests_get_data() - gets the data of the request
  *
  * @data: the data is obtained as a pointer an manipulated directly
  *        accesing to the members of the structure. Note that this is
@@ -149,19 +84,7 @@ extern int frescan_requests_free(frescan_request_id_t req);
  *        will just access to the members of the struc directly
  */
 
-extern int frescan_requests_get_data(frescan_request_id_t   req,
-                                     frescan_request_data_t **data);
-
-/**
- * frescan_requests_enqueue() - enqueue a request
- */
-
-extern int frescan_requests_enqueue(frescan_request_id_t req);
-
-/**
- * frescan_requests_dequeue() - dequeue a request
- */
-
-extern int frescan_requests_dequeue(frescan_request_id_t *req);
+extern int frescan_bwres_requests_get_data(frescan_bwres_request_id_t   req,
+                                           frescan_bwres_request_data_t **data);
 
 #endif // _FRESCAN_BWRES_REQUESTS_H_
index d2784da7577fddf825850969c884b31105180b55..cdf29151d4abbd28445123d71f64fcfb4dcdab6c 100644 (file)
@@ -93,7 +93,7 @@ struct replyobj_t {
         fosa_mutex_t mutex;
 };
 
-static struct replyobj_t the_reply_objects[FRESCAN_MX_REPLY_OBJECTS];
+static struct replyobj_t the_reply_objects[FRESCAN_BWRES_MX_REPLY_OBJECTS];
 static freelist_t freelist;
 
 /**
@@ -112,7 +112,7 @@ int frescan_bwres_robjs_init(int max_ceiling)
         err = fosa_mutex_init(&freelist_mutex, max_ceiling);
         if (err != 0) return err;
 
-        err = freelist_init(&freelist, FRESCAN_MX_REPLY_OBJECTS);
+        err = freelist_init(&freelist, FRESCAN_BWRES_MX_REPLY_OBJECTS);
         if (err != 0) return err;
 
         is_initialized = true;
@@ -128,11 +128,11 @@ int frescan_bwres_robjs_init(int max_ceiling)
  *
  **/
 
-int frescan_bwres_robjs_alloc(frescan_robj_id_t *id, int ceiling)
+int frescan_bwres_robjs_alloc(frescan_bwres_robj_id_t *id, int ceiling)
 {
         int err, pos;
 
-        DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
               "allocating reply object, is_initialized=%d\n", is_initialized);
 
         if (is_initialized == false) return -1;
@@ -155,7 +155,7 @@ int frescan_bwres_robjs_alloc(frescan_robj_id_t *id, int ceiling)
         err = fosa_mutex_init(&the_reply_objects[pos].mutex, ceiling);
         if (err != 0) return err;
 
-        DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
               "reply object allocated, id=%d\n", *id);
 
         return 0;
@@ -172,11 +172,11 @@ locked_error:
  *
  **/
 
-int frescan_bwres_robjs_free(frescan_robj_id_t id)
+int frescan_bwres_robjs_free(frescan_bwres_robj_id_t id)
 {
         int err;
 
-        DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
               "free reply id=%d, is_initialized=%d\n", id, is_initialized);
 
         if (is_initialized == false) return -1;
@@ -212,22 +212,22 @@ locked_error:
  *
  **/
 
-int frescan_bwres_robjs_signal(frescan_robj_id_t id)
+int frescan_bwres_robjs_signal(frescan_bwres_robj_id_t id)
 {
         int err;
 
-        DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
               "is_initialized=%d\n", is_initialized);
         if (is_initialized == false) return -1;
 
-        DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
               "taking mutex of the reply id=%d\n", id);
         err = fosa_mutex_lock(&the_reply_objects[id].mutex);
         if (err != 0) return err;
 
                 the_reply_objects[id].is_work_done = true;
 
-                DEBUG(FRESCAN_ROBJS_ENABLE_DEBUG,
+                DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
                       "signal the cond variable\n");
                 err = fosa_cond_signal(&the_reply_objects[id].cond);
                 if (err != 0) goto locked_error;
@@ -250,7 +250,7 @@ locked_error:
  *
  **/
 
-int frescan_bwres_robjs_wait(frescan_robj_id_t id)
+int frescan_bwres_robjs_wait(frescan_bwres_robj_id_t id)
 {
         int err;
 
@@ -284,7 +284,7 @@ locked_error:
  *
  **/
 
-int frescan_bwres_robjs_timedwait(frescan_robj_id_t id,
+int frescan_bwres_robjs_timedwait(frescan_bwres_robj_id_t id,
                                   const struct timespec *abstime)
 {
         int err;
index 941735ce9c92da7b75f39965896afb4e8cb233f9..ceb0395cfe7a71f97c5f876e1a237600a678fff5 100644 (file)
 #ifndef _FRESCAN_BWRES_ROBJS_H_
 #define _FRESCAN_BWRES_ROBJS_H_
 
-#include <time.h> /* for timespec */
-#include "fosa_opaque_types.h" /* for FOSA_ETIMEDOUT */
-
-typedef unsigned int frescan_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
-#define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
+#include "frescan_types.h"
 
 extern int frescan_bwres_robjs_init(int max_ceiling);
-extern int frescan_bwres_robjs_alloc(frescan_robj_id_t *id, int ceiling);
-extern int frescan_bwres_robjs_free(frescan_robj_id_t id);
-extern int frescan_bwres_robjs_signal(frescan_robj_id_t id);
-extern int frescan_bwres_robjs_wait(frescan_robj_id_t id);
-extern int frescan_bwres_robjs_timedwait(frescan_robj_id_t id,
+extern int frescan_bwres_robjs_alloc(frescan_bwres_robj_id_t *id, int ceiling);
+extern int frescan_bwres_robjs_free(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_signal(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_wait(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_timedwait(frescan_bwres_robj_id_t id,
                                          const struct timespec *abstime);
 
 #endif // _FRESCAN_BWRES_ROBJS_H_
index fed6212169192b8f70a175cc093fffa477d33e65..38bcc21f535b0fd77157962bb3df874a555057d2 100644 (file)
@@ -69,6 +69,7 @@
 #include "frescan_bwres_threads.h"
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
 #include "frescan_bwres_analysis.h"
 #include "frescan_bwres_mode_change.h"
 #include "frescan_config.h"
 #include "frescan_data.h"
 #include "frescan_servers.h"
 
+static void *frescan_manager_thread(void *arg);
+static void *frescan_acceptor_thread(void *arg);
+
+static void frescan_manager_gn_prepare_scenario
+                                (frescan_bwres_sa_scenario_t  *scenario,
+                                 frescan_bwres_request_data_t *req_data);
+
+static void frescan_manager_gn_restore_scenario
+                                (frescan_bwres_sa_scenario_t  *scenario,
+                                 frescan_bwres_request_data_t *req_data);
+
+static void frescan_manager_req_gn(frescan_bwres_request_data_t *req_data);
+static void frescan_manager_rep_gn(frescan_bwres_request_data_t *req_data);
+static void frescan_manager_req_mc(frescan_bwres_request_data_t *req_data);
+
 /**
  * frescan_manager_thread_create()
  *
@@ -83,8 +99,6 @@
  * in a request queue for LOCAL or EXTERNAL requests.
  */
 
-static void *frescan_manager_thread(void *arg);
-
 int frescan_manager_thread_create(frescan_network_t net)
 {
         int ret;
@@ -93,10 +107,10 @@ int frescan_manager_thread_create(frescan_network_t net)
         ret = fosa_thread_attr_init(&attr);
         if (ret != 0) return ret;
 
-        ret = fosa_thread_attr_set_prio(&attr, FRESCAN_NEG_THREAD_PRIO);
+        ret = fosa_thread_attr_set_prio(&attr, FRESCAN_BWRES_NEG_THREAD_PRIO);
         if (ret != 0) return ret;
 
-        ret = fosa_thread_create(&the_networks[net].manager_thread_id,
+        ret = fosa_thread_create(&frescan_data[net].manager_thread_id,
                                  &attr,
                                  frescan_manager_thread,
                                  (void *)(uint32_t)net);
@@ -115,8 +129,6 @@ int frescan_manager_thread_create(frescan_network_t net)
  * messages from the network and converting them into requests.
  */
 
-static void *frescan_acceptor_thread(void *arg);
-
 int frescan_acceptor_thread_create(frescan_network_t net)
 {
         int ret;
@@ -125,10 +137,10 @@ int frescan_acceptor_thread_create(frescan_network_t net)
         ret = fosa_thread_attr_init(&attr);
         if (ret != 0) return ret;
 
-        ret = fosa_thread_attr_set_prio(&attr, FRESCAN_ACCEPTOR_THREAD_PRIO);
+        ret = fosa_thread_attr_set_prio(&attr, FRESCAN_BWRES_ACCEPTOR_PRIO);
         if (ret != 0) return ret;
 
-        ret = fosa_thread_create(&the_networks[net].acceptor_thread_id,
+        ret = fosa_thread_create(&frescan_data[net].acceptor_thread_id,
                                  &attr,
                                  frescan_acceptor_thread,
                                  (void *)(uint32_t)net);
@@ -144,54 +156,47 @@ int frescan_acceptor_thread_create(frescan_network_t net)
  * frescan_manager_thread
  */
 
-static void frescan_manager_neg(frescan_request_data_t *req_data);
-static void frescan_manager_reneg(frescan_request_data_t *req_data);
-static void frescan_manager_cancel(frescan_request_data_t *req_data);
-static void frescan_manager_repneg(frescan_request_data_t *req_data);
-static void frescan_manager_budget_change(frescan_request_data_t *req_data);
-
 static void *frescan_manager_thread(void *arg)
 {
         int ret;
-        frescan_request_id_t   req;
-        frescan_request_data_t *req_data;
+        frescan_bwres_request_id_t   req;
+        frescan_bwres_request_data_t *req_data;
         frescan_network_t net = (uint32_t)arg;
 
-        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "manager thread starts\n");
+        DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "manager thread starts\n");
 
         while(1) {
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "wait for a request\n");
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "wait for a request\n");
 
-                ret = frescan_requests_dequeue(&req);
+                ret = frescan_bwres_requests_dequeue(&req);
                 assert(ret == 0);
 
-                ret = frescan_requests_get_data(req, &req_data);
+                ret = frescan_bwres_requests_get_data(req, &req_data);
                 assert(ret == 0);
 
                 switch(req_data->type) {
-                        case FRESCAN_REQ_NEG:
-                                frescan_manager_neg(req_data);
-                                break;
-                        case FRESCAN_REQ_RENEG:
-                                frescan_manager_reneg(req_data);
-                                break;
-                        case FRESCAN_REQ_CANCEL:
-                                frescan_manager_cancel(req_data);
+                        case FRESCAN_BWRES_REQ_GN:
+                                frescan_manager_req_gn(req_data);
                                 break;
-                        case FRESCAN_REP_DEC_BUDGET:
-                        case FRESCAN_REP_INC_BUDGET:
-                                frescan_manager_budget_change(req_data);
+                        case FRESCAN_BWRES_REP_GN:
+                                frescan_manager_rep_gn(req_data);
                                 break;
-                        case FRESCAN_REP_NEG:
-                                frescan_manager_repneg(req_data);
+                        case FRESCAN_BWRES_REQ_MC:
+                                frescan_manager_req_mc(req_data);
                                 break;
+                        case FRESCAN_BWRES_REQ_RES:
+                        case FRESCAN_BWRES_REQ_RES_GET:
+                        case FRESCAN_BWRES_REP_RES_GET:
+                        case FRESCAN_BWRES_REQ_RES_SET:
+                        case FRESCAN_BWRES_REQ_RES_COMMIT:
+                        case FRESCAN_BWRES_REQ_RES_CANCEL:
                         default:
                                 FRESCAN_ERROR("request type not supported\n");
                                 assert(0);
                 }
 
-                if(req_data->request_node != the_networks[net].local_node) {
-                        ret = frescan_requests_free(req); // acceptor request
+                if(req_data->request_node != frescan_data[net].local_node) {
+                        ret = frescan_bwres_requests_free(req);
                         assert(ret == 0);
                 }
         }
@@ -204,16 +209,16 @@ static void *frescan_manager_thread(void *arg)
 static void *frescan_acceptor_thread(void *arg)
 {
         int ret;
-        frescan_request_id_t req;
+        frescan_bwres_request_id_t req;
         frescan_network_t net = (uint32_t)arg;
 
-        DEBUG(FRESCAN_ACCEPTOR_ENABLE_DEBUG, "acceptor thread starts\n");
+        DEBUG(FRESCAN_BWRES_ACCEPTOR_ENABLE_DEBUG, "acceptor thread starts\n");
 
         while(1) {
                 ret = frescan_messages_recv_request(net, &req);
                 assert(ret == 0);
 
-                ret = frescan_requests_enqueue(req);
+                ret = frescan_bwres_requests_enqueue(req);
                 assert(ret == 0);
         }
 
@@ -221,256 +226,200 @@ static void *frescan_acceptor_thread(void *arg)
 }
 
 /**
- * frescan_manager_neg
+ * frescan_manager_req_gn
  */
 
-static void frescan_manager_neg(frescan_request_data_t *req_data)
+static void frescan_manager_req_gn(frescan_bwres_request_data_t *req_data)
 {
         int ret;
+        frescan_node_t me;
         bool accepted;
-        frescan_sa_scenario_t *scenario;
-
-        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "negotiation request\n");
-
-        scenario = &the_networks[req_data->net].scenario;
+        frescan_bwres_sa_scenario_t *scenario;
 
-        if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "add contract to scenario\n");
+        me = frescan_data[req_data->net].local_node;
 
-                ret = frescan_sa_add_contract
-                                (scenario,
-                                 req_data->ss,
-                                 req_data->request_node,
-                                 req_data->contract);
+        if (me != FRESCAN_BWRES_MASTER_NODE) {
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+                      "send gn req to master\n");
+                ret = frescan_messages_send_request(req_data);
                 assert(ret == 0);
+                return;
+        }
 
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "perform sched analysis\n");
-
-                ret = frescan_sa_sched_test(scenario, &accepted);
-                assert(ret == 0);
+        scenario = &frescan_data[req_data->net].scenario;
 
-                if (accepted) {
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                              "schedulable! distribute spare capacity\n");
+        DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "prepare new scenario\n");
+        frescan_manager_gn_prepare_scenario(scenario, req_data);
 
-                        ret = frescan_sa_spare_capacity(scenario);
-                        assert(ret == 0);
+        DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "perform sched analysis\n");
+        ret = frescan_bwres_sa_sched_test(scenario, &accepted);
+        assert(ret == 0);
 
-                        req_data->return_value = FRESCAN_REQ_ACCEPTED;
+        if (accepted) {
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "ACCEPTED!\n");
+                req_data->return_value = FRESCAN_BWRES_REQ_ACCEPTED;
 
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                              "perform the mode change protocol!\n");
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+                      "spare capacity and mode change\n");
 
-                        ret = frescan_bwres_mode_change_protocol(req_data);
-                        assert(ret == 0);
+                ret = frescan_bwres_sa_spare_capacity(scenario);
+                assert(ret == 0);
 
-                        if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
-                                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                                      "signal local request\n");
-                                ret = frescan_bwres_robjs_signal
-                                                        (req_data->robj);
-                                assert(ret == 0);
-                        }
-                } else {
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                              "not schedulable!\n");
-
-                        ret = frescan_sa_remove_contract
-                                        (scenario,
-                                         req_data->ss,
-                                         req_data->request_node);
-                        assert(ret == 0);
+                ret = frescan_bwres_mode_change_protocol(req_data);
+                assert(ret == 0);
+        } else {
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "FAILED!\n");
+                req_data->return_value = FRESCAN_BWRES_REQ_NOT_ACCEPTED;
+                frescan_manager_gn_restore_scenario(scenario, req_data);
+        }
 
-                        req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED;
-
-                        if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
-                                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                                      "signal local request\n");
-                                ret = frescan_bwres_robjs_signal(req_data->robj);
-                                assert(ret == 0);
-                        } else {
-                                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                                      "sending reply\n");
-                                req_data->type = FRESCAN_REP_NEG;
-                                ret = frescan_messages_send_request(req_data);
-                                assert(ret == 0);
-                        }
-                }
+        if (req_data->request_node == me) {
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "signal robj\n");
+                ret = frescan_bwres_robjs_signal(req_data->robj);
+                assert(ret == 0);
         } else {
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "send negotiation request to master\n");
+                DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "send reply\n");
+                req_data->type = FRESCAN_BWRES_REP_GN;
                 ret = frescan_messages_send_request(req_data);
                 assert(ret == 0);
         }
 }
 
 /**
- * frescan_manager_reneg
+ * frescan_manager_gn_prepare_scenario
  */
 
-static void frescan_manager_reneg(frescan_request_data_t *req_data)
+static void frescan_manager_gn_prepare_scenario
+                                (frescan_bwres_sa_scenario_t  *scenario,
+                                 frescan_bwres_request_data_t *req_data)
 {
-        int ret;
-        bool is_schedulable;
-        frsh_contract_t old_contract;
-        frescan_sa_scenario_t *scenario;
-
-        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "renegotiation request\n");
-
-        scenario = &the_networks[req_data->net].scenario;
+        int ret, i;
+        frescan_server_params_t server_params;
+
+        // NEG-GROUP
+        server_params.budget         = 0;
+        server_params.period.tv_sec  = 0;
+        server_params.period.tv_nsec = 0;
+        server_params.prio           = 0;
+
+        for(i=0; i<req_data->contracts_to_neg->size; i++) {
+                ret = frescan_servers_create(req_data->net,
+                                             &server_params,
+                                             &req_data->ss_new->ss[i]);
+                assert(ret == 0);
 
-        if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
-                // scheduling analysis
-                ret = frescan_sa_update_contract
+                ret = frescan_bwres_sa_add_contract
                                 (scenario,
-                                 req_data->ss,
+                                 req_data->ss_new->ss[i],
                                  req_data->request_node,
-                                 req_data->contract,
-                                 &old_contract);
+                                 &req_data->contracts_to_neg->contracts[i]);
                 assert(ret == 0);
+        }
 
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "perform sched analysis\n");
-
-                ret = frescan_sa_sched_test(scenario, &is_schedulable);
+        // RENEG-GROUP
+        scenario->backup_contracts_to_reneg.size =
+                                        req_data->contracts_to_reneg->size;
+
+        for(i=0; i<req_data->contracts_to_reneg->size; i++) {
+                ret = frescan_bwres_sa_update_contract
+                        (scenario,
+                         req_data->ss_to_reneg->ss[i],
+                         req_data->request_node,
+                         &req_data->contracts_to_reneg->contracts[i],
+                         &scenario->backup_contracts_to_reneg.contracts[i]);
                 assert(ret == 0);
+        }
 
-                if (is_schedulable) {
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                              "schedulable! distribute spare capacity\n");
-
-                        ret = frescan_sa_spare_capacity(scenario);
-                        assert(ret == 0);
-
-                        req_data->return_value = FRESCAN_REQ_ACCEPTED;
-
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                              "perform the mode change protocol!\n");
+        // CANCEL-GROUP
+        scenario->backup_contracts_to_cancel.size =
+                                                req_data->ss_to_cancel->size;
 
-                        ret = frescan_bwres_mode_change_protocol(req_data);
-                        assert(ret == 0);
-                } else {
-                        ret = frescan_sa_update_contract
-                                        (scenario,
-                                         req_data->ss,
-                                         req_data->request_node,
-                                         &old_contract,
-                                         NULL);
-                        assert(ret == 0);
-                        req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED;
-                }
-
-                // signal or reply the results
-                if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
-                        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n");
-                        ret = frescan_bwres_robjs_signal(req_data->robj);
-                        assert(ret == 0);
-                }
-        } else {
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "send renegotiation request to master\n");
-                ret = frescan_messages_send_request(req_data);
+        for(i=0; i<req_data->ss_to_cancel->size; i++) {
+                ret = frescan_bwres_sa_remove_contract
+                        (scenario,
+                         req_data->ss_to_cancel->ss[i],
+                         req_data->request_node,
+                         &scenario->backup_contracts_to_cancel.contracts[i]);
                 assert(ret == 0);
         }
 }
 
 /**
- * frescan_manager_cancel
+ * frescan_manager_gn_restore_scenario
  */
 
-static void frescan_manager_cancel(frescan_request_data_t *req_data)
+static void frescan_manager_gn_restore_scenario
+                (frescan_bwres_sa_scenario_t  *scenario,
+                 frescan_bwres_request_data_t *req_data)
 {
-        int ret;
-        bool is_schedulable;
-        frescan_sa_scenario_t *scenario;
-
-        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "cancel request\n");
+        int ret, i;
 
-        scenario = &the_networks[req_data->net].scenario;
-
-        if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
-                ret = frescan_sa_remove_contract
+        // NEG-GROUP
+        for(i=0; i<req_data->contracts_to_neg->size; i++) {
+                ret = frescan_bwres_sa_remove_contract
                                 (scenario,
-                                 req_data->ss,
-                                 req_data->request_node);
-                assert(ret == 0);
-
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "assign priorities\n");
-
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "perform sched analysis\n");
-
-                ret = frescan_sa_sched_test(scenario, &is_schedulable);
+                                 req_data->ss_new->ss[i],
+                                 req_data->request_node,
+                                 NULL);
                 assert(ret == 0);
 
-                assert(is_schedulable == true);
-
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "redistribute spare capacity\n");
-
-                ret = frescan_sa_spare_capacity(scenario);
+                ret = frescan_servers_destroy(req_data->net,
+                                              req_data->ss_new->ss[i]);
                 assert(ret == 0);
+        }
 
-                ret = frescan_bwres_mode_change_protocol(req_data);
-                assert(ret == 0);
-        } else {
-                DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
-                      "send cancel request to master\n");
-                ret = frescan_messages_send_request(req_data);
+        // RENEG-GROUP
+        for(i=0; i<req_data->contracts_to_reneg->size; i++) {
+                ret = frescan_bwres_sa_update_contract
+                        (scenario,
+                         req_data->ss_to_reneg->ss[i],
+                         req_data->request_node,
+                         &scenario->backup_contracts_to_reneg.contracts[i],
+                         NULL);
                 assert(ret == 0);
         }
 
-        if (req_data->request_node == the_networks[req_data->net].local_node) {
-                ret = frescan_bwres_robjs_signal(req_data->robj);
+        // CANCEL-GROUP
+        for(i=0; i<req_data->ss_to_cancel->size; i++) {
+                ret = frescan_bwres_sa_add_contract
+                        (scenario,
+                         req_data->ss_to_cancel->ss[i],
+                         req_data->request_node,
+                         &scenario->backup_contracts_to_cancel.contracts[i]);
                 assert(ret == 0);
         }
 }
 
 /**
- * frescan_manager_budget_change
+ * frescan_manager_rep_gn
  */
 
-static void frescan_manager_budget_change(frescan_request_data_t *req_data)
+static void frescan_manager_rep_gn(frescan_bwres_request_data_t *req_data)
 {
         int ret;
-        frescan_sa_mode_change_type_t mode_change_type;
-        frescan_node_t me = the_networks[req_data->net].local_node;
+        frescan_bwres_request_data_t *orig_req_data;
 
-        DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "budget change request\n");
+        ret = frescan_bwres_requests_get_data(req_data->req, &orig_req_data);
+        assert(ret == 0);
 
-        if (req_data->type == FRESCAN_REP_INC_BUDGET) {
-                mode_change_type = FRESCAN_SA_BUDGET_INC;
-        } else {
-                mode_change_type = FRESCAN_SA_BUDGET_DEC;
-        }
+        DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+              "reply to gn, return value:%d\n", req_data->return_value);
+
+        orig_req_data->return_value = req_data->return_value;
 
-        ret = frescan_bwres_budget_change(req_data,
-                                          me,
-                                          mode_change_type);
+        ret = frescan_bwres_robjs_signal(orig_req_data->robj);
         assert(ret == 0);
 }
 
 /**
- * frescan_manager_repneg
+ * frescan_manager_req_mc
  */
 
-static void frescan_manager_repneg(frescan_request_data_t *req_data)
+static void frescan_manager_req_mc(frescan_bwres_request_data_t *req_data)
 {
-//         int ret;
-//         frescan_request_data_t *neg_req_data;
-//
-//         DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "reply to neg request\n");
-//
-//         ret = frescan_requests_get_data(req_data->req, &neg_req_data);
-//         assert(ret == 0);
-//
-//         neg_req_data->return_value = req_data->return_value;
-//         neg_req_data->final_values = req_data->final_values;
-//
-//         ret = frescan_bwres_robjs_signal(neg_req_data->robj);
-//         assert(ret == 0);
+        int ret;
 
+        ret = frescan_bwres_mode_change_local(req_data->net,
+                                              req_data->mode_change_type);
+        assert(ret == 0);
 }
index 969a181d6109cf1ba0ad78cd0f5cd4dfb0ef3711..2657ad0041a03eac17bc2fd1ad6aec253145faec 100644 (file)
@@ -67,7 +67,7 @@
 #ifndef _FRESCAN_BWRES_THREADS_H_
 #define _FRESCAN_BWRES_THREADS_H_
 
-#include "frescan.h"
+#include "frescan_types.h"
 
 /**
  * frescan_manager_thread_create()
@@ -82,7 +82,8 @@ extern int frescan_manager_thread_create(frescan_network_t net);
  * frescan_acceptor_thread_create()
  *
  * This call creates the acceptor thread which will be waiting negotiation
- * messages from the network and converting them into requests.
+ * messages from the network and converting them into EXTERNAL requests for
+ * the manager thread.
  */
 
 extern int frescan_acceptor_thread_create(frescan_network_t net);
index 6b13eea60ddb3c20380dcd3f0dcea9dd6890b359..45af9236bc7f2b12b022af20f44625c9a0bfde21 100644 (file)
 #define FRESCAN_MX_PRIOS          32
 #define FRESCAN_REPL_SIGNAL_NUM   FOSA_SIGNAL_MIN + 10 // real-time signal
 #define FRESCAN_BACKGROUND_PRIO   0
-#define FRESCAN_MX_REPLY_OBJECTS  40
 #define FRESCAN_REPL_THREAD_PRIO  60
-#define FRESCAN_NEG_THREAD_PRIO   50
-#define FRESCAN_MX_REQUESTS       40
-#define FRESCAN_NEG_MASTER_NODE   0
-#define FRESCAN_REPLY_OBJECTS_MX_CEILING 90
-#define FRESCAN_REQUESTS_MX_CEILING 90
-#define FRESCAN_BWRES_MX_PRIO     60
-#define FRESCAN_ACCEPTOR_THREAD_PRIO FRESCAN_NEG_THREAD_PRIO - 1
-#define FRESCAN_BWRES_NEG_MESSAGES_PRIO 8
-#define FRESCAN_NEG_CHANNEL       0
 #define FRESCAN_MX_NODES          2
-#define FRESCAN_MX_CONTRACTS      (FRESCAN_MX_NODES*FRESCAN_MX_IDS)
 #define FRESCAN_MX_REPL_OPS       FRESCAN_MX_IDS*10
 
-#define FRESCAN_FRAME_TX_TIME_US     200  // measured transmission time of an 8byte frame
+// Configuration values for FRESCAN_BWRES
+#define FRESCAN_BWRES_MX_REPLY_OBJECTS  40
+#define FRESCAN_BWRES_MX_REQUESTS       40
+#define FRESCAN_BWRES_MASTER_NODE       0
+#define FRESCAN_BWRES_ROBJS_MX_CEILING  90
+#define FRESCAN_BWRES_REQ_MX_CEILING    90
+#define FRESCAN_BWRES_MX_PRIO           60
+#define FRESCAN_BWRES_NEG_THREAD_PRIO   50
+#define FRESCAN_BWRES_ACCEPTOR_PRIO     FRESCAN_BWRES_NEG_THREAD_PRIO - 1
+#define FRESCAN_BWRES_NEG_MESSAGES_PRIO 8
+#define FRESCAN_BWRES_NEG_CHANNEL       0
+#define FRESCAN_BWRES_MX_CONTRACTS      (FRESCAN_MX_NODES*FRESCAN_MX_IDS)
+#define FRESCAN_BWRES_MAX_GROUP_OPS     5
+
+// FRESCAN_FRAME_TX_TIME_US: measured transmission time of an 8byte frame
+#define FRESCAN_FRAME_TX_TIME_US        200
 
 #define FRESCAN_MLOCK_T            unsigned
 #define FRESCAN_CREATE_LOCK(l)
index b35c441c08247540370d849efedbff58e6622019..367923810b9cde6031d2b46b5b7c3ebfa9a44956 100644 (file)
  */
 
 #include "frescan_data.h"
-#include "frescan_debug.h"
 
-frescan_network_data_t the_networks[FRESCAN_MX_NETWORKS];
-frescan_server_data_t the_servers_pool[FRESCAN_MX_NETWORKS][FRESCAN_MX_IDS];
-freelist_t the_servers_pool_freelist[FRESCAN_MX_NETWORKS];
-frescan_server_data_t the_active_servers[FRESCAN_MX_NETWORKS];
-
-/**
- * frescan_data_init() - init the data global variables
- *
- */
+frescan_network_data_t frescan_data[FRESCAN_MX_NETWORKS];
 
 int frescan_data_init(int fd, frescan_init_params_t *params)
 {
@@ -86,22 +77,22 @@ int frescan_data_init(int fd, frescan_init_params_t *params)
         frescan_prio_t prio;
         frescan_node_t src;
 
-        the_networks[params->net].fd = fd;
-        the_networks[params->net].local_node = params->node;
-        the_networks[params->net].last_packet = NULL;
-        the_networks[params->net].last_packet_prio = 0;
+        frescan_data[params->net].fd = fd;
+        frescan_data[params->net].local_node = params->node;
+        frescan_data[params->net].last_packet = NULL;
+        frescan_data[params->net].last_packet_prio = 0;
 
-        FRESCAN_CREATE_LOCK(&the_networks[params->net].lock);
+        FRESCAN_CREATE_LOCK(&frescan_data[params->net].lock);
 
         for(id=0; id<FRESCAN_MX_IDS; id++) {
                 for(src=0; src<FRESCAN_MX_NODES; src++) {
-                        the_networks[params->net].id_queues[src][id] = NULL;
+                      frescan_data[params->net].id_queues[src][id] = NULL;
                 }
         }
 
         for(prio=0; prio<FRESCAN_MX_PRIOS; prio++) {
                 for(src=0; src<FRESCAN_MX_NODES; src++) {
-                        the_networks[params->net].id_fp_queues[src][prio] = NULL;
+                      frescan_data[params->net].id_fp_queues[src][prio] = NULL;
                 }
         }
 
index b4c046327dc3e702c0b54b54a02dc8da4bbdd677..c035f9821c996914ee0e2f112c02c97251786c2e 100644 (file)
 #ifndef _MARTE_FRESCAN_DATA_H_
 #define _MARTE_FRESCAN_DATA_H_
 
-#include <stdint.h>    // uint32_t
-#include <semaphore.h> // sem_t
-#include <time.h>      // struct timespec, timer_t
-#include "fosa_threads_and_signals.h"   // fosa_thread_id_t
-
-#include <misc/linux_list.h> // struct list_head
-#include <misc/freelist.h>   // freelist_t
-
-#include "frescan.h"         // frescan_node_t, _prio_t, _budget_t
+#include "frescan_types.h"   // frescan_node_t, _prio_t, _budget_t
 #include "frescan_config.h"  // FRESCAN_MLOCK_T, FRESCAN_MX_XXX
-#include "frescan_packets.h" // frescan_packet_t
-
-#include "frsh.h" // for frsh_contract_t
-#include "fsa.h"  // for frsh_sa_scenario_t
-
-/**
- * frescan_repl_op_t - a replenishment operation
- *
- * @when: when the replenishment operation is programmed at
- * @amount: number of frames to add to the available budget
- * @repl_list: to chain the replenishments for a certain sporadic server
- * @pool_pos: to know how to free it from the replenishment pool
- */
-
-typedef struct {
-        struct timespec when;
-        frescan_budget_t amount;
-        struct list_head repl_list;
-        int pool_pos;
-} frescan_repl_op_t;
-
-/**
- * frescan_server_params_t - server parameters
- *
- * @budget: the budget in CAN 8-byte frames
- * @period: the replenishment period for the server
- * @prio: the priority of the server
- */
-
-typedef struct {
-        frescan_budget_t budget;
-        struct timespec  period;
-        frescan_prio_t prio;
-} frescan_server_params_t;
-
-/**
- * frescan_server_data_t - server data
- *
- * @committed_params: the committed params (C,T,Prio) for the server
- * @perceived_params: the params perceived by the user (we can lie to him)
- * @current_priority: the current priority (0=background)
- * @repl_list: the list of pending replenishment operations
- * @repl_timer: the timer for the replenishments associated to this server
- *     NOTE: we could use a single timer for all but for now this is simpler
- * @act_time: the last activation time for the server
- * @packet_list: the packets enqueued on this server
- * @servers_list: the list of servers
- */
-
-typedef struct {
-        frescan_server_params_t committed_params;
-        frescan_server_params_t perceived_params;
-        frescan_network_t       net;
-        frescan_ss_t            id;
-        frescan_prio_t          current_priority;
-        frescan_budget_t        pending_packets;
-        frescan_repl_op_t       replenishments;
-        timer_t                 repl_timer;
-        struct timespec         act_time;
-        frescan_packet_t        packet_list;
-        struct list_head        servers_list;
-} frescan_server_data_t;
-
-/**
- * the_servers_pool - pool of servers structure
- */
-
-extern frescan_server_data_t the_servers_pool[FRESCAN_MX_NETWORKS][FRESCAN_MX_IDS];
-extern freelist_t the_servers_pool_freelist[FRESCAN_MX_NETWORKS];
-extern frescan_server_data_t the_active_servers[FRESCAN_MX_NETWORKS];
-
-/**
- * frescan_sa_vres_t - a frescan vres
- *
- * @contract: the contract of the virtual resource
- * @node: the node where the vres belongs to
- * @ss: the sporadic server identifier
- * @list: the list of vres. Note that this is the list of all the vres
- *      in the network instace. As this is a master-slave protocol the master
- *      knows everything about the contracts of the rest of nodes.
- */
-
-typedef enum {
-        FRESCAN_SA_PERIOD_DEC = 1<<5,
-        FRESCAN_SA_PERIOD_INC = 1<<4,
-        FRESCAN_SA_BUDGET_DEC = 1<<3,
-        FRESCAN_SA_BUDGET_INC = 1<<2,
-        FRESCAN_SA_PRIO_DEC   = 1<<1,
-        FRESCAN_SA_PRIO_INC   = 1
-} frescan_sa_mode_change_type_t;
-
-typedef struct {
-        frsh_contract_t    contract;
-        frescan_node_t     node;
-        frescan_ss_t       ss;
-        frsh_sa_vres_id_t  fsa_vres_global_id;
-        struct list_head   list;
-        // mode change variables
-        frsh_sa_time_t old_c;
-        frsh_sa_time_t old_t;
-        frsh_sa_prio_t old_p;
-        frescan_sa_mode_change_type_t mode_change_type;
-        struct list_head              mode_change_list;
-} frescan_sa_vres_t;
 
-/**
- * frescan_sa_scenario_t - the scheduling analysis scenario
- */
-
-typedef struct {
-        frescan_prio_t    max_prio;
-        frescan_prio_t    min_prio;
-} frescan_sa_init_params_t;
-
-typedef struct {
-        frescan_sa_init_params_t init_params;
-        frescan_sa_vres_t vres_pool[FRESCAN_MX_NODES][FRESCAN_MX_IDS];
-        frescan_sa_vres_t vres_head;
-        freelist_t fsa_id_freelist;
-        frsh_sa_scenario_t fsa_scenario;
-} frescan_sa_scenario_t;
-
-/**
- * frescan_prio_queue_t - priority queue
- *
- * FRESCAN priority queues are implemented as an array of one 'fifo_queue' for
- * each priority. Where the 'fifo_queues' are implemented using the
- * 'struct list_head fifo_list;' field of each packet structure (Linux lists).
- *
- * So far mutual exclusion is achieved by disabling interrupts and
- * synchronization is done using a semaphore. This is because the queues
- * are accesed concurrently from user threads and the IRQ handler.
- *
- * @net: the network this priority queue belongs to (mainly for locking)
- * @fifo_queues: an array of packets for each priority where each packet
- *               is just the head of a fifo_list. The array is allocated
- *               from the heap, using malloc, at initialization with range
- *               0..max_prio-1
- * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
- * @sem: semaphore used for synchronization
- */
-
-typedef struct {
-        frescan_network_t net;
-        frescan_packet_t *fifo_queues;
-        uint32_t max_prio;
-        sem_t sem;
-} frescan_prio_queue_t;
-
-/**
- * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
- *
- * @tx_fp_queue: priority queue for the fixed priority packets
- * @rx_channel_queues: a priority queue for each receiving channel
- *
- * TODO: add here the sporadic server queues...
- */
-
-typedef struct {
-        frescan_prio_queue_t *tx_fp_queue;
-        frescan_prio_queue_t **rx_channel_queues;
-        uint32_t num_rx_channels;
-} frescan_queues_t;
-
-/**
- * frescan_network_data_t - data for each network instance
- *
- * @local_node: the local node id for that network. The implementation does not
- * support several interfaces for the same network.
- * @fd: file descriptor associated to /dev/canXX
- * @repl_thread_id: replenishment thread id
- * @manager_thread_id: manager thread id
- * @acceptor_thread_id: acceptor thread id
- * @neg_messages_ss_id: sporadic server for negotiation messages
- * @queues: the queues of this network instance
- * @last_packet: pointer to the last packet from which a frame was inserted
- *               in the chip and its transmission is not complete.
- * @last_packet_prio: prio of the packet in the buffer
- * @id_queues: queues to store received packets while the whole message is
- *             not complete (fragmentation). (id = 0 .. FRESCAN_MX_IDS - 1)
- * @id_fp_queues: the same as id_queues but for fp messages, which have
- *                id=FRESCAN_MX_IDS and are distinguised through their
- *                priorities.
- * @scenario: the scheduling analysis scenario for the network
- *
- * the implementation can handle several FRESCAN networks at the same time
- * in the same node, so we need a place to store its internal data. The data
- * is allocated as an array where the index is the MINOR number (which also
- * identifies the /dev/canx device for that network)
- */
-
-typedef struct {
-        FRESCAN_MLOCK_T lock;
-        frescan_node_t local_node;
-        int fd;
-        fosa_thread_id_t repl_thread_id;
-        fosa_thread_id_t manager_thread_id;
-        fosa_thread_id_t acceptor_thread_id;
-        frescan_ss_t neg_messages_ss_id;
-        frescan_queues_t queues;
-        frescan_packet_t *last_packet;
-        frescan_prio_t last_packet_prio;
-        frescan_packet_t *id_queues[FRESCAN_MX_NODES][FRESCAN_MX_IDS];      // TODO: alloc at init
-        frescan_packet_t *id_fp_queues[FRESCAN_MX_NODES][FRESCAN_MX_PRIOS]; // TODO: alloc at init
-        frescan_sa_scenario_t scenario;
-        struct list_head mode_change_budget_inc_list_head[FRESCAN_MX_NODES];
-        struct list_head mode_change_budget_dec_list_head[FRESCAN_MX_NODES];
-} frescan_network_data_t;
-
-extern frescan_network_data_t the_networks[FRESCAN_MX_NETWORKS];
-
-/**
- * frescan_data_init() - init the data global variables
- *
- */
+extern frescan_network_data_t frescan_data[FRESCAN_MX_NETWORKS];
 
 extern int frescan_data_init(int fd, frescan_init_params_t *params);
 
index cb11efc24b0d0e02243ea7f6486afb0458a872b9..0f2222b373e1fc973d3373868bf60fc1106c136b 100644 (file)
 #define FRESCAN_QUEUES_ENABLE_DEBUG     false
 #define FRESCAN_HW_BUFFER_ENABLE_DEBUG  false
 #define FRESCAN_REPLENSH_ENABLE_DEBUG   false
-#define FRESCAN_ROBJS_ENABLE_DEBUG      false
-#define FRESCAN_BWRES_ENABLE_DEBUG      true
-#define FRESCAN_REQUESTS_ENABLE_DEBUG   false
-#define FRESCAN_MANAGER_ENABLE_DEBUG    true
-#define FRESCAN_ACCEPTOR_ENABLE_DEBUG   false
-#define FRESCAN_MODECHANGE_ENABLE_DEBUG true
-#define FRESCAN_FNA_ENABLE_DEBUG        false
-#define FRESCAN_MESSAGES_ENABLE_DEBUG   false
-#define FRESCAN_SA_ENABLE_DEBUG         false
+
+#define FRESCAN_BWRES_ENABLE_DEBUG            false
+#define FRESCAN_BWRES_ROBJS_ENABLE_DEBUG      false
+#define FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG   false
+#define FRESCAN_BWRES_MANAGER_ENABLE_DEBUG    false
+#define FRESCAN_BWRES_ACCEPTOR_ENABLE_DEBUG   false
+#define FRESCAN_BWRES_MC_ENABLE_DEBUG         false
+#define FRESCAN_BWRES_FNA_ENABLE_DEBUG        false
+#define FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG   false
+#define FRESCAN_BWRES_SA_ENABLE_DEBUG         false
 
 /**
  * MEASUREMENT FLAGS
  */
-#define FRESCAN_MEASURE_REPL_TH         true
+#define FRESCAN_MEASURE_REPL_TH         false
 #define FRESCAN_MEASURE_REPL_PROGRAM    false
 
 #endif // _MARTE_FRESCAN_DEBUG_H_
index 3608cf59e2ef8d5341cb41d8b6de4804d759acd5..6fc886ebc4bb9d6f420603682ba3605063de3fd9 100644 (file)
@@ -73,7 +73,7 @@
 
 #include <string.h> // memcpy
 
-#include "frescan_data.h"    // the_networks
+#include "frescan_data.h"    // frescan_data
 #include "frescan_debug.h"   // DEBUG, FRESCAN_ERROR
 #include "frescan_servers.h" // frescan_servers_get_highest_prio
 #include "frescan_queues.h"  // frescan_pqueue_xxx, frescan_servers_dequeue
@@ -95,7 +95,7 @@ int frescan_hw_buffer_abort(frescan_network_t net)
 {
         int ret;
 
-        ret = ioctl(the_networks[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
+        ret = ioctl(frescan_data[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
         if (ret == -1) {
                 FRESCAN_ERROR ("could not abort the frame\n");
                 return -1;
@@ -126,7 +126,7 @@ int frescan_hw_buffer_update(frescan_network_t net)
         ret = frescan_servers_get_highest_prio(net, &id, &sprio);
         if (ret != 0) return ret;
 
-        pqueue = the_networks[net].queues.tx_fp_queue;
+        pqueue = frescan_data[net].queues.tx_fp_queue;
 
         ret = frescan_pqueue_get_highest_prio(pqueue, &packet, &fprio);
         if (ret != 0) return ret;
@@ -152,10 +152,10 @@ int frescan_hw_buffer_update(frescan_network_t net)
         }
 
         prio = (is_fp_highest_prio) ? fprio : sprio;
-        is_frame_in_chip = (the_networks[net].last_packet != NULL);
+        is_frame_in_chip = (frescan_data[net].last_packet != NULL);
 
         if (is_frame_in_chip &&
-           (prio > the_networks[net].last_packet_prio)) {
+           (prio > frescan_data[net].last_packet_prio)) {
                 DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,"abort frame\n");
                 ret = frescan_hw_buffer_abort(net);
                 if (ret != 0) {
@@ -194,8 +194,8 @@ int frescan_hw_buffer_update(frescan_network_t net)
         frescan_id_set_field
                         (&packet->frame->id, FRESCAN_FIELD_FRAG_FLAG, frag_flag);
 
-        the_networks[net].last_packet = packet;
-        the_networks[net].last_packet_prio = prio;
+        frescan_data[net].last_packet = packet;
+        frescan_data[net].last_packet_prio = prio;
 
         DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
               "frame->id:0x%X pend_bytes:%u dlc:%u fflag:%u\n",
@@ -204,7 +204,7 @@ int frescan_hw_buffer_update(frescan_network_t net)
               packet->frame->dlc,
               frag_flag);
 
-        ret = write(the_networks[net].fd,
+        ret = write(frescan_data[net].fd,
                     (void *)packet->frame,
                     sizeof(struct can_frame_t));
 
index e0c179f8e038e3699a19b6e9df002742f0522fad..d6eb2ca53a30b66d57b1ba77ec280210a5442389 100644 (file)
@@ -72,7 +72,7 @@
 #ifndef _MARTE_FRESCAN_HW_BUFFER_H_
 #define _MARTE_FRESCAN_HW_BUFFER_H_
 
-#include "frescan.h"
+#include "frescan_types.h"
 
 extern int frescan_hw_buffer_update(frescan_network_t net);
 
index dc1c408ea4856e285c5fcb6eeedeae541cd31252..049a7b3e5a4772f2be05edcc7e679889716d981a 100644 (file)
  *
  */
 
-#ifndef _MARTE_FRESCAN_PACKETS_H_
-#define _MARTE_FRESCAN_PACKETS_H_
+#ifndef _FRESCAN_PACKETS_H_
+#define _FRESCAN_PACKETS_H_
 
-#include <time.h>             // struct timespec
-#include <stdint.h>           // uint8_t ...
-#include "frescan.h"          // frescan_flags_t
-#include <misc/linux_list.h>  // struct list_head
-#include <drivers/can.h>      // can_frame_t
-
-/**
- * frescan_packet_t - a frescan packet
- *
- * This structure is very important and it is used to store a FRESCAN packet.
- * As we support fragmentation, a FRESCAN packet can be composed of several
- * CAN frames. This 'frescan_packet_t' structure is used in two main cases:
- *
- * 1.- When we are sending data. In this case, the buffer pointers store the
- *     real data we want to sent and we use a 'buffer_read_pointer' to know
- *     how many bytes of the buffer we already sent. In 'frame', we store the
- *     last sent frame (with the corresponding CAN id fields). We will have
- *     to update the fragmentation fields as long as we send more packets.
- *     The 'fifo_list' is used to chained frescan packets of the same priority
- *     or that belong to the same sporadic server. Finally, 'flags', specify
- *     if we are sending ASYNC or SYNC. If we are sending SYNC the buffer
- *     pointers are pointing to the buffer sent by the user (zero copying),
- *     while if we use ASYNC, a copy of the data is done to the buffer.
- *
- * 2.- When we are receiving data, we only use 'frame' and 'fifo_list' fields.
- *     The IRQ handler of the chip allocates a CAN frame and calls to our hook.
- *     We store the pointer to that frame in 'frame' and we make a chain with
- *     frames of the same message (using the fragmentation fields). When we
- *     have all of them, we move the packet list to the corresponding
- *     receiving channel to wait for the user to perform a receive operation
- *     when we will copy the data and free both the packets and the frames.
- *
- * @flags: to know if the packet is to be sent SYNC or ASYNC, FP or SERVER...
- * @frame: pointer to the last sent frame or the received frame
- * @fifo_list: list to put several packets together
- * @msg_list: list to put packets of the same message together
- * @buffer_head: pointer to first byte of the buffer that is going to be sent
- * @buffer_read_pointer: pointer to the part of the buffer being read
- * @buffer_pending_bytes: bytes waiting to be sent
- * @timestamp: time when the packet was enqueued (activation time)
- * @pool_pos: position in the packets pool to know how to free it
- *
- * NOTE: the buffers could also be used on the receiving part to support
- * sequential reads, instead of reading the whole message at once.
- *
- */
-
-typedef struct {
-        frescan_flags_t flags;
-        struct can_frame_t *frame;
-        struct list_head fifo_list;
-        struct list_head msg_list;
-        uint8_t *buffer_head;         // only for sending packets
-        uint8_t *buffer_read_pointer; // only for sending packets
-        uint32_t buffer_pending_bytes; // only for sending packets
-        struct timespec timestamp;
-        int pool_pos;
-} frescan_packet_t;
-
-/**
- * frescan_packets_init
- *
- * Initializes a pool of packets that will be managed internally
- */
+#include "frescan_types.h"
 
 extern int frescan_packets_init();
-
-/**
- * frescan_packets_alloc
- *
- * Allocates a frame from the pool of packets. On error it returns NULL
- */
-
 extern frescan_packet_t *frescan_packets_alloc();
-
-/**
- * frescan_packets_free
- *
- * Frees a frame and returns it to the pool of packets.
- */
-
 extern int frescan_packets_free(frescan_packet_t *packet);
 
-#endif // _MARTE_FRESCAN_PACKETS_H_
+#endif // _FRESCAN_PACKETS_H_
index 2206cd6594b8fe101a062cb4a9c1582d5ddd4e76..fc29e59edba366cd0ef224b889c5284b25947343 100644 (file)
@@ -76,6 +76,7 @@
 #include "frescan_packets.h"
 #include "frescan_debug.h"
 #include "frescan_id.h"
+#include "frescan_data.h"
 
 /**
  * frescan_pqueue_create() - creates a priority queue
@@ -260,7 +261,7 @@ int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
         // calls are made from a context with no interrupts (when updating
         // the buffer at 'frescan_hw_buffer_update' which is always called
         // with interrupts disabled)
-        if (blocking) FRESCAN_ACQUIRE_LOCK(&the_networks[pqueue->net].lock);
+        if (blocking) FRESCAN_ACQUIRE_LOCK(&frescan_data[pqueue->net].lock);
 
         for(prio=pqueue->max_prio-1; prio >= 0; prio--) {
                 if (!list_empty(&pqueue->fifo_queues[prio].fifo_list)) {
@@ -276,7 +277,7 @@ int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
                 }
         }
 
-        if (blocking) FRESCAN_RELEASE_LOCK(&the_networks[pqueue->net].lock);
+        if (blocking) FRESCAN_RELEASE_LOCK(&frescan_data[pqueue->net].lock);
 
         DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "dequeued prio %u\n", prio);
         *packet_prio = prio;
@@ -332,7 +333,7 @@ int frescan_servers_enqueue(frescan_network_t net,
                             frescan_ss_t id,
                             frescan_packet_t *packet)
 {
-        frescan_server_data_t *server = &the_servers_pool[net][id];
+        frescan_ss_data_t *server = &frescan_data[net].ss_data[id];
 
         clock_gettime (CLOCK_MONOTONIC, &packet->timestamp);
 
@@ -347,7 +348,7 @@ int frescan_servers_enqueue(frescan_network_t net,
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
                       "ss becomes active act_time=timestamp\n");
                 list_add_tail(&server->servers_list,
-                              &the_active_servers[net].servers_list);
+                               &frescan_data[net].ss_active_head.servers_list);
                 server->act_time = packet->timestamp;
         }
 
@@ -373,18 +374,18 @@ int frescan_servers_requeue(frescan_network_t net,
 
         // add the packet to the server fifo list
         list_add(&packet->fifo_list,
-                  &the_servers_pool[net][id].packet_list.fifo_list);
+                  &frescan_data[net].ss_data[id].packet_list.fifo_list);
 
         // if the server was inactive (no packets to send) put it active
         // (in the active list)
-        if (the_servers_pool[net][id].pending_packets == 0) {
+        if (frescan_data[net].ss_data[id].pending_packets == 0) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
                       "server was inactive, put in the active list\n");
-                list_add(&the_servers_pool[net][id].servers_list,
-                          &the_active_servers[net].servers_list);
+                list_add(&frescan_data[net].ss_data[id].servers_list,
+                          &frescan_data[net].ss_active_head.servers_list);
         }
 
-        the_servers_pool[net][id].pending_packets++;
+        frescan_data[net].ss_data[id].pending_packets++;
         return 0;
 }
 
@@ -404,9 +405,9 @@ int frescan_servers_dequeue(frescan_network_t net,
                             frescan_prio_t *packet_prio)
 {
         struct list_head *pos;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
 
         if (list_empty(&server->packet_list.fifo_list)) {
                 FRESCAN_ERROR("no packet in server %d fifo list\n", id);
index ffc9bb71fa39652bdb91828b24b256880e63d722..93fd58d6f677c4cf9e7b362f2e62d26138310a6b 100644 (file)
 #ifndef _MARTE_FRESCAN_QUEUES_H_
 #define _MARTE_FRESCAN_QUEUES_H_
 
-#include <stdint.h>           // uint8_t
-#include <stdbool.h>          // bool
-
-#include "frescan.h"          // frescan_prio_t
-#include "frescan_packets.h"  // frescan_packet_t
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 /**
  * frescan_queues_init() - initialize the queues
index f1cc09d769d40fd5892b74ed9eab050d715a1def..8f8d3bfc100e0fc0049caeef23a43c2b69354d7d 100644 (file)
@@ -71,6 +71,7 @@
 #include "frescan_servers.h"
 #include "frescan_servers_replenishments.h" // frescan_replenishments_xxx
 #include "frescan_debug.h"
+#include "frescan_packets.h"
 #include "frescan_data.h"
 #include <signal.h>
 #include <time.h>
@@ -89,11 +90,11 @@ int frescan_servers_init(frescan_network_t net)
 
         DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "initializing servers\n");
 
-        ret = freelist_init(&the_servers_pool_freelist[net], FRESCAN_MX_IDS);
+        ret = freelist_init(&frescan_data[net].ss_id_freelist, FRESCAN_MX_IDS);
         if (ret != 0) return ret;
 
         for (i=0; i<FRESCAN_MX_NETWORKS; i++) {
-                INIT_LIST_HEAD(&the_active_servers[net].servers_list);
+                INIT_LIST_HEAD(&frescan_data[net].ss_active_head.servers_list);
         }
 
         ret = frescan_replenishments_init(net);
@@ -120,12 +121,12 @@ int frescan_servers_create(frescan_network_t net,
 {
         int i, ret, pos;
         struct sigevent evp;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         frescan_repl_op_t *repl;
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
-        pos = freelist_alloc(&the_servers_pool_freelist[net]);
-        FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
+        pos = freelist_alloc(&frescan_data[net].ss_id_freelist);
+        FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
 
         if (pos == -1) {
                 FRESCAN_ERROR("could not allocate servers\n");
@@ -134,14 +135,14 @@ int frescan_servers_create(frescan_network_t net,
 
         *id = (frescan_ss_t)pos;
 
-        server = &the_servers_pool[net][*id];
+        server = &frescan_data[net].ss_data[*id];
 
         server->net = net;
         server->id  = *id;
-        server->committed_params  = *params;
+        server->committed_params = *params;
         server->perceived_params = server->committed_params;
         server->current_priority = params->prio;
-        server->pending_packets = 0;
+        server->pending_packets  = 0;
 
         // the first act_time is set to the server creation time
         clock_gettime (CLOCK_MONOTONIC, &server->act_time);
@@ -191,7 +192,7 @@ int frescan_servers_set_perceived(frescan_network_t net,
                                   const frescan_server_params_t *params,
                                   frescan_ss_t id)
 {
-        the_servers_pool[net][id].perceived_params = *params;
+        frescan_data[net].ss_data[id].perceived_params = *params;
         return 0;
 }
 
@@ -209,12 +210,12 @@ int frescan_servers_commit_perceived(frescan_network_t net,
                                      frescan_ss_t id)
 {
         int i, ret;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         int budget_variation;
-        frescan_repl_op_t *repl;
+        frescan_repl_op_t *repl = NULL;
         struct list_head *pos;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
         budget_variation = server->perceived_params.budget -
                            server->committed_params.budget;
 
@@ -286,9 +287,9 @@ int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id)
         int ret;
         frescan_repl_op_t *repl;
         frescan_packet_t *packet;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
 
         ret = timer_delete (server->repl_timer);
         if (ret != 0) {
@@ -317,10 +318,10 @@ int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id)
         }
         INIT_LIST_HEAD(&server->replenishments.repl_list);
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
         list_del(&server->servers_list);
-        ret = freelist_free(&the_servers_pool_freelist[net], id);
-        FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
+        ret = freelist_free(&frescan_data[net].ss_id_freelist, id);
+        FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
 
         if (ret != 0) {
                 FRESCAN_ERROR("could not free server data from pool\n");
@@ -343,7 +344,7 @@ int frescan_servers_get_data(frescan_network_t net,
                              frescan_server_params_t *params,
                              frescan_ss_t id)
 {
-        *params = the_servers_pool[net][id].perceived_params;
+        *params = frescan_data[net].ss_data[id].perceived_params;
         return 0;
 }
 
@@ -369,10 +370,10 @@ int frescan_servers_get_current_budget(frescan_network_t net,
 {
         struct timespec now;
         frescan_repl_op_t *repl;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         int count;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
 
         // first we get the current real budget in the capacity queue
         clock_gettime (CLOCK_MONOTONIC, &now);
@@ -417,16 +418,17 @@ int frescan_servers_get_highest_prio(frescan_network_t net,
                                      frescan_ss_t *id,
                                      frescan_prio_t *prio)
 {
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        if (list_empty(&the_active_servers->servers_list)) {
+        if (list_empty(&frescan_data[net].ss_active_head.servers_list)) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "server list is empty\n");
                 *id = FRESCAN_MX_IDS;
                 return 0;
         }
 
         *prio = 0;
-        list_for_each_entry(server, &the_active_servers[net].servers_list,
+        list_for_each_entry(server,
+                            &frescan_data[net].ss_active_head.servers_list,
                             servers_list) {
                 if (server->current_priority >= *prio) {
                         *id = server->id;
@@ -461,9 +463,9 @@ int frescan_servers_frame_sent(frescan_network_t net,
 {
         int ret;
         struct timespec *repl_time;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
 
         if (server->current_priority != FRESCAN_BACKGROUND_PRIO) {
                 if (smaller_timespec(packet->timestamp, server->act_time)) {
index 0ecaed88e3690a8ca0df6962506480472cde4ce9..0e967cbe5a560481bbfdd9c16f2b69e95b573b96 100644 (file)
@@ -71,9 +71,7 @@
 #ifndef _MARTE_FRESCAN_SERVERS_H_
 #define _MARTE_FRESCAN_SERVERS_H_
 
-#include "frescan.h"         // frescan_prio_t, frescan_ss_t
-#include "frescan_packets.h" // frescan_packet_t
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 /**
  * frescan_servers_init() - initialize server structures
index 3ae76abb7541e159cbdc2a08bc2815f5004e8182..b2e75f44045b8dfa88f85d5b1927a9e89cfaf567 100644 (file)
@@ -136,7 +136,7 @@ static void *frescan_repl_thread(void *arg)
         siginfo_t siginfo;
         frescan_ss_t id;
         frescan_network_t net;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         struct itimerspec timerdata;
 
         net = (frescan_network_t)(uint32_t)arg;
@@ -164,7 +164,7 @@ static void *frescan_repl_thread(void *arg)
                       siginfo.si_value.sival_int); // the server id
 
                 id = siginfo.si_value.sival_int;
-                server = &the_servers_pool[net][id];
+                server = &frescan_data[net].ss_data[id];
 
                 DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
                       "id:%u current_prio:%u\n", id, server->current_priority);
@@ -239,7 +239,7 @@ int frescan_replenishments_init(frescan_network_t net)
                 return ret;
         }
 
-        ret = fosa_thread_create(&the_networks[net].repl_thread_id,
+        ret = fosa_thread_create(&frescan_data[net].repl_thread_id,
                                  &attr,
                                  frescan_repl_thread,
                                  (void *)(uint32_t)net);
@@ -265,13 +265,13 @@ int frescan_replenishments_init(frescan_network_t net)
  */
 
 int frescan_replenishment_program(frescan_network_t net,
-                                  frescan_ss_t ss,
+                                  frescan_ss_t id,
                                   const struct timespec *timestamp)
 {
         int ret;
         frescan_repl_op_t *repl = NULL;
         struct itimerspec timerdata;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         struct list_head *pos;
         struct timespec now;
 
@@ -280,7 +280,7 @@ int frescan_replenishment_program(frescan_network_t net,
         assert(ret == 0);
 #endif
 
-        server = &the_servers_pool[net][ss];
+        server = &frescan_data[net].ss_data[id];
 
         // extract the head
         list_for_each(pos, &server->replenishments.repl_list) {
index abf2ddd62a49eb2e436cac3305d21b8f14a0654b..ecf2791a2a60ccc90dc3e36083affa112ffe0438 100644 (file)
@@ -70,9 +70,7 @@
 #ifndef _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
 #define _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
 
-#include <time.h>
-#include "frescan.h" // frescan_network_t
-#include "frescan_data.h"
+#include "frescan_types.h"
 
 /**
  * frescan_replenishments_init - init the replenishment structures and thread
@@ -97,10 +95,11 @@ extern int frescan_repl_op_free(frescan_repl_op_t *repl_op);
  *
  * @net: the network instance
  * @ss: the server
+ * @timestamp: timestamp
  */
 
 extern int frescan_replenishment_program(frescan_network_t net,
-                                         frescan_ss_t ss,
+                                         frescan_ss_t id,
                                          const struct timespec *timestamp);
 
 #endif // _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
diff --git a/src_frescan/frescan_types.h b/src_frescan/frescan_types.h
new file mode 100644 (file)
index 0000000..db5c819
--- /dev/null
@@ -0,0 +1,500 @@
+/*!
+ * @file frescan_types.h
+ *
+ * @brief types used in FRESCAN
+ *
+ * @version 0.01
+ *
+ * @date 16-Nov-2008
+ *
+ * @author
+ *      Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the types used in FRESCAN protocol
+ *
+ * @license
+ *
+ * -----------------------------------------------------------------------
+ *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ *    Universidad de Cantabria,              SPAIN
+ *    University of York,                    UK
+ *    Scuola Superiore Sant'Anna,            ITALY
+ *    Kaiserslautern University,             GERMANY
+ *    Univ. Politécnica  Valencia,           SPAIN
+ *    Czech Technical University in Prague,  CZECH REPUBLIC
+ *    ENEA                                   SWEDEN
+ *    Thales Communication S.A.              FRANCE
+ *    Visual Tools S.A.                      SPAIN
+ *    Rapita Systems Ltd                     UK
+ *    Evidence                               ITALY
+ *
+ *    See http://www.frescor.org for a link to partners' websites
+ *
+ *           FRESCOR project (FP6/2005/IST/5-034026) is funded
+ *        in part by the European Union Sixth Framework Programme
+ *        The European Union is not liable of any use that may be
+ *        made of this code.
+ *
+ *  This file is part of FRESCAN
+ *
+ *  FRESCAN is free software; you can  redistribute it and/or  modify
+ *  it under the terms of  the GNU General Public License as published by
+ *  the Free Software Foundation;  either  version 2, or (at  your option)
+ *  any later version.
+ *
+ *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
+ *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
+ *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
+ *  General Public License for more details.
+ *
+ *  You should have  received a  copy of  the  GNU  General Public License
+ *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
+ *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
+ *  02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_TYPES_H_
+#define _FRESCAN_TYPES_H_
+
+#include <stdint.h>  // uint8_t, uint32_t..
+#include <stdbool.h> // bool
+#include <unistd.h>  // size_t
+#include <time.h>    // struct timespec, timer_t
+#include <semaphore.h> // sem_t
+
+#include "frsh.h" // for frsh_contract_t
+#include "fsa.h"  // for frsh_sa_scenario_t
+#include "fosa_opaque_types.h" // for FOSA_ETIMEDOUT
+#include "fosa_threads_and_signals.h"   // fosa_thread_id_t
+#include "frescan_config.h"
+
+#include <misc/linux_list.h> // struct list_head
+#include <drivers/can.h>     // can_frame_t
+#include <misc/freelist.h>   // freelist_t
+
+typedef uint8_t frescan_network_t;
+typedef uint8_t frescan_node_t;
+typedef uint8_t frescan_channel_t;
+typedef uint8_t frescan_prio_t;
+typedef uint8_t frescan_ss_t;
+typedef uint32_t frescan_budget_t;
+
+typedef struct {
+        int           size;
+        frescan_ss_t  ss[FRESCAN_BWRES_MAX_GROUP_OPS];
+} frescan_ss_group_t;
+
+/**
+ * frescan_flags_t - frescan flags
+ *
+ * @FRESCAN_SS: send the message using sporadic servers
+ * @FRESCAN_FP: send the message using fixed priorities
+ * @FRESCAN_POLL: no buffer copy, only pointer and use the ID to poll status
+ * @FRESCAN_SYNC: no buffer copy, only pointer and block until it is sent
+ * @FRESCAN_ASYNC: use buffer copy and return immediately
+ */
+
+typedef enum {
+        FRESCAN_SS    = 1<<4,  // sporadic server
+        FRESCAN_FP    = 1<<3,  // fixed priorities
+        FRESCAN_POLL  = 1<<2,  // polling
+        FRESCAN_SYNC  = 1<<1,  // synchronous
+        FRESCAN_ASYNC = 1      // asynchronous
+} frescan_flags_t;
+
+/**
+ * frescan_send_params_t - send parameters
+ *
+ * @net: the network to use
+ * @to: the node where the message shoud be sent to
+ * @channel: the channel in 'to' where the message shoud be sent to
+ * @flags: the flags (see frescan_flags_t)
+ * @prio: the priority for the message if (flags & FRESCAN_FP)
+ * @ss: the sporadic server for the message if (flags & FRESCAN_SS)
+ */
+
+typedef struct {
+        frescan_network_t net;
+        frescan_node_t to;
+        frescan_channel_t channel;
+        frescan_flags_t flags;
+        union {
+                frescan_prio_t prio;
+                frescan_ss_t ss;
+        };
+} frescan_send_params_t;
+
+/**
+ * frescan_recv_params_t - receive parameters
+ *
+ * @net: the network to use
+ * @channel: the channel from which we want to extract a message
+ * @flags: FRESCAN_SYNC/ASYNC
+ */
+
+typedef struct {
+        frescan_network_t net;
+        frescan_channel_t channel;
+        frescan_flags_t flags;
+} frescan_recv_params_t;
+
+/**
+ * frescan_init_params_t - initialization parameters
+ *
+ * @net: network to initialize (minor number ie: /dev/can0 -> 0)
+ * @node: set the local node identificator
+ * @tx_fp_max_prio: maximum number of priorities for the fixed priority
+ *                  transmission queues. (prio = 0 .. max_prio - 1)
+ * @rx_num_of_channels: number of rx channels (0 .. rx_num_of_channels - 1)
+ * @rx_channel_max_prio: array (range rx_num_of_channels) saying the number
+ *                       of priorities for each channel. If this parameter is
+ *                       NULL tx_fp_max_prio will be used for all queues.
+ */
+
+typedef struct {
+        frescan_network_t net;
+        frescan_node_t node;
+        uint32_t tx_fp_max_prio;
+        uint32_t rx_num_of_channels;
+        uint32_t *rx_channel_max_prio;
+} frescan_init_params_t;
+
+/**
+ * frescan_packet_t - a frescan packet
+ *
+ * This structure is very important and it is used to store a FRESCAN packet.
+ * As we support fragmentation, a FRESCAN packet can be composed of several
+ * CAN frames. This 'frescan_packet_t' structure is used in two main cases:
+ *
+ * 1.- When we are sending data. In this case, the buffer pointers store the
+ *     real data we want to sent and we use a 'buffer_read_pointer' to know
+ *     how many bytes of the buffer we already sent. In 'frame', we store the
+ *     last sent frame (with the corresponding CAN id fields). We will have
+ *     to update the fragmentation fields as long as we send more packets.
+ *     The 'fifo_list' is used to chained frescan packets of the same priority
+ *     or that belong to the same sporadic server. Finally, 'flags', specify
+ *     if we are sending ASYNC or SYNC. If we are sending SYNC the buffer
+ *     pointers are pointing to the buffer sent by the user (zero copying),
+ *     while if we use ASYNC, a copy of the data is done to the buffer.
+ *
+ * 2.- When we are receiving data, we only use 'frame' and 'fifo_list' fields.
+ *     The IRQ handler of the chip allocates a CAN frame and calls to our hook.
+ *     We store the pointer to that frame in 'frame' and we make a chain with
+ *     frames of the same message (using the fragmentation fields). When we
+ *     have all of them, we move the packet list to the corresponding
+ *     receiving channel to wait for the user to perform a receive operation
+ *     when we will copy the data and free both the packets and the frames.
+ *
+ * @flags: to know if the packet is to be sent SYNC or ASYNC, FP or SERVER...
+ * @frame: pointer to the last sent frame or the received frame
+ * @fifo_list: list to put several packets together
+ * @msg_list: list to put packets of the same message together
+ * @buffer_head: pointer to first byte of the buffer that is going to be sent
+ * @buffer_read_pointer: pointer to the part of the buffer being read
+ * @buffer_pending_bytes: bytes waiting to be sent
+ * @timestamp: time when the packet was enqueued (activation time)
+ * @pool_pos: position in the packets pool to know how to free it
+ *
+ * NOTE: the buffers could also be used on the receiving part to support
+ * sequential reads, instead of reading the whole message at once.
+ *
+ */
+
+typedef struct {
+        frescan_flags_t flags;
+        struct can_frame_t *frame;
+        struct list_head fifo_list;
+        struct list_head msg_list;
+        uint8_t *buffer_head;         // only for sending packets
+        uint8_t *buffer_read_pointer; // only for sending packets
+        uint32_t buffer_pending_bytes; // only for sending packets
+        struct timespec timestamp;
+        int pool_pos;
+} frescan_packet_t;
+
+/**
+ * frescan_repl_op_t - a replenishment operation
+ *
+ * @when: when the replenishment operation is programmed at
+ * @amount: number of frames to add to the available budget
+ * @repl_list: to chain the replenishments for a certain sporadic server
+ * @pool_pos: to know how to free it from the replenishment pool
+ */
+
+typedef struct {
+        struct timespec when;
+        frescan_budget_t amount;
+        struct list_head repl_list;
+        int pool_pos;
+} frescan_repl_op_t;
+
+/**
+ * frescan_server_params_t - server parameters
+ *
+ * @budget: the budget in CAN 8-byte frames
+ * @period: the replenishment period for the server
+ * @prio: the priority of the server
+ */
+
+typedef struct {
+        frescan_budget_t budget;
+        struct timespec  period;
+        frescan_prio_t prio;
+} frescan_server_params_t;
+
+/**
+ * frescan_ss_data_t - sporadic server data
+ *
+ * @committed_params: the committed params (C,T,Prio) for the server
+ * @perceived_params: the params perceived by the user (we can lie to him)
+ * @current_priority: the current priority (0=background)
+ * @repl_list: the list of pending replenishment operations
+ * @repl_timer: the timer for the replenishments associated to this server
+ *     NOTE: we could use a single timer for all but for now this is simpler
+ * @act_time: the last activation time for the server
+ * @packet_list: the packets enqueued on this server
+ * @servers_list: the list of servers
+ */
+
+typedef struct {
+        frescan_server_params_t committed_params;
+        frescan_server_params_t perceived_params;
+        frescan_network_t       net;
+        frescan_ss_t            id;
+        frescan_prio_t          current_priority;
+        frescan_budget_t        pending_packets;
+        frescan_repl_op_t       replenishments; // TODO: use struct list_head
+        timer_t                 repl_timer;
+        struct timespec         act_time;
+        frescan_packet_t        packet_list; // TODO: use struct list_head
+        struct list_head        servers_list;
+} frescan_ss_data_t;
+
+/**
+ * frescan_prio_queue_t - priority queue
+ *
+ * FRESCAN priority queues are implemented as an array of one 'fifo_queue' for
+ * each priority. Where the 'fifo_queues' are implemented using the
+ * 'struct list_head fifo_list;' field of each packet structure (Linux lists).
+ *
+ * So far mutual exclusion is achieved by disabling interrupts and
+ * synchronization is done using a semaphore. This is because the queues
+ * are accesed concurrently from user threads and the IRQ handler.
+ *
+ * @net: the network this priority queue belongs to (mainly for locking)
+ * @fifo_queues: an array of packets for each priority where each packet
+ *               is just the head of a fifo_list. The array is allocated
+ *               from the heap, using malloc, at initialization with range
+ *               0..max_prio-1
+ * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
+ * @sem: semaphore used for synchronization
+ */
+
+typedef struct {
+        frescan_network_t net;
+        frescan_packet_t *fifo_queues;
+        uint32_t max_prio;
+        sem_t sem;
+} frescan_prio_queue_t;
+
+/**
+ * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
+ *
+ * @tx_fp_queue: priority queue for the fixed priority packets
+ * @rx_channel_queues: a priority queue for each receiving channel
+ *
+ * TODO: add here the sporadic server queues...
+ */
+
+typedef struct {
+        frescan_prio_queue_t *tx_fp_queue;
+        frescan_prio_queue_t **rx_channel_queues;
+        uint32_t num_rx_channels;
+} frescan_queues_t;
+
+
+// BWRES TYPES
+
+typedef unsigned int frescan_bwres_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
+#define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
+
+/**
+ * frescan_bwres_vres_t - a frescan virtual resource
+ *
+ * @contract: the contract of the virtual resource
+ * @node: the node where the vres belongs to
+ * @ss: the sporadic server identifier
+ * @list: the list of vres. Note that this is the list of all the vres
+ *      in the network instace. As this is a master-slave protocol the master
+ *      knows everything about the contracts of the rest of nodes.
+ */
+
+typedef enum {
+        FRESCAN_BWRES_MC_PERIOD_DEC = 1<<5,
+        FRESCAN_BWRES_MC_PERIOD_INC = 1<<4,
+        FRESCAN_BWRES_MC_BUDGET_DEC = 1<<3,
+        FRESCAN_BWRES_MC_BUDGET_INC = 1<<2,
+        FRESCAN_BWRES_MC_PRIO_DEC   = 1<<1,
+        FRESCAN_BWRES_MC_PRIO_INC   = 1
+} frescan_bwres_mode_change_type_t;
+
+typedef struct {
+        frsh_contract_t    contract;
+        frescan_node_t     node;
+        frescan_ss_t       ss;
+        frsh_sa_vres_id_t  fsa_vres_global_id;
+        struct list_head   list;
+        // mode change variables
+        frsh_sa_time_t old_c;
+        frsh_sa_time_t old_t;
+        frsh_sa_prio_t old_p;
+        frescan_bwres_mode_change_type_t mode_change_type;
+        struct list_head                 mode_change_list;
+} frescan_bwres_vres_t;
+
+/**
+ * frescan_bwres_request_data_t
+ *
+ * This are the data contained in a request to perform the negotiation of
+ * contracts.
+ *
+ * @type: indicates the type of the request
+ * @contract: a contract to (re)negotiate
+ * @contract_ref: a pointer to the contract to (re)negotiate (optimization)
+ * @ss: the local sporadic server ID
+ * @request_node: the node that performed the request
+ * @req: the request id of the SLAVE to identify the request in the reply
+ * @return_value: the value returned in a Reply (accepted or not)
+ * @final_values: the values for the ss after the negotiation
+ * @net: the network instance where this request belongs to
+ * @robj: a reply object to wait until a negotiation is completed
+ *
+ */
+
+typedef uint16_t frescan_bwres_request_id_t; /* 0 .. MX_REQUESTS */
+
+typedef enum {
+        FRESCAN_BWRES_REQ_GN         =  0,  // group negotiation
+        FRESCAN_BWRES_REP_GN         =  1,  // negotiation reply
+        FRESCAN_BWRES_REQ_MC         =  2,  // mode change
+        FRESCAN_BWRES_REQ_RES        =  3,  // reservation negotiation
+        FRESCAN_BWRES_REQ_RES_GET    =  4,  // reservation get values
+        FRESCAN_BWRES_REP_RES_GET    =  5,  // reservation get values reply
+        FRESCAN_BWRES_REQ_RES_SET    =  6,  // reservation set values
+        FRESCAN_BWRES_REQ_RES_COMMIT =  7,  // reservation commit
+        FRESCAN_BWRES_REQ_RES_CANCEL =  8,  // reservation cancel
+} frescan_bwres_request_type_t;
+
+typedef enum {
+        FRESCAN_BWRES_REQ_ACCEPTED      =  0,  // negotiation accepted
+        FRESCAN_BWRES_REQ_NOT_ACCEPTED  =  1,  // negotiation not accepted
+        FRESCAN_BWRES_REQ_ERROR         =  2,  // there was an error
+} frescan_bwres_request_retval_t;
+
+typedef struct {
+        frescan_network_t               net;
+        frescan_bwres_request_type_t    type;
+        frescan_bwres_request_id_t      req;
+        frescan_node_t                  request_node;
+        frescan_bwres_request_retval_t  return_value;
+        frescan_bwres_robj_id_t         robj;
+        // contracts and ss groups
+        frsh_contracts_group_t  *contracts_to_neg;
+        frsh_contracts_group_t  *contracts_to_reneg;
+        frescan_ss_group_t      *ss_to_reneg;
+        frescan_ss_group_t      *ss_to_cancel;
+        frescan_ss_group_t      *ss_new;
+        // contracts and ss groups data (to store the info at master node)
+        frsh_contracts_group_t  contracts_to_neg_data;
+        frsh_contracts_group_t  contracts_to_reneg_data;
+        frescan_ss_group_t      ss_to_reneg_data;
+        frescan_ss_group_t      ss_to_cancel_data;
+        frescan_ss_group_t      ss_new_data;
+        // for FRESCAN_BWRES_REQ_MC
+        frescan_bwres_mode_change_type_t mode_change_type;
+} frescan_bwres_request_data_t;
+
+/**
+ * frescan_bwres_sa_scenario_t - the scheduling analysis scenario
+ */
+
+typedef struct {
+        frescan_prio_t    max_prio;
+        frescan_prio_t    min_prio;
+} frescan_bwres_sa_init_params_t;
+
+typedef struct {
+        frescan_bwres_sa_init_params_t init_params;
+        frescan_bwres_vres_t vres_pool[FRESCAN_MX_NODES][FRESCAN_MX_IDS];
+        frescan_bwres_vres_t vres_head; // TODO: use struct list_head
+        freelist_t fsa_vres_global_id_freelist;
+        frsh_sa_scenario_t fsa_scenario;
+        frsh_contracts_group_t backup_contracts_to_reneg;
+        frsh_contracts_group_t backup_contracts_to_cancel;
+} frescan_bwres_sa_scenario_t;
+
+/**
+ * frescan_network_data_t - data for each network instance
+ *
+ * @local_node: the local node id for that network. The implementation does not
+ * support several interfaces for the same network.
+ * @fd: file descriptor associated to /dev/canXX
+ * @repl_thread_id: replenishment thread id
+ * @manager_thread_id: manager thread id
+ * @acceptor_thread_id: acceptor thread id
+ * @neg_messages_ss_id: sporadic server for negotiation messages
+ * @queues: the queues of this network instance
+ * @last_packet: pointer to the last packet from which a frame was inserted
+ *               in the chip and its transmission is not complete.
+ * @last_packet_prio: prio of the packet in the buffer
+ * @id_queues: queues to store received packets while the whole message is
+ *             not complete (fragmentation). (id = 0 .. FRESCAN_MX_IDS - 1)
+ * @id_fp_queues: the same as id_queues but for fp messages, which have
+ *                id=FRESCAN_MX_IDS and are distinguised through their
+ *                priorities.
+ * @scenario: the scheduling analysis scenario for the network
+ * @mode_change_list: list of sa_vres that have changes to commit
+ * @mode_change_type: what type of changes are to commit
+ *
+ * the implementation can handle several FRESCAN networks at the same time
+ * in the same node, so we need a place to store its internal data. The data
+ * is allocated as an array where the index is the MINOR number (which also
+ * identifies the /dev/canx device for that network)
+ */
+
+typedef struct {
+        FRESCAN_MLOCK_T lock;
+        frescan_node_t local_node;
+        int fd;
+        fosa_thread_id_t repl_thread_id;
+        frescan_packet_t *last_packet;
+        frescan_prio_t last_packet_prio;
+        frescan_queues_t queues;
+        frescan_packet_t *id_queues[FRESCAN_MX_NODES][FRESCAN_MX_IDS];      // TODO: alloc at init
+        frescan_packet_t *id_fp_queues[FRESCAN_MX_NODES][FRESCAN_MX_PRIOS]; // TODO: alloc at init
+        frescan_ss_data_t ss_data[FRESCAN_MX_IDS];
+        freelist_t ss_id_freelist;
+        frescan_ss_data_t ss_active_head; // TODO: use struct list_head
+        // BWRES data
+        fosa_thread_id_t manager_thread_id;
+        fosa_thread_id_t acceptor_thread_id;
+        frescan_ss_t neg_messages_ss_id;
+        frescan_bwres_sa_scenario_t scenario;
+        struct list_head mode_change_list[FRESCAN_MX_NODES];
+        frescan_bwres_mode_change_type_t mode_change_type[FRESCAN_MX_NODES];
+} frescan_network_data_t;
+
+#endif // _FRESCAN_TYPES_H_