nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /*************************************************************************** |
2 | * * |
||
3 | * ########### ########### ########## ########## * |
||
4 | * ############ ############ ############ ############ * |
||
5 | * ## ## ## ## ## ## ## * |
||
6 | * ## ## ## ## ## ## ## * |
||
7 | * ########### #### ###### ## ## ## ## ###### * |
||
8 | * ########### #### # ## ## ## ## # # * |
||
9 | * ## ## ###### ## ## ## ## # # * |
||
10 | * ## ## # ## ## ## ## # # * |
||
11 | * ############ ##### ###### ## ## ## ##### ###### * |
||
12 | * ########### ########### ## ## ## ########## * |
||
13 | * * |
||
14 | * S E C U R E M O B I L E N E T W O R K I N G * |
||
15 | * * |
||
16 | * This file is part of NexMon. * |
||
17 | * * |
||
18 | * Copyright (c) 2016 NexMon Team * |
||
19 | * * |
||
20 | * NexMon is free software: you can redistribute it and/or modify * |
||
21 | * it under the terms of the GNU General Public License as published by * |
||
22 | * the Free Software Foundation, either version 3 of the License, or * |
||
23 | * (at your option) any later version. * |
||
24 | * * |
||
25 | * NexMon is distributed in the hope that it will be useful, * |
||
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
||
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
||
28 | * GNU General Public License for more details. * |
||
29 | * * |
||
30 | * You should have received a copy of the GNU General Public License * |
||
31 | * along with NexMon. If not, see <http://www.gnu.org/licenses/>. * |
||
32 | * * |
||
33 | **************************************************************************/ |
||
34 | |||
35 | #pragma NEXMON targetregion "patch" |
||
36 | |||
37 | #include <firmware_version.h> // definition of firmware version macros |
||
38 | #include <debug.h> // contains macros to access the debug hardware |
||
39 | #include <wrapper.h> // wrapper definitions for functions that already exist in the firmware |
||
40 | #include <structs.h> // structures that are used by the code in the firmware |
||
41 | #include <helper.h> // useful helper functions |
||
42 | #include <patcher.h> // macros used to craete patches such as BLPatch, BPatch, ... |
||
43 | #include <rates.h> // rates used to build the ratespec for frame injection |
||
44 | #include <nexioctls.h> // ioctls added in the nexmon patch |
||
45 | #include <capabilities.h> // capabilities included in a nexmon patch |
||
46 | |||
47 | struct tx_task { |
||
48 | struct wlc_info *wlc; |
||
49 | struct sk_buff *p; |
||
50 | unsigned int fifo; |
||
51 | unsigned int rate; |
||
52 | int txrepetitions; |
||
53 | int txperiodicity; |
||
54 | }; |
||
55 | |||
56 | void |
||
57 | sendframe(struct wlc_info *wlc, struct sk_buff *p, unsigned int fifo, unsigned int rate) |
||
58 | { |
||
59 | if (wlc->band->bandtype == WLC_BAND_5G && rate < RATES_RATE_6M) { |
||
60 | rate = RATES_RATE_6M; |
||
61 | } |
||
62 | |||
63 | if (wlc->hw->up) { |
||
64 | if (p->flags & 0x80) { // WLF_TXHDR = 0x80 |
||
65 | if (wlc_prec_enq(wlc, wlc->active_queue + 4, p, 5)) { |
||
66 | wlc_send_q(wlc, wlc->active_queue); |
||
67 | } else { |
||
68 | pkt_buf_free_skb(wlc->osh, p, 0); |
||
69 | } |
||
70 | } else { |
||
71 | wlc_sendctl(wlc, p, wlc->active_queue, wlc->band->hwrs_scb, fifo, rate, 0); |
||
72 | } |
||
73 | } else { |
||
74 | pkt_buf_free_skb(wlc->osh, p, 0); |
||
75 | printf("ERR: wlc down\n"); |
||
76 | } |
||
77 | } |
||
78 | |||
79 | static void |
||
80 | sendframe_copy(struct tx_task *task) |
||
81 | { |
||
82 | // first, we create a copy copy of the frame that should be transmitted |
||
83 | struct sk_buff *p_copy = pkt_buf_get_skb(task->wlc->osh, task->p->len + 202); |
||
84 | skb_pull(p_copy, 202); |
||
85 | memcpy(p_copy->data, task->p->data, task->p->len); |
||
86 | p_copy->flags = task->p->flags; |
||
87 | p_copy->scb = task->p->scb; |
||
88 | |||
89 | sendframe(task->wlc, p_copy, task->fifo, task->rate); |
||
90 | |||
91 | if (task->txrepetitions > 0) { |
||
92 | task->txrepetitions--; |
||
93 | } |
||
94 | } |
||
95 | |||
96 | static void |
||
97 | sendframe_timer_handler(struct hndrte_timer *t) |
||
98 | { |
||
99 | struct tx_task *task = (struct tx_task *) t->data; |
||
100 | |||
101 | if (task->txrepetitions == 0) { |
||
102 | // there must have been a mistake, just delete the frame task and timer |
||
103 | pkt_buf_free_skb(task->wlc->osh, task->p, 0); |
||
104 | goto free_timer_and_task; |
||
105 | } else if (task->txrepetitions == 1) { |
||
106 | // transmit the last frame |
||
107 | sendframe(task->wlc, task->p, task->fifo, task->rate); |
||
108 | free_timer_and_task: |
||
109 | hndrte_del_timer(t); |
||
110 | hndrte_free_timer(t); |
||
111 | free(task); |
||
112 | } else { |
||
113 | sendframe_copy(task); |
||
114 | } |
||
115 | } |
||
116 | |||
117 | static void |
||
118 | sendframe_repeatedly(struct tx_task *task) |
||
119 | { |
||
120 | struct hndrte_timer *t; |
||
121 | |||
122 | sendframe_copy(task); |
||
123 | if (task->txrepetitions == 0) |
||
124 | return; |
||
125 | |||
126 | t = hndrte_init_timer(sendframe_repeatedly, task, sendframe_timer_handler, 0); |
||
127 | |||
128 | if (!t) { |
||
129 | free(task); |
||
130 | return; |
||
131 | } |
||
132 | |||
133 | if (!hndrte_add_timer(t, task->txperiodicity, 1)) { |
||
134 | hndrte_free_timer(t); |
||
135 | free(task); |
||
136 | |||
137 | printf("ERR: could not add timer"); |
||
138 | } |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Is scheduled to transmit a frame after a delay |
||
143 | */ |
||
144 | static void |
||
145 | sendframe_task_handler(struct hndrte_timer *t) |
||
146 | { |
||
147 | struct tx_task *task = (struct tx_task *) t->data; |
||
148 | |||
149 | if (task->txrepetitions != 0 && task->txperiodicity > 0) { |
||
150 | sendframe_repeatedly(task); |
||
151 | } else { |
||
152 | sendframe(task->wlc, task->p, task->fifo, task->rate); |
||
153 | free(task); |
||
154 | } |
||
155 | } |
||
156 | |||
157 | void |
||
158 | sendframe_with_timer(struct wlc_info *wlc, struct sk_buff *p, unsigned int fifo, unsigned int rate, int txdelay, int txrepetitions, int txperiodicity) |
||
159 | { |
||
160 | struct tx_task *task = 0; |
||
161 | |||
162 | // if we need to send the frame with a delay or repeatedly, we create a task |
||
163 | if (txdelay > 0 || (txrepetitions != 0 && txperiodicity > 0)) { |
||
164 | task = (struct tx_task *) malloc(sizeof(struct tx_task), 0); |
||
165 | memset(task, 0, sizeof(struct tx_task)); // will be freed after finishing the task |
||
166 | task->wlc = wlc; |
||
167 | task->p = p; |
||
168 | task->fifo = fifo; |
||
169 | task->rate = rate; |
||
170 | task->txrepetitions = txrepetitions; |
||
171 | task->txperiodicity = txperiodicity; |
||
172 | } |
||
173 | |||
174 | if (txdelay > 0) { |
||
175 | hndrte_schedule_work(sendframe_with_timer, task, sendframe_task_handler, txdelay); |
||
176 | } else if (txrepetitions != 0 && txperiodicity > 0) { |
||
177 | sendframe_repeatedly(task); |
||
178 | } else { |
||
179 | sendframe(wlc, p, fifo, rate); |
||
180 | } |
||
181 | } |