SingingCat 0
application
nic_manager.c
1#include "main-header.h"
2#include "networkif.h"
3#include "irq_router.h"
4
5static void nic_set_status_bit(struct network_context *nir, int bit) {
6 nir->status = nir->status | (1 << bit);
7}
8static void nic_clr_status_bit(struct network_context *nir, int bit) {
9 nir->status = nir->status & ~(1 << bit);
10}
11
12static int nic_get_status_bit(struct network_context *nir, int bit) {
13 return (nir->status & (1 << bit)) ? 1 : 0;
14}
15
16// display status of all nics
17void print_all_nics() {
18 int i = 0;
19
20 // PROBE all nics
21 printf("Network interfaces:\r\n");
22 for (;;) {
23 struct network_context *nir = nic_by_index(i);
24 i++;
25 if (nir == NULL) {
26 break;
27 }
28 printf(" Network device %i (%s)\r\n", nir->source, command_get_source_name(nir->source));
29 printf(" Flags: ");
30 if (nic_get_status_bit(nir, STATUS_PROBED)) {
31 printf("PROBED |");
32 } else {
33 printf("NOT PROBED |");
34 }
35 if (nic_get_status_bit(nir, STATUS_PROBE_SUCCESS)) {
36 printf("PROBE_SUCCESS |");
37 } else {
38 printf("NOT PROBE_SUCCESS |");
39 }
40 if (nic_get_status_bit(nir, STATUS_INITIALISED)) {
41 printf("INITIALISED |");
42 } else {
43 printf("NOT INITIALISED |");
44 }
45 if (nic_get_status_bit(nir, STATUS_READY_TO_TRANSMIT)) {
46 printf("READY_TO_TRANSMIT");
47 } else {
48 printf("NOT READY_TO_TRANSMIT");
49 }
50 printf("\r\n");
51
52 if (nir->nif->info == NULL) {
53 printf(" no info available\r\n");
54 continue;
55 }
56 nir->nif->info(nir);
57 }
58}
59void init_all_nics() {
60 int i = 0;
61
62 if (config_get_ti1101disable()) {
63 printf("NICs disabled\r\n");
64 return;
65 }
66
67 // PROBE all nics
68 for (;;) {
69 struct network_context *nir = nic_by_index(i);
70 i++;
71 if (nir == NULL) {
72 break;
73 }
74 printf("Probing network device %i (%s) (handle %i)\r\n", nir->source, command_get_source_name(nir->source), nir->mculib_handle);
75 if (nir->nif->probe == NULL) {
76 printf("Skipping network device %i (%s) - no probe()\r\n", nir->source, command_get_source_name(nir->source));
77 continue;
78 }
79 int p = nir->nif->probe(nir);
80 nic_set_status_bit(nir, STATUS_PROBED);
81 release_irq_by_handle(nir->mculib_handle);
82 mculib_release_by_handle(nir->mculib_handle);
83 mculib_print_mappings(&printf);
84 if (p != 0) {
85 printf("Skipping network device %i (%s) - probe() failed, code=%i\r\n", nir->source, command_get_source_name(nir->source), p);
86 continue;
87 }
88 nic_set_status_bit(nir, STATUS_PROBE_SUCCESS);
89 }
90 i = 0;
91 for (;;) {
92 struct network_context *nir = nic_by_index(i);
93 i++;
94 if (nir == NULL) {
95 break;
96 }
97 if (nic_get_status_bit(nir, STATUS_PROBE_SUCCESS) == 0) {
98 printf("Skipping network device %i (%s) - probe did not detect it\r\n", nir->source, command_get_source_name(nir->source));
99 continue;
100 }
101 printf("Activating network device %i (%s)\r\n", nir->source, command_get_source_name(nir->source));
102 if (nir->nif->init == NULL) {
103 printf("Skipping network device %i (%s) - no init()\r\n", nir->source, command_get_source_name(nir->source));
104 continue;
105 }
106
107 printf("Initialising network device %i (%s)\r\n", nir->source, command_get_source_name(nir->source));
108 int p = nir->nif->init(nir);
109 if (p != 0) {
110 printf("Initialisation of network device %i (%s) failed with code %i\r\n", nir->source, command_get_source_name(nir->source), p);
111 continue;
112 }
113 nic_set_status_bit(nir, STATUS_INITIALISED);
114 printf("Started network device %i (%s)\r\n", nir->source, command_get_source_name(nir->source));
115 }
116}
117// return 1 if it was enabled previously
118int stop_nic_by_type(int source) {
119 struct network_context *nc = nic_by_type(source);
120
121 if (!nic_get_status_bit(nc, STATUS_INITIALISED)) {
122 return 0;
123 }
124 if ((nc != NULL) && (nc->nif->stop != NULL)) {
125 nc->nif->stop(nc);
126 }
127 return 1;
128}
129int start_nic_by_type(int source) {
130 struct network_context *nc = nic_by_type(source);
131
132 if ((nc != NULL) && (nc->nif->init != NULL)) {
133 // was it initialised previously? (during boot)?
134 if (nic_get_status_bit(nc, STATUS_INITIALISED)) {
135 // yes was initialised, re initialise it
136 int rc = nc->nif->init(nc);
137 if (rc == 0) {
138 nic_set_status_bit(nc, STATUS_INITIALISED);
139 } else {
140 nic_clr_status_bit(nc, STATUS_INITIALISED);
141 }
142 }
143 }
144 return 0;
145}
146static void announce(struct network_context *nctx) {
147 struct command *com = alloc_command();
148
149 if (com == NULL) {
150 return;
151 }
152 com->sourcedev = nctx->source;
153 com->com = 23; // announce
154 com->sender = get_my_node_id();
155 com->target = 0xFFFFFFFF;
156 com->recipient = 0xFFFFFFFF;
157 com->flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
158 if (config_get_flag(CONFIG_FLAGS_POWER_SAVE)) {
159 com->flags |= COMFLAGS_POWERSAVE;
160 }
162 command_add_arg(com, "1");
163 int r = send_command(com);
164
165 if (r != 0) {
166 printf("nicmanager: failed to announce, reason: %i\r\n", r);
167 }
169}
170// calls nic->busy()
171int nic_is_busy(int source) {
172 struct network_context *nctx = nic_by_type(source);
173
174 if (nctx == NULL) {
175 return 1;
176 }
177 if ((nctx->status & (1 << STATUS_PROBE_SUCCESS)) == 0) {
178 // not probed successfully == always busy
179 return 1;
180 }
181 if (nctx->nif->busy == NULL) {
182 // no busy handler, assumed to be non-busy
183 return 0;
184 }
185 return nctx->nif->busy(nctx);
186}
187
188// the device calls this to indicate wether or not it is ready to send outbound commands
189// status == 0 (not ready), status == 1 (ready)
190// if a nic goes to (ready) it will also send an "announce"
191void nic_set_transmit_status(struct network_context *nctx, int status) {
192 if (status) {
193 if ((nctx->status & (1 << STATUS_PROBE_SUCCESS)) == 0) {
194 // this thing has not even been successfully probed. so it is definitely NOT ready to transmit
195 return;
196 }
197 nctx->status = nctx->status | (1 << STATUS_READY_TO_TRANSMIT);
198 announce(nctx);
199 // transmit stuff...
200 // char *txt = "foo hello world singingcat";
201 // nctx->nif->transmit(nctx,(const uint8_t *)txt,(uint16_t)strlen(txt));
202 } else {
203 nctx->status = nctx->status & ~(1 << STATUS_READY_TO_TRANSMIT);
204 }
205}
206
207// returns true if the device is ready to transmit
208int isready_by_type(int source) {
209 struct network_context *nctx = nic_by_type(source);
210
211 if (nctx == NULL) {
212 return 0;
213 }
214 return nctx->status & (1 << STATUS_READY_TO_TRANSMIT);
215}
216
217// returns true if the device is ready to transmit or is expected to be able to transmit shortly
218int isonline_by_type(int source) {
219 struct network_context *nctx = nic_by_type(source);
220
221 if (nctx == NULL) {
222 return 0;
223 }
224 if ((nctx->status & (1 << STATUS_READY_TO_TRANSMIT)) || (nctx->status & (1 << STATUS_INITIALISED))) {
225 return 1;
226 }
227 return 0;
228}
229
230
231void process_nic_event_loop() {
232 int i = 0;
233
234 for (;;) {
235 struct network_context *nir = nic_by_index(i);
236 i++;
237 if (nir == NULL) {
238 break;
239 }
240 if ((nir->nif->loop != NULL) && (nir->status & (1 << STATUS_INITIALISED))) {
241 nir->nif->loop(nir);
242 }
243 }
244}
char * command_get_source_name(byte sourcedev)
returns a human readable text identifying a source device
int send_command(struct command *com)
send a command to another module (or broadcast)
Definition: queue.c:374
void free_command(struct command *com)
free a command
Definition: queue.c:200
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
long get_my_node_id()
get the id of my node
byte get_hops_to_server()
how many hops to the server?
Definition: routing.c:526
struct command * alloc_command()
allocate a free command
Definition: queue.c:173
int com
Definition: command.h:22