*
* @license
*
- * See MaRTE OS 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.
+ * -----------------------------------------------------------------------
*
*/
#include <unistd.h> // ioctl
#include <stdlib.h> // malloc
#include <string.h> // memcpy
+#include <assert.h>
#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
#include "frescan_hw_buffer.h" // frescan_hw_buffer_update
-#include "frescan_reply_objects.h" // frescan_replyobjects_init
-#include "frescan_servers_replenishments.h" // frescan_replenishments_xxx
#include "frescan_packets.h"
static int frescan_hook_frame_recv (const struct can_chip_t *chip,
fd = open (can_path, O_RDWR);
if (fd == -1) {
- ERROR ("could not open /dev/can%u\n", params->net);
+ FRESCAN_ERROR ("could not open /dev/can%u\n", params->net);
+ FRESCAN_ERROR ("hint: check driver or card installation\n");
return -1;
}
ret = ioctl(fd, CAN_IOCTL_SET_FILTERS, &ioctl_filters);
if (ret == -1) {
- ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n",
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n",
params->net);
return -1;
}
ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent);
if (ret == -1) {
- ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n",
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n",
params->net);
return -1;
}
ret = ioctl(fd, CAN_IOCTL_SET_RX_HOOK, frescan_hook_frame_recv);
if (ret == -1) {
- ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n",
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n",
params->net);
return -1;
}
ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted);
if (ret == -1) {
- ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n",
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n",
params->net);
return -1;
}
ret = frescan_data_init(fd, params);
if (ret != 0) {
- ERROR("could not initialize the global data\n");
+ FRESCAN_ERROR("could not initialize the global data\n");
return -1;
}
ret = frescan_packets_init();
if (ret != 0) {
- ERROR("could not initialize the packets pool\n");
+ FRESCAN_ERROR("could not initialize the packets pool\n");
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) {
- ERROR("could not initialize the queues\n");
+ FRESCAN_ERROR("could not initialize the queues\n");
return -1;
}
ret = frescan_servers_init(params->net);
if (ret != 0) {
- ERROR("could not initialize the servers\n");
- return -1;
- }
-
- ret = frescan_replenishments_init(params->net);
- if (ret != 0) {
- ERROR("could not initialize the replenishments\n");
- return -1;
- }
-
- ret = frescan_replyobjects_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
- if (ret != 0) {
- ERROR("could not initialize the reply objects\n");
+ FRESCAN_ERROR("could not initialize the servers\n");
return -1;
}
"checking arguments (msg size=%d)\n", size);
if ((params == NULL) || (msg == NULL) || (size == 0)) {
- ERROR("arguments are not ok\n");
+ FRESCAN_ERROR("arguments are not ok\n");
return -1;
}
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) {
- ERROR("could not allocate packet\n");
+ FRESCAN_ERROR("could not allocate packet\n");
return -1;
}
packet->flags = params->flags; // set the flags (to remember them)
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) {
- ERROR("could not allocate frame\n");
+ FRESCAN_ERROR("could not allocate frame\n");
return -1;
}
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,
// NOTE: instead of this we could use a chain of frames but
// i think it would be inefficient since each one can only
// hold 8 user bytes and we need to write its headers.
- packet->buffer_head = (uint8_t *)malloc(size*sizeof(uint8_t));
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ packet->buffer_head = (uint8_t *)malloc(size*sizeof(uint8_t)); // TODO: FREE IT!!!
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
memcpy(packet->buffer_head, msg, size);
} else {
packet->buffer_head = (uint8_t *)msg;
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) {
- ERROR("could not enqueue the packet\n");
+ 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) {
- ERROR("could not enqueue the packet\n");
+ FRESCAN_ERROR("could not enqueue the packet\n");
return -1;
}
}
- 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) {
- ERROR("could not update hw buffer\n");
+ FRESCAN_ERROR("could not update hw buffer\n");
return -1;
}
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);
if (ret != 0) {
- ERROR ("could not dequeue packet\n");
+ FRESCAN_ERROR ("could not dequeue packet\n");
return -1;
}
*recv_bytes = 0;
return 0;
} else {
- ERROR ("blocking true, and packet = null\n");
+ FRESCAN_ERROR ("blocking true, and packet = null\n");
return -1;
}
}
*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
ret = can_framespool_free(packet->frame);
if (ret != 0) {
- ERROR("could not free frame\n");
+ FRESCAN_ERROR("could not free frame\n");
return -1;
}
ret = frescan_packets_free(packet);
if (ret != 0) {
- ERROR("could not free packet\n");
+ FRESCAN_ERROR("could not free packet\n");
return -1;
}
}
ret = frescan_packets_free(head);
- FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
if (ret != 0) {
- ERROR("could not free head packet\n");
+ FRESCAN_ERROR("could not free head packet\n");
return -1;
}
DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
"prio:%u dest:%u src:%u chan:%u id:%u flag:%u\n",
prio, dest, src, channel, frag_id, frag_flag);
-
DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
"enqueue the packet in ID queue\n");
+
packet = frescan_packets_alloc();
+ if (packet == NULL) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ return -1;
+ }
+
packet->frame = frame;
- if (frag_id == 0) {
- head = the_networks[net].id_fp_queues[prio];
+ if (frag_id == FRESCAN_MX_IDS) {
+ head = frescan_data[net].id_fp_queues[src][prio];
} else {
- head = the_networks[net].id_queues[frag_id];
+ head = frescan_data[net].id_queues[src][frag_id];
}
if (head == NULL) {
FRESCAN_FRAG_ENABLE_DEBUG,
"allocate head for id=%u\n", frag_id);
head = frescan_packets_alloc();
+ if (head == NULL) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ return -1;
+ }
+
INIT_LIST_HEAD(&head->msg_list);
- if (frag_id == 0) {
- the_networks[net].id_fp_queues[prio] = head;
+ if (frag_id == FRESCAN_MX_IDS) {
+ frescan_data[net].id_fp_queues[src][prio] = head;
} else {
- the_networks[net].id_queues[frag_id] = head;
+ frescan_data[net].id_queues[src][frag_id] = head;
}
}
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) {
- ERROR("could not enqueue message in channel queue\n");
+ FRESCAN_ERROR("could not enqueue message in channel queue\n");
return -1;
}
- if (frag_id == 0) {
- the_networks[net].id_fp_queues[prio] = NULL;
+ if (frag_id == FRESCAN_MX_IDS) {
+ frescan_data[net].id_fp_queues[src][prio] = NULL;
} else {
- the_networks[net].id_queues[frag_id] = NULL;
+ frescan_data[net].id_queues[src][frag_id] = NULL;
}
} else {
frescan_prio_t prio;
frescan_ss_t id;
- packet = the_networks[chip->minor].last_packet;
+ packet = frescan_data[chip->minor].last_packet;
+ assert(packet != NULL);
id = frescan_id_get_field(packet->frame->id,
FRESCAN_FIELD_FRAG_ID);
DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
"calling frame_sent + program repl for id:%u\n", id);
- ret = frescan_replenishment_program(chip->minor, id);
- if (ret != 0) {
- ERROR("could not program replenishment\n");
- return -1;
- }
-
- ret = frescan_servers_frame_sent(chip->minor, id);
+ ret = frescan_servers_frame_sent(chip->minor, id, packet);
if (ret != 0) {
- ERROR("could not let the server a frame was sent\n");
+ FRESCAN_ERROR("could not let the server a frame was sent\n");
return -1;
}
}
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) {
- ERROR("could not requeue the packet\n");
+ FRESCAN_ERROR("could not requeue the packet packet:%p flags:0x%X\n", packet, packet->flags);
return -1;
}
} else if (packet->flags & FRESCAN_SS) {
"requeue server %u packet\n", id);
ret = frescan_servers_requeue(chip->minor, id, packet);
if (ret != 0) {
- ERROR("could not requeue the packet\n");
+ FRESCAN_ERROR("could not requeue the packet\n");
return -1;
}
} else {
- ERROR("flags are not correct\n");
+ FRESCAN_ERROR("flags are not correct\n");
return -1;
}
} else {
ret = can_framespool_free(packet->frame);
if (ret != 0) {
- ERROR ("could not free the frame\n");
+ FRESCAN_ERROR ("could not free the frame\n");
return ret;
}
ret = frescan_packets_free(packet);
if (ret != 0) {
- ERROR ("could not free the packet\n");
+ FRESCAN_ERROR ("could not free the packet\n");
return ret;
}
// 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) {
- ERROR("could not update hw buffer\n");
+ FRESCAN_ERROR("could not update hw buffer\n");
return -1;
}
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);
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) {
- ERROR("could not requeue the packet\n");
+ FRESCAN_ERROR("could not requeue the packet\n");
return -1;
}
} else if (packet->flags & FRESCAN_SS) {
ret = frescan_servers_requeue(chip->minor, id, packet);
if (ret != 0) {
- ERROR("could not requeue the packet\n");
+ FRESCAN_ERROR("could not requeue the packet\n");
return -1;
}
} else {
- ERROR("flags are not correct\n");
+ FRESCAN_ERROR("flags are not correct\n");
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) {
- ERROR("could not update hw buffer\n");
+ FRESCAN_ERROR("could not update hw buffer\n");
return -1;
}