OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_Demo_Rowley_ARM7/] [lwip-1.1.0/] [src/] [api/] [api_lib.c] - Blame information for rev 583

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 583 jeremybenn
/*
2
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25
 * OF SUCH DAMAGE.
26
 *
27
 * This file is part of the lwIP TCP/IP stack.
28
 *
29
 * Author: Adam Dunkels <adam@sics.se>
30
 *
31
 */
32
 
33
/* This is the part of the API that is linked with
34
   the application */
35
 
36
#include "lwip/opt.h"
37
#include "lwip/api.h"
38
#include "lwip/api_msg.h"
39
#include "lwip/memp.h"
40
 
41
 
42
struct
43
netbuf *netbuf_new(void)
44
{
45
  struct netbuf *buf;
46
 
47
  buf = memp_malloc(MEMP_NETBUF);
48
  if (buf != NULL) {
49
    buf->p = NULL;
50
    buf->ptr = NULL;
51
    return buf;
52
  } else {
53
    return NULL;
54
  }
55
}
56
 
57
void
58
netbuf_delete(struct netbuf *buf)
59
{
60
  if (buf != NULL) {
61
    if (buf->p != NULL) {
62
      pbuf_free(buf->p);
63
      buf->p = buf->ptr = NULL;
64
    }
65
    memp_free(MEMP_NETBUF, buf);
66
  }
67
}
68
 
69
void *
70
netbuf_alloc(struct netbuf *buf, u16_t size)
71
{
72
  /* Deallocate any previously allocated memory. */
73
  if (buf->p != NULL) {
74
    pbuf_free(buf->p);
75
  }
76
  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
77
  if (buf->p == NULL) {
78
     return NULL;
79
  }
80
  buf->ptr = buf->p;
81
  return buf->p->payload;
82
}
83
 
84
void
85
netbuf_free(struct netbuf *buf)
86
{
87
  if (buf->p != NULL) {
88
    pbuf_free(buf->p);
89
  }
90
  buf->p = buf->ptr = NULL;
91
}
92
 
93
void
94
netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
95
{
96
  if (buf->p != NULL) {
97
    pbuf_free(buf->p);
98
  }
99
  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
100
  buf->p->payload = dataptr;
101
  buf->p->len = buf->p->tot_len = size;
102
  buf->ptr = buf->p;
103
}
104
 
105
void
106
netbuf_chain(struct netbuf *head, struct netbuf *tail)
107
{
108
  pbuf_chain(head->p, tail->p);
109
  head->ptr = head->p;
110
  memp_free(MEMP_NETBUF, tail);
111
}
112
 
113
u16_t
114
netbuf_len(struct netbuf *buf)
115
{
116
  return buf->p->tot_len;
117
}
118
 
119
err_t
120
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
121
{
122
  if (buf->ptr == NULL) {
123
    return ERR_BUF;
124
  }
125
  *dataptr = buf->ptr->payload;
126
  *len = buf->ptr->len;
127
  return ERR_OK;
128
}
129
 
130
s8_t
131
netbuf_next(struct netbuf *buf)
132
{
133
  if (buf->ptr->next == NULL) {
134
    return -1;
135
  }
136
  buf->ptr = buf->ptr->next;
137
  if (buf->ptr->next == NULL) {
138
    return 1;
139
  }
140
  return 0;
141
}
142
 
143
void
144
netbuf_first(struct netbuf *buf)
145
{
146
  buf->ptr = buf->p;
147
}
148
 
149
void
150
netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
151
{
152
  struct pbuf *p;
153
  u16_t i, left;
154
 
155
  left = 0;
156
 
157
  if(buf == NULL || dataptr == NULL) {
158
    return;
159
  }
160
 
161
  /* This implementation is bad. It should use bcopy
162
     instead. */
163
  for(p = buf->p; left < len && p != NULL; p = p->next) {
164
    if (offset != 0 && offset >= p->len) {
165
      offset -= p->len;
166
    } else {
167
      for(i = offset; i < p->len; ++i) {
168
  ((char *)dataptr)[left] = ((char *)p->payload)[i];
169
  if (++left >= len) {
170
    return;
171
  }
172
      }
173
      offset = 0;
174
    }
175
  }
176
}
177
 
