RepeaterPage » History » Version 11
matt, 11/12/2017 11:56 PM
1 | 2 | matt | h1. SUMMARY |
---|---|---|---|
2 | 1 | zecke | |
3 | * Simultaneous multi-channel transmission/reception |
||
4 | * Uses USRP and/or conventional receiver/transmitter hardware |
||
5 | * Generic interface to Asterisk via app_rpt (full VOIP, radio control, and standard repeater functions) |
||
6 | * Features: P25, analog NBFM with CTCSS |
||
7 | * Expected to be fully "ROIP" [Radio Over IP] compatible |
||
8 | |||
9 | 2 | matt | h2. Multi-channel reception using the USRP |
10 | 1 | zecke | |
11 | Assume we want to receive simultaneously the four signals shown below; |
||
12 | one conventional (analog) FM voice channel plus three P25 |
||
13 | signals. The two P25 voice channels are to be IMBE-decoded whereas the |
||
14 | P25 data channel is to be sent to Wireshark after decoding. For all three voice |
||
15 | channels, we want to forward the received PTT and audio info to Asterisk app_rpt. |
||
16 | The received PTT [Push To Talk, or "keyed"] signal is a bit that ideally tracks |
||
17 | the state of the PTT key at transmitter, indicating the presence or absence of the |
||
18 | received signal. |
||
19 | |||
20 | 8 | matt | h2. Spectrum plot |
21 | |||
22 | 11 | matt | Spectrum plot as received by a USRP:- |
23 | 7 | matt | !spectrum.png! |
24 | 1 | zecke | |
25 | Fig. 1 - Spectrum of repeater input band (sample; diagram not to scale) |
||
26 | |||
27 | For now, it's necessary to edit the source code file manually to specify |
||
28 | the list of channels/modes to be received (file usrp_rx.py): |
||
29 | |||
30 | 3 | matt | <pre> |
31 | 1 | zecke | channels = [ |
32 | {'freq':435.200e6, 'mode':'c4fm', 'port':32001}, |
||
33 | {'freq':435.350e6, 'mode':'fm', 'port':32002, 'ctcss':97.4}, |
||
34 | {'freq':435.600e6, 'mode':'cqpsk', 'port':23456, 'wireshark':1}, |
||
35 | {'freq':435.775e6, 'mode':'cqpsk', 'port':32003} |
||
36 | ] |
||
37 | 3 | matt | </pre> |
38 | 1 | zecke | |
39 | Individual channels are defined one per line; note that all definition lines |
||
40 | except the last must end with a comma. |
||
41 | |||
42 | We choose a frequency somewhere close to the center of this band. |
||
43 | which will set the USRP's nominal receive frequency; this must also |
||
44 | be manually set in the source file: |
||
45 | |||
46 | 3 | matt | <pre> |
47 | 1 | zecke | center_freq = 435.500e6 |
48 | 3 | matt | </pre> |
49 | 1 | zecke | |
50 | Before running the receiver app, we |
||
51 | * measure the current calibration error value (I use kalibrate) |
||
52 | * determine the optimum USRP receiver gain value |
||
53 | The values used in this example are +1234 and 35, respectively. |
||
54 | |||
55 | We're now ready to start the receiver: |
||
56 | |||
57 | 3 | matt | <pre> |
58 | 1 | zecke | usrp_rx.py -RA -c 1234 -H 127.0.0.1 -g 35 -d 25 |
59 | 3 | matt | </pre> |
60 | 1 | zecke | |
61 | The receiver continuously monitors all four channels. For each of the three |
||
62 | voice channels, the audio and the PTT info ("key up" and "key down" events) |
||
63 | are forwarded to asterisk app_rpt over separate UDP channels. |
||
64 | |||
65 | = P25 and/or analog NBFM Reception using a discriminator-tapped receiver = |
||
66 | |||
67 | One or more disc-tapped conventional receivers may be used at the same time, and can |
||
68 | coexist with one or more USRP's. |
||
69 | |||
70 | An audio cable is connected between the disc-tap point in the receiver and the PC soundcard. |
||
71 | |||
72 | Single-channel reception is possible using disctap_rx.py. |
||
73 | The app dynmically auto-detects the modulation type (P25 or analog NBFM). |
||
74 | |||
75 | Audio and PTT events are forwarded to asterisk app_rpt over two separate UDP |
||
76 | channels, depending on modulation type: |
||
77 | * received P25 audio is sent to asterisk on UDP port 32004 |
||
78 | * when analog NBFM is received with the proper CTCSS tone (97.4 Hz), port 32005 is used |
||
79 | |||
80 | 3 | matt | <pre> |
81 | 1 | zecke | disctap_rx.py -i -A 0.05 -c 97.4 -H 127.0.0.1 -p 32004 -g 35 -d 25 |
82 | 3 | matt | </pre> |
83 | 1 | zecke | |
84 | The -g (gain) parameter is used to set the proper audio gain level. See |
||
85 | the hardware page for further guidance - this value is important for achieving |
||
86 | correct operation. |
||
87 | |||
88 | 3 | matt | h2. Asterisk and app_rpt |
89 | 1 | zecke | |
90 | For all voice modes (IMBE and analog FM) the audio is transmitted |
||
91 | as frames over the UDP channel to and from Asterisk in the standard native audio format: |
||
92 | * 50 frames per second |
||
93 | * 160 audio samples per frame |
||
94 | * 8000 samples per second |
||
95 | * signed |
||
96 | * 16-bit |
||
97 | * linear |
||
98 | |||
99 | 3 | matt | h3. Build asterisk with app_rpt |
100 | 1 | zecke | |
101 | As a prereq make sure the Linux kernel headers are installed, as zaptel installs kernel modules. |
||
102 | |||
103 | First obtain and unpack the sources |
||
104 | |||
105 | 3 | matt | - http://ohnosec.org/drupal/node/6 [use @svn checkout@ to grab the "Asterisk Sources"] |
106 | 1 | zecke | |
107 | 3 | matt | Locate the toplevel directory - this should have several subdirectories including @zaptel@ and @asterisk@ . |
108 | 1 | zecke | |
109 | 3 | matt | Then locate the subdirectory named @asterisk/channels@ , |
110 | and copy the files @chan_usrp.c@ and @chan_usrp.h@ (from @repeater/src/lib@ in the op25 sources) to this subdirectory. |
||
111 | 1 | zecke | |
112 | Now, build and install asterisk and app_rpt |
||
113 | |||
114 | 3 | matt | @cd@ to the toplevel directory |
115 | |||
116 | @cd zaptel && ./configure && make && sudo make install@ |
||
117 | |||
118 | 1 | zecke | and then (again from the toplevel directory) |
119 | |||
120 | 3 | matt | @cd asterisk && ./configure && make && sudo make install@ |
121 | |||
122 | |||
123 | 1 | zecke | For a first time installation of asterisk there are also other steps such as config file installation. |
124 | 3 | matt | Before setting up @rpt.conf@ you must first set up asterisk itself - see for example |
125 | 1 | zecke | |
126 | http://www.voip-info.org/wiki/view/Asterisk+quickstart |
||
127 | |||
128 | 3 | matt | h2. Configuration |
129 | 1 | zecke | |
130 | 3 | matt | We define five repeater nodes in @/etc/asterisk/rpt.conf@ |
131 | 1 | zecke | |
132 | 3 | matt | <pre> |
133 | 1 | zecke | [000] |
134 | rxchannel = usrp/127.0.0.1:34001:32001 |
||
135 | duplex = 2 |
||
136 | scheduler=scheduler |
||
137 | functions = functions-repeater |
||
138 | hangtime=0 |
||
139 | authlevel = 0 |
||
140 | |||
141 | [001] |
||
142 | rxchannel = usrp/127.0.0.1:34002:32002 |
||
143 | duplex = 2 |
||
144 | scheduler=scheduler |
||
145 | functions = functions-repeater |
||
146 | hangtime=0 |
||
147 | authlevel = 0 |
||
148 | |||
149 | [002] |
||
150 | rxchannel = usrp/127.0.0.1:34003:32003 |
||
151 | duplex = 2 |
||
152 | scheduler=scheduler |
||
153 | functions = functions-repeater |
||
154 | hangtime=0 |
||
155 | authlevel = 0 |
||
156 | |||
157 | [003] |
||
158 | rxchannel = usrp/127.0.0.1:34004:32004 |
||
159 | duplex = 2 |
||
160 | scheduler=scheduler |
||
161 | functions = functions-repeater |
||
162 | hangtime=0 |
||
163 | authlevel = 0 |
||
164 | |||
165 | [004] |
||
166 | rxchannel = usrp/127.0.0.1:34005:32005 |
||
167 | duplex = 2 |
||
168 | scheduler=scheduler |
||
169 | functions = functions-repeater |
||
170 | hangtime=0 |
||
171 | authlevel = 0 |
||
172 | 3 | matt | </pre> |
173 | 1 | zecke | |
174 | Continuing the example of five voice channels from above, we define five repeater nodes (channels). Voice and PTT traffic that |
||
175 | is output by asterisk/app_rpt for RF transmission is forwarded to usrp_tx.py (see below) using UDP ports in the 3400x range. |
||
176 | Voice data received in usrp_rx.py and/or disctap_rx.py is forwarded to asterisk/app_rpt (chan_usrp.c) via ports in the 3200x range. |
||
177 | |||
178 | 3 | matt | The driver invocation in @rpt.conf@ is |
179 | <pre> |
||
180 | 1 | zecke | usrp/HISIP:HISPORT[:MYPORT] |
181 | HISIP is the IP address (or FQDN) of the GR app |
||
182 | HISPORT is the UDP socket of the GR app |
||
183 | MYPORT (optional) is the UDP socket that Asterisk listens on |
||
184 | for this channel |
||
185 | 3 | matt | </pre> |
186 | 1 | zecke | |
187 | 4 | matt | TIP: You can use the @usrp show@ command to display status information from within the Asterisk CLI. |
188 | 1 | zecke | |
189 | 3 | matt | TIP: Another handy command is @rpt playback@ to start transmission on a channel. |
190 | 1 | zecke | |
191 | 3 | matt | h2. Channel Bank Configuration |
192 | 1 | zecke | |
193 | Typically the audio links are terminated on channel banks which provide a standard interface to user |
||
194 | equipment. Commonly, this equipment places an "offhook" indication on the signalling circuit when it |
||
195 | wishes to initiate a radio transmission, and signals the end of the transmission by placing the circuit |
||
196 | in the "onhook" state. Standard audio transmission levels are defined at the channel bank interface. |
||
197 | |||
198 | 3 | matt | A standard FXS port on the channel bank is defined in @/etc/asterisk/zapata.conf@ with |
199 | <pre> |
||
200 | 1 | zecke | signalling=fxo_ls |
201 | immediate=yes |
||
202 | context = chan1 |
||
203 | channel => 1 |
||
204 | 3 | matt | </pre> |
205 | 1 | zecke | |
206 | An offhook (PTT) signal from user equipment on the FXS channel bank port |
||
207 | 3 | matt | (due to the @immmediate=yes@) starts processing in @/etc/asterisk/extensions.conf@: |
208 | 1 | zecke | |
209 | 3 | matt | <pre> |
210 | 1 | zecke | [chan1] |
211 | exten => s,1,Dial(local/1@radio/n) |
||
212 | 3 | matt | </pre> |
213 | This jumps to extension "1" in context @radio@ (also in @/etc/asterisk/extensions.conf@) |
||
214 | <pre> |
||
215 | 1 | zecke | [radio] |
216 | exten => 1,1,rpt(000|D) |
||
217 | exten => 2,1,rpt(001|D) |
||
218 | exten => 3,1,rpt(002|D) |
||
219 | exten => 4,1,rpt(003|D) |
||
220 | exten => 5,1,rpt(004|D) |
||
221 | 3 | matt | </pre> |
222 | 1 | zecke | |
223 | So the call resulting from the offhook (PTT) signal is routed to |
||
224 | 3 | matt | extension "1" in context @[radio]@ where it's connected to the desired |
225 | 1 | zecke | repeater node (channel). If the GR app is running it will initiate |
226 | radio transmission. An onhook signal on the FXS channel bank port |
||
227 | causes the end of the transmission by ending the asterisk call in |
||
228 | 3 | matt | progress*. The @hangtime=0@ setting in @rpt.conf@ was used to reduce the |
229 | 1 | zecke | tail delay in this setup. |
230 | |||
231 | *The end of the transmission may be modified however, for example when |
||
232 | app_rpt appends an "ID" or if a "timeout" occurs. |
||
233 | |||
234 | Note: "Dumb" mode is used in these examples (theory: if it can't be made to work in its dumb mode, there's no prayer of getting smart mode to work) |
||
235 | |||
236 | 3 | matt | h2. USRP Transmission |
237 | 1 | zecke | |
238 | The multi-channel USRP transmitter app currently has some limitations: |
||
239 | * Transmit channel spacing is at arbitrary 25 KHz intervals |
||
240 | * Analog NBFM mode is not yet supported |
||
241 | Before running the app you must first determine (example values shown in square brackets - YMMV) |
||
242 | * the USRP TX daughterboard ID (A or B) [A] |
||
243 | * carrier frequency of the first ("center") TX channel [435.125 MHz] |
||
244 | * number of channels to be transmitted [five] |
||
245 | * the first UDP port number over which usrp_tx.py receives data from chan_usrp.c [port 34001] |
||
246 | Example: |
||
247 | 3 | matt | |
248 | @usrp_tx.py -TA -e -f 435.125e6 -n 5 -p 34001@ |
||
249 | |||
250 | 1 | zecke | Here we also request a FFT display. With port 34001 as the starting UDP port number and |
251 | 3 | matt | five channels, @usrp_tx.py@ listens on ports 34001-34005 for TX traffic coming from chan_usrp.c, as |
252 | configured in @/etc/asterisk/rpt.conf@ (see above). |
||
253 | 1 | zecke | |
254 | 3 | matt | h2. Soundcard Transmission |
255 | 1 | zecke | |
256 | The soundcard TX program outputs an analog waveform that is suitable for application to the |
||
257 | modulator stage of an FM transmitter. It listens on the UDP port for audio frames sent to it |
||
258 | by asterisk/chan_usrp. The analog audio thus received is encoded by the soundcard TX app to |
||
259 | IMBE voice code words, which are in turn assembled into P25 voice frames (LDU1/LDU2's). The |
||
260 | resulting 4800 baud symbol stream is then RRC filtered and shaped according to the P25 spec. |
||
261 | This signal is output to the sound card (and optionally to an on-screen oscilloscope using |
||
262 | 3 | matt | the @-e@ option). |
263 | 1 | zecke | |
264 | This app may be run on the same server as asterisk or on a different machine. |
||
265 | |||
266 | Currently only a single channel is supported (per invocation of soundcard_tx). If more than |
||
267 | one TX channel is to be used simultaneously, run a another copy of the app (either on a different |
||
268 | host or using a different UDP port). |
||
269 | |||
270 | Syntax: |
||
271 | |||
272 | 5 | matt | @soundcard_tx.py -g 0.3 -p 32001@ |
273 | 3 | matt | |
274 | |||
275 | The gain value (@0.3@) would cause the output envelope (ranging from -3 to +3) to be scaled to |
||
276 | 1 | zecke | fit within the standard band from -1 to +1. Values larger than 0.3 may cause clipping and distortion. |
277 | |||
278 | The final output amplitude to the radio can also be adjusted in discrete steps using the audio mixer |
||
279 | 3 | matt | application (e.g., @alsamixer@) |