]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan.c
changes to use the FRSH FSA module to do the analysis and spare capacity. TODO: finis...
[frescor/fna.git] / src_frescan / frescan.c
1 /*!
2  * @file frescan.c
3  *
4  * @brief the FRESCAN protocol
5  *
6  * @version 0.01
7  *
8  * @date 20-Feb-2008
9  *
10  * @author
11  *      Daniel Sangorrin
12  *
13  * @comments
14  *
15  * This file contains the implementation of the FRESCAN protocol
16  *
17  * @license
18  *
19  * -----------------------------------------------------------------------
20  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
21  *
22  *    Universidad de Cantabria,              SPAIN
23  *    University of York,                    UK
24  *    Scuola Superiore Sant'Anna,            ITALY
25  *    Kaiserslautern University,             GERMANY
26  *    Univ. Politécnica  Valencia,           SPAIN
27  *    Czech Technical University in Prague,  CZECH REPUBLIC
28  *    ENEA                                   SWEDEN
29  *    Thales Communication S.A.              FRANCE
30  *    Visual Tools S.A.                      SPAIN
31  *    Rapita Systems Ltd                     UK
32  *    Evidence                               ITALY
33  *
34  *    See http://www.frescor.org for a link to partners' websites
35  *
36  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
37  *        in part by the European Union Sixth Framework Programme
38  *        The European Union is not liable of any use that may be
39  *        made of this code.
40  *
41  *  This file is part of FRESCAN
42  *
43  *  FRESCAN is free software; you can  redistribute it and/or  modify
44  *  it under the terms of  the GNU General Public License as published by
45  *  the Free Software Foundation;  either  version 2, or (at  your option)
46  *  any later version.
47  *
48  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
49  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
50  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
51  *  General Public License for more details.
52  *
53  *  You should have  received a  copy of  the  GNU  General Public License
54  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
55  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
56  *  02111-1307, USA.
57  *
58  * As a special exception, including FRESCAN header files in a file,
59  * instantiating FRESCAN generics or templates, or linking other files
60  * with FRESCAN objects to produce an executable application, does not
61  * by itself cause the resulting executable application to be covered
62  * by the GNU General Public License. This exception does not
63  * however invalidate any other reasons why the executable file might be
64  * covered by the GNU Public License.
65  * -----------------------------------------------------------------------
66  *
67  */
68
69 #include <sys/marte_configuration_parameters.h> // PATH_MX
70 #include <fcntl.h>  // open
71 #include <unistd.h> // ioctl
72 #include <stdlib.h> // malloc
73 #include <string.h> // memcpy
74
75 #include <drivers/can.h>       // can_chip_t, can_frame_t
76 #include "frescan.h"           // frescan_init_params_t, frescan_send_params_t
77 #include "frescan_queues.h"    // init, enqueue, requeue
78 #include "frescan_data.h"      // init, the_networks
79 #include "frescan_servers.h"   // init, frame_sent
80 #include "frescan_debug.h"     // DEBUG
81 #include "frescan_id.h"        // frescan_id_set_field, frescan_id_get_field
82 #include "frescan_hw_buffer.h" // frescan_hw_buffer_update
83 #include "frescan_packets.h"
84
85 static int frescan_hook_frame_recv (const struct can_chip_t *chip,
86                                     struct can_frame_t *frame);
87
88 static int frescan_hook_frame_sent(const struct can_chip_t *chip);
89
90 static int frescan_hook_frame_aborted(const struct can_chip_t *chip);
91
92 /**
93  * frescan_init - initializes the network and the internal structures
94  *
95  * @params: the initialization parameters
96  *
97  * This function initializes the frescan network protocol.
98  *
99  * First it opens and configures the corresponding CAN chip device. For the
100  * CAN chip acceptance filter we use a dual filter configuration. The first
101  * filter is to set my local address address and the second one is to allow
102  * broadcast messages.
103  *
104  * Once the CAN chip is configured we call the initialization functions of
105  * the rest of modules of frescan.
106  *
107  */
108
109 int frescan_init(frescan_init_params_t *params)
110 {
111         int fd, ret;
112         char can_path[PATH_MX];
113         struct ioctl_filters_t ioctl_filters;
114         struct can_filter_t filters[2];
115
116         snprintf(can_path, PATH_MX, "/dev/can%u", params->net);
117
118         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "open %s\n", can_path);
119
120         fd = open (can_path, O_RDWR);
121         if (fd == -1) {
122                 FRESCAN_ERROR ("could not open /dev/can%u\n", params->net);
123                 return -1;
124         }
125
126         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set acceptance filters\n");
127
128         filters[0].mask = 0xFFFFFFFF;
129         frescan_id_set_field(&filters[0].mask, FRESCAN_FIELD_DEST,0x00);
130         filters[0].code = 0;
131         frescan_id_set_field(&filters[0].code, FRESCAN_FIELD_DEST,params->node);
132
133         filters[1].mask = filters[0].mask;
134         filters[1].code = 0;
135         frescan_id_set_field(&filters[1].code,
136                              FRESCAN_FIELD_DEST,
137                              FRESCAN_BROADCAST_ADDR);
138
139         ioctl_filters.filters = filters;
140         ioctl_filters.len = 2;
141
142         ret = ioctl(fd, CAN_IOCTL_SET_FILTERS, &ioctl_filters);
143         if (ret == -1) {
144                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n",
145                        params->net);
146                 return -1;
147         }
148
149         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set tx, rx, abort hooks\n");
150
151         ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent);
152         if (ret == -1) {
153                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n",
154                        params->net);
155                 return -1;
156         }
157
158         ret = ioctl(fd, CAN_IOCTL_SET_RX_HOOK, frescan_hook_frame_recv);
159         if (ret == -1) {
160                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n",
161                        params->net);
162                 return -1;
163         }
164
165         ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted);
166         if (ret == -1) {
167                 FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n",
168                        params->net);
169                 return -1;
170         }
171
172         DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "init the rest of modules\n");
173
174         ret = frescan_data_init(fd, params);
175         if (ret != 0) {
176                 FRESCAN_ERROR("could not initialize the global data\n");
177                 return -1;
178         }
179
180         ret = frescan_packets_init();
181         if (ret != 0) {
182                 FRESCAN_ERROR("could not initialize the packets pool\n");
183                 return -1;
184         }
185
186         ret = frescan_queues_init(&the_networks[params->net].queues, params);
187         if (ret != 0) {
188                 FRESCAN_ERROR("could not initialize the queues\n");
189                 return -1;
190         }
191
192         ret = frescan_servers_init(params->net);
193         if (ret != 0) {
194                 FRESCAN_ERROR("could not initialize the servers\n");
195                 return -1;
196         }
197
198         return 0;
199 }
200
201 /**
202  * frescan_send - send a message
203  *
204  * @params: the parameters needed by the protocol to send the message
205  * @msg: the message buffer
206  * @size: the size of the message
207  *
208  * This is one of the main functions of the protocol and it provides the
209  * means to send a message through the protocol stack.
210  */
211
212 int frescan_send(const frescan_send_params_t *params,
213                  const uint8_t *msg,
214                  const size_t size)
215 {
216         int ret;
217         frescan_packet_t *packet;
218         frescan_prio_queue_t *pqueue;
219
220         DEBUG(FRESCAN_SEND_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
221               "checking arguments (msg size=%d)\n", size);
222
223         if ((params == NULL) || (msg == NULL) || (size == 0)) {
224                 FRESCAN_ERROR("arguments are not ok\n");
225                 return -1;
226         }
227
228         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a packet\n");
229
230         FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
231         packet = frescan_packets_alloc();
232         FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
233
234         if (packet == NULL) {
235                 FRESCAN_ERROR("could not allocate packet\n");
236                 return -1;
237         }
238         packet->flags = params->flags; // set the flags (to remember them)
239
240         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a frame\n");
241
242         FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
243         packet->frame = can_framespool_alloc();
244         FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
245
246         if (packet->frame == NULL) {
247                 FRESCAN_ERROR("could not allocate frame\n");
248                 return -1;
249         }
250
251         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set values for the frame header\n");
252         packet->frame->is_extended_format = true;
253         packet->frame->is_rtr = false;
254
255         if (params->flags & FRESCAN_FP) {
256                 // NOTE: frag id for fp is: FRESCAN_MX_IDS, so the servers can
257                 // have IDs in the range (0 .. FRESCAN_MX_IDS-1)
258                 frescan_id_set_field(&packet->frame->id,
259                                      FRESCAN_FIELD_FRAG_ID,
260                                      (uint32_t)FRESCAN_MX_IDS);
261
262                 frescan_id_set_field(&packet->frame->id,
263                                       FRESCAN_FIELD_PRIO,
264                                       (uint32_t)params->prio);
265         } else {
266                 // NOTE: the priority is put when the packet is dequeued
267                 // and it is the priority of th server
268                 frescan_id_set_field(&packet->frame->id,
269                                      FRESCAN_FIELD_FRAG_ID,
270                                      (uint32_t)params->ss);
271         }
272
273         frescan_id_set_field(&packet->frame->id,
274                              FRESCAN_FIELD_DEST,
275                              (uint32_t)params->to);
276
277         frescan_id_set_field(&packet->frame->id,
278                              FRESCAN_FIELD_SRC,
279                              (uint32_t)the_networks[params->net].local_node);
280
281         frescan_id_set_field(&packet->frame->id,
282                               FRESCAN_FIELD_CHAN,
283                               (uint32_t)params->channel);
284
285         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set the packet data bytes\n");
286         if (params->flags & FRESCAN_ASYNC) {
287                 // allocate a buffer and copy the data
288                 // NOTE: instead of this we could use a chain of frames but
289                 // i think it would be inefficient since each one can only
290                 // hold 8 user bytes and we need to write its headers.
291                 packet->buffer_head = (uint8_t *)malloc(size*sizeof(uint8_t));
292                 memcpy(packet->buffer_head, msg, size);
293         } else {
294                 packet->buffer_head = (uint8_t *)msg;
295         }
296
297         packet->buffer_read_pointer = packet->buffer_head;
298         packet->buffer_pending_bytes = size;
299         pqueue = the_networks[params->net].queues.tx_fp_queue;
300
301         DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "enqueue the packet\n");
302         if (packet->flags & FRESCAN_FP) {
303                 FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
304                 ret = frescan_pqueue_enqueue(pqueue, packet, params->prio);
305                 FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
306
307                 if (ret != 0) {
308                         FRESCAN_ERROR("could not enqueue the packet\n");
309                         return -1;
310                 }
311         } else {
312                 FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
313                 ret = frescan_servers_enqueue(params->net, params->ss, packet);
314                 FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
315
316                 if (ret != 0) {
317                         FRESCAN_ERROR("could not enqueue the packet\n");
318                         return -1;
319                 }
320         }
321
322         FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
323         ret = frescan_hw_buffer_update(params->net);
324         FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
325
326         if (ret != 0) {
327                 FRESCAN_ERROR("could not update hw buffer\n");
328                 return -1;
329         }
330
331         return 0;
332 }
333
334 /**
335  * frescan_recv - receive a message
336  *
337  * @params: the parameters needed by the protocol to receive the message
338  * @msg: the message buffer
339  * @size: the size of the message buffer
340  * @recv_bytes: the number of bytes received
341  * @from: the node that sent the message
342  * @prio: the priority of the message
343  *
344  * This is one of the main functions of the protocol and it provides the
345  * means to receive a message through the protocol stack.
346  */
347
348 int frescan_recv(const frescan_recv_params_t *params,
349                  uint8_t *msg,
350                  const size_t size,
351                  size_t *recv_bytes,
352                  frescan_node_t *from,
353                  frescan_prio_t *prio)
354 {
355         int ret;
356         frescan_prio_queue_t *pqueue;
357         bool blocking;
358         frescan_packet_t *head, *packet;
359
360         if (params->flags & FRESCAN_SYNC) {
361                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
362                       "receive a packet in blocking mode\n");
363                 blocking = true;
364         } else {
365                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
366                       "receive a packet in non-blocking mode\n");
367                 blocking = false;
368         }
369
370         pqueue = the_networks[params->net].queues.rx_channel_queues
371                                                              [params->channel];
372
373         ret = frescan_pqueue_dequeue(pqueue, &head, prio, blocking);
374         if (ret != 0) {
375                 FRESCAN_ERROR ("could not dequeue packet\n");
376                 return -1;
377         }
378
379         if (head == NULL) {
380                 if (blocking == false) {
381                         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
382                               "blocking false, no packets\n");
383                         *recv_bytes = 0;
384                         return 0;
385                 } else {
386                         FRESCAN_ERROR ("blocking true, and packet = null\n");
387                         return -1;
388                 }
389         }
390
391         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
392               "traverse the list of packets for this message\n");
393
394         *recv_bytes = 0;
395
396         FRESCAN_ACQUIRE_LOCK(&the_networks[params->net].lock);
397
398         list_for_each_entry(packet, &head->msg_list, msg_list) {
399                 // TODO: memory checks, delete the packets
400                 memcpy(msg + *recv_bytes,
401                        packet->frame->data,
402                        packet->frame->dlc);
403                 *recv_bytes += packet->frame->dlc;
404
405                 *from = (frescan_node_t)frescan_id_get_field(packet->frame->id,
406                                                              FRESCAN_FIELD_SRC);
407                 DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
408                       "ID Packet, dlc: %u, frame pool pos: %u, from:%u\n",
409                       packet->frame->dlc, packet->frame->pool_pos, *from);
410
411                 ret = can_framespool_free(packet->frame);
412                 if (ret != 0) {
413                         FRESCAN_ERROR("could not free frame\n");
414                         return -1;
415                 }
416
417                 ret = frescan_packets_free(packet);
418                 if (ret != 0) {
419                         FRESCAN_ERROR("could not free packet\n");
420                         return -1;
421                 }
422         }
423
424         ret = frescan_packets_free(head);
425
426         FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock);
427
428         if (ret != 0) {
429                 FRESCAN_ERROR("could not free head packet\n");
430                 return -1;
431         }
432
433         DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
434               "received bytes: %u\n", *recv_bytes);
435
436         return 0;
437 }
438
439
440 /**
441  * frescan_hook_frame_recv - frame received hook
442  *
443  * This function will be called by the CAN driver's IRQ handler when a frame
444  * is received so we can store it in an appropiate queue.
445  *
446  * NOTE: in the future it could consist simply of signaling a semaphore to
447  * let a bottom half thread do the hard work.
448  */
449
450
451 static int frescan_hook_frame_recv (const struct can_chip_t *chip,
452                                     struct can_frame_t *frame)
453 {
454         int i, ret;
455         uint32_t prio, dest, src, channel, frag_id, frag_flag;
456         frescan_packet_t *packet, *head;
457         frescan_prio_queue_t *pqueue;
458         int net;
459
460         net = chip->minor;
461
462         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG, "received a frame, net=%d\n", net);
463         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
464               "%s %s, id=0x%X, dlc=%u, pool:%u\n",
465               (frame->is_extended_format) ? "Ext" : "Stnd",
466               (frame->is_rtr) ? "RTR Frame" : "DATA Frame",
467               frame->id,
468               frame->dlc,
469               frame->pool_pos);
470
471         for (i=0; i<frame->dlc; i++) {
472                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
473                       "data[%d] = 0x%X;\n", i, frame->data[i]);
474         }
475
476         prio      = frescan_id_get_field(frame->id, FRESCAN_FIELD_PRIO);
477         dest      = frescan_id_get_field(frame->id, FRESCAN_FIELD_DEST);
478         src       = frescan_id_get_field(frame->id, FRESCAN_FIELD_SRC);
479         channel   = frescan_id_get_field(frame->id, FRESCAN_FIELD_CHAN);
480         frag_id   = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_ID);
481         frag_flag = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_FLAG);
482
483         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
484               "prio:%u dest:%u src:%u chan:%u id:%u flag:%u\n",
485               prio, dest, src, channel, frag_id, frag_flag);
486
487         DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
488               "enqueue the packet in ID queue\n");
489         packet = frescan_packets_alloc();
490         packet->frame = frame;
491
492         if (frag_id == FRESCAN_MX_IDS) {
493                 head = the_networks[net].id_fp_queues[src][prio];
494         } else {
495                 head = the_networks[net].id_queues[src][frag_id];
496         }
497
498         if (head == NULL) {
499                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
500                                 FRESCAN_FRAG_ENABLE_DEBUG,
501                 "allocate head for id=%u\n", frag_id);
502                 head = frescan_packets_alloc();
503                 INIT_LIST_HEAD(&head->msg_list);
504
505                 if (frag_id == FRESCAN_MX_IDS) {
506                         the_networks[net].id_fp_queues[src][prio] = head;
507                 } else {
508                         the_networks[net].id_queues[src][frag_id] = head;
509                 }
510         }
511
512         list_add_tail(&packet->msg_list, &head->msg_list);
513
514         if (frag_flag == false) {
515                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
516                                 FRESCAN_FRAG_ENABLE_DEBUG,
517                 "message complete, move msg to channel\n");
518                 // TODO: select the highest priority??
519                 pqueue = the_networks[net].queues.rx_channel_queues[channel];
520                 ret = frescan_pqueue_enqueue(pqueue, head, prio);
521                 if (ret != 0) {
522                         FRESCAN_ERROR("could not enqueue message in channel queue\n");
523                         return -1;
524                 }
525
526                 if (frag_id == FRESCAN_MX_IDS) {
527                         the_networks[net].id_fp_queues[src][prio] = NULL;
528                 } else {
529                         the_networks[net].id_queues[src][frag_id] = NULL;
530                 }
531
532         } else {
533                 DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
534                                 FRESCAN_FRAG_ENABLE_DEBUG,
535                 "message not complete, wait for more fragments\n");
536         }
537
538         // NOTE: don't forget to free the frame and the packet when it is
539         // read by the user application
540
541         return 0;
542 };
543
544 /**
545  * frescan_hook_frame_sent - frame sent hook
546  *
547  * This function will be called by the CAN driver's IRQ handler when a frame
548  * is sent through the CAN bus so we can enqueue another one, signal a
549  * semaphore, consume sporadic server capacity...
550  */
551
552 static int frescan_hook_frame_sent(const struct can_chip_t *chip)
553 {
554         int ret;
555         frescan_packet_t *packet;
556         frescan_prio_queue_t *pqueue;
557         frescan_prio_t prio;
558         frescan_ss_t id;
559
560         packet = the_networks[chip->minor].last_packet;
561
562         id = frescan_id_get_field(packet->frame->id,
563                                   FRESCAN_FIELD_FRAG_ID);
564
565         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
566               "frame sent, minor:%u flags:0x%X frag_id:0x%X\n",
567               chip->minor, packet->flags, id);
568
569         if (packet->flags & FRESCAN_SS) {
570                 DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
571                       "calling frame_sent + program repl for id:%u\n", id);
572
573                 ret = frescan_servers_frame_sent(chip->minor, id, packet);
574                 if (ret != 0) {
575                         FRESCAN_ERROR("could not let the server a frame was sent\n");
576                         return -1;
577                 }
578         }
579
580         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
581               "last packet buffer_pending_bytes=%u\n",
582               packet->buffer_pending_bytes);
583
584         if (packet->buffer_pending_bytes > 0) {
585                 if (packet->flags & FRESCAN_FP) {
586                         prio = frescan_id_get_field(packet->frame->id,
587                                         FRESCAN_FIELD_PRIO);
588
589                         DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
590                               "requeue fp packet, prio:%u\n", prio);
591
592                         pqueue = the_networks[chip->minor].queues.tx_fp_queue;
593                         ret = frescan_pqueue_requeue(pqueue, packet, prio);
594                         if (ret != 0) {
595                                 FRESCAN_ERROR("could not requeue the packet\n");
596                                 return -1;
597                         }
598                 } else if (packet->flags & FRESCAN_SS) {
599                         DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
600                               "requeue server %u packet\n", id);
601                         ret = frescan_servers_requeue(chip->minor, id, packet);
602                         if (ret != 0) {
603                                 FRESCAN_ERROR("could not requeue the packet\n");
604                                 return -1;
605                         }
606                 } else {
607                         FRESCAN_ERROR("flags are not correct\n");
608                         return -1;
609                 }
610         } else {
611                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
612                       "all packet fragmets sent, freeing the packet\n");
613
614                 ret = can_framespool_free(packet->frame);
615                 if (ret != 0)  {
616                         FRESCAN_ERROR ("could not free the frame\n");
617                         return ret;
618                 }
619
620                 ret = frescan_packets_free(packet);
621                 if (ret != 0)  {
622                         FRESCAN_ERROR ("could not free the packet\n");
623                         return ret;
624                 }
625
626                 // TODO: signal semaphore for send_sync
627         }
628
629         the_networks[chip->minor].last_packet = NULL;
630
631         ret = frescan_hw_buffer_update(chip->minor);
632         if (ret != 0) {
633                 FRESCAN_ERROR("could not update hw buffer\n");
634                 return -1;
635         }
636
637         return 0;
638 };
639
640 /**
641  * frescan_hook_frame_aborted - frame frame aborted hook
642  *
643  * This function will be called by the CAN driver's IRQ handler when a frame
644  * is aborted (because another frame with higher priority is waiting). We
645  * have to requeue the frame and update the buffer.
646  */
647
648 static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
649 {
650         int ret;
651         frescan_packet_t *packet;
652         frescan_prio_queue_t *pqueue;
653         frescan_prio_t prio;
654         frescan_ss_t id;
655
656         packet = the_networks[chip->minor].last_packet;
657
658         id = frescan_id_get_field(packet->frame->id,
659                                   FRESCAN_FIELD_FRAG_ID);
660
661         DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
662               "frame aborted, minor:%u flags:0x%X frag_id:0x%X\n",
663               chip->minor, packet->flags, id);
664
665         if (packet->flags & FRESCAN_FP) {
666                 prio = frescan_id_get_field(packet->frame->id,
667                                             FRESCAN_FIELD_PRIO);
668
669                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
670                       "requeue fp packet, prio:%u\n", prio);
671
672                 pqueue = the_networks[chip->minor].queues.tx_fp_queue;
673                 ret = frescan_pqueue_requeue(pqueue, packet, prio);
674                 if (ret != 0) {
675                         FRESCAN_ERROR("could not requeue the packet\n");
676                         return -1;
677                 }
678         } else if (packet->flags & FRESCAN_SS) {
679                 DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
680                       "requeue server %u packet\n", id);
681
682                 ret = frescan_servers_requeue(chip->minor, id, packet);
683                 if (ret != 0) {
684                         FRESCAN_ERROR("could not requeue the packet\n");
685                         return -1;
686                 }
687         } else {
688                 FRESCAN_ERROR("flags are not correct\n");
689                 return -1;
690         }
691
692         the_networks[chip->minor].last_packet = NULL;
693
694         ret = frescan_hw_buffer_update(chip->minor);
695         if (ret != 0) {
696                 FRESCAN_ERROR("could not update hw buffer\n");
697                 return -1;
698         }
699
700         return 0;
701 }