1229970Sadrian/*-
2229970Sadrian * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB
3229970Sadrian * All rights reserved.
4229970Sadrian *
5229970Sadrian * Redistribution and use in source and binary forms, with or without
6229970Sadrian * modification, are permitted provided that the following conditions
7229970Sadrian * are met:
8229970Sadrian * 1. Redistributions of source code must retain the above copyright
9229970Sadrian *    notice, this list of conditions and the following disclaimer,
10229970Sadrian *    without modification.
11229970Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12229970Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13229970Sadrian *    redistribution must be conditioned upon including a substantially
14229970Sadrian *    similar Disclaimer requirement for further binary redistribution.
15229970Sadrian *
16229970Sadrian * NO WARRANTY
17229970Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18229970Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19229970Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20229970Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21229970Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22229970Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23229970Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24229970Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25229970Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26229970Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27229970Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28229970Sadrian *
29229970Sadrian * $FreeBSD$
30229970Sadrian */
31229970Sadrian#include "if_wtapvar.h"
32229970Sadrian#include "if_medium.h"
33229970Sadrian
34229970Sadrianvoid
35229970Sadrianinit_medium(struct wtap_medium *md)
36229970Sadrian{
37229970Sadrian
38229970Sadrian	DWTAP_PRINTF("%s\n", __func__);
39229970Sadrian	STAILQ_INIT(&md->md_pktbuf);
40229970Sadrian	mtx_init(&md->md_mtx, "wtap_medium mtx", NULL, MTX_DEF | MTX_RECURSE);
41229970Sadrian
42229970Sadrian	/* Event handler for sending packets between wtaps */
43229970Sadrian	struct eventhandler *eh = (struct eventhandler *)
44229970Sadrian	    malloc(sizeof(struct eventhandler), M_WTAP, M_NOWAIT | M_ZERO);
45229970Sadrian	eh->tq = taskqueue_create("wtap_tx_taskq",  M_NOWAIT | M_ZERO,
46229970Sadrian	    taskqueue_thread_enqueue, &eh->tq);
47229970Sadrian	taskqueue_start_threads(&eh->tq, 1, PI_NET, "%s taskq", "wtap_medium");
48229970Sadrian	md->tx_handler = eh;
49229970Sadrian	/* Mark medium closed by default */
50229970Sadrian	md->open = 0;
51229970Sadrian}
52229970Sadrian
53229970Sadrianvoid
54229970Sadriandeinit_medium(struct wtap_medium *md)
55229970Sadrian{
56229970Sadrian
57229970Sadrian	DWTAP_PRINTF("%s\n", __func__);
58229970Sadrian	taskqueue_free(md->tx_handler->tq);
59229970Sadrian	free(md->tx_handler, M_WTAP);
60229970Sadrian}
61229970Sadrian
62229970Sadrianint
63229970Sadrianmedium_transmit(struct wtap_medium *md, int id, struct mbuf*m)
64229970Sadrian{
65229970Sadrian
66229970Sadrian	mtx_lock(&md->md_mtx);
67229970Sadrian	if (md->open == 0){
68229970Sadrian		DWTAP_PRINTF("[%d] dropping m=%p\n", id, m);
69229970Sadrian		m_free(m);
70229970Sadrian		mtx_unlock(&md->md_mtx);
71229970Sadrian		return 0;
72229970Sadrian	}
73229970Sadrian
74229970Sadrian	DWTAP_PRINTF("[%d] transmiting m=%p\n", id, m);
75229970Sadrian	struct packet *p = (struct packet *)malloc(sizeof(struct packet),
76229970Sadrian	    M_WTAP_PACKET, M_ZERO | M_NOWAIT);
77229970Sadrian	p->id = id;
78229970Sadrian	p->m = m;
79229970Sadrian
80229970Sadrian	STAILQ_INSERT_TAIL(&md->md_pktbuf, p, pf_list);
81229970Sadrian	taskqueue_enqueue(md->tx_handler->tq, &md->tx_handler->proc);
82229970Sadrian	mtx_unlock(&md->md_mtx);
83229970Sadrian
84229970Sadrian      return 0;
85229970Sadrian}
86229970Sadrian
87229970Sadrianstruct packet *
88229970Sadrianmedium_get_next_packet(struct wtap_medium *md)
89229970Sadrian{
90229970Sadrian	struct packet *p;
91229970Sadrian
92229970Sadrian	mtx_lock(&md->md_mtx);
93229970Sadrian	p = STAILQ_FIRST(&md->md_pktbuf);
94229970Sadrian	if (p == NULL){
95229970Sadrian		mtx_unlock(&md->md_mtx);
96229970Sadrian		return NULL;
97229970Sadrian	}
98229970Sadrian
99229970Sadrian	STAILQ_REMOVE_HEAD(&md->md_pktbuf, pf_list);
100229970Sadrian	mtx_unlock(&md->md_mtx);
101229970Sadrian	return p;
102229970Sadrian}
103229970Sadrian
104229970Sadrianvoid
105229970Sadrianmedium_open(struct wtap_medium *md)
106229970Sadrian{
107229970Sadrian
108229970Sadrian	mtx_lock(&md->md_mtx);
109229970Sadrian	md->open = 1;
110229970Sadrian	mtx_unlock(&md->md_mtx);
111229970Sadrian}
112229970Sadrian
113229970Sadrianvoid
114229970Sadrianmedium_close(struct wtap_medium *md)
115229970Sadrian{
116229970Sadrian
117229970Sadrian	mtx_lock(&md->md_mtx);
118229970Sadrian	md->open = 0;
119229970Sadrian	mtx_unlock(&md->md_mtx);
120229970Sadrian}
121