3 * Copyright 2010 - 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
6 * Faculty of Computer Science, Mathematics and Natural Sciences,
7 * Leipzig University of Applied Sciences (HTWK Leipzig)
10 /* Needs here & there some cleanups and rewrites */
15 #include <sys/types.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
28 #define NET_DEV_FILE "/dev/nao"
29 #define NET_DEV_MAX_SEG_SIZE 1500
31 pthread_mutex_t list_head_lock
;
32 static naonet_block_t
*list_head
= NULL
;
34 static int __register_rx_hook(naonet_block_t
**head
, naonet_block_t
*block
)
41 pthread_mutex_lock(&list_head_lock
);
42 while((*head
) != NULL
) {
43 if(block
->priority
> (*head
)->priority
)
45 head
= &((*head
)->next
);
47 block
->next
= (*head
);
49 pthread_mutex_unlock(&list_head_lock
);
54 static int __register_rx_hook_once(naonet_block_t
**head
, naonet_block_t
*block
)
61 pthread_mutex_lock(&list_head_lock
);
62 while((*head
) != NULL
) {
63 if(unlikely(block
== (*head
)))
65 if(block
->priority
> (*head
)->priority
)
67 head
= &((*head
)->next
);
69 block
->next
= (*head
);
71 pthread_mutex_unlock(&list_head_lock
);
76 static int __unregister_rx_hook(naonet_block_t
**head
, naonet_block_t
*block
)
81 pthread_mutex_lock(&list_head_lock
);
82 while((*head
) != NULL
) {
83 if(unlikely(block
== (*head
))) {
84 (*head
) = block
->next
;
87 head
= &((*head
)->next
);
89 pthread_mutex_unlock(&list_head_lock
);
94 static int __call_rx_hook_chain(naonet_block_t
**head
, uint8_t type
,
95 uint32_t src
, char *message
, size_t len
,
98 int rc
= BLOCK_SUCC_DONE
;
99 naonet_block_t
*block
= (*head
), *next_block
;
101 if(!head
|| !message
|| !len
)
106 pthread_mutex_lock(&list_head_lock
);
108 next_block
= block
->next
;
109 if(block
->type
!= type
)
111 rc
= block
->rx_hook(block
, src
, message
, len
);
112 if((rc
& BLOCK_STOP_CHAIN
) == BLOCK_STOP_CHAIN
)
119 pthread_mutex_unlock(&list_head_lock
);
123 int register_rx_hook(naonet_block_t
*block
)
125 return __register_rx_hook(&list_head
, block
);
128 int register_rx_hook_once(naonet_block_t
*block
)
130 return __register_rx_hook_once(&list_head
, block
);
133 int unregister_rx_hook(naonet_block_t
*block
)
135 return __unregister_rx_hook(&list_head
, block
);
138 static int call_rx_hook_chain(uint8_t type
, uint32_t src
, char *message
,
139 size_t len
, int *called
)
141 return __call_rx_hook_chain(&list_head
, type
, src
, message
, len
,
145 int send_message(char *message
, size_t len
, uint8_t type
)
149 char buf
[NET_DEV_MAX_SEG_SIZE
];
151 if(!message
|| !len
|| len
>= NET_DEV_MAX_SEG_SIZE
)
154 fd
= open(NET_DEV_FILE
, O_WRONLY
);
160 /* No memset in fastpath */
161 memcpy(&buf
[1], message
, len
);
164 ret
= write(fd
, buf
, len
+ 1);
165 if(ret
!= (len
+ 1)) {
174 static void *rx_thread(void *null
)
178 char buf
[NET_DEV_MAX_SEG_SIZE
];
181 fd
= open(NET_DEV_FILE
, O_RDONLY
);
187 while((len
= read(fd
, buf
, sizeof(buf
))) > 0) {
188 nh
= (naonet_header_t
*) ((void *) buf
);
189 call_rx_hook_chain((uint8_t) (*(buf
+ sizeof(*nh
))), nh
->src_id
,
190 (buf
+ sizeof(*nh
) + 1), ntohs(nh
->len
) - 1,
192 memset(buf
, 0, sizeof(buf
));
199 uint32_t naonet_fetch_id(void)
203 char buff
[200] = {0};
205 fd
= open("/proc/naonet/id", O_RDONLY
);
207 perror("Cannot open /proc/naonet/id");
211 if(read(fd
, buff
, sizeof(buff
)) > 0) {
212 sscanf(buff
, "%u", &id
);
217 printf("Cannot parse naonet ID from /var/log/messages!\n");
221 int naonet_init(pthread_t
*rx_thread_p
)
228 rc
= pthread_create(rx_thread_p
, NULL
, rx_thread
, NULL
);
230 perror("pthread_create");
234 pthread_detach((*rx_thread_p
));