178
void
179
netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
180
{
181
  netbuf_copy_partial(buf, dataptr, len, 0);
182
}
183
 
184
struct ip_addr *
185
netbuf_fromaddr(struct netbuf *buf)
186
{
187
  return buf->fromaddr;
188
}
189
 
190
u16_t
191
netbuf_fromport(struct netbuf *buf)
192
{
193
  return buf->fromport;
194
}
195
 
196
struct
197
netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
198
                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
199
{
200
  struct netconn *conn;
201
  struct api_msg *msg;
202
 
203
  conn = memp_malloc(MEMP_NETCONN);
204
  if (conn == NULL) {
205
    return NULL;
206
  }
207
 
208
  conn->err = ERR_OK;
209
  conn->type = t;
210
  conn->pcb.tcp = NULL;
211
 
212
  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
213
    memp_free(MEMP_NETCONN, conn);
214
    return NULL;
215
  }
216
  conn->recvmbox = SYS_MBOX_NULL;
217
  conn->acceptmbox = SYS_MBOX_NULL;
218
  conn->sem = SYS_SEM_NULL;
219
  conn->state = NETCONN_NONE;
220
  conn->socket = 0;
221
  conn->callback = callback;
222
  conn->recv_avail = 0;
223
 
224
  if((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
225
    memp_free(MEMP_NETCONN, conn);
226
    return NULL;
227
  }
228
 
229
  msg->type = API_MSG_NEWCONN;
230
  msg->msg.msg.bc.port = proto; /* misusing the port field */
231
  msg->msg.conn = conn;
232
  api_msg_post(msg);
233
  sys_mbox_fetch(conn->mbox, NULL);
234
  memp_free(MEMP_API_MSG, msg);
235
 
236
  if ( conn->err != ERR_OK ) {
237
    memp_free(MEMP_NETCONN, conn);
238
    return NULL;
239
  }
240
 
241
  return conn;
242
}
243
 
244
 
245
struct
246
netconn *netconn_new(enum netconn_type t)
247
{
248
  return netconn_new_with_proto_and_callback(t,0,NULL);
249
}
250
 
251
struct
252
netconn *netconn_new_with_callback(enum netconn_type t,
253
                                   void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
254
{
255
  return netconn_new_with_proto_and_callback(t,0,callback);
256
}
257
 
258
 
259
err_t
260
netconn_delete(struct netconn *conn)
261
{
262
  struct api_msg *msg;
263
  void *mem;
264
 
265
  if (conn == NULL) {
266
    return ERR_OK;
267
  }
268
 
269
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
270
    return ERR_MEM;
271
  }
272
 
273
  msg->type = API_MSG_DELCONN;
274
  msg->msg.conn = conn;
275
  api_msg_post(msg);
276
  sys_mbox_fetch(conn->mbox, NULL);
277
  memp_free(MEMP_API_MSG, msg);
278
 
279
  /* Drain the recvmbox. */
280
  if (conn->recvmbox != SYS_MBOX_NULL) {
281
    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
282
      if (conn->type == NETCONN_TCP) {
283
        if(mem != NULL)
284
          pbuf_free((struct pbuf *)mem);
285
      } else {
286
        netbuf_delete((struct netbuf *)mem);
287
      }
288
    }
289
    sys_mbox_free(conn->recvmbox);
290
    conn->recvmbox = SYS_MBOX_NULL;
291
  }
292
 
293
 
294
  /* Drain the acceptmbox. */
295
  if (conn->acceptmbox != SYS_MBOX_NULL) {
296
    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
297
      netconn_delete((struct netconn *)mem);
298
    }
299
 
300
    sys_mbox_free(conn->acceptmbox);
301
    conn->acceptmbox = SYS_MBOX_NULL;
302
  }
303
 
304
  sys_mbox_free(conn->mbox);
305
  conn->mbox = SYS_MBOX_NULL;
306
  if (conn->sem != SYS_SEM_NULL) {
307
    sys_sem_free(conn->sem);
308
  }
309
  /*  conn->sem = SYS_SEM_NULL;*/
310
  memp_free(MEMP_NETCONN, conn);
311
  return ERR_OK;
312
}
313
 
314
enum netconn_type
315
netconn_type(struct netconn *conn)
316
{
317
  return conn->type;
318
}
319
 
320
err_t
321
netconn_peer(struct netconn *conn, struct ip_addr *addr,
322
       u16_t *port)
323
{
324
  switch (conn->type) {
325
  case NETCONN_RAW:
326
    /* return an error as connecting is only a helper for upper layers */
327
    return ERR_CONN;
328
  case NETCONN_UDPLITE:
329
  case NETCONN_UDPNOCHKSUM:
330
  case NETCONN_UDP:
331
    if (conn->pcb.udp == NULL ||
332
  ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))
333
     return ERR_CONN;
334
    *addr = (conn->pcb.udp->remote_ip);
335
    *port = conn->pcb.udp->remote_port;
336
    break;
337
  case NETCONN_TCP:
338
    if (conn->pcb.tcp == NULL)
339
      return ERR_CONN;
340
    *addr = (conn->pcb.tcp->remote_ip);
341
    *port = conn->pcb.tcp->remote_port;
342
    break;
343
  }
344
  return (conn->err = ERR_OK);
345
}
346
 
347
err_t
348
netconn_addr(struct netconn *conn, struct ip_addr **addr,
349
       u16_t *port)
350
{
351
  switch (conn->type) {
352
  case NETCONN_RAW:
353
    *addr = &(conn->pcb.raw->local_ip);
354
    *port = conn->pcb.raw->protocol;
355
    break;
356
  case NETCONN_UDPLITE:
357
  case NETCONN_UDPNOCHKSUM:
358
  case NETCONN_UDP:
359
    *addr = &(conn->pcb.udp->local_ip);
360
    *port = conn->pcb.udp->local_port;
361
    break;
362
  case NETCONN_TCP:
363
    *addr = &(conn->pcb.tcp->local_ip);
364
    *port = conn->pcb.tcp->local_port;
365
    break;
366
  }
367
  return (conn->err = ERR_OK);
368
}
369
 
370
err_t
371
netconn_bind(struct netconn *conn, struct ip_addr *addr,
372
      u16_t port)
373
{
374
  struct api_msg *msg;
375
 
376
  if (conn == NULL) {
377
    return ERR_VAL;
378
  }
379
 
380
  if (conn->type != NETCONN_TCP &&
381
     conn->recvmbox == SYS_MBOX_NULL) {
382
    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
383
      return ERR_MEM;
384
    }
385
  }
386
 
387
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
388
    return (conn->err = ERR_MEM);
389
  }
390
  msg->type = API_MSG_BIND;
391
  msg->msg.conn = conn;
392
  msg->msg.msg.bc.ipaddr = addr;
393
  msg->msg.msg.bc.port = port;
394
  api_msg_post(msg);
395
  sys_mbox_fetch(conn->mbox, NULL);
396
  memp_free(MEMP_API_MSG, msg);
397
  return conn->err;
398
}
399
 
400
 
401
err_t
402
netconn_connect(struct netconn *conn, struct ip_addr *addr,
403
       u16_t port)
404
{
405
  struct api_msg *msg;
406
 
407
  if (conn == NULL) {
408
    return ERR_VAL;
409
  }
410
 
411
 
412
  if (conn->recvmbox == SYS_MBOX_NULL) {
413
    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
414
      return ERR_MEM;
415
    }
416
  }
417
 
418
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
419
    return ERR_MEM;
420
  }
421
  msg->type = API_MSG_CONNECT;
422
  msg->msg.conn = conn;
423
  msg->msg.msg.bc.ipaddr = addr;
424
  msg->msg.msg.bc.port = port;
425
  api_msg_post(msg);
426
  sys_mbox_fetch(conn->mbox, NULL);
427
  memp_free(MEMP_API_MSG, msg);
428
  return conn->err;
429
}
430
 
431
err_t
432
netconn_disconnect(struct netconn *conn)
433
{
434
  struct api_msg *msg;
435
 
436
  if (conn == NULL) {
437
    return ERR_VAL;
438
  }
439
 
440
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
441
    return ERR_MEM;
442
  }
443
  msg->type = API_MSG_DISCONNECT;
444
  msg->msg.conn = conn;
445
  api_msg_post(msg);
446
  sys_mbox_fetch(conn->mbox, NULL);
447
  memp_free(MEMP_API_MSG, msg);
448
  return conn->err;
449
 
450
}
451
 
452
err_t
453
netconn_listen(struct netconn *conn)
454
{
455
  struct api_msg *msg;
456
 
457
  if (conn == NULL) {
458
    return ERR_VAL;
459
  }
460
 
461
  if (conn->acceptmbox == SYS_MBOX_NULL) {
462
    conn->acceptmbox = sys_mbox_new();
463
    if (conn->acceptmbox == SYS_MBOX_NULL) {
464
      return ERR_MEM;
465
    }
466
  }
467
 
468
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
469
    return (conn->err = ERR_MEM);
470
  }
471
  msg->type = API_MSG_LISTEN;
472
  msg->msg.conn = conn;
473
  api_msg_post(msg);
474
  sys_mbox_fetch(conn->mbox, NULL);
475
  memp_free(MEMP_API_MSG, msg);
476
  return conn->err;
477
}
478
 
479
struct netconn *
480
netconn_accept(struct netconn *conn)
481
{
482
  struct netconn *newconn;
483
 
484
  if (conn == NULL) {
485
    return NULL;
486
  }
487
 
488
  sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
489
  /* Register event with callback */
490
  if (conn->callback)
491
      (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);
492
 
493
  return newconn;
494
}
495
 
496
struct netbuf *
497
netconn_recv(struct netconn *conn)
498
{
499
  struct api_msg *msg;
500
  struct netbuf *buf;
501
  struct pbuf *p;
502
  u16_t len;
503
 
504
  if (conn == NULL) {
505
    return NULL;
506
  }
507
 
508
  if (conn->recvmbox == SYS_MBOX_NULL) {
509
    conn->err = ERR_CONN;
510
    return NULL;
511
  }
512
 
513
  if (conn->err != ERR_OK) {
514
    return NULL;
515
  }
516
 
517
  if (conn->type == NETCONN_TCP) {
518
    if (conn->pcb.tcp->state == LISTEN) {
519
      conn->err = ERR_CONN;
520
      return NULL;
521
    }
522
 
523
 
524
    buf = memp_malloc(MEMP_NETBUF);
525
 
526
    if (buf == NULL) {
527
      conn->err = ERR_MEM;
528
      return NULL;
529
    }
530
 
531
    sys_mbox_fetch(conn->recvmbox, (void **)&p);
532
 
533
    if (p != NULL)
534
    {
535
        len = p->tot_len;
536
        conn->recv_avail -= len;
537
    }
538
    else
539
        len = 0;
540
 
541
    /* Register event with callback */
542
      if (conn->callback)
543
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
544
 
545
    /* If we are closed, we indicate that we no longer wish to receive
546
       data by setting conn->recvmbox to SYS_MBOX_NULL. */
547
    if (p == NULL) {
548
      memp_free(MEMP_NETBUF, buf);
549
      sys_mbox_free(conn->recvmbox);
550
      conn->recvmbox = SYS_MBOX_NULL;
551
      return NULL;
552
    }
553
 
554
    buf->p = p;
555
    buf->ptr = p;
556
    buf->fromport = 0;
557
    buf->fromaddr = NULL;
558
 
559
    /* Let the stack know that we have taken the data. */
560
    if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
561
      conn->err = ERR_MEM;
562
      return buf;
563
    }
564
    msg->type = API_MSG_RECV;
565
    msg->msg.conn = conn;
566
    if (buf != NULL) {
567
      msg->msg.msg.len = buf->p->tot_len;
568
    } else {
569
      msg->msg.msg.len = 1;
570
    }
571
    api_msg_post(msg);
572
 
573
    sys_mbox_fetch(conn->mbox, NULL);
574
    memp_free(MEMP_API_MSG, msg);
575
  } else {
576
    sys_mbox_fetch(conn->recvmbox, (void **)&buf);
577
  conn->recv_avail -= buf->p->tot_len;
578
    /* Register event with callback */
579
    if (conn->callback)
580
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
581
  }
582
 
583
 
584
 
585
 
586
  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
587
 
588
 
589
  return buf;
590
}
591
 
592
err_t
593
netconn_send(struct netconn *conn, struct netbuf *buf)
594
{
595
  struct api_msg *msg;
596
 
597
  if (conn == NULL) {
598
    return ERR_VAL;
599
  }
600
 
601
  if (conn->err != ERR_OK) {
602
    return conn->err;
603
  }
604
 
605
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
606
    return (conn->err = ERR_MEM);
607
  }
608
 
609
  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
610
  msg->type = API_MSG_SEND;
611
  msg->msg.conn = conn;
612
  msg->msg.msg.p = buf->p;
613
  api_msg_post(msg);
614
 
615
  sys_mbox_fetch(conn->mbox, NULL);
616
  memp_free(MEMP_API_MSG, msg);
617
  return conn->err;
618
}
619
 
620
err_t
621
netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
622
{
623
  struct api_msg *msg;
624
  u16_t len;
625
 
626
  if (conn == NULL) {
627
    return ERR_VAL;
628
  }
629
 
630
  if (conn->err != ERR_OK) {
631
    return conn->err;
632
  }
633
 
634
  if (conn->sem == SYS_SEM_NULL) {
635
    conn->sem = sys_sem_new(0);
636
    if (conn->sem == SYS_SEM_NULL) {
637
      return ERR_MEM;
638
    }
639
  }
640
 
641
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
642
    return (conn->err = ERR_MEM);
643
  }
644
  msg->type = API_MSG_WRITE;
645
  msg->msg.conn = conn;
646
 
647
 
648
  conn->state = NETCONN_WRITE;
649
  while (conn->err == ERR_OK && size > 0) {
650
    msg->msg.msg.w.dataptr = dataptr;
651
    msg->msg.msg.w.copy = copy;
652
 
653
    if (conn->type == NETCONN_TCP) {
654
      if (tcp_sndbuf(conn->pcb.tcp) == 0) {
655
  sys_sem_wait(conn->sem);
656
  if (conn->err != ERR_OK) {
657
    goto ret;
658
  }
659
      }
660
      if (size > tcp_sndbuf(conn->pcb.tcp)) {
661
  /* We cannot send more than one send buffer's worth of data at a
662
     time. */
663
  len = tcp_sndbuf(conn->pcb.tcp);
664
      } else {
665
  len = size;
666
      }
667
    } else {
668
      len = size;
669
    }
670
 
671
    LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
672
    msg->msg.msg.w.len = len;
673
    api_msg_post(msg);
674
    sys_mbox_fetch(conn->mbox, NULL);
675
    if (conn->err == ERR_OK) {
676
      dataptr = (void *)((char *)dataptr + len);
677
      size -= len;
678
    } else if (conn->err == ERR_MEM) {
679
      conn->err = ERR_OK;
680
      sys_sem_wait(conn->sem);
681
    } else {
682
      goto ret;
683
    }
684
  }
685
 ret:
686
  memp_free(MEMP_API_MSG, msg);
687
  conn->state = NETCONN_NONE;
688
  if (conn->sem != SYS_SEM_NULL) {
689
    sys_sem_free(conn->sem);
690
    conn->sem = SYS_SEM_NULL;
691
  }
692
 
693
  return conn->err;
694
}
695
 
696
err_t
697
netconn_close(struct netconn *conn)
698
{
699
  struct api_msg *msg;
700
 
701
  if (conn == NULL) {
702
    return ERR_VAL;
703
  }
704
  if ((msg = memp_malloc(MEMP_API_MSG)) == NULL) {
705
    return (conn->err = ERR_MEM);
706
  }
707
 
708
  conn->state = NETCONN_CLOSE;
709
 again:
710
  msg->type = API_MSG_CLOSE;
711
  msg->msg.conn = conn;
712
  api_msg_post(msg);
713
  sys_mbox_fetch(conn->mbox, NULL);
714
  if (conn->err == ERR_MEM &&
715
     conn->sem != SYS_SEM_NULL) {
716
    sys_sem_wait(conn->sem);
717
    goto again;
718
  }
719
  conn->state = NETCONN_NONE;
720
  memp_free(MEMP_API_MSG, msg);
721
  return conn->err;
722
}
723
 
724
err_t
725
netconn_err(struct netconn *conn)
726
{
727
  return conn->err;
728
}
729
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